Skip to content

Commit 2d8b9d7

Browse files
authored
Revert "feat: add support for LTM metadata (#1281)" (#1338)
This reverts commit 44b5c2c.
1 parent ae1b932 commit 2d8b9d7

17 files changed

Lines changed: 266 additions & 880 deletions

File tree

docs/memory.md

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -210,43 +210,6 @@ Each strategy can have optional configuration:
210210
| `namespaces` | No | **Deprecated alias for `namespaceTemplates`.** Accepted for backward compatibility. |
211211
| `reflectionNamespaces` | EPISODIC only | **Deprecated alias for `reflectionNamespaceTemplates`.** Accepted for backward compatibility. |
212212

213-
## Indexed Metadata Keys
214-
215-
Indexed keys declare metadata fields on a memory that can be used to filter long-term memory records on retrieval. Up to
216-
10 keys per memory.
217-
218-
```bash
219-
agentcore add memory \
220-
--name SupportMemory \
221-
--strategies SEMANTIC \
222-
--indexed-key priority:NUMBER \
223-
--indexed-key agent_type:STRING \
224-
--indexed-key tags:STRINGLIST
225-
```
226-
227-
In `agentcore.json`:
228-
229-
```json
230-
{
231-
"name": "SupportMemory",
232-
"strategies": [{ "type": "SEMANTIC" }],
233-
"indexedKeys": [
234-
{ "key": "priority", "type": "NUMBER" },
235-
{ "key": "agent_type", "type": "STRING" },
236-
{ "key": "tags", "type": "STRINGLIST" }
237-
]
238-
}
239-
```
240-
241-
| Type | Description |
242-
| ------------ | --------------------- |
243-
| `STRING` | Single string value |
244-
| `STRINGLIST` | List of string values |
245-
| `NUMBER` | Numeric value |
246-
247-
Indexed keys require at least one long-term memory strategy. They can only be added to an existing memory — once
248-
declared, an indexed key cannot be removed.
249-
250213
## Event Expiry
251214

252215
Memory events expire after a configurable duration (7-365 days, default 30):

npm-shrinkwrap.json

Lines changed: 215 additions & 181 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
"@aws-sdk/client-bedrock": "^3.1012.0",
8080
"@aws-sdk/client-bedrock-agent": "^3.1012.0",
8181
"@aws-sdk/client-bedrock-agentcore": "^3.1020.0",
82-
"@aws-sdk/client-bedrock-agentcore-control": "^3.1048.0",
82+
"@aws-sdk/client-bedrock-agentcore-control": "^3.1039.0",
8383
"@aws-sdk/client-bedrock-runtime": "^3.893.0",
8484
"@aws-sdk/client-cloudformation": "^3.893.0",
8585
"@aws-sdk/client-cloudwatch-logs": "^3.893.0",

src/cli/aws/agentcore-control.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,6 @@ export interface MemoryDetail {
371371
namespaceTemplates?: string[];
372372
reflectionNamespaceTemplates?: string[];
373373
}[];
374-
indexedKeys?: { key: string; type: string }[];
375374
tags?: Record<string, string>;
376375
encryptionKeyArn?: string;
377376
executionRoleArn?: string;
@@ -409,14 +408,6 @@ export async function getMemoryDetail(options: GetMemoryOptions): Promise<Memory
409408

410409
const tags = await fetchTags(client, memory.arn, 'memory');
411410

412-
const indexedKeys = memory.indexedKeys?.flatMap(k => {
413-
if (!k.key || !k.type) {
414-
console.warn(`Warning: Skipping malformed indexed key from API response: ${JSON.stringify(k)}`);
415-
return [];
416-
}
417-
return [{ key: k.key, type: k.type }];
418-
});
419-
420411
return {
421412
memoryId: memory.id,
422413
memoryArn: memory.arn,
@@ -427,7 +418,6 @@ export async function getMemoryDetail(options: GetMemoryOptions): Promise<Memory
427418
tags,
428419
encryptionKeyArn: memory.encryptionKeyArn,
429420
executionRoleArn: memory.memoryExecutionRoleArn,
430-
...(indexedKeys && indexedKeys.length > 0 && { indexedKeys }),
431421
strategies: (memory.strategies ?? []).map(s => {
432422
if (!s.type) {
433423
throw new Error(`Memory ${options.memoryId} has a strategy with missing required field: type`);

src/cli/aws/policy-generation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
StartPolicyGenerationCommand,
77
waitUntilPolicyGenerationCompleted,
88
} from '@aws-sdk/client-bedrock-agentcore-control';
9-
import { WaiterState } from '@smithy/core/client';
9+
import { WaiterState } from '@smithy/util-waiter';
1010

1111
export interface StartPolicyGenerationOptions {
1212
policyEngineId: string;

src/cli/commands/add/__tests__/validate.test.ts

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,118 +1126,6 @@ describe('validate', () => {
11261126
expect(result.valid).toBe(false);
11271127
expect(result.error).toContain('does not match the expected schema');
11281128
});
1129-
1130-
// Indexed keys: requires LTM strategy
1131-
it('rejects --indexed-key without any LTM strategy', () => {
1132-
const result = validateAddMemoryOptions({
1133-
...validMemoryOptions,
1134-
strategies: undefined,
1135-
indexedKey: ['priority:NUMBER'],
1136-
});
1137-
expect(result.valid).toBe(false);
1138-
expect(result.error).toContain('requires at least one long-term memory strategy');
1139-
});
1140-
1141-
it('accepts --indexed-key with an LTM strategy', () => {
1142-
expect(
1143-
validateAddMemoryOptions({
1144-
...validMemoryOptions,
1145-
strategies: 'SEMANTIC',
1146-
indexedKey: ['priority:NUMBER'],
1147-
})
1148-
).toEqual({ valid: true });
1149-
});
1150-
1151-
it('rejects more than 10 indexed keys', () => {
1152-
const eleven = Array.from({ length: 11 }, (_, i) => `k${i}:STRING`);
1153-
const result = validateAddMemoryOptions({
1154-
...validMemoryOptions,
1155-
strategies: 'SEMANTIC',
1156-
indexedKey: eleven,
1157-
});
1158-
expect(result.valid).toBe(false);
1159-
expect(result.error).toContain('Maximum 10 indexed keys');
1160-
});
1161-
1162-
it('accepts exactly 10 indexed keys (boundary)', () => {
1163-
const ten = Array.from({ length: 10 }, (_, i) => `k${i}:STRING`);
1164-
expect(validateAddMemoryOptions({ ...validMemoryOptions, strategies: 'SEMANTIC', indexedKey: ten })).toEqual({
1165-
valid: true,
1166-
});
1167-
});
1168-
1169-
it('rejects an empty key (":STRING")', () => {
1170-
const result = validateAddMemoryOptions({
1171-
...validMemoryOptions,
1172-
strategies: 'SEMANTIC',
1173-
indexedKey: [':STRING'],
1174-
});
1175-
expect(result.valid).toBe(false);
1176-
expect(result.error).toContain('Key name cannot be empty');
1177-
});
1178-
1179-
it('rejects a key longer than 128 characters', () => {
1180-
const longKey = 'a'.repeat(129);
1181-
const result = validateAddMemoryOptions({
1182-
...validMemoryOptions,
1183-
strategies: 'SEMANTIC',
1184-
indexedKey: [`${longKey}:STRING`],
1185-
});
1186-
expect(result.valid).toBe(false);
1187-
expect(result.error).toContain('exceeds maximum length');
1188-
});
1189-
1190-
it('rejects an invalid type token', () => {
1191-
const result = validateAddMemoryOptions({
1192-
...validMemoryOptions,
1193-
strategies: 'SEMANTIC',
1194-
indexedKey: ['priority:INTEGER'],
1195-
});
1196-
expect(result.valid).toBe(false);
1197-
expect(result.error).toContain('Invalid type');
1198-
});
1199-
1200-
it('rejects duplicate keys', () => {
1201-
const result = validateAddMemoryOptions({
1202-
...validMemoryOptions,
1203-
strategies: 'SEMANTIC',
1204-
indexedKey: ['priority:NUMBER', 'priority:STRING'],
1205-
});
1206-
expect(result.valid).toBe(false);
1207-
expect(result.error).toContain('Duplicate indexed key');
1208-
});
1209-
1210-
it('rejects whitespace-only key', () => {
1211-
const result = validateAddMemoryOptions({
1212-
...validMemoryOptions,
1213-
strategies: 'SEMANTIC',
1214-
indexedKey: [' :STRING'],
1215-
});
1216-
expect(result.valid).toBe(false);
1217-
expect(result.error).toContain('whitespace');
1218-
});
1219-
1220-
it('rejects malformed entry without colon', () => {
1221-
const result = validateAddMemoryOptions({
1222-
...validMemoryOptions,
1223-
strategies: 'SEMANTIC',
1224-
indexedKey: ['priority'],
1225-
});
1226-
expect(result.valid).toBe(false);
1227-
expect(result.error).toContain('Expected key:TYPE');
1228-
});
1229-
1230-
it.each([
1231-
['user.email:STRING'],
1232-
['tag/v2:STRINGLIST'],
1233-
['kebab-case:STRING'],
1234-
['x-custom:STRING'],
1235-
['has:colons:in:key:NUMBER'],
1236-
])('accepts punctuation-rich key %s', raw => {
1237-
expect(validateAddMemoryOptions({ ...validMemoryOptions, strategies: 'SEMANTIC', indexedKey: [raw] })).toEqual({
1238-
valid: true,
1239-
});
1240-
});
12411129
});
12421130

12431131
describe('validateAddCredentialOptions', () => {

src/cli/commands/add/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ export interface AddMemoryOptions {
9696
dataStreamArn?: string;
9797
contentLevel?: string;
9898
streamDeliveryResources?: string;
99-
indexedKey?: string[];
10099
json?: boolean;
101100
}
102101

src/cli/commands/add/validate.ts

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {
1919
} from '../../../schema';
2020
import { ARN_VALIDATION_MESSAGE, isValidArn } from '../shared/arn-utils';
2121
import { validateHeaderAllowlist } from '../shared/header-utils';
22-
import { MAX_INDEXED_KEYS, parseIndexedKeyArg } from '../shared/indexed-key-parser';
2322
import { parseAndValidateLifecycleOptions } from '../shared/lifecycle-utils';
2423
import { validateVpcOptions } from '../shared/vpc-utils';
2524
import { validateJwtAuthorizerOptions } from './auth-options';
@@ -727,37 +726,6 @@ export function validateAddMemoryOptions(options: AddMemoryOptions): ValidationR
727726
}
728727
}
729728

730-
if (options.indexedKey && options.indexedKey.length > 0) {
731-
const ltmStrategies = (options.strategies ?? '')
732-
.split(',')
733-
.map(s => s.trim().toUpperCase())
734-
.filter(Boolean);
735-
if (ltmStrategies.length === 0) {
736-
return {
737-
valid: false,
738-
error:
739-
'--indexed-key requires at least one long-term memory strategy (--strategies). Indexed keys filter long-term memory records on retrieval.',
740-
};
741-
}
742-
743-
if (options.indexedKey.length > MAX_INDEXED_KEYS) {
744-
return { valid: false, error: `Maximum ${MAX_INDEXED_KEYS} indexed keys allowed` };
745-
}
746-
747-
const seenKeys = new Set<string>();
748-
for (const raw of options.indexedKey) {
749-
const result = parseIndexedKeyArg(raw);
750-
if (!result.ok) {
751-
return { valid: false, error: result.error };
752-
}
753-
const { key } = result.value;
754-
if (seenKeys.has(key)) {
755-
return { valid: false, error: `Duplicate indexed key: "${key}"` };
756-
}
757-
seenKeys.add(key);
758-
}
759-
}
760-
761729
if (options.streamDeliveryResources && (options.dataStreamArn || options.contentLevel || options.deliveryType)) {
762730
return {
763731
valid: false,

src/cli/commands/import/import-memory.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { Memory } from '../../../schema';
2-
import { IndexedKeyTypeSchema } from '../../../schema';
32
import type { MemoryDetail, MemorySummary } from '../../aws/agentcore-control';
43
import { getMemoryDetail, listAllMemories } from '../../aws/agentcore-control';
54
import { withCommandRunTelemetry } from '../../telemetry/cli-command-run.js';
@@ -57,26 +56,10 @@ function toMemorySpec(memory: MemoryDetail, localName: string): Memory {
5756
};
5857
});
5958

60-
// Validate each indexed key's type against our enum. Drop
61-
// entries whose type is not one we recognize with a warning
62-
const indexedKeys: Memory['indexedKeys'] = memory.indexedKeys
63-
?.flatMap(k => {
64-
const parsedType = IndexedKeyTypeSchema.safeParse(k.type);
65-
if (!parsedType.success) {
66-
console.warn(
67-
`${ANSI.yellow}[warn]${ANSI.reset} Skipping indexed key "${k.key}" with unrecognised type "${k.type}".`
68-
);
69-
return [];
70-
}
71-
return [{ key: k.key, type: parsedType.data }];
72-
})
73-
.filter(Boolean);
74-
7559
return {
7660
name: localName,
7761
eventExpiryDuration: Math.max(3, Math.min(365, memory.eventExpiryDuration)),
7862
strategies,
79-
...(indexedKeys && indexedKeys.length > 0 && { indexedKeys }),
8063
...(memory.tags && Object.keys(memory.tags).length > 0 && { tags: memory.tags }),
8164
...(memory.encryptionKeyArn && { encryptionKeyArn: memory.encryptionKeyArn }),
8265
...(memory.executionRoleArn && { executionRoleArn: memory.executionRoleArn }),

src/cli/commands/shared/indexed-key-parser.ts

Lines changed: 0 additions & 86 deletions
This file was deleted.

0 commit comments

Comments
 (0)