diff --git a/docs/screenshots/advanced-gate-confirm-public.svg b/docs/screenshots/advanced-gate-confirm-public.svg new file mode 100644 index 00000000..067dc828 --- /dev/null +++ b/docs/screenshots/advanced-gate-confirm-public.svg @@ -0,0 +1,35 @@ + + + + + + + + + Add Agent + ✓ Name ✓ Type ✓ Language ✓ Build ✓ Protocol ✓ Framework ✓ Model + ✓ Memory ✓ Advanced ● Confirm + ╭──────────────────────────────────────────────────────────╮ +Review Configuration + │ │ +Name: MyAgent │ +Language: Python │ +Build: Direct Code Deploy │ +Protocol: HTTP │ +Framework: Strands │ +Model Provider: Bedrock │ + │ (us.anthropic.claude-sonnet-4-5-20250514-v1:0) │ +Memory: None │ +Network: PUBLIC │ + ╰──────────────────────────────────────────────────────────╯ + Enter/Y confirm · Esc back + + + \ No newline at end of file diff --git a/docs/screenshots/advanced-gate-default.svg b/docs/screenshots/advanced-gate-default.svg new file mode 100644 index 00000000..643b7b21 --- /dev/null +++ b/docs/screenshots/advanced-gate-default.svg @@ -0,0 +1,26 @@ + + + + + + + + + Add Agent + ✓ Name ✓ Type ✓ Language ✓ Build ✓ Protocol ✓ Framework ✓ Model + ✓ Memory ● Advanced Confirm + ╭──────────────────────────────────────────────────────────╮ +❯ No, use defaults - Public network, no VPC + │ Yes, customize │ + ╰──────────────────────────────────────────────────────────╯ + ↑↓ navigate · Enter select · Esc back + + + \ No newline at end of file diff --git a/docs/screenshots/advanced-gate-yes-network.svg b/docs/screenshots/advanced-gate-yes-network.svg new file mode 100644 index 00000000..e579ad50 --- /dev/null +++ b/docs/screenshots/advanced-gate-yes-network.svg @@ -0,0 +1,26 @@ + + + + + + + + + Add Agent + ✓ Name ✓ Type ✓ Language ✓ Build ✓ Protocol ✓ Framework ✓ Model + ✓ Memory ✓ Advanced ● Network Confirm + ╭──────────────────────────────────────────────────────────╮ +❯ Public + │ VPC - Attach to your VPC + ╰──────────────────────────────────────────────────────────╯ + ↑↓ navigate · Enter select · Esc back + + + \ No newline at end of file diff --git a/src/cli/tui/screens/agent/AddAgentScreen.tsx b/src/cli/tui/screens/agent/AddAgentScreen.tsx index 530feff4..6971474b 100644 --- a/src/cli/tui/screens/agent/AddAgentScreen.tsx +++ b/src/cli/tui/screens/agent/AddAgentScreen.tsx @@ -23,6 +23,7 @@ import { useListNavigation, useProject } from '../../hooks'; import { generateUniqueName } from '../../utils'; import { BUILD_TYPE_OPTIONS, GenerateWizardUI, getWizardHelpText, useGenerateWizard } from '../generate'; import type { BuildType } from '../generate'; +import { ADVANCED_OPTIONS } from '../generate/types'; import type { AddAgentConfig, AgentType } from './types'; import { ADD_AGENT_STEP_LABELS, @@ -63,22 +64,19 @@ type ByoStep = | 'buildType' | 'modelProvider' | 'apiKey' + | 'advanced' | 'networkMode' | 'subnets' | 'securityGroups' | 'confirm'; const INITIAL_STEPS: InitialStep[] = ['name', 'agentType']; -const BYO_STEPS: ByoStep[] = [ - 'codeLocation', - 'buildType', - 'modelProvider', - 'apiKey', - 'networkMode', - 'subnets', - 'securityGroups', - 'confirm', -]; +const ADVANCED_ITEMS: SelectableItem[] = ADVANCED_OPTIONS.map(o => ({ + id: o.id, + title: o.title, + description: o.description, +})); +const BYO_STEPS: ByoStep[] = ['codeLocation', 'buildType', 'modelProvider', 'apiKey', 'advanced', 'confirm']; export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAgentScreenProps) { // Phase 1: name + agentType selection @@ -102,6 +100,7 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg subnets: '' as string, securityGroups: '' as string, }); + const [byoAdvancedSelected, setByoAdvancedSelected] = useState(false); const { project } = useProject(); @@ -210,11 +209,15 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg if (byoConfig.modelProvider === 'Bedrock') { steps = steps.filter(s => s !== 'apiKey'); } - if (byoConfig.networkMode !== 'VPC') { - steps = steps.filter(s => s !== 'subnets' && s !== 'securityGroups'); + if (byoAdvancedSelected) { + const advancedIndex = steps.indexOf('advanced'); + const afterAdvanced = advancedIndex + 1; + const networkSteps: ByoStep[] = + byoConfig.networkMode === 'VPC' ? ['networkMode', 'subnets', 'securityGroups'] : ['networkMode']; + steps = [...steps.slice(0, afterAdvanced), ...networkSteps, ...steps.slice(afterAdvanced)]; } return steps; - }, [byoConfig.modelProvider, byoConfig.networkMode]); + }, [byoConfig.modelProvider, byoConfig.networkMode, byoAdvancedSelected]); const byoCurrentIndex = byoSteps.indexOf(byoStep); @@ -292,7 +295,7 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg if (provider !== 'Bedrock') { setByoStep('apiKey'); } else { - setByoStep('networkMode'); + setByoStep('advanced'); } }, onExit: handleByoBack, @@ -310,6 +313,22 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg [] ); + const advancedNav = useListNavigation({ + items: ADVANCED_ITEMS, + onSelect: item => { + if (item.id === 'yes') { + setByoAdvancedSelected(true); + setByoStep('networkMode'); + } else { + setByoAdvancedSelected(false); + setByoConfig(c => ({ ...c, networkMode: 'PUBLIC' as NetworkMode, subnets: '', securityGroups: '' })); + setByoStep('confirm'); + } + }, + onExit: handleByoBack, + isActive: isByoPath && byoStep === 'advanced', + }); + const networkModeNav = useListNavigation({ items: networkModeItems, onSelect: item => { @@ -477,13 +496,21 @@ export function AddAgentScreen({ existingAgentNames, onComplete, onExit }: AddAg envVarName={getProviderInfo(byoConfig.modelProvider).envVarName} onSubmit={apiKey => { setByoConfig(c => ({ ...c, apiKey })); - setByoStep('networkMode'); + setByoStep('advanced'); }} - onSkip={() => setByoStep('networkMode')} + onSkip={() => setByoStep('advanced')} onCancel={handleByoBack} /> )} + {byoStep === 'advanced' && ( + + )} + {byoStep === 'networkMode' && ( = { framework: 'Framework', modelProvider: 'Model', apiKey: 'API Key', + advanced: 'Advanced', networkMode: 'Network', subnets: 'Subnets', securityGroups: 'Security Groups', diff --git a/src/cli/tui/screens/generate/GenerateWizardUI.tsx b/src/cli/tui/screens/generate/GenerateWizardUI.tsx index 914dedcd..1545ae03 100644 --- a/src/cli/tui/screens/generate/GenerateWizardUI.tsx +++ b/src/cli/tui/screens/generate/GenerateWizardUI.tsx @@ -7,6 +7,7 @@ import type { SelectableItem } from '../../components'; import { useListNavigation } from '../../hooks'; import type { BuildType, GenerateConfig, GenerateStep, MemoryOption, ProtocolMode } from './types'; import { + ADVANCED_OPTIONS, BUILD_TYPE_OPTIONS, LANGUAGE_OPTIONS, MEMORY_OPTIONS, @@ -79,6 +80,8 @@ export function GenerateWizardUI({ })); case 'memory': return MEMORY_OPTIONS.map(o => ({ id: o.id, title: o.title, description: o.description })); + case 'advanced': + return ADVANCED_OPTIONS.map(o => ({ id: o.id, title: o.title, description: o.description })); case 'networkMode': return NETWORK_MODE_OPTIONS.map(o => ({ id: o.id, title: o.title, description: o.description })); default: @@ -114,6 +117,9 @@ export function GenerateWizardUI({ case 'memory': wizard.setMemory(item.id as MemoryOption); break; + case 'advanced': + wizard.setAdvanced(item.id === 'yes'); + break; case 'networkMode': wizard.setNetworkMode(item.id as NetworkMode); break; diff --git a/src/cli/tui/screens/generate/__tests__/useGenerateWizard.test.tsx b/src/cli/tui/screens/generate/__tests__/useGenerateWizard.test.tsx new file mode 100644 index 00000000..69a65608 --- /dev/null +++ b/src/cli/tui/screens/generate/__tests__/useGenerateWizard.test.tsx @@ -0,0 +1,274 @@ +import { useGenerateWizard } from '../useGenerateWizard'; +import { Text } from 'ink'; +import { render } from 'ink-testing-library'; +import React, { act, useImperativeHandle } from 'react'; +import { describe, expect, it } from 'vitest'; + +// --------------------------------------------------------------------------- +// Imperative harness — exposes wizard methods via ref for act()-based tests +// --------------------------------------------------------------------------- + +type WizardReturn = ReturnType; + +interface HarnessHandle { + wizard: WizardReturn; +} + +const Harness = React.forwardRef((props, ref) => { + const wizard = useGenerateWizard(props.initialName ? { initialName: props.initialName } : undefined); + useImperativeHandle(ref, () => ({ wizard })); + return ( + + step:{wizard.step} steps:{wizard.steps.join(',')} networkMode:{wizard.config.networkMode ?? 'undefined'}{' '} + advancedSelected:{String(wizard.advancedSelected)} + + ); +}); +Harness.displayName = 'Harness'; + +function setup(initialName?: string) { + const ref = React.createRef(); + const result = render(); + return { ref, ...result }; +} + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe('useGenerateWizard — advanced config gate', () => { + describe('step list includes advanced', () => { + it('BASE steps include advanced before confirm', () => { + const { lastFrame } = setup(); + const frame = lastFrame()!; + expect(frame).toContain('steps:'); + // Default modelProvider is Bedrock which filters out apiKey + expect(frame).toMatch(/modelProvider,advanced,confirm/); + expect(frame).not.toContain('apiKey'); + }); + + it('MCP protocol skips sdk/modelProvider/apiKey but keeps advanced', () => { + const { ref, lastFrame } = setup(); + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('MCP'); + }); + const frame = lastFrame()!; + expect(frame).toContain('advanced'); + expect(frame).not.toMatch(/steps:[^]*sdk/); + expect(frame).not.toMatch(/steps:[^]*modelProvider/); + }); + + it('Strands SDK inserts memory before advanced', () => { + const { ref, lastFrame } = setup(); + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('HTTP'); + ref.current!.wizard.setSdk('Strands'); + }); + const frame = lastFrame()!; + expect(frame).toMatch(/memory,advanced/); + }); + }); + + describe('setAdvanced routing', () => { + function walkToAdvanced(ref: React.RefObject) { + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('HTTP'); + ref.current!.wizard.setSdk('Strands'); + ref.current!.wizard.setModelProvider('Bedrock'); + ref.current!.wizard.setMemory('none'); + }); + } + + it('setAdvanced(false) jumps to confirm with PUBLIC defaults', () => { + const { ref, lastFrame } = setup(); + walkToAdvanced(ref); + expect(lastFrame()).toContain('step:advanced'); + + act(() => ref.current!.wizard.setAdvanced(false)); + + const frame = lastFrame()!; + expect(frame).toContain('step:confirm'); + expect(frame).toContain('networkMode:PUBLIC'); + expect(frame).toContain('advancedSelected:false'); + }); + + it('setAdvanced(true) navigates to networkMode', () => { + const { ref, lastFrame } = setup(); + walkToAdvanced(ref); + + act(() => ref.current!.wizard.setAdvanced(true)); + + const frame = lastFrame()!; + expect(frame).toContain('step:networkMode'); + expect(frame).toContain('advancedSelected:true'); + }); + + it('setAdvanced(true) injects networkMode into steps', () => { + const { ref, lastFrame } = setup(); + walkToAdvanced(ref); + + act(() => ref.current!.wizard.setAdvanced(true)); + + expect(lastFrame()).toMatch(/advanced,networkMode,confirm/); + }); + + it('setAdvanced(true) then VPC injects subnets and securityGroups', () => { + const { ref } = setup(); + walkToAdvanced(ref); + + act(() => ref.current!.wizard.setAdvanced(true)); + act(() => ref.current!.wizard.setNetworkMode('VPC')); + + const steps = ref.current!.wizard.steps; + const advIdx = steps.indexOf('advanced'); + expect(steps.slice(advIdx)).toEqual(['advanced', 'networkMode', 'subnets', 'securityGroups', 'confirm']); + }); + }); + + describe('state cleanup on toggle', () => { + function walkToAdvancedAndSelectYes(ref: React.RefObject) { + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('HTTP'); + ref.current!.wizard.setSdk('Strands'); + ref.current!.wizard.setModelProvider('Bedrock'); + ref.current!.wizard.setMemory('none'); + }); + act(() => ref.current!.wizard.setAdvanced(true)); + act(() => ref.current!.wizard.setNetworkMode('VPC')); + act(() => ref.current!.wizard.setSubnets(['subnet-123'])); + act(() => ref.current!.wizard.setSecurityGroups(['sg-456'])); + } + + it('switching from Yes to No clears VPC config', () => { + const { ref } = setup(); + walkToAdvancedAndSelectYes(ref); + + // Now go back and select No + act(() => ref.current!.wizard.setAdvanced(false)); + + const w = ref.current!.wizard; + expect(w.step).toBe('confirm'); + expect(w.config.networkMode).toBe('PUBLIC'); + expect(w.advancedSelected).toBe(false); + // Network steps should not be in the step list + expect(w.steps).not.toContain('subnets'); + expect(w.steps).not.toContain('securityGroups'); + expect(w.steps).not.toContain('networkMode'); + }); + + it('config subnets and securityGroups are cleared to undefined', () => { + const { ref } = setup(); + walkToAdvancedAndSelectYes(ref); + + act(() => ref.current!.wizard.setAdvanced(false)); + + expect(ref.current!.wizard.config.subnets).toBeUndefined(); + expect(ref.current!.wizard.config.securityGroups).toBeUndefined(); + expect(ref.current!.wizard.config.networkMode).toBe('PUBLIC'); + }); + }); + + describe('routing callbacks target advanced', () => { + it('setProtocol(MCP) routes to advanced', () => { + const { ref, lastFrame } = setup(); + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('MCP'); + }); + expect(lastFrame()).toContain('step:advanced'); + }); + + it('setModelProvider(Bedrock) with non-Strands routes to advanced', () => { + const { ref, lastFrame } = setup(); + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('HTTP'); + ref.current!.wizard.setSdk('LangChain_LangGraph'); + }); + // Separate act() so setModelProvider picks up the new config.sdk + act(() => ref.current!.wizard.setModelProvider('Bedrock')); + expect(lastFrame()).toContain('step:advanced'); + }); + + it('setApiKey with non-Strands routes to advanced', () => { + const { ref, lastFrame } = setup(); + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('HTTP'); + ref.current!.wizard.setSdk('LangChain_LangGraph'); + }); + // Separate act() calls so callbacks pick up the new config.sdk + act(() => ref.current!.wizard.setModelProvider('OpenAI')); + act(() => ref.current!.wizard.setApiKey('sk-test')); + expect(lastFrame()).toContain('step:advanced'); + }); + + it('skipApiKey with non-Strands routes to advanced', () => { + const { ref, lastFrame } = setup(); + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('HTTP'); + ref.current!.wizard.setSdk('LangChain_LangGraph'); + }); + // Separate act() calls so callbacks pick up the new config.sdk + act(() => ref.current!.wizard.setModelProvider('OpenAI')); + act(() => ref.current!.wizard.skipApiKey()); + expect(lastFrame()).toContain('step:advanced'); + }); + + it('setMemory routes to advanced', () => { + const { ref, lastFrame } = setup(); + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('HTTP'); + ref.current!.wizard.setSdk('Strands'); + ref.current!.wizard.setModelProvider('Bedrock'); + ref.current!.wizard.setMemory('shortTerm'); + }); + expect(lastFrame()).toContain('step:advanced'); + }); + }); + + describe('reset clears advancedSelected', () => { + it('reset returns advancedSelected to false', () => { + const { ref, lastFrame } = setup(); + act(() => { + ref.current!.wizard.setProjectName('Test'); + ref.current!.wizard.setLanguage('Python'); + ref.current!.wizard.setBuildType('CodeZip'); + ref.current!.wizard.setProtocol('HTTP'); + ref.current!.wizard.setSdk('Strands'); + ref.current!.wizard.setModelProvider('Bedrock'); + ref.current!.wizard.setMemory('none'); + ref.current!.wizard.setAdvanced(true); + }); + expect(lastFrame()).toContain('advancedSelected:true'); + + act(() => ref.current!.wizard.reset()); + + expect(lastFrame()).toContain('advancedSelected:false'); + }); + }); +}); diff --git a/src/cli/tui/screens/generate/types.ts b/src/cli/tui/screens/generate/types.ts index ad314d05..036ea6e7 100644 --- a/src/cli/tui/screens/generate/types.ts +++ b/src/cli/tui/screens/generate/types.ts @@ -17,6 +17,7 @@ export type GenerateStep = | 'modelProvider' | 'apiKey' | 'memory' + | 'advanced' | 'networkMode' | 'subnets' | 'securityGroups' @@ -51,7 +52,7 @@ export const BASE_GENERATE_STEPS: GenerateStep[] = [ 'sdk', 'modelProvider', 'apiKey', - 'networkMode', + 'advanced', 'confirm', ]; @@ -64,6 +65,7 @@ export const STEP_LABELS: Record = { modelProvider: 'Model', apiKey: 'API Key', memory: 'Memory', + advanced: 'Advanced', networkMode: 'Network', subnets: 'Subnets', securityGroups: 'Security Groups', @@ -125,6 +127,11 @@ export const NETWORK_MODE_OPTIONS = [ { id: 'VPC', title: 'VPC', description: 'Attach to your VPC' }, ] as const; +export const ADVANCED_OPTIONS = [ + { id: 'no', title: 'No, use defaults', description: 'Public network, no VPC' }, + { id: 'yes', title: 'Yes, customize', description: undefined }, +] as const; + export const MEMORY_OPTIONS = [ { id: 'none', title: 'None', description: 'No memory' }, { id: 'shortTerm', title: 'Short-term memory', description: 'Context within a session' }, diff --git a/src/cli/tui/screens/generate/useGenerateWizard.ts b/src/cli/tui/screens/generate/useGenerateWizard.ts index 323d0394..6d20ab65 100644 --- a/src/cli/tui/screens/generate/useGenerateWizard.ts +++ b/src/cli/tui/screens/generate/useGenerateWizard.ts @@ -34,6 +34,7 @@ export function useGenerateWizard(options?: UseGenerateWizardOptions) { // Track if user has selected a framework (moved past sdk step) const [sdkSelected, setSdkSelected] = useState(false); + const [advancedSelected, setAdvancedSelected] = useState(false); // Steps depend on protocol, SDK, model provider, network mode, and whether we have an initial name // MCP skips sdk, modelProvider, apiKey, memory @@ -50,16 +51,27 @@ export function useGenerateWizard(options?: UseGenerateWizardOptions) { filtered = filtered.filter(s => s !== 'apiKey'); } if (sdkSelected && config.sdk === 'Strands') { - const networkModeIndex = filtered.indexOf('networkMode'); - filtered = [...filtered.slice(0, networkModeIndex), 'memory', ...filtered.slice(networkModeIndex)]; + const advancedIndex = filtered.indexOf('advanced'); + filtered = [...filtered.slice(0, advancedIndex), 'memory', ...filtered.slice(advancedIndex)]; } } - if (config.networkMode === 'VPC') { - const confirmIndex = filtered.indexOf('confirm'); - filtered = [...filtered.slice(0, confirmIndex), 'subnets', 'securityGroups', ...filtered.slice(confirmIndex)]; + if (advancedSelected) { + const advancedIndex = filtered.indexOf('advanced'); + const afterAdvanced = advancedIndex + 1; + const networkSteps: GenerateStep[] = + config.networkMode === 'VPC' ? ['networkMode', 'subnets', 'securityGroups'] : ['networkMode']; + filtered = [...filtered.slice(0, afterAdvanced), ...networkSteps, ...filtered.slice(afterAdvanced)]; } return filtered; - }, [config.modelProvider, config.sdk, config.protocol, config.networkMode, hasInitialName, sdkSelected]); + }, [ + config.modelProvider, + config.sdk, + config.protocol, + config.networkMode, + hasInitialName, + sdkSelected, + advancedSelected, + ]); const currentIndex = steps.indexOf(step); @@ -88,7 +100,7 @@ export function useGenerateWizard(options?: UseGenerateWizardOptions) { const setProtocol = useCallback((protocol: ProtocolMode) => { setConfig(c => ({ ...c, protocol, memory: protocol === 'MCP' ? 'none' : c.memory })); if (protocol === 'MCP') { - setStep('confirm'); + setStep('advanced'); } else { setStep('sdk'); } @@ -117,7 +129,7 @@ export function useGenerateWizard(options?: UseGenerateWizardOptions) { } else if (config.sdk === 'Strands') { setStep('memory'); } else { - setStep('networkMode'); + setStep('advanced'); } }, [config.sdk] @@ -129,7 +141,7 @@ export function useGenerateWizard(options?: UseGenerateWizardOptions) { if (config.sdk === 'Strands') { setStep('memory'); } else { - setStep('networkMode'); + setStep('advanced'); } }, [config.sdk] @@ -139,13 +151,24 @@ export function useGenerateWizard(options?: UseGenerateWizardOptions) { if (config.sdk === 'Strands') { setStep('memory'); } else { - setStep('networkMode'); + setStep('advanced'); } }, [config.sdk]); const setMemory = useCallback((memory: MemoryOption) => { setConfig(c => ({ ...c, memory })); - setStep('networkMode'); + setStep('advanced'); + }, []); + + const setAdvanced = useCallback((wantsAdvanced: boolean) => { + if (wantsAdvanced) { + setAdvancedSelected(true); + setStep('networkMode'); + } else { + setAdvancedSelected(false); + setConfig(c => ({ ...c, networkMode: 'PUBLIC', subnets: undefined, securityGroups: undefined })); + setStep('confirm'); + } }, []); const setNetworkMode = useCallback((networkMode: NetworkMode) => { @@ -178,6 +201,7 @@ export function useGenerateWizard(options?: UseGenerateWizardOptions) { setConfig(getDefaultConfig()); setError(null); setSdkSelected(false); + setAdvancedSelected(false); }, []); /** @@ -207,6 +231,8 @@ export function useGenerateWizard(options?: UseGenerateWizardOptions) { setApiKey, skipApiKey, setMemory, + setAdvanced, + advancedSelected, setNetworkMode, setSubnets, setSecurityGroups,