@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
@@ -0,0 +1,152 @@
1
+ import type {
2
+ MCPJsonRpcMessage,
3
+ MCPStreamableHttpTransportConfig,
4
+ MCPTransport,
5
+ } from '../../types/connector/index.js'
6
+ import { type Logger, getRootLogger } from '../../utils/logger.js'
7
+
8
+ const DEFAULT_TIMEOUT_MS = 30_000
9
+
10
+ export class StreamableHttpTransport implements MCPTransport {
11
+ private messageHandlers: Array<(message: MCPJsonRpcMessage) => void> = []
12
+ private closeHandlers: Array<() => void> = []
13
+ private errorHandlers: Array<(error: Error) => void> = []
14
+ private connected = false
15
+ private sessionId: string | null = null
16
+ private log: Logger
17
+
18
+ constructor(private readonly config: MCPStreamableHttpTransportConfig) {
19
+ this.log = getRootLogger().child({ component: 'StreamableHttpTransport' })
20
+ }
21
+
22
+ async connect(): Promise<void> {
23
+ if (this.connected) return
24
+ this.connected = true
25
+ this.log.info(`StreamableHttpTransport connected to ${this.config.url}`)
26
+ }
27
+
28
+ async close(): Promise<void> {
29
+ if (!this.connected) return
30
+ this.connected = false
31
+ for (const handler of this.closeHandlers) handler()
32
+ }
33
+
34
+ async send(message: MCPJsonRpcMessage): Promise<void> {
35
+ if (!this.connected) {
36
+ throw new Error('StreamableHttpTransport: not connected')
37
+ }
38
+
39
+ const controller = new AbortController()
40
+ const timeout = setTimeout(
41
+ () => controller.abort(),
42
+ this.config.timeoutMs ?? DEFAULT_TIMEOUT_MS,
43
+ )
44
+
45
+ try {
46
+ const response = await fetch(this.config.url, {
47
+ method: 'POST',
48
+ headers: this.buildHeaders(),
49
+ body: JSON.stringify(message),
50
+ signal: controller.signal,
51
+ })
52
+
53
+ this.captureSessionId(response)
54
+
55
+ if (!response.ok) {
56
+ throw new Error(`StreamableHttpTransport: HTTP ${response.status}: ${response.statusText}`)
57
+ }
58
+
59
+ await this.dispatchResponseMessages(response)
60
+ } catch (err) {
61
+ const error = err instanceof Error ? err : new Error(String(err))
62
+ for (const handler of this.errorHandlers) handler(error)
63
+ throw error
64
+ } finally {
65
+ clearTimeout(timeout)
66
+ }
67
+ }
68
+
69
+ onMessage(handler: (message: MCPJsonRpcMessage) => void): void {
70
+ this.messageHandlers.push(handler)
71
+ }
72
+
73
+ onClose(handler: () => void): void {
74
+ this.closeHandlers.push(handler)
75
+ }
76
+
77
+ onError(handler: (error: Error) => void): void {
78
+ this.errorHandlers.push(handler)
79
+ }
80
+
81
+ isConnected(): boolean {
82
+ return this.connected
83
+ }
84
+
85
+ private buildHeaders(): Record<string, string> {
86
+ const headers: Record<string, string> = {
87
+ 'Content-Type': 'application/json',
88
+ Accept: 'application/json, text/event-stream',
89
+ ...this.config.headers,
90
+ }
91
+
92
+ if (this.sessionId) {
93
+ headers['Mcp-Session-Id'] = this.sessionId
94
+ }
95
+
96
+ return headers
97
+ }
98
+
99
+ private captureSessionId(response: Response): void {
100
+ const sessionId =
101
+ response.headers.get('mcp-session-id') ?? response.headers.get('Mcp-Session-Id')
102
+ if (sessionId && sessionId.length > 0) {
103
+ this.sessionId = sessionId
104
+ }
105
+ }
106
+
107
+ private async dispatchResponseMessages(response: Response): Promise<void> {
108
+ const text = await response.text()
109
+ if (text.trim().length === 0) return
110
+
111
+ const contentType = response.headers.get('content-type') ?? ''
112
+ const messages = contentType.includes('text/event-stream')
113
+ ? parseSseMessages(text)
114
+ : parseJsonMessages(text)
115
+
116
+ for (const message of messages) {
117
+ for (const handler of this.messageHandlers) handler(message)
118
+ }
119
+ }
120
+ }
121
+
122
+ function parseJsonMessages(raw: string): MCPJsonRpcMessage[] {
123
+ const parsed = JSON.parse(raw) as MCPJsonRpcMessage | MCPJsonRpcMessage[]
124
+ return Array.isArray(parsed) ? parsed : [parsed]
125
+ }
126
+
127
+ function parseSseMessages(raw: string): MCPJsonRpcMessage[] {
128
+ const normalized = raw.replace(/\r\n/g, '\n')
129
+ const events = normalized.split(/\n\n+/)
130
+ const messages: MCPJsonRpcMessage[] = []
131
+
132
+ for (const event of events) {
133
+ const dataLines = event
134
+ .split('\n')
135
+ .filter((line) => line.startsWith('data:'))
136
+ .map((line) => line.slice('data:'.length).trimStart())
137
+
138
+ if (dataLines.length === 0) continue
139
+
140
+ const data = dataLines.join('\n').trim()
141
+ if (data.length === 0 || data === '[DONE]') continue
142
+
143
+ const parsed = JSON.parse(data) as MCPJsonRpcMessage | MCPJsonRpcMessage[]
144
+ if (Array.isArray(parsed)) {
145
+ messages.push(...parsed)
146
+ } else {
147
+ messages.push(parsed)
148
+ }
149
+ }
150
+
151
+ return messages
152
+ }
@@ -11,6 +11,11 @@
11
11
  * that match this constant verbatim, so the run's `result` field
