aismemory 0.7.3 → 0.7.5

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 (80) hide show
  1. package/README.md +51 -11
  2. package/dist/__tests__/agent-key-mode.test.js +72 -7
  3. package/dist/__tests__/agent-key-mode.test.js.map +1 -1
  4. package/dist/__tests__/ais-http.test.js +42 -2
  5. package/dist/__tests__/ais-http.test.js.map +1 -1
  6. package/dist/__tests__/credential-isolation.test.js +117 -3
  7. package/dist/__tests__/credential-isolation.test.js.map +1 -1
  8. package/dist/__tests__/device-flow-gate-e2e.test.js +5 -0
  9. package/dist/__tests__/device-flow-gate-e2e.test.js.map +1 -1
  10. package/dist/__tests__/doctor.test.js +1 -1
  11. package/dist/__tests__/doctor.test.js.map +1 -1
  12. package/dist/__tests__/mcp-init-no-auth.test.js +29 -5
  13. package/dist/__tests__/mcp-init-no-auth.test.js.map +1 -1
  14. package/dist/__tests__/mcp-tools.test.d.ts +1 -0
  15. package/dist/__tests__/mcp-tools.test.js +155 -0
  16. package/dist/__tests__/mcp-tools.test.js.map +1 -0
  17. package/dist/__tests__/memory-pull.test.d.ts +1 -0
  18. package/dist/__tests__/memory-pull.test.js +380 -0
  19. package/dist/__tests__/memory-pull.test.js.map +1 -0
  20. package/dist/__tests__/pending-device-flow-e2e.test.d.ts +19 -0
  21. package/dist/__tests__/pending-device-flow-e2e.test.js +159 -0
  22. package/dist/__tests__/pending-device-flow-e2e.test.js.map +1 -0
  23. package/dist/__tests__/pending-device-flow.test.d.ts +15 -0
  24. package/dist/__tests__/pending-device-flow.test.js +108 -0
  25. package/dist/__tests__/pending-device-flow.test.js.map +1 -0
  26. package/dist/__tests__/readme-quickstart-default-ais-url.test.d.ts +1 -0
  27. package/dist/__tests__/readme-quickstart-default-ais-url.test.js +80 -0
  28. package/dist/__tests__/readme-quickstart-default-ais-url.test.js.map +1 -0
  29. package/dist/__tests__/reconnect-survival-e2e.test.js +17 -8
  30. package/dist/__tests__/reconnect-survival-e2e.test.js.map +1 -1
  31. package/dist/__tests__/remember-duplicate-truth.test.d.ts +13 -0
  32. package/dist/__tests__/remember-duplicate-truth.test.js +106 -0
  33. package/dist/__tests__/remember-duplicate-truth.test.js.map +1 -0
  34. package/dist/__tests__/startup-credential-warning-e2e.test.d.ts +1 -0
  35. package/dist/__tests__/startup-credential-warning-e2e.test.js +102 -0
  36. package/dist/__tests__/startup-credential-warning-e2e.test.js.map +1 -0
  37. package/dist/__tests__/tool-args.test.js +10 -0
  38. package/dist/__tests__/tool-args.test.js.map +1 -1
  39. package/dist/__tests__/version-check.test.d.ts +1 -0
  40. package/dist/__tests__/version-check.test.js +349 -0
  41. package/dist/__tests__/version-check.test.js.map +1 -0
  42. package/dist/agent-key-mode.d.ts +1 -1
  43. package/dist/agent-key-mode.js +30 -10
  44. package/dist/agent-key-mode.js.map +1 -1
  45. package/dist/ais-http-error.d.ts +22 -0
  46. package/dist/ais-http-error.js +42 -0
  47. package/dist/ais-http-error.js.map +1 -1
  48. package/dist/ais-http.d.ts +1 -0
  49. package/dist/ais-http.js +39 -16
  50. package/dist/ais-http.js.map +1 -1
  51. package/dist/cli/doctor.d.ts +16 -0
  52. package/dist/cli/doctor.js +66 -1
  53. package/dist/cli/doctor.js.map +1 -1
  54. package/dist/cli/enable-key-auth.js +2 -1
  55. package/dist/cli/enable-key-auth.js.map +1 -1
  56. package/dist/cli/pull-memory.d.ts +17 -0
  57. package/dist/cli/pull-memory.js +141 -0
  58. package/dist/cli/pull-memory.js.map +1 -0
  59. package/dist/index.js +108 -383
  60. package/dist/index.js.map +1 -1
  61. package/dist/mcp/tools.d.ts +78 -0
  62. package/dist/mcp/tools.js +433 -0
  63. package/dist/mcp/tools.js.map +1 -0
  64. package/dist/memory-pull.d.ts +114 -0
  65. package/dist/memory-pull.js +171 -0
  66. package/dist/memory-pull.js.map +1 -0
  67. package/dist/pending-device-flow.d.ts +49 -0
  68. package/dist/pending-device-flow.js +96 -0
  69. package/dist/pending-device-flow.js.map +1 -0
  70. package/dist/telemetry.d.ts +1 -1
  71. package/dist/telemetry.js.map +1 -1
  72. package/dist/tool-args.d.ts +2 -0
  73. package/dist/tool-args.js +6 -0
  74. package/dist/tool-args.js.map +1 -1
  75. package/dist/version-check.d.ts +72 -0
  76. package/dist/version-check.js +237 -0
  77. package/dist/version-check.js.map +1 -0
  78. package/dist/workspace-key-mode.js +15 -6
  79. package/dist/workspace-key-mode.js.map +1 -1
  80. package/package.json +5 -3
