@namzu/sdk 1.0.0 → 1.2.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 (330) hide show
  1. package/CHANGELOG.md +253 -0
  2. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  3. package/dist/agents/ReactiveAgent.js +5 -0
  4. package/dist/agents/ReactiveAgent.js.map +1 -1
  5. package/dist/agents/SupervisorAgent.d.ts +22 -1
  6. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  7. package/dist/agents/SupervisorAgent.js +47 -14
  8. package/dist/agents/SupervisorAgent.js.map +1 -1
  9. package/dist/agents/__tests__/supervisor-ledger.test.d.ts +2 -0
  10. package/dist/agents/__tests__/supervisor-ledger.test.d.ts.map +1 -0
  11. package/dist/agents/__tests__/supervisor-ledger.test.js +131 -0
  12. package/dist/agents/__tests__/supervisor-ledger.test.js.map +1 -0
  13. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  14. package/dist/bridge/a2a/mapper.js +2 -0
  15. package/dist/bridge/a2a/mapper.js.map +1 -1
  16. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  17. package/dist/bridge/sse/mapper.js +4 -0
  18. package/dist/bridge/sse/mapper.js.map +1 -1
  19. package/dist/config/runtime.d.ts +24 -0
  20. package/dist/config/runtime.d.ts.map +1 -1
  21. package/dist/config/runtime.js +9 -0
  22. package/dist/config/runtime.js.map +1 -1
  23. package/dist/connector/builtins/webhook.test.js +17 -0
  24. package/dist/connector/builtins/webhook.test.js.map +1 -1
  25. package/dist/connector/index.d.ts +1 -0
  26. package/dist/connector/index.d.ts.map +1 -1
  27. package/dist/connector/index.js +1 -0
  28. package/dist/connector/index.js.map +1 -1
  29. package/dist/connector/mcp/client.d.ts.map +1 -1
  30. package/dist/connector/mcp/client.js +4 -0
  31. package/dist/connector/mcp/client.js.map +1 -1
  32. package/dist/connector/mcp/index.d.ts +1 -0
  33. package/dist/connector/mcp/index.d.ts.map +1 -1
  34. package/dist/connector/mcp/index.js +1 -0
  35. package/dist/connector/mcp/index.js.map +1 -1
  36. package/dist/connector/mcp/streamable-http.d.ts +22 -0
  37. package/dist/connector/mcp/streamable-http.d.ts.map +1 -0
  38. package/dist/connector/mcp/streamable-http.js +128 -0
  39. package/dist/connector/mcp/streamable-http.js.map +1 -0
  40. package/dist/connector/mcp/streamable-http.test.d.ts +2 -0
  41. package/dist/connector/mcp/streamable-http.test.d.ts.map +1 -0
  42. package/dist/connector/mcp/streamable-http.test.js +132 -0
  43. package/dist/connector/mcp/streamable-http.test.js.map +1 -0
  44. package/dist/{runtime/query → constants}/continuation.d.ts +5 -0
  45. package/dist/constants/continuation.d.ts.map +1 -0
  46. package/dist/{runtime/query → constants}/continuation.js +5 -0
  47. package/dist/constants/continuation.js.map +1 -0
  48. package/dist/constants/index.d.ts +1 -0
  49. package/dist/constants/index.d.ts.map +1 -1
  50. package/dist/constants/index.js +1 -0
  51. package/dist/constants/index.js.map +1 -1
  52. package/dist/manager/run/persistence.d.ts +11 -0
  53. package/dist/manager/run/persistence.d.ts.map +1 -1
  54. package/dist/manager/run/persistence.js +30 -1
  55. package/dist/manager/run/persistence.js.map +1 -1
  56. package/dist/persona/assembler.d.ts.map +1 -1
  57. package/dist/persona/assembler.js +18 -9
  58. package/dist/persona/assembler.js.map +1 -1
  59. package/dist/provider/capabilities.d.ts +27 -0
  60. package/dist/provider/capabilities.d.ts.map +1 -0
  61. package/dist/provider/capabilities.js +29 -0
  62. package/dist/provider/capabilities.js.map +1 -0
  63. package/dist/provider/collect.d.ts.map +1 -1
  64. package/dist/provider/collect.js +4 -1
  65. package/dist/provider/collect.js.map +1 -1
  66. package/dist/provider/index.d.ts +2 -0
  67. package/dist/provider/index.d.ts.map +1 -1
  68. package/dist/provider/index.js +1 -0
  69. package/dist/provider/index.js.map +1 -1
  70. package/dist/public-runtime.d.ts +4 -3
  71. package/dist/public-runtime.d.ts.map +1 -1
  72. package/dist/public-runtime.js +3 -3
  73. package/dist/public-runtime.js.map +1 -1
  74. package/dist/registry/tool/execute.d.ts +27 -0
  75. package/dist/registry/tool/execute.d.ts.map +1 -1
  76. package/dist/registry/tool/execute.js +124 -21
  77. package/dist/registry/tool/execute.js.map +1 -1
  78. package/dist/registry/tool/execute.test.d.ts +9 -6
  79. package/dist/registry/tool/execute.test.d.ts.map +1 -1
  80. package/dist/registry/tool/execute.test.js +72 -10
  81. package/dist/registry/tool/execute.test.js.map +1 -1
  82. package/dist/registry/toolset/catalog.test.js +62 -0
  83. package/dist/registry/toolset/catalog.test.js.map +1 -1
  84. package/dist/run/reporter.d.ts.map +1 -1
  85. package/dist/run/reporter.js +8 -0
  86. package/dist/run/reporter.js.map +1 -1
  87. package/dist/runtime/query/__tests__/capability-negotiation.test.d.ts +2 -0
  88. package/dist/runtime/query/__tests__/capability-negotiation.test.d.ts.map +1 -0
  89. package/dist/runtime/query/__tests__/capability-negotiation.test.js +184 -0
  90. package/dist/runtime/query/__tests__/capability-negotiation.test.js.map +1 -0
  91. package/dist/runtime/query/__tests__/checkpoint-store.test.d.ts +2 -0
  92. package/dist/runtime/query/__tests__/checkpoint-store.test.d.ts.map +1 -0
  93. package/dist/runtime/query/__tests__/checkpoint-store.test.js +259 -0
  94. package/dist/runtime/query/__tests__/checkpoint-store.test.js.map +1 -0
  95. package/dist/runtime/query/__tests__/checkpoint.test.js +9 -3
  96. package/dist/runtime/query/__tests__/checkpoint.test.js.map +1 -1
  97. package/dist/runtime/query/__tests__/deferred-tools.test.js +43 -5
  98. package/dist/runtime/query/__tests__/deferred-tools.test.js.map +1 -1
  99. package/dist/runtime/query/__tests__/long-document-flow.test.d.ts +2 -0
  100. package/dist/runtime/query/__tests__/long-document-flow.test.d.ts.map +1 -0
  101. package/dist/runtime/query/__tests__/long-document-flow.test.js +154 -0
  102. package/dist/runtime/query/__tests__/long-document-flow.test.js.map +1 -0
  103. package/dist/runtime/query/__tests__/orphan-task-turn-end.test.d.ts +2 -0
  104. package/dist/runtime/query/__tests__/orphan-task-turn-end.test.d.ts.map +1 -0
  105. package/dist/runtime/query/__tests__/orphan-task-turn-end.test.js +110 -0
  106. package/dist/runtime/query/__tests__/orphan-task-turn-end.test.js.map +1 -0
  107. package/dist/runtime/query/__tests__/prompt.test.js +15 -11
  108. package/dist/runtime/query/__tests__/prompt.test.js.map +1 -1
  109. package/dist/runtime/query/checkpoint.d.ts +16 -2
  110. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  111. package/dist/runtime/query/checkpoint.js +21 -7
  112. package/dist/runtime/query/checkpoint.js.map +1 -1
  113. package/dist/runtime/query/context.d.ts +7 -0
  114. package/dist/runtime/query/context.d.ts.map +1 -1
  115. package/dist/runtime/query/context.js +1 -0
  116. package/dist/runtime/query/context.js.map +1 -1
  117. package/dist/runtime/query/index.d.ts +29 -0
  118. package/dist/runtime/query/index.d.ts.map +1 -1
  119. package/dist/runtime/query/index.js +98 -8
  120. package/dist/runtime/query/index.js.map +1 -1
  121. package/dist/runtime/query/iteration/index.d.ts +3 -55
  122. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  123. package/dist/runtime/query/iteration/index.js +260 -656
  124. package/dist/runtime/query/iteration/index.js.map +1 -1
  125. package/dist/runtime/query/iteration/phases/checkpoint.d.ts.map +1 -1
  126. package/dist/runtime/query/iteration/phases/checkpoint.js +24 -2
  127. package/dist/runtime/query/iteration/phases/checkpoint.js.map +1 -1
  128. package/dist/runtime/query/iteration/phases/compaction.d.ts +8 -0
  129. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  130. package/dist/runtime/query/iteration/phases/compaction.js +84 -3
  131. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  132. package/dist/runtime/query/iteration/phases/context.d.ts +13 -2
  133. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  134. package/dist/runtime/query/iteration/phases/context.js +53 -0
  135. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  136. package/dist/runtime/query/iteration/phases/hitl-abort-race.test.d.ts +2 -0
  137. package/dist/runtime/query/iteration/phases/hitl-abort-race.test.d.ts.map +1 -0
  138. package/dist/runtime/query/iteration/phases/hitl-abort-race.test.js +73 -0
  139. package/dist/runtime/query/iteration/phases/hitl-abort-race.test.js.map +1 -0
  140. package/dist/runtime/query/iteration/phases/hitl-answer-question.test.d.ts +2 -0
  141. package/dist/runtime/query/iteration/phases/hitl-answer-question.test.d.ts.map +1 -0
  142. package/dist/runtime/query/iteration/phases/hitl-answer-question.test.js +120 -0
  143. package/dist/runtime/query/iteration/phases/hitl-answer-question.test.js.map +1 -0
  144. package/dist/runtime/query/iteration/phases/tool-review.d.ts +1 -1
  145. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  146. package/dist/runtime/query/iteration/phases/tool-review.js +7 -2
  147. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  148. package/dist/runtime/query/iteration/phases/working-memory-compaction.test.d.ts +19 -0
  149. package/dist/runtime/query/iteration/phases/working-memory-compaction.test.d.ts.map +1 -0
  150. package/dist/runtime/query/iteration/phases/working-memory-compaction.test.js +177 -0
  151. package/dist/runtime/query/iteration/phases/working-memory-compaction.test.js.map +1 -0
  152. package/dist/runtime/query/iteration/phases/working-memory.d.ts +31 -0
  153. package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -0
  154. package/dist/runtime/query/iteration/phases/working-memory.js +81 -0
  155. package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -0
  156. package/dist/runtime/query/iteration/stream-turn.d.ts +35 -0
  157. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -0
  158. package/dist/runtime/query/iteration/stream-turn.js +341 -0
  159. package/dist/runtime/query/iteration/stream-turn.js.map +1 -0
  160. package/dist/runtime/query/replay/list.d.ts +17 -1
  161. package/dist/runtime/query/replay/list.d.ts.map +1 -1
  162. package/dist/runtime/query/replay/list.js +21 -4
  163. package/dist/runtime/query/replay/list.js.map +1 -1
  164. package/dist/runtime/query/replay/prepare.d.ts +10 -0
  165. package/dist/runtime/query/replay/prepare.d.ts.map +1 -1
  166. package/dist/runtime/query/replay/prepare.js +20 -4
  167. package/dist/runtime/query/replay/prepare.js.map +1 -1
  168. package/dist/session/workspace/__tests__/shared-run.test.js +1 -1
  169. package/dist/session/workspace/__tests__/shared-run.test.js.map +1 -1
  170. package/dist/session/workspace/shared-run.js +1 -0
  171. package/dist/session/workspace/shared-run.js.map +1 -1
  172. package/dist/skills/loader.test.js +8 -8
  173. package/dist/skills/loader.test.js.map +1 -1
  174. package/dist/store/index.d.ts +1 -0
  175. package/dist/store/index.d.ts.map +1 -1
  176. package/dist/store/index.js +1 -0
  177. package/dist/store/index.js.map +1 -1
  178. package/dist/store/run/checkpoint-disk.d.ts +28 -0
  179. package/dist/store/run/checkpoint-disk.d.ts.map +1 -0
  180. package/dist/store/run/checkpoint-disk.js +55 -0
  181. package/dist/store/run/checkpoint-disk.js.map +1 -0
  182. package/dist/streaming/coalesce.test.js.map +1 -1
  183. package/dist/tools/builtins/__tests__/payload-budget.test.js +48 -0
  184. package/dist/tools/builtins/__tests__/payload-budget.test.js.map +1 -1
  185. package/dist/tools/builtins/__tests__/read-file.test.js +9 -0
  186. package/dist/tools/builtins/__tests__/read-file.test.js.map +1 -1
  187. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  188. package/dist/tools/builtins/read-file.js +50 -2
  189. package/dist/tools/builtins/read-file.js.map +1 -1
  190. package/dist/tools/builtins/search-tools.d.ts.map +1 -1
  191. package/dist/tools/builtins/search-tools.js +32 -7
  192. package/dist/tools/builtins/search-tools.js.map +1 -1
  193. package/dist/tools/coordinator/__tests__/approve-plan.test.d.ts +2 -0
  194. package/dist/tools/coordinator/__tests__/approve-plan.test.d.ts.map +1 -0
  195. package/dist/tools/coordinator/__tests__/approve-plan.test.js +114 -0
  196. package/dist/tools/coordinator/__tests__/approve-plan.test.js.map +1 -0
  197. package/dist/tools/coordinator/__tests__/ask-user-question.test.d.ts +2 -0
  198. package/dist/tools/coordinator/__tests__/ask-user-question.test.d.ts.map +1 -0
  199. package/dist/tools/coordinator/__tests__/ask-user-question.test.js +309 -0
  200. package/dist/tools/coordinator/__tests__/ask-user-question.test.js.map +1 -0
  201. package/dist/tools/coordinator/index.d.ts +8 -0
  202. package/dist/tools/coordinator/index.d.ts.map +1 -1
  203. package/dist/tools/coordinator/index.js +195 -15
  204. package/dist/tools/coordinator/index.js.map +1 -1
  205. package/dist/types/agent/index.d.ts +1 -0
  206. package/dist/types/agent/index.d.ts.map +1 -1
  207. package/dist/types/agent/index.js +1 -0
  208. package/dist/types/agent/index.js.map +1 -1
  209. package/dist/types/agent/reactive.d.ts +15 -0
  210. package/dist/types/agent/reactive.d.ts.map +1 -1
  211. package/dist/types/agent/supervisor.d.ts +18 -0
  212. package/dist/types/agent/supervisor.d.ts.map +1 -1
  213. package/dist/types/agent/working-memory.d.ts +29 -0
  214. package/dist/types/agent/working-memory.d.ts.map +1 -0
  215. package/dist/types/agent/working-memory.js +2 -0
  216. package/dist/types/agent/working-memory.js.map +1 -0
  217. package/dist/types/common/index.d.ts +10 -0
  218. package/dist/types/common/index.d.ts.map +1 -1
  219. package/dist/types/common/index.js +18 -0
  220. package/dist/types/common/index.js.map +1 -1
  221. package/dist/types/common/usage-merge.test.d.ts +2 -0
  222. package/dist/types/common/usage-merge.test.d.ts.map +1 -0
  223. package/dist/types/common/usage-merge.test.js +48 -0
  224. package/dist/types/common/usage-merge.test.js.map +1 -0
  225. package/dist/types/connector/mcp.d.ts +9 -2
  226. package/dist/types/connector/mcp.d.ts.map +1 -1
  227. package/dist/types/hitl/index.d.ts +42 -0
  228. package/dist/types/hitl/index.d.ts.map +1 -1
  229. package/dist/types/hitl/index.js +11 -0
  230. package/dist/types/hitl/index.js.map +1 -1
  231. package/dist/types/provider/chat.d.ts +9 -0
  232. package/dist/types/provider/chat.d.ts.map +1 -1
  233. package/dist/types/provider/config.d.ts +18 -0
  234. package/dist/types/provider/config.d.ts.map +1 -1
  235. package/dist/types/provider/interface.d.ts +10 -0
  236. package/dist/types/provider/interface.d.ts.map +1 -1
  237. package/dist/types/run/checkpoint-store.d.ts +64 -0
  238. package/dist/types/run/checkpoint-store.d.ts.map +1 -0
  239. package/dist/types/run/checkpoint-store.js +12 -0
  240. package/dist/types/run/checkpoint-store.js.map +1 -0
  241. package/dist/types/run/config.d.ts +27 -0
  242. package/dist/types/run/config.d.ts.map +1 -1
  243. package/dist/types/run/events.d.ts +6 -0
  244. package/dist/types/run/events.d.ts.map +1 -1
  245. package/dist/types/run/events.js.map +1 -1
  246. package/dist/types/run/index.d.ts +1 -0
  247. package/dist/types/run/index.d.ts.map +1 -1
  248. package/dist/types/run/index.js +1 -0
  249. package/dist/types/run/index.js.map +1 -1
  250. package/dist/version.d.ts.map +1 -1
  251. package/dist/version.js +25 -4
  252. package/dist/version.js.map +1 -1
  253. package/package.json +1 -1
  254. package/src/agents/ReactiveAgent.ts +5 -0
  255. package/src/agents/SupervisorAgent.ts +56 -16
  256. package/src/agents/__tests__/supervisor-ledger.test.ts +185 -0
  257. package/src/bridge/a2a/mapper.ts +3 -0
  258. package/src/bridge/sse/mapper.ts +5 -0
  259. package/src/config/runtime.ts +9 -0
  260. package/src/connector/builtins/webhook.test.ts +21 -0
  261. package/src/connector/index.ts +1 -0
  262. package/src/connector/mcp/client.ts +4 -0
  263. package/src/connector/mcp/index.ts +1 -0
  264. package/src/connector/mcp/streamable-http.test.ts +169 -0
  265. package/src/connector/mcp/streamable-http.ts +152 -0
  266. package/src/{runtime/query → constants}/continuation.ts +5 -0
  267. package/src/constants/index.ts +1 -0
  268. package/src/manager/run/persistence.ts +34 -1
  269. package/src/persona/assembler.ts +18 -6
  270. package/src/provider/capabilities.ts +47 -0
  271. package/src/provider/collect.ts +4 -1
  272. package/src/provider/index.ts +5 -0
  273. package/src/public-runtime.ts +5 -0
  274. package/src/registry/tool/execute.test.ts +85 -10
  275. package/src/registry/tool/execute.ts +124 -21
  276. package/src/registry/toolset/catalog.test.ts +68 -0
  277. package/src/run/reporter.ts +9 -0
  278. package/src/runtime/query/__tests__/capability-negotiation.test.ts +248 -0
  279. package/src/runtime/query/__tests__/checkpoint-store.test.ts +322 -0
  280. package/src/runtime/query/__tests__/checkpoint.test.ts +15 -6
  281. package/src/runtime/query/__tests__/deferred-tools.test.ts +52 -5
  282. package/src/runtime/query/__tests__/long-document-flow.test.ts +180 -0
  283. package/src/runtime/query/__tests__/orphan-task-turn-end.test.ts +127 -0
  284. package/src/runtime/query/__tests__/prompt.test.ts +15 -11
  285. package/src/runtime/query/checkpoint.ts +23 -9
  286. package/src/runtime/query/context.ts +9 -0
  287. package/src/runtime/query/index.ts +148 -29
  288. package/src/runtime/query/iteration/index.ts +316 -831
  289. package/src/runtime/query/iteration/phases/checkpoint.ts +32 -2
  290. package/src/runtime/query/iteration/phases/compaction.ts +89 -3
  291. package/src/runtime/query/iteration/phases/context.ts +59 -3
  292. package/src/runtime/query/iteration/phases/hitl-abort-race.test.ts +86 -0
  293. package/src/runtime/query/iteration/phases/hitl-answer-question.test.ts +139 -0
  294. package/src/runtime/query/iteration/phases/tool-review.ts +7 -3
  295. package/src/runtime/query/iteration/phases/working-memory-compaction.test.ts +215 -0
  296. package/src/runtime/query/iteration/phases/working-memory.ts +86 -0
  297. package/src/runtime/query/iteration/stream-turn.ts +396 -0
  298. package/src/runtime/query/replay/list.ts +38 -4
  299. package/src/runtime/query/replay/prepare.ts +37 -4
  300. package/src/session/workspace/__tests__/shared-run.test.ts +1 -1
  301. package/src/session/workspace/shared-run.ts +1 -0
  302. package/src/skills/loader.test.ts +8 -8
  303. package/src/store/index.ts +1 -0
  304. package/src/store/run/checkpoint-disk.ts +67 -0
  305. package/src/streaming/coalesce.test.ts +3 -3
  306. package/src/tools/builtins/__tests__/payload-budget.test.ts +63 -0
  307. package/src/tools/builtins/__tests__/read-file.test.ts +12 -0
  308. package/src/tools/builtins/read-file.ts +50 -2
  309. package/src/tools/builtins/search-tools.ts +38 -7
  310. package/src/tools/coordinator/__tests__/approve-plan.test.ts +139 -0
  311. package/src/tools/coordinator/__tests__/ask-user-question.test.ts +370 -0
  312. package/src/tools/coordinator/index.ts +227 -17
  313. package/src/types/agent/index.ts +1 -0
  314. package/src/types/agent/reactive.ts +17 -0
  315. package/src/types/agent/supervisor.ts +20 -0
  316. package/src/types/agent/working-memory.ts +29 -0
  317. package/src/types/common/index.ts +19 -0
  318. package/src/types/common/usage-merge.test.ts +53 -0
  319. package/src/types/connector/mcp.ts +14 -2
  320. package/src/types/hitl/index.ts +52 -1
  321. package/src/types/provider/chat.ts +10 -0
  322. package/src/types/provider/config.ts +18 -0
  323. package/src/types/provider/interface.ts +11 -0
  324. package/src/types/run/checkpoint-store.ts +72 -0
  325. package/src/types/run/config.ts +30 -0
  326. package/src/types/run/events.ts +13 -0
  327. package/src/types/run/index.ts +1 -0
  328. package/src/version.ts +26 -4
  329. package/dist/runtime/query/continuation.d.ts.map +0 -1
  330. package/dist/runtime/query/continuation.js.map +0 -1
