aismemory 0.7.0 → 0.7.2

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 (59) hide show
  1. package/README.md +11 -2
  2. package/dist/__tests__/agent-key-mode-e2e.test.js +78 -0
  3. package/dist/__tests__/agent-key-mode-e2e.test.js.map +1 -1
  4. package/dist/__tests__/agent-key-mode.test.js +63 -0
  5. package/dist/__tests__/agent-key-mode.test.js.map +1 -1
  6. package/dist/__tests__/agent-load-session-override-e2e.test.js +7 -5
  7. package/dist/__tests__/agent-load-session-override-e2e.test.js.map +1 -1
  8. package/dist/__tests__/agent-preference.test.js +99 -2
  9. package/dist/__tests__/agent-preference.test.js.map +1 -1
  10. package/dist/__tests__/ais-http.test.d.ts +1 -0
  11. package/dist/__tests__/ais-http.test.js +119 -0
  12. package/dist/__tests__/ais-http.test.js.map +1 -0
  13. package/dist/__tests__/auto-enroll-key.test.js +20 -0
  14. package/dist/__tests__/auto-enroll-key.test.js.map +1 -1
  15. package/dist/__tests__/delegated-read-args.test.d.ts +9 -0
  16. package/dist/__tests__/delegated-read-args.test.js +80 -0
  17. package/dist/__tests__/delegated-read-args.test.js.map +1 -0
  18. package/dist/__tests__/inbox-client.test.d.ts +1 -0
  19. package/dist/__tests__/inbox-client.test.js +108 -0
  20. package/dist/__tests__/inbox-client.test.js.map +1 -0
  21. package/dist/__tests__/key-auth.test.js +7 -1
  22. package/dist/__tests__/key-auth.test.js.map +1 -1
  23. package/dist/__tests__/provisional-register-mcp-remember.test.d.ts +1 -0
  24. package/dist/__tests__/provisional-register-mcp-remember.test.js +192 -0
  25. package/dist/__tests__/provisional-register-mcp-remember.test.js.map +1 -0
  26. package/dist/__tests__/reconnect-survival-e2e.test.d.ts +1 -0
  27. package/dist/__tests__/reconnect-survival-e2e.test.js +248 -0
  28. package/dist/__tests__/reconnect-survival-e2e.test.js.map +1 -0
  29. package/dist/__tests__/silent-renewal-e2e.test.js +12 -9
  30. package/dist/__tests__/silent-renewal-e2e.test.js.map +1 -1
  31. package/dist/__tests__/split-brain-upgrade-e2e.test.d.ts +1 -0
  32. package/dist/__tests__/split-brain-upgrade-e2e.test.js +206 -0
  33. package/dist/__tests__/split-brain-upgrade-e2e.test.js.map +1 -0
  34. package/dist/__tests__/token-manager.test.js +158 -1
  35. package/dist/__tests__/token-manager.test.js.map +1 -1
  36. package/dist/__tests__/tool-args.test.js +68 -1
  37. package/dist/__tests__/tool-args.test.js.map +1 -1
  38. package/dist/agent-key-mode.js +39 -5
  39. package/dist/agent-key-mode.js.map +1 -1
  40. package/dist/agent-preference.d.ts +36 -1
  41. package/dist/agent-preference.js +79 -3
  42. package/dist/agent-preference.js.map +1 -1
  43. package/dist/ais-http.d.ts +6 -0
  44. package/dist/ais-http.js +75 -0
  45. package/dist/ais-http.js.map +1 -0
  46. package/dist/inbox-client.d.ts +9 -0
  47. package/dist/inbox-client.js +74 -0
  48. package/dist/inbox-client.js.map +1 -0
  49. package/dist/index.js +189 -79
  50. package/dist/index.js.map +1 -1
  51. package/dist/key-auth.js +12 -6
  52. package/dist/key-auth.js.map +1 -1
  53. package/dist/token-manager.d.ts +33 -6
  54. package/dist/token-manager.js +115 -44
  55. package/dist/token-manager.js.map +1 -1
  56. package/dist/tool-args.d.ts +42 -0
  57. package/dist/tool-args.js +70 -0
  58. package/dist/tool-args.js.map +1 -1
  59. package/package.json +1 -1
