@namzu/sdk 34.2.0 → 35.0.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 (637) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/README.md +2 -6
  3. package/dist/agents/PipelineAgent.d.ts.map +1 -1
  4. package/dist/agents/PipelineAgent.js +118 -100
  5. package/dist/agents/PipelineAgent.js.map +1 -1
  6. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  7. package/dist/agents/ReactiveAgent.js +2 -0
  8. package/dist/agents/ReactiveAgent.js.map +1 -1
  9. package/dist/agents/RouterAgent.d.ts.map +1 -1
  10. package/dist/agents/RouterAgent.js +105 -61
  11. package/dist/agents/RouterAgent.js.map +1 -1
  12. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  13. package/dist/agents/SupervisorAgent.js +8 -4
  14. package/dist/agents/SupervisorAgent.js.map +1 -1
  15. package/dist/agents/budget.d.ts +6 -0
  16. package/dist/agents/budget.d.ts.map +1 -0
  17. package/dist/agents/budget.js +33 -0
  18. package/dist/agents/budget.js.map +1 -0
  19. package/dist/agents/explore.d.ts +20 -0
  20. package/dist/agents/explore.d.ts.map +1 -0
  21. package/dist/agents/explore.js +26 -0
  22. package/dist/agents/explore.js.map +1 -0
  23. package/dist/agents/file-definitions.d.ts +80 -0
  24. package/dist/agents/file-definitions.d.ts.map +1 -0
  25. package/dist/agents/file-definitions.js +179 -0
  26. package/dist/agents/file-definitions.js.map +1 -0
  27. package/dist/agents/index.d.ts +3 -0
  28. package/dist/agents/index.d.ts.map +1 -1
  29. package/dist/agents/index.js +2 -0
  30. package/dist/agents/index.js.map +1 -1
  31. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  32. package/dist/bridge/a2a/mapper.js +6 -0
  33. package/dist/bridge/a2a/mapper.js.map +1 -1
  34. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  35. package/dist/bridge/sse/mapper.js +22 -0
  36. package/dist/bridge/sse/mapper.js.map +1 -1
  37. package/dist/bus/lock.d.ts.map +1 -1
  38. package/dist/bus/lock.js +1 -10
  39. package/dist/bus/lock.js.map +1 -1
  40. package/dist/compaction/consolidation.d.ts +31 -0
  41. package/dist/compaction/consolidation.d.ts.map +1 -0
  42. package/dist/compaction/consolidation.js +63 -0
  43. package/dist/compaction/consolidation.js.map +1 -0
  44. package/dist/compaction/factory.d.ts.map +1 -1
  45. package/dist/compaction/factory.js +3 -0
  46. package/dist/compaction/factory.js.map +1 -1
  47. package/dist/compaction/index.d.ts +6 -1
  48. package/dist/compaction/index.d.ts.map +1 -1
  49. package/dist/compaction/index.js +6 -0
  50. package/dist/compaction/index.js.map +1 -1
  51. package/dist/compaction/manager.d.ts +7 -0
  52. package/dist/compaction/manager.d.ts.map +1 -1
  53. package/dist/compaction/manager.js +31 -0
  54. package/dist/compaction/manager.js.map +1 -1
  55. package/dist/compaction/plan.d.ts +23 -0
  56. package/dist/compaction/plan.d.ts.map +1 -1
  57. package/dist/compaction/plan.js +41 -24
  58. package/dist/compaction/plan.js.map +1 -1
  59. package/dist/compaction/salience/bm25.d.ts +26 -0
  60. package/dist/compaction/salience/bm25.d.ts.map +1 -0
  61. package/dist/compaction/salience/bm25.js +56 -0
  62. package/dist/compaction/salience/bm25.js.map +1 -0
  63. package/dist/compaction/salience/goal.d.ts +21 -0
  64. package/dist/compaction/salience/goal.d.ts.map +1 -0
  65. package/dist/compaction/salience/goal.js +32 -0
  66. package/dist/compaction/salience/goal.js.map +1 -0
  67. package/dist/compaction/salience/index.d.ts +4 -0
  68. package/dist/compaction/salience/index.d.ts.map +1 -0
  69. package/dist/compaction/salience/index.js +4 -0
  70. package/dist/compaction/salience/index.js.map +1 -0
  71. package/dist/compaction/salience/minhash.d.ts +17 -0
  72. package/dist/compaction/salience/minhash.d.ts.map +1 -0
  73. package/dist/compaction/salience/minhash.js +54 -0
  74. package/dist/compaction/salience/minhash.js.map +1 -0
  75. package/dist/compaction/salience/score.d.ts +64 -0
  76. package/dist/compaction/salience/score.d.ts.map +1 -0
  77. package/dist/compaction/salience/score.js +256 -0
  78. package/dist/compaction/salience/score.js.map +1 -0
  79. package/dist/compaction/salience/tokenize.d.ts +20 -0
  80. package/dist/compaction/salience/tokenize.d.ts.map +1 -0
  81. package/dist/compaction/salience/tokenize.js +92 -0
  82. package/dist/compaction/salience/tokenize.js.map +1 -0
  83. package/dist/compaction/salience/working-set.d.ts +59 -0
  84. package/dist/compaction/salience/working-set.d.ts.map +1 -0
  85. package/dist/compaction/salience/working-set.js +137 -0
  86. package/dist/compaction/salience/working-set.js.map +1 -0
  87. package/dist/compaction/serializer.d.ts +2 -0
  88. package/dist/compaction/serializer.d.ts.map +1 -1
  89. package/dist/compaction/serializer.js +15 -0
  90. package/dist/compaction/serializer.js.map +1 -1
  91. package/dist/compaction/token-estimate.d.ts +13 -0
  92. package/dist/compaction/token-estimate.d.ts.map +1 -0
  93. package/dist/compaction/token-estimate.js +58 -0
  94. package/dist/compaction/token-estimate.js.map +1 -0
  95. package/dist/compaction/tool-result-editing.d.ts +10 -2
  96. package/dist/compaction/tool-result-editing.d.ts.map +1 -1
  97. package/dist/compaction/tool-result-editing.js +22 -24
  98. package/dist/compaction/tool-result-editing.js.map +1 -1
  99. package/dist/compaction/types.d.ts +22 -1
  100. package/dist/compaction/types.d.ts.map +1 -1
  101. package/dist/compaction/wire.d.ts +3 -1
  102. package/dist/compaction/wire.d.ts.map +1 -1
  103. package/dist/compaction/wire.js +2 -0
  104. package/dist/compaction/wire.js.map +1 -1
  105. package/dist/config/runtime.d.ts +58 -28
  106. package/dist/config/runtime.d.ts.map +1 -1
  107. package/dist/config/runtime.js +13 -1
  108. package/dist/config/runtime.js.map +1 -1
  109. package/dist/connector/builtins/http.d.ts.map +1 -1
  110. package/dist/connector/builtins/http.js +2 -8
  111. package/dist/connector/builtins/http.js.map +1 -1
  112. package/dist/connector/builtins/webhook.js +2 -2
  113. package/dist/connector/builtins/webhook.js.map +1 -1
  114. package/dist/connector/mcp/adapter.d.ts +2 -0
  115. package/dist/connector/mcp/adapter.d.ts.map +1 -1
  116. package/dist/connector/mcp/adapter.js +30 -0
  117. package/dist/connector/mcp/adapter.js.map +1 -1
  118. package/dist/connector/tools/adapter.js +2 -2
  119. package/dist/connector/tools/adapter.js.map +1 -1
  120. package/dist/connector/tools/definitions.js +2 -2
  121. package/dist/connector/tools/definitions.js.map +1 -1
  122. package/dist/constants/compaction/index.d.ts +1 -0
  123. package/dist/constants/compaction/index.d.ts.map +1 -1
  124. package/dist/constants/compaction/index.js +1 -0
  125. package/dist/constants/compaction/index.js.map +1 -1
  126. package/dist/constants/telemetry/index.d.ts +0 -1
  127. package/dist/constants/telemetry/index.d.ts.map +1 -1
  128. package/dist/constants/telemetry/index.js +0 -1
  129. package/dist/constants/telemetry/index.js.map +1 -1
  130. package/dist/contracts/a2a.d.ts +5 -5
  131. package/dist/contracts/api.d.ts +4 -2
  132. package/dist/contracts/api.d.ts.map +1 -1
  133. package/dist/contracts/schemas.d.ts +1 -15
  134. package/dist/contracts/schemas.d.ts.map +1 -1
  135. package/dist/contracts/schemas.js +5 -20
  136. package/dist/contracts/schemas.js.map +1 -1
  137. package/dist/invariants/index.d.ts +1 -1
  138. package/dist/manager/agent/lifecycle.d.ts +2 -18
  139. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  140. package/dist/manager/agent/lifecycle.js +373 -340
  141. package/dist/manager/agent/lifecycle.js.map +1 -1
  142. package/dist/manager/run/persistence.d.ts +3 -0
  143. package/dist/manager/run/persistence.d.ts.map +1 -1
  144. package/dist/manager/run/persistence.js +35 -5
  145. package/dist/manager/run/persistence.js.map +1 -1
  146. package/dist/plugin/index.d.ts +2 -0
  147. package/dist/plugin/index.d.ts.map +1 -1
  148. package/dist/plugin/index.js +1 -0
  149. package/dist/plugin/index.js.map +1 -1
  150. package/dist/plugin/shell-hook.d.ts +128 -0
  151. package/dist/plugin/shell-hook.d.ts.map +1 -0
  152. package/dist/plugin/shell-hook.js +299 -0
  153. package/dist/plugin/shell-hook.js.map +1 -0
  154. package/dist/prompt/coding-agent-doctrine.d.ts +63 -0
  155. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -0
  156. package/dist/prompt/coding-agent-doctrine.js +100 -0
  157. package/dist/prompt/coding-agent-doctrine.js.map +1 -0
  158. package/dist/prompt/index.d.ts +2 -0
  159. package/dist/prompt/index.d.ts.map +1 -1
  160. package/dist/prompt/index.js +1 -0
  161. package/dist/prompt/index.js.map +1 -1
  162. package/dist/provider/errors.d.ts +1 -1
  163. package/dist/provider/errors.js +1 -1
  164. package/dist/provider/fallback.d.ts +2 -0
  165. package/dist/provider/fallback.d.ts.map +1 -1
  166. package/dist/provider/fallback.js +3 -1
  167. package/dist/provider/fallback.js.map +1 -1
  168. package/dist/provider/retry.d.ts +2 -0
  169. package/dist/provider/retry.d.ts.map +1 -1
  170. package/dist/provider/retry.js +3 -1
  171. package/dist/provider/retry.js.map +1 -1
  172. package/dist/provider/token-budget.d.ts +13 -0
  173. package/dist/provider/token-budget.d.ts.map +1 -0
  174. package/dist/provider/token-budget.js +102 -0
  175. package/dist/provider/token-budget.js.map +1 -0
  176. package/dist/public-runtime.d.ts +12 -12
  177. package/dist/public-runtime.d.ts.map +1 -1
  178. package/dist/public-runtime.js +14 -9
  179. package/dist/public-runtime.js.map +1 -1
  180. package/dist/public-tools.d.ts +2 -0
  181. package/dist/public-tools.d.ts.map +1 -1
  182. package/dist/public-tools.js +2 -0
  183. package/dist/public-tools.js.map +1 -1
  184. package/dist/public-types.d.ts +12 -2
  185. package/dist/public-types.d.ts.map +1 -1
  186. package/dist/registry/command/kernel-commands.d.ts.map +1 -1
  187. package/dist/registry/command/kernel-commands.js +18 -6
  188. package/dist/registry/command/kernel-commands.js.map +1 -1
  189. package/dist/registry/tool/execute.d.ts.map +1 -1
  190. package/dist/registry/tool/execute.js +4 -1
  191. package/dist/registry/tool/execute.js.map +1 -1
  192. package/dist/run/LimitChecker.js +1 -1
  193. package/dist/run/LimitChecker.js.map +1 -1
  194. package/dist/run/drain.js +1 -1
  195. package/dist/run/reporter.d.ts.map +1 -1
  196. package/dist/run/reporter.js +15 -0
  197. package/dist/run/reporter.js.map +1 -1
  198. package/dist/run/token-budget.d.ts +108 -0
  199. package/dist/run/token-budget.d.ts.map +1 -0
  200. package/dist/run/token-budget.js +591 -0
  201. package/dist/run/token-budget.js.map +1 -0
  202. package/dist/runtime/jobs/registry.d.ts +29 -0
  203. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  204. package/dist/runtime/jobs/registry.js +98 -18
  205. package/dist/runtime/jobs/registry.js.map +1 -1
  206. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  207. package/dist/runtime/query/checkpoint.js +10 -3
  208. package/dist/runtime/query/checkpoint.js.map +1 -1
  209. package/dist/runtime/query/context.d.ts +2 -26
  210. package/dist/runtime/query/context.d.ts.map +1 -1
  211. package/dist/runtime/query/context.js +1 -29
  212. package/dist/runtime/query/context.js.map +1 -1
  213. package/dist/runtime/query/executor.d.ts +12 -9
  214. package/dist/runtime/query/executor.d.ts.map +1 -1
  215. package/dist/runtime/query/executor.js +95 -46
  216. package/dist/runtime/query/executor.js.map +1 -1
  217. package/dist/runtime/query/guard.d.ts.map +1 -1
  218. package/dist/runtime/query/guard.js +8 -0
  219. package/dist/runtime/query/guard.js.map +1 -1
  220. package/dist/runtime/query/index.d.ts +35 -4
  221. package/dist/runtime/query/index.d.ts.map +1 -1
  222. package/dist/runtime/query/index.js +152 -52
  223. package/dist/runtime/query/index.js.map +1 -1
  224. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  225. package/dist/runtime/query/iteration/index.js +16 -5
  226. package/dist/runtime/query/iteration/index.js.map +1 -1
  227. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  228. package/dist/runtime/query/iteration/phases/compaction.js +98 -30
  229. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  230. package/dist/runtime/query/iteration/phases/context.d.ts +2 -0
  231. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  232. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  233. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  234. package/dist/runtime/query/iteration/phases/tool-review.js +29 -7
  235. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  236. package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -1
  237. package/dist/runtime/query/iteration/phases/working-memory.js +25 -15
  238. package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -1
  239. package/dist/runtime/query/plugin-hooks.d.ts +1 -1
  240. package/dist/runtime/query/plugin-hooks.d.ts.map +1 -1
  241. package/dist/runtime/query/plugin-hooks.js +20 -1
  242. package/dist/runtime/query/plugin-hooks.js.map +1 -1
  243. package/dist/runtime/query/repeat-call.d.ts +20 -2
  244. package/dist/runtime/query/repeat-call.d.ts.map +1 -1
  245. package/dist/runtime/query/repeat-call.js +35 -7
  246. package/dist/runtime/query/repeat-call.js.map +1 -1
  247. package/dist/runtime/query/result.d.ts.map +1 -1
  248. package/dist/runtime/query/result.js +9 -0
  249. package/dist/runtime/query/result.js.map +1 -1
  250. package/dist/runtime/query/review-policy.d.ts +142 -0
  251. package/dist/runtime/query/review-policy.d.ts.map +1 -0
  252. package/dist/runtime/query/review-policy.js +144 -0
  253. package/dist/runtime/query/review-policy.js.map +1 -0
  254. package/dist/runtime/query/run-state.d.ts.map +1 -1
  255. package/dist/runtime/query/run-state.js +4 -0
  256. package/dist/runtime/query/run-state.js.map +1 -1
  257. package/dist/runtime/query/steering.d.ts +4 -0
  258. package/dist/runtime/query/steering.d.ts.map +1 -1
  259. package/dist/runtime/query/steering.js +29 -0
  260. package/dist/runtime/query/steering.js.map +1 -1
  261. package/dist/runtime/query/token-budget.d.ts +7 -0
  262. package/dist/runtime/query/token-budget.d.ts.map +1 -0
  263. package/dist/runtime/query/token-budget.js +101 -0
  264. package/dist/runtime/query/token-budget.js.map +1 -0
  265. package/dist/runtime/query/tool-output-budget.d.ts +2 -0
  266. package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
  267. package/dist/runtime/query/tool-output-budget.js +29 -11
  268. package/dist/runtime/query/tool-output-budget.js.map +1 -1
  269. package/dist/runtime/query/tool-pause.d.ts.map +1 -1
  270. package/dist/runtime/query/tool-pause.js +4 -2
  271. package/dist/runtime/query/tool-pause.js.map +1 -1
  272. package/dist/runtime/query/tooling.d.ts +4 -0
  273. package/dist/runtime/query/tooling.d.ts.map +1 -1
  274. package/dist/runtime/query/tooling.js +4 -0
  275. package/dist/runtime/query/tooling.js.map +1 -1
  276. package/dist/sandbox/provider/local.d.ts +3 -1
  277. package/dist/sandbox/provider/local.d.ts.map +1 -1
  278. package/dist/sandbox/provider/local.js +112 -12
  279. package/dist/sandbox/provider/local.js.map +1 -1
  280. package/dist/scheduler/delegating.d.ts +1 -0
  281. package/dist/scheduler/delegating.d.ts.map +1 -1
  282. package/dist/scheduler/delegating.js +29 -12
  283. package/dist/scheduler/delegating.js.map +1 -1
  284. package/dist/scheduler/local.d.ts +1 -0
  285. package/dist/scheduler/local.d.ts.map +1 -1
  286. package/dist/scheduler/local.js +4 -7
  287. package/dist/scheduler/local.js.map +1 -1
  288. package/dist/session/index.d.ts +0 -1
  289. package/dist/session/index.d.ts.map +1 -1
  290. package/dist/session/index.js +0 -1
  291. package/dist/session/index.js.map +1 -1
  292. package/dist/session/workspace/path-builder.d.ts.map +1 -1
  293. package/dist/session/workspace/path-builder.js +5 -4
  294. package/dist/session/workspace/path-builder.js.map +1 -1
  295. package/dist/store/feedback/disk.d.ts.map +1 -1
  296. package/dist/store/feedback/disk.js +4 -6
  297. package/dist/store/feedback/disk.js.map +1 -1
  298. package/dist/store/index.d.ts +2 -0
  299. package/dist/store/index.d.ts.map +1 -1
  300. package/dist/store/index.js +1 -0
  301. package/dist/store/index.js.map +1 -1
  302. package/dist/store/memory/disk.d.ts.map +1 -1
  303. package/dist/store/memory/disk.js +3 -12
  304. package/dist/store/memory/disk.js.map +1 -1
  305. package/dist/store/run/checkpoint-disk.d.ts +3 -3
  306. package/dist/store/run/checkpoint-disk.d.ts.map +1 -1
  307. package/dist/store/run/checkpoint-disk.js +14 -26
  308. package/dist/store/run/checkpoint-disk.js.map +1 -1
  309. package/dist/store/run/claim-disk.js +1 -1
  310. package/dist/store/run/conformance.d.ts +1 -1
  311. package/dist/store/run/conformance.d.ts.map +1 -1
  312. package/dist/store/run/conformance.js +41 -33
  313. package/dist/store/run/conformance.js.map +1 -1
  314. package/dist/store/run/disk.d.ts.map +1 -1
  315. package/dist/store/run/disk.js +20 -4
  316. package/dist/store/run/disk.js.map +1 -1
  317. package/dist/store/run/token-budget-disk.d.ts +37 -0
  318. package/dist/store/run/token-budget-disk.d.ts.map +1 -0
  319. package/dist/store/run/token-budget-disk.js +208 -0
  320. package/dist/store/run/token-budget-disk.js.map +1 -0
  321. package/dist/store/session/disk.d.ts +4 -13
  322. package/dist/store/session/disk.d.ts.map +1 -1
  323. package/dist/store/session/disk.js +34 -31
  324. package/dist/store/session/disk.js.map +1 -1
  325. package/dist/store/session/memory.d.ts +2 -0
  326. package/dist/store/session/memory.d.ts.map +1 -1
  327. package/dist/store/session/memory.js +41 -2
  328. package/dist/store/session/memory.js.map +1 -1
  329. package/dist/store/task/disk.d.ts.map +1 -1
  330. package/dist/store/task/disk.js +7 -8
  331. package/dist/store/task/disk.js.map +1 -1
  332. package/dist/store/topic/memory.d.ts +2 -0
  333. package/dist/store/topic/memory.d.ts.map +1 -1
  334. package/dist/store/topic/memory.js +13 -1
  335. package/dist/store/topic/memory.js.map +1 -1
  336. package/dist/test-support/ids.d.ts +4 -19
  337. package/dist/test-support/ids.d.ts.map +1 -1
  338. package/dist/test-support/ids.js +51 -59
  339. package/dist/test-support/ids.js.map +1 -1
  340. package/dist/tools/advisory/index.d.ts.map +1 -1
  341. package/dist/tools/advisory/index.js +3 -1
  342. package/dist/tools/advisory/index.js.map +1 -1
  343. package/dist/tools/builtins/bash.d.ts +2 -0
  344. package/dist/tools/builtins/bash.d.ts.map +1 -1
  345. package/dist/tools/builtins/bash.js +9 -11
  346. package/dist/tools/builtins/bash.js.map +1 -1
  347. package/dist/tools/builtins/computer-use.d.ts +2 -2
  348. package/dist/tools/builtins/computer-use.d.ts.map +1 -1
  349. package/dist/tools/builtins/computer-use.js +4 -2
  350. package/dist/tools/builtins/computer-use.js.map +1 -1
  351. package/dist/tools/builtins/edit.js +2 -2
  352. package/dist/tools/builtins/edit.js.map +1 -1
  353. package/dist/tools/builtins/glob.js +3 -3
  354. package/dist/tools/builtins/glob.js.map +1 -1
  355. package/dist/tools/builtins/grep.js +2 -2
  356. package/dist/tools/builtins/grep.js.map +1 -1
  357. package/dist/tools/builtins/ls.js +2 -2
  358. package/dist/tools/builtins/ls.js.map +1 -1
  359. package/dist/tools/builtins/lsp.js +2 -2
  360. package/dist/tools/builtins/lsp.js.map +1 -1
  361. package/dist/tools/builtins/read-file.js +2 -2
  362. package/dist/tools/builtins/read-file.js.map +1 -1
  363. package/dist/tools/builtins/write-file.js +2 -2
  364. package/dist/tools/builtins/write-file.js.map +1 -1
  365. package/dist/tools/coordinator/ask-user-question.d.ts +33 -0
  366. package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -0
  367. package/dist/tools/coordinator/ask-user-question.js +237 -0
  368. package/dist/tools/coordinator/ask-user-question.js.map +1 -0
  369. package/dist/tools/coordinator/index.d.ts +1 -2
  370. package/dist/tools/coordinator/index.d.ts.map +1 -1
  371. package/dist/tools/coordinator/index.js +4 -220
  372. package/dist/tools/coordinator/index.js.map +1 -1
  373. package/dist/tools/memory/read.d.ts.map +1 -1
  374. package/dist/tools/memory/read.js +2 -4
  375. package/dist/tools/memory/read.js.map +1 -1
  376. package/dist/tools/paths.d.ts +13 -0
  377. package/dist/tools/paths.d.ts.map +1 -1
  378. package/dist/tools/paths.js +53 -0
  379. package/dist/tools/paths.js.map +1 -1
  380. package/dist/tools/roster.d.ts +27 -0
  381. package/dist/tools/roster.d.ts.map +1 -0
  382. package/dist/tools/roster.js +42 -0
  383. package/dist/tools/roster.js.map +1 -0
  384. package/dist/types/agent/base.d.ts +5 -0
  385. package/dist/types/agent/base.d.ts.map +1 -1
  386. package/dist/types/agent/pipeline.d.ts +3 -0
  387. package/dist/types/agent/pipeline.d.ts.map +1 -1
  388. package/dist/types/agent/router.d.ts +2 -3
  389. package/dist/types/agent/router.d.ts.map +1 -1
  390. package/dist/types/agent/scheduler.d.ts +3 -0
  391. package/dist/types/agent/scheduler.d.ts.map +1 -1
  392. package/dist/types/agent/task.d.ts +5 -16
  393. package/dist/types/agent/task.d.ts.map +1 -1
  394. package/dist/types/agent/task.js.map +1 -1
  395. package/dist/types/common/index.d.ts.map +1 -1
  396. package/dist/types/common/index.js +3 -0
  397. package/dist/types/common/index.js.map +1 -1
  398. package/dist/types/computer-use/index.d.ts +8 -0
  399. package/dist/types/computer-use/index.d.ts.map +1 -1
  400. package/dist/types/computer-use/index.js.map +1 -1
  401. package/dist/types/hitl/index.d.ts +5 -0
  402. package/dist/types/hitl/index.d.ts.map +1 -1
  403. package/dist/types/hitl/index.js.map +1 -1
  404. package/dist/types/ids/brand.d.ts +5 -47
  405. package/dist/types/ids/brand.d.ts.map +1 -1
  406. package/dist/types/ids/brand.js +2 -39
  407. package/dist/types/ids/brand.js.map +1 -1
  408. package/dist/types/ids/index.d.ts +59 -69
  409. package/dist/types/ids/index.d.ts.map +1 -1
  410. package/dist/types/ids/index.js +12 -10
  411. package/dist/types/ids/index.js.map +1 -1
  412. package/dist/types/permission/index.d.ts +9 -0
  413. package/dist/types/permission/index.d.ts.map +1 -1
  414. package/dist/types/permission/index.js +9 -1
  415. package/dist/types/permission/index.js.map +1 -1
  416. package/dist/types/plugin/index.d.ts +45 -4
  417. package/dist/types/plugin/index.d.ts.map +1 -1
  418. package/dist/types/plugin/index.js +7 -0
  419. package/dist/types/plugin/index.js.map +1 -1
  420. package/dist/types/run/config.d.ts +3 -0
  421. package/dist/types/run/config.d.ts.map +1 -1
  422. package/dist/types/run/emergency.d.ts +5 -0
  423. package/dist/types/run/emergency.d.ts.map +1 -1
  424. package/dist/types/run/emergency.js.map +1 -1
  425. package/dist/types/run/entity.d.ts +6 -2
  426. package/dist/types/run/entity.d.ts.map +1 -1
  427. package/dist/types/run/events.d.ts +35 -0
  428. package/dist/types/run/events.d.ts.map +1 -1
  429. package/dist/types/run/events.js.map +1 -1
  430. package/dist/types/run/index.d.ts +1 -0
  431. package/dist/types/run/index.d.ts.map +1 -1
  432. package/dist/types/run/index.js +1 -0
  433. package/dist/types/run/index.js.map +1 -1
  434. package/dist/types/run/state.d.ts +16 -15
  435. package/dist/types/run/state.d.ts.map +1 -1
  436. package/dist/types/run/state.js +41 -22
  437. package/dist/types/run/state.js.map +1 -1
  438. package/dist/types/run/stop-reason.d.ts +3 -14
  439. package/dist/types/run/stop-reason.d.ts.map +1 -1
  440. package/dist/types/run/token-budget-store.d.ts +29 -0
  441. package/dist/types/run/token-budget-store.d.ts.map +1 -0
  442. package/dist/types/run/token-budget-store.js +25 -0
  443. package/dist/types/run/token-budget-store.js.map +1 -0
  444. package/dist/types/sandbox/index.d.ts +27 -2
  445. package/dist/types/sandbox/index.d.ts.map +1 -1
  446. package/dist/types/sandbox/index.js.map +1 -1
  447. package/dist/types/session/store.d.ts +8 -0
  448. package/dist/types/session/store.d.ts.map +1 -1
  449. package/dist/types/tool/index.d.ts +15 -0
  450. package/dist/types/tool/index.d.ts.map +1 -1
  451. package/dist/types/tool/index.js.map +1 -1
  452. package/dist/utils/frontmatter.d.ts +1 -1
  453. package/dist/utils/frontmatter.js +1 -1
  454. package/dist/utils/id-format.d.ts +3 -0
  455. package/dist/utils/id-format.d.ts.map +1 -0
  456. package/dist/utils/id-format.js +9 -0
  457. package/dist/utils/id-format.js.map +1 -0
  458. package/dist/utils/id.d.ts +65 -32
  459. package/dist/utils/id.d.ts.map +1 -1
  460. package/dist/utils/id.js +168 -148
  461. package/dist/utils/id.js.map +1 -1
  462. package/dist/utils/log/exception.js +1 -1
  463. package/dist/utils/log/exception.js.map +1 -1
  464. package/dist/utils/log/index.d.ts.map +1 -1
  465. package/dist/utils/log/index.js +1 -2
  466. package/dist/utils/log/index.js.map +1 -1
  467. package/dist/utils/log/templates.d.ts.map +1 -1
  468. package/dist/utils/log/templates.js +0 -1
  469. package/dist/utils/log/templates.js.map +1 -1
  470. package/package.json +1 -1
  471. package/src/agents/AGENTS.md +1 -1
  472. package/src/agents/PipelineAgent.ts +129 -109
  473. package/src/agents/ReactiveAgent.ts +2 -0
  474. package/src/agents/RouterAgent.ts +120 -73
  475. package/src/agents/SupervisorAgent.ts +12 -4
  476. package/src/agents/budget.ts +42 -0
  477. package/src/agents/explore.ts +29 -0
  478. package/src/agents/file-definitions.ts +237 -0
  479. package/src/agents/index.ts +15 -0
  480. package/src/bridge/a2a/mapper.ts +6 -0
  481. package/src/bridge/sse/mapper.ts +22 -0
  482. package/src/bus/lock.ts +1 -10
  483. package/src/compaction/consolidation.ts +79 -0
  484. package/src/compaction/factory.ts +3 -0
  485. package/src/compaction/index.ts +34 -4
  486. package/src/compaction/manager.ts +39 -1
  487. package/src/compaction/plan.ts +52 -21
  488. package/src/compaction/salience/bm25.ts +72 -0
  489. package/src/compaction/salience/goal.ts +44 -0
  490. package/src/compaction/salience/index.ts +19 -0
  491. package/src/compaction/salience/minhash.ts +53 -0
  492. package/src/compaction/salience/score.ts +305 -0
  493. package/src/compaction/salience/tokenize.ts +89 -0
  494. package/src/compaction/salience/working-set.ts +187 -0
  495. package/src/compaction/serializer.ts +16 -0
  496. package/src/compaction/token-estimate.ts +57 -0
  497. package/src/compaction/tool-result-editing.ts +28 -26
  498. package/src/compaction/types.ts +24 -1
  499. package/src/compaction/wire.ts +5 -1
  500. package/src/config/runtime.ts +13 -1
  501. package/src/connector/builtins/http.ts +2 -8
  502. package/src/connector/builtins/webhook.ts +2 -2
  503. package/src/connector/mcp/adapter.ts +32 -0
  504. package/src/connector/tools/adapter.ts +2 -2
  505. package/src/connector/tools/definitions.ts +2 -2
  506. package/src/constants/compaction/index.ts +1 -0
  507. package/src/constants/telemetry/index.ts +0 -1
  508. package/src/contracts/api.ts +5 -1
  509. package/src/contracts/schemas.ts +6 -20
  510. package/src/invariants/index.ts +1 -1
  511. package/src/manager/agent/lifecycle.ts +380 -352
  512. package/src/manager/run/persistence.ts +35 -5
  513. package/src/plugin/index.ts +19 -0
  514. package/src/plugin/shell-hook.ts +403 -0
  515. package/src/prompt/coding-agent-doctrine.ts +118 -0
  516. package/src/prompt/index.ts +8 -0
  517. package/src/provider/errors.ts +1 -1
  518. package/src/provider/fallback.ts +4 -1
  519. package/src/provider/retry.ts +4 -1
  520. package/src/provider/token-budget.ts +114 -0
  521. package/src/public-runtime.ts +54 -27
  522. package/src/public-tools.ts +5 -0
  523. package/src/public-types.ts +65 -0
  524. package/src/registry/command/kernel-commands.ts +16 -6
  525. package/src/registry/tool/execute.ts +4 -1
  526. package/src/run/LimitChecker.ts +1 -1
  527. package/src/run/drain.ts +1 -1
  528. package/src/run/reporter.ts +15 -0
  529. package/src/run/token-budget.ts +692 -0
  530. package/src/runtime/jobs/registry.ts +123 -17
  531. package/src/runtime/query/checkpoint.ts +10 -3
  532. package/src/runtime/query/context.ts +3 -57
  533. package/src/runtime/query/executor.ts +128 -58
  534. package/src/runtime/query/guard.ts +8 -0
  535. package/src/runtime/query/index.ts +201 -62
  536. package/src/runtime/query/iteration/index.ts +24 -6
  537. package/src/runtime/query/iteration/phases/compaction.ts +130 -31
  538. package/src/runtime/query/iteration/phases/context.ts +2 -0
  539. package/src/runtime/query/iteration/phases/tool-review.ts +39 -7
  540. package/src/runtime/query/iteration/phases/working-memory.ts +23 -14
  541. package/src/runtime/query/plugin-hooks.ts +24 -2
  542. package/src/runtime/query/repeat-call.ts +42 -7
  543. package/src/runtime/query/result.ts +9 -0
  544. package/src/runtime/query/review-policy.ts +231 -0
  545. package/src/runtime/query/run-state.ts +4 -0
  546. package/src/runtime/query/steering.ts +32 -0
  547. package/src/runtime/query/token-budget.ts +127 -0
  548. package/src/runtime/query/tool-output-budget.ts +33 -10
  549. package/src/runtime/query/tool-pause.ts +4 -2
  550. package/src/runtime/query/tooling.ts +8 -0
  551. package/src/sandbox/provider/local.ts +123 -13
  552. package/src/scheduler/delegating.ts +35 -13
  553. package/src/scheduler/local.ts +5 -7
  554. package/src/session/index.ts +0 -1
  555. package/src/session/workspace/path-builder.ts +5 -4
  556. package/src/store/feedback/disk.ts +4 -6
  557. package/src/store/index.ts +2 -0
  558. package/src/store/memory/disk.ts +3 -11
  559. package/src/store/run/checkpoint-disk.ts +14 -27
  560. package/src/store/run/claim-disk.ts +1 -1
  561. package/src/store/run/conformance.ts +55 -39
  562. package/src/store/run/disk.ts +19 -4
  563. package/src/store/run/token-budget-disk.ts +247 -0
  564. package/src/store/session/disk.ts +36 -29
  565. package/src/store/session/memory.ts +38 -1
  566. package/src/store/task/disk.ts +7 -8
  567. package/src/store/topic/memory.ts +13 -1
  568. package/src/test-support/ids.ts +62 -59
  569. package/src/tools/advisory/index.ts +3 -1
  570. package/src/tools/builtins/bash.ts +11 -12
  571. package/src/tools/builtins/computer-use.ts +6 -2
  572. package/src/tools/builtins/edit.ts +2 -2
  573. package/src/tools/builtins/glob.ts +3 -3
  574. package/src/tools/builtins/grep.ts +2 -2
  575. package/src/tools/builtins/ls.ts +2 -2
  576. package/src/tools/builtins/lsp.ts +2 -2
  577. package/src/tools/builtins/read-file.ts +2 -2
  578. package/src/tools/builtins/write-file.ts +2 -2
  579. package/src/tools/coordinator/ask-user-question.ts +284 -0
  580. package/src/tools/coordinator/index.ts +5 -248
  581. package/src/tools/memory/read.ts +2 -4
  582. package/src/tools/paths.ts +64 -0
  583. package/src/tools/roster.ts +46 -0
  584. package/src/types/agent/base.ts +6 -0
  585. package/src/types/agent/pipeline.ts +3 -0
  586. package/src/types/agent/router.ts +2 -3
  587. package/src/types/agent/scheduler.ts +4 -0
  588. package/src/types/agent/task.ts +5 -18
  589. package/src/types/common/index.ts +3 -0
  590. package/src/types/computer-use/index.ts +8 -0
  591. package/src/types/hitl/index.ts +5 -0
  592. package/src/types/ids/brand.ts +5 -48
  593. package/src/types/ids/index.ts +66 -75
  594. package/src/types/permission/index.ts +11 -0
  595. package/src/types/plugin/index.ts +49 -1
  596. package/src/types/run/config.ts +3 -0
  597. package/src/types/run/emergency.ts +5 -0
  598. package/src/types/run/entity.ts +6 -2
  599. package/src/types/run/events.ts +37 -0
  600. package/src/types/run/index.ts +1 -0
  601. package/src/types/run/state.ts +58 -30
  602. package/src/types/run/stop-reason.ts +3 -14
  603. package/src/types/run/token-budget-store.ts +54 -0
  604. package/src/types/sandbox/index.ts +32 -0
  605. package/src/types/session/store.ts +8 -0
  606. package/src/types/tool/index.ts +15 -0
  607. package/src/utils/frontmatter.ts +1 -1
  608. package/src/utils/id-format.ts +9 -0
  609. package/src/utils/id.ts +222 -181
  610. package/src/utils/log/exception.ts +1 -1
  611. package/src/utils/log/index.ts +1 -2
  612. package/src/utils/log/templates.ts +0 -1
  613. package/dist/session/migration/errors.d.ts +0 -26
  614. package/dist/session/migration/errors.d.ts.map +0 -1
  615. package/dist/session/migration/errors.js +0 -22
  616. package/dist/session/migration/errors.js.map +0 -1
  617. package/dist/session/migration/filesystem.d.ts +0 -122
  618. package/dist/session/migration/filesystem.d.ts.map +0 -1
  619. package/dist/session/migration/filesystem.js +0 -379
  620. package/dist/session/migration/filesystem.js.map +0 -1
  621. package/dist/session/migration/id-prefix.d.ts +0 -113
  622. package/dist/session/migration/id-prefix.d.ts.map +0 -1
  623. package/dist/session/migration/id-prefix.js +0 -132
  624. package/dist/session/migration/id-prefix.js.map +0 -1
  625. package/dist/session/migration/index.d.ts +0 -12
  626. package/dist/session/migration/index.d.ts.map +0 -1
  627. package/dist/session/migration/index.js +0 -12
  628. package/dist/session/migration/index.js.map +0 -1
  629. package/dist/session/migration/marker.d.ts +0 -57
  630. package/dist/session/migration/marker.d.ts.map +0 -1
  631. package/dist/session/migration/marker.js +0 -123
  632. package/dist/session/migration/marker.js.map +0 -1
  633. package/src/session/migration/errors.ts +0 -23
  634. package/src/session/migration/filesystem.ts +0 -468
  635. package/src/session/migration/id-prefix.ts +0 -166
  636. package/src/session/migration/index.ts +0 -41
  637. package/src/session/migration/marker.ts +0 -142
