agentfootprint 7.13.0 → 7.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/adapters/hosting/agentcore.js +350 -0
  2. package/dist/adapters/hosting/agentcore.js.map +1 -0
  3. package/dist/adapters/memory/agentcore.js +125 -1
  4. package/dist/adapters/memory/agentcore.js.map +1 -1
  5. package/dist/adapters/security/agentcore.js +0 -0
  6. package/dist/adapters/security/agentcore.js.map +1 -0
  7. package/dist/core/Agent.js +79 -2
  8. package/dist/core/Agent.js.map +1 -1
  9. package/dist/esm/adapters/hosting/agentcore.d.ts +199 -0
  10. package/dist/esm/adapters/hosting/agentcore.js +321 -0
  11. package/dist/esm/adapters/hosting/agentcore.js.map +1 -0
  12. package/dist/esm/adapters/memory/agentcore.d.ts +88 -2
  13. package/dist/esm/adapters/memory/agentcore.js +125 -1
  14. package/dist/esm/adapters/memory/agentcore.js.map +1 -1
  15. package/dist/esm/adapters/security/agentcore.d.ts +157 -0
  16. package/dist/esm/adapters/security/agentcore.js +0 -0
  17. package/dist/esm/adapters/security/agentcore.js.map +1 -0
  18. package/dist/esm/core/Agent.d.ts +47 -0
  19. package/dist/esm/core/Agent.js +79 -2
  20. package/dist/esm/core/Agent.js.map +1 -1
  21. package/dist/esm/hosting/envelope.d.ts +33 -0
  22. package/dist/esm/hosting/envelope.js +49 -0
  23. package/dist/esm/hosting/envelope.js.map +1 -0
  24. package/dist/esm/hosting/errors.d.ts +78 -0
  25. package/dist/esm/hosting/errors.js +119 -0
  26. package/dist/esm/hosting/errors.js.map +1 -0
  27. package/dist/esm/hosting/httpHost.d.ts +121 -0
  28. package/dist/esm/hosting/httpHost.js +248 -0
  29. package/dist/esm/hosting/httpHost.js.map +1 -0
  30. package/dist/esm/hosting/index.d.ts +60 -0
  31. package/dist/esm/hosting/index.js +58 -0
  32. package/dist/esm/hosting/index.js.map +1 -0
  33. package/dist/esm/hosting/memorySessions.d.ts +22 -0
  34. package/dist/esm/hosting/memorySessions.js +31 -0
  35. package/dist/esm/hosting/memorySessions.js.map +1 -0
  36. package/dist/esm/hosting/nodeHost.d.ts +71 -0
  37. package/dist/esm/hosting/nodeHost.js +78 -0
  38. package/dist/esm/hosting/nodeHost.js.map +1 -0
  39. package/dist/esm/hosting/standingAgent.d.ts +62 -0
  40. package/dist/esm/hosting/standingAgent.js +192 -0
  41. package/dist/esm/hosting/standingAgent.js.map +1 -0
  42. package/dist/esm/hosting/types.d.ts +206 -0
  43. package/dist/esm/hosting/types.js +21 -0
  44. package/dist/esm/hosting/types.js.map +1 -0
  45. package/dist/esm/hosting-providers.d.ts +50 -0
  46. package/dist/esm/hosting-providers.js +50 -0
  47. package/dist/esm/hosting-providers.js.map +1 -0
  48. package/dist/esm/lib/mcp/gatewayTransport.d.ts +103 -0
  49. package/dist/esm/lib/mcp/gatewayTransport.js +123 -0
  50. package/dist/esm/lib/mcp/gatewayTransport.js.map +1 -0
  51. package/dist/esm/lib/mcp/index.d.ts +2 -1
  52. package/dist/esm/lib/mcp/index.js +1 -0
  53. package/dist/esm/lib/mcp/index.js.map +1 -1
  54. package/dist/esm/lib/mcp/mcpClient.js +10 -2
  55. package/dist/esm/lib/mcp/mcpClient.js.map +1 -1
  56. package/dist/esm/lib/mcp/types.d.ts +45 -1
  57. package/dist/esm/memory/store/types.d.ts +22 -0
  58. package/dist/esm/memory-providers.d.ts +1 -1
  59. package/dist/esm/memory-providers.js.map +1 -1
  60. package/dist/esm/security/index.d.ts +10 -1
  61. package/dist/esm/security/index.js +14 -1
  62. package/dist/esm/security/index.js.map +1 -1
  63. package/dist/esm/tool-providers/index.d.ts +6 -2
  64. package/dist/esm/tool-providers/index.js +5 -1
  65. package/dist/esm/tool-providers/index.js.map +1 -1
  66. package/dist/hosting/envelope.js +54 -0
  67. package/dist/hosting/envelope.js.map +1 -0
  68. package/dist/hosting/errors.js +126 -0
  69. package/dist/hosting/errors.js.map +1 -0
  70. package/dist/hosting/httpHost.js +276 -0
  71. package/dist/hosting/httpHost.js.map +1 -0
  72. package/dist/hosting/index.js +73 -0
  73. package/dist/hosting/index.js.map +1 -0
  74. package/dist/hosting/memorySessions.js +35 -0
  75. package/dist/hosting/memorySessions.js.map +1 -0
  76. package/dist/hosting/nodeHost.js +82 -0
  77. package/dist/hosting/nodeHost.js.map +1 -0
  78. package/dist/hosting/standingAgent.js +196 -0
  79. package/dist/hosting/standingAgent.js.map +1 -0
  80. package/dist/hosting/types.js +22 -0
  81. package/dist/hosting/types.js.map +1 -0
  82. package/dist/hosting-providers.js +57 -0
  83. package/dist/hosting-providers.js.map +1 -0
  84. package/dist/lib/mcp/gatewayTransport.js +129 -0
  85. package/dist/lib/mcp/gatewayTransport.js.map +1 -0
  86. package/dist/lib/mcp/index.js +4 -1
  87. package/dist/lib/mcp/index.js.map +1 -1
  88. package/dist/lib/mcp/mcpClient.js +10 -2
  89. package/dist/lib/mcp/mcpClient.js.map +1 -1
  90. package/dist/memory-providers.js.map +1 -1
  91. package/dist/security/index.js +16 -2
  92. package/dist/security/index.js.map +1 -1
  93. package/dist/tool-providers/index.js +7 -1
  94. package/dist/tool-providers/index.js.map +1 -1
  95. package/dist/types/adapters/hosting/agentcore.d.ts +200 -0
  96. package/dist/types/adapters/hosting/agentcore.d.ts.map +1 -0
  97. package/dist/types/adapters/memory/agentcore.d.ts +88 -2
  98. package/dist/types/adapters/memory/agentcore.d.ts.map +1 -1
  99. package/dist/types/adapters/security/agentcore.d.ts +158 -0
  100. package/dist/types/adapters/security/agentcore.d.ts.map +1 -0
  101. package/dist/types/core/Agent.d.ts +47 -0
  102. package/dist/types/core/Agent.d.ts.map +1 -1
  103. package/dist/types/hosting/envelope.d.ts +34 -0
  104. package/dist/types/hosting/envelope.d.ts.map +1 -0
  105. package/dist/types/hosting/errors.d.ts +79 -0
  106. package/dist/types/hosting/errors.d.ts.map +1 -0
  107. package/dist/types/hosting/httpHost.d.ts +122 -0
  108. package/dist/types/hosting/httpHost.d.ts.map +1 -0
  109. package/dist/types/hosting/index.d.ts +61 -0
  110. package/dist/types/hosting/index.d.ts.map +1 -0
  111. package/dist/types/hosting/memorySessions.d.ts +23 -0
  112. package/dist/types/hosting/memorySessions.d.ts.map +1 -0
  113. package/dist/types/hosting/nodeHost.d.ts +72 -0
  114. package/dist/types/hosting/nodeHost.d.ts.map +1 -0
  115. package/dist/types/hosting/standingAgent.d.ts +63 -0
  116. package/dist/types/hosting/standingAgent.d.ts.map +1 -0
  117. package/dist/types/hosting/types.d.ts +207 -0
  118. package/dist/types/hosting/types.d.ts.map +1 -0
  119. package/dist/types/hosting-providers.d.ts +51 -0
  120. package/dist/types/hosting-providers.d.ts.map +1 -0
  121. package/dist/types/lib/mcp/gatewayTransport.d.ts +104 -0
  122. package/dist/types/lib/mcp/gatewayTransport.d.ts.map +1 -0
  123. package/dist/types/lib/mcp/index.d.ts +2 -1
  124. package/dist/types/lib/mcp/index.d.ts.map +1 -1
  125. package/dist/types/lib/mcp/mcpClient.d.ts.map +1 -1
  126. package/dist/types/lib/mcp/types.d.ts +45 -1
  127. package/dist/types/lib/mcp/types.d.ts.map +1 -1
  128. package/dist/types/memory/store/types.d.ts +22 -0
  129. package/dist/types/memory/store/types.d.ts.map +1 -1
  130. package/dist/types/memory-providers.d.ts +1 -1
  131. package/dist/types/memory-providers.d.ts.map +1 -1
  132. package/dist/types/security/index.d.ts +10 -1
  133. package/dist/types/security/index.d.ts.map +1 -1
  134. package/dist/types/tool-providers/index.d.ts +6 -2
  135. package/dist/types/tool-providers/index.d.ts.map +1 -1
  136. package/package.json +27 -1
