@@ -28,37 +28,40 @@ interface ProviderDetailsModalProps {
2828 providerId ?: string ;
2929}
3030
31- // Default configurations for each provider type
31+ const ACCELERATOR_OPTIONS = [ 'AppleSilicon' , 'NVIDIA' , 'AMD' , 'cpu' ] ;
32+
33+ // Default configurations for each provider type (excluding supported_accelerators,
34+ // which is managed via the dedicated UI field).
3235const DEFAULT_CONFIGS = {
3336 skypilot : `{
3437 "server_url": "<Your SkyPilot server URL e.g. http://localhost:46580>",
3538 "default_env_vars": {
3639 "SKYPILOT_USER_ID": "<Your SkyPilot user ID>",
3740 "SKYPILOT_USER": "<Your SkyPilot user name>"
3841 },
39- "default_entrypoint_command": "",
40- "supported_accelerators": ["NVIDIA"]
42+ "default_entrypoint_command": ""
4143}` ,
4244 slurm : `{
4345 "mode": "ssh",
4446 "ssh_host": "<Machine IP for the SLURM login node>",
4547 "ssh_user": "<Your SLURM user ID - all jobs will run as this user>",
4648 "ssh_key_path": "",
47- "ssh_port": 22,
48- "supported_accelerators": ["NVIDIA"]
49+ "ssh_port": 22
4950}` ,
5051 runpod : `{
5152 "api_key": "<Your Runpod API key>",
52- "api_base_url": "https://rest.runpod.io/v1",
53- "supported_accelerators": ["NVIDIA"]
54- }` ,
55- local : `{
56- "supported_accelerators": ["AppleSilicon", "cpu"]
53+ "api_base_url": "https://rest.runpod.io/v1"
5754}` ,
55+ local : `{}` ,
56+ } as const ;
57+
58+ const DEFAULT_SUPPORTED_ACCELERATORS : Record < string , string [ ] > = {
59+ skypilot : [ 'NVIDIA' ] ,
60+ slurm : [ 'NVIDIA' ] ,
61+ runpod : [ 'NVIDIA' ] ,
62+ local : [ 'AppleSilicon' , 'cpu' ] ,
5863} ;
5964
60- const ACCELERATOR_OPTIONS = [ 'AppleSilicon' , 'NVIDIA' , 'AMD' , 'cpu' ] ;
61-
6265export default function ProviderDetailsModal ( {
6366 open,
6467 onClose,
@@ -148,21 +151,22 @@ export default function ProviderDetailsModal({
148151 setName ( providerData . name || '' ) ;
149152 setType ( providerData . type || '' ) ;
150153 // Config is an object, stringify it for display in textarea
151- const configObj =
154+ const rawConfigObj =
152155 typeof providerData . config === 'string'
153156 ? JSON . parse ( providerData . config || '{}' )
154157 : providerData . config || { } ;
155158
156- // Parse SLURM-specific fields if this is a SLURM provider
157- if ( providerData . type === 'slurm' ) {
158- parseSlurmConfig ( configObj ) ;
159+ // Extract supported_accelerators into dedicated state, but do not show it in raw JSON.
160+ if ( rawConfigObj . supported_accelerators ) {
161+ setSupportedAccelerators ( rawConfigObj . supported_accelerators ) ;
162+ delete rawConfigObj . supported_accelerators ;
159163 }
160164
161- if ( configObj . supported_accelerators ) {
162- setSupportedAccelerators ( configObj . supported_accelerators ) ;
165+ // Parse SLURM-specific fields if this is a SLURM provider
166+ if ( providerData . type === 'slurm' ) {
167+ parseSlurmConfig ( rawConfigObj ) ;
163168 }
164-
165- setConfig ( JSON . stringify ( configObj , null , 2 ) ) ;
169+ setConfig ( JSON . stringify ( rawConfigObj , null , 2 ) ) ;
166170 } else if ( ! providerId ) {
167171 // Reset form when in "add" mode (no providerId)
168172 setName ( '' ) ;
@@ -203,18 +207,22 @@ export default function ProviderDetailsModal({
203207 DEFAULT_CONFIGS [ type as keyof typeof DEFAULT_CONFIGS ] ;
204208 setConfig ( defaultConfig ) ;
205209
206- try {
207- const configObj = JSON . parse ( defaultConfig ) ;
208- if ( configObj . supported_accelerators ) {
209- setSupportedAccelerators ( configObj . supported_accelerators ) ;
210- }
210+ // Initialize default supported accelerators per provider type, but keep them
211+ // out of the raw JSON configuration.
212+ if ( DEFAULT_SUPPORTED_ACCELERATORS [ type ] ) {
213+ setSupportedAccelerators ( DEFAULT_SUPPORTED_ACCELERATORS [ type ] ) ;
214+ } else {
215+ setSupportedAccelerators ( [ ] ) ;
216+ }
211217
212- // Parse SLURM defaults
213- if ( type === 'slurm' ) {
218+ // Parse SLURM defaults from the JSON template
219+ if ( type === 'slurm' ) {
220+ try {
221+ const configObj = JSON . parse ( defaultConfig ) ;
214222 parseSlurmConfig ( configObj ) ;
223+ } catch ( e ) {
224+ // Ignore parse errors
215225 }
216- } catch ( e ) {
217- // Ignore parse errors
218226 }
219227 }
220228 } , [ type , providerId ] ) ;
@@ -226,14 +234,6 @@ export default function ProviderDetailsModal({
226234 if ( type === 'slurm' ) {
227235 const configObj = buildSlurmConfig ( ) ;
228236 setConfig ( JSON . stringify ( configObj , null , 2 ) ) ;
229- } else if ( type && type in DEFAULT_CONFIGS ) {
230- try {
231- const configObj = JSON . parse ( config ) ;
232- configObj . supported_accelerators = supportedAccelerators ;
233- setConfig ( JSON . stringify ( configObj , null , 2 ) ) ;
234- } catch ( e ) {
235- // If JSON is invalid (e.g. while typing), don't update
236- }
237237 }
238238 }
239239 } , [
@@ -282,6 +282,12 @@ export default function ProviderDetailsModal({
282282 let parsedConfig : any ;
283283 if ( type === 'slurm' ) {
284284 parsedConfig = buildSlurmConfig ( ) ;
285+ } else if ( type === 'local' ) {
286+ // Local providers are configured via supported accelerators only
287+ parsedConfig = { } ;
288+ if ( supportedAccelerators . length > 0 ) {
289+ parsedConfig . supported_accelerators = supportedAccelerators ;
290+ }
285291 } else {
286292 // The API expects an object for config, not a JSON string
287293 parsedConfig = typeof config === 'string' ? JSON . parse ( config ) : config ;
@@ -542,7 +548,7 @@ export default function ProviderDetailsModal({
542548 ) }
543549
544550 { /* Generic JSON config for non-SLURM providers or advanced editing */ }
545- { type !== 'slurm' && (
551+ { type !== 'slurm' && type !== 'local' && (
546552 < FormControl sx = { { mt : 1 } } >
547553 < FormLabel > Configuration</ FormLabel >
548554 < Textarea
0 commit comments