@@ -4,21 +4,63 @@ import { ToolRegistry } from '../registry/tool/execute.js'
4
4
  import { drainQuery } from '../runtime/query/index.js'
5
5
  import type { LaunchedTaskMeta } from '../runtime/query/iteration/phases/context.js'
6
6
  import { buildCoordinatorTools } from '../tools/coordinator/index.js'
7
- import type { TaskGateway } from '../types/agent/gateway.js'
7
+ import type { TaskGateway, TaskHandle } from '../types/agent/gateway.js'
8
8
  import type {
9
9
  AgentInput,
10
10
  AgentMetadata,
11
+ AgentTaskResult,
11
12
  SupervisorAgentConfig,
12
13
  SupervisorAgentResult,
13
14
  } from '../types/agent/index.js'
14
15
  import type { AgentTaskContext } from '../types/agent/task.js'
15
- import type { AgentId, TaskId } from '../types/ids/index.js'
16
+ import type { AgentId, RunId, TaskId } from '../types/ids/index.js'
16
17
  import { deriveChildState } from '../types/invocation/index.js'
17
18
  import type { RunEventListener } from '../types/run/index.js'
18
19
  import type { ActorRef } from '../types/session/actor.js'
19
20
  import { ZERO_COST } from '../utils/cost.js'
