11import { APP_DIR , ConfigIO } from '../../../../lib' ;
2- import type { ModelProvider } from '../../../../schema' ;
2+ import type { ModelProvider , NetworkMode } from '../../../../schema' ;
33import { AgentNameSchema , DEFAULT_MODEL_IDS } from '../../../../schema' ;
44import { computeDefaultCredentialEnvVarName } from '../../../operations/identity/create-identity' ;
55import {
@@ -16,7 +16,16 @@ import type { SelectableItem } from '../../components';
1616import { HELP_TEXT } from '../../constants' ;
1717import { useListNavigation , useProject } from '../../hooks' ;
1818import { generateUniqueName } from '../../utils' ;
19- import { BUILD_TYPE_OPTIONS , GenerateWizardUI , getWizardHelpText , useGenerateWizard } from '../generate' ;
19+ import {
20+ BUILD_TYPE_OPTIONS ,
21+ GenerateWizardUI ,
22+ NETWORK_MODE_OPTIONS ,
23+ getWizardHelpText ,
24+ parseCommaSeparatedIds ,
25+ useGenerateWizard ,
26+ validateSecurityGroupsInput ,
27+ validateSubnetsInput ,
28+ } from '../generate' ;
2029import type { BuildType } from '../generate' ;
2130import type { AddAgentConfig , AgentType } from './types' ;
2231import {
@@ -52,10 +61,27 @@ interface AddAgentScreenProps {
5261// Steps for the initial phase (before branching to create or byo)
5362type InitialStep = 'name' | 'agentType' ;
5463// Steps for BYO path only (no framework/language - user's code already has these baked in)
55- type ByoStep = 'codeLocation' | 'buildType' | 'modelProvider' | 'apiKey' | 'confirm' ;
64+ type ByoStep =
65+ | 'codeLocation'
66+ | 'buildType'
67+ | 'modelProvider'
68+ | 'apiKey'
69+ | 'networkMode'
70+ | 'subnets'
71+ | 'securityGroups'
72+ | 'confirm' ;
5673
5774const INITIAL_STEPS : InitialStep [ ] = [ 'name' , 'agentType' ] ;
58- const BYO_STEPS : ByoStep [ ] = [ 'codeLocation' , 'buildType' , 'modelProvider' , 'apiKey' , 'confirm' ] ;
75+ const BYO_STEPS : ByoStep [ ] = [
76+ 'codeLocation' ,
77+ 'buildType' ,
78+ 'modelProvider' ,
79+ 'apiKey' ,
80+ 'networkMode' ,
81+ 'subnets' ,
82+ 'securityGroups' ,
83+ 'confirm' ,
84+ ] ;
5985
6086export function AddAgentScreen ( { existingAgentNames, onComplete, onExit } : AddAgentScreenProps ) {
6187 // Phase 1: name + agentType selection
@@ -75,6 +101,9 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg
75101 buildType : 'CodeZip' as BuildType ,
76102 modelProvider : 'Bedrock' as ModelProvider ,
77103 apiKey : undefined as string | undefined ,
104+ networkMode : 'PUBLIC' as NetworkMode ,
105+ subnets : undefined as string [ ] | undefined ,
106+ securityGroups : undefined as string [ ] | undefined ,
78107 } ) ;
79108
80109 const { project } = useProject ( ) ;
@@ -156,6 +185,9 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg
156185 apiKey : generateWizard . config . apiKey ,
157186 pythonVersion : DEFAULT_PYTHON_VERSION ,
158187 memory : generateWizard . config . memory ,
188+ networkMode : generateWizard . config . networkMode ?? 'PUBLIC' ,
189+ subnets : generateWizard . config . subnets ,
190+ securityGroups : generateWizard . config . securityGroups ,
159191 } ;
160192 onComplete ( config ) ;
161193 } , [ name , generateWizard . config , onComplete ] ) ;
@@ -174,13 +206,17 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg
174206 // BYO Path
175207 // ─────────────────────────────────────────────────────────────────────────────
176208
177- // BYO steps filtering (remove apiKey for Bedrock)
209+ // BYO steps filtering (remove apiKey for Bedrock, subnets/securityGroups when not VPC )
178210 const byoSteps = useMemo ( ( ) => {
211+ let steps = BYO_STEPS ;
179212 if ( byoConfig . modelProvider === 'Bedrock' ) {
180- return BYO_STEPS . filter ( s => s !== 'apiKey' ) ;
213+ steps = steps . filter ( s => s !== 'apiKey' ) ;
214+ }
215+ if ( byoConfig . networkMode !== 'VPC' ) {
216+ steps = steps . filter ( s => s !== 'subnets' && s !== 'securityGroups' ) ;
181217 }
182- return BYO_STEPS ;
183- } , [ byoConfig . modelProvider ] ) ;
218+ return steps ;
219+ } , [ byoConfig . modelProvider , byoConfig . networkMode ] ) ;
184220
185221 const byoCurrentIndex = byoSteps . indexOf ( byoStep ) ;
186222
@@ -232,6 +268,9 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg
232268 apiKey : byoConfig . apiKey ,
233269 pythonVersion : DEFAULT_PYTHON_VERSION ,
234270 memory : 'none' ,
271+ networkMode : byoConfig . networkMode ,
272+ subnets : byoConfig . subnets ,
273+ securityGroups : byoConfig . securityGroups ,
235274 } ;
236275 onComplete ( config ) ;
237276 } , [ name , byoConfig , onComplete ] ) ;
@@ -254,13 +293,40 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg
254293 if ( provider !== 'Bedrock' ) {
255294 setByoStep ( 'apiKey' ) ;
256295 } else {
257- setByoStep ( 'confirm ' ) ;
296+ setByoStep ( 'networkMode ' ) ;
258297 }
259298 } ,
260299 onExit : handleByoBack ,
261300 isActive : isByoPath && byoStep === 'modelProvider' ,
262301 } ) ;
263302
303+ // BYO network mode options
304+ const networkModeItems : SelectableItem [ ] = useMemo (
305+ ( ) =>
306+ NETWORK_MODE_OPTIONS . map ( o => ( {
307+ id : o . id ,
308+ title : o . title ,
309+ description : o . description ,
310+ } ) ) ,
311+ [ ]
312+ ) ;
313+
314+ const networkModeNav = useListNavigation ( {
315+ items : networkModeItems ,
316+ onSelect : item => {
317+ const mode = item . id as NetworkMode ;
318+ if ( mode === 'PUBLIC' ) {
319+ setByoConfig ( c => ( { ...c , networkMode : mode , subnets : undefined , securityGroups : undefined } ) ) ;
320+ setByoStep ( 'confirm' ) ;
321+ } else {
322+ setByoConfig ( c => ( { ...c , networkMode : mode } ) ) ;
323+ setByoStep ( 'subnets' ) ;
324+ }
325+ } ,
326+ onExit : handleByoBack ,
327+ isActive : isByoPath && byoStep === 'networkMode' ,
328+ } ) ;
329+
264330 useListNavigation ( {
265331 items : [ { id : 'confirm' , title : 'Confirm' } ] ,
266332 onSelect : handleByoComplete ,
@@ -281,7 +347,7 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg
281347 return getWizardHelpText ( generateWizard . step ) ;
282348 }
283349 // BYO path
284- if ( byoStep === 'codeLocation' || byoStep === 'apiKey' ) {
350+ if ( byoStep === 'codeLocation' || byoStep === 'apiKey' || byoStep === 'subnets' || byoStep === 'securityGroups' ) {
285351 return HELP_TEXT . TEXT_INPUT ;
286352 }
287353 if ( byoStep === 'confirm' ) {
@@ -413,10 +479,58 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg
413479 envVarName = { getProviderInfo ( byoConfig . modelProvider ) . envVarName }
414480 onSubmit = { apiKey => {
415481 setByoConfig ( c => ( { ...c , apiKey } ) ) ;
482+ setByoStep ( 'networkMode' ) ;
483+ } }
484+ onSkip = { ( ) => setByoStep ( 'networkMode' ) }
485+ onCancel = { handleByoBack }
486+ />
487+ ) }
488+
489+ { byoStep === 'networkMode' && (
490+ < WizardSelect
491+ title = "Select network mode"
492+ items = { networkModeItems }
493+ selectedIndex = { networkModeNav . selectedIndex }
494+ />
495+ ) }
496+
497+ { byoStep === 'subnets' && (
498+ < Box flexDirection = "column" >
499+ < Text color = "yellow" >
500+ Note: Your agent will run inside these VPC subnets. Ensure they have connectivity to required services
501+ (S3, ECR, Bedrock) and public internet if using public MCP servers or non-Bedrock model providers.
502+ </ Text >
503+ < Box marginTop = { 1 } >
504+ < TextInput
505+ prompt = "Subnet IDs (comma-separated)"
506+ initialValue = { byoConfig . subnets ?. join ( ', ' ) ?? '' }
507+ onSubmit = { value => {
508+ const result = validateSubnetsInput ( value ) ;
509+ if ( result !== true ) return false ;
510+ setByoConfig ( c => ( { ...c , subnets : parseCommaSeparatedIds ( value ) } ) ) ;
511+ setByoStep ( 'securityGroups' ) ;
512+ return true ;
513+ } }
514+ onCancel = { handleByoBack }
515+ customValidation = { validateSubnetsInput }
516+ />
517+ </ Box >
518+ </ Box >
519+ ) }
520+
521+ { byoStep === 'securityGroups' && (
522+ < TextInput
523+ prompt = "Security Group IDs (comma-separated)"
524+ initialValue = { byoConfig . securityGroups ?. join ( ', ' ) ?? '' }
525+ onSubmit = { value => {
526+ const result = validateSecurityGroupsInput ( value ) ;
527+ if ( result !== true ) return false ;
528+ setByoConfig ( c => ( { ...c , securityGroups : parseCommaSeparatedIds ( value ) } ) ) ;
416529 setByoStep ( 'confirm' ) ;
530+ return true ;
417531 } }
418- onSkip = { ( ) => setByoStep ( 'confirm' ) }
419532 onCancel = { handleByoBack }
533+ customValidation = { validateSecurityGroupsInput }
420534 />
421535 ) }
422536
@@ -450,6 +564,13 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg
450564 } ,
451565 ]
452566 : [ ] ) ,
567+ { label : 'Network Mode' , value : byoConfig . networkMode } ,
568+ ...( byoConfig . networkMode === 'VPC' && byoConfig . subnets
569+ ? [ { label : 'Subnets' , value : byoConfig . subnets . join ( ', ' ) } ]
570+ : [ ] ) ,
571+ ...( byoConfig . networkMode === 'VPC' && byoConfig . securityGroups
572+ ? [ { label : 'Security Groups' , value : byoConfig . securityGroups . join ( ', ' ) } ]
573+ : [ ] ) ,
453574 ] }
454575 />
455576 ) }
0 commit comments