@@ -0,0 +1,321 @@
1
+ /**
2
+ * adapters/hosting/agentcore — AWS Bedrock **AgentCore Runtime** adapters for
3
+ * the two hosting ports.
4
+ *
5
+ * import { agentCoreRuntimeHost, agentCoreSessions } from 'agentfootprint/hosting-providers';
6
+ * import { standingAgent } from 'agentfootprint/hosting';
7
+ *
8
+ * const handle = await standingAgent({
9
+ * agent,
10
+ * host: agentCoreRuntimeHost(),
11
+ * sessions: agentCoreSessions({ store: 'session-storage' }),
12
+ * });
13
+ *
14
+ * ── What this file actually is ───────────────────────────────────────────────
15
+ * Vendor paths, a header name, and two JSON body shapes. That is the whole
16
+ * adapter, and it is the claim the hosting ports were designed to make: a
17
+ * container runtime's contract is a CONFIGURATION of HTTP work that already
18
+ * exists, not a second implementation of it. Nothing here reaches into the
19
+ * ports, and nothing here needed the ports to change.
20
+ *
21
+ * AgentCore Runtime is a **container contract**: an ARM64 image serving HTTP on
22
+ * `0.0.0.0:8080` —
23
+ *
24
+ * POST /invocations JSON `{ "prompt": "..." }` → JSON `{ "response", "status" }`
25
+ * GET /ping → `{ "status": "Healthy", "time_of_last_update": <unix seconds> }`
26
+ *
27
+ * and the caller's conversation arrives in the
28
+ * `X-Amzn-Bedrock-AgentCore-Runtime-Session-Id` header rather than in the body,
29
+ * which is the one thing paths-and-bodies configuration alone could not
30
+ * express before this release.
31
+ *
32
+ * ── Verification status, stated plainly ──────────────────────────────────────
33
+ * `agentCoreRuntimeHost` is **plain HTTP and is really verified**: it runs the
34
+ * same host conformance suite as `nodeHost`, over a real socket, in
35
+ * `test/hosting/host-contract.test.ts`. There is no AWS SDK on its path.
36
+ *
37
+ * `agentCoreSessions({ store: 'memory' })` is **contract-mapped and
38
+ * injection-tested**: its AgentCore Memory calls are exercised through the
39
+ * `_client` seam, never against AWS. Confirm the command and field names
40
+ * against your installed `@aws-sdk/client-bedrock-agentcore` before you rely
41
+ * on it; real-cloud verification lands with a field deployment.
42
+ *
43
+ * Pattern: Adapter (GoF). Role: outer ring. The file-backed session store uses
44
+ * `node:fs` and nothing else; the event-backed one lazy-loads the AWS SDK, so
45
+ * importing this module costs zero peer-dep load.
46
+ */
47
+ import { readEnvelope } from '../../hosting/envelope.js';
48
+ import { headerValue, httpHost } from '../../hosting/httpHost.js';
49
+ import { lazyRequire } from '../../lib/lazyRequire.js';
50
+ // ─── The runtime host ────────────────────────────────────────────────
51
+ const HOST_NAME = 'agentCoreRuntimeHost';
52
+ /** The runtime's container contract, as constants rather than as scattered literals. */
53
+ const INVOKE_PATH = '/invocations';
54
+ const HEALTH_PATH = '/ping';
55
+ const RUNTIME_PORT = 8080;
56
+ /**
57
+ * The header the runtime puts the caller's conversation in. Matched
58
+ * case-insensitively — HTTP header names are case-insensitive and a proxy in
59
+ * front of the container is free to re-case them.
60
+ */
61
+ const SESSION_HEADER = 'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id';
62
+ /**
63
+ * The AgentCore Runtime contract as an {@link HttpWire}.
64
+ *
65
+ * Exported so the body shapes are inspectable and testable without binding a
66
+ * socket, and so a deployment that must serve the same bodies from somewhere
67
+ * else can reuse them by name.
68
+ */
69
+ export function agentCoreRuntimeWire(busy) {
70
+ return {
71
+ readRequest(facts) {
72
+ // `prompt` is the field the runtime's own quickstart and this repo's
73
+ // deploy template use. `input` is accepted too because the runtime passes
74
+ // the payload through verbatim — it is the CALLER who picks the field —
75
+ // and refusing a caller who used the port's own word would be a rule this
76
+ // adapter invented rather than one the contract imposes.
77
+ const prompt = facts.body.prompt ?? facts.body.input;
78
+ const input = typeof prompt === 'string' ? prompt : '';
79
+ // The conversation id arrives in a header, never in the body. It is
80
+ // caller-adjacent data, not identity — the port says so and it is just as
81
+ // true here.
82
+ const sessionId = headerValue(facts, SESSION_HEADER);
83
+ return sessionId !== undefined ? { input, sessionId } : { input };
84
+ },
85
+ // The runtime polls this to decide whether the container is ready and
86
+ // whether to send it more work. `time_of_last_update` is unix SECONDS.
87
+ health: () => ({
88
+ status: busy?.() === true ? 'HealthyBusy' : 'Healthy',
89
+ time_of_last_update: Math.floor(Date.now() / 1000),
90
+ }),
91
+ output: (response) => ({ response, status: 'success' }),
92
+ // The message only — never a stack. The runtime surfaces the status code;
93
+ // the body is read by whoever called the agent.
94
+ failure: (error, code) => ({ error, status: 'error', ...(code !== undefined && { code }) }),
95
+ // A distinct field from `response` on purpose: a caller concatenating
96
+ // stream frames must not be able to double-count the final answer by
97
+ // reading the same key twice.
98
+ chunk: (chunk) => ({ chunk }),
99
+ };
100
+ }
101
+ /**
102
+ * An `AgentHost` that speaks AgentCore Runtime's container contract.
103
+ *
104
+ * Passes the same conformance suite as `nodeHost` — it is the same HTTP host
105
+ * with this runtime's two paths, its header, and its two body shapes.
106
+ *
107
+ * @example The container's entry point
108
+ * const handle = await standingAgent({
109
+ * agent,
110
+ * host: agentCoreRuntimeHost(),
111
+ * sessions: agentCoreSessions({ store: 'session-storage' }),
112
+ * });
113
+ * process.on('SIGTERM', () => void handle.close());
114
+ */
115
+ export function agentCoreRuntimeHost(options = {}) {
116
+ return httpHost({
117
+ name: HOST_NAME,
118
+ wire: agentCoreRuntimeWire(options.busy),
119
+ invokePath: INVOKE_PATH,
120
+ healthPath: HEALTH_PATH,
121
+ port: options.port ?? RUNTIME_PORT,
122
+ hostname: options.hostname ?? '0.0.0.0',
123
+ });
124
+ }
125
+ /** The default file the `'session-storage'` mode writes to. */
126
+ export const DEFAULT_SESSION_STORAGE_PATH = '/tmp/agentcore-session';
127
+ /**
128
+ * A `SessionLifecycle` backed by AgentCore, with the checkpoint's home chosen
129
+ * at construction.
130
+ *
131
+ * Both modes store the SAME `CheckpointEnvelope` the port defines, and both
132
+ * refuse an unknown `format` by name through the shared `readEnvelope` — a
133
+ * conversation written by a newer runtime is refused, never half-restored.
134
+ * That law is inherited, not re-implemented.
135
+ *
136
+ * @example Survive a stop/resume, no AWS SDK required
137
+ * agentCoreSessions({ store: 'session-storage' });
138
+ *
139
+ * @example Outlive the session entirely
140
+ * agentCoreSessions({ store: 'memory', memoryId: process.env.MEMORY_ID!, region: 'us-west-2' });
141
+ */
142
+ export function agentCoreSessions(options) {
143
+ return options.store === 'memory' ? memoryEventSessions(options) : fileSessions(options);
144
+ }
145
+ function fileSessions(options) {
146
+ const path = options.path ?? DEFAULT_SESSION_STORAGE_PATH;
147
+ async function readFile() {
148
+ const { readFile: read } = await import('node:fs/promises');
149
+ let raw;
150
+ try {
151
+ raw = await read(path, 'utf8');
152
+ }
153
+ catch {
154
+ // No file yet is the ordinary first-request state, not an error.
155
+ return { version: 1, sessions: {} };
156
+ }
157
+ let parsed;
158
+ try {
159
+ parsed = JSON.parse(raw);
160
+ }
161
+ catch (err) {
162
+ throw new TypeError(`[hosting] the session file at '${path}' is not JSON (${err.message}). ` +
163
+ `Refusing rather than starting every conversation over silently — delete the file ` +
164
+ `to start fresh, or point 'path' somewhere else.`);
165
+ }
166
+ const sessions = parsed?.sessions;
167
+ return sessions && typeof sessions === 'object'
168
+ ? { version: 1, sessions: sessions }
169
+ : { version: 1, sessions: {} };
170
+ }
171
+ return {
172
+ async hydrate(sessionId) {
173
+ const file = await readFile();
174
+ const stored = file.sessions[sessionId];
175
+ if (stored === undefined)
176
+ return undefined;
177
+ // Validate HERE as well as in the composer, so a refusal points at the
178
+ // store that produced the bytes rather than at whoever read them next.
179
+ readEnvelope(stored);
180
+ return stored;
181
+ },
182
+ async persist(sessionId, envelope) {
183
+ const { writeFile, rename, mkdir } = await import('node:fs/promises');
184
+ const { dirname } = await import('node:path');
185
+ const file = await readFile();
186
+ const next = {
187
+ version: 1,
188
+ sessions: { ...file.sessions, [sessionId]: envelope },
189
+ };
190
+ await mkdir(dirname(path), { recursive: true }).catch(() => undefined);
191
+ // Write-then-rename: a container killed mid-write leaves the previous
192
+ // conversation intact rather than a truncated file that refuses to parse.
193
+ const temporary = `${path}.${process.pid}.tmp`;
194
+ await writeFile(temporary, JSON.stringify(next), 'utf8');
195
+ await rename(temporary, path);
196
+ },
197
+ };
198
+ }
199
+ // ─── 'memory': one AgentCore Memory event per persist ────────────────
200
+ const DEFAULT_ACTOR_ID = 'afp-standing-agent';
201
+ function memoryEventSessions(options) {
202
+ if (!options.memoryId) {
203
+ throw new Error(`agentCoreSessions({ store: 'memory' }) requires 'memoryId'.`);
204
+ }
205
+ const memoryId = options.memoryId;
206
+ const actorId = options.actorId ?? DEFAULT_ACTOR_ID;
207
+ const client = options._client ?? options.client ?? createSessionClient(options.region, options._sdk);
208
+ return {
209
+ async hydrate(sessionId) {
210
+ // AgentCore Memory is an append-only log and lists newest-first, so the
211
+ // newest readable event IS the conversation. Older ones are the earlier
212
+ // turns and deliberately left where they are — they are the audit trail.
213
+ const page = await client.listEvents({
214
+ memoryId,
215
+ actorId,
216
+ sessionId: safeSessionId(sessionId),
217
+ maxResults: 1,
218
+ });
219
+ const newest = page.events[0];
220
+ if (!newest || newest.envelope === null || newest.envelope === undefined)
221
+ return undefined;
222
+ readEnvelope(newest.envelope);
223
+ return newest.envelope;
224
+ },
225
+ async persist(sessionId, envelope) {
226
+ await client.createEvent({
227
+ memoryId,
228
+ actorId,
229
+ sessionId: safeSessionId(sessionId),
230
+ envelope,
231
+ });
232
+ },
233
+ };
234
+ }
235
+ const SESSION_ID_MAX = 99;
236
+ /** AgentCore ids accept `[A-Za-z0-9_-]`; a session id is caller data and need not. */
237
+ function safeSessionId(raw) {
238
+ const slug = raw.replace(/[^A-Za-z0-9_-]/g, '-');
239
+ if (slug.length <= SESSION_ID_MAX)
240
+ return slug;
241
+ // Keep a readable head plus a stable tail so two long ids stay distinct.
242
+ return `${slug.slice(0, SESSION_ID_MAX - 9)}-${fnv1a(raw)}`;
243
+ }
244
+ function fnv1a(s) {
245
+ let h = 0x811c9dc5;
246
+ for (let i = 0; i < s.length; i++) {
247
+ h ^= s.charCodeAt(i);
248
+ h = Math.imul(h, 0x01000193);
249
+ }
250
+ return (h >>> 0).toString(36);
251
+ }
252
+ /** Pull the envelope out of an event's `payload` (a single `blob` document). */
253
+ function envelopeFromPayload(payload) {
254
+ if (!Array.isArray(payload))
255
+ return null;
256
+ for (const part of payload) {
257
+ const blob = part?.blob;
258
+ if (blob && typeof blob === 'object')
259
+ return blob;
260
+ }
261
+ return null;
262
+ }
263
+ /**
264
+ * Map {@link AgentCoreSessionClientLike} onto the real SDK commands. If AWS
265
+ * renames a command, only this function changes — which is also why every test
266
+ * injects past it.
267
+ */
268
+ function createSessionClient(region, injected) {
269
+ let mod;
270
+ if (injected) {
271
+ mod = injected;
272
+ }
273
+ else {
274
+ try {
275
+ mod = lazyRequire('@aws-sdk/client-bedrock-agentcore');
276
+ }
277
+ catch {
278
+ throw new Error(`agentCoreSessions({ store: 'memory' }) requires the ` +
279
+ '`@aws-sdk/client-bedrock-agentcore` peer dependency.\n' +
280
+ ' Install: npm install @aws-sdk/client-bedrock-agentcore\n' +
281
+ " Or use { store: 'session-storage' }, which needs no SDK at all.");
282
+ }
283
+ }
284
+ if (!mod.BedrockAgentCoreClient) {
285
+ throw new Error('agentCoreSessions: `@aws-sdk/client-bedrock-agentcore` is installed but ' +
286
+ '`BedrockAgentCoreClient` was not found. Update the SDK.');
287
+ }
288
+ const sdk = new mod.BedrockAgentCoreClient({ ...(region && { region }) });
289
+ const send = async (Ctor, name, input) => {
290
+ if (!Ctor) {
291
+ throw new Error(`agentCoreSessions: \`@aws-sdk/client-bedrock-agentcore\` is missing ${name}. Upgrade the SDK.`);
292
+ }
293
+ return sdk.send(new Ctor(input));
294
+ };
295
+ return {
296
+ async createEvent({ memoryId, actorId, sessionId, envelope }) {
297
+ await send(mod.CreateEventCommand, 'CreateEventCommand', {
298
+ memoryId,
299
+ actorId,
300
+ sessionId,
301
+ eventTimestamp: new Date(),
302
+ payload: [{ blob: envelope }],
303
+ });
304
+ },
305
+ async listEvents({ memoryId, actorId, sessionId, maxResults }) {
306
+ const result = (await send(mod.ListEventsCommand, 'ListEventsCommand', {
307
+ memoryId,
308
+ actorId,
309
+ sessionId,
310
+ includePayloads: true,
311
+ ...(maxResults !== undefined && { maxResults }),
312
+ }));
313
+ const events = (result?.events ?? []).map((event) => ({
314
+ eventId: event.eventId ?? '',
315
+ envelope: envelopeFromPayload(event.payload),
316
+ }));
317
+ return { events };
318
+ },
319
+ };
320
+ }
321
+ //# sourceMappingURL=agentcore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentcore.js","sourceRoot":"","sources":["../../../../src/adapters/hosting/agentcore.ts"],"names":[],"mappings":"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"}
@@ -27,14 +27,20 @@
27
27
  * AgentCore's ids are server-assigned. **O(events in session)** — fine for typical