20
21
  import { AbstractAgent } from './AbstractAgent.js'
21
22
 
23
+ /**
24
+ * Build the authoritative per-task ledger from the gateway's task handles.
25
+ *
26
+ * A handle carries a `result` only when its worker actually produced one. A
27
+ * handle with NO result never produced a verifiable outcome, so it MUST NOT be
28
+ * synthesized as a success: the synthesized status is always the terminal
29
+ * `'failed'`, regardless of the handle's reported `state` (which may itself be
30
+ * `'completed'`).
31
+ *
32
+ * The earlier implementation cast `handle.state` onto the synthesized result's
33
+ * status, letting a worker that ended without a result count toward
34
+ * `completedTasks`. That produced fabricated "done" workers with empty outputs
35
+ * (cowork task 02c5cf2b): the supervisor reported "3 workers done, 40KB
36
+ * reports" when the workers never started. Real workers (those with a present
37
+ * `result`) are unaffected — their `result` is preserved verbatim.
38
+ */
39
+ export function synthesizeTaskResults(
40
+ taskHandles: readonly TaskHandle[],
41
+ runId: RunId,
42
+ now: number = Date.now(),
43
+ ): AgentTaskResult[] {
44
+ return taskHandles.map((handle, index) => ({
45
+ agentId: handle.agentId,
46
+ result: handle.result ?? {
47
+ runId,
48
+ status: 'failed' as const,
49
+ usage: { ...EMPTY_TOKEN_USAGE },
50
+ cost: { ...ZERO_COST },
51
+ iterations: 0,
52
+ durationMs: now - handle.createdAt,
53
+ messages: [],
54
+ },
55
+ taskIndex: index,
56
+ }))
57
+ }
58
+
59
+ /** Count only the task results that genuinely completed. */
60
+ export function countCompletedTasks(taskResults: readonly AgentTaskResult[]): number {
61
+ return taskResults.filter((t) => t.result.status === 'completed').length
62
+ }
63
+
22
64
  export class SupervisorAgent extends AbstractAgent<SupervisorAgentConfig, SupervisorAgentResult> {
23
65
  readonly type = 'supervisor' as const
24
66
 
@@ -110,6 +152,10 @@ export class SupervisorAgent extends AbstractAgent<SupervisorAgentConfig, Superv
110
152
  onTaskLaunched: (agentTaskId, meta) => {
111
153
  launchedTasks.set(agentTaskId, meta)
112
154
  },
155
+ // With a resume handler present the coordinator surface gains
156
+ // ask_user_question — the model can park the run on a question
157
+ // routed through the same HITL channel as plan approvals.
158
+ ...(config.resumeHandler ? { resumeHandler: config.resumeHandler } : {}),
113
159
  })