12
12
  * concatenates the full multi-turn assistant output instead of only
13
13
  * surfacing the trailing continuation chunk.
14
+ *
15
+ * Lives in `constants/` (not `runtime/query/`) because both the
16
+ * runtime iteration loop and `manager/run/persistence.ts` consume
17
+ * it — a manager→runtime import for a string constant would create
18
+ * a manager↔runtime directory cycle.
14
19
  */
15
20
  export const AUTO_CONTINUATION_USER_MESSAGE =
16
21
  'Continue exactly where you left off. Do not repeat content you already wrote — pick up at the next token.'
@@ -7,6 +7,7 @@ export * from './rag/index.js'
7
7
  export * from './tools/index.js'
8
8
  export * from './telemetry/index.js'
9
9
  export * from './agent/index.js'
10
+ export * from './continuation.js'
10
11
  export * from './limits.js'
11
12
  export * from './bus/index.js'
12
13
  export * from './verification/index.js'
@@ -1,9 +1,11 @@
1
+ import { AUTO_CONTINUATION_USER_MESSAGE } from '../../constants/continuation.js'
1
2
  import { EMPTY_TOKEN_USAGE } from '../../constants/limits.js'
2
- import { AUTO_CONTINUATION_USER_MESSAGE } from '../../runtime/query/continuation.js'
3
+ import { DiskCheckpointStore } from '../../store/run/checkpoint-disk.js'
3
4
  import { RunDiskStore } from '../../store/run/disk.js'
4
5
  import { type CostInfo, type TokenUsage, accumulateTokenUsage } from '../../types/common/index.js'
5
6
  import type { RunId, SessionId, TenantId } from '../../types/ids/index.js'
6
7
  import type { Message } from '../../types/message/index.js'
8
+ import type { CheckpointRunScope, CheckpointStore } from '../../types/run/checkpoint-store.js'
7
9
  import type { EmergencySaveData } from '../../types/run/emergency.js'
8
10
  import type { Run, RunPersistenceConfig, StopReason } from '../../types/run/index.js'
9
11
  import type { ProjectId, ThreadId } from '../../types/session/ids.js'
@@ -14,6 +16,7 @@ import type { Logger } from '../../utils/logger.js'
14
16
  export class RunPersistence {
15
17
  private run: Run
16
18
  private runStore: RunDiskStore
19
+ private checkpointStore: CheckpointStore
17
20
  private pricing?: ModelPricing
18
21
  private log: Logger
19
22
  private readonly _sessionId: SessionId
@@ -34,6 +37,15 @@ export class RunPersistence {
34
37
  logger: config.log,
35
38
  })
36
39
 
