11import type { MemoryStrategyType } from '../../../../schema' ;
2- import { AgentNameSchema } from '../../../../schema' ;
2+ import { AgentNameSchema , StreamContentLevelSchema } from '../../../../schema' ;
3+ import { ARN_VALIDATION_MESSAGE , isValidArn } from '../../../commands/shared/arn-utils' ;
34import {
45 ConfirmReview ,
56 Panel ,
@@ -14,7 +15,7 @@ import { HELP_TEXT } from '../../constants';
1415import { useListNavigation , useMultiSelectNavigation } from '../../hooks' ;
1516import { generateUniqueName } from '../../utils' ;
1617import type { AddMemoryConfig } from './types' ;
17- import { EVENT_EXPIRY_OPTIONS , MEMORY_STEP_LABELS , MEMORY_STRATEGY_OPTIONS } from './types' ;
18+ import { CONTENT_LEVEL_OPTIONS , EVENT_EXPIRY_OPTIONS , MEMORY_STEP_LABELS , MEMORY_STRATEGY_OPTIONS } from './types' ;
1819import { useAddMemoryWizard } from './useAddMemoryWizard' ;
1920import React , { useMemo } from 'react' ;
2021
@@ -24,6 +25,11 @@ interface AddMemoryScreenProps {
2425 existingMemoryNames : string [ ] ;
2526}
2627
28+ const STREAMING_OPTIONS : SelectableItem [ ] = [
29+ { id : 'no' , title : 'No' , description : 'No streaming' } ,
30+ { id : 'yes' , title : 'Yes' , description : 'Stream memory record events to a delivery target (e.g. Kinesis)' } ,
31+ ] ;
32+
2733export function AddMemoryScreen ( { onComplete, onExit, existingMemoryNames } : AddMemoryScreenProps ) {
2834 const wizard = useAddMemoryWizard ( ) ;
2935
@@ -37,9 +43,17 @@ export function AddMemoryScreen({ onComplete, onExit, existingMemoryNames }: Add
3743 [ ]
3844 ) ;
3945
46+ const contentLevelItems : SelectableItem [ ] = useMemo (
47+ ( ) => CONTENT_LEVEL_OPTIONS . map ( opt => ( { id : opt . id , title : opt . title , description : opt . description } ) ) ,
48+ [ ]
49+ ) ;
50+
4051 const isNameStep = wizard . step === 'name' ;
4152 const isExpiryStep = wizard . step === 'expiry' ;
4253 const isStrategiesStep = wizard . step === 'strategies' ;
54+ const isStreamingStep = wizard . step === 'streaming' ;
55+ const isStreamArnStep = wizard . step === 'streamArn' ;
56+ const isContentLevelStep = wizard . step === 'contentLevel' ;
4357 const isConfirmStep = wizard . step === 'confirm' ;
4458
4559 const expiryNav = useListNavigation ( {
@@ -58,6 +72,20 @@ export function AddMemoryScreen({ onComplete, onExit, existingMemoryNames }: Add
5872 requireSelection : false ,
5973 } ) ;
6074
75+ const streamingNav = useListNavigation ( {
76+ items : STREAMING_OPTIONS ,
77+ onSelect : item => wizard . setStreamingEnabled ( item . id === 'yes' ) ,
78+ onExit : ( ) => wizard . goBack ( ) ,
79+ isActive : isStreamingStep ,
80+ } ) ;
81+
82+ const contentLevelNav = useListNavigation ( {
83+ items : contentLevelItems ,
84+ onSelect : item => wizard . setContentLevel ( StreamContentLevelSchema . parse ( item . id ) ) ,
85+ onExit : ( ) => wizard . goBack ( ) ,
86+ isActive : isContentLevelStep ,
87+ } ) ;
88+
6189 useListNavigation ( {
6290 items : [ { id : 'confirm' , title : 'Confirm' } ] ,
6391 onSelect : ( ) => onComplete ( wizard . config ) ,
@@ -67,16 +95,37 @@ export function AddMemoryScreen({ onComplete, onExit, existingMemoryNames }: Add
6795
6896 const helpText = isStrategiesStep
6997 ? 'Space toggle · Enter confirm · Esc back'
70- : isExpiryStep
98+ : isExpiryStep || isStreamingStep || isContentLevelStep
7199 ? HELP_TEXT . NAVIGATE_SELECT
72100 : isConfirmStep
73101 ? HELP_TEXT . CONFIRM_CANCEL
74102 : HELP_TEXT . TEXT_INPUT ;
75103
76104 const headerContent = < StepIndicator steps = { wizard . steps } currentStep = { wizard . step } labels = { MEMORY_STEP_LABELS } /> ;
77105
106+ const confirmFields = useMemo (
107+ ( ) => [
108+ { label : 'Name' , value : wizard . config . name } ,
109+ { label : 'Event Expiry' , value : `${ wizard . config . eventExpiryDuration } days` } ,
110+ { label : 'Strategies' , value : wizard . config . strategies . map ( s => s . type ) . join ( ', ' ) || 'None' } ,
111+ ...( wizard . config . streaming
112+ ? [
113+ { label : 'Stream ARN' , value : wizard . config . streaming . dataStreamArn } ,
114+ { label : 'Content Level' , value : wizard . config . streaming . contentLevel } ,
115+ ]
116+ : [ { label : 'Streaming' , value : 'Disabled' } ] ) ,
117+ ] ,
118+ [ wizard . config ]
119+ ) ;
120+
78121 return (
79- < Screen title = "Add Memory" onExit = { onExit } helpText = { helpText } headerContent = { headerContent } >
122+ < Screen
123+ title = "Add Memory"
124+ onExit = { onExit }
125+ helpText = { helpText }
126+ headerContent = { headerContent }
127+ exitEnabled = { isNameStep }
128+ >
80129 < Panel >
81130 { isNameStep && (
82131 < TextInput
@@ -109,15 +158,36 @@ export function AddMemoryScreen({ onComplete, onExit, existingMemoryNames }: Add
109158 />
110159 ) }
111160
112- { isConfirmStep && (
113- < ConfirmReview
114- fields = { [
115- { label : 'Name' , value : wizard . config . name } ,
116- { label : 'Event Expiry' , value : `${ wizard . config . eventExpiryDuration } days` } ,
117- { label : 'Strategies' , value : wizard . config . strategies . map ( s => s . type ) . join ( ', ' ) || 'None' } ,
118- ] }
161+ { isStreamingStep && (
162+ < WizardSelect
163+ title = "Enable memory record streaming?"
164+ description = "Stream memory record lifecycle events to a delivery target"
165+ items = { STREAMING_OPTIONS }
166+ selectedIndex = { streamingNav . selectedIndex }
167+ />
168+ ) }
169+
170+ { isStreamArnStep && (
171+ < TextInput
172+ key = "streamArn"
173+ prompt = "Delivery target ARN (e.g. Kinesis stream)"
174+ initialValue = ""
175+ onSubmit = { wizard . setStreamArn }
176+ onCancel = { ( ) => wizard . goBack ( ) }
177+ customValidation = { value => isValidArn ( value ) || ARN_VALIDATION_MESSAGE }
119178 />
120179 ) }
180+
181+ { isContentLevelStep && (
182+ < WizardSelect
183+ title = "Stream content level"
184+ description = "What data to include in stream events"
185+ items = { contentLevelItems }
186+ selectedIndex = { contentLevelNav . selectedIndex }
187+ />
188+ ) }
189+
190+ { isConfirmStep && < ConfirmReview fields = { confirmFields } /> }
121191 </ Panel >
122192 </ Screen >
123193 ) ;
0 commit comments