114
160
 
115
161
  const tools = new ToolRegistry()
@@ -171,26 +217,20 @@ export class SupervisorAgent extends AbstractAgent<SupervisorAgentConfig, Superv
171
217
  ...(config.resumeHandler ? { resumeHandler: config.resumeHandler } : {}),
172
218
  ...(config.verificationGate ? { verificationGate: config.verificationGate } : {}),
173
219
  ...(config.sandboxProvider ? { sandboxProvider: config.sandboxProvider } : {}),
220
+ // Working-memory / compaction seam (optional; absent => unchanged
221
+ // run path, byte-identical for every existing consumer).
222
+ ...(config.compactionConfig ? { compactionConfig: config.compactionConfig } : {}),
223
+ ...(config.workingMemoryProvider
224
+ ? { workingMemoryProvider: config.workingMemoryProvider }
225
+ : {}),
174
226
  },
175
227
  listener,
176
228
  )
177
229
 
178
230
  const taskHandles = gateway.listTasks()
179
- const taskResults = taskHandles.map((handle, index) => ({
180
- agentId: handle.agentId,
181
- result: handle.result ?? {
182
- runId,
183
- status: handle.state as 'completed' | 'failed' | 'cancelled',
184
- usage: { ...EMPTY_TOKEN_USAGE },
185
- cost: { ...ZERO_COST },
186
- iterations: 0,
187
- durationMs: Date.now() - handle.createdAt,
188
- messages: [],
189
- },
190
- taskIndex: index,
191
- }))
231
+ const taskResults = synthesizeTaskResults(taskHandles, runId)
192
232
 