@@ -12,7 +12,7 @@
12
12
  *
13
13
  * Server-side contract (packages/agent-identity-service/src/api/middleware/
14
14
  * agentApiKeyAuth.ts): the key authenticates ONLY
15
- * `/v1/agents/:agentId/{memory,goals,dream,full-context}`, and only when
15
+ * `/v1/agents/:agentId/{memory,goals,dream,full-context,inbox}`, and only when
16
16
  * :agentId equals the key's own agent. Every other route (tenant-wide agent
17
17
  * listing, handoff, personality, key management, ...) is 403'd server-side.
18
18
  * This module honors that scope client-side too: tools that need an
@@ -21,7 +21,8 @@
21
21
  */
22
22
  import { AisHttpError } from './ais-http-error.js';
23
23
  import { emitTelemetry } from './telemetry.js';
24
- import { parseEmptyToolArgs, parseRecallArgs, parseRememberArgs, } from './tool-args.js';
24
+ import { parseEmptyToolArgs, parseRecallArgs, parseFullContextArgs, parseRememberArgs, parseInboxSendArgs, parseInboxReadArgs, } from './tool-args.js';
25
+ import { readInboxAndMaybeAck } from './inbox-client.js';
25
26
  /** Thrown by loadAgentApiKeyConfig when AIS_AGENT_API_KEY is set without AIS_AGENT_ID. */
26
27
  export class AgentApiKeyConfigError extends Error {
27
28
  constructor(message) {
@@ -146,11 +147,22 @@ export async function dispatchToolKeyMode(aisUrl, config, name, rawArgs, fetchIm
146
147
  params.set('limit', String(args.limit));
147
148
  if (args.type !== undefined)
148
149
  params.set('types', args.type);
150
+ if (args.principalAgentId !== undefined) {
151
+ params.set('principalAgentId', args.principalAgentId);
152
+ }
149
153
  return aisKeyGet(aisUrl, `/v1/agents/${agentId}/memory?${params}`, apiKey, fetchImpl);
150
154
  }
151
- case 'full_context':
152
- parseEmptyToolArgs(rawArgs);
153
- return aisKeyGet(aisUrl, `/v1/agents/${agentId}/full-context`, apiKey, fetchImpl);
155
+ case 'full_context': {
156
+ const fcArgs = parseFullContextArgs(rawArgs);
157
+ const fcParams = new URLSearchParams();
158
+ if (fcArgs.principalAgentId !== undefined)
159
+ fcParams.set('principalAgentId', fcArgs.principalAgentId);
160
+ if (fcArgs.memoriesLimit !== undefined)
161
+ fcParams.set('memoriesLimit', String(fcArgs.memoriesLimit));
162
+ const fcQs = fcParams.toString();
163
+ const fcPath = `/v1/agents/${agentId}/full-context${fcQs ? `?${fcQs}` : ''}`;
164
+ return aisKeyGet(aisUrl, fcPath, apiKey, fetchImpl);
165
+ }
154
166
  case 'dream':
155
167
  parseEmptyToolArgs(rawArgs);
156
168
  return aisKeyPost(aisUrl, `/v1/agents/${agentId}/dream`, apiKey, {}, fetchImpl);
@@ -171,6 +183,28 @@ export async function dispatchToolKeyMode(aisUrl, config, name, rawArgs, fetchIm
171
183
  },
172
184
  };
173
185
  }