40
+ // Checkpoints go through the injectable seam; the disk layout under
41
+ // `outputDir` (same tree the runStore writes to) stays the default.
42
+ this.checkpointStore =
43
+ config.checkpointStore ??
44
+ new DiskCheckpointStore({
45
+ baseDir: config.outputDir,
46
+ logger: config.log,
47
+ })
48
+
37
49
  this.run = {
38
50
  id: config.runId,
39
51
  status: 'idle',
@@ -109,6 +121,27 @@ export class RunPersistence {
109
121
  return this.runStore
110
122
  }
111
123
 
124
+ /**
125
+ * Checkpoint persistence for this run — the injected
126
+ * {@link CheckpointStore} when the host provided one, otherwise the
127
+ * disk default. Pair with {@link getRunScope} when constructing a
128
+ * `CheckpointManager`.
129
+ */
130
+ getCheckpointStore(): CheckpointStore {
131
+ return this.checkpointStore
132
+ }
133
+
134
+ /** Full five-layer scope key for this run's checkpoint operations. */
135
+ getRunScope(): CheckpointRunScope {
136
+ return {
137
+ tenantId: this._tenantId,
138
+ projectId: this._projectId,
139
+ sessionId: this._sessionId,
140
+ runId: this.run.id,
141
+ parentRunId: this.run.parentRunId,
142
+ }
143
+ }
144
+
112
145
  getRunDir(): string | null {
113
146
  return this.runStore.getRunDir()
114
147
  }
@@ -48,17 +48,29 @@ export function renderSkillsSection(skills?: Skill[]): string | null {
48
48
 
49
49
  const available = skills
50
50
  .map((s) => {
51
- const details = [`description: ${s.metadata.description.trim()}`]
52
- if (s.metadata.compatibility) details.push(`compatibility: ${s.metadata.compatibility}`)
53
- if (s.metadata.license) details.push(`license: ${s.metadata.license}`)
54
- if (s.metadata.allowedTools) details.push(`allowed-tools: ${s.metadata.allowedTools}`)
55
- return `- ${s.metadata.name} (${details.join('; ')})\n directory: ${s.dirPath}`
51
+ const lines = [
52
+ '<skill>',
53
+ `<name>${s.metadata.name}</name>`,
54
+ `<description>${s.metadata.description.trim()}</description>`,
55
+ `<location>${s.dirPath}/SKILL.md</location>`,
56
+ ]
57
+ if (s.metadata.compatibility) {
58
+ lines.push(`<compatibility>${s.metadata.compatibility}</compatibility>`)
59
+ }
60
+ if (s.metadata.license) {
61
+ lines.push(`<license>${s.metadata.license}</license>`)
62
+ }
63
+ if (s.metadata.allowedTools) {
64
+ lines.push(`<allowed_tools>${s.metadata.allowedTools}</allowed_tools>`)
65
+ }
66
+ lines.push('</skill>')
67
+ return lines.join('\n')
56
68
  })
57
69
  .join('\n')
58
70
 
59
71
  const loadedSkills = skills.filter((s) => s.body)
60
72
  const sections = [
61
- `## Available Skills\nThese Agent Skills are available through progressive disclosure. Use a skill only when the task matches its description. If a skill is not already loaded below, activate/read its SKILL.md from the listed directory when the runtime provides filesystem or skill-loading access.\n\n${available}`,
73
+ `## Available Skills\nThe following block is a manifest, not the full skill content. Skill metadata is always visible; SKILL.md bodies are loaded only when the user's task matches the skill description.\n\n<available_skills>\n${available}\n</available_skills>\n\nSkill usage protocol:\n- Plain questions do not require a skill.\n- When a matching skill is already listed under Loaded Skills, apply its loaded instructions.\n- When a matching skill is not loaded and the runtime exposes filesystem or skill-loading tools, read the SKILL.md at its <location> before writing code, creating files, running shell commands for that workflow, or calling mutation tools guided by the skill.\n- Do not claim to have read a SKILL.md until its content is actually present in the prompt or returned by a tool.\n- Tool schemas and runtime permissions remain authoritative; skills provide guidance, not hidden tools.`,
62
74
  ]
63
75
 
64
76
  if (loadedSkills.length > 0) {
@@ -0,0 +1,47 @@
1
+ import type { LLMProvider, ProviderCapabilities } from '../types/provider/index.js'
2
+
3
+ /**
4
+ * Fully-resolved capability set: every flag present, no optionals left.
5
+ * What the query runtime branches on after applying the permissive default.
6
+ */
7
+ export interface ResolvedProviderCapabilities {
8
+ supportsTools: boolean
9
+ supportsStreaming: boolean
10
+ supportsFunctionCalling: boolean
11
+ supportsVision: boolean
12
+ maxOutputTokens?: number
13
+ }
14
+
15
+ /**
16
+ * THE permissive default: a provider that declares nothing is assumed to
17
+ * handle everything — exactly the pre-negotiation behavior, so third-party
18
+ * providers written before `LLMProvider.capabilities` existed keep working
19
+ * without a warning storm. Shipped drivers always declare explicitly.
20
+ */
21
+ export const PERMISSIVE_PROVIDER_CAPABILITIES: ResolvedProviderCapabilities = {
22
+ supportsTools: true,
23
+ supportsStreaming: true,
24
+ supportsFunctionCalling: true,
25
+ supportsVision: true,
26
+ }
27
+
28
+ /**
29
+ * Resolve a provider's declared capabilities against the permissive
30
+ * default. Absent declaration ⇒ everything `true`; a partial declaration
31
+ * (e.g. one missing `supportsVision`, added later) fills the gap
32
+ * permissively per field.
33
+ */
34
+ export function resolveProviderCapabilities(
35
+ provider: Pick<LLMProvider, 'capabilities'>,
36
+ ): ResolvedProviderCapabilities {
37
+ const declared: ProviderCapabilities | undefined = provider.capabilities
38
+ return {
39
+ supportsTools: declared?.supportsTools ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsTools,
40
+ supportsStreaming:
41
+ declared?.supportsStreaming ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsStreaming,
42
+ supportsFunctionCalling:
43
+ declared?.supportsFunctionCalling ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsFunctionCalling,
44
+ supportsVision: declared?.supportsVision ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsVision,
45
+ maxOutputTokens: declared?.maxOutputTokens,
46
+ }
47
+ }
@@ -1,3 +1,4 @@
1
+ import { mergeTokenUsage } from '../types/common/index.js'
1
2
  import type { ChatCompletionResponse } from '../types/provider/chat.js'
2
3
  import type { StreamChunk } from '../types/provider/stream.js'
3
4
 
@@ -60,7 +61,9 @@ export async function collect(stream: AsyncIterable<StreamChunk>): Promise<ChatC
60
61
  }
61
62
 
62
63
  if (chunk.finishReason) finishReason = chunk.finishReason
63
- if (chunk.usage) usage = chunk.usage
64
+ // Merge (per-field max), not last-write-wins: a late frame that omits
65
+ // input/cache tokens must not zero the counts captured earlier in the stream.
66
+ if (chunk.usage) usage = mergeTokenUsage(usage, chunk.usage)
64
67
  }
65
68
 
66
69
  const toolCalls = [...toolBuckets.entries()]
@@ -1,3 +1,8 @@
1
1
  export { ProviderRegistry, UnknownProviderError, DuplicateProviderError } from './registry.js'
2
2
  export { MockLLMProvider } from './mock.js'
3
3
  export { registerMock, MOCK_CAPABILITIES } from './mock-register.js'
4
+ export {
5
+ PERMISSIVE_PROVIDER_CAPABILITIES,
6
+ resolveProviderCapabilities,
7
+ } from './capabilities.js'
8
+ export type { ResolvedProviderCapabilities } from './capabilities.js'
@@ -99,6 +99,7 @@ export {
99
99
 
100
100
  export {
101
101
  ActivityStore,
102
+ DiskCheckpointStore,
102
103
  DiskMemoryStore,
103
104
  DiskTaskStore,
104
105
  InMemoryMemoryIndex,
@@ -146,8 +147,10 @@ export {
146
147
  DuplicateProviderError,
147
148
  MOCK_CAPABILITIES,
148
149
  MockLLMProvider,
150
+ PERMISSIVE_PROVIDER_CAPABILITIES,
149
151
  ProviderRegistry,
150
152
  registerMock,
153
+ resolveProviderCapabilities,
151
154
  UnknownProviderError,
152
155
  } from './provider/index.js'
153
156
 
@@ -194,6 +197,7 @@ export {
194
197
  RemoteExecutionContext,
195
198
  ScopedConnectorRegistry,
196
199
  StdioTransport,
200
+ StreamableHttpTransport,
197
201
  TenantConnectorManager,
198
202
  toolDefinitionToMCPTool,
199
203
  toolResultToMCPToolResult,
@@ -247,6 +251,7 @@ export {
247
251
 
248
252
  export { wrapProviderWithProbes } from './provider/instrumentation.js'
249
253
  export type { ProviderInstrumentationOptions } from './provider/instrumentation.js'
254
+ export type { ResolvedProviderCapabilities } from './provider/capabilities.js'
250
255
  export { collect } from './provider/collect.js'
251
256
 
252
257
  export { wrapVaultWithProbes } from './vault/instrumentation.js'
@@ -20,18 +20,21 @@
20
20
  * reports true iff at least one tool is suspended.
21
21
  * - `getAvailability(name)` returns 'active' as a default even for
22
22
  * unknown names (this is non-obvious but is the current behavior).
23
- * - `searchDeferred(q)` filters DEFERRED tools: a useful whole query
24
- * matches name OR description (case-insensitive); a batched multi-term
25
- * query matches meaningful tokens against the NAME only. Generic/short
26
- * tokens (`clawtool`, `tool`, …) are ignored so they can't over-activate.
23
+ * - `searchDeferred(q)` is a RANKED weighted search over DEFERRED tools:
24
+ * per meaningful term (≥3 chars, not a stop token) the score is
25
+ * exact-name 12 / name-substring 8 / description 5 / argument-name 3;
26
+ * results sort score-descending with name ties broken alphabetically.
27
+ * Generic/short tokens (`clawtool`, `tool`, CRUD verbs like `list`,
28
+ * `read`, …) are stopped so they can't over-activate the catalog.
27
29
  * - `assignTiers(mapping)` mutates `tool.tier` on existing tools;
28
30
  * throws via `getOrThrow` on unknown name; throws if the tier id
29
31
  * is not in `tierConfig.tiers`.
30
32
  * - `toTierGuidance` returns null without a guidanceTemplate; calls
31
33
  * the template with every defined tier otherwise.
32
34
  * - `toPromptSection`: returns '' when no active or deferred tools;
33
- * otherwise produces `<available_tools>` + `<deferred_tools>`
34
- * fragments.
35
+ * otherwise produces `<available_tools>` (name-only — descriptions
36
+ * already ride the runtime tools param) + `<deferred_tools>` (name +
37
+ * first-sentence hint ≤100 chars) fragments.
35
38
  * - `toLLMTools`: converts active + suspended tools (filtered by
36
39
  * `toolNames` if provided) into LLM tool schemas via
37
40
  * `zodToJsonSchema`. When `tierConfig.labelInDescription` is true,
@@ -198,15 +201,59 @@ describe('ToolRegistry — searchDeferred', () => {
198
201
  r.register([makeTool('clawtool_PeerRegister')], 'deferred')
199
202
  r.register([makeTool('clawtool_PeerList')], 'deferred')
200
203
  r.register([makeTool('clawtool_Unrelated')], 'deferred')
201
- // A whole-phrase substring match would find none of these.
204
+ // A whole-phrase substring match would find none of these. Equal
205
+ // scores tie-break alphabetically by name (deterministic ranking).
202
206
  expect(r.searchDeferred('A2aCard PeerRegister PeerList').map((t) => t.name)).toEqual([
203
207
  'clawtool_A2aCard',
204
- 'clawtool_PeerRegister',
205
208
  'clawtool_PeerList',
209
+ 'clawtool_PeerRegister',
206
210
  ])
207
211
  expect(r.searchDeferred(' ')).toEqual([])
208
212
  })
209
213
 
214
+ it('ranks exact name above name substring above description-only matches', () => {
215
+ const r = new ToolRegistry()
216
+ r.register([makeTool('release_notes', { description: 'Write deploy notes.' })], 'deferred')
217
+ r.register([makeTool('deploy_preview', { description: 'Stage a preview build.' })], 'deferred')
218
+ r.register([makeTool('deploy', { description: 'Ship the current build.' })], 'deferred')
219
+ expect(r.searchDeferred('deploy').map((t) => t.name)).toEqual([
220
+ 'deploy', // exact name → 12
221
+ 'deploy_preview', // name substring → 8
222
+ 'release_notes', // description only → 5
223
+ ])
224
+ })
225
+
226
+ it('indexes argument names so a parameter term can locate a tool', () => {
227
+ const r = new ToolRegistry()
228
+ r.register(
229
+ [
230
+ makeTool('send_invoice', {
231
+ inputSchema: z.object({ customerEmail: z.string(), amount: z.number() }),
232
+ }),
233
+ ],
234
+ 'deferred',
235
+ )
236
+ r.register([makeTool('send_reminder')], 'deferred')
237
+ expect(r.searchDeferred('customerEmail').map((t) => t.name)).toEqual(['send_invoice'])
238
+ })
239
+
240
+ it('stops generic CRUD verbs so they cannot activate catalog slices', () => {
241
+ const r = new ToolRegistry()
242
+ r.register(
243
+ [makeTool('list_deals', { description: 'List the deals in an account.' })],
244
+ 'deferred',
245
+ )
246
+ r.register([makeTool('list_workflows', { description: 'List workflows.' })], 'deferred')
247
+ r.register([makeTool('read_document', { description: 'Read a document body.' })], 'deferred')
248
+ // Bare CRUD verbs identify nothing.
249
+ expect(r.searchDeferred('list')).toEqual([])
250
+ expect(r.searchDeferred('read')).toEqual([])
251
+ expect(r.searchDeferred('create update delete')).toEqual([])
252
+ // The non-generic remainder carries the query.
253
+ expect(r.searchDeferred('list deals').map((t) => t.name)).toEqual(['list_deals'])
254
+ expect(r.searchDeferred('read document').map((t) => t.name)).toEqual(['read_document'])
255
+ })
256
+
210
257
  it('does not over-activate on generic/shared tokens', () => {
211
258
  const r = new ToolRegistry()
212
259
  r.register([makeTool('clawtool_A2aCard', { description: 'peer card' })], 'deferred')
@@ -270,10 +317,38 @@ describe('ToolRegistry — toPromptSection + toLLMTools', () => {
270
317
  expect(s).toContain('<tool_runtime_contract>')
271
318
  expect(s).toContain('runtime tools parameter')
272
319
  expect(s).toContain('<available_tools>')
273
- expect(s).toContain('- a: a tool')
320
+ // Active entries are NAME-ONLY: the description already rides the
321
+ // runtime tools param every request — repeating it double-bills.
322
+ expect(s).toContain('- a\n')
323
+ expect(s).not.toContain('- a: a tool')
274
324
  expect(s).toContain('<deferred_tools>')
275
325
  expect(s).toContain('Deferred tools are discoverable')
276
- expect(s).toContain('- b')
326
+ // Deferred entries carry a one-line hint — their schema is off the
327
+ // wire, so the hint is the model's only capability signal.
328
+ expect(s).toContain('- b: b tool')
329
+ })
330
+
331
+ it('toPromptSection truncates deferred hints to the first sentence, capped at 100 chars', () => {
332
+ const r = new ToolRegistry()
333
+ r.register(
334
+ [
335
+ makeTool('two_sentences', {
336
+ description: 'Reads the document. Second sentence that must not appear.',
337
+ }),
338
+ makeTool('long_sentence', {
339
+ description: `${'x'.repeat(150)} end`,
340
+ }),
341
+ ],
342
+ 'deferred',
343
+ )
344
+ const s = r.toPromptSection()
345
+ expect(s).toContain('- two_sentences: Reads the document.')
346
+ expect(s).not.toContain('Second sentence')
347
+ const longLine = s.split('\n').find((line) => line.startsWith('- long_sentence:'))
348
+ expect(longLine).toBeDefined()
349
+ const hint = (longLine ?? '').replace('- long_sentence: ', '')
350
+ expect(hint.length).toBeLessThanOrEqual(100)
351
+ expect(hint.endsWith('…')).toBe(true)
277
352
  })
278
353
 
279
354
  it('toPromptSection references search_tools only when it is active', () => {