agenthub-multiagent-mcp 1.61.0 → 1.65.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 (131) hide show
  1. package/README.md +3 -3
  2. package/dist/brain/memvidBrain.d.ts +22 -0
  3. package/dist/brain/memvidBrain.d.ts.map +1 -1
  4. package/dist/brain/memvidBrain.js +41 -2
  5. package/dist/brain/memvidBrain.js.map +1 -1
  6. package/dist/brain/memvidBrain.test.js +90 -0
  7. package/dist/brain/memvidBrain.test.js.map +1 -1
  8. package/dist/brain/migrate.d.ts +43 -0
  9. package/dist/brain/migrate.d.ts.map +1 -1
  10. package/dist/brain/migrate.js +148 -23
  11. package/dist/brain/migrate.js.map +1 -1
  12. package/dist/brain/migrate.test.js +194 -1
  13. package/dist/brain/migrate.test.js.map +1 -1
  14. package/dist/channel.js +47 -5
  15. package/dist/channel.js.map +1 -1
  16. package/dist/channelDiagnostics.d.ts +36 -0
  17. package/dist/channelDiagnostics.d.ts.map +1 -1
  18. package/dist/channelDiagnostics.js +65 -0
  19. package/dist/channelDiagnostics.js.map +1 -1
  20. package/dist/channelDiagnostics.test.js +81 -1
  21. package/dist/channelDiagnostics.test.js.map +1 -1
  22. package/dist/client.d.ts +17 -0
  23. package/dist/client.d.ts.map +1 -1
  24. package/dist/client.js +32 -0
  25. package/dist/client.js.map +1 -1
  26. package/dist/daemon.js +16 -22
  27. package/dist/daemon.js.map +1 -1
  28. package/dist/index.js +36 -3
  29. package/dist/index.js.map +1 -1
  30. package/dist/lib/pending-items.d.ts +63 -0
  31. package/dist/lib/pending-items.d.ts.map +1 -0
  32. package/dist/lib/pending-items.js +96 -0
  33. package/dist/lib/pending-items.js.map +1 -0
  34. package/dist/pinSweep.d.ts +83 -0
  35. package/dist/pinSweep.d.ts.map +1 -0
  36. package/dist/pinSweep.js +105 -0
  37. package/dist/pinSweep.js.map +1 -0
  38. package/dist/pinSweep.test.d.ts +12 -0
  39. package/dist/pinSweep.test.d.ts.map +1 -0
  40. package/dist/pinSweep.test.js +110 -0
  41. package/dist/pinSweep.test.js.map +1 -0
  42. package/dist/pinSweepCli.d.ts +20 -0
  43. package/dist/pinSweepCli.d.ts.map +1 -0
  44. package/dist/pinSweepCli.js +287 -0
  45. package/dist/pinSweepCli.js.map +1 -0
  46. package/dist/run-claude.sh +36 -5
  47. package/dist/sessionCapture.d.ts.map +1 -1
  48. package/dist/sessionCapture.js +7 -1
  49. package/dist/sessionCapture.js.map +1 -1
  50. package/dist/sessionCapture.test.js +20 -0
  51. package/dist/sessionCapture.test.js.map +1 -1
  52. package/dist/setup.js +11 -0
  53. package/dist/setup.js.map +1 -1
  54. package/dist/shiftFiles.d.ts +33 -0
  55. package/dist/shiftFiles.d.ts.map +1 -0
  56. package/dist/shiftFiles.js +57 -0
  57. package/dist/shiftFiles.js.map +1 -0
  58. package/dist/shiftFiles.test.d.ts +2 -0
  59. package/dist/shiftFiles.test.d.ts.map +1 -0
  60. package/dist/shiftFiles.test.js +141 -0
  61. package/dist/shiftFiles.test.js.map +1 -0
  62. package/dist/skillInstaller.d.ts.map +1 -1
  63. package/dist/skillInstaller.gate.test.js +2 -0
  64. package/dist/skillInstaller.gate.test.js.map +1 -1
  65. package/dist/skillInstaller.js +8 -0
  66. package/dist/skillInstaller.js.map +1 -1
  67. package/dist/skillInstaller.test.js +8 -1
  68. package/dist/skillInstaller.test.js.map +1 -1
  69. package/dist/tools/goshtiRead.d.ts +72 -0
  70. package/dist/tools/goshtiRead.d.ts.map +1 -0
  71. package/dist/tools/goshtiRead.js +274 -0
  72. package/dist/tools/goshtiRead.js.map +1 -0
  73. package/dist/tools/goshtiRead.test.d.ts +8 -0
  74. package/dist/tools/goshtiRead.test.d.ts.map +1 -0
  75. package/dist/tools/goshtiRead.test.js +182 -0
  76. package/dist/tools/goshtiRead.test.js.map +1 -0
  77. package/dist/tools/inboxBounds.d.ts +80 -0
  78. package/dist/tools/inboxBounds.d.ts.map +1 -0
  79. package/dist/tools/inboxBounds.js +105 -0
  80. package/dist/tools/inboxBounds.js.map +1 -0
  81. package/dist/tools/inboxBounds.test.d.ts +15 -0
  82. package/dist/tools/inboxBounds.test.d.ts.map +1 -0
  83. package/dist/tools/inboxBounds.test.js +135 -0
  84. package/dist/tools/inboxBounds.test.js.map +1 -0
  85. package/dist/tools/index.d.ts +11 -0
  86. package/dist/tools/index.d.ts.map +1 -1
  87. package/dist/tools/index.js +106 -102
  88. package/dist/tools/index.js.map +1 -1
  89. package/dist/tools/intakeRequests.d.ts +35 -0
  90. package/dist/tools/intakeRequests.d.ts.map +1 -0
  91. package/dist/tools/intakeRequests.js +344 -0
  92. package/dist/tools/intakeRequests.js.map +1 -0
  93. package/dist/tools/intakeRequests.test.d.ts +8 -0
  94. package/dist/tools/intakeRequests.test.d.ts.map +1 -0
  95. package/dist/tools/intakeRequests.test.js +183 -0
  96. package/dist/tools/intakeRequests.test.js.map +1 -0
  97. package/dist/tools/openspec-viz/taskSync.d.ts +115 -0
  98. package/dist/tools/openspec-viz/taskSync.d.ts.map +1 -0
  99. package/dist/tools/openspec-viz/taskSync.js +144 -0
  100. package/dist/tools/openspec-viz/taskSync.js.map +1 -0
  101. package/dist/tools/openspec-viz/taskSync.test.d.ts +2 -0
  102. package/dist/tools/openspec-viz/taskSync.test.d.ts.map +1 -0
  103. package/dist/tools/openspec-viz/taskSync.test.js +198 -0
  104. package/dist/tools/openspec-viz/taskSync.test.js.map +1 -0
  105. package/dist/tools/pushedItemsSafety.test.d.ts +12 -0
  106. package/dist/tools/pushedItemsSafety.test.d.ts.map +1 -0
  107. package/dist/tools/pushedItemsSafety.test.js +179 -0
  108. package/dist/tools/pushedItemsSafety.test.js.map +1 -0
  109. package/dist/tools/tools.test.js +17 -5
  110. package/dist/tools/tools.test.js.map +1 -1
  111. package/dist/tools/wrapperCost.test.d.ts +13 -0
  112. package/dist/tools/wrapperCost.test.d.ts.map +1 -0
  113. package/dist/tools/wrapperCost.test.js +149 -0
  114. package/dist/tools/wrapperCost.test.js.map +1 -0
  115. package/dist/websocket.d.ts +30 -1
  116. package/dist/websocket.d.ts.map +1 -1
  117. package/dist/websocket.js +40 -3
  118. package/dist/websocket.js.map +1 -1
  119. package/dist/websocketQueue.test.d.ts +10 -0
  120. package/dist/websocketQueue.test.d.ts.map +1 -0
  121. package/dist/websocketQueue.test.js +78 -0
  122. package/dist/websocketQueue.test.js.map +1 -0
  123. package/package.json +4 -4
  124. package/skills/catalog.json +23 -10
  125. package/skills/commands/close-session.md +144 -144
  126. package/skills/commands/start-session.md +25 -6
  127. package/skills/manifest.json +8 -1
  128. package/skills/skills/code-brain-hook/SKILL.md +61 -61
  129. package/skills/skills/file-bug/SKILL.md +75 -75
  130. package/skills/skills/inbox/SKILL.md +99 -0
  131. package/skills/skills/multiagent-brainstorm/SKILL.md +164 -164
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Bounds for the check_inbox payload (fix-inbox-delivery-and-tool-wrapping §1).
3
+ *
4
+ * check_inbox used to pass no `limit`, so the server applied its own default of
5
+ * 50 messages with full bodies and nothing truncated anywhere in the path. One
6
+ * such call measured 115,769 characters across 787 lines, exceeded the
7
+ * tool-result token budget, and never reached the model — the harness spilled it
8
+ * to a file. From the model's seat an unusable result is indistinguishable from
9
+ * a hang, which is how it was first reported.
10
+ *
11
+ * The cap alone would not be a fix. A caller that silently receives 10 of 40
12
+ * messages has no way to know, and the loss happened precisely because a
13
+ * slash-command bulk-marked read a result nobody had actually seen. So every
14
+ * bound here is paired with a signal: `truncated`, `omitted_count`, and a
15
+ * `_truncated` marker naming the original byte length on any clipped body.
16
+ *
17
+ * The rule that follows — never bulk-ack a truncated result — belongs to the
18
+ * caller, and is why the bundled `inbox` skill is part of this change.
19
+ */
20
+ import type { Message } from "../client.js";
21
+ /** Messages returned when the caller names no limit. */
22
+ export declare const CHECK_INBOX_DEFAULT_LIMIT = 10;
23
+ /**
24
+ * Hard ceiling on messages per call, whatever the caller asks for. The server
25
+ * clamps too; this stops a client from making the request in the first place.
26
+ */
27
+ export declare const CHECK_INBOX_MAX_LIMIT = 50;
28
+ /**
29
+ * Per-message body cap. Generous enough for a normal A2A message to arrive
30
+ * whole — the bodies that blew the budget were multi-kilobyte bug reports — and
31
+ * small enough that a full page of them cannot.
32
+ */
33
+ export declare const CHECK_INBOX_BODY_CAP_BYTES = 4000;
34
+ /** A message body clipped by the cap, carrying its true length. */
35
+ export interface TruncationMarker {
36
+ original_bytes: number;
37
+ }
38
+ export interface BoundedInbox {
39
+ messages: (Message & {
40
+ _truncated?: TruncationMarker;
41
+ })[];
42
+ /** Total matching the query server-side, not the number returned. */
43
+ total: number;
44
+ returned: number;
45
+ omitted_count: number;
46
+ /** True when any message was withheld OR any body was clipped. */
47
+ truncated: boolean;
48
+ }
49
+ /**
50
+ * Resolve the limit to send to the server.
51
+ *
52
+ * A missing, non-numeric, zero or negative limit takes the default rather than
53
+ * meaning "unbounded" — "no limit" is the bug this exists to remove, and it must
54
+ * not be reachable by typo or by a caller passing 0. This mirrors
55
+ * `requestTimeoutMs`, where a malformed override also falls back rather than
56
+ * disabling the deadline.
57
+ */
58
+ export declare function resolveInboxLimit(requested?: unknown): number;
59
+ /**
60
+ * Bound an inbox response and declare what was withheld.
61
+ *
62
+ * `total` is the server's count for the query, which may exceed the rows
63
+ * returned; `omitted_count` is the difference. A clipped body also sets
64
+ * `truncated`, because a caller deciding whether it is safe to acknowledge
65
+ * these messages needs one flag that means "you did not get everything",
66
+ * not two it might check only one of.
67
+ */
68
+ export declare function boundInbox(raw: {
69
+ messages?: Message[];
70
+ total?: number;
71
+ /**
72
+ * How many matched the query server-side, independent of the page size. The
73
+ * server's `total` has always meant "how many are in this response", so it
74
+ * cannot answer "what was withheld" — `matching_total` was added for that.
75
+ * Absent against an older server, in which case the omitted count collapses
76
+ * to 0 and only body clipping can set `truncated`.
77
+ */
78
+ matching_total?: number;
79
+ }): BoundedInbox;
80
+ //# sourceMappingURL=inboxBounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inboxBounds.d.ts","sourceRoot":"","sources":["../../src/tools/inboxBounds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,wDAAwD;AACxD,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C,mEAAmE;AACnE,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,CAAC,OAAO,GAAG;QAAE,UAAU,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC,EAAE,CAAC;IAC1D,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAO7D;AAyBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE;IAC9B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,YAAY,CAyBf"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Bounds for the check_inbox payload (fix-inbox-delivery-and-tool-wrapping §1).
3
+ *
4
+ * check_inbox used to pass no `limit`, so the server applied its own default of
5
+ * 50 messages with full bodies and nothing truncated anywhere in the path. One
6
+ * such call measured 115,769 characters across 787 lines, exceeded the
7
+ * tool-result token budget, and never reached the model — the harness spilled it
8
+ * to a file. From the model's seat an unusable result is indistinguishable from
9
+ * a hang, which is how it was first reported.
10
+ *
11
+ * The cap alone would not be a fix. A caller that silently receives 10 of 40
12
+ * messages has no way to know, and the loss happened precisely because a
13
+ * slash-command bulk-marked read a result nobody had actually seen. So every
14
+ * bound here is paired with a signal: `truncated`, `omitted_count`, and a
15
+ * `_truncated` marker naming the original byte length on any clipped body.
16
+ *
17
+ * The rule that follows — never bulk-ack a truncated result — belongs to the
18
+ * caller, and is why the bundled `inbox` skill is part of this change.
19
+ */
20
+ /** Messages returned when the caller names no limit. */
21
+ export const CHECK_INBOX_DEFAULT_LIMIT = 10;
22
+ /**
23
+ * Hard ceiling on messages per call, whatever the caller asks for. The server
24
+ * clamps too; this stops a client from making the request in the first place.
25
+ */
26
+ export const CHECK_INBOX_MAX_LIMIT = 50;
27
+ /**
28
+ * Per-message body cap. Generous enough for a normal A2A message to arrive
29
+ * whole — the bodies that blew the budget were multi-kilobyte bug reports — and
30
+ * small enough that a full page of them cannot.
31
+ */
32
+ export const CHECK_INBOX_BODY_CAP_BYTES = 4000;
33
+ /**
34
+ * Resolve the limit to send to the server.
35
+ *
36
+ * A missing, non-numeric, zero or negative limit takes the default rather than
37
+ * meaning "unbounded" — "no limit" is the bug this exists to remove, and it must
38
+ * not be reachable by typo or by a caller passing 0. This mirrors
39
+ * `requestTimeoutMs`, where a malformed override also falls back rather than
40
+ * disabling the deadline.
41
+ */
42
+ export function resolveInboxLimit(requested) {
43
+ const n = typeof requested === "number"
44
+ ? requested
45
+ : Number.parseInt(String(requested ?? ""), 10);
46
+ if (!Number.isFinite(n) || n <= 0)
47
+ return CHECK_INBOX_DEFAULT_LIMIT;
48
+ return Math.min(Math.trunc(n), CHECK_INBOX_MAX_LIMIT);
49
+ }
50
+ /**
51
+ * Apply the body cap to one message, attaching a marker when it bites.
52
+ *
53
+ * Measured in UTF-16 code units (`String.length`), matching how the payload is
54
+ * counted downstream. `original_bytes` keeps the field name the session-event
55
+ * truncation marker already uses, so there is one truncation idiom in the
56
+ * codebase rather than two.
57
+ */
58
+ function capBody(msg) {
59
+ const body = typeof msg.body === "string" ? msg.body : "";
60
+ if (body.length <= CHECK_INBOX_BODY_CAP_BYTES)
61
+ return { msg, clipped: false };
62
+ return {
63
+ msg: {
64
+ ...msg,
65
+ body: body.slice(0, CHECK_INBOX_BODY_CAP_BYTES),
66
+ _truncated: { original_bytes: body.length },
67
+ },
68
+ clipped: true,
69
+ };
70
+ }
71
+ /**
72
+ * Bound an inbox response and declare what was withheld.
73
+ *
74
+ * `total` is the server's count for the query, which may exceed the rows
75
+ * returned; `omitted_count` is the difference. A clipped body also sets
76
+ * `truncated`, because a caller deciding whether it is safe to acknowledge
77
+ * these messages needs one flag that means "you did not get everything",
78
+ * not two it might check only one of.
79
+ */
80
+ export function boundInbox(raw) {
81
+ const messages = raw.messages ?? [];
82
+ let anyClipped = false;
83
+ const capped = messages.map((m) => {
84
+ const { msg, clipped } = capBody(m);
85
+ if (clipped)
86
+ anyClipped = true;
87
+ return msg;
88
+ });
89
+ const returned = capped.length;
90
+ // Prefer matching_total; fall back to total for an older server. Trust the
91
+ // larger of the two either way: a count below the rows actually sent is
92
+ // wrong, and a negative omitted count would read as "nothing withheld" — the
93
+ // one answer that must never be wrong in this direction.
94
+ const reported = raw.matching_total ?? raw.total ?? returned;
95
+ const total = Math.max(reported, returned);
96
+ const omitted = total - returned;
97
+ return {
98
+ messages: capped,
99
+ total,
100
+ returned,
101
+ omitted_count: omitted,
102
+ truncated: omitted > 0 || anyClipped,
103
+ };
104
+ }
105
+ //# sourceMappingURL=inboxBounds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inboxBounds.js","sourceRoot":"","sources":["../../src/tools/inboxBounds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,wDAAwD;AACxD,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAE5C;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,CAAC;AAiB/C;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAmB;IACnD,MAAM,CAAC,GACL,OAAO,SAAS,KAAK,QAAQ;QAC3B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,yBAAyB,CAAC;IACpE,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,OAAO,CACd,GAAY;IAEZ,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,IAAI,IAAI,CAAC,MAAM,IAAI,0BAA0B;QAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9E,OAAO;QACL,GAAG,EAAE;YACH,GAAG,GAAG;YACN,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,0BAA0B,CAAC;YAC/C,UAAU,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE;SAC5C;QACD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,GAW1B;IACC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;IACpC,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAChC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,OAAO;YAAE,UAAU,GAAG,IAAI,CAAC;QAC/B,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/B,2EAA2E;IAC3E,wEAAwE;IACxE,6EAA6E;IAC7E,yDAAyD;IACzD,MAAM,QAAQ,GAAG,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,KAAK,IAAI,QAAQ,CAAC;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;IAEjC,OAAO;QACL,QAAQ,EAAE,MAAM;QAChB,KAAK;QACL,QAAQ;QACR,aAAa,EAAE,OAAO;QACtB,SAAS,EAAE,OAAO,GAAG,CAAC,IAAI,UAAU;KACrC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * fix-inbox-delivery-and-tool-wrapping §1 — check_inbox bounds its payload and
3
+ * declares what it withheld.
4
+ *
5
+ * Why this file exists: check_inbox passed no `limit`, so the server returned
6
+ * its default 50 messages with full bodies and nothing truncated anywhere. One
7
+ * such call measured 115,769 characters, exceeded the tool-result token budget
8
+ * and never reached the model. A slash-command then bulk-marked those messages
9
+ * read, and because `unread_only` only returns 'pending'/'delivered' rows they
10
+ * became invisible for good. Bounding the payload is half the fix; SAYING what
11
+ * was withheld is the other half, because a silent cap turns loud breakage into
12
+ * quiet breakage.
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=inboxBounds.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inboxBounds.test.d.ts","sourceRoot":"","sources":["../../src/tools/inboxBounds.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * fix-inbox-delivery-and-tool-wrapping §1 — check_inbox bounds its payload and
3
+ * declares what it withheld.
4
+ *
5
+ * Why this file exists: check_inbox passed no `limit`, so the server returned
6
+ * its default 50 messages with full bodies and nothing truncated anywhere. One
7
+ * such call measured 115,769 characters, exceeded the tool-result token budget
8
+ * and never reached the model. A slash-command then bulk-marked those messages
9
+ * read, and because `unread_only` only returns 'pending'/'delivered' rows they
10
+ * became invisible for good. Bounding the payload is half the fix; SAYING what
11
+ * was withheld is the other half, because a silent cap turns loud breakage into
12
+ * quiet breakage.
13
+ */
14
+ import { describe, it, expect, beforeEach, vi } from "vitest";
15
+ import { handleToolCall } from "./index.js";
16
+ import { CHECK_INBOX_DEFAULT_LIMIT, CHECK_INBOX_MAX_LIMIT, CHECK_INBOX_BODY_CAP_BYTES, } from "./inboxBounds.js";
17
+ vi.mock("../state.js", () => ({
18
+ loadState: vi.fn(() => null),
19
+ saveState: vi.fn(),
20
+ deleteState: vi.fn(),
21
+ stateExists: vi.fn(() => false),
22
+ getCurrentOwner: vi.fn(() => "test-user"),
23
+ }));
24
+ vi.mock("../hooks/sessionState.js", async (importOriginal) => {
25
+ const actual = (await importOriginal());
26
+ return { ...actual, isEnabled: vi.fn(() => false) };
27
+ });
28
+ const mockClient = {
29
+ getBaseUrl: vi.fn(() => "http://localhost:8787/api"),
30
+ getInbox: vi.fn(),
31
+ getPendingTasks: vi.fn(),
32
+ };
33
+ /** n messages, each body `bodyBytes` long, newest first like GetInbox returns. */
34
+ function makeMessages(n, bodyBytes = 10) {
35
+ return Array.from({ length: n }, (_, i) => ({
36
+ id: `msg-${i}`,
37
+ from_agent: "sender",
38
+ to_agent: "test-agent",
39
+ broadcast: false,
40
+ type: "question",
41
+ subject: `subject ${i}`,
42
+ body: "x".repeat(bodyBytes),
43
+ status: "delivered",
44
+ priority: "normal",
45
+ created_at: new Date(Date.now() - i * 1000).toISOString(),
46
+ }));
47
+ }
48
+ describe("check_inbox payload bounds", () => {
49
+ let context;
50
+ let agentId;
51
+ beforeEach(() => {
52
+ vi.clearAllMocks();
53
+ agentId = "test-agent";
54
+ context = {
55
+ getCurrentAgentId: () => agentId,
56
+ setCurrentAgentId: (id) => {
57
+ agentId = id;
58
+ },
59
+ stopHeartbeat: () => { },
60
+ getWorkingDir: () => "/tmp",
61
+ setWorkingDir: () => { },
62
+ getPushedItems: () => ({ tasks: [], messages: [] }),
63
+ };
64
+ });
65
+ it("applies a default limit and reports what it withheld", async () => {
66
+ // The regression: 40 unread messages, no limit given by the caller.
67
+ vi.mocked(mockClient.getInbox).mockResolvedValue({
68
+ messages: makeMessages(CHECK_INBOX_DEFAULT_LIMIT),
69
+ total: 40,
70
+ });
71
+ const result = (await handleToolCall("check_inbox", { unread_only: true }, mockClient, context));
72
+ // The limit must reach the client call — omitting it is the original bug.
73
+ expect(mockClient.getInbox).toHaveBeenCalledWith("test-agent", true, CHECK_INBOX_DEFAULT_LIMIT);
74
+ expect(result.total).toBe(40);
75
+ expect(result.returned).toBe(CHECK_INBOX_DEFAULT_LIMIT);
76
+ expect(result.omitted_count).toBe(40 - CHECK_INBOX_DEFAULT_LIMIT);
77
+ expect(result.truncated).toBe(true);
78
+ });
79
+ it("clips an oversized body and names its original length", async () => {
80
+ const original = CHECK_INBOX_BODY_CAP_BYTES + 1000;
81
+ vi.mocked(mockClient.getInbox).mockResolvedValue({
82
+ messages: makeMessages(1, original),
83
+ total: 1,
84
+ });
85
+ const result = (await handleToolCall("check_inbox", { unread_only: true }, mockClient, context));
86
+ const msg = result.messages[0];
87
+ expect(msg.body.length).toBeLessThanOrEqual(CHECK_INBOX_BODY_CAP_BYTES);
88
+ expect(msg._truncated).toEqual({ original_bytes: original });
89
+ // A clipped body is still a withheld thing: the caller must be told.
90
+ expect(result.truncated).toBe(true);
91
+ });
92
+ it("reports nothing withheld when nothing was withheld", async () => {
93
+ vi.mocked(mockClient.getInbox).mockResolvedValue({
94
+ messages: makeMessages(3),
95
+ total: 3,
96
+ });
97
+ const result = (await handleToolCall("check_inbox", { unread_only: true }, mockClient, context));
98
+ expect(result.truncated).toBe(false);
99
+ expect(result.omitted_count).toBe(0);
100
+ expect(result.returned).toBe(3);
101
+ for (const m of result.messages) {
102
+ expect(m._truncated).toBeUndefined();
103
+ expect(m.body.length).toBe(10);
104
+ }
105
+ });
106
+ it("clamps a caller-supplied limit above the maximum", async () => {
107
+ vi.mocked(mockClient.getInbox).mockResolvedValue({
108
+ messages: makeMessages(CHECK_INBOX_MAX_LIMIT),
109
+ total: 500,
110
+ });
111
+ await handleToolCall("check_inbox", { unread_only: true, limit: 10_000 }, mockClient, context);
112
+ expect(mockClient.getInbox).toHaveBeenCalledWith("test-agent", true, CHECK_INBOX_MAX_LIMIT);
113
+ });
114
+ it("honours a caller-supplied limit below the maximum", async () => {
115
+ vi.mocked(mockClient.getInbox).mockResolvedValue({
116
+ messages: makeMessages(2),
117
+ total: 2,
118
+ });
119
+ await handleToolCall("check_inbox", { unread_only: true, limit: 2 }, mockClient, context);
120
+ expect(mockClient.getInbox).toHaveBeenCalledWith("test-agent", true, 2);
121
+ });
122
+ it("keeps the payload well under the budget for an inbox that once blew it", async () => {
123
+ // 787 rows averaging ~147 bytes of body is what produced the 115,769-char
124
+ // response observed on 2026-10-17. Same corpus, bounded output.
125
+ vi.mocked(mockClient.getInbox).mockResolvedValue({
126
+ messages: makeMessages(CHECK_INBOX_DEFAULT_LIMIT, 8000),
127
+ total: 787,
128
+ });
129
+ const result = (await handleToolCall("check_inbox", { unread_only: true }, mockClient, context));
130
+ expect(JSON.stringify(result).length).toBeLessThan(60_000);
131
+ expect(result.truncated).toBe(true);
132
+ expect(result.omitted_count).toBe(787 - CHECK_INBOX_DEFAULT_LIMIT);
133
+ });
134
+ });
135
+ //# sourceMappingURL=inboxBounds.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inboxBounds.test.js","sourceRoot":"","sources":["../../src/tools/inboxBounds.test.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,18 @@ export interface ToolContext {
13
13
  stopHeartbeat: () => void;