28
28
  * window sizes; if you need O(1) keyed access at scale, use RedisStore.
29
29
  * • `forget` → `ListEvents` + `DeleteEvent` per event (no `DeleteSession` on AgentCore).
30
- * • `search` → still unwired (AgentCore's `RetrieveMemoryRecords` lands as a later helper).
30
+ * • `search` → `RetrieveMemoryRecords`, **text-in**. AgentCore embeds and ranks on its
31
+ * own side, so it takes a natural-language query; the port's `search()` takes a
32
+ * vector. Pass `options.text` and this store serves the query; omit it and it refuses
33
+ * by name rather than ranking an empty set. See `search()` below for the whole story.
31
34
  * • `putIfVersion` / `seen` / `feedback` → in-process emulation (AgentCore has no native
32
35
  * CAS / dedup / feedback primitive; these don't survive process restart).
36
+ * • no `stream()` — AgentCore Memory has no streaming data-plane operation, and the
37
+ * `MemoryStore` port has no streaming method to implement. Inventing one for a single
38
+ * backend is how a port stops being a port.
33
39
  *
34
40
  * Role: Outer ring. Lazy-requires the AWS SDK; zero runtime cost when another adapter is
35
41
  * in use. Emits: N/A (storage adapters don't emit).
36
42
  */
37
- import type { ListOptions, ListResult, MemoryStore, PutIfVersionResult } from '../../memory/store/types.js';
43
+ import type { ListOptions, ListResult, MemoryStore, PutIfVersionResult, ScoredEntry, SearchOptions } from '../../memory/store/types.js';
38
44
  import type { MemoryEntry } from '../../memory/entry/index.js';
39
45
  import type { MemoryIdentity } from '../../memory/identity/index.js';
40
46
  /** One event as the adapter cares about it: AgentCore's id + the decoded entry. */
@@ -75,6 +81,35 @@ export interface AgentCoreLikeClient {
75
81
  sessionId: string;
76
82
  eventId: string;
77
83
  }): Promise<void>;
84
+ /**
85
+ * Server-side semantic retrieval (`RetrieveMemoryRecords`). Optional: a client
86
+ * built before this existed still satisfies the interface, and `search()`
87
+ * feature-detects it rather than assuming.
88
+ */
89
+ retrieveRecords?(input: {
90
+ memoryId: string;
91
+ namespace: string;
92
+ searchQuery: string;
93
+ maxResults?: number;
94
+ memoryStrategyId?: string;
95
+ }): Promise<{
96
+ records: readonly AgentCoreMemoryRecord[];
97
+ }>;
98
+ }
99
+ /** One record as `RetrieveMemoryRecords` returns it. */
100
+ export interface AgentCoreMemoryRecord {
101
+ /** AgentCore's own record id. */
102
+ readonly memoryRecordId: string;
103
+ /** The record's text content. */
104
+ readonly content: string;
105
+ /** Relevance as AgentCore scored it, when it reports one. */
106
+ readonly score?: number;
107
+ /** Which strategy produced the record (semantic, summary, user-preference, …). */
108
+ readonly memoryStrategyId?: string;
109
+ /** The namespace it was found in. */
110
+ readonly namespace?: string;
111
+ /** When AgentCore created it (unix ms), when reported. */
112
+ readonly createdAt?: number;
78
113
  }
79
114
  export interface AgentCoreStoreOptions {
80
115
  /** AgentCore Memory ARN or id. Required. */
@@ -85,6 +120,27 @@ export interface AgentCoreStoreOptions {
85
120
  readonly client?: AgentCoreLikeClient;
86
121
  /** Page size for `listEvents`. Default 100. */
87
122
  readonly pageSize?: number;
123
+ /**
124
+ * Where `search()` looks. AgentCore organises extracted memory records into
125
+ * namespaces configured on the Memory resource's strategies (commonly
126
+ * something like `/strategies/{strategyId}/actors/{actorId}`).
127
+ *
128
+ * A function, because the namespace usually contains the actor: it is handed
129
+ * the resolved AgentCore ids for the identity being searched. Default:
130
+ * `/actors/{actorId}/sessions/{sessionId}` — the session's own records.
131
+ */
132
+ readonly searchNamespace?: (scope: {
133
+ readonly actorId: string;
134
+ readonly sessionId: string;
135
+ }) => string;
136
+ /**
137
+ * Restrict `search()` to one extraction strategy (semantic, summary,
138
+ * user-preference…). Omit to search across all of them.
139
+ *
140
+ * This is the metadata filter that reaches AgentCore's own side; `tiers` /
141
+ * `minScore` / `k` from {@link SearchOptions} are applied to what comes back.
142
+ */
143
+ readonly searchStrategyId?: string;
88
144
  /** @internal Test injection — skips the SDK require entirely. */
89
145
  readonly _client?: AgentCoreLikeClient;
90
146
  /** @internal Test injection — the AWS SDK module (to exercise the real shim with a mock SDK). */
@@ -100,6 +156,8 @@ export declare class AgentCoreStore implements MemoryStore {
100
156
  private readonly client;
101
157
  private readonly memoryId;
102
158
  private readonly pageSize;
159
+ private readonly searchNamespace;
160
+ private readonly searchStrategyId;
103
161
  private closed;
104
162
  private readonly signatures;
105
163
  private readonly feedbackBag;
@@ -130,6 +188,33 @@ export declare class AgentCoreStore implements MemoryStore {
130
188
  } | null>;
131
189
  /** GDPR "everything for this identity, gone." No DeleteSession on AgentCore → delete every event. */
132
190
  forget(identity: MemoryIdentity): Promise<void>;
191
+ /**
192
+ * Server-side semantic retrieval over AgentCore's extracted memory records
193
+ * (`RetrieveMemoryRecords`).
194
+ *
195
+ * ── Read this before you call it ─────────────────────────────────────────
196
+ * **It takes TEXT, not the vector.** AgentCore embeds and ranks on its own
197
+ * side, so `query` — the port's vector — is unusable here, and the query it
198
+ * actually needs travels in `options.text`. Omit that and this method throws
199
+ * a corrective error naming what is missing, because the alternative is
200
+ * ranking nothing and handing back `[]`, which reads as "no matches" when it
201
+ * really means "wrong query form". Pass both and every store can serve you:
202
+ * local-ranking backends use the vector and ignore the text.
203
+ *
204
+ * **It searches a DIFFERENT population than `list()`.** `list` returns the
205
+ * events this store wrote. This returns the records AgentCore's extraction
206
+ * strategies derived FROM those events — summaries, semantic facts, user
207
+ * preferences. The ids therefore belong to AgentCore, not to entries you
208
+ * `put()`, and `store.get(entry.id)` will not find them. They arrive as
209
+ * entries so ranking code needs no special case, with `metadata.source`
210
+ * saying plainly where they came from.
211
+ *
212
+ * Filters: `searchStrategyId` and the namespace reach AgentCore's own side;
213
+ * `k`, `minScore` and `tiers` are applied to what comes back.
214
+ *
215
+ * @throws when `options.text` is absent, or when the client cannot retrieve.
216
+ */
217
+ search<T = unknown>(identity: MemoryIdentity, query: readonly number[], options?: SearchOptions): Promise<readonly ScoredEntry<T>[]>;
133
218
  close(): Promise<void>;
134
219
  private ensureOpen;
135
220
  }
@@ -143,4 +228,5 @@ export interface BedrockAgentCoreSdkModule {
143
228
  readonly CreateEventCommand?: new (input: unknown) => unknown;
144
229
  readonly ListEventsCommand?: new (input: unknown) => unknown;
145
230
  readonly DeleteEventCommand?: new (input: unknown) => unknown;
231
+ readonly RetrieveMemoryRecordsCommand?: new (input: unknown) => unknown;
146
232
  }
@@ -27,9 +27,15 @@
27
27
  * AgentCore's ids are server-assigned. **O(events in session)** — fine for typical
28
28
  * window sizes; if you need O(1) keyed access at scale, use RedisStore.
29
29
  * • `forget` → `ListEvents` + `DeleteEvent` per event (no `DeleteSession` on AgentCore).
30
- * • `search` → still unwired (AgentCore's `RetrieveMemoryRecords` lands as a later helper).
30
+ * • `search` → `RetrieveMemoryRecords`, **text-in**. AgentCore embeds and ranks on its
31
+ * own side, so it takes a natural-language query; the port's `search()` takes a
32
+ * vector. Pass `options.text` and this store serves the query; omit it and it refuses
33
+ * by name rather than ranking an empty set. See `search()` below for the whole story.
31
34
  * • `putIfVersion` / `seen` / `feedback` → in-process emulation (AgentCore has no native
32
35
  * CAS / dedup / feedback primitive; these don't survive process restart).
36
+ * • no `stream()` — AgentCore Memory has no streaming data-plane operation, and the
37
+ * `MemoryStore` port has no streaming method to implement. Inventing one for a single
38
+ * backend is how a port stops being a port.
33
39
  *
34
40
  * Role: Outer ring. Lazy-requires the AWS SDK; zero runtime cost when another adapter is
35
41
  * in use. Emits: N/A (storage adapters don't emit).
@@ -55,6 +61,8 @@ export class AgentCoreStore {
55
61
  client;
56
62
  memoryId;
57
63
  pageSize;
64
+ searchNamespace;
65
+ searchStrategyId;
58
66
  closed = false;
59
67
  // In-process shadow state for things AgentCore doesn't surface natively.
60
68
  signatures = new Map();
@@ -64,6 +72,10 @@ export class AgentCoreStore {
64
72
  throw new Error('AgentCoreStore requires `memoryId`.');
65
73
  this.memoryId = options.memoryId;
66
74
  this.pageSize = options.pageSize ?? 100;
75
+ this.searchNamespace =
76
+ options.searchNamespace ??
77
+ (({ actorId, sessionId }) => `/actors/${actorId}/sessions/${sessionId}`);
78
+ this.searchStrategyId = options.searchStrategyId;
67
79
  if (options._client)
68
80
  this.client = options._client;
69
81
  else if (options.client)
@@ -224,6 +236,90 @@ export class AgentCoreStore {
224
236
  this.feedbackBag.delete(key);
225
237
  }
226
238
  }
239
+ /**
240
+ * Server-side semantic retrieval over AgentCore's extracted memory records
241
+ * (`RetrieveMemoryRecords`).
242
+ *
243
+ * ── Read this before you call it ─────────────────────────────────────────
244
+ * **It takes TEXT, not the vector.** AgentCore embeds and ranks on its own
245
+ * side, so `query` — the port's vector — is unusable here, and the query it
246
+ * actually needs travels in `options.text`. Omit that and this method throws
247
+ * a corrective error naming what is missing, because the alternative is
248
+ * ranking nothing and handing back `[]`, which reads as "no matches" when it
249
+ * really means "wrong query form". Pass both and every store can serve you:
250
+ * local-ranking backends use the vector and ignore the text.
251
+ *
252
+ * **It searches a DIFFERENT population than `list()`.** `list` returns the
253
+ * events this store wrote. This returns the records AgentCore's extraction
254
+ * strategies derived FROM those events — summaries, semantic facts, user
255
+ * preferences. The ids therefore belong to AgentCore, not to entries you
256
+ * `put()`, and `store.get(entry.id)` will not find them. They arrive as
257
+ * entries so ranking code needs no special case, with `metadata.source`
258
+ * saying plainly where they came from.
259
+ *
260
+ * Filters: `searchStrategyId` and the namespace reach AgentCore's own side;
261
+ * `k`, `minScore` and `tiers` are applied to what comes back.
262
+ *
263
+ * @throws when `options.text` is absent, or when the client cannot retrieve.
264
+ */
265
+ async search(identity, query, options = {}) {
266
+ this.ensureOpen('search');
267
+ const text = options.text?.trim();
268
+ if (!text) {
269
+ throw new Error('AgentCoreStore.search() needs the query as TEXT, in `options.text`.\n' +
270
+ ` AgentCore embeds and ranks server-side (RetrieveMemoryRecords), so the ${query.length}-dimension\n` +
271
+ ' vector this method was handed cannot be sent anywhere — and returning [] would look\n' +
272
+ ' like "no matches" rather than "wrong query form".\n' +
273
+ ' Fix: store.search(identity, vector, { text: theUserQuestion })\n' +
274
+ ' Backends that rank locally ignore `text`, so passing both is always safe.');
275
+ }
276
+ if (!this.client.retrieveRecords) {
277
+ throw new Error('AgentCoreStore.search() requires a client that implements `retrieveRecords`.\n' +
278
+ ' The built-in client does; a custom or older injected `client` / `_client` may not.');
279
+ }
280
+ const scope = this.scope(identity);
281
+ const k = options.k ?? 10;
282
+ const page = await this.client.retrieveRecords({
283
+ memoryId: this.memoryId,
284
+ namespace: this.searchNamespace({ actorId: scope.actorId, sessionId: scope.sessionId }),
285
+ searchQuery: text,
286
+ maxResults: k,
287
+ ...(this.searchStrategyId !== undefined && { memoryStrategyId: this.searchStrategyId }),
288
+ });
289
+ const scored = [];
290
+ for (const record of page.records) {
291
+ const score = record.score ?? 0;
292
+ if (options.minScore !== undefined && score < options.minScore)
293
+ continue;
294
+ // AgentCore records carry no tier. A tier filter therefore excludes them
295
+ // all rather than silently ignoring the filter the caller asked for.
296
+ if (options.tiers && options.tiers.length > 0)
297
+ continue;
298
+ const createdAt = record.createdAt ?? Date.now();
299
+ const entry = {
300
+ id: record.memoryRecordId,
301
+ value: record.content,
302
+ version: 1,
303
+ createdAt,
304
+ updatedAt: createdAt,
305
+ lastAccessedAt: Date.now(),
306
+ accessCount: 0,
307
+ metadata: {
308
+ // Says plainly that this did not come from an event this store wrote.
309
+ source: 'agentcore-memory-record',
310
+ ...(record.memoryStrategyId !== undefined && {
311
+ memoryStrategyId: record.memoryStrategyId,
312
+ }),
313
+ ...(record.namespace !== undefined && { namespace: record.namespace }),
314
+ },
315
+ };
316
+ scored.push({ entry, score });
317
+ }
318
+ // AgentCore returns its own ranking; re-sort anyway so the port's
319
+ // "descending by score" holds even if a future API version reorders.
320
+ scored.sort((a, b) => b.score !== a.score ? b.score - a.score : a.entry.id < b.entry.id ? -1 : 1);
321
+ return scored.slice(0, k);
322
+ }
227
323
  async close() {
228
324
  if (this.closed)
229
325
  return;
@@ -318,6 +414,34 @@ function createAgentCoreClient(region, injected) {
318
414
  eventId,
319
415
  });
320
416
  },
417
+ async retrieveRecords({ memoryId, namespace, searchQuery, maxResults, memoryStrategyId }) {
418
+ // AgentCore nests the query under `searchCriteria`; the strategy id is the
419
+ // metadata filter that reaches its side rather than being applied after.
420
+ const r = (await send(mod.RetrieveMemoryRecordsCommand, 'RetrieveMemoryRecordsCommand', {
421
+ memoryId,
422
+ namespace,
423
+ searchCriteria: {
424
+ searchQuery,
425
+ ...(maxResults !== undefined && { topK: maxResults }),
426
+ ...(memoryStrategyId !== undefined && { memoryStrategyId }),
427
+ },
428
+ ...(maxResults !== undefined && { maxResults }),
429
+ }));
430
+ const records = (r?.memoryRecordSummaries ?? []).map((s) => {
431
+ const content = typeof s.content === 'string' ? s.content : s.content?.text ?? '';
432
+ const namespaceValue = Array.isArray(s.namespace) ? s.namespace[0] : s.namespace;
433
+ const createdAt = s.createdAt === undefined ? undefined : new Date(s.createdAt).getTime();
434
+ return {
435
+ memoryRecordId: s.memoryRecordId ?? '',
436
+ content,
437
+ ...(typeof s.score === 'number' && { score: s.score }),
438
+ ...(s.memoryStrategyId !== undefined && { memoryStrategyId: s.memoryStrategyId }),
439
+ ...(typeof namespaceValue === 'string' && { namespace: namespaceValue }),
440
+ ...(createdAt !== undefined && Number.isFinite(createdAt) && { createdAt }),
441
+ };
442
+ });
443
+ return { records };
444
+ },
321
445
  };
322
446
  }
323
447
  //# sourceMappingURL=agentcore.js.map