@@ -57,11 +57,25 @@ export interface BackgroundJobOutput {
57
57
  readonly exitCode?: number
58
58
  }
59
59
 
60
+ /** A job's process, when something other than the registry starts it. */
61
+ export interface JobProcess {
62
+ readonly child: ReturnType<typeof spawn>
63
+ /** How to stop it, when the registry's process-group kill would not reach everything. */
64
+ kill?(signal: NodeJS.Signals): void
65
+ }
66
+
60
67
  export interface StartJobParams {
61
68
  readonly owner: string
62
69
  readonly command: string
63
70
  readonly workingDirectory: string
64
71
  readonly env?: Readonly<Record<string, string>>
72
+ /**
73
+ * Start the process yourself — a sandbox does, so the job runs inside
74
+ * its boundary. Absent, the registry runs `/bin/sh -c command` on the
75
+ * host. The process must be the leader of its own group and must not
76
+ * expect stdin.
77
+ */
78
+ readonly spawn?: () => JobProcess
65
79
  }
66
80
 
67
81
  export interface BackgroundJobRegistryConfig {
@@ -106,6 +120,8 @@ export class UnknownBackgroundJobError extends Error {
106
120
  interface JobEntry {
107
121
  record: BackgroundJob
108
122
  child: ReturnType<typeof spawn>
123
+ /** The spawner's own kill, when it gave one. */
124
+ killProcess?: (signal: NodeJS.Signals) => void
109
125
  /** Retained tail. */
110
126
  buffer: string
111
127
  /** Bytes produced in total, including the ones the cap dropped. */
@@ -113,9 +129,46 @@ interface JobEntry {
113
129
  exit: Promise<void>
114
130
  }
115
131
 
132
+ /** Whether any process of the group led by `pid` is still alive. */
133
+ function groupAlive(pid: number | undefined): boolean {
134
+ if (pid === undefined || process.platform === 'win32') return false
135
+ try {
136
+ process.kill(-pid, 0)
137
+ return true
138
+ } catch {
139
+ return false
140
+ }
141
+ }
142
+
143
+ const GROUP_POLL_MS = 250
144
+
116
145
  export class BackgroundJobRegistry {
117
146
  private readonly jobs = new Map<string, JobEntry>()
118
147
  private counter = 0
148
+ private readonly exitListeners = new Set<(job: BackgroundJob) => void>()
149
+
150
+ /**
151
+ * Be told when a job ends, whoever owns it. A job outlives the call that
152
+ * started it, so the one thing the model could not do was learn that it
153
+ * had finished without polling; a run subscribes here and turns the exit
154
+ * into a notice on its next tool result. Returns the unsubscribe.
155
+ */
156
+ onExit(listener: (job: BackgroundJob) => void): () => void {
157
+ this.exitListeners.add(listener)
158
+ return () => {
159
+ this.exitListeners.delete(listener)
160
+ }
161
+ }
162
+
163
+ private announceExit(job: BackgroundJob): void {
164
+ for (const listener of this.exitListeners) {
165
+ try {
166
+ listener(job)
167
+ } catch {
168
+ // A listener that throws is its owner's problem, not the job's.
169
+ }
170
+ }
171
+ }
119
172
 
120
173
  constructor(private readonly config: BackgroundJobRegistryConfig = {}) {}
121
174
 
@@ -151,15 +204,20 @@ export class BackgroundJobRegistry {
151
204
  // started it, which makes the leak longer-lived, not smaller.
152
205
  const inherited = scrubInheritedEnv()
153
206
 
154
- const child = spawn('/bin/sh', ['-c', params.command], {
155
- cwd: params.workingDirectory,
156
- env: { ...inherited.env, ...params.env },
157
- // Leader of its own process group, which is what `killTree` needs
158
- // to reach the command and everything it forks rather than only the
159
- // wrapping shell. See `process/kill-tree.ts`.
160
- detached: process.platform !== 'win32',
161
- stdio: ['ignore', 'pipe', 'pipe'],
162
- })
207
+ const started = params.spawn
208
+ ? params.spawn()
209
+ : {
210
+ child: spawn('/bin/sh', ['-c', params.command], {
211
+ cwd: params.workingDirectory,
212
+ env: { ...inherited.env, ...params.env },
213
+ // Leader of its own process group, which is what `killTree` needs
214
+ // to reach the command and everything it forks rather than only the
215
+ // wrapping shell. See `process/kill-tree.ts`.
216
+ detached: process.platform !== 'win32',
217
+ stdio: ['ignore', 'pipe', 'pipe'],
218
+ }),
219
+ }
220
+ const child = started.child
163
221
  // Started, not adopted: this process stays the parent for the job's
164
222
  // whole life. `unref` would let Node exit with the job still running,
165
223
  // which is the orphan this registry exists to prevent.
@@ -175,10 +233,11 @@ export class BackgroundJobRegistry {
175
233
  startedAt: Date.now(),
176
234
  },
177
235
  child,
236
+ ...(started.kill ? { killProcess: started.kill.bind(started) } : {}),
178
237
  buffer: '',
179
238
  produced: 0,
180
239
  exit: new Promise<void>((resolve) => {
181
- child.once('close', (code, signal) => {
240
+ const finalize = (code: number | null, signal: NodeJS.Signals | null): void => {
182
241
  entry.record = {
183
242
  ...entry.record,
184
243
  // A job killed by this registry says `killed`, not
@@ -190,10 +249,33 @@ export class BackgroundJobRegistry {
190
249
  ...(signal ? { signal } : {}),
191
250
  }
192
251
  resolve()
252
+ this.announceExit(entry.record)
253
+ }
254
+ child.once('close', (code, signal) => {
255
+ // The job is the process GROUP, not the shell. A command that
256
+ // backgrounds its real work (`server &`) exits the shell at
257
+ // once and leaves the server as the group's survivor; calling
258
+ // that "exited" told the model the job was over while the
259
+ // port was still held, and nothing stopped the survivor at
260
+ // session end because the job was no longer running. So a
261
+ // job whose shell has ended stays running while its group is
262
+ // alive, and ends — with the shell's exit code — when the
263
+ // group is empty.
264
+ if (entry.record.status !== 'killed' && groupAlive(child.pid)) {
265
+ const poll = setInterval(() => {
266
+ if (groupAlive(child.pid)) return
267
+ clearInterval(poll)
268
+ finalize(code, signal)
269
+ }, GROUP_POLL_MS)
270
+ poll.unref()
271
+ return
272
+ }
273
+ finalize(code, signal)
193
274
  })
194
275
  child.once('error', () => {
195
276
  entry.record = { ...entry.record, status: 'exited', exitedAt: Date.now() }
196
277
  resolve()
278
+ this.announceExit(entry.record)
197
279
  })
198
280
  }),
199
281
  }
@@ -266,8 +348,10 @@ export class BackgroundJobRegistry {
266
348
  // tell a kill from an ordinary exit. Set it after and the race decides
267
349
  // which of two different answers a reader gets.
268
350
  entry.record = { ...entry.record, status: 'killed' }
269
- killTree(entry.child, 'SIGTERM')
270
- const grace = setTimeout(() => killTree(entry.child, 'SIGKILL'), SANDBOX_KILL_GRACE_MS)
351
+ const signal = (sig: NodeJS.Signals) =>
352
+ entry.killProcess ? entry.killProcess(sig) : killTree(entry.child, sig)
353
+ signal('SIGTERM')
354
+ const grace = setTimeout(() => signal('SIGKILL'), SANDBOX_KILL_GRACE_MS)
271
355
  // Unreffed: a job that exits on SIGTERM must not hold the process open
272
356
  // for the remaining grace period doing nothing.
273
357
  grace.unref?.()
@@ -317,7 +401,16 @@ export class BackgroundJobRegistry {
317
401
  export function bindOwner(
318
402
  registry: BackgroundJobRegistry,
319
403
  owner: string,
320
- defaults: { readonly workingDirectory?: string; readonly env?: Record<string, string> } = {},
404
+ defaults: {
405
+ readonly workingDirectory?: string
406
+ readonly env?: Record<string, string>
407
+ /** See `StartJobParams.spawn`; given the resolved command, directory and env. */
408
+ readonly spawn?: (params: {
409
+ readonly command: string
410
+ readonly workingDirectory: string
411
+ readonly env?: Record<string, string>
412
+ }) => JobProcess
413
+ } = {},
321
414
  ) {
322
415
  const mine = (id: string): BackgroundJob => {
323
416
  const job = registry.get(id)
@@ -325,13 +418,26 @@ export function bindOwner(
325
418
  return job
326
419
  }
327
420
  return {
328
- start: (params: { command: string; workingDirectory?: string }) =>
329
- registry.start({
421
+ start: (params: { command: string; workingDirectory?: string }) => {
422
+ const workingDirectory = params.workingDirectory ?? defaults.workingDirectory ?? process.cwd()
423
+ const spawnHost = defaults.spawn
424
+ return registry.start({
330
425
  owner,
331
426
  command: params.command,
332
- workingDirectory: params.workingDirectory ?? defaults.workingDirectory ?? process.cwd(),
427
+ workingDirectory,
333
428
  ...(defaults.env ? { env: defaults.env } : {}),
334
- }),
429
+ ...(spawnHost
430
+ ? {
431
+ spawn: () =>
432
+ spawnHost({
433
+ command: params.command,
434
+ workingDirectory,
435
+ ...(defaults.env ? { env: defaults.env } : {}),
436
+ }),
437
+ }
438
+ : {}),
439
+ })
440
+ },
335
441
  get: (id: string) => mine(id),
336
442
  read: (id: string, opts?: { fromOffset?: number }) => {
337
443
  mine(id)
@@ -20,7 +20,7 @@ import type { EmergencySaveData } from '../../types/run/emergency.js'
20
20
  import type { CheckpointListEntry } from '../../types/run/replay.js'
21
21
  import { ZERO_COST } from '../../utils/cost.js'
22
22
  import { buildToolResultHashes } from '../../utils/hash.js'
23
- import { asCheckpointId, generateCheckpointId } from '../../utils/id.js'
23
+ import { asCheckpointId, asEmergencySaveId, generateCheckpointId } from '../../utils/id.js'
24
24
 
25
25
  /**
26
26
  * Projection from a full checkpoint payload to the public listing entry.
@@ -72,9 +72,11 @@ export function toCheckpointListEntry(cp: IterationCheckpoint): CheckpointListEn
72
72
  * See ses_005-deterministic-replay design §2 + §5.2.
73
73
  */
74
74
  export function projectEmergencyToCheckpoint(dump: EmergencySaveData): IterationCheckpoint {
75
- const emergencySuffix = dump.id.replace(/^esave_/, '')
75
+ const emergencyId = asEmergencySaveId(dump.id)
76
+ // The checkpoint is another view of the same snapshot and retains its key.
77
+ const checkpointId = asCheckpointId(emergencyId)
76
78
  return {
77
- id: asCheckpointId(`cp_emergency_${emergencySuffix}`),
79
+ id: checkpointId,
78
80
  runId: dump.runId,
79
81
  // The dump records the run's start, so this projection carries the
80
82
  // same stamp an ordinary checkpoint of that run would — a run whose
@@ -85,6 +87,8 @@ export function projectEmergencyToCheckpoint(dump: EmergencySaveData): Iteration
85
87
  iteration: dump.currentIteration,
86
88
  messages: dump.messages,
87
89
  tokenUsage: dump.tokenUsage,
90
+ budgetBinding: dump.budgetBinding,
91
+ budgetAccountId: dump.budgetAccountId,
88
92
  costInfo: { ...ZERO_COST, unpricedTokens: dump.tokenUsage.totalTokens },
89
93
  guardState: {
90
94
  iterationCount: dump.currentIteration,
@@ -264,6 +268,8 @@ export class CheckpointManager {
264
268
  iteration,
265
269
  messages: [...runMgr.messages],
266
270
  tokenUsage: { ...runMgr.tokenUsage },
271
+ budgetBinding: runMgr.budget?.binding,
272
+ budgetAccountId: runMgr.budget?.accountId,
267
273
  costInfo: { ...runMgr.costInfo },
268
274
  guardState: {
269
275
  iterationCount: runMgr.currentIteration,
@@ -275,6 +281,7 @@ export class CheckpointManager {
275
281
  traceContext: this.traceSource?.(),
276
282
  }
277
283
 
284
+ await runMgr.budget?.flush()
278
285
  await this.store.writeCheckpoint(this.scope, checkpoint, this.claimFence)
279
286
  this.lastCreatedId = checkpoint.id
280
287
  return checkpoint
@@ -2,12 +2,7 @@ import { join } from 'node:path'
2
2
  import { GENAI, NAMZU } from '../../constants/telemetry/index.js'
3
3
  import { PlanManager } from '../../manager/plan/lifecycle.js'
4
4
  import { RunPersistence } from '../../manager/run/persistence.js'
5
- import {
6
- DefaultFilesystemMigrator,
7
- type FilesystemMigrationResult,
8
- type FilesystemMigrator,
9
- NOOP_FILESYSTEM_MIGRATION_SINK,
10
- } from '../../session/migration/index.js'
5
+ import type { TokenBudget } from '../../run/token-budget.js'
11
6
  import { DefaultPathBuilder, type PathBuilder } from '../../session/workspace/path-builder.js'
12
7
  import { ActivityStore } from '../../store/activity/memory.js'
13
8
  import { type ActivityTrackingConfig, resolveActivityTracking } from '../../types/activity/index.js'
@@ -33,20 +28,9 @@ import { type Logger, resolveLogger } from '../../utils/logger.js'
33
28
  * `pathBuilder` is optional; when absent a {@link DefaultPathBuilder} is
34
29
  * constructed against `{workingDirectory}/.namzu`.
35
30
  *
36
- * `filesystemMigrator` is optional, but note what `build` actually does
37
- * with it: nothing. Migration is not part of `build` — it runs once per
38
- * process via {@link RunContextFactory.ensureMigrated}, kept out of `build`
39
- * entirely so the static method stays synchronous for existing callers;
40
- * `query()` calls `ensureMigrated` itself, with its own migrator, before it
41
- * ever calls `build`. This field predates that split, and no code path
42
- * threads it to `ensureMigrated` on `build`'s behalf. Its sibling
43
- * `migrationSink` had the identical shape — declared, never read anywhere
44
- * in the workspace — and NZ-BOOT-04 removed it
45
- * (`docs/conventions/declared-but-undriven.md`) rather than invent a caller
46
- * for a field nothing needed; `filesystemMigrator` is the same defect, left
47
- * for a follow-up rather than folded into that change.
48
31
  */
49
32
  export interface RunContextConfig {
33
+ budget?: TokenBudget
50
34
  /**
51
35
  * The mode this conversation was left in, when the run config names none.
52
36
  *
@@ -93,13 +77,6 @@ export interface RunContextConfig {
93
77
  checkpointStore?: CheckpointStore
94
78
  runStore?: RunStore
95
79
 
96
- /**
97
- * Optional injected migrator — tests pass a stub; production code relies
98
- * on the {@link DefaultFilesystemMigrator}. See session-hierarchy.md
99
- * §13.4.1.
100
- */
101
- filesystemMigrator?: FilesystemMigrator
102
-
103
80
  runId?: RunId
104
81
 
105
82
  parentRunId?: RunId
@@ -138,39 +115,7 @@ export interface RunContext {
138
115
  trackingConfig: ActivityTrackingConfig
139
116
  }
140
117
 
141
- /**
142
- * Module-level first-call guard for the boot-time filesystem migration
143
- * (session-hierarchy.md §13.4.1). Keyed on the root directory so a single
144
- * process that spans multiple `.namzu` roots (unusual but legal) migrates
145
- * each one once. Subsequent calls short-circuit via the cached promise —
146
- * never re-reading the on-disk marker per call.
147
- */
148
- const migrationPromises = new Map<string, Promise<FilesystemMigrationResult>>()
149
-
150
118
  export class RunContextFactory {
151
- /**
152
- * Run the boot-time filesystem migration for `rootDir` at most once per
153
- * process. Safe to `await` from any async entry point; concurrent callers
154
- * for the same root share a single migration promise (no duplicate work,
155
- * no race with the on-disk `.tmp` lock).
156
- */
157
- static ensureMigrated(
158
- rootDir: string,
159
- migrator: FilesystemMigrator = new DefaultFilesystemMigrator(NOOP_FILESYSTEM_MIGRATION_SINK),
160
- ): Promise<FilesystemMigrationResult> {
161
- const cached = migrationPromises.get(rootDir)
162
- if (cached) return cached
163
- const promise = migrator.migrate(rootDir)
164
- migrationPromises.set(rootDir, promise)
165
- // Crash-safety: if the migration rejects, drop the cached promise so
166
- // the next caller gets a fresh attempt. Successful results stay cached
167
- // (idempotency — further calls short-circuit without re-running).
168
- promise.catch(() => {
169
- migrationPromises.delete(rootDir)
170
- })
171
- return promise
172
- }
173
-
174
119
  /**
175
120
  * The run's one correlated logger, built once and handed to every
176
121
  * consumer that used to construct its own. Split out of `build` because
@@ -271,6 +216,7 @@ export class RunContextFactory {
271
216
 
272
217
  const runMgr = new RunPersistence({
273
218
  runId,
219
+ budget: config.budget,
274
220
  agentId: config.agentId,
275
221
  agentName: config.agentName,
276
222
  runConfig: config.runConfig,
@@ -1,3 +1,4 @@
1
+ import { join } from 'node:path'
1
2
  import type { Span } from '@opentelemetry/api'
2
3
  import type { AuthorizationGate } from '../../authorization/gate.js'
3
4
  import { extractFromToolCall, extractFromToolResult } from '../../compaction/extractor.js'
@@ -47,10 +48,11 @@ import { toErrorMessage } from '../../utils/error.js'
47
48
  import { generateToolCallId } from '../../utils/id.js'
48
49
  import type { Logger } from '../../utils/logger.js'
49
50
  import { compressShellOutput } from '../../utils/shell-compress.js'
50
- import { type BackgroundJobRegistry, bindOwner } from '../jobs/registry.js'
51
+ import { type BackgroundJobRegistry, type JobProcess, bindOwner } from '../jobs/registry.js'
51
52
  import type { ToolResultObservation } from './project-instructions.js'
52
53
  import {
53
54
  DEFAULT_MAX_TOOL_OUTPUT_CHARS,
55
+ type ToolOutputBudgetResult,
54
56
  applyToolOutputBudget,
55
57
  describeDroppedContent,
56
58
  measureContentBytes,
@@ -290,6 +292,8 @@ export interface ToolExecutorConfig {
290
292
  tools: ToolRegistryContract
291
293
  runId: RunId
292
294
  workingDirectory: string
295
+ /** See `ToolContext.additionalDirectories`. */
296
+ additionalDirectories?: readonly string[]
293
297
  /**
294
298
  * Read LIVE, not frozen at run start.
295
299
  *
@@ -319,6 +323,13 @@ export interface ToolExecutorConfig {
319
323
  * that fallback is a lie rather than a lesser version.
320
324
  */
321
325
  backgroundJobs?: BackgroundJobRegistry
326
+ /**
327
+ * Which owner the run's jobs are bound to. The run id by default, which
328
+ * scopes them to the run; a host that wants jobs to outlive a turn (a
329
+ * dev server started in one, read in the next) binds them to its
330
+ * session and stops them itself when the session ends.
331
+ */
332
+ backgroundJobOwner?: string
322
333
 
323
334
  /**
324
335
  * Where the `skill` tool reads from.
@@ -1175,6 +1186,9 @@ export class ToolExecutor {
1175
1186
  const context: ToolContext = {
1176
1187
  runId: this.config.runId,
1177
1188
  workingDirectory: this.config.workingDirectory,
1189
+ ...(this.config.additionalDirectories?.length
1190
+ ? { additionalDirectories: this.config.additionalDirectories }
1191
+ : {}),
1178
1192
  abortSignal: this.config.abortSignal,
1179
1193
  env: this.config.env,
1180
1194
  log: (level, message) => this.log[level](message),
@@ -1219,12 +1233,38 @@ export class ToolExecutor {
1219
1233
  // that its foreground work would use. A sandbox-aware persistent
1220
1234
  // process capability needs its own execution seam; until one exists,
1221
1235
  // the safe composition is to withhold this host capability entirely.
1222
- ...(this.config.backgroundJobs && !this.config.sandbox
1236
+ //
1237
+ // That seam now exists: a sandbox that can `spawnDetached` starts
1238
+ // the job inside its boundary, and the registry only keeps it. A
1239
+ // sandbox without it still withholds the capability.
1240
+ ...(this.config.backgroundJobs &&
1241
+ (!this.config.sandbox || this.config.sandbox.spawnDetached !== undefined)
1223
1242
  ? {
1224
- backgroundJobs: bindOwner(this.config.backgroundJobs, this.config.runId, {
1225
- workingDirectory: this.config.workingDirectory,
1226
- env: this.config.env,
1227
- }),
1243
+ backgroundJobs: bindOwner(
1244
+ this.config.backgroundJobs,
1245
+ this.config.backgroundJobOwner ?? this.config.runId,
1246
+ {
1247
+ workingDirectory: this.config.workingDirectory,
1248
+ env: this.config.env,
1249
+ ...(this.config.sandbox?.spawnDetached
1250
+ ? {
1251
+ spawn: (job: {
1252
+ readonly command: string
1253
+ readonly workingDirectory: string
1254
+ readonly env?: Record<string, string>
1255
+ }): JobProcess =>
1256
+ (this.config.sandbox as Sandbox).spawnDetached?.(
1257
+ '/bin/sh',
1258
+ ['-c', job.command],
1259
+ {
1260
+ cwd: job.workingDirectory,
1261
+ ...(job.env ? { env: job.env } : {}),
1262
+ },
1263
+ ) as JobProcess,
1264
+ }
1265
+ : {}),
1266
+ },
1267
+ ),
1228
1268
  }
1229
1269
  : {}),
1230
1270
  ...(this.parentSpan ? { parentSpan: this.parentSpan } : {}),
@@ -1510,23 +1550,23 @@ export class ToolExecutor {
1510
1550
  const postOverride = post.override
1511
1551
  let output =
1512
1552
  postOverride?.output ?? (result.success ? this.maybeCompress(toolName, rawOutput) : rawOutput)
1513
- const selectedContent = postOverride?.isError
1553
+ let selectedContent = postOverride?.isError
1514
1554
  ? undefined
1515
1555
  : (postOverride?.content ?? result.content)
1516
- const maxToolOutputChars = this.config.maxToolOutputChars ?? DEFAULT_MAX_TOOL_OUTPUT_CHARS
1517
-
1518
- // If the text preview forces rich content out, say so inside the SAME
1519
- // budget. Appending this after truncation made the diagnostic itself a
1520
- // cap bypass; selecting a post-hook override after truncation was a
1521
- // larger bypass that could replace a bounded result with anything.
1522
- if (
1523
- maxToolOutputChars > 0 &&
1524
- output.length > maxToolOutputChars &&
1525
- selectedContent !== undefined
1526
- ) {
1527
- const dropped = describeDroppedContent(selectedContent)
1528
- if (dropped) output = `${output}\n\n${dropped}`
1556
+ if (postOverride && !postOverride.isError && postOverride.content === undefined) {
1557
+ // A text redaction must reach both text channels. Only the image or
1558
+ // document blocks survive implicitly; explicit replacement content
1559
+ // remains the hook's complete model-visible decision.
1560
+ if (typeof selectedContent === 'string') selectedContent = postOverride.output
1561
+ else if (selectedContent) {
1562
+ selectedContent = [
1563
+ { type: 'text', text: postOverride.output },
1564
+ ...selectedContent.filter((block) => block.type !== 'text'),
1565
+ ]
1566
+ }
1529
1567
  }
1568
+ const maxToolOutputChars = this.config.maxToolOutputChars ?? DEFAULT_MAX_TOOL_OUTPUT_CHARS
1569
+ const sourceOutput = output
1530
1570
 
1531
1571
  // Compression is opportunistic and shell-only; the budget is the
1532
1572
  // hard bound that applies to every final tool result, including a
@@ -1553,6 +1593,10 @@ export class ToolExecutor {
1553
1593
  })
1554
1594
  }
1555
1595
  output = budgeted.output
1596
+ const modelContent =
1597
+ selectedContent === undefined
1598
+ ? undefined
1599
+ : this.budgetContent(selectedContent, toolName, toolCall.id, { sourceOutput, budgeted })
1556
1600
 
1557
1601
  // A failed call, or an override that says the call failed. A `replace`
1558
1602
  // says the opposite, and reading it as a failure is what made redaction
@@ -1562,6 +1606,9 @@ export class ToolExecutor {
1562
1606
 
1563
1607
  if (this.workingStateManager) {
1564
1608
  extractFromToolResult(this.workingStateManager, toolName, output, effectiveIsError)
1609
+ for (const pin of result.workingState ?? []) {
1610
+ this.workingStateManager.pin(pin.key, pin.text, toolName)
1611
+ }
1565
1612
  }
1566
1613
 
1567
1614
  if (result.success) {
@@ -1615,11 +1662,6 @@ export class ToolExecutor {
1615
1662
  result,
1616
1663
  })
1617
1664
 
1618
- const resolveContent = (): { content?: ToolResultContent } => {
1619
- if (budgeted.truncated || selectedContent === undefined) return {}
1620
- return { content: this.budgetContent(selectedContent, toolName) }
1621
- }
1622
-
1623
1665
  return {
1624
1666
  toolCallId: toolCall.id,
1625
1667
  toolName,
@@ -1629,13 +1671,12 @@ export class ToolExecutor {
1629
1671
  //
1630
1672
  // An ERROR override drops it: the payload is no longer the tool's,
1631
1673
  // and shipping an image beside a failure message describes something
1632
- // the model was just told did not happen. A spilled preview drops it
1633
- // for the same reason.
1674
+ // the model was just told did not happen.
1634
1675
  //
1635
1676
  // A REPLACE keeps it, because the common case is redacting text from
1636
1677
  // a result whose image is unaffected — and a hook that needs it gone
1637
1678
  // says so with `content`, which wins over both.
1638
- ...resolveContent(),
1679
+ ...(modelContent !== undefined ? { content: modelContent } : {}),
1639
1680
  }
1640
1681
  }
1641
1682
 
@@ -2108,6 +2149,7 @@ export class ToolExecutor {
2108
2149
  output: `Error: ${result.message}`,
2109
2150
  }
2110
2151
  case 'retry':
2152
+ case 'annotate':
2111
2153
  // There is no result to replace yet. Rejecting loudly beats
2112
2154
  // silently ignoring it: a hook author who returned this here
2113
2155
  // meant to redact something and would otherwise watch the secret
@@ -2368,6 +2410,7 @@ export class ToolExecutor {
2368
2410
  continue
2369
2411
  case 'skip':
2370
2412
  case 'modify':
2413
+ case 'annotate':
2371
2414
  throw new Error(
2372
2415
  `Plugin hook post_tool_use returned unsupported action '${result.action}' for tool ${toolName}`,
2373
2416
  )
@@ -2493,42 +2536,69 @@ export class ToolExecutor {
2493
2536
  }
2494
2537
 
2495
2538
  /**
2496
- * Bound the rich channel, or leave it alone when no cap is configured.
2497
- *
2498
- * Refused whole rather than trimmed: half a base64 payload is not a
2499
- * smaller image, it is a corrupt one, and a driver handed it would
2500
- * either fail the request or show the model noise. The text half stays
2501
- * untouched, so the result still says what happened — and the
2502
- * replacement names what was withheld and how big it was, which is what
2503
- * lets the agent ask for a smaller region instead of retrying the same
2504
- * call.
2539
+ * The host preview and model text may differ; each gets its own text
2540
+ * budget. Rich bytes are measured separately and withheld whole when
2541
+ * over their cap, with a notice inside the model text's same hard bound.
2505
2542
  */
2506
2543
  private budgetContent(
2507
- content: import('../../types/message/index.js').ToolResultContent,
2544
+ content: ToolResultContent,
2508
2545
  toolName: string,
2509
- ): import('../../types/message/index.js').ToolResultContent {
2546
+ toolUseId: string,
2547
+ host: { sourceOutput: string; budgeted: ToolOutputBudgetResult },
2548
+ ): ToolResultContent {
2510
2549
  const cap = this.config.maxToolContentBytes ?? 0
2511
- if (cap <= 0) return content
2512
-
2513
2550
  const size = measureContentBytes(content)
2514
- if (size <= cap) return content
2515
-
2516
- this.log.warn('Tool result content exceeded the rich-content budget', {
2517
- [NAMZU.RUN_ID]: this.config.runId,
2518
- [GENAI.TOOL_NAME]: toolName,
2519
- 'namzu.runtime.content_bytes': size,
2520
- 'namzu.runtime.cap': cap,
2521
- })
2522
-
2523
- const described = describeDroppedContent(content)
2551
+ const richWithheld = cap > 0 && size > cap
2552
+ const text =
2553
+ typeof content === 'string'
2554
+ ? content
2555
+ : content.flatMap((block) => (block.type === 'text' ? [block.text] : [])).join('\n')
2556
+ const notice = richWithheld
2557
+ ? `[rich content withheld: ${size} base64 chars exceeds this run's ${cap} cap] ${describeDroppedContent(content) ?? ''}`
2558
+ : undefined
2559
+ if (richWithheld) {
2560
+ this.log.warn('Tool result content exceeded the rich-content budget', {
2561
+ [NAMZU.RUN_ID]: this.config.runId,
2562
+ [GENAI.TOOL_NAME]: toolName,
2563
+ 'namzu.runtime.content_bytes': size,
2564
+ 'namzu.runtime.cap': cap,
2565
+ })
2566
+ }
2567
+ const budgeted =
2568
+ text === host.sourceOutput && !notice
2569
+ ? host.budgeted
2570
+ : applyToolOutputBudget({
2571
+ toolName,
2572
+ toolUseId,
2573
+ output: text,
2574
+ maxChars: this.config.maxToolOutputChars ?? DEFAULT_MAX_TOOL_OUTPUT_CHARS,
2575
+ ...(notice ? { notice } : {}),
2576
+ // A tool may return different host and model text. They must
2577
+ // never compete for the same exclusive spill filename.
2578
+ spillDir: this.config.toolOutputDir
2579
+ ? join(this.config.toolOutputDir, 'content')
2580
+ : undefined,
2581
+ onError: (message) =>
2582
+ this.log.warn('Failed to spill oversized model tool content', {
2583
+ [NAMZU.RUN_ID]: this.config.runId,
2584
+ [GENAI.TOOL_NAME]: toolName,
2585
+ 'exception.message': message,
2586
+ }),
2587
+ })
2588
+ if (budgeted.truncated && budgeted !== host.budgeted) {
2589
+ this.log.warn('Model tool text exceeded the model-visible budget', {
2590
+ [NAMZU.RUN_ID]: this.config.runId,
2591
+ [GENAI.TOOL_NAME]: toolName,
2592
+ 'namzu.runtime.original_length': budgeted.originalLength,
2593
+ 'namzu.runtime.spill_path': budgeted.spillPath,
2594
+ })
2595
+ }
2596
+ if (!budgeted.truncated && !richWithheld) return content
2597
+ if (typeof content === 'string') return budgeted.output
2524
2598
  return [
2525
- {
2526
- type: 'text',
2527
- text: `[rich content withheld: ${size} base64 chars exceeds this run's ${cap} cap${
2528
- described ? ` — ${described}` : ''
2529
- }]`,
2530
- },
2531
- ] as import('../../types/message/index.js').ToolResultContent
2599
+ ...(budgeted.output ? [{ type: 'text' as const, text: budgeted.output }] : []),
2600
+ ...(richWithheld ? [] : content.filter((block) => block.type !== 'text')),
2601
+ ]
2532
2602
  }
2533
2603
 
2534
2604
  private maybeCompress(toolName: string, output: string): string {
@@ -110,6 +110,14 @@ export class GuardCoordinator {
110
110
  }
111
111
 
112
112
  const limitResult = checkLimitsDetailed(this.limitConfig, limitState)
113
+ if (!abortSignal.aborted && runMgr.budget && runMgr.budget.remaining <= 0) {
114
+ return {
115
+ shouldStop: true,
116
+ forceFinalize: false,
117
+ stopReason: 'token_budget',
118
+ isCancelled: false,
119
+ }
120
+ }
113
121
 
114
122
  if (limitResult.type === 'hard_stop') {
115
123
  return {