From 8a8c2971f9d90d7c53004d7f20ce1643f17124f1 Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Fri, 27 Mar 2026 17:30:40 -0400 Subject: [PATCH 1/3] Revert "feat: add semanticOverride support for SEMANTIC memory strategies (#678) (#696)" This reverts commit 5e0f584ac8c87074b8a69ece6178bc97ad4b5f1c. --- src/schema/llm-compacted/agentcore.ts | 5 - .../__tests__/agentcore-project.test.ts | 50 -------- src/schema/schemas/agentcore-project.ts | 8 +- .../primitives/__tests__/memory.test.ts | 119 +----------------- src/schema/schemas/primitives/index.ts | 11 +- src/schema/schemas/primitives/memory.ts | 56 +-------- 6 files changed, 4 insertions(+), 245 deletions(-) diff --git a/src/schema/llm-compacted/agentcore.ts b/src/schema/llm-compacted/agentcore.ts index 1ed6da52..392b0a72 100644 --- a/src/schema/llm-compacted/agentcore.ts +++ b/src/schema/llm-compacted/agentcore.ts @@ -78,11 +78,6 @@ interface MemoryStrategy { description?: string; namespaces?: string[]; reflectionNamespaces?: string[]; // EPISODIC only: namespaces for cross-episode reflections - semanticOverride?: { - // Only valid when type is 'SEMANTIC' - extraction?: { appendToPrompt: string; modelId: string }; // @min 1 for both, @max 30000 for appendToPrompt - consolidation?: { appendToPrompt: string; modelId: string }; // At least one of extraction/consolidation required - }; } // ───────────────────────────────────────────────────────────────────────────── diff --git a/src/schema/schemas/__tests__/agentcore-project.test.ts b/src/schema/schemas/__tests__/agentcore-project.test.ts index 1d125726..f0e250e7 100644 --- a/src/schema/schemas/__tests__/agentcore-project.test.ts +++ b/src/schema/schemas/__tests__/agentcore-project.test.ts @@ -452,54 +452,4 @@ describe('AgentCoreProjectSpecSchema', () => { }); expect(result.success).toBe(false); }); - - it('accepts memory with semanticOverride on SEMANTIC strategy', () => { - const result = AgentCoreProjectSpecSchema.safeParse({ - ...minimalProject, - memories: [ - { - name: 'TestMemory', - eventExpiryDuration: 30, - strategies: [ - { - type: 'SEMANTIC', - namespaces: ['/users/{actorId}/facts'], - semanticOverride: { - extraction: { - appendToPrompt: 'Extract key facts', - modelId: 'anthropic.claude-3-sonnet-20240229-v1:0', - }, - }, - }, - ], - }, - ], - }); - expect(result.success).toBe(true); - }); - - it('rejects memory with semanticOverride on SUMMARIZATION strategy', () => { - const result = AgentCoreProjectSpecSchema.safeParse({ - ...minimalProject, - memories: [ - { - name: 'TestMemory', - eventExpiryDuration: 30, - strategies: [ - { - type: 'SUMMARIZATION', - namespaces: ['/summaries/{actorId}/{sessionId}'], - semanticOverride: { - extraction: { - appendToPrompt: 'test', - modelId: 'model-1', - }, - }, - }, - ], - }, - ], - }); - expect(result.success).toBe(false); - }); }); diff --git a/src/schema/schemas/agentcore-project.ts b/src/schema/schemas/agentcore-project.ts index 8617b1d6..d6903a1c 100644 --- a/src/schema/schemas/agentcore-project.ts +++ b/src/schema/schemas/agentcore-project.ts @@ -30,13 +30,7 @@ export { MemoryStrategyTypeSchema, }; export { EvaluationLevelSchema }; -export type { - MemoryStrategy, - MemoryStrategyType, - SemanticOverride, - SemanticExtractionOverride, - SemanticConsolidationOverride, -} from './primitives/memory'; +export type { MemoryStrategy, MemoryStrategyType } from './primitives/memory'; export type { OnlineEvalConfig } from './primitives/online-eval-config'; export { OnlineEvalConfigSchema, OnlineEvalConfigNameSchema } from './primitives/online-eval-config'; export type { EvaluationLevel, EvaluatorConfig, LlmAsAJudgeConfig, RatingScale } from './primitives/evaluator'; diff --git a/src/schema/schemas/primitives/__tests__/memory.test.ts b/src/schema/schemas/primitives/__tests__/memory.test.ts index 84f6cbb5..e8beca6b 100644 --- a/src/schema/schemas/primitives/__tests__/memory.test.ts +++ b/src/schema/schemas/primitives/__tests__/memory.test.ts @@ -1,9 +1,4 @@ -import { - DEFAULT_STRATEGY_NAMESPACES, - MemoryStrategySchema, - MemoryStrategyTypeSchema, - SemanticOverrideSchema, -} from '../memory'; +import { DEFAULT_STRATEGY_NAMESPACES, MemoryStrategySchema, MemoryStrategyTypeSchema } from '../memory'; import { describe, expect, it } from 'vitest'; describe('MemoryStrategyTypeSchema', () => { @@ -175,115 +170,3 @@ describe('DEFAULT_STRATEGY_NAMESPACES', () => { expect(DEFAULT_STRATEGY_NAMESPACES).not.toHaveProperty('CUSTOM'); }); }); - -describe('SemanticOverrideSchema', () => { - it('accepts extraction-only override', () => { - const result = SemanticOverrideSchema.safeParse({ - extraction: { appendToPrompt: 'Extract key facts', modelId: 'anthropic.claude-3-sonnet-20240229-v1:0' }, - }); - expect(result.success).toBe(true); - }); - - it('accepts consolidation-only override', () => { - const result = SemanticOverrideSchema.safeParse({ - consolidation: { appendToPrompt: 'Consolidate memories', modelId: 'anthropic.claude-3-sonnet-20240229-v1:0' }, - }); - expect(result.success).toBe(true); - }); - - it('accepts both extraction and consolidation', () => { - const result = SemanticOverrideSchema.safeParse({ - extraction: { appendToPrompt: 'Extract', modelId: 'model-1' }, - consolidation: { appendToPrompt: 'Consolidate', modelId: 'model-2' }, - }); - expect(result.success).toBe(true); - }); - - it('rejects empty override (at least one required)', () => { - const result = SemanticOverrideSchema.safeParse({}); - expect(result.success).toBe(false); - }); - - it('rejects extraction with empty appendToPrompt', () => { - const result = SemanticOverrideSchema.safeParse({ - extraction: { appendToPrompt: '', modelId: 'model-1' }, - }); - expect(result.success).toBe(false); - }); - - it('rejects extraction with missing modelId', () => { - const result = SemanticOverrideSchema.safeParse({ - extraction: { appendToPrompt: 'test' }, - }); - expect(result.success).toBe(false); - }); -}); - -describe('MemoryStrategySchema with semanticOverride', () => { - it('accepts SEMANTIC strategy with extraction override', () => { - const result = MemoryStrategySchema.safeParse({ - type: 'SEMANTIC', - semanticOverride: { - extraction: { appendToPrompt: 'Extract key facts', modelId: 'anthropic.claude-3-sonnet-20240229-v1:0' }, - }, - }); - expect(result.success).toBe(true); - }); - - it('accepts SEMANTIC strategy with both overrides', () => { - const result = MemoryStrategySchema.safeParse({ - type: 'SEMANTIC', - semanticOverride: { - extraction: { appendToPrompt: 'Extract', modelId: 'model-1' }, - consolidation: { appendToPrompt: 'Consolidate', modelId: 'model-2' }, - }, - }); - expect(result.success).toBe(true); - }); - - it('accepts SEMANTIC strategy without override (backward compat)', () => { - const result = MemoryStrategySchema.safeParse({ type: 'SEMANTIC' }); - expect(result.success).toBe(true); - }); - - it('rejects semanticOverride on SUMMARIZATION strategy', () => { - const result = MemoryStrategySchema.safeParse({ - type: 'SUMMARIZATION', - semanticOverride: { - extraction: { appendToPrompt: 'test', modelId: 'model-1' }, - }, - }); - expect(result.success).toBe(false); - if (!result.success) { - expect(result.error.issues.some(i => i.message.includes('SEMANTIC'))).toBe(true); - } - }); - - it('rejects semanticOverride on USER_PREFERENCE strategy', () => { - const result = MemoryStrategySchema.safeParse({ - type: 'USER_PREFERENCE', - semanticOverride: { - extraction: { appendToPrompt: 'test', modelId: 'model-1' }, - }, - }); - expect(result.success).toBe(false); - }); - - it('rejects consolidation-only semanticOverride on USER_PREFERENCE strategy', () => { - const result = MemoryStrategySchema.safeParse({ - type: 'USER_PREFERENCE', - semanticOverride: { - consolidation: { appendToPrompt: 'test', modelId: 'model-1' }, - }, - }); - expect(result.success).toBe(false); - }); - - it('rejects SEMANTIC strategy with empty semanticOverride', () => { - const result = MemoryStrategySchema.safeParse({ - type: 'SEMANTIC', - semanticOverride: {}, - }); - expect(result.success).toBe(false); - }); -}); diff --git a/src/schema/schemas/primitives/index.ts b/src/schema/schemas/primitives/index.ts index fb63f728..0549a2ce 100644 --- a/src/schema/schemas/primitives/index.ts +++ b/src/schema/schemas/primitives/index.ts @@ -1,19 +1,10 @@ -export type { - MemoryStrategy, - MemoryStrategyType, - SemanticOverride, - SemanticExtractionOverride, - SemanticConsolidationOverride, -} from './memory'; +export type { MemoryStrategy, MemoryStrategyType } from './memory'; export { DEFAULT_EPISODIC_REFLECTION_NAMESPACES, DEFAULT_STRATEGY_NAMESPACES, MemoryStrategyNameSchema, MemoryStrategySchema, MemoryStrategyTypeSchema, - SemanticOverrideSchema, - SemanticExtractionOverrideSchema, - SemanticConsolidationOverrideSchema, } from './memory'; export type { diff --git a/src/schema/schemas/primitives/memory.ts b/src/schema/schemas/primitives/memory.ts index af11cf72..ab476cff 100644 --- a/src/schema/schemas/primitives/memory.ts +++ b/src/schema/schemas/primitives/memory.ts @@ -48,54 +48,6 @@ export const MemoryStrategyNameSchema = z 'Must begin with a letter and contain only alphanumeric characters and underscores (max 48 chars)' ); -// ============================================================================ -// Semantic Override Types (CloudFormation SemanticOverride) -// ============================================================================ - -/** - * Configuration for overriding semantic memory extraction behavior. - * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-bedrockagentcore-memory-semanticoverrideextractionconfigurationinput.html - */ -export const SemanticExtractionOverrideSchema = z.object({ - /** Custom prompt to append for memory extraction */ - appendToPrompt: z.string().min(1).max(30000), - /** Bedrock model ID to use for extraction */ - modelId: z.string().min(1), -}); - -export type SemanticExtractionOverride = z.infer; - -/** - * Configuration for overriding semantic memory consolidation behavior. - * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-bedrockagentcore-memory-semanticoverrideconsolidationconfigurationinput.html - */ -export const SemanticConsolidationOverrideSchema = z.object({ - /** Custom prompt to append for memory consolidation */ - appendToPrompt: z.string().min(1).max(30000), - /** Bedrock model ID to use for consolidation */ - modelId: z.string().min(1), -}); - -export type SemanticConsolidationOverride = z.infer; - -/** - * Override configuration for semantic memory strategy. - * At least one of extraction or consolidation must be provided. - * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-bedrockagentcore-memory-semanticoverride.html - */ -export const SemanticOverrideSchema = z - .object({ - /** Override extraction behavior (custom prompt + model) */ - extraction: SemanticExtractionOverrideSchema.optional(), - /** Override consolidation behavior (custom prompt + model) */ - consolidation: SemanticConsolidationOverrideSchema.optional(), - }) - .refine(data => data.extraction !== undefined || data.consolidation !== undefined, { - message: 'At least one of extraction or consolidation must be provided', - }); - -export type SemanticOverride = z.infer; - /** * Memory strategy configuration. * Each memory can have multiple strategies with optional namespace scoping. @@ -112,8 +64,6 @@ export const MemoryStrategySchema = z namespaces: z.array(z.string()).optional(), /** Reflection namespaces for EPISODIC strategy. Required by the service for episodic strategies. */ reflectionNamespaces: z.array(z.string()).optional(), - /** Only valid when type is 'SEMANTIC'. Override extraction and/or consolidation behavior. */ - semanticOverride: SemanticOverrideSchema.optional(), }) .refine( strategy => @@ -133,10 +83,6 @@ export const MemoryStrategySchema = z message: 'Each reflectionNamespace must be a prefix of at least one namespace', path: ['reflectionNamespaces'], } - ) - .refine(strategy => strategy.semanticOverride === undefined || strategy.type === 'SEMANTIC', { - message: 'semanticOverride is only valid for SEMANTIC strategy type', - path: ['semanticOverride'], - }); + ); export type MemoryStrategy = z.infer; From 62a88b6f2f96d80b8805dc5805b9fa7b3f228b6c Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Fri, 27 Mar 2026 17:30:47 -0400 Subject: [PATCH 2/3] Revert "feat(memory): add CUSTOM strategy type to agentcore-cli (#677) (#694)" This reverts commit beac707fca248729d370a22d4b2265553c2a6da0. --- docs/commands.md | 12 +- docs/configuration.md | 12 +- docs/memory.md | 43 +---- .../assets.snapshot.test.ts.snap | 12 +- src/assets/agents/AGENTS.md | 2 +- .../strands/capabilities/memory/session.py | 5 - .../strands/capabilities/memory/session.py | 5 - .../commands/add/__tests__/add-memory.test.ts | 13 +- .../commands/add/__tests__/validate.test.ts | 12 +- src/cli/commands/add/validate.ts | 9 +- src/cli/commands/create/action.ts | 2 +- src/cli/commands/create/command.tsx | 4 +- src/cli/commands/create/validate.ts | 6 +- .../generate/__tests__/schema-mapper.test.ts | 170 ------------------ src/cli/operations/agent/generate/index.ts | 1 - .../agent/generate/schema-mapper.ts | 34 +--- .../agent/generate/write-agent-to-project.ts | 5 +- src/cli/primitives/AgentPrimitive.tsx | 9 +- src/cli/primitives/MemoryPrimitive.tsx | 9 +- src/cli/tui/screens/agent/useAddAgent.ts | 4 +- .../tui/screens/generate/GenerateWizardUI.tsx | 2 - src/cli/tui/screens/generate/types.ts | 3 +- src/cli/tui/screens/memory/types.ts | 1 - src/schema/llm-compacted/agentcore.ts | 5 +- .../primitives/__tests__/memory.test.ts | 37 ++-- src/schema/schemas/primitives/memory.ts | 3 +- 26 files changed, 69 insertions(+), 351 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index 3a617b4a..851370d0 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -225,12 +225,12 @@ agentcore add memory \ --expiry 30 ``` -| Flag | Description | -| ---------------------- | ------------------------------------------------------------------------------------- | -| `--name ` | Memory name | -| `--strategies ` | Comma-separated: `SEMANTIC`, `SUMMARIZATION`, `USER_PREFERENCE`, `EPISODIC`, `CUSTOM` | -| `--expiry ` | Event expiry duration in days (default: 30, min: 7, max: 365) | -| `--json` | JSON output | +| Flag | Description | +| ---------------------- | --------------------------------------------------------------------------- | +| `--name ` | Memory name | +| `--strategies ` | Comma-separated: `SEMANTIC`, `SUMMARIZATION`, `USER_PREFERENCE`, `EPISODIC` | +| `--expiry ` | Event expiry duration in days (default: 30, min: 7, max: 365) | +| `--json` | JSON output | ### add gateway diff --git a/docs/configuration.md b/docs/configuration.md index 3c4194a6..6e66c895 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -239,13 +239,11 @@ on the next deployment. ### Memory Strategies -| Strategy | Description | -| ----------------- | ----------------------------------------------------------- | -| `SEMANTIC` | Vector-based similarity search for relevant context | -| `SUMMARIZATION` | Compressed conversation history | -| `USER_PREFERENCE` | Store user-specific preferences and settings | -| `EPISODIC` | Capture and reflect on meaningful interaction episodes | -| `CUSTOM` | Self-managed strategy with user-controlled extraction logic | +| Strategy | Description | +| ----------------- | --------------------------------------------------- | +| `SEMANTIC` | Vector-based similarity search for relevant context | +| `SUMMARIZATION` | Compressed conversation history | +| `USER_PREFERENCE` | Store user-specific preferences and settings | Strategy configuration: diff --git a/docs/memory.md b/docs/memory.md index 615de94b..0a1195b8 100644 --- a/docs/memory.md +++ b/docs/memory.md @@ -168,13 +168,12 @@ conversations, enabling cross-session recall via semantic search. ## Memory Strategies -| Strategy | Description | -| ----------------- | ----------------------------------------------------------- | -| `SEMANTIC` | Vector-based similarity search for relevant context | -| `SUMMARIZATION` | Compressed conversation history | -| `USER_PREFERENCE` | Store user-specific preferences and settings | -| `EPISODIC` | Capture and reflect on meaningful interaction episodes | -| `CUSTOM` | Self-managed strategy with user-controlled extraction logic | +| Strategy | Description | +| ----------------- | ------------------------------------------------------ | +| `SEMANTIC` | Vector-based similarity search for relevant context | +| `SUMMARIZATION` | Compressed conversation history | +| `USER_PREFERENCE` | Store user-specific preferences and settings | +| `EPISODIC` | Capture and reflect on meaningful interaction episodes | You can combine multiple strategies: @@ -189,36 +188,6 @@ You can combine multiple strategies: } ``` -### Self-Managed (Custom) Strategy - -The `CUSTOM` strategy lets you control memory extraction logic externally rather than relying on built-in -implementations. This is useful when you need specialized extraction pipelines or want to integrate with your own -processing infrastructure. - -**Prerequisites:** CUSTOM strategies require user-managed extraction logic and are not functional without it. You must -implement your own extraction mechanism (e.g., via AWS Lambda). - -**Key characteristics:** - -- No default namespaces are assigned — you provide your own or omit them -- Each memory supports at most one CUSTOM strategy -- You are responsible for implementing the extraction logic that processes memory events - -```json -{ - "type": "AgentCoreMemory", - "name": "MyMemory", - "eventExpiryDuration": 30, - "strategies": [ - { - "type": "CUSTOM", - "name": "my_custom_strategy", - "description": "Custom extraction logic" - } - ] -} -``` - ### Strategy Options Each strategy can have optional configuration: diff --git a/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap b/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap index 2aaf157e..793de2f3 100644 --- a/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +++ b/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap @@ -1696,11 +1696,6 @@ def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[Agent {{/if}} {{#if (includes memoryProviders.[0].strategies "SUMMARIZATION")}} f"/summaries/{actor_id}/{session_id}": RetrievalConfig(top_k=3, relevance_score=0.5), -{{/if}} -{{#if (includes memoryProviders.[0].strategies "CUSTOM")}} - # TODO: Add your custom namespace and retrieval config. - # Custom strategies use user-controlled extraction logic. - # Example: f"/custom/{actor_id}/data": RetrievalConfig(top_k=3, relevance_score=0.5), {{/if}} } {{/if}} @@ -3662,11 +3657,6 @@ def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[Agent {{/if}} {{#if (includes memoryProviders.[0].strategies "SUMMARIZATION")}} f"/summaries/{actor_id}/{session_id}": RetrievalConfig(top_k=3, relevance_score=0.5), -{{/if}} -{{#if (includes memoryProviders.[0].strategies "CUSTOM")}} - # TODO: Add your custom namespace and retrieval config. - # Custom strategies use user-controlled extraction logic. - # Example: f"/custom/{actor_id}/data": RetrievalConfig(top_k=3, relevance_score=0.5), {{/if}} } {{/if}} @@ -4010,7 +4000,7 @@ file maps to a JSON config file and includes validation constraints as comments. - **BuildType**: \`'CodeZip'\` | \`'Container'\` - **NetworkMode**: \`'PUBLIC'\` - **RuntimeVersion**: \`'PYTHON_3_10'\` | \`'PYTHON_3_11'\` | \`'PYTHON_3_12'\` | \`'PYTHON_3_13'\` -- **MemoryStrategyType**: \`'SEMANTIC'\` | \`'SUMMARIZATION'\` | \`'USER_PREFERENCE'\` | \`'EPISODIC'\` | \`'CUSTOM'\` +- **MemoryStrategyType**: \`'SEMANTIC'\` | \`'SUMMARIZATION'\` | \`'USER_PREFERENCE'\` | \`'EPISODIC'\` ### Build Types diff --git a/src/assets/agents/AGENTS.md b/src/assets/agents/AGENTS.md index 86351f3f..10c5b45b 100644 --- a/src/assets/agents/AGENTS.md +++ b/src/assets/agents/AGENTS.md @@ -63,7 +63,7 @@ file maps to a JSON config file and includes validation constraints as comments. - **BuildType**: `'CodeZip'` | `'Container'` - **NetworkMode**: `'PUBLIC'` - **RuntimeVersion**: `'PYTHON_3_10'` | `'PYTHON_3_11'` | `'PYTHON_3_12'` | `'PYTHON_3_13'` -- **MemoryStrategyType**: `'SEMANTIC'` | `'SUMMARIZATION'` | `'USER_PREFERENCE'` | `'EPISODIC'` | `'CUSTOM'` +- **MemoryStrategyType**: `'SEMANTIC'` | `'SUMMARIZATION'` | `'USER_PREFERENCE'` | `'EPISODIC'` ### Build Types diff --git a/src/assets/python/a2a/strands/capabilities/memory/session.py b/src/assets/python/a2a/strands/capabilities/memory/session.py index c95cf40f..9661243b 100644 --- a/src/assets/python/a2a/strands/capabilities/memory/session.py +++ b/src/assets/python/a2a/strands/capabilities/memory/session.py @@ -21,11 +21,6 @@ def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[Agent {{/if}} {{#if (includes memoryProviders.[0].strategies "SUMMARIZATION")}} f"/summaries/{actor_id}/{session_id}": RetrievalConfig(top_k=3, relevance_score=0.5), -{{/if}} -{{#if (includes memoryProviders.[0].strategies "CUSTOM")}} - # TODO: Add your custom namespace and retrieval config. - # Custom strategies use user-controlled extraction logic. - # Example: f"/custom/{actor_id}/data": RetrievalConfig(top_k=3, relevance_score=0.5), {{/if}} } {{/if}} diff --git a/src/assets/python/http/strands/capabilities/memory/session.py b/src/assets/python/http/strands/capabilities/memory/session.py index afebc29c..dc0cb7bf 100644 --- a/src/assets/python/http/strands/capabilities/memory/session.py +++ b/src/assets/python/http/strands/capabilities/memory/session.py @@ -21,11 +21,6 @@ def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[Agent {{/if}} {{#if (includes memoryProviders.[0].strategies "SUMMARIZATION")}} f"/summaries/{actor_id}/{session_id}": RetrievalConfig(top_k=3, relevance_score=0.5), -{{/if}} -{{#if (includes memoryProviders.[0].strategies "CUSTOM")}} - # TODO: Add your custom namespace and retrieval config. - # Custom strategies use user-controlled extraction logic. - # Example: f"/custom/{actor_id}/data": RetrievalConfig(top_k=3, relevance_score=0.5), {{/if}} } {{/if}} diff --git a/src/cli/commands/add/__tests__/add-memory.test.ts b/src/cli/commands/add/__tests__/add-memory.test.ts index 7cbab67f..3a518f79 100644 --- a/src/cli/commands/add/__tests__/add-memory.test.ts +++ b/src/cli/commands/add/__tests__/add-memory.test.ts @@ -51,17 +51,16 @@ describe('add memory command', () => { expect(json.error.includes('INVALID'), `Error: ${json.error}`).toBeTruthy(); }); - // Issue #677: CUSTOM strategy is now supported - it('creates memory with CUSTOM strategy', async () => { - const memoryName = `memCustom${Date.now()}`; + // Issue #235: CUSTOM strategy has been removed + it('rejects CUSTOM strategy', async () => { const result = await runCLI( - ['add', 'memory', '--name', memoryName, '--strategies', 'CUSTOM', '--json'], + ['add', 'memory', '--name', 'testCustom', '--strategies', 'CUSTOM', '--json'], projectDir ); - expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0); + expect(result.exitCode).toBe(1); const json = JSON.parse(result.stdout); - expect(json.success).toBe(true); - expect(json.memoryName).toBe(memoryName); + expect(json.success).toBe(false); + expect(json.error.includes('CUSTOM'), `Error: ${json.error}`).toBeTruthy(); }); }); diff --git a/src/cli/commands/add/__tests__/validate.test.ts b/src/cli/commands/add/__tests__/validate.test.ts index 68c5c098..6c73adb3 100644 --- a/src/cli/commands/add/__tests__/validate.test.ts +++ b/src/cli/commands/add/__tests__/validate.test.ts @@ -953,15 +953,17 @@ describe('validate', () => { ).toEqual({ valid: true }); }); - // Issue #677: CUSTOM strategy is now supported - it('accepts CUSTOM strategy', () => { + // AC23: CUSTOM strategy is not supported (Issue #235) + it('rejects CUSTOM strategy', () => { const result = validateAddMemoryOptions({ ...validMemoryOptions, strategies: 'CUSTOM' }); - expect(result.valid).toBe(true); + expect(result.valid).toBe(false); + expect(result.error).toContain('Invalid strategy: CUSTOM'); }); - it('accepts CUSTOM mixed with other strategies', () => { + it('rejects CUSTOM even when mixed with valid strategies', () => { const result = validateAddMemoryOptions({ ...validMemoryOptions, strategies: 'SEMANTIC,CUSTOM' }); - expect(result.valid).toBe(true); + expect(result.valid).toBe(false); + expect(result.error).toContain('Invalid strategy: CUSTOM'); }); // AC24: Each individual valid strategy should pass diff --git a/src/cli/commands/add/validate.ts b/src/cli/commands/add/validate.ts index 1390ba56..44a01016 100644 --- a/src/cli/commands/add/validate.ts +++ b/src/cli/commands/add/validate.ts @@ -4,7 +4,6 @@ import { BuildTypeSchema, GatewayExceptionLevelSchema, GatewayNameSchema, - MemoryStrategyTypeSchema, ModelProviderSchema, ProtocolModeSchema, RuntimeAuthorizerTypeSchema, @@ -34,8 +33,8 @@ export interface ValidationResult { } // Constants -const MEMORY_OPTIONS = ['none', 'shortTerm', 'longAndShortTerm', 'custom'] as const; -const VALID_STRATEGIES: readonly string[] = MemoryStrategyTypeSchema.options; +const MEMORY_OPTIONS = ['none', 'shortTerm', 'longAndShortTerm'] as const; +const VALID_STRATEGIES = ['SEMANTIC', 'SUMMARIZATION', 'USER_PREFERENCE', 'EPISODIC']; /** * Validate that a credential name exists in the project spec. @@ -135,7 +134,7 @@ export function validateAddAgentOptions(options: AddAgentOptions): ValidationRes if (!MEMORY_OPTIONS.includes(options.memory as (typeof MEMORY_OPTIONS)[number])) { return { valid: false, - error: `Invalid memory option: ${options.memory}. Use none, shortTerm, longAndShortTerm, or custom`, + error: `Invalid memory option: ${options.memory}. Use none, shortTerm, or longAndShortTerm`, }; } // Parse and validate lifecycle configuration for import path @@ -243,7 +242,7 @@ export function validateAddAgentOptions(options: AddAgentOptions): ValidationRes if (!MEMORY_OPTIONS.includes(options.memory as (typeof MEMORY_OPTIONS)[number])) { return { valid: false, - error: `Invalid memory option: ${options.memory}. Use none, shortTerm, longAndShortTerm, or custom`, + error: `Invalid memory option: ${options.memory}. Use none, shortTerm, or longAndShortTerm`, }; } } diff --git a/src/cli/commands/create/action.ts b/src/cli/commands/create/action.ts index 173856c5..b1d17f47 100644 --- a/src/cli/commands/create/action.ts +++ b/src/cli/commands/create/action.ts @@ -102,7 +102,7 @@ export async function createProject(options: CreateProjectOptions): Promise { framework: options.framework as SDKFramework | undefined, modelProvider: options.modelProvider as ModelProvider | undefined, apiKey: options.apiKey, - memory: (options.memory as 'none' | 'shortTerm' | 'longAndShortTerm' | 'custom') ?? 'none', + memory: (options.memory as 'none' | 'shortTerm' | 'longAndShortTerm') ?? 'none', protocol: options.protocol as ProtocolMode | undefined, agentId: options.agentId, agentAliasId: options.agentAliasId, @@ -170,7 +170,7 @@ export const registerCreate = (program: Command) => { ) .option('--model-provider ', 'Model provider (Bedrock, Anthropic, OpenAI, Gemini) [non-interactive]') .option('--api-key ', 'API key for non-Bedrock providers [non-interactive]') - .option('--memory