193
- const completedTasks = taskResults.filter((t) => t.result.status === 'completed').length
233
+ const completedTasks = countCompletedTasks(taskResults)
194
234
 
195
235
  return {
196
236
  runId: run.id,
@@ -0,0 +1,185 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import type { TaskHandle } from '../../types/agent/gateway.js'
3
+ import type { AgentTaskResult, BaseAgentResult } from '../../types/agent/index.js'
4
+ import type { RunId, TaskId } from '../../types/ids/index.js'
5
+ import { countCompletedTasks, synthesizeTaskResults } from '../SupervisorAgent.js'
6
+
7
+ const RUN_ID = 'run-supervisor' as RunId
8
+ const NOW = 1_000_000
9
+
10
+ function at(results: AgentTaskResult[], index: number): AgentTaskResult {
11
+ const entry = results[index]
12
+ if (!entry) {
13
+ throw new Error(`expected a task result at index ${index}, got ${results.length} results`)
14
+ }
15
+ return entry
16
+ }
17
+
18
+ function handle(overrides: Partial<TaskHandle> & Pick<TaskHandle, 'state'>): TaskHandle {
19
+ return {
20
+ taskId: 'task-1' as TaskId,
21
+ agentId: 'worker-1',
22
+ createdAt: NOW - 5_000,
23
+ ...overrides,
24
+ }
25
+ }
26
+
27
+ function completedResult(): BaseAgentResult {
28
+ return {
29
+ runId: 'run-worker' as RunId,
30
+ status: 'completed',
31
+ usage: {
32
+ promptTokens: 10,
33
+ completionTokens: 20,
34
+ totalTokens: 30,
35
+ cachedTokens: 0,
36
+ cacheWriteTokens: 0,
37
+ },
38
+ cost: {
39
+ inputCostPer1M: 0,
40
+ outputCostPer1M: 0,
41
+ totalCost: 0,
42
+ cacheDiscount: 0,
43
+ },
44
+ iterations: 3,
45
+ durationMs: 4_200,
46
+ messages: [],
47
+ result: 'real worker output',
48
+ }
49
+ }
50
+
51
+ describe('supervisor ledger truthfulness', () => {
52
+ describe('synthesizeTaskResults', () => {
53
+ it('synthesizes a FAILED result when a handle has no result, regardless of state', () => {
54
+ // A worker that ended with no result is NOT a success even when the
55
+ // handle reports a terminal 'completed' state — this is the exact
56
+ // fabrication that made the supervisor claim "3 workers done" with
57
+ // empty outputs (cowork task 02c5cf2b).
58
+ const results = synthesizeTaskResults(
59
+ [handle({ state: 'completed', result: undefined })],
60
+ RUN_ID,
61
+ NOW,
62
+ )
63
+
64
+ expect(results).toHaveLength(1)
65
+ expect(at(results, 0).result.status).toBe('failed')
66
+ expect(at(results, 0).result.status).not.toBe('completed')
67
+ expect(at(results, 0).result.runId).toBe(RUN_ID)
68
+ expect(at(results, 0).result.durationMs).toBe(NOW - (NOW - 5_000))
69
+ })
70
+
71
+ it('synthesizes a FAILED result for a genuinely failed handle', () => {
72
+ const results = synthesizeTaskResults(
73
+ [handle({ state: 'failed', result: undefined })],
74
+ RUN_ID,
75
+ NOW,
76
+ )
77
+
78
+ expect(at(results, 0).result.status).toBe('failed')
79
+ })
80
+
81
+ it('synthesizes a FAILED result for a canceled handle with no result', () => {
82
+ const results = synthesizeTaskResults(
83
+ [handle({ state: 'canceled', result: undefined })],
84
+ RUN_ID,
85
+ NOW,
86
+ )
87
+
88
+ expect(at(results, 0).result.status).toBe('failed')
89
+ })
90
+
91
+ it('preserves a present completed result verbatim (real workers unaffected)', () => {
92
+ const real = completedResult()
93
+ const results = synthesizeTaskResults(
94
+ [handle({ state: 'completed', result: real })],
95
+ RUN_ID,
96
+ NOW,
97
+ )
98
+
99
+ expect(at(results, 0).result).toBe(real)
100
+ expect(at(results, 0).result.status).toBe('completed')
101
+ expect(at(results, 0).result.result).toBe('real worker output')
102
+ })
103
+
104
+ it('preserves a present failed result verbatim', () => {
105
+ const failed: BaseAgentResult = { ...completedResult(), status: 'failed' }
106
+ const results = synthesizeTaskResults(
107
+ [handle({ state: 'failed', result: failed })],
108
+ RUN_ID,
109
+ NOW,
110
+ )
111
+
112
+ expect(at(results, 0).result).toBe(failed)
113
+ expect(at(results, 0).result.status).toBe('failed')
114
+ })
115
+ })
116
+
117
+ describe('countCompletedTasks', () => {
118
+ it('excludes an absent-result handle from completedTasks', () => {
119
+ const taskResults = synthesizeTaskResults(
120
+ [
121
+ handle({
122
+ taskId: 'task-a' as TaskId,
123
+ agentId: 'a',
124
+ state: 'completed',
125
+ result: undefined,
126
+ }),
127
+ handle({
128
+ taskId: 'task-b' as TaskId,
129
+ agentId: 'b',
130
+ state: 'completed',
131
+ result: completedResult(),
132
+ }),
133
+ ],
134
+ RUN_ID,
135
+ NOW,
136
+ )
137
+
138
+ // Two handles, both with handle.state === 'completed', but only the
139
+ // one that actually produced a result counts.
140
+ expect(taskResults).toHaveLength(2)
141
+ expect(countCompletedTasks(taskResults)).toBe(1)
142
+ })
143
+
144
+ it('counts every present completed result', () => {
145
+ const taskResults = synthesizeTaskResults(
146
+ [
147
+ handle({
148
+ taskId: 'task-a' as TaskId,
149
+ agentId: 'a',
150
+ state: 'completed',
151
+ result: completedResult(),
152
+ }),
153
+ handle({
154
+ taskId: 'task-b' as TaskId,
155
+ agentId: 'b',
156
+ state: 'completed',
157
+ result: completedResult(),
158
+ }),
159
+ ],
160
+ RUN_ID,
161
+ NOW,
162
+ )
163
+
164
+ expect(countCompletedTasks(taskResults)).toBe(2)
165
+ })
166
+
167
+ it('reports zero completed when no worker produced a result', () => {
168
+ const taskResults = synthesizeTaskResults(
169
+ [
170
+ handle({
171
+ taskId: 'task-a' as TaskId,
172
+ agentId: 'a',
173
+ state: 'completed',
174
+ result: undefined,
175
+ }),
176
+ handle({ taskId: 'task-b' as TaskId, agentId: 'b', state: 'running', result: undefined }),
177
+ ],
178
+ RUN_ID,
179
+ NOW,
180
+ )
181
+
182
+ expect(countCompletedTasks(taskResults)).toBe(0)
183
+ })
184
+ })
185
+ })
@@ -60,6 +60,9 @@ const MAPPING: {
60
60
  parts: [{ kind: 'text', text: e.error }],
61
61
  }),