186
+ case 'inbox_send': {
187
+ const args = parseInboxSendArgs(rawArgs);
188
+ return aisKeyPost(aisUrl, `/v1/agents/${agentId}/inbox`, apiKey, {
189
+ recipientAgentId: args.recipientAgentId,
190
+ kind: args.kind,
191
+ body: args.body,
192
+ ...(args.threadId !== undefined ? { threadId: args.threadId } : {}),
193
+ ...(args.taskId !== undefined ? { taskId: args.taskId } : {}),
194
+ ...(args.inReplyTo !== undefined ? { inReplyTo: args.inReplyTo } : {}),
195
+ ...(args.messageId !== undefined ? { messageId: args.messageId } : {}),
196
+ ...(args.ttlSeconds !== undefined ? { ttlSeconds: args.ttlSeconds } : {}),
197
+ }, fetchImpl);
198
+ }
199
+ case 'inbox_read': {
200
+ const args = parseInboxReadArgs(rawArgs);
201
+ const params = new URLSearchParams();
202
+ if (args.cursor !== undefined)
203
+ params.set('cursor', args.cursor);
204
+ params.set('limit', String(args.limit));
205
+ params.set('unreadOnly', String(args.unreadOnly));
206
+ return readInboxAndMaybeAck(args, () => aisKeyGet(aisUrl, `/v1/agents/${agentId}/inbox?${params}`, apiKey, fetchImpl), (messageIds) => aisKeyPost(aisUrl, `/v1/agents/${agentId}/inbox/ack`, apiKey, { messageIds }, fetchImpl));
207
+ }
174
208
  case 'handoff':
175
209
  throw new OutOfScopeToolError('handoff', "the handoff route is outside the key's allowed scope (memory, goals, dream, full-context).");
176
210
  case 'agent_load':