@@ -0,0 +1,433 @@
1
+ /**
2
+ * Model context protocol `tools/call` dispatch for the aismemory server.
3
+ *
4
+ * Moved verbatim out of `src/index.ts` (CORBOT-B8D6C9BA) so the entrypoint
5
+ * keeps only process wiring. Each factory below returns the exact handler the
6
+ * matching auth mode used to register inline; behaviour, error text, telemetry
7
+ * and tool ordering are unchanged. State that lives on the entrypoint (the
8
+ * active credentials, the session agent override, the hydrated agent context)
9
+ * is reached through the context objects rather than a closure.
10
+ */
11
+ import { aisGet, aisPost, aisPatch } from '../ais-http.js';
12
+ import { isAuthErrorResult } from '../auth-staleness.js';
13
+ import { saveAgentPreference } from '../agent-preference.js';
14
+ import { hydrateIdentity } from '../hydration.js';
15
+ import { emitTelemetry, hashAgentId } from '../telemetry.js';
16
+ import { duplicateMemoryResult } from '../ais-http-error.js';
17
+ import { parseAgentLoadArgs, parseEmptyToolArgs, parseHandoffArgs, parseRecallArgs, parseFullContextArgs, parseRememberArgs, parseInboxSendArgs, parseInboxReadArgs, parseInboxAckArgs, parseGoalCreateArgs, parseGoalListArgs, parseGoalUpdateProgressArgs, parseGoalCompleteArgs, } from '../tool-args.js';
18
+ import { assertPinnedAgent, requiresIdentityGate, verifyPinnedIdentity } from '../harness-identity.js';
19
+ import { readInboxAndMaybeAck } from '../inbox-client.js';
20
+ import { dispatchToolKeyMode, UNKNOWN_TOOL_KEY_MODE } from '../agent-key-mode.js';
21
+ import { getUpdateNotice } from '../version-check.js';
22
+ import { dispatchToolWorkspaceKeyMode, UNKNOWN_TOOL_WORKSPACE_KEY_MODE, } from '../workspace-key-mode.js';
23
+ /**
24
+ * Tools whose result carries the "a newer aismemory has been published" notice
25
+ * (CORBOT-7B8A1D16). whoami and full_context are the two orientation calls an
26
+ * agent makes at the start of a session, so the notice lands where a person
27
+ * reading the transcript sees it — unlike a stderr line, which no model
28
+ * context protocol client shows. The check runs in the background at startup;
29
+ * when it has not settled yet, or the version is current, nothing is added.
30
+ */
31
+ const UPDATE_NOTICE_TOOLS = new Set(['whoami', 'full_context']);
32
+ function withUpdateNotice(toolName, result) {
33
+ if (!UPDATE_NOTICE_TOOLS.has(toolName))
34
+ return result;
35
+ const notice = getUpdateNotice();
36
+ if (notice === null)
37
+ return result;
38
+ if (typeof result !== 'object' || result === null || Array.isArray(result))
39
+ return result;
40
+ return { ...result, aismemoryUpdateAvailable: notice };
41
+ }
42
+ /**
43
+ * `tools/call` handler for workspace-key auth mode (CORBOT-3103ED88).
44
+ *
45
+ * Like agent-API-key mode but supports agent_load: when agent_load succeeds,
46
+ * the active agentId is updated for subsequent calls.
47
+ */
48
+ export function createWorkspaceKeyCallToolHandler(ctx) {
49
+ return async (request) => {
50
+ const { name, arguments: args } = request.params;
51
+ const rawArgs = args ?? {};
52
+ ctx.activityTracker.recordToolUse(name);
53
+ const toolStartedAt = Date.now();
54
+ try {
55
+ const callConfig = ctx.getActiveConfig();
56
+ if (requiresIdentityGate(name, rawArgs)) {
57
+ await verifyPinnedIdentity(ctx.getHarnessIdentity(), callConfig.agentId, () => dispatchToolWorkspaceKeyMode(ctx.aisUrl, callConfig, 'whoami', {}));
58
+ }
59
+ const result = await dispatchToolWorkspaceKeyMode(ctx.aisUrl, callConfig, name, rawArgs);
60
+ if (result === UNKNOWN_TOOL_WORKSPACE_KEY_MODE) {
61
+ return {
62
+ content: [{ type: 'text', text: JSON.stringify({ error: `Unknown tool: ${name}` }) }],
63
+ isError: true,
64
+ };
65
+ }
66
+ // agent_load: update the active agentId for subsequent calls.
67
+ if (name === 'agent_load' &&
68
+ typeof result === 'object' &&
69
+ result !== null &&
70
+ 'switched' in result &&
71
+ result.switched) {
72
+ const switchResult = result;
73
+ if (ctx.getHarnessIdentity()) {
74
+ await verifyPinnedIdentity(ctx.getHarnessIdentity(), switchResult.agentId, () => dispatchToolWorkspaceKeyMode(ctx.aisUrl, { ...callConfig, agentId: switchResult.agentId }, 'whoami', {}));
75
+ }
76
+ ctx.setActiveConfig({ ...ctx.getActiveConfig(), agentId: switchResult.agentId });
77
+ ctx.stderr(`Switched active agent to ${switchResult.agentId}`);
78
+ }
79
+ emitTelemetry({
80
+ event: 'tool.call',
81
+ tool: name,
82
+ agentIdHash: hashAgentId(ctx.getActiveConfig().agentId),
83
+ latencyMs: Date.now() - toolStartedAt,
84
+ status: 'ok',
85
+ });
86
+ return { content: [{ type: 'text', text: JSON.stringify(withUpdateNotice(name, result), null, 2) }] };
87
+ }
88
+ catch (error) {
89
+ const message = error instanceof Error ? error.message : 'Unknown error';
90
+ emitTelemetry({
91
+ event: 'tool.call',
92
+ tool: name,
93
+ agentIdHash: hashAgentId(ctx.getActiveConfig().agentId),
94
+ latencyMs: Date.now() - toolStartedAt,
95
+ status: 'error',
96
+ error: message,
97
+ });
98
+ return {
99
+ content: [{ type: 'text', text: JSON.stringify({ error: message }) }],
100
+ isError: true,
101
+ };
102
+ }
103
+ };
104
+ }
105
+ /** `tools/call` handler for agent-API-key auth mode (CORBOT-B1D3244C). */
106
+ export function createAgentKeyCallToolHandler(ctx) {
107
+ const { config } = ctx;
108
+ return async (request) => {
109
+ const { name, arguments: args } = request.params;
110
+ const rawArgs = args ?? {};
111
+ ctx.activityTracker.recordToolUse(name);
112
+ const toolStartedAt = Date.now();
113
+ try {
114
+ if (requiresIdentityGate(name, rawArgs)) {
115
+ await verifyPinnedIdentity(ctx.getHarnessIdentity(), config.agentId, () => dispatchToolKeyMode(ctx.aisUrl, config, 'whoami', {}));
116
+ }
117
+ const result = await dispatchToolKeyMode(ctx.aisUrl, config, name, rawArgs);
118
+ if (result === UNKNOWN_TOOL_KEY_MODE) {
119
+ return {
120
+ content: [{ type: 'text', text: JSON.stringify({ error: `Unknown tool: ${name}` }) }],
121
+ isError: true,
122
+ };
123
+ }
124
+ emitTelemetry({
125
+ event: 'tool.call',
126
+ tool: name,
127
+ agentIdHash: hashAgentId(config.agentId),
128
+ latencyMs: Date.now() - toolStartedAt,
129
+ status: 'ok',
130
+ });
131
+ return { content: [{ type: 'text', text: JSON.stringify(withUpdateNotice(name, result), null, 2) }] };
132
+ }
133
+ catch (error) {
134
+ const message = error instanceof Error ? error.message : 'Unknown error';
135
+ emitTelemetry({
136
+ event: 'tool.call',
137
+ tool: name,
138
+ agentIdHash: hashAgentId(config.agentId),
139
+ latencyMs: Date.now() - toolStartedAt,
140
+ status: 'error',
141
+ error: message,
142
+ });
143
+ return {
144
+ content: [{ type: 'text', text: JSON.stringify({ error: message }) }],
145
+ isError: true,
146
+ };
147
+ }
148
+ };
149
+ }
150
+ /**
151
+ * `tools/call` handler for the bearer / device-flow mode — the full tool
152
+ * surface, including the invalidate-and-retry-once path for a token the
153
+ * server rejected mid-session (CORBOT-A5BBD580).
154
+ */
155
+ export function createOAuthCallToolHandler(ctx) {
156
+ return async (request) => {
157
+ const { name, arguments: args } = request.params;
158
+ const rawArgs = args ?? {};
159
+ ctx.activityTracker.recordToolUse(name);
160
+ const toolStartedAt = Date.now();
161
+ try {
162
+ if (requiresIdentityGate(name, rawArgs)) {
163
+ assertPinnedAgent(ctx.getHarnessIdentity(), ctx.getHarnessIdentity()?.agentId ?? 'unselected');
164
+ }
165
+ const UNKNOWN_TOOL = Symbol('unknown-tool');
166
+ const dispatchTool = async (c) => {
167
+ const token = c.token;
168
+ // agentId is mutable across `agent_load` calls within this session.
169
+ let agentId = ctx.getHarnessIdentity()?.agentId ?? c.agentId;
170
+ if (requiresIdentityGate(name, rawArgs)) {
171
+ await verifyPinnedIdentity(ctx.getHarnessIdentity(), agentId, () => aisGet(`/v1/agents/${agentId}`, token));
172
+ }
173
+ let result;
174
+ switch (name) {
175
+ case 'remember': {
176
+ const rememberArgs = parseRememberArgs(rawArgs);
177
+ try {
178
+ result = await aisPost(`/v1/agents/${agentId}/memory`, {
179
+ content: rememberArgs.content,
180
+ type: rememberArgs.type,
181
+ importance: rememberArgs.importance,
182
+ }, token);
183
+ ctx.activityTracker.recordMemoryStored(rememberArgs.content);
184
+ }
185
+ catch (err) {
186
+ // CORBOT-F21668B5: the server deduplicated this write. The content
187
+ // is stored (from the earlier identical write), so answer with the
188
+ // truth rather than an error. No recordMemoryStored: this call
189
+ // added nothing to the session's stored set.
190
+ const duplicate = duplicateMemoryResult(err);
191
+ if (!duplicate)
192
+ throw err;
193
+ result = duplicate;
194
+ }
195
+ break;
196
+ }
197
+ case 'recall': {
198
+ const recallArgs = parseRecallArgs(rawArgs);
199
+ const params = new URLSearchParams();
200
+ params.set('query', recallArgs.query);
201
+ if (recallArgs.limit !== undefined)
202
+ params.set('limit', String(recallArgs.limit));
203
+ if (recallArgs.type !== undefined)
204
+ params.set('types', recallArgs.type);
205
+ if (recallArgs.principalAgentId !== undefined) {
206
+ params.set('principalAgentId', recallArgs.principalAgentId);
207
+ }
208
+ result = await aisGet(`/v1/agents/${agentId}/memory?${params}`, token);
209
+ break;
210
+ }
211
+ case 'whoami':
212
+ parseEmptyToolArgs(rawArgs);
213
+ result = await aisGet(`/v1/agents/${agentId}`, token);
214
+ break;
215
+ case 'full_context': {
216
+ const fcArgs = parseFullContextArgs(rawArgs);
217
+ const fcParams = new URLSearchParams();
218
+ if (fcArgs.principalAgentId !== undefined)
219
+ fcParams.set('principalAgentId', fcArgs.principalAgentId);
220
+ if (fcArgs.memoriesLimit !== undefined)
221
+ fcParams.set('memoriesLimit', String(fcArgs.memoriesLimit));
222
+ if (fcArgs.view !== undefined)
223
+ fcParams.set('view', fcArgs.view);
224
+ const fcQs = fcParams.toString();
225
+ const fcPath = `/v1/agents/${agentId}/full-context${fcQs ? `?${fcQs}` : ''}`;
226
+ result = await aisGet(fcPath, token);
227
+ break;
228
+ }
229
+ case 'dream':
230
+ parseEmptyToolArgs(rawArgs);
231
+ result = await aisPost(`/v1/agents/${agentId}/dream`, {}, token);
232
+ break;
233
+ case 'handoff': {
234
+ const handoffArgs = parseHandoffArgs(rawArgs);
235
+ result = await aisPost(`/v1/agents/${agentId}/handoff`, {
236
+ summary: handoffArgs.summary ?? 'Session ended',
237
+ keyLearnings: handoffArgs.keyLearnings ?? [],
238
+ // CORBOT-E3541A7F: the handoff tool schema declares these two, so
239
+ // the token path forwards them too — otherwise a field the schema
240
+ // advertises would be silently dropped in this mode alone.
241
+ ...(handoffArgs.docPath !== undefined ? { docPath: handoffArgs.docPath } : {}),
242
+ ...(handoffArgs.docPrUrl !== undefined ? { docPrUrl: handoffArgs.docPrUrl } : {}),
243
+ }, token);
244
+ break;
245
+ }
246
+ case 'agent_load': {
247
+ const { query, memoriesLimit } = parseAgentLoadArgs(rawArgs);
248
+ const target = await ctx.resolveAgentForLoad(token, query);
249
+ const harnessIdentity = ctx.getHarnessIdentity();
250
+ if (harnessIdentity)
251
+ assertPinnedAgent(harnessIdentity, target.id);
252
+ ctx.persistClaudeSessionAgentName(process.env.CLAUDE_SESSION_ID, target.name);
253
+ agentId = target.id;
254
+ // Persist the switch so subsequent tool calls use the new agent.
255
+ // saveAgentPreference() MUST be called here so that a process
256
+ // restart (silent MCP reconnect) restores the switched agent from
257
+ // disk instead of silently reverting to the default
258
+ // (CORBOT-497C7FA3). Ids only — no token is ever written to disk.
259
+ // sessionAgentOverride MUST also be set so that a key-enrolled
260
+ // TokenManager doesn't clobber this switch on the very next
261
+ // ensureCredentials() call (the manager resolves identity once
262
+ // and never re-resolves it).
263
+ const currentCreds = ctx.getCredentials();
264
+ if (currentCreds) {
265
+ const switchedCreds = { ...currentCreds, agentId };
266
+ ctx.setCredentials(switchedCreds);
267
+ ctx.setSessionAgentOverride({ agentId, tenantId: switchedCreds.tenantId });
268
+ if (!harnessIdentity)
269
+ saveAgentPreference({ agentId, tenantId: switchedCreds.tenantId });
270
+ }
271
+ const loaded = await hydrateIdentity(ctx.aisUrl, agentId, token, memoriesLimit);
272
+ ctx.setAgentContext(loaded);
273
+ ctx.applyMemoryRefresh(agentId, token);
274
+ ctx.server.notification({ method: 'notifications/prompts/list_changed' });
275
+ ctx.stderr(`agent_load: switched to "${target.name}" (${target.id})`);
276
+ result = {
277
+ success: true,
278
+ agentId: target.id,
279
+ name: target.name,
280
+ did: loaded?.identity.did ?? null,
281
+ status: target.status,
282
+ memoriesLoaded: loaded?.recentMemories.length ?? 0,
283
+ goalsLoaded: loaded?.goals.length ?? 0,
284
+ };
285
+ break;
286
+ }
287
+ case 'inbox_send': {
288
+ const inboxSendArgs = parseInboxSendArgs(rawArgs);
289
+ result = await aisPost(`/v1/agents/${agentId}/inbox`, {
290
+ recipientAgentId: inboxSendArgs.recipientAgentId,
291
+ kind: inboxSendArgs.kind,
292
+ body: inboxSendArgs.body,
293
+ ...(inboxSendArgs.threadId !== undefined ? { threadId: inboxSendArgs.threadId } : {}),
294
+ ...(inboxSendArgs.taskId !== undefined ? { taskId: inboxSendArgs.taskId } : {}),
295
+ ...(inboxSendArgs.inReplyTo !== undefined ? { inReplyTo: inboxSendArgs.inReplyTo } : {}),
296
+ ...(inboxSendArgs.messageId !== undefined ? { messageId: inboxSendArgs.messageId } : {}),
297
+ ...(inboxSendArgs.ttlSeconds !== undefined ? { ttlSeconds: inboxSendArgs.ttlSeconds } : {}),
298
+ }, token);
299
+ break;
300
+ }
301
+ case 'inbox_read': {
302
+ const inboxReadArgs = parseInboxReadArgs(rawArgs);
303
+ const inboxParams = new URLSearchParams();
304
+ if (inboxReadArgs.cursor !== undefined)
305
+ inboxParams.set('cursor', inboxReadArgs.cursor);
306
+ inboxParams.set('limit', String(inboxReadArgs.limit));
307
+ inboxParams.set('unreadOnly', String(inboxReadArgs.unreadOnly));
308
+ result = await readInboxAndMaybeAck(inboxReadArgs, () => aisGet(`/v1/agents/${agentId}/inbox?${inboxParams}`, token), (messageIds) => aisPost(`/v1/agents/${agentId}/inbox/ack`, { messageIds }, token));
309
+ break;
310
+ }
311
+ case 'inbox_ack': {
312
+ const inboxAckArgs = parseInboxAckArgs(rawArgs);
313
+ result = await aisPost(`/v1/agents/${agentId}/inbox/ack`, { messageIds: inboxAckArgs.messageIds }, token);
314
+ break;
315
+ }
316
+ case 'goal_create': {
317
+ const goalCreateArgs = parseGoalCreateArgs(rawArgs);
318
+ result = await aisPost(`/v1/agents/${agentId}/goals`, {
319
+ title: goalCreateArgs.title,
320
+ description: goalCreateArgs.description,
321
+ ...(goalCreateArgs.successCriteria !== undefined ? { successCriteria: goalCreateArgs.successCriteria } : {}),
322
+ ...(goalCreateArgs.parentGoalId !== undefined ? { parentGoalId: goalCreateArgs.parentGoalId } : {}),
323
+ }, token);
324
+ break;
325
+ }
326
+ case 'goal_list': {
327
+ const goalListArgs = parseGoalListArgs(rawArgs);
328
+ const goalParams = new URLSearchParams();
329
+ if (goalListArgs.status !== undefined)
330
+ goalParams.set('status', goalListArgs.status);
331
+ if (goalListArgs.page !== undefined)
332
+ goalParams.set('page', String(goalListArgs.page));
333
+ goalParams.set('limit', String(goalListArgs.limit));
334
+ if (goalListArgs.parentGoalId !== undefined)
335
+ goalParams.set('parentGoalId', goalListArgs.parentGoalId);
336
+ result = await aisGet(`/v1/agents/${agentId}/goals?${goalParams}`, token);
337
+ break;
338
+ }
339
+ case 'goal_update_progress': {
340
+ const goalProgressArgs = parseGoalUpdateProgressArgs(rawArgs);
341
+ result = await aisPatch(`/v1/agents/${agentId}/goals/${goalProgressArgs.goalId}`, {
342
+ progress: goalProgressArgs.progress,
343
+ }, token);
344
+ break;
345
+ }
346
+ case 'goal_complete': {
347
+ const goalCompleteArgs = parseGoalCompleteArgs(rawArgs);
348
+ result = await aisPost(`/v1/agents/${agentId}/goals/${goalCompleteArgs.goalId}/complete`, {
349
+ success: goalCompleteArgs.success,
350
+ ...(goalCompleteArgs.notes !== undefined ? { notes: goalCompleteArgs.notes } : {}),
351
+ ...(goalCompleteArgs.lessonsLearned !== undefined ? { lessonsLearned: goalCompleteArgs.lessonsLearned } : {}),
352
+ }, token);
353
+ break;
354
+ }
355
+ default:
356
+ emitTelemetry({
357
+ event: 'tool.call',
358
+ tool: name,
359
+ agentIdHash: hashAgentId(agentId),
360
+ latencyMs: Date.now() - toolStartedAt,
361
+ status: 'error',
362
+ error: `Unknown tool: ${name}`,
363
+ });
364
+ return UNKNOWN_TOOL;
365
+ }
366
+ return result;
367
+ };
368
+ let result = await dispatchTool(await ctx.ensureCredentials());
369
+ if (isAuthErrorResult(result)) {
370
+ // CORBOT-A5BBD580: the server rejected our token mid-session
371
+ // (expired or secret rotated). Clear the cached creds, silently
372
+ // re-auth (key auth when a key file exists), and retry once.
373
+ ctx.stderr('AIS rejected the cached token; re-authenticating and retrying once...');
374
+ ctx.setCredentials(null);
375
+ // Drop the TokenManager's cached token too — without this, the
376
+ // key-enrolled path's ensureCredentials() would just re-serve the
377
+ // same still-time-valid-but-server-rejected token from `current`
378
+ // instead of re-running challenge/prove (CORBOT-A5BBD580: a JWT
379
+ // rejection mid-session, e.g. AIS rotating JWT_SECRET, must force a
380
+ // real re-auth, not a no-op retry with the same token). Also reset
381
+ // any escalated backoff window (CORBOT-4F7CAA8E / F2b): the server
382
+ // just responded with a 401, so it is reachable right now — a stale
383
+ // backoff window computed from unrelated prior renewal failures must
384
+ // not hold this re-prove behind the getCredentials() gate.
385
+ ctx.invalidateToken();
386
+ result = await dispatchTool(await ctx.ensureCredentials());
387
+ }
388
+ if (result === UNKNOWN_TOOL) {
389
+ return {
390
+ content: [{ type: 'text', text: JSON.stringify({ error: `Unknown tool: ${name}` }) }],
391
+ isError: true,
392
+ };
393
+ }
394
+ const okCreds = ctx.getCredentials();
395
+ emitTelemetry({
396
+ event: 'tool.call',
397
+ tool: name,
398
+ agentIdHash: okCreds ? hashAgentId(okCreds.agentId) : undefined,
399
+ latencyMs: Date.now() - toolStartedAt,
400
+ status: 'ok',
401
+ });
402
+ return {
403
+ content: [{ type: 'text', text: JSON.stringify(withUpdateNotice(name, result), null, 2) }],
404
+ };
405
+ }
406
+ catch (error) {
407
+ const message = error instanceof Error ? error.message : 'Unknown error';
408
+ const errorCreds = ctx.getCredentials();
409
+ const agentHash = errorCreds ? hashAgentId(errorCreds.agentId) : undefined;
410
+ emitTelemetry({
411
+ event: 'tool.call',
412
+ tool: name,
413
+ agentIdHash: agentHash,
414
+ latencyMs: Date.now() - toolStartedAt,
415
+ status: 'error',
416
+ error: message,
417
+ });
418
+ // BondPendingError carries human-readable text that the agent should
419
+ // render verbatim — return as plain text rather than JSON.
420
+ if (ctx.isBondPendingError(error)) {
421
+ return {
422
+ content: [{ type: 'text', text: message }],
423
+ isError: true,
424
+ };
425
+ }
426
+ return {
427
+ content: [{ type: 'text', text: JSON.stringify({ error: message }) }],
428
+ isError: true,
429
+ };
430
+ }
431
+ };
432
+ }
433
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Memory pull — read an agent's own memories back out of the Agent Identity
3
+ * Service and into a local JSON Lines backup (CORBOT-31C43CBD).
4
+ *
5
+ * WHY THIS EXISTS
6
+ * The package could only ever push local -> Agent Identity Service
7
+ * (LocalMirror, aismemory-sync). Nothing an agent API key can call brought
8
+ * memories back down, so memories written from the Claude app or from Codex
9
+ * never reached the local copy. The two export routes do not help a key-only
10
+ * caller:
11
+ * * POST /v1/agents/:agentId/export -> 403, `export` is not in the
12
+ * agent-API-key allowlist (agentApiKeyAuth.ts ALLOWED_AGENT_SUBRESOURCES).
13
+ * * POST /v1/agents/:agentId/memory/export -> 400 "platform is required";
14
+ * it pushes to a third-party platform adapter and refuses file paths over
15
+ * HTTP, so it cannot produce a local file.
16
+ *
17
+ * WHAT THIS DOES INSTEAD
18
+ * Pages the browse path of GET /v1/agents/:agentId/memory, which IS already on
19
+ * the allowlist and already supports `limit` + `offset` pagination. No server
20
+ * change and no access scope change: this is a client that uses a route the
21
+ * key can call today.
22
+ *
23
+ * SCOPE SAFETY
24
+ * The agent id is taken from the caller's own configuration and interpolated
25
+ * into the path; the server additionally rejects any request whose path agent
26
+ * does not equal the agent the key encodes. `principalAgentId` (the delegated
27
+ * cross-agent read parameter) is never sent, so a pull can only ever read the
28
+ * caller's own memories.
29
+ */
30
+ /**
31
+ * Server-side cap on `limit` for GET /v1/agents/:agentId/memory
32
+ * (agent-identity-service `env.benchQueryLimitCap`; a larger value is a 400).
33
+ */
34
+ export declare const MAX_PAGE_SIZE = 100;
35
+ /** Page size used when the caller does not choose one. */
36
+ export declare const DEFAULT_PAGE_SIZE = 100;
37
+ /**
38
+ * Hard stop on pages fetched, so a server that never reports exhaustion cannot
39
+ * spin forever. At the maximum page size this covers 500,000 memories, an order
40
+ * of magnitude above the 50,000 the `.aismem` export format itself allows.
41
+ */
42
+ export declare const MAX_PAGES = 5000;
43
+ /** One memory as the browse path returns it. Fields beyond `id` are passed through untouched. */
44
+ export interface PulledMemory {
45
+ id: string;
46
+ [key: string]: unknown;
47
+ }
48
+ export interface PullProgress {
49
+ /** 1-based index of the page just fetched. */
50
+ page: number;
51
+ /** Memories on that page that had not been seen before. */
52
+ added: number;
53
+ /** Distinct memories accumulated so far. */
54
+ total: number;
55
+ /** Server's reported corpus size, when it sent one. */
56
+ totalCount?: number;
57
+ }
58
+ export interface PullMemoriesOptions {
59
+ /** Base Agent Identity Service URL, no trailing slash. */
60
+ aisUrl: string;
61
+ /** The caller's own agent id — the only agent a scoped key may read. */
62
+ agentId: string;
63
+ /** Scoped `ais_ak_` agent API key. */
64
+ apiKey: string;
65
+ /** Memories per request. Clamped to 1..MAX_PAGE_SIZE. */
66
+ pageSize?: number;
67
+ /** Injected for tests. */
68
+ fetchImpl?: typeof globalThis.fetch;
69
+ /** Called after each page. */
70
+ onProgress?: (progress: PullProgress) => void;
71
+ }
72
+ export interface PullMemoriesResult {
73
+ memories: PulledMemory[];
74
+ /** Pages actually requested. */
75
+ pagesFetched: number;
76
+ /** Server's reported corpus size from the last page that carried one. */
77
+ totalCount?: number;
78
+ /** True when MAX_PAGES stopped the walk before the corpus was exhausted. */
79
+ truncated: boolean;
80
+ }
81
+ interface BrowsePage {
82
+ memories: PulledMemory[];
83
+ totalCount?: number;
84
+ }
85
+ /**
86
+ * Pull `data.memories` and `data.totalCount` out of a browse response, rejecting
87
+ * anything that does not have the documented shape. A silently-empty parse would
88
+ * be indistinguishable from "this agent has no memories" and would write an
89
+ * empty backup over a good one.
90
+ */
91
+ export declare function parseBrowsePage(payload: unknown): BrowsePage;
92
+ /** Clamp a requested page size into the range the server accepts. */
93
+ export declare function clampPageSize(requested: number | undefined): number;
94
+ /**
95
+ * Page the whole corpus for one agent, newest first.
96
+ *
97
+ * Deduplicates by memory id. This is load-bearing rather than defensive: the
98
+ * browse path orders by `createdAt` descending, so a memory written while the
99
+ * walk is in progress lands at offset 0 and shifts every later row down one,
100
+ * which would otherwise re-read a row that has already been captured.
101
+ */
102
+ export declare function pullMemories(options: PullMemoriesOptions): Promise<PullMemoriesResult>;
103
+ /**
104
+ * Render memories as JSON Lines: one memory object per line, in the order they
105
+ * were pulled (newest first). Always ends with a newline so the file can be
106
+ * appended to or concatenated cleanly.
107
+ */
108
+ export declare function toJsonLines(memories: readonly PulledMemory[]): string;
109
+ /**
110
+ * Turn an out-of-scope or rejected pull into a message that names the cause,
111
+ * rather than leaving a bare HTTP status for the operator to decode.
112
+ */
113
+ export declare function describePullFailure(error: unknown): string;
114
+ export {};