14
14
  getWorkingDir: () => string;
15
15
  setWorkingDir: (dir: string) => void;
16
+ /**
17
+ * @deprecated Destructive read; see peekPushedItems
18
+ * (fix-inbox-delivery-and-tool-wrapping §2). Kept so older callers compile.
19
+ */
16
20
  getPushedItems: () => PushedItems;
21
+ /** Read pushed items without consuming them. */
22
+ peekPushedItems?: () => PushedItems;
23
+ /** Consume exactly the items that made it into a built response. */
24
+ commitPushedItems?: (consumed: {
25
+ taskIds?: string[];
26
+ messageIds?: string[];
27
+ }) => void;
17
28
  }
18
29
  interface PendingTask {
19
30
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAqD,MAAM,cAAc,CAAC;AAOrG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAiF/D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,iBAAiB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,cAAc,EAAE,MAAM,WAAW,CAAC;CACnC;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAwJD,wBAAgB,aAAa,IAAI,IAAI,EAAE,CA80FtC;AA2BD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CA8sFlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAqD,MAAM,cAAc,CAAC;AAOrG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAmG/D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,iBAAiB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;;OAGG;IACH,cAAc,EAAE,MAAM,WAAW,CAAC;IAClC,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,WAAW,CAAC;IACpC,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,KAAK,IAAI,CAAC;CACZ;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAyLD,wBAAgB,aAAa,IAAI,IAAI,EAAE,CAk2FtC;AA2BD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CA+qFlB"}