@@ -1 +1 @@
1
- {"version":3,"file":"agent-key-mode.js","sourceRoot":"","sources":["../src/agent-key-mode.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-key-mode.js","sourceRoot":"","sources":["../src/agent-key-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAOzD,0FAA0F;AAC1F,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAA0C,OAAO,CAAC,GAAG;IAErD,MAAM,SAAS,GAAG,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC3C,4EAA4E;IAC5E,qEAAqE;IACrE,2EAA2E;IAC3E,6DAA6D;IAC7D,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEzC,4EAA4E;IAC5E,2EAA2E;IAC3E,2DAA2D;IAC3D,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,sBAAsB,CAC9B,4DAA4D;YAC1D,oEAAoE;YACpE,yCAAyC;YACzC,uEAAuE,CAC1E,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,sBAAsB,CAC9B,uEAAuE;YACrE,kEAAkE;YAClE,mDAAmD,CACtD,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,sBAAsB,CAC9B,yDAAyD;YACvD,8EAA8E;YAC9E,wEAAwE;YACxE,uEAAuE;YACvE,4DAA4D,CAC/D,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC;AAMD,KAAK,UAAU,QAAQ,CAAC,GAAa;IACnC,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAc,EACd,IAAY,EACZ,MAAc,EACd,IAAa,EACb,YAAuB,UAAU,CAAC,KAAK;IAEvC,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,iBAAiB,EAAE,MAAM;KAC1B,CAAC;IACF,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrG,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5G,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,aAAa,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxG,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAc,EACd,IAAY,EACZ,MAAc,EACd,YAAuB,UAAU,CAAC,KAAK;IAEvC,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,iBAAiB,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACxF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5G,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,aAAa,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxG,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4EAA4E;AAE5E,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAErE;;;;;;GAMG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,IAAY,EAAE,MAAc;QACtC,KAAK,CAAC,GAAG,IAAI,mEAAmE,MAAM,EAAE,CAAC,CAAC;QAC1F,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAc,EACd,MAAyB,EACzB,IAAY,EACZ,OAAgB,EAChB,YAAuB,UAAU,CAAC,KAAK;IAEvC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAEnC,QAAQ,IAAI,EAAE,CAAC;QACf,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;YACxC,OAAO,UAAU,CAAC,MAAM,EAAE,cAAc,OAAO,SAAS,EAAE,MAAM,EAAE;gBAChE,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,UAAU,EAAE,IAAI,CAAC,UAAU;aAC5B,EAAE,SAAS,CAAC,CAAC;QAChB,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;YACtC,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;gBAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;gBAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5D,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBACxC,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,SAAS,CAAC,MAAM,EAAE,cAAc,OAAO,WAAW,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACxF,CAAC;QAED,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC7C,MAAM,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS;gBAAE,QAAQ,CAAC,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACrG,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS;gBAAE,QAAQ,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;YACpG,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,cAAc,OAAO,gBAAgB,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC7E,OAAO,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACtD,CAAC;QAED,KAAK,OAAO;YACV,kBAAkB,CAAC,OAAO,CAAC,CAAC;YAC5B,OAAO,UAAU,CAAC,MAAM,EAAE,cAAc,OAAO,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;QAElF,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,kBAAkB,CAAC,OAAO,CAAC,CAAC;YAC5B,sEAAsE;YACtE,kEAAkE;YAClE,iEAAiE;YACjE,sEAAsE;YACtE,yEAAyE;YACzE,MAAM,SAAS,CAAC,MAAM,EAAE,cAAc,OAAO,iBAAiB,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;YACnF,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,OAAO;oBACP,QAAQ,EAAE,eAAe;oBACzB,QAAQ,EAAE,IAAI;iBACf;aACF,CAAC;QACJ,CAAC;QAED,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,UAAU,CAAC,MAAM,EAAE,cAAc,OAAO,QAAQ,EAAE,MAAM,EAAE;gBAC/D,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;gBACvC,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnE,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtE,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtE,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1E,EAAE,SAAS,CAAC,CAAC;QAChB,CAAC;QAED,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;gBAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACjE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAClD,OAAO,oBAAoB,CACzB,IAAI,EACJ,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,cAAc,OAAO,UAAU,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EACnF,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,cAAc,OAAO,YAAY,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,EAAE,SAAS,CAAC,CACzG,CAAC;QACJ,CAAC;QAED,KAAK,SAAS;YACZ,MAAM,IAAI,mBAAmB,CAC3B,SAAS,EACT,4FAA4F,CAC7F,CAAC;QAEJ,KAAK,YAAY;YACf,MAAM,IAAI,mBAAmB,CAC3B,YAAY,EACZ,oFAAoF;gBAClF,8FAA8F,CACjG,CAAC;QAEJ;YACE,OAAO,qBAAqB,CAAC;IAC/B,CAAC;AACH,CAAC"}
@@ -7,18 +7,53 @@ export interface AgentPreference {
7
7
  * Persist agent preference (schemaVersion + ids, no secrets) under
8
8
  * ~/.aismemory/credentials.json with restrictive POSIX permissions
9
9
  * (dir 0700, file 0600). Replaces legacy token-based persistence.
10
+ *
11
+ * F6 (CORBOT-48DD2E25): writes via a tmp file + renameSync so a crash
12
+ * mid-write can never leave a truncated/corrupt credentials.json behind,
13
+ * and two processes racing this same path never interleave partial writes
14
+ * (mirrors the atomic-write pattern in config.ts:59-62).
10
15
  */
11
16
  export declare function saveAgentPreference(pref: {
12
17
  agentId: string;
13
18
  tenantId: string;
14
19
  }, home?: string): void;
20
+ /**
21
+ * Migrate a legacy v1 credentials.json (token/agentId/tenantId/expiresAt) to
22
+ * the v2 schema (schemaVersion + ids only) IN PLACE, atomically — but ONLY
23
+ * when a device key is enrolled.
24
+ *
25
+ * F5a (CORBOT-48DD2E25): once a device key exists, the TokenManager mints
26
+ * its own tokens via key auth and the disk bearer is no longer needed —
27
+ * it must not survive past the first process start that observes both the
28
+ * v1 file and the enrolled key ("zero secrets at rest" was false for that
29
+ * window before this fix; the bearer used to live on disk until the next
30
+ * unrelated write).
31
+ *
32
+ * F5b (CORBOT-48DD2E25): when NO device key is enrolled, migrating here
33
+ * would strand that cohort with neither a live disk token nor a key to
34
+ * silently re-auth with — every silent stdio respawn would then demand a
35
+ * fresh browser bond, which 0.6.2 never did (it kept the token on disk and
36
+ * reconnected silently). So the v1 token is deliberately left in place
37
+ * until a key gets enrolled (this same check migrates it on the very next
38
+ * load) or a fresh device-flow completion overwrites the file.
39
+ *
40
+ * Best-effort: any read/parse/write failure is swallowed — migration must
41
+ * never block startup or credential loading. `home`/`hasKey` are
42
+ * parameterized for tests; production callers use the defaults.
43
+ */
44
+ export declare function migrateCredentialsFileIfNeeded(home?: string, hasKey?: () => boolean): void;
15
45
  /**
16
46
  * Load agent preference from ~/.aismemory/credentials.json.
17
47
  * Handles both v2 files (agentId/tenantId only) and legacy v1 files
18
48
  * (token/agentId/tenantId/expiresAt) — returns ids only.
19
49
  * Returns null if file is missing or corrupt.
50
+ *
51
+ * Triggers migrateCredentialsFileIfNeeded() first (F5a/F5b) so every
52
+ * caller on this path — including the TokenManager's per-acquire
53
+ * resolveIdentity() in index.ts — helps migrate a v1 file left over from
54
+ * before the device key was enrolled.
20
55
  */
21
- export declare function loadAgentPreference(home?: string): {
56
+ export declare function loadAgentPreference(home?: string, hasKey?: () => boolean): {
22
57
  agentId: string;
23
58
  tenantId: string;
24
59
  } | null;
@@ -1,14 +1,26 @@
1
- import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
1
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
3
4
  import { credentialsDir, credentialsFilePath } from './oauth-credentials.js';
5
+ import { hasEnrolledKey } from './key-auth.js';
6
+ /** Default hasKey() check for `home`, wired to the real on-disk key store. */
7
+ function defaultHasKey(home) {
8
+ return () => hasEnrolledKey({ keysDir: join(home, '.aismemory', 'keys') });
9
+ }
4
10
  /**
5
11
  * Persist agent preference (schemaVersion + ids, no secrets) under
6
12
  * ~/.aismemory/credentials.json with restrictive POSIX permissions
7
13
  * (dir 0700, file 0600). Replaces legacy token-based persistence.
14
+ *
15
+ * F6 (CORBOT-48DD2E25): writes via a tmp file + renameSync so a crash
16
+ * mid-write can never leave a truncated/corrupt credentials.json behind,
17
+ * and two processes racing this same path never interleave partial writes
18
+ * (mirrors the atomic-write pattern in config.ts:59-62).
8
19
  */
9
20
  export function saveAgentPreference(pref, home = homedir()) {
10
21
  const dir = credentialsDir(home);
11
22
  const file = credentialsFilePath(home);
23
+ const tmp = `${file}.tmp`;
12
24
  // Create directory with restrictive permissions (0700)
13
25
  mkdirSync(dir, { recursive: true, mode: 0o700 });
14
26
  // Write the file with schemaVersion + ids (no legacy token/expiresAt)
@@ -17,19 +29,83 @@ export function saveAgentPreference(pref, home = homedir()) {
17
29
  agentId: pref.agentId,
18
30
  tenantId: pref.tenantId,
19
31
  };
20
- writeFileSync(file, JSON.stringify(data, null, 2), { mode: 0o600 });
32
+ writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 0o600 });
33
+ renameSync(tmp, file);
21
34
  // chmod is the reliable path on POSIX
22
35
  if (process.platform !== 'win32') {
23
36
  chmodSync(file, 0o600);
24
37
  }
25
38
  }
39
+ /**
40
+ * Migrate a legacy v1 credentials.json (token/agentId/tenantId/expiresAt) to
41
+ * the v2 schema (schemaVersion + ids only) IN PLACE, atomically — but ONLY
42
+ * when a device key is enrolled.
43
+ *
44
+ * F5a (CORBOT-48DD2E25): once a device key exists, the TokenManager mints
45
+ * its own tokens via key auth and the disk bearer is no longer needed —
46
+ * it must not survive past the first process start that observes both the
47
+ * v1 file and the enrolled key ("zero secrets at rest" was false for that
48
+ * window before this fix; the bearer used to live on disk until the next
49
+ * unrelated write).
50
+ *
51
+ * F5b (CORBOT-48DD2E25): when NO device key is enrolled, migrating here
52
+ * would strand that cohort with neither a live disk token nor a key to
53
+ * silently re-auth with — every silent stdio respawn would then demand a
54
+ * fresh browser bond, which 0.6.2 never did (it kept the token on disk and
55
+ * reconnected silently). So the v1 token is deliberately left in place
56
+ * until a key gets enrolled (this same check migrates it on the very next
57
+ * load) or a fresh device-flow completion overwrites the file.
58
+ *
59
+ * Best-effort: any read/parse/write failure is swallowed — migration must
60
+ * never block startup or credential loading. `home`/`hasKey` are
61
+ * parameterized for tests; production callers use the defaults.
62
+ */
63
+ export function migrateCredentialsFileIfNeeded(home = homedir(), hasKey = defaultHasKey(home)) {
64
+ const file = credentialsFilePath(home);
65
+ try {
66
+ if (!existsSync(file))
67
+ return;
68
+ const raw = readFileSync(file, 'utf-8');
69
+ const parsed = JSON.parse(raw);
70
+ // Already v2 (or an unrecognized shape) — nothing to migrate.
71
+ if (typeof parsed['token'] !== 'string')
72
+ return;
73
+ const agentId = parsed['agentId'];
74
+ const tenantId = parsed['tenantId'];
75
+ if (typeof agentId !== 'string' || typeof tenantId !== 'string')
76
+ return;
77
+ // F5b: do not strand the no-enrolled-key cohort.
78
+ if (!hasKey())
79
+ return;
80
+ const dir = credentialsDir(home);
81
+ const tmp = `${file}.tmp`;
82
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
83
+ const data = { schemaVersion: 2, agentId, tenantId };
84
+ writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 0o600 });
85
+ renameSync(tmp, file);
86
+ if (process.platform !== 'win32') {
87
+ chmodSync(file, 0o600);
88
+ }
89
+ }
90
+ catch {
91
+ // Best-effort — a migration failure must never block startup. The
92
+ // existing v1-tolerant parse in loadAgentPreference (below) and
93
+ // loadCredentials (index.ts) still work even if migration didn't run.
94
+ }
95
+ }
26
96
  /**
27
97
  * Load agent preference from ~/.aismemory/credentials.json.
28
98
  * Handles both v2 files (agentId/tenantId only) and legacy v1 files
29
99
  * (token/agentId/tenantId/expiresAt) — returns ids only.
30
100
  * Returns null if file is missing or corrupt.
101
+ *
102
+ * Triggers migrateCredentialsFileIfNeeded() first (F5a/F5b) so every
103
+ * caller on this path — including the TokenManager's per-acquire
104
+ * resolveIdentity() in index.ts — helps migrate a v1 file left over from
105
+ * before the device key was enrolled.
31
106
  */