62
62
 
63
+ // Capability degradation is host-facing diagnostics, not A2A task state.
64
+ capability_warning: null,
65
+
63
66
  iteration_started: (e, ctx) =>
64
67
  statusEvent(e.runId, 'running', false, ctx, {
65
68
  role: 'agent',
@@ -165,6 +165,11 @@ const MAPPING: {
165
165
  run_completed: null,
166
166
  run_failed: null,
167
167
 
168
+ // Not mapped to a wire event yet — hosts consume `capability_warning`
169
+ // from the RunEvent stream directly; promoting it to the SSE contract
170
+ // needs a StreamEventType addition first.
171
+ capability_warning: null,
172
+
168
173
  agent_pending: {
169
174
  wire: 'agent.pending',
170
175
  transform: (e, runId) => ({
@@ -18,6 +18,15 @@ export const TaskRouterConfigSchema = z
18
18
 
19
19
  export const CompactionConfigSchema = z.object({
20
20
  strategy: z.enum(['structured', 'sliding-window', 'disabled']).default('structured'),
21
+ /**
22
+ * Optional model context-window size (tokens) the compaction trigger
23
+ * measures the CURRENT window against. NO default: when omitted the
24
+ * trigger falls back to the run-level cumulative `tokenBudget` exactly as
25
+ * before, so existing consumers are byte-identical. Hosts that keep
26
+ * `tokenBudget` unlimited (0) set this so compaction fires on
27
+ * window-pressure instead of being a silent no-op.
28
+ */
29
+ contextWindowTokens: z.number().positive().optional(),
21
30
  triggerThreshold: z.number().min(0).max(1).default(0.7),
22
31
  resetThreshold: z.number().min(0).max(1).default(0.4),
23
32
  keepRecentMessages: z.number().positive().default(4),
@@ -126,6 +126,27 @@ describe('WebhookConnector', () => {
126
126
  expect((await c.execute('send', { payload: {} })).success).toBe(false)
127
127
  })
128
128
 
129
+ it('healthCheck returns false when the HEAD fetch throws', async () => {
130
+ const c = new WebhookConnector()
131
+ await c.connect({ url: 'https://hook.example.com' })
132
+ fetchMock.mockRejectedValueOnce(new Error('network down'))
133
+ expect(await c.healthCheck()).toBe(false)
134
+ })
135
+
136
+ it('reads a text body when the response is not JSON', async () => {
137
+ const c = new WebhookConnector()
138
+ await c.connect({ url: 'https://hook.example.com' })
139
+ fetchMock.mockResolvedValueOnce(
140
+ makeResponse({
141
+ status: 200,
142
+ headers: { 'content-type': 'text/plain' },
143
+ body: 'plain-text-ack',
144
+ }),
145
+ )
146
+ const result = await c.execute('send', { payload: { k: 'v' } })
147
+ expect((result.output as { body: unknown }).body).toBe('plain-text-ack')
148
+ })
149
+
129
150
  it('metadata.deliveredAt is a recent timestamp', async () => {
130
151
  const before = Date.now()
131
152
  const c = new WebhookConnector()
@@ -34,6 +34,7 @@ export type {
34
34
 
35
35
  export { StdioTransport } from './mcp/stdio.js'
36
36
  export { HttpSseTransport } from './mcp/http-sse.js'
37
+ export { StreamableHttpTransport } from './mcp/streamable-http.js'
37
38
 
38
39
  export { MCPClient } from './mcp/client.js'
39
40
 
@@ -19,6 +19,7 @@ import { generateMCPClientId } from '../../utils/id.js'
19
19
  import { type Logger, getRootLogger } from '../../utils/logger.js'
20
20
  import { HttpSseTransport } from './http-sse.js'
21
21
  import { StdioTransport } from './stdio.js'
22
+ import { StreamableHttpTransport } from './streamable-http.js'
22
23
 
23
24
  import { MCP_PROTOCOL_VERSION } from '../../constants/mcp/index.js'
24
25
  import { VERSION } from '../../version.js'
@@ -175,6 +176,9 @@ export class MCPClient {
175
176
  return new StdioTransport(config)
176
177
  case 'http-sse':
177
178
  return new HttpSseTransport(config)
179
+ case 'streamable_http':
180
+ case 'streamable-http':
181
+ return new StreamableHttpTransport(config)
178
182
  default:
179
183
  throw new Error(`Unsupported MCP transport type: ${(config as MCPTransportUnion).type}`)
180
184
  }
@@ -1,5 +1,6 @@
1
1
  export { StdioTransport } from './stdio.js'
2
2
  export { HttpSseTransport } from './http-sse.js'
3
+ export { StreamableHttpTransport } from './streamable-http.js'
3
4
 
4
5
  export { MCPClient } from './client.js'
5
6
 
@@ -0,0 +1,169 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest'
2
+
3
+ import type { MCPJsonRpcMessage } from '../../types/connector/index.js'
4
+ import { MCPClient } from './client.js'
5
+
6
+ afterEach(() => {
7
+ vi.unstubAllGlobals()
8
+ })
9
+
10
+ describe('Streamable HTTP MCP transport', () => {
11
+ it('connects through MCPClient, preserves session headers, and parses SSE responses', async () => {
12
+ const fetchMock = vi.fn<typeof fetch>()
13
+ fetchMock
14
+ .mockResolvedValueOnce(
15
+ jsonResponse(
16
+ {
17
+ jsonrpc: '2.0',
18
+ id: 1,
19
+ result: {
20
+ protocolVersion: '2024-11-05',
21
+ capabilities: { tools: { listChanged: true } },
22
+ serverInfo: { name: 'github' },
23
+ },
24
+ },
25
+ { 'mcp-session-id': 'sid_123' },
26
+ ),
27
+ )
28
+ .mockResolvedValueOnce(new Response('', { status: 202 }))
29
+ .mockResolvedValueOnce(
30
+ sseResponse([
31
+ { jsonrpc: '2.0', method: 'notifications/progress', params: { pct: 50 } },
32
+ {
33
+ jsonrpc: '2.0',
34
+ id: 2,
35
+ result: {
36
+ tools: [
37
+ {
38
+ name: 'search_repositories',
39
+ description: 'Search repositories',
40
+ inputSchema: { type: 'object' },
41
+ },
42
+ ],
43
+ },
44
+ },
45
+ ]),
46
+ )
47
+ vi.stubGlobal('fetch', fetchMock)
48
+
49
+ const client = new MCPClient({
50
+ serverName: 'github',
51
+ transport: {
52
+ type: 'streamable_http',
53
+ url: 'https://mcp.example.test/mcp',
54
+ headers: { Authorization: 'Bearer token' },
55
+ },
56
+ })
57
+ const notifications: string[] = []
58
+ client.onNotification((method) => notifications.push(method))
59
+
60
+ await client.connect()
61
+ const tools = await client.listTools()
62
+
63
+ expect(tools.map((tool) => tool.name)).toEqual(['search_repositories'])
64
+ expect(notifications).toEqual(['notifications/progress'])
65
+ expect(fetchMock).toHaveBeenCalledTimes(3)
66
+
67
+ const initialize = requestAt(fetchMock, 0)
68
+ expect(initialize.input).toBe('https://mcp.example.test/mcp')
69
+ expect(initialize.body.method).toBe('initialize')
70
+ expect(initialize.headers.Authorization).toBe('Bearer token')
71
+ expect(initialize.headers.Accept).toBe('application/json, text/event-stream')
72
+
73
+ const initialized = requestAt(fetchMock, 1)
74
+ expect(initialized.body.method).toBe('notifications/initialized')
75
+ expect(initialized.headers['Mcp-Session-Id']).toBe('sid_123')
76
+
77
+ const listTools = requestAt(fetchMock, 2)
78
+ expect(listTools.body.method).toBe('tools/list')
79
+ expect(listTools.headers['Mcp-Session-Id']).toBe('sid_123')
80
+ })
81
+
82
+ it('supports the streamable-http alias without non-standard hint headers', async () => {
83
+ const fetchMock = vi.fn<typeof fetch>()
84
+ fetchMock
85
+ .mockResolvedValueOnce(
86
+ jsonResponse(
87
+ {
88
+ jsonrpc: '2.0',
89
+ id: 1,
90
+ result: {
91
+ protocolVersion: '2024-11-05',
92
+ capabilities: { tools: {} },
93
+ serverInfo: { name: 'linear' },
94
+ },
95
+ },
96
+ { 'Mcp-Session-Id': 'sid_alias' },
97
+ ),
98
+ )
99
+ .mockResolvedValueOnce(new Response(null, { status: 204 }))
100
+ .mockResolvedValueOnce(
101
+ jsonResponse({
102
+ jsonrpc: '2.0',
103
+ id: 2,
104
+ result: { content: [{ type: 'text', text: 'ok' }] },
105
+ }),
106
+ )
107
+ vi.stubGlobal('fetch', fetchMock)
108
+
109
+ const client = new MCPClient({
110
+ serverName: 'linear',
111
+ transport: {
112
+ type: 'streamable-http',
113
+ url: 'https://mcp.example.test/linear',
114
+ },
115
+ })
116
+
117
+ await client.connect()
118
+ const result = await client.callTool('create_issue', { title: 'Bug' })
119
+
120
+ expect(result.content).toEqual([{ type: 'text', text: 'ok' }])
121
+ const callTool = requestAt(fetchMock, 2)
122
+ expect(callTool.body.method).toBe('tools/call')
123
+ expect(callTool.headers).toEqual({
124
+ 'Content-Type': 'application/json',
125
+ Accept: 'application/json, text/event-stream',
126
+ 'Mcp-Session-Id': 'sid_alias',
127
+ })
128
+ })
129
+ })
130
+
131
+ function jsonResponse(body: MCPJsonRpcMessage, headers?: Record<string, string>): Response {
132
+ return new Response(JSON.stringify(body), {
133
+ status: 200,
134
+ headers: {
135
+ 'content-type': 'application/json',
136
+ ...headers,
137
+ },
138
+ })
139
+ }
140
+
141
+ function sseResponse(messages: MCPJsonRpcMessage[]): Response {
142
+ return new Response(messages.map((message) => `data: ${JSON.stringify(message)}\n\n`).join(''), {
143
+ status: 200,
144
+ headers: {
145
+ 'content-type': 'text/event-stream',
146
+ },
147
+ })
148
+ }
149
+
150
+ function requestAt(
151
+ fetchMock: ReturnType<typeof vi.fn<typeof fetch>>,
152
+ index: number,
153
+ ): {
154
+ input: Parameters<typeof fetch>[0]
155
+ headers: Record<string, string>
156
+ body: MCPJsonRpcMessage
157
+ } {
158
+ const call = fetchMock.mock.calls[index]
159
+ if (!call) {
160
+ throw new Error(`No fetch call at index ${index}`)
161
+ }
162
+ const [input, init] = call
163
+ if (!init) {
164
+ throw new Error(`Fetch call at index ${index} had no init`)
165
+ }
166
+ const headers = init.headers as Record<string, string>
167
+ const body = JSON.parse(String(init.body)) as MCPJsonRpcMessage
168
+ return { input, headers, body }
169
+ }