32
- export function loadAgentPreference(home = homedir()) {
107
+ export function loadAgentPreference(home = homedir(), hasKey = defaultHasKey(home)) {
108
+ migrateCredentialsFileIfNeeded(home, hasKey);
33
109
  const file = credentialsFilePath(home);
34
110
  try {
35
111
  if (!existsSync(file))
@@ -1 +1 @@
1
- {"version":3,"file":"agent-preference.js","sourceRoot":"","sources":["../src/agent-preference.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAQ7E;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAA2C,EAC3C,OAAe,OAAO,EAAE;IAExB,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAEvC,uDAAuD;IACvD,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEjD,sEAAsE;IACtE,MAAM,IAAI,GAAG;QACX,aAAa,EAAE,CAAC;QAChB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC;IAEF,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEpE,sCAAsC;IACtC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe,OAAO,EAAE;IAI1D,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAEnC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;QAE9D,uEAAuE;QACvE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAEjC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC/B,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"agent-preference.js","sourceRoot":"","sources":["../src/agent-preference.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * AIS HTTP helpers — extracted from index.ts for reuse without MCP side effects.
3
+ * CORBOT-282AE4FE
4
+ */
5
+ export declare function aisPost(path: string, body: unknown, token?: string): Promise<unknown>;
6
+ export declare function aisGet(path: string, token: string): Promise<unknown>;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * AIS HTTP helpers — extracted from index.ts for reuse without MCP side effects.
3
+ * CORBOT-282AE4FE
4
+ */
5
+ import { isAuthErrorResult } from './auth-staleness.js';
6
+ import { AisHttpError } from './ais-http-error.js';
7
+ import { emitTelemetry } from './telemetry.js';
8
+ const AIS_URL = process.env['AIS_URL'] ?? 'https://ais.agentsandswarms.ai';
9
+ export async function aisPost(path, body, token) {
10
+ const headers = { 'Content-Type': 'application/json' };
11
+ if (token)
12
+ headers['Authorization'] = `Bearer ${token}`;
13
+ let res;
14
+ try {
15
+ res = await fetch(`${AIS_URL}${path}`, {
16
+ method: 'POST',
17
+ headers,
18
+ body: JSON.stringify(body),
19
+ });
20
+ }
21
+ catch (err) {
22
+ emitTelemetry({
23
+ event: 'ais.http.failure',
24
+ path,
25
+ error: err instanceof Error ? err.message : String(err),
26
+ });
27
+ throw err;
28
+ }
29
+ const data = await res.json().catch(() => null);
30
+ if (!res.ok) {
31
+ emitTelemetry({
32
+ event: 'ais.http.failure',
33
+ path,
34
+ httpStatus: res.status,
35
+ error: `HTTP ${res.status}`,
36
+ });
37
+ // Token-rejection bodies feed the silent re-auth-and-retry loop; every
38
+ // other non-2xx must throw so a failed write surfaces as an MCP error
39
+ // instead of being mistaken for a successful one.
40
+ if (isAuthErrorResult(data))
41
+ return data;
42
+ throw new AisHttpError(res.status, path, data);
43
+ }
44
+ return data;
45
+ }
46
+ export async function aisGet(path, token) {
47
+ let res;
48
+ try {
49
+ res = await fetch(`${AIS_URL}${path}`, {
50
+ headers: { 'Authorization': `Bearer ${token}` },
51
+ });
52
+ }
53
+ catch (err) {
54
+ emitTelemetry({
55
+ event: 'ais.http.failure',
56
+ path,
57
+ error: err instanceof Error ? err.message : String(err),
58
+ });
59
+ throw err;
60
+ }
61
+ const data = await res.json().catch(() => null);
62
+ if (!res.ok) {
63
+ emitTelemetry({
64
+ event: 'ais.http.failure',
65
+ path,
66
+ httpStatus: res.status,
67
+ error: `HTTP ${res.status}`,
68
+ });
69
+ if (isAuthErrorResult(data))
70
+ return data;
71
+ throw new AisHttpError(res.status, path, data);
72
+ }
73
+ return data;
74
+ }
75
+ //# sourceMappingURL=ais-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ais-http.js","sourceRoot":"","sources":["../src/ais-http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,gCAAgC,CAAC;AAE3E,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAY,EAAE,IAAa,EAAE,KAAc;IACvE,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;IAC/E,IAAI,KAAK;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;IACxD,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,CAAC;YACZ,KAAK,EAAE,kBAAkB;YACzB,IAAI;YACJ,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC,CAAC;QACH,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,aAAa,CAAC;YACZ,KAAK,EAAE,kBAAkB;YACzB,IAAI;YACJ,UAAU,EAAE,GAAG,CAAC,MAAM;YACtB,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE;SAC5B,CAAC,CAAC;QACH,uEAAuE;QACvE,sEAAsE;QACtE,kDAAkD;QAClD,IAAI,iBAAiB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAY,EAAE,KAAa;IACtD,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,EAAE;YACrC,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,KAAK,EAAE,EAAE;SAChD,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,CAAC;YACZ,KAAK,EAAE,kBAAkB;YACzB,IAAI;YACJ,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC,CAAC;QACH,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,aAAa,CAAC;YACZ,KAAK,EAAE,kBAAkB;YACzB,IAAI;YACJ,UAAU,EAAE,GAAG,CAAC,MAAM;YACtB,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE;SAC5B,CAAC,CAAC;QACH,IAAI,iBAAiB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { InboxReadArgs } from './tool-args.js';
2
+ /**
3
+ * Reads one inbox page via `getPage`, then acks the returned messageIds via
4
+ * `ackMessages` when `args.ack` is set. Both callbacks return AIS's raw
5
+ * response body (as `aisGet`/`aisPost`/`aisKeyGet`/`aisKeyPost` already do);
6
+ * an auth-error body from either call is returned as-is so the caller's
7
+ * existing re-auth-and-retry loop (`isAuthErrorResult`) still fires.
8
+ */
9
+ export declare function readInboxAndMaybeAck(args: InboxReadArgs, getPage: () => Promise<unknown>, ackMessages: (messageIds: string[]) => Promise<unknown>): Promise<unknown>;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Client-side composition for `inbox_read` (CORBOT-7115B8AE).
3
+ *
4
+ * AIS's own `inbox_read` MCP handler
5
+ * (agent-identity-service/src/mcp/handlers/agent-inbox-handlers.ts) folds a
6
+ * conditional ack into one call because it already holds the
7
+ * AgentMessageService in-process. This package instead talks to AIS over
8
+ * REST (GET /v1/agents/:agentId/inbox, POST .../inbox/ack), so the same
9
+ * "read a page, then ack what it returned" composition has to happen here —
10
+ * shaped to match handleInboxRead's result exactly (messages, nextCursor,
11
+ * unreadRemaining?, acked?) so a caller sees the same contract regardless of
12
+ * which AIS entrypoint served it.
13
+ */
14
+ import { isAuthErrorResult } from './auth-staleness.js';
15
+ /** Mirrors AIS core/inbox/types.ts MAX_ACK_IDS. A page never exceeds it (MAX_PAGE_SIZE === MAX_ACK_IDS), so no chunking is needed. */
16
+ const MAX_ACK_IDS = 100;
17
+ function isInboxMessageArray(value) {
18
+ return (Array.isArray(value) &&
19
+ value.every((item) => typeof item === 'object' && item !== null && typeof item.messageId === 'string'));
20
+ }
21
+ function isInboxListResponse(value) {
22
+ if (typeof value !== 'object' || value === null)
23
+ return false;
24
+ const r = value;
25
+ if (r.success !== true || typeof r.data !== 'object' || r.data === null)
26
+ return false;
27
+ const d = r.data;
28
+ return isInboxMessageArray(d.messages) && (typeof d.nextCursor === 'string' || d.nextCursor === null) && typeof d.hasMore === 'boolean';
29
+ }
30
+ function isAckResponse(value) {
31
+ if (typeof value !== 'object' || value === null)
32
+ return false;
33
+ const r = value;
34
+ if (r.success !== true || typeof r.data !== 'object' || r.data === null)
35
+ return false;
36
+ const acked = r.data.acked;
37
+ return Array.isArray(acked) && acked.every((id) => typeof id === 'string');
38
+ }
39
+ /**
40
+ * Reads one inbox page via `getPage`, then acks the returned messageIds via
41
+ * `ackMessages` when `args.ack` is set. Both callbacks return AIS's raw
42
+ * response body (as `aisGet`/`aisPost`/`aisKeyGet`/`aisKeyPost` already do);
43
+ * an auth-error body from either call is returned as-is so the caller's
44
+ * existing re-auth-and-retry loop (`isAuthErrorResult`) still fires.
45
+ */
46
+ export async function readInboxAndMaybeAck(args, getPage, ackMessages) {
47
+ const page = await getPage();
48
+ if (isAuthErrorResult(page))
49
+ return page;
50
+ if (!isInboxListResponse(page)) {
51
+ // AIS's response envelope changed shape underneath us — surface it
52
+ // verbatim rather than guessing, same as every other tool's `result`.
53
+ return page;
54
+ }
55
+ const { messages, nextCursor, hasMore } = page.data;
56
+ const result = { messages, nextCursor };
57
+ if (args.ack && messages.length > 0) {
58
+ const ids = messages.slice(0, MAX_ACK_IDS).map((m) => m.messageId);
59
+ const ackResult = await ackMessages(ids);
60
+ if (isAuthErrorResult(ackResult))
61
+ return ackResult;
62
+ result.acked = isAckResponse(ackResult) ? ackResult.data.acked : ids;
63
+ }
64
+ else if (args.ack) {
65
+ result.acked = [];
66
+ }
67
+ // Exact only when this read reached the end of the unread stream — see
68
+ // handleInboxRead's identical comment in agent-inbox-handlers.ts.
69
+ if (args.unreadOnly && !hasMore) {
70
+ result.unreadRemaining = args.ack ? 0 : messages.length;
71
+ }
72
+ return { success: true, data: result };
73
+ }
74
+ //# sourceMappingURL=inbox-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox-client.js","sourceRoot":"","sources":["../src/inbox-client.ts"],"names":[],"mappings":"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"}