@namzu/sdk 42.0.2 → 44.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 (2100) hide show
  1. package/CHANGELOG.md +540 -0
  2. package/README.md +41 -34
  3. package/dist/advisory/budget.js +3 -3
  4. package/dist/advisory/budget.js.map +1 -1
  5. package/dist/advisory/context.d.ts +5 -5
  6. package/dist/advisory/context.d.ts.map +1 -1
  7. package/dist/advisory/context.js +6 -6
  8. package/dist/advisory/context.js.map +1 -1
  9. package/dist/advisory/evaluator.js +2 -2
  10. package/dist/advisory/evaluator.js.map +1 -1
  11. package/dist/advisory/parse.d.ts +1 -1
  12. package/dist/advisory/parse.js +1 -1
  13. package/dist/agents/AbstractAgent.d.ts +47 -40
  14. package/dist/agents/AbstractAgent.d.ts.map +1 -1
  15. package/dist/agents/AbstractAgent.js +60 -46
  16. package/dist/agents/AbstractAgent.js.map +1 -1
  17. package/dist/agents/PipelineAgent.d.ts +7 -7
  18. package/dist/agents/PipelineAgent.d.ts.map +1 -1
  19. package/dist/agents/PipelineAgent.js +75 -23
  20. package/dist/agents/PipelineAgent.js.map +1 -1
  21. package/dist/agents/ReactiveAgent.d.ts +7 -7
  22. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  23. package/dist/agents/ReactiveAgent.js +32 -25
  24. package/dist/agents/ReactiveAgent.js.map +1 -1
  25. package/dist/agents/RouterAgent.d.ts +7 -7
  26. package/dist/agents/RouterAgent.d.ts.map +1 -1
  27. package/dist/agents/RouterAgent.js +29 -32
  28. package/dist/agents/RouterAgent.js.map +1 -1
  29. package/dist/agents/SupervisorAgent.d.ts +13 -10
  30. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  31. package/dist/agents/SupervisorAgent.js +50 -36
  32. package/dist/agents/SupervisorAgent.js.map +1 -1
  33. package/dist/agents/budget.d.ts +17 -4
  34. package/dist/agents/budget.d.ts.map +1 -1
  35. package/dist/agents/budget.js +55 -14
  36. package/dist/agents/budget.js.map +1 -1
  37. package/dist/agents/defineAgent.d.ts +2 -2
  38. package/dist/agents/defineAgent.d.ts.map +1 -1
  39. package/dist/agents/defineAgent.js.map +1 -1
  40. package/dist/agents/handle.d.ts +12 -14
  41. package/dist/agents/handle.d.ts.map +1 -1
  42. package/dist/agents/handle.js +6 -6
  43. package/dist/agents/handle.js.map +1 -1
  44. package/dist/agents/lock.js +4 -4
  45. package/dist/agents/lock.js.map +1 -1
  46. package/dist/agents/runAgent.d.ts +42 -29
  47. package/dist/agents/runAgent.d.ts.map +1 -1
  48. package/dist/agents/runAgent.js +53 -14
  49. package/dist/agents/runAgent.js.map +1 -1
  50. package/dist/agents/storage.d.ts +21 -0
  51. package/dist/agents/storage.d.ts.map +1 -0
  52. package/dist/agents/storage.js +33 -0
  53. package/dist/agents/storage.js.map +1 -0
  54. package/dist/authorization/command-line.d.ts +1 -1
  55. package/dist/authorization/command-line.js +1 -1
  56. package/dist/authorization/gate.js +1 -1
  57. package/dist/authorization/gate.js.map +1 -1
  58. package/dist/authorization/permission-presets.d.ts +4 -4
  59. package/dist/authorization/permission-presets.d.ts.map +1 -1
  60. package/dist/authorization/permission-presets.js +2 -2
  61. package/dist/bridge/a2a/client.d.ts +1 -1
  62. package/dist/bridge/a2a/client.js +2 -2
  63. package/dist/bridge/a2a/client.js.map +1 -1
  64. package/dist/bridge/a2a/context.d.ts +26 -0
  65. package/dist/bridge/a2a/context.d.ts.map +1 -0
  66. package/dist/bridge/a2a/context.js +20 -0
  67. package/dist/bridge/a2a/context.js.map +1 -0
  68. package/dist/bridge/a2a/index.d.ts +4 -2
  69. package/dist/bridge/a2a/index.d.ts.map +1 -1
  70. package/dist/bridge/a2a/index.js +6 -2
  71. package/dist/bridge/a2a/index.js.map +1 -1
  72. package/dist/bridge/a2a/mapper.d.ts +12 -4
  73. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  74. package/dist/bridge/a2a/mapper.js +38 -31
  75. package/dist/bridge/a2a/mapper.js.map +1 -1
  76. package/dist/bridge/a2a/task.d.ts +39 -7
  77. package/dist/bridge/a2a/task.d.ts.map +1 -1
  78. package/dist/bridge/a2a/task.js +52 -31
  79. package/dist/bridge/a2a/task.js.map +1 -1
  80. package/dist/bridge/acp/permission.d.ts +2 -2
  81. package/dist/bridge/acp/server.d.ts +22 -8
  82. package/dist/bridge/acp/server.d.ts.map +1 -1
  83. package/dist/bridge/acp/server.js +18 -5
  84. package/dist/bridge/acp/server.js.map +1 -1
  85. package/dist/bridge/acp/update.d.ts +4 -4
  86. package/dist/bridge/acp/update.d.ts.map +1 -1
  87. package/dist/bridge/acp/update.js +6 -6
  88. package/dist/bridge/acp/update.js.map +1 -1
  89. package/dist/bridge/external-session.d.ts +43 -0
  90. package/dist/bridge/external-session.d.ts.map +1 -0
  91. package/dist/bridge/external-session.js +28 -0
  92. package/dist/bridge/external-session.js.map +1 -0
  93. package/dist/bridge/sse/index.d.ts +1 -1
  94. package/dist/bridge/sse/index.d.ts.map +1 -1
  95. package/dist/bridge/sse/index.js +1 -1
  96. package/dist/bridge/sse/index.js.map +1 -1
  97. package/dist/bridge/sse/mapper.d.ts +21 -13
  98. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  99. package/dist/bridge/sse/mapper.js +99 -129
  100. package/dist/bridge/sse/mapper.js.map +1 -1
  101. package/dist/bus/breaker.d.ts +6 -6
  102. package/dist/bus/breaker.d.ts.map +1 -1
  103. package/dist/bus/breaker.js +28 -27
  104. package/dist/bus/breaker.js.map +1 -1
  105. package/dist/bus/index.d.ts +2 -2
  106. package/dist/bus/index.d.ts.map +1 -1
  107. package/dist/bus/index.js +6 -6
  108. package/dist/bus/index.js.map +1 -1
  109. package/dist/bus/lock.d.ts +5 -5
  110. package/dist/bus/lock.d.ts.map +1 -1
  111. package/dist/bus/lock.js.map +1 -1
  112. package/dist/bus/ownership.d.ts +8 -8
  113. package/dist/bus/ownership.d.ts.map +1 -1
  114. package/dist/bus/ownership.js.map +1 -1
  115. package/dist/compaction/consolidation.d.ts +23 -11
  116. package/dist/compaction/consolidation.d.ts.map +1 -1
  117. package/dist/compaction/consolidation.js +43 -13
  118. package/dist/compaction/consolidation.js.map +1 -1
  119. package/dist/compaction/context-window.d.ts +4 -4
  120. package/dist/compaction/context-window.js +4 -4
  121. package/dist/compaction/index.d.ts +1 -1
  122. package/dist/compaction/index.d.ts.map +1 -1
  123. package/dist/compaction/index.js +2 -2
  124. package/dist/compaction/index.js.map +1 -1
  125. package/dist/compaction/manager.d.ts +4 -4
  126. package/dist/compaction/manager.js +4 -4
  127. package/dist/compaction/manual.d.ts +2 -2
  128. package/dist/compaction/manual.js +3 -3
  129. package/dist/compaction/manual.js.map +1 -1
  130. package/dist/compaction/plan.d.ts +5 -5
  131. package/dist/compaction/plan.js +4 -4
  132. package/dist/compaction/plan.js.map +1 -1
  133. package/dist/compaction/reducer.d.ts +8 -8
  134. package/dist/compaction/reducer.d.ts.map +1 -1
  135. package/dist/compaction/retention.js +2 -2
  136. package/dist/compaction/salience/bm25.d.ts +2 -2
  137. package/dist/compaction/salience/bm25.js +2 -2
  138. package/dist/compaction/salience/goal.d.ts +3 -3
  139. package/dist/compaction/salience/goal.js +3 -3
  140. package/dist/compaction/salience/minhash.d.ts +1 -1
  141. package/dist/compaction/salience/minhash.js +1 -1
  142. package/dist/compaction/salience/score.d.ts +2 -2
  143. package/dist/compaction/salience/score.js +3 -3
  144. package/dist/compaction/salience/score.js.map +1 -1
  145. package/dist/compaction/salience/tokenize.d.ts +1 -1
  146. package/dist/compaction/salience/tokenize.js +1 -1
  147. package/dist/compaction/verifier.d.ts +6 -6
  148. package/dist/compaction/verifier.js +5 -5
  149. package/dist/compaction/verifier.js.map +1 -1
  150. package/dist/compaction/wire.d.ts +1 -1
  151. package/dist/config/registry.d.ts +4 -4
  152. package/dist/config/registry.js +2 -2
  153. package/dist/config/runtime.d.ts +24 -24
  154. package/dist/config/runtime.js +3 -3
  155. package/dist/connector/http-operation.d.ts +1 -1
  156. package/dist/connector/http-operation.js +1 -1
  157. package/dist/connector/mcp/adapter.js +1 -1
  158. package/dist/connector/mcp/client.d.ts +1 -1
  159. package/dist/connector/mcp/client.js +1 -1
  160. package/dist/connector/mcp/discovery.d.ts +1 -1
  161. package/dist/connector/mcp/discovery.js +1 -1
  162. package/dist/connector/mcp/discovery.js.map +1 -1
  163. package/dist/connector/mcp/policy.d.ts +1 -1
  164. package/dist/connector/mcp/prompt-adapter.d.ts +1 -1
  165. package/dist/connector/mcp/prompt-adapter.js +3 -3
  166. package/dist/connector/mcp/prompt-adapter.js.map +1 -1
  167. package/dist/constants/a2a/index.d.ts +8 -2
  168. package/dist/constants/a2a/index.d.ts.map +1 -1
  169. package/dist/constants/a2a/index.js +9 -2
  170. package/dist/constants/a2a/index.js.map +1 -1
  171. package/dist/constants/continuation.d.ts +1 -1
  172. package/dist/constants/continuation.js +1 -1
  173. package/dist/constants/index.d.ts +0 -1
  174. package/dist/constants/index.d.ts.map +1 -1
  175. package/dist/constants/index.js +0 -1
  176. package/dist/constants/index.js.map +1 -1
  177. package/dist/constants/limits.d.ts +2 -2
  178. package/dist/constants/limits.js +2 -2
  179. package/dist/constants/telemetry/index.d.ts +9 -3
  180. package/dist/constants/telemetry/index.d.ts.map +1 -1
  181. package/dist/constants/telemetry/index.js +14 -12
  182. package/dist/constants/telemetry/index.js.map +1 -1
  183. package/dist/constants/tools/index.d.ts +2 -2
  184. package/dist/constants/tools/index.js +2 -2
  185. package/dist/contracts/a2a.d.ts +2 -2
  186. package/dist/contracts/api.d.ts +11 -126
  187. package/dist/contracts/api.d.ts.map +1 -1
  188. package/dist/contracts/index.d.ts +3 -2
  189. package/dist/contracts/index.d.ts.map +1 -1
  190. package/dist/contracts/index.js +7 -2
  191. package/dist/contracts/index.js.map +1 -1
  192. package/dist/contracts/schemas.d.ts +6 -165
  193. package/dist/contracts/schemas.d.ts.map +1 -1
  194. package/dist/contracts/schemas.js +6 -36
  195. package/dist/contracts/schemas.js.map +1 -1
  196. package/dist/contracts/session/api.d.ts +94 -0
  197. package/dist/contracts/session/api.d.ts.map +1 -0
  198. package/dist/contracts/session/api.js +10 -0
  199. package/dist/contracts/session/api.js.map +1 -0
  200. package/dist/contracts/session/index.d.ts +7 -0
  201. package/dist/contracts/session/index.d.ts.map +1 -0
  202. package/dist/contracts/session/index.js +7 -0
  203. package/dist/contracts/session/index.js.map +1 -0
  204. package/dist/contracts/session/schemas.d.ts +173 -0
  205. package/dist/contracts/session/schemas.d.ts.map +1 -0
  206. package/dist/contracts/session/schemas.js +52 -0
  207. package/dist/contracts/session/schemas.js.map +1 -0
  208. package/dist/contracts/session/turn-status.d.ts +45 -0
  209. package/dist/contracts/session/turn-status.d.ts.map +1 -0
  210. package/dist/contracts/session/turn-status.js +46 -0
  211. package/dist/contracts/session/turn-status.js.map +1 -0
  212. package/dist/contracts/session/turn.d.ts +64 -0
  213. package/dist/contracts/session/turn.d.ts.map +1 -0
  214. package/dist/contracts/session/turn.js +2 -0
  215. package/dist/contracts/session/turn.js.map +1 -0
  216. package/dist/directory/derive-supervisor.d.ts +1 -1
  217. package/dist/directory/derive-supervisor.js +2 -2
  218. package/dist/directory/derive-supervisor.js.map +1 -1
  219. package/dist/directory/derive.d.ts +2 -2
  220. package/dist/directory/derive.d.ts.map +1 -1
  221. package/dist/directory/derive.js +2 -2
  222. package/dist/directory/derive.js.map +1 -1
  223. package/dist/directory/index.d.ts +2 -2
  224. package/dist/directory/index.d.ts.map +1 -1
  225. package/dist/directory/index.js +1 -1
  226. package/dist/directory/index.js.map +1 -1
  227. package/dist/directory/load.js +2 -2
  228. package/dist/directory/load.js.map +1 -1
  229. package/dist/directory/types.d.ts +2 -2
  230. package/dist/directory/types.d.ts.map +1 -1
  231. package/dist/eval/experiment.d.ts +5 -5
  232. package/dist/eval/experiment.d.ts.map +1 -1
  233. package/dist/eval/experiment.js +18 -18
  234. package/dist/eval/experiment.js.map +1 -1
  235. package/dist/eval/from-turn.d.ts +30 -0
  236. package/dist/eval/from-turn.d.ts.map +1 -0
  237. package/dist/eval/from-turn.js +46 -0
  238. package/dist/eval/from-turn.js.map +1 -0
  239. package/dist/eval/harness-verification.js +7 -7
  240. package/dist/eval/harness-verification.js.map +1 -1
  241. package/dist/eval/index.d.ts +2 -2
  242. package/dist/eval/index.d.ts.map +1 -1
  243. package/dist/eval/index.js +1 -1
  244. package/dist/eval/index.js.map +1 -1
  245. package/dist/eval/judge.d.ts +3 -3
  246. package/dist/eval/judge.d.ts.map +1 -1
  247. package/dist/eval/judge.js +6 -6
  248. package/dist/eval/judge.js.map +1 -1
  249. package/dist/eval/scorers.d.ts +8 -8
  250. package/dist/eval/scorers.d.ts.map +1 -1
  251. package/dist/eval/scorers.js +21 -21
  252. package/dist/eval/scorers.js.map +1 -1
  253. package/dist/eval/types.d.ts +12 -12
  254. package/dist/eval/types.d.ts.map +1 -1
  255. package/dist/eval/uncertainty.d.ts +2 -2
  256. package/dist/eval/uncertainty.js +2 -2
  257. package/dist/execution/code-runtime/types.d.ts +4 -4
  258. package/dist/execution/code-runtime/types.js +2 -2
  259. package/dist/execution/code-runtime/worker.d.ts +1 -1
  260. package/dist/execution/code-runtime/worker.js +1 -1
  261. package/dist/invariants/index.d.ts +1 -1
  262. package/dist/manager/agent/child-session.d.ts +49 -0
  263. package/dist/manager/agent/child-session.d.ts.map +1 -0
  264. package/dist/manager/agent/child-session.js +94 -0
  265. package/dist/manager/agent/child-session.js.map +1 -0
  266. package/dist/manager/agent/lifecycle.d.ts +90 -13
  267. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  268. package/dist/manager/agent/lifecycle.js +332 -88
  269. package/dist/manager/agent/lifecycle.js.map +1 -1
  270. package/dist/manager/index.d.ts +1 -2
  271. package/dist/manager/index.d.ts.map +1 -1
  272. package/dist/manager/index.js +1 -2
  273. package/dist/manager/index.js.map +1 -1
  274. package/dist/manager/plan/lifecycle.d.ts +11 -7
  275. package/dist/manager/plan/lifecycle.d.ts.map +1 -1
  276. package/dist/manager/plan/lifecycle.js +12 -9
  277. package/dist/manager/plan/lifecycle.js.map +1 -1
  278. package/dist/manager/resident/consumption.d.ts +12 -6
  279. package/dist/manager/resident/consumption.d.ts.map +1 -1
  280. package/dist/manager/resident/consumption.js +7 -5
  281. package/dist/manager/resident/consumption.js.map +1 -1
  282. package/dist/manager/resident/evidence-recall.d.ts +5 -5
  283. package/dist/manager/resident/evidence-recall.d.ts.map +1 -1
  284. package/dist/manager/resident/evidence-recall.js +9 -9
  285. package/dist/manager/resident/evidence-recall.js.map +1 -1
  286. package/dist/manager/resident/host.d.ts +2 -2
  287. package/dist/manager/resident/host.d.ts.map +1 -1
  288. package/dist/manager/resident/host.js +1 -1
  289. package/dist/manager/resident/learning-cycle.d.ts +8 -4
  290. package/dist/manager/resident/learning-cycle.d.ts.map +1 -1
  291. package/dist/manager/resident/learning-cycle.js +4 -2
  292. package/dist/manager/resident/learning-cycle.js.map +1 -1
  293. package/dist/manager/resident/learning-observation.d.ts +12 -7
  294. package/dist/manager/resident/learning-observation.d.ts.map +1 -1
  295. package/dist/manager/resident/learning-observation.js +8 -4
  296. package/dist/manager/resident/learning-observation.js.map +1 -1
  297. package/dist/manager/resident/learning-store.d.ts +13 -0
  298. package/dist/manager/resident/learning-store.d.ts.map +1 -1
  299. package/dist/manager/resident/learning-store.js +35 -16
  300. package/dist/manager/resident/learning-store.js.map +1 -1
  301. package/dist/manager/resident/learning.d.ts +14 -14
  302. package/dist/manager/resident/outbox.d.ts +4 -4
  303. package/dist/manager/resident/store.d.ts +8 -8
  304. package/dist/manager/resident/tool-evidence.d.ts +15 -10
  305. package/dist/manager/resident/tool-evidence.d.ts.map +1 -1
  306. package/dist/manager/resident/tool-evidence.js +14 -14
  307. package/dist/manager/resident/tool-evidence.js.map +1 -1
  308. package/dist/manager/session/turn-recorder.d.ts +261 -0
  309. package/dist/manager/session/turn-recorder.d.ts.map +1 -0
  310. package/dist/manager/session/turn-recorder.js +1115 -0
  311. package/dist/manager/session/turn-recorder.js.map +1 -0
  312. package/dist/plugin/lifecycle.d.ts +4 -4
  313. package/dist/plugin/lifecycle.d.ts.map +1 -1
  314. package/dist/plugin/lifecycle.js +17 -10
  315. package/dist/plugin/lifecycle.js.map +1 -1
  316. package/dist/plugin/shell-hook.d.ts +35 -12
  317. package/dist/plugin/shell-hook.d.ts.map +1 -1
  318. package/dist/plugin/shell-hook.js +52 -20
  319. package/dist/plugin/shell-hook.js.map +1 -1
  320. package/dist/pricing/index.d.ts +4 -4
  321. package/dist/pricing/index.js +5 -5
  322. package/dist/pricing/index.js.map +1 -1
  323. package/dist/probe/context.d.ts +3 -2
  324. package/dist/probe/context.d.ts.map +1 -1
  325. package/dist/probe/context.js +2 -1
  326. package/dist/probe/context.js.map +1 -1
  327. package/dist/probe/registry.js +1 -1
  328. package/dist/probe/registry.js.map +1 -1
  329. package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
  330. package/dist/prompt/coding-agent-doctrine.js +1 -1
  331. package/dist/prompt/contributions.d.ts +27 -6
  332. package/dist/prompt/contributions.d.ts.map +1 -1
  333. package/dist/prompt/contributions.js +1 -1
  334. package/dist/prompt/contributions.js.map +1 -1
  335. package/dist/prompt/resident-learning.js +2 -2
  336. package/dist/prompt/resident-learning.js.map +1 -1
  337. package/dist/provider/collect-chat-completion.d.ts +2 -2
  338. package/dist/provider/collect-chat-completion.js +3 -3
  339. package/dist/provider/collect-chat-completion.js.map +1 -1
  340. package/dist/provider/conformance.d.ts +8 -1
  341. package/dist/provider/conformance.d.ts.map +1 -1
  342. package/dist/provider/conformance.js +13 -1
  343. package/dist/provider/conformance.js.map +1 -1
  344. package/dist/provider/errors.d.ts +1 -1
  345. package/dist/provider/errors.js +2 -2
  346. package/dist/provider/fallback.d.ts +4 -4
  347. package/dist/provider/fallback.js +6 -6
  348. package/dist/provider/fallback.js.map +1 -1
  349. package/dist/provider/idle-timeout.d.ts +2 -2
  350. package/dist/provider/idle-timeout.d.ts.map +1 -1
  351. package/dist/provider/idle-timeout.js +3 -3
  352. package/dist/provider/idle-timeout.js.map +1 -1
  353. package/dist/provider/instrumentation.d.ts +5 -2
  354. package/dist/provider/instrumentation.d.ts.map +1 -1
  355. package/dist/provider/instrumentation.js +9 -5
  356. package/dist/provider/instrumentation.js.map +1 -1
  357. package/dist/provider/mock.d.ts +1 -1
  358. package/dist/provider/mock.js +1 -1
  359. package/dist/provider/retry.d.ts +2 -2
  360. package/dist/provider/retry.js +6 -6
  361. package/dist/provider/retry.js.map +1 -1
  362. package/dist/provider/stream-text.d.ts +1 -1
  363. package/dist/provider/stream-text.d.ts.map +1 -1
  364. package/dist/provider/stream-text.js +1 -1
  365. package/dist/provider/stream-text.js.map +1 -1
  366. package/dist/provider/thinking-support.js +2 -2
  367. package/dist/provider/thinking-support.js.map +1 -1
  368. package/dist/provider/token-budget.d.ts +2 -2
  369. package/dist/provider/token-budget.d.ts.map +1 -1
  370. package/dist/provider/token-budget.js.map +1 -1
  371. package/dist/public-runtime.d.ts +69 -55
  372. package/dist/public-runtime.d.ts.map +1 -1
  373. package/dist/public-runtime.js +104 -99
  374. package/dist/public-runtime.js.map +1 -1
  375. package/dist/public-tools.d.ts +2 -2
  376. package/dist/public-tools.d.ts.map +1 -1
  377. package/dist/public-tools.js +7 -7
  378. package/dist/public-tools.js.map +1 -1
  379. package/dist/public-types.d.ts +18 -16
  380. package/dist/public-types.d.ts.map +1 -1
  381. package/dist/rag/embedding.js +1 -1
  382. package/dist/rag/embedding.js.map +1 -1
  383. package/dist/read-model/index.d.ts +2 -2
  384. package/dist/read-model/index.d.ts.map +1 -1
  385. package/dist/read-model/index.js +1 -1
  386. package/dist/read-model/index.js.map +1 -1
  387. package/dist/read-model/registry.d.ts +11 -11
  388. package/dist/read-model/registry.d.ts.map +1 -1
  389. package/dist/read-model/registry.js +2 -2
  390. package/dist/read-model/registry.js.map +1 -1
  391. package/dist/read-model/session-status.d.ts +34 -0
  392. package/dist/read-model/session-status.d.ts.map +1 -0
  393. package/dist/read-model/session-status.js +58 -0
  394. package/dist/read-model/session-status.js.map +1 -0
  395. package/dist/registry/command/kernel-commands.d.ts +4 -4
  396. package/dist/registry/command/kernel-commands.d.ts.map +1 -1
  397. package/dist/registry/command/kernel-commands.js +6 -6
  398. package/dist/registry/command/kernel-commands.js.map +1 -1
  399. package/dist/registry/tool/dialect.js +1 -1
  400. package/dist/registry/tool/execute.d.ts +2 -2
  401. package/dist/registry/tool/execute.d.ts.map +1 -1
  402. package/dist/registry/tool/execute.js +19 -7
  403. package/dist/registry/tool/execute.js.map +1 -1
  404. package/dist/registry/tool/portable.d.ts +1 -1
  405. package/dist/registry/tool/portable.js +1 -1
  406. package/dist/registry/tool/presentation.d.ts +1 -1
  407. package/dist/registry/tool/presentation.js +1 -1
  408. package/dist/registry/tool/schema.js +1 -1
  409. package/dist/registry/tool/screen.js +3 -3
  410. package/dist/registry/tool/screen.js.map +1 -1
  411. package/dist/runtime/bidi/index.d.ts +2 -2
  412. package/dist/runtime/bidi/index.d.ts.map +1 -1
  413. package/dist/runtime/bidi/index.js +1 -1
  414. package/dist/runtime/bidi/index.js.map +1 -1
  415. package/dist/runtime/bidi/session.d.ts +14 -11
  416. package/dist/runtime/bidi/session.d.ts.map +1 -1
  417. package/dist/runtime/bidi/session.js +27 -21
  418. package/dist/runtime/bidi/session.js.map +1 -1
  419. package/dist/runtime/jobs/awaited-jobs.d.ts +15 -15
  420. package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -1
  421. package/dist/runtime/jobs/awaited-jobs.js +13 -13
  422. package/dist/runtime/jobs/awaited-jobs.js.map +1 -1
  423. package/dist/runtime/jobs/registry.d.ts +10 -10
  424. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  425. package/dist/runtime/jobs/registry.js +5 -5
  426. package/dist/runtime/jobs/registry.js.map +1 -1
  427. package/dist/runtime/query/abandon-turn.d.ts +35 -0
  428. package/dist/runtime/query/abandon-turn.d.ts.map +1 -0
  429. package/dist/runtime/query/abandon-turn.js +81 -0
  430. package/dist/runtime/query/abandon-turn.js.map +1 -0
  431. package/dist/runtime/query/approval-policy.d.ts +10 -10
  432. package/dist/runtime/query/approval-policy.d.ts.map +1 -1
  433. package/dist/runtime/query/approval-policy.js +5 -5
  434. package/dist/runtime/query/approval-policy.js.map +1 -1
  435. package/dist/runtime/query/callback-inference.d.ts +1 -1
  436. package/dist/runtime/query/callback-inference.d.ts.map +1 -1
  437. package/dist/runtime/query/callback-inference.js +12 -6
  438. package/dist/runtime/query/callback-inference.js.map +1 -1
  439. package/dist/runtime/query/cancelled-before-start.d.ts +20 -20
  440. package/dist/runtime/query/cancelled-before-start.d.ts.map +1 -1
  441. package/dist/runtime/query/cancelled-before-start.js +72 -55
  442. package/dist/runtime/query/cancelled-before-start.js.map +1 -1
  443. package/dist/runtime/query/checkpoint.d.ts +153 -220
  444. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  445. package/dist/runtime/query/checkpoint.js +399 -370
  446. package/dist/runtime/query/checkpoint.js.map +1 -1
  447. package/dist/runtime/query/compact-session.d.ts +20 -0
  448. package/dist/runtime/query/compact-session.d.ts.map +1 -0
  449. package/dist/runtime/query/compact-session.js +81 -0
  450. package/dist/runtime/query/compact-session.js.map +1 -0
  451. package/dist/runtime/query/context.d.ts +42 -85
  452. package/dist/runtime/query/context.d.ts.map +1 -1
  453. package/dist/runtime/query/context.js +36 -75
  454. package/dist/runtime/query/context.js.map +1 -1
  455. package/dist/runtime/query/events.d.ts +54 -26
  456. package/dist/runtime/query/events.d.ts.map +1 -1
  457. package/dist/runtime/query/events.js +121 -114
  458. package/dist/runtime/query/events.js.map +1 -1
  459. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
  460. package/dist/runtime/query/executor/tool-call-admission.js +6 -5
  461. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
  462. package/dist/runtime/query/executor.d.ts +56 -34
  463. package/dist/runtime/query/executor.d.ts.map +1 -1
  464. package/dist/runtime/query/executor.js +165 -85
  465. package/dist/runtime/query/executor.js.map +1 -1
  466. package/dist/runtime/query/file-evidence-seed.d.ts +1 -1
  467. package/dist/runtime/query/file-evidence-seed.d.ts.map +1 -1
  468. package/dist/runtime/query/file-evidence-seed.js +1 -1
  469. package/dist/runtime/query/finalize-turn.d.ts +55 -0
  470. package/dist/runtime/query/finalize-turn.d.ts.map +1 -0
  471. package/dist/runtime/query/finalize-turn.js +129 -0
  472. package/dist/runtime/query/finalize-turn.js.map +1 -0
  473. package/dist/runtime/query/fork/list.d.ts +15 -0
  474. package/dist/runtime/query/fork/list.d.ts.map +1 -0
  475. package/dist/runtime/query/fork/list.js +11 -0
  476. package/dist/runtime/query/fork/list.js.map +1 -0
  477. package/dist/runtime/query/fork/mutate.d.ts +17 -0
  478. package/dist/runtime/query/fork/mutate.d.ts.map +1 -0
  479. package/dist/runtime/query/fork/mutate.js +69 -0
  480. package/dist/runtime/query/fork/mutate.js.map +1 -0
  481. package/dist/runtime/query/fork/prepare.d.ts +52 -0
  482. package/dist/runtime/query/fork/prepare.d.ts.map +1 -0
  483. package/dist/runtime/query/fork/prepare.js +43 -0
  484. package/dist/runtime/query/fork/prepare.js.map +1 -0
  485. package/dist/runtime/query/guard.d.ts +16 -16
  486. package/dist/runtime/query/guard.d.ts.map +1 -1
  487. package/dist/runtime/query/guard.js +16 -16
  488. package/dist/runtime/query/guard.js.map +1 -1
  489. package/dist/runtime/query/guardrail-presets.d.ts +10 -10
  490. package/dist/runtime/query/guardrail-presets.js +12 -12
  491. package/dist/runtime/query/guardrail-presets.js.map +1 -1
  492. package/dist/runtime/query/guardrails.d.ts +4 -4
  493. package/dist/runtime/query/guardrails.js +11 -11
  494. package/dist/runtime/query/guardrails.js.map +1 -1
  495. package/dist/runtime/query/index.d.ts +178 -155
  496. package/dist/runtime/query/index.d.ts.map +1 -1
  497. package/dist/runtime/query/index.js +1294 -1260
  498. package/dist/runtime/query/index.js.map +1 -1
  499. package/dist/runtime/query/iteration/index.d.ts +16 -16
  500. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  501. package/dist/runtime/query/iteration/index.js +285 -243
  502. package/dist/runtime/query/iteration/index.js.map +1 -1
  503. package/dist/runtime/query/iteration/outstanding-work.d.ts +22 -22
  504. package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -1
  505. package/dist/runtime/query/iteration/outstanding-work.js +63 -63
  506. package/dist/runtime/query/iteration/outstanding-work.js.map +1 -1
  507. package/dist/runtime/query/iteration/phases/advisory.js +16 -16
  508. package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
  509. package/dist/runtime/query/iteration/phases/checkpoint.d.ts +2 -2
  510. package/dist/runtime/query/iteration/phases/checkpoint.d.ts.map +1 -1
  511. package/dist/runtime/query/iteration/phases/checkpoint.js +25 -8
  512. package/dist/runtime/query/iteration/phases/checkpoint.js.map +1 -1
  513. package/dist/runtime/query/iteration/phases/compaction.d.ts +2 -2
  514. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  515. package/dist/runtime/query/iteration/phases/compaction.js +74 -72
  516. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  517. package/dist/runtime/query/iteration/phases/context.d.ts +32 -29
  518. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  519. package/dist/runtime/query/iteration/phases/context.js +29 -29
  520. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  521. package/dist/runtime/query/iteration/phases/plan.d.ts +2 -2
  522. package/dist/runtime/query/iteration/phases/plan.d.ts.map +1 -1
  523. package/dist/runtime/query/iteration/phases/plan.js +5 -4
  524. package/dist/runtime/query/iteration/phases/plan.js.map +1 -1
  525. package/dist/runtime/query/iteration/phases/tool-review.d.ts +2 -2
  526. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  527. package/dist/runtime/query/iteration/phases/tool-review.js +129 -24
  528. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  529. package/dist/runtime/query/iteration/phases/working-memory.d.ts +27 -3
  530. package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -1
  531. package/dist/runtime/query/iteration/phases/working-memory.js +54 -20
  532. package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -1
  533. package/dist/runtime/query/iteration/step-context.d.ts +11 -0
  534. package/dist/runtime/query/iteration/step-context.d.ts.map +1 -0
  535. package/dist/runtime/query/iteration/step-context.js +14 -0
  536. package/dist/runtime/query/iteration/step-context.js.map +1 -0
  537. package/dist/runtime/query/iteration/step-shaping.d.ts +4 -3
  538. package/dist/runtime/query/iteration/step-shaping.d.ts.map +1 -1
  539. package/dist/runtime/query/iteration/step-shaping.js +20 -19
  540. package/dist/runtime/query/iteration/step-shaping.js.map +1 -1
  541. package/dist/runtime/query/iteration/stream-turn.d.ts +5 -3
  542. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  543. package/dist/runtime/query/iteration/stream-turn.js +32 -28
  544. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  545. package/dist/runtime/query/plugin-hooks.js +1 -1
  546. package/dist/runtime/query/plugin-hooks.js.map +1 -1
  547. package/dist/runtime/query/prepare-turn.d.ts +105 -0
  548. package/dist/runtime/query/prepare-turn.d.ts.map +1 -0
  549. package/dist/runtime/query/prepare-turn.js +779 -0
  550. package/dist/runtime/query/prepare-turn.js.map +1 -0
  551. package/dist/runtime/query/project-instructions.d.ts +5 -4
  552. package/dist/runtime/query/project-instructions.d.ts.map +1 -1
  553. package/dist/runtime/query/project-instructions.js.map +1 -1
  554. package/dist/runtime/query/prompt-cache.js +1 -1
  555. package/dist/runtime/query/prompt-cache.js.map +1 -1
  556. package/dist/runtime/query/prompt.d.ts +3 -3
  557. package/dist/runtime/query/prompt.d.ts.map +1 -1
  558. package/dist/runtime/query/prompt.js +3 -3
  559. package/dist/runtime/query/prompt.js.map +1 -1
  560. package/dist/runtime/query/question-park.d.ts +7 -7
  561. package/dist/runtime/query/question-park.d.ts.map +1 -1
  562. package/dist/runtime/query/question-park.js +5 -5
  563. package/dist/runtime/query/question-park.js.map +1 -1
  564. package/dist/runtime/query/release-turn.d.ts +53 -0
  565. package/dist/runtime/query/release-turn.d.ts.map +1 -0
  566. package/dist/runtime/query/release-turn.js +95 -0
  567. package/dist/runtime/query/release-turn.js.map +1 -0
  568. package/dist/runtime/query/repeat-call.d.ts +2 -2
  569. package/dist/runtime/query/repeat-call.js +7 -7
  570. package/dist/runtime/query/repeat-call.js.map +1 -1
  571. package/dist/runtime/query/result.d.ts +25 -17
  572. package/dist/runtime/query/result.d.ts.map +1 -1
  573. package/dist/runtime/query/result.js +110 -115
  574. package/dist/runtime/query/result.js.map +1 -1
  575. package/dist/runtime/query/resume-pending.d.ts +34 -17
  576. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  577. package/dist/runtime/query/resume-pending.js +70 -30
  578. package/dist/runtime/query/resume-pending.js.map +1 -1
  579. package/dist/runtime/query/resume-session.d.ts +65 -0
  580. package/dist/runtime/query/resume-session.d.ts.map +1 -0
  581. package/dist/runtime/query/resume-session.js +88 -0
  582. package/dist/runtime/query/resume-session.js.map +1 -0
  583. package/dist/runtime/query/review-policy.d.ts +57 -16
  584. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  585. package/dist/runtime/query/review-policy.js +115 -11
  586. package/dist/runtime/query/review-policy.js.map +1 -1
  587. package/dist/runtime/query/sandbox-lifecycle.d.ts +5 -5
  588. package/dist/runtime/query/sandbox-lifecycle.d.ts.map +1 -1
  589. package/dist/runtime/query/sandbox-lifecycle.js +4 -4
  590. package/dist/runtime/query/sandbox-lifecycle.js.map +1 -1
  591. package/dist/runtime/query/session-storage.d.ts +75 -0
  592. package/dist/runtime/query/session-storage.d.ts.map +1 -0
  593. package/dist/runtime/query/session-storage.js +236 -0
  594. package/dist/runtime/query/session-storage.js.map +1 -0
  595. package/dist/runtime/query/steering.d.ts +9 -3
  596. package/dist/runtime/query/steering.d.ts.map +1 -1
  597. package/dist/runtime/query/steering.js +12 -2
  598. package/dist/runtime/query/steering.js.map +1 -1
  599. package/dist/runtime/query/token-budget.d.ts +19 -5
  600. package/dist/runtime/query/token-budget.d.ts.map +1 -1
  601. package/dist/runtime/query/token-budget.js +43 -74
  602. package/dist/runtime/query/token-budget.js.map +1 -1
  603. package/dist/runtime/query/tool-call-budget.d.ts +6 -5
  604. package/dist/runtime/query/tool-call-budget.d.ts.map +1 -1
  605. package/dist/runtime/query/tool-call-budget.js +10 -12
  606. package/dist/runtime/query/tool-call-budget.js.map +1 -1
  607. package/dist/runtime/query/tool-executions.d.ts +26 -0
  608. package/dist/runtime/query/tool-executions.d.ts.map +1 -0
  609. package/dist/runtime/query/tool-executions.js +66 -0
  610. package/dist/runtime/query/tool-executions.js.map +1 -0
  611. package/dist/runtime/query/tool-grants.d.ts +3 -3
  612. package/dist/runtime/query/tool-grants.js +3 -3
  613. package/dist/runtime/query/tool-output-budget.d.ts +2 -2
  614. package/dist/runtime/query/tool-output-budget.js +4 -4
  615. package/dist/runtime/query/tool-output-budget.js.map +1 -1
  616. package/dist/runtime/query/tool-pause.d.ts +4 -3
  617. package/dist/runtime/query/tool-pause.d.ts.map +1 -1
  618. package/dist/runtime/query/tool-pause.js +5 -4
  619. package/dist/runtime/query/tool-pause.js.map +1 -1
  620. package/dist/runtime/query/tooling.d.ts +15 -10
  621. package/dist/runtime/query/tooling.d.ts.map +1 -1
  622. package/dist/runtime/query/tooling.js +7 -4
  623. package/dist/runtime/query/tooling.js.map +1 -1
  624. package/dist/runtime/query/turn-state.d.ts +56 -0
  625. package/dist/runtime/query/turn-state.d.ts.map +1 -0
  626. package/dist/runtime/query/turn-state.js +99 -0
  627. package/dist/runtime/query/turn-state.js.map +1 -0
  628. package/dist/sandbox/isolation.d.ts +1 -1
  629. package/dist/sandbox/isolation.js +2 -2
  630. package/dist/sandbox/isolation.js.map +1 -1
  631. package/dist/sandbox/provider/local.d.ts +2 -2
  632. package/dist/sandbox/provider/local.js +7 -7
  633. package/dist/sandbox/provider/local.js.map +1 -1
  634. package/dist/scheduler/completion-inbox.d.ts +21 -21
  635. package/dist/scheduler/completion-inbox.js +36 -36
  636. package/dist/scheduler/completion-inbox.js.map +1 -1
  637. package/dist/scheduler/delegating.d.ts +6 -3
  638. package/dist/scheduler/delegating.d.ts.map +1 -1
  639. package/dist/scheduler/delegating.js +15 -8
  640. package/dist/scheduler/delegating.js.map +1 -1
  641. package/dist/scheduler/local.d.ts +10 -8
  642. package/dist/scheduler/local.d.ts.map +1 -1
  643. package/dist/scheduler/local.js +37 -11
  644. package/dist/scheduler/local.js.map +1 -1
  645. package/dist/session/events/index.d.ts +3 -3
  646. package/dist/session/events/index.d.ts.map +1 -1
  647. package/dist/session/events/index.js +4 -8
  648. package/dist/session/events/index.js.map +1 -1
  649. package/dist/session/handoff/broadcast.d.ts +3 -3
  650. package/dist/session/handoff/broadcast.d.ts.map +1 -1
  651. package/dist/session/handoff/broadcast.js +4 -4
  652. package/dist/session/handoff/broadcast.js.map +1 -1
  653. package/dist/session/handoff/events.d.ts +1 -1
  654. package/dist/session/handoff/events.js +1 -1
  655. package/dist/session/handoff/index.d.ts +1 -1
  656. package/dist/session/handoff/index.d.ts.map +1 -1
  657. package/dist/session/handoff/single.d.ts +12 -12
  658. package/dist/session/handoff/single.d.ts.map +1 -1
  659. package/dist/session/handoff/single.js +9 -9
  660. package/dist/session/handoff/single.js.map +1 -1
  661. package/dist/session/handoff/version.d.ts +7 -7
  662. package/dist/session/handoff/version.d.ts.map +1 -1
  663. package/dist/session/handoff/version.js +2 -2
  664. package/dist/session/handoff/version.js.map +1 -1
  665. package/dist/session/home.d.ts +23 -0
  666. package/dist/session/home.d.ts.map +1 -0
  667. package/dist/session/home.js +45 -0
  668. package/dist/session/home.js.map +1 -0
  669. package/dist/session/index.d.ts +1 -0
  670. package/dist/session/index.d.ts.map +1 -1
  671. package/dist/session/index.js +1 -0
  672. package/dist/session/index.js.map +1 -1
  673. package/dist/session/log-hash.d.ts +25 -0
  674. package/dist/session/log-hash.d.ts.map +1 -0
  675. package/dist/session/log-hash.js +82 -0
  676. package/dist/session/log-hash.js.map +1 -0
  677. package/dist/session/messages.d.ts +11 -0
  678. package/dist/session/messages.d.ts.map +1 -0
  679. package/dist/session/messages.js +32 -0
  680. package/dist/session/messages.js.map +1 -0
  681. package/dist/session/paths.d.ts +168 -0
  682. package/dist/session/paths.d.ts.map +1 -0
  683. package/dist/session/paths.js +338 -0
  684. package/dist/session/paths.js.map +1 -0
  685. package/dist/session/retention/archive.d.ts +8 -1
  686. package/dist/session/retention/archive.d.ts.map +1 -1
  687. package/dist/session/retention/archive.js +3 -5
  688. package/dist/session/retention/archive.js.map +1 -1
  689. package/dist/session/status/derive.d.ts +13 -13
  690. package/dist/session/status/derive.d.ts.map +1 -1
  691. package/dist/session/status/derive.js +20 -20
  692. package/dist/session/status/derive.js.map +1 -1
  693. package/dist/session/workspace/git-worktree.d.ts +8 -1
  694. package/dist/session/workspace/git-worktree.d.ts.map +1 -1
  695. package/dist/session/workspace/git-worktree.js +29 -1
  696. package/dist/session/workspace/git-worktree.js.map +1 -1
  697. package/dist/session/workspace/index.d.ts +2 -4
  698. package/dist/session/workspace/index.d.ts.map +1 -1
  699. package/dist/session/workspace/index.js +2 -3
  700. package/dist/session/workspace/index.js.map +1 -1
  701. package/dist/session/workspace/shared-session.d.ts +112 -0
  702. package/dist/session/workspace/shared-session.d.ts.map +1 -0
  703. package/dist/session/workspace/shared-session.js +290 -0
  704. package/dist/session/workspace/shared-session.js.map +1 -0
  705. package/dist/session-query/index.d.ts +67 -0
  706. package/dist/session-query/index.d.ts.map +1 -0
  707. package/dist/session-query/index.js +100 -0
  708. package/dist/session-query/index.js.map +1 -0
  709. package/dist/skills/registry.d.ts +1 -1
  710. package/dist/skills/registry.js +1 -1
  711. package/dist/store/activity/memory.d.ts +3 -3
  712. package/dist/store/activity/memory.d.ts.map +1 -1
  713. package/dist/store/activity/memory.js +4 -4
  714. package/dist/store/activity/memory.js.map +1 -1
  715. package/dist/store/attachment/index.d.ts +4 -4
  716. package/dist/store/attachment/index.d.ts.map +1 -1
  717. package/dist/store/attachment/index.js +3 -3
  718. package/dist/store/attachment/index.js.map +1 -1
  719. package/dist/store/budget/disk.d.ts +59 -0
  720. package/dist/store/budget/disk.d.ts.map +1 -0
  721. package/dist/store/budget/disk.js +179 -0
  722. package/dist/store/budget/disk.js.map +1 -0
  723. package/dist/store/budget/index.d.ts +6 -0
  724. package/dist/store/budget/index.d.ts.map +1 -0
  725. package/dist/store/budget/index.js +6 -0
  726. package/dist/store/budget/index.js.map +1 -0
  727. package/dist/store/budget/ledger.d.ts +156 -0
  728. package/dist/store/budget/ledger.d.ts.map +1 -0
  729. package/dist/store/budget/ledger.js +683 -0
  730. package/dist/store/budget/ledger.js.map +1 -0
  731. package/dist/store/budget/memory.d.ts +18 -0
  732. package/dist/store/budget/memory.d.ts.map +1 -0
  733. package/dist/store/budget/memory.js +31 -0
  734. package/dist/store/budget/memory.js.map +1 -0
  735. package/dist/store/checkpoint/contract.d.ts +140 -0
  736. package/dist/store/checkpoint/contract.d.ts.map +1 -0
  737. package/dist/store/checkpoint/contract.js +91 -0
  738. package/dist/store/checkpoint/contract.js.map +1 -0
  739. package/dist/store/checkpoint/disk.d.ts +44 -0
  740. package/dist/store/checkpoint/disk.d.ts.map +1 -0
  741. package/dist/store/checkpoint/disk.js +168 -0
  742. package/dist/store/checkpoint/disk.js.map +1 -0
  743. package/dist/store/checkpoint/index.d.ts +9 -0
  744. package/dist/store/checkpoint/index.d.ts.map +1 -0
  745. package/dist/store/checkpoint/index.js +7 -0
  746. package/dist/store/checkpoint/index.js.map +1 -0
  747. package/dist/store/checkpoint/memory.d.ts +27 -0
  748. package/dist/store/checkpoint/memory.d.ts.map +1 -0
  749. package/dist/store/checkpoint/memory.js +80 -0
  750. package/dist/store/checkpoint/memory.js.map +1 -0
  751. package/dist/store/checkpoint/prune.d.ts +45 -0
  752. package/dist/store/checkpoint/prune.d.ts.map +1 -0
  753. package/dist/store/checkpoint/prune.js +71 -0
  754. package/dist/store/checkpoint/prune.js.map +1 -0
  755. package/dist/store/config/index.d.ts +1 -1
  756. package/dist/store/config/index.js +1 -1
  757. package/dist/store/evidence/disk.d.ts +25 -8
  758. package/dist/store/evidence/disk.d.ts.map +1 -1
  759. package/dist/store/evidence/disk.js +148 -47
  760. package/dist/store/evidence/disk.js.map +1 -1
  761. package/dist/store/evidence/index-page.d.ts +31 -140
  762. package/dist/store/evidence/index-page.d.ts.map +1 -1
  763. package/dist/store/evidence/index-page.js +59 -129
  764. package/dist/store/evidence/index-page.js.map +1 -1
  765. package/dist/store/evidence/source-text.d.ts +7 -6
  766. package/dist/store/evidence/source-text.d.ts.map +1 -1
  767. package/dist/store/evidence/source-text.js +16 -23
  768. package/dist/store/evidence/source-text.js.map +1 -1
  769. package/dist/store/evidence/types.d.ts +38 -39
  770. package/dist/store/evidence/types.d.ts.map +1 -1
  771. package/dist/store/feedback/conformance.d.ts +6 -6
  772. package/dist/store/feedback/conformance.d.ts.map +1 -1
  773. package/dist/store/feedback/conformance.js +30 -29
  774. package/dist/store/feedback/conformance.js.map +1 -1
  775. package/dist/store/feedback/disk.d.ts +20 -19
  776. package/dist/store/feedback/disk.d.ts.map +1 -1
  777. package/dist/store/feedback/disk.js +53 -53
  778. package/dist/store/feedback/disk.js.map +1 -1
  779. package/dist/store/feedback/index.d.ts +1 -1
  780. package/dist/store/feedback/index.d.ts.map +1 -1
  781. package/dist/store/feedback/index.js +1 -1
  782. package/dist/store/feedback/index.js.map +1 -1
  783. package/dist/store/feedback/memory.d.ts +8 -5
  784. package/dist/store/feedback/memory.d.ts.map +1 -1
  785. package/dist/store/feedback/memory.js +0 -0
  786. package/dist/store/feedback/memory.js.map +1 -1
  787. package/dist/store/feedback/types.d.ts +12 -11
  788. package/dist/store/feedback/types.d.ts.map +1 -1
  789. package/dist/store/feedback/types.js +3 -3
  790. package/dist/store/feedback/types.js.map +1 -1
  791. package/dist/store/index.d.ts +7 -8
  792. package/dist/store/index.d.ts.map +1 -1
  793. package/dist/store/index.js +4 -16
  794. package/dist/store/index.js.map +1 -1
  795. package/dist/store/memory/digest.d.ts +15 -0
  796. package/dist/store/memory/digest.d.ts.map +1 -0
  797. package/dist/store/memory/digest.js +27 -0
  798. package/dist/store/memory/digest.js.map +1 -0
  799. package/dist/store/memory/disk.d.ts.map +1 -1
  800. package/dist/store/memory/disk.js +42 -7
  801. package/dist/store/memory/disk.js.map +1 -1
  802. package/dist/store/memory/index-file.d.ts +56 -0
  803. package/dist/store/memory/index-file.d.ts.map +1 -0
  804. package/dist/store/memory/index-file.js +92 -0
  805. package/dist/store/memory/index-file.js.map +1 -0
  806. package/dist/store/memory/index.d.ts.map +1 -1
  807. package/dist/store/memory/index.js +4 -2
  808. package/dist/store/memory/index.js.map +1 -1
  809. package/dist/store/memory/links.d.ts +15 -0
  810. package/dist/store/memory/links.d.ts.map +1 -0
  811. package/dist/store/memory/links.js +35 -0
  812. package/dist/store/memory/links.js.map +1 -0
  813. package/dist/store/memory/markdown-format.d.ts +88 -0
  814. package/dist/store/memory/markdown-format.d.ts.map +1 -0
  815. package/dist/store/memory/markdown-format.js +222 -0
  816. package/dist/store/memory/markdown-format.js.map +1 -0
  817. package/dist/store/memory/markdown.d.ts +109 -0
  818. package/dist/store/memory/markdown.d.ts.map +1 -0
  819. package/dist/store/memory/markdown.js +606 -0
  820. package/dist/store/memory/markdown.js.map +1 -0
  821. package/dist/store/memory/memory.d.ts.map +1 -1
  822. package/dist/store/memory/memory.js +17 -4
  823. package/dist/store/memory/memory.js.map +1 -1
  824. package/dist/store/memory/naming.d.ts +66 -0
  825. package/dist/store/memory/naming.d.ts.map +1 -0
  826. package/dist/store/memory/naming.js +162 -0
  827. package/dist/store/memory/naming.js.map +1 -0
  828. package/dist/store/memory/origin.d.ts +25 -0
  829. package/dist/store/memory/origin.d.ts.map +1 -0
  830. package/dist/store/memory/origin.js +26 -0
  831. package/dist/store/memory/origin.js.map +1 -0
  832. package/dist/store/session/disk.d.ts +21 -24
  833. package/dist/store/session/disk.d.ts.map +1 -1
  834. package/dist/store/session/disk.js +27 -132
  835. package/dist/store/session/disk.js.map +1 -1
  836. package/dist/store/session/index.d.ts +0 -3
  837. package/dist/store/session/index.d.ts.map +1 -1
  838. package/dist/store/session/index.js +5 -7
  839. package/dist/store/session/index.js.map +1 -1
  840. package/dist/store/session/memory.d.ts +1 -8
  841. package/dist/store/session/memory.d.ts.map +1 -1
  842. package/dist/store/session/memory.js +1 -58
  843. package/dist/store/session/memory.js.map +1 -1
  844. package/dist/store/session-claim.d.ts +30 -0
  845. package/dist/store/session-claim.d.ts.map +1 -0
  846. package/dist/store/session-claim.js +71 -0
  847. package/dist/store/session-claim.js.map +1 -0
  848. package/dist/store/session-index/fts.d.ts +60 -0
  849. package/dist/store/session-index/fts.d.ts.map +1 -0
  850. package/dist/store/session-index/fts.js +160 -0
  851. package/dist/store/session-index/fts.js.map +1 -0
  852. package/dist/store/session-index/index.d.ts +206 -0
  853. package/dist/store/session-index/index.d.ts.map +1 -0
  854. package/dist/store/session-index/index.js +22 -0
  855. package/dist/store/session-index/index.js.map +1 -0
  856. package/dist/store/session-index/rebuild.d.ts +180 -0
  857. package/dist/store/session-index/rebuild.d.ts.map +1 -0
  858. package/dist/store/session-index/rebuild.js +669 -0
  859. package/dist/store/session-index/rebuild.js.map +1 -0
  860. package/dist/store/session-index/refs.d.ts +66 -0
  861. package/dist/store/session-index/refs.d.ts.map +1 -0
  862. package/dist/store/session-index/refs.js +107 -0
  863. package/dist/store/session-index/refs.js.map +1 -0
  864. package/dist/store/session-index/scan.d.ts +42 -0
  865. package/dist/store/session-index/scan.d.ts.map +1 -0
  866. package/dist/store/session-index/scan.js +188 -0
  867. package/dist/store/session-index/scan.js.map +1 -0
  868. package/dist/store/session-index/sqlite.d.ts +76 -0
  869. package/dist/store/session-index/sqlite.d.ts.map +1 -0
  870. package/dist/store/session-index/sqlite.js +547 -0
  871. package/dist/store/session-index/sqlite.js.map +1 -0
  872. package/dist/store/session-log/chain.d.ts +111 -0
  873. package/dist/store/session-log/chain.d.ts.map +1 -0
  874. package/dist/store/session-log/chain.js +212 -0
  875. package/dist/store/session-log/chain.js.map +1 -0
  876. package/dist/store/session-log/conformance.d.ts +61 -0
  877. package/dist/store/session-log/conformance.d.ts.map +1 -0
  878. package/dist/store/session-log/conformance.js +392 -0
  879. package/dist/store/session-log/conformance.js.map +1 -0
  880. package/dist/store/session-log/core.d.ts +203 -0
  881. package/dist/store/session-log/core.d.ts.map +1 -0
  882. package/dist/store/session-log/core.js +516 -0
  883. package/dist/store/session-log/core.js.map +1 -0
  884. package/dist/store/session-log/disk.d.ts +56 -0
  885. package/dist/store/session-log/disk.d.ts.map +1 -0
  886. package/dist/store/session-log/disk.js +169 -0
  887. package/dist/store/session-log/disk.js.map +1 -0
  888. package/dist/store/session-log/fold.d.ts +115 -0
  889. package/dist/store/session-log/fold.d.ts.map +1 -0
  890. package/dist/store/session-log/fold.js +265 -0
  891. package/dist/store/session-log/fold.js.map +1 -0
  892. package/dist/store/session-log/heal.d.ts +34 -0
  893. package/dist/store/session-log/heal.d.ts.map +1 -0
  894. package/dist/store/session-log/heal.js +12 -0
  895. package/dist/store/session-log/heal.js.map +1 -0
  896. package/dist/store/session-log/held-leases.d.ts +56 -0
  897. package/dist/store/session-log/held-leases.d.ts.map +1 -0
  898. package/dist/store/session-log/held-leases.js +67 -0
  899. package/dist/store/session-log/held-leases.js.map +1 -0
  900. package/dist/store/session-log/index.d.ts +10 -0
  901. package/dist/store/session-log/index.d.ts.map +1 -0
  902. package/dist/store/session-log/index.js +16 -0
  903. package/dist/store/session-log/index.js.map +1 -0
  904. package/dist/store/session-log/lease.d.ts +126 -0
  905. package/dist/store/session-log/lease.d.ts.map +1 -0
  906. package/dist/store/session-log/lease.js +226 -0
  907. package/dist/store/session-log/lease.js.map +1 -0
  908. package/dist/store/session-log/memory.d.ts +43 -0
  909. package/dist/store/session-log/memory.d.ts.map +1 -0
  910. package/dist/store/session-log/memory.js +78 -0
  911. package/dist/store/session-log/memory.js.map +1 -0
  912. package/dist/store/session-log/spill.d.ts +109 -0
  913. package/dist/store/session-log/spill.d.ts.map +1 -0
  914. package/dist/store/session-log/spill.js +223 -0
  915. package/dist/store/session-log/spill.js.map +1 -0
  916. package/dist/store/task/context.d.ts +25 -0
  917. package/dist/store/task/context.d.ts.map +1 -0
  918. package/dist/store/task/context.js +18 -0
  919. package/dist/store/task/context.js.map +1 -0
  920. package/dist/store/task/disk.d.ts +29 -26
  921. package/dist/store/task/disk.d.ts.map +1 -1
  922. package/dist/store/task/disk.js +102 -137
  923. package/dist/store/task/disk.js.map +1 -1
  924. package/dist/store/task/memory.d.ts +2 -2
  925. package/dist/store/task/memory.d.ts.map +1 -1
  926. package/dist/store/task/memory.js +10 -6
  927. package/dist/store/task/memory.js.map +1 -1
  928. package/dist/store/topic/index.js +2 -2
  929. package/dist/store/topic/index.js.map +1 -1
  930. package/dist/store/topic/objective.d.ts.map +1 -1
  931. package/dist/store/topic/objective.js +10 -3
  932. package/dist/store/topic/objective.js.map +1 -1
  933. package/dist/store/topic/state.js +1 -1
  934. package/dist/streaming/coalesce.d.ts +3 -3
  935. package/dist/streaming/coalesce.d.ts.map +1 -1
  936. package/dist/streaming/coalesce.js +1 -1
  937. package/dist/streaming/coalesce.js.map +1 -1
  938. package/dist/telemetry/attributes.d.ts +9 -8
  939. package/dist/telemetry/attributes.d.ts.map +1 -1
  940. package/dist/telemetry/attributes.js +6 -5
  941. package/dist/telemetry/attributes.js.map +1 -1
  942. package/dist/telemetry/metrics.d.ts +2 -2
  943. package/dist/telemetry/metrics.d.ts.map +1 -1
  944. package/dist/telemetry/metrics.js +5 -5
  945. package/dist/telemetry/metrics.js.map +1 -1
  946. package/dist/telemetry/runtime-accessors.js +1 -1
  947. package/dist/telemetry/runtime-accessors.js.map +1 -1
  948. package/dist/test-support/ids.d.ts +4 -4
  949. package/dist/test-support/ids.d.ts.map +1 -1
  950. package/dist/test-support/ids.js +3 -3
  951. package/dist/test-support/ids.js.map +1 -1
  952. package/dist/testing.d.ts +4 -6
  953. package/dist/testing.d.ts.map +1 -1
  954. package/dist/testing.js +3 -5
  955. package/dist/testing.js.map +1 -1
  956. package/dist/tools/advisory/index.js +1 -1
  957. package/dist/tools/advisory/index.js.map +1 -1
  958. package/dist/tools/builtins/bash.d.ts +6 -0
  959. package/dist/tools/builtins/bash.d.ts.map +1 -1
  960. package/dist/tools/builtins/bash.js +37 -5
  961. package/dist/tools/builtins/bash.js.map +1 -1
  962. package/dist/tools/builtins/content-fingerprint.d.ts +2 -2
  963. package/dist/tools/builtins/content-fingerprint.js +2 -2
  964. package/dist/tools/builtins/edit-apply.js +1 -1
  965. package/dist/tools/builtins/edit-apply.js.map +1 -1
  966. package/dist/tools/builtins/edit.d.ts.map +1 -1
  967. package/dist/tools/builtins/edit.js +3 -0
  968. package/dist/tools/builtins/edit.js.map +1 -1
  969. package/dist/tools/builtins/glob.d.ts.map +1 -1
  970. package/dist/tools/builtins/glob.js +3 -0
  971. package/dist/tools/builtins/glob.js.map +1 -1
  972. package/dist/tools/builtins/grep.d.ts.map +1 -1
  973. package/dist/tools/builtins/grep.js +3 -0
  974. package/dist/tools/builtins/grep.js.map +1 -1
  975. package/dist/tools/builtins/job.js +5 -5
  976. package/dist/tools/builtins/job.js.map +1 -1
  977. package/dist/tools/builtins/ls.d.ts +1 -1
  978. package/dist/tools/builtins/ls.d.ts.map +1 -1
  979. package/dist/tools/builtins/ls.js +3 -0
  980. package/dist/tools/builtins/ls.js.map +1 -1
  981. package/dist/tools/builtins/lsp.d.ts +1 -1
  982. package/dist/tools/builtins/lsp.d.ts.map +1 -1
  983. package/dist/tools/builtins/lsp.js +5 -2
  984. package/dist/tools/builtins/lsp.js.map +1 -1
  985. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  986. package/dist/tools/builtins/read-file.js +3 -0
  987. package/dist/tools/builtins/read-file.js.map +1 -1
  988. package/dist/tools/builtins/run-code.js +9 -9
  989. package/dist/tools/builtins/run-code.js.map +1 -1
  990. package/dist/tools/builtins/skill.js +3 -3
  991. package/dist/tools/builtins/skill.js.map +1 -1
  992. package/dist/tools/builtins/wait-for-job-bounds.d.ts +4 -4
  993. package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -1
  994. package/dist/tools/builtins/wait-for-job-bounds.js +2 -2
  995. package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -1
  996. package/dist/tools/builtins/wait-for-job.js +3 -3
  997. package/dist/tools/builtins/wait-for-job.js.map +1 -1
  998. package/dist/tools/builtins/web-guidance.d.ts +2 -2
  999. package/dist/tools/builtins/web-guidance.js +2 -2
  1000. package/dist/tools/builtins/web.js +3 -3
  1001. package/dist/tools/builtins/web.js.map +1 -1
  1002. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  1003. package/dist/tools/builtins/write-file.js +3 -0
  1004. package/dist/tools/builtins/write-file.js.map +1 -1
  1005. package/dist/tools/coordinator/agent.d.ts +1 -1
  1006. package/dist/tools/coordinator/agent.js +7 -7
  1007. package/dist/tools/coordinator/agent.js.map +1 -1
  1008. package/dist/tools/coordinator/ask-user-question.d.ts +10 -9
  1009. package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -1
  1010. package/dist/tools/coordinator/ask-user-question.js +9 -8
  1011. package/dist/tools/coordinator/ask-user-question.js.map +1 -1
  1012. package/dist/tools/coordinator/index.d.ts +17 -11
  1013. package/dist/tools/coordinator/index.d.ts.map +1 -1
  1014. package/dist/tools/coordinator/index.js +45 -44
  1015. package/dist/tools/coordinator/index.js.map +1 -1
  1016. package/dist/tools/coordinator/outcome.d.ts +5 -5
  1017. package/dist/tools/coordinator/outcome.js +7 -7
  1018. package/dist/tools/coordinator/outcome.js.map +1 -1
  1019. package/dist/tools/coordinator/plan-dependencies.js +1 -1
  1020. package/dist/tools/coordinator/plan-dependencies.js.map +1 -1
  1021. package/dist/tools/coordinator/wait-with-idle-bound.d.ts +4 -4
  1022. package/dist/tools/coordinator/wait-with-idle-bound.d.ts.map +1 -1
  1023. package/dist/tools/coordinator/wait-with-idle-bound.js +2 -2
  1024. package/dist/tools/coordinator/wait-with-idle-bound.js.map +1 -1
  1025. package/dist/tools/defineTool.d.ts +5 -1
  1026. package/dist/tools/defineTool.d.ts.map +1 -1
  1027. package/dist/tools/defineTool.js +4 -0
  1028. package/dist/tools/defineTool.js.map +1 -1
  1029. package/dist/tools/env-scrub.d.ts +1 -1
  1030. package/dist/tools/env-scrub.js +1 -1
  1031. package/dist/tools/goal/index.d.ts +10 -6
  1032. package/dist/tools/goal/index.d.ts.map +1 -1
  1033. package/dist/tools/goal/index.js +9 -9
  1034. package/dist/tools/goal/index.js.map +1 -1
  1035. package/dist/tools/memory/fields.d.ts +8 -0
  1036. package/dist/tools/memory/fields.d.ts.map +1 -0
  1037. package/dist/tools/memory/fields.js +22 -0
  1038. package/dist/tools/memory/fields.js.map +1 -0
  1039. package/dist/tools/memory/read.d.ts.map +1 -1
  1040. package/dist/tools/memory/read.js +60 -7
  1041. package/dist/tools/memory/read.js.map +1 -1
  1042. package/dist/tools/memory/resolve.d.ts +21 -0
  1043. package/dist/tools/memory/resolve.d.ts.map +1 -0
  1044. package/dist/tools/memory/resolve.js +23 -0
  1045. package/dist/tools/memory/resolve.js.map +1 -0
  1046. package/dist/tools/memory/save.d.ts.map +1 -1
  1047. package/dist/tools/memory/save.js +57 -18
  1048. package/dist/tools/memory/save.js.map +1 -1
  1049. package/dist/tools/memory/search.d.ts.map +1 -1
  1050. package/dist/tools/memory/search.js +9 -2
  1051. package/dist/tools/memory/search.js.map +1 -1
  1052. package/dist/tools/memory/update.d.ts.map +1 -1
  1053. package/dist/tools/memory/update.js +45 -7
  1054. package/dist/tools/memory/update.js.map +1 -1
  1055. package/dist/tools/paths.d.ts +29 -3
  1056. package/dist/tools/paths.d.ts.map +1 -1
  1057. package/dist/tools/paths.js +81 -23
  1058. package/dist/tools/paths.js.map +1 -1
  1059. package/dist/tools/posix-path.js +1 -1
  1060. package/dist/tools/posix-path.js.map +1 -1
  1061. package/dist/tools/resident-history.d.ts +1 -1
  1062. package/dist/tools/resident-history.js +1 -1
  1063. package/dist/tools/resident-tool-evidence.d.ts +1 -1
  1064. package/dist/tools/resident-tool-evidence.d.ts.map +1 -1
  1065. package/dist/tools/resident-tool-evidence.js +1 -1
  1066. package/dist/tools/resident-tool-evidence.js.map +1 -1
  1067. package/dist/tools/task/create.d.ts +2 -2
  1068. package/dist/tools/task/create.d.ts.map +1 -1
  1069. package/dist/tools/task/create.js +3 -2
  1070. package/dist/tools/task/create.js.map +1 -1
  1071. package/dist/tools/task/index.d.ts +16 -2
  1072. package/dist/tools/task/index.d.ts.map +1 -1
  1073. package/dist/tools/task/index.js +4 -3
  1074. package/dist/tools/task/index.js.map +1 -1
  1075. package/dist/tools/task/list.d.ts +4 -2
  1076. package/dist/tools/task/list.d.ts.map +1 -1
  1077. package/dist/tools/task/list.js +8 -4
  1078. package/dist/tools/task/list.js.map +1 -1
  1079. package/dist/turn/LimitChecker.d.ts +30 -0
  1080. package/dist/turn/LimitChecker.d.ts.map +1 -0
  1081. package/dist/turn/LimitChecker.js +57 -0
  1082. package/dist/turn/LimitChecker.js.map +1 -0
  1083. package/dist/turn/command-gate.d.ts +107 -0
  1084. package/dist/turn/command-gate.d.ts.map +1 -0
  1085. package/dist/turn/command-gate.js +221 -0
  1086. package/dist/turn/command-gate.js.map +1 -0
  1087. package/dist/turn/drain.d.ts +138 -0
  1088. package/dist/turn/drain.d.ts.map +1 -0
  1089. package/dist/turn/drain.js +209 -0
  1090. package/dist/turn/drain.js.map +1 -0
  1091. package/dist/turn/evidence-query.d.ts +41 -0
  1092. package/dist/turn/evidence-query.d.ts.map +1 -0
  1093. package/dist/turn/evidence-query.js +270 -0
  1094. package/dist/turn/evidence-query.js.map +1 -0
  1095. package/dist/turn/evidence-recall.d.ts +102 -0
  1096. package/dist/turn/evidence-recall.d.ts.map +1 -0
  1097. package/dist/turn/evidence-recall.js +635 -0
  1098. package/dist/turn/evidence-recall.js.map +1 -0
  1099. package/dist/turn/index.d.ts +17 -0
  1100. package/dist/turn/index.d.ts.map +1 -0
  1101. package/dist/turn/index.js +9 -0
  1102. package/dist/turn/index.js.map +1 -0
  1103. package/dist/turn/json-claim-verifier.d.ts +83 -0
  1104. package/dist/turn/json-claim-verifier.d.ts.map +1 -0
  1105. package/dist/turn/json-claim-verifier.js +200 -0
  1106. package/dist/turn/json-claim-verifier.js.map +1 -0
  1107. package/dist/turn/memory-promoter.d.ts +43 -0
  1108. package/dist/turn/memory-promoter.d.ts.map +1 -0
  1109. package/dist/turn/memory-promoter.js +111 -0
  1110. package/dist/turn/memory-promoter.js.map +1 -0
  1111. package/dist/turn/memory-recall.d.ts +33 -0
  1112. package/dist/turn/memory-recall.d.ts.map +1 -0
  1113. package/dist/turn/memory-recall.js +248 -0
  1114. package/dist/turn/memory-recall.js.map +1 -0
  1115. package/dist/turn/preparation-context-error.d.ts.map +1 -0
  1116. package/dist/turn/preparation-context-error.js.map +1 -0
  1117. package/dist/turn/reporter.d.ts +8 -0
  1118. package/dist/turn/reporter.d.ts.map +1 -0
  1119. package/dist/turn/reporter.js +420 -0
  1120. package/dist/turn/reporter.js.map +1 -0
  1121. package/dist/turn/workspace-fingerprint.d.ts.map +1 -0
  1122. package/dist/turn/workspace-fingerprint.js.map +1 -0
  1123. package/dist/types/activity/index.d.ts +2 -2
  1124. package/dist/types/activity/index.d.ts.map +1 -1
  1125. package/dist/types/advisory/config.d.ts +7 -7
  1126. package/dist/types/advisory/config.d.ts.map +1 -1
  1127. package/dist/types/agent/base.d.ts +71 -44
  1128. package/dist/types/agent/base.d.ts.map +1 -1
  1129. package/dist/types/agent/core.d.ts +10 -10
  1130. package/dist/types/agent/core.d.ts.map +1 -1
  1131. package/dist/types/agent/delegate.d.ts +2 -2
  1132. package/dist/types/agent/factory.d.ts +6 -4
  1133. package/dist/types/agent/factory.d.ts.map +1 -1
  1134. package/dist/types/agent/manager.d.ts +6 -6
  1135. package/dist/types/agent/manager.d.ts.map +1 -1
  1136. package/dist/types/agent/pipeline.d.ts +5 -4
  1137. package/dist/types/agent/pipeline.d.ts.map +1 -1
  1138. package/dist/types/agent/reactive.d.ts +11 -10
  1139. package/dist/types/agent/reactive.d.ts.map +1 -1
  1140. package/dist/types/agent/router.d.ts +1 -1
  1141. package/dist/types/agent/scheduler.d.ts +27 -11
  1142. package/dist/types/agent/scheduler.d.ts.map +1 -1
  1143. package/dist/types/agent/supervisor.d.ts +13 -13
  1144. package/dist/types/agent/task.d.ts +48 -12
  1145. package/dist/types/agent/task.d.ts.map +1 -1
  1146. package/dist/types/agent/working-memory.d.ts +5 -4
  1147. package/dist/types/agent/working-memory.d.ts.map +1 -1
  1148. package/dist/types/authorization/index.d.ts +6 -6
  1149. package/dist/types/bidi/index.d.ts +21 -12
  1150. package/dist/types/bidi/index.d.ts.map +1 -1
  1151. package/dist/types/bus/index.d.ts +34 -28
  1152. package/dist/types/bus/index.d.ts.map +1 -1
  1153. package/dist/types/code-navigation/index.d.ts +1 -1
  1154. package/dist/types/common/index.d.ts +10 -18
  1155. package/dist/types/common/index.d.ts.map +1 -1
  1156. package/dist/types/common/index.js +3 -2
  1157. package/dist/types/common/index.js.map +1 -1
  1158. package/dist/types/connector/core.d.ts +2 -2
  1159. package/dist/types/connector/definition.d.ts +1 -1
  1160. package/dist/types/connector/mcp.d.ts +1 -1
  1161. package/dist/types/errors/catalog.js +4 -4
  1162. package/dist/types/errors/catalog.js.map +1 -1
  1163. package/dist/types/errors/index.d.ts +5 -5
  1164. package/dist/types/errors/index.d.ts.map +1 -1
  1165. package/dist/types/guardrail/index.d.ts +12 -10
  1166. package/dist/types/guardrail/index.d.ts.map +1 -1
  1167. package/dist/types/hitl/index.d.ts +60 -117
  1168. package/dist/types/hitl/index.d.ts.map +1 -1
  1169. package/dist/types/hitl/index.js +1 -1
  1170. package/dist/types/hitl/index.js.map +1 -1
  1171. package/dist/types/hitl/policy.d.ts +8 -6
  1172. package/dist/types/hitl/policy.d.ts.map +1 -1
  1173. package/dist/types/ids/brand.d.ts +10 -3
  1174. package/dist/types/ids/brand.d.ts.map +1 -1
  1175. package/dist/types/ids/brand.js.map +1 -1
  1176. package/dist/types/ids/index.d.ts +10 -4
  1177. package/dist/types/ids/index.d.ts.map +1 -1
  1178. package/dist/types/ids/index.js.map +1 -1
  1179. package/dist/types/memory/index.d.ts +35 -0
  1180. package/dist/types/memory/index.d.ts.map +1 -1
  1181. package/dist/types/memory/index.js +17 -0
  1182. package/dist/types/memory/index.js.map +1 -1
  1183. package/dist/types/message/index.d.ts +4 -4
  1184. package/dist/types/plan/index.d.ts +5 -3
  1185. package/dist/types/plan/index.d.ts.map +1 -1
  1186. package/dist/types/plugin/index.d.ts +27 -19
  1187. package/dist/types/plugin/index.d.ts.map +1 -1
  1188. package/dist/types/plugin/index.js +16 -3
  1189. package/dist/types/plugin/index.js.map +1 -1
  1190. package/dist/types/probe/event-kind.d.ts +3 -3
  1191. package/dist/types/probe/event-kind.d.ts.map +1 -1
  1192. package/dist/types/probe/registry.d.ts +3 -2
  1193. package/dist/types/probe/registry.d.ts.map +1 -1
  1194. package/dist/types/project/entity.d.ts +3 -3
  1195. package/dist/types/provider/config.d.ts +3 -3
  1196. package/dist/types/provider/error.d.ts +1 -1
  1197. package/dist/types/provider/errors.d.ts +2 -2
  1198. package/dist/types/provider/errors.js +2 -2
  1199. package/dist/types/provider/errors.js.map +1 -1
  1200. package/dist/types/provider/interface.d.ts +5 -5
  1201. package/dist/types/provider/model.d.ts +26 -2
  1202. package/dist/types/provider/model.d.ts.map +1 -1
  1203. package/dist/types/router/task-router.d.ts +1 -1
  1204. package/dist/types/sandbox/index.d.ts +14 -14
  1205. package/dist/types/sandbox/index.d.ts.map +1 -1
  1206. package/dist/types/sandbox/index.js +4 -4
  1207. package/dist/types/session/answer-review.d.ts +80 -0
  1208. package/dist/types/session/answer-review.d.ts.map +1 -0
  1209. package/dist/types/session/answer-review.js.map +1 -0
  1210. package/dist/types/session/audit.d.ts +153 -0
  1211. package/dist/types/session/audit.d.ts.map +1 -0
  1212. package/dist/types/session/audit.js +35 -0
  1213. package/dist/types/session/audit.js.map +1 -0
  1214. package/dist/types/session/cancel-cause.d.ts +49 -0
  1215. package/dist/types/session/cancel-cause.d.ts.map +1 -0
  1216. package/dist/types/session/cancel-cause.js +39 -0
  1217. package/dist/types/session/cancel-cause.js.map +1 -0
  1218. package/dist/types/session/checkpoint.d.ts +325 -0
  1219. package/dist/types/session/checkpoint.d.ts.map +1 -0
  1220. package/dist/types/session/checkpoint.js +100 -0
  1221. package/dist/types/session/checkpoint.js.map +1 -0
  1222. package/dist/types/session/config.d.ts +199 -0
  1223. package/dist/types/session/config.d.ts.map +1 -0
  1224. package/dist/types/session/config.js.map +1 -0
  1225. package/dist/types/session/derive-status.d.ts +28 -0
  1226. package/dist/types/session/derive-status.d.ts.map +1 -0
  1227. package/dist/types/session/derive-status.js +49 -0
  1228. package/dist/types/session/derive-status.js.map +1 -0
  1229. package/dist/types/session/durable.d.ts +142 -0
  1230. package/dist/types/session/durable.d.ts.map +1 -0
  1231. package/dist/types/session/durable.js +11 -0
  1232. package/dist/types/session/durable.js.map +1 -0
  1233. package/dist/types/session/entity.d.ts +1 -1
  1234. package/dist/types/session/events.d.ts +1139 -0
  1235. package/dist/types/session/events.d.ts.map +1 -0
  1236. package/dist/types/session/events.js +15 -0
  1237. package/dist/types/session/events.js.map +1 -0
  1238. package/dist/types/session/fork.d.ts +45 -0
  1239. package/dist/types/session/fork.d.ts.map +1 -0
  1240. package/dist/types/session/fork.js +15 -0
  1241. package/dist/types/session/fork.js.map +1 -0
  1242. package/dist/types/session/ids.d.ts +1 -1
  1243. package/dist/types/session/ids.d.ts.map +1 -1
  1244. package/dist/types/session/index.d.ts +20 -1
  1245. package/dist/types/session/index.d.ts.map +1 -1
  1246. package/dist/types/session/index.js +22 -4
  1247. package/dist/types/session/index.js.map +1 -1
  1248. package/dist/types/session/lineage.d.ts +15 -0
  1249. package/dist/types/session/lineage.d.ts.map +1 -0
  1250. package/dist/types/session/lineage.js.map +1 -0
  1251. package/dist/types/session/log-cursor.d.ts +57 -0
  1252. package/dist/types/session/log-cursor.d.ts.map +1 -0
  1253. package/dist/types/session/log-cursor.js +34 -0
  1254. package/dist/types/session/log-cursor.js.map +1 -0
  1255. package/dist/types/session/memory-promotion.d.ts +91 -0
  1256. package/dist/types/session/memory-promotion.d.ts.map +1 -0
  1257. package/dist/types/session/memory-promotion.js +39 -0
  1258. package/dist/types/session/memory-promotion.js.map +1 -0
  1259. package/dist/types/session/messages.d.ts +1 -1
  1260. package/dist/types/session/messages.js +1 -1
  1261. package/dist/types/session/prepare-step.d.ts +278 -0
  1262. package/dist/types/session/prepare-step.d.ts.map +1 -0
  1263. package/dist/types/session/prepare-step.js.map +1 -0
  1264. package/dist/types/session/records.d.ts +5597 -0
  1265. package/dist/types/session/records.d.ts.map +1 -0
  1266. package/dist/types/session/records.js +721 -0
  1267. package/dist/types/session/records.js.map +1 -0
  1268. package/dist/types/session/step.d.ts +195 -0
  1269. package/dist/types/session/step.d.ts.map +1 -0
  1270. package/dist/types/session/step.js +26 -0
  1271. package/dist/types/session/step.js.map +1 -0
  1272. package/dist/types/session/stop-reason.d.ts +67 -0
  1273. package/dist/types/session/stop-reason.d.ts.map +1 -0
  1274. package/dist/types/session/stop-reason.js.map +1 -0
  1275. package/dist/types/session/store.d.ts +2 -43
  1276. package/dist/types/session/store.d.ts.map +1 -1
  1277. package/dist/types/session/tool-execution.d.ts +34 -0
  1278. package/dist/types/session/tool-execution.d.ts.map +1 -0
  1279. package/dist/types/session/tool-execution.js +11 -0
  1280. package/dist/types/session/tool-execution.js.map +1 -0
  1281. package/dist/types/session/turn-state.d.ts +74 -0
  1282. package/dist/types/session/turn-state.d.ts.map +1 -0
  1283. package/dist/types/session/turn-state.js +59 -0
  1284. package/dist/types/session/turn-state.js.map +1 -0
  1285. package/dist/types/session/turn.d.ts +215 -0
  1286. package/dist/types/session/turn.d.ts.map +1 -0
  1287. package/dist/types/session/turn.js +44 -0
  1288. package/dist/types/session/turn.js.map +1 -0
  1289. package/dist/types/structured-output/index.d.ts +2 -2
  1290. package/dist/types/structured-output/index.d.ts.map +1 -1
  1291. package/dist/types/summary/deliverable.d.ts +4 -4
  1292. package/dist/types/summary/deliverable.d.ts.map +1 -1
  1293. package/dist/types/task/index.d.ts +8 -4
  1294. package/dist/types/task/index.d.ts.map +1 -1
  1295. package/dist/types/tool/index.d.ts +73 -26
  1296. package/dist/types/tool/index.d.ts.map +1 -1
  1297. package/dist/types/tool/index.js.map +1 -1
  1298. package/dist/types/topic/entity.d.ts +6 -6
  1299. package/dist/types/topic/objective.d.ts +10 -5
  1300. package/dist/types/topic/objective.d.ts.map +1 -1
  1301. package/dist/types/topic/objective.js.map +1 -1
  1302. package/dist/types/topic/state.d.ts +4 -4
  1303. package/dist/types/topic/store.d.ts +1 -1
  1304. package/dist/types/topic/store.js +1 -1
  1305. package/dist/types/workspace/index.d.ts +1 -1
  1306. package/dist/types/workspace/index.d.ts.map +1 -1
  1307. package/dist/types/workspace/index.js +1 -1
  1308. package/dist/types/workspace/index.js.map +1 -1
  1309. package/dist/types/workspace/ref.d.ts +3 -3
  1310. package/dist/types/workspace/shared-session.d.ts +61 -0
  1311. package/dist/types/workspace/shared-session.d.ts.map +1 -0
  1312. package/dist/types/workspace/shared-session.js +2 -0
  1313. package/dist/types/workspace/shared-session.js.map +1 -0
  1314. package/dist/utils/abort.js +4 -4
  1315. package/dist/utils/abort.js.map +1 -1
  1316. package/dist/utils/atomic-write.d.ts +29 -1
  1317. package/dist/utils/atomic-write.d.ts.map +1 -1
  1318. package/dist/utils/atomic-write.js +60 -4
  1319. package/dist/utils/atomic-write.js.map +1 -1
  1320. package/dist/utils/cost.d.ts +3 -3
  1321. package/dist/utils/cost.d.ts.map +1 -1
  1322. package/dist/utils/cost.js +11 -12
  1323. package/dist/utils/cost.js.map +1 -1
  1324. package/dist/utils/env.d.ts +1 -1
  1325. package/dist/utils/env.js +1 -1
  1326. package/dist/utils/id.d.ts +9 -8
  1327. package/dist/utils/id.d.ts.map +1 -1
  1328. package/dist/utils/id.js +20 -13
  1329. package/dist/utils/id.js.map +1 -1
  1330. package/dist/utils/log/create-logger.js +1 -1
  1331. package/dist/utils/log/create-logger.js.map +1 -1
  1332. package/dist/utils/log/types.js +1 -1
  1333. package/dist/utils/log/types.js.map +1 -1
  1334. package/dist/utils/shell-compress.js +2 -2
  1335. package/dist/utils/shell-compress.js.map +1 -1
  1336. package/dist/utils/uuidv7.d.ts +33 -0
  1337. package/dist/utils/uuidv7.d.ts.map +1 -0
  1338. package/dist/utils/uuidv7.js +70 -0
  1339. package/dist/utils/uuidv7.js.map +1 -0
  1340. package/dist/vault/instrumentation.d.ts +5 -2
  1341. package/dist/vault/instrumentation.d.ts.map +1 -1
  1342. package/dist/vault/instrumentation.js +12 -6
  1343. package/dist/vault/instrumentation.js.map +1 -1
  1344. package/package.json +1 -1
  1345. package/src/advisory/budget.ts +3 -3
  1346. package/src/advisory/context.ts +9 -9
  1347. package/src/advisory/evaluator.ts +2 -2
  1348. package/src/advisory/parse.ts +1 -1
  1349. package/src/agents/AbstractAgent.ts +74 -50
  1350. package/src/agents/PipelineAgent.ts +91 -26
  1351. package/src/agents/ReactiveAgent.ts +35 -29
  1352. package/src/agents/RouterAgent.ts +32 -44
  1353. package/src/agents/SupervisorAgent.ts +55 -41
  1354. package/src/agents/budget.ts +73 -16
  1355. package/src/agents/defineAgent.ts +7 -3
  1356. package/src/agents/handle.ts +17 -19
  1357. package/src/agents/lock.ts +4 -4
  1358. package/src/agents/runAgent.ts +96 -38
  1359. package/src/agents/storage.ts +36 -0
  1360. package/src/authorization/command-line.ts +1 -1
  1361. package/src/authorization/gate.ts +1 -1
  1362. package/src/authorization/permission-presets.ts +4 -4
  1363. package/src/bridge/a2a/client.ts +2 -2
  1364. package/src/bridge/a2a/context.ts +46 -0
  1365. package/src/bridge/a2a/index.ts +12 -5
  1366. package/src/bridge/a2a/mapper.ts +48 -38
  1367. package/src/bridge/a2a/task.ts +91 -37
  1368. package/src/bridge/acp/permission.ts +2 -2
  1369. package/src/bridge/acp/server.ts +45 -11
  1370. package/src/bridge/acp/update.ts +9 -9
  1371. package/src/bridge/external-session.ts +82 -0
  1372. package/src/bridge/sse/index.ts +1 -1
  1373. package/src/bridge/sse/mapper.ts +116 -145
  1374. package/src/bus/breaker.ts +30 -29
  1375. package/src/bus/index.ts +7 -7
  1376. package/src/bus/lock.ts +7 -7
  1377. package/src/bus/ownership.ts +8 -8
  1378. package/src/compaction/consolidation.ts +61 -15
  1379. package/src/compaction/context-window.ts +4 -4
  1380. package/src/compaction/index.ts +2 -2
  1381. package/src/compaction/manager.ts +4 -4
  1382. package/src/compaction/manual.ts +5 -5
  1383. package/src/compaction/plan.ts +8 -8
  1384. package/src/compaction/reducer.ts +8 -8
  1385. package/src/compaction/retention.ts +2 -2
  1386. package/src/compaction/salience/bm25.ts +2 -2
  1387. package/src/compaction/salience/goal.ts +3 -3
  1388. package/src/compaction/salience/minhash.ts +1 -1
  1389. package/src/compaction/salience/score.ts +3 -3
  1390. package/src/compaction/salience/tokenize.ts +1 -1
  1391. package/src/compaction/verifier.ts +7 -7
  1392. package/src/compaction/wire.ts +1 -1
  1393. package/src/config/registry.ts +4 -4
  1394. package/src/config/runtime.ts +3 -3
  1395. package/src/connector/http-operation.ts +1 -1
  1396. package/src/connector/mcp/adapter.ts +1 -1
  1397. package/src/connector/mcp/client.ts +1 -1
  1398. package/src/connector/mcp/discovery.ts +2 -2
  1399. package/src/connector/mcp/policy.ts +1 -1
  1400. package/src/connector/mcp/prompt-adapter.ts +3 -3
  1401. package/src/constants/a2a/index.ts +10 -3
  1402. package/src/constants/continuation.ts +1 -1
  1403. package/src/constants/index.ts +0 -1
  1404. package/src/constants/limits.ts +2 -2
  1405. package/src/constants/telemetry/index.ts +15 -12
  1406. package/src/constants/tools/index.ts +2 -2
  1407. package/src/contracts/api.ts +11 -202
  1408. package/src/contracts/index.ts +8 -15
  1409. package/src/contracts/schemas.ts +6 -39
  1410. package/src/contracts/session/api.ts +150 -0
  1411. package/src/contracts/session/index.ts +29 -0
  1412. package/src/contracts/session/schemas.ts +60 -0
  1413. package/src/contracts/session/turn-status.ts +83 -0
  1414. package/src/contracts/session/turn.ts +67 -0
  1415. package/src/directory/derive-supervisor.ts +2 -2
  1416. package/src/directory/derive.ts +4 -4
  1417. package/src/directory/index.ts +2 -2
  1418. package/src/directory/load.ts +2 -2
  1419. package/src/directory/types.ts +2 -2
  1420. package/src/eval/experiment.ts +23 -23
  1421. package/src/eval/from-turn.ts +50 -0
  1422. package/src/eval/harness-verification.ts +7 -7
  1423. package/src/eval/index.ts +2 -2
  1424. package/src/eval/judge.ts +10 -10
  1425. package/src/eval/scorers.ts +23 -23
  1426. package/src/eval/types.ts +12 -12
  1427. package/src/eval/uncertainty.ts +2 -2
  1428. package/src/execution/code-runtime/types.ts +4 -4
  1429. package/src/execution/code-runtime/worker.ts +1 -1
  1430. package/src/invariants/index.ts +2 -2
  1431. package/src/manager/agent/child-session.ts +120 -0
  1432. package/src/manager/agent/lifecycle.ts +422 -102
  1433. package/src/manager/index.ts +1 -2
  1434. package/src/manager/plan/lifecycle.ts +16 -10
  1435. package/src/manager/resident/consumption.ts +8 -6
  1436. package/src/manager/resident/evidence-recall.ts +14 -14
  1437. package/src/manager/resident/host.ts +2 -2
  1438. package/src/manager/resident/learning-cycle.ts +5 -3
  1439. package/src/manager/resident/learning-observation.ts +9 -4
  1440. package/src/manager/resident/learning-store.ts +46 -16
  1441. package/src/manager/resident/tool-evidence.ts +38 -31
  1442. package/src/manager/session/turn-recorder.ts +1291 -0
  1443. package/src/plugin/lifecycle.ts +20 -13
  1444. package/src/plugin/shell-hook.ts +64 -25
  1445. package/src/pricing/index.ts +5 -5
  1446. package/src/pricing/rates.source.json +5 -5
  1447. package/src/probe/context.ts +5 -3
  1448. package/src/probe/registry.ts +1 -1
  1449. package/src/prompt/coding-agent-doctrine.ts +1 -1
  1450. package/src/prompt/contributions.ts +28 -6
  1451. package/src/prompt/resident-learning.ts +2 -2
  1452. package/src/provider/collect-chat-completion.ts +3 -3
  1453. package/src/provider/conformance.ts +21 -6
  1454. package/src/provider/errors.ts +2 -2
  1455. package/src/provider/fallback.ts +8 -8
  1456. package/src/provider/idle-timeout.ts +4 -4
  1457. package/src/provider/instrumentation.ts +14 -7
  1458. package/src/provider/mock.ts +1 -1
  1459. package/src/provider/retry.ts +7 -7
  1460. package/src/provider/stream-text.ts +1 -1
  1461. package/src/provider/thinking-support.ts +2 -2
  1462. package/src/provider/token-budget.ts +2 -2
  1463. package/src/public-runtime.ts +213 -141
  1464. package/src/public-tools.ts +14 -7
  1465. package/src/public-types.ts +71 -59
  1466. package/src/rag/embedding.ts +1 -1
  1467. package/src/read-model/index.ts +2 -2
  1468. package/src/read-model/registry.ts +11 -11
  1469. package/src/read-model/session-status.ts +87 -0
  1470. package/src/registry/command/kernel-commands.ts +10 -10
  1471. package/src/registry/tool/dialect.ts +1 -1
  1472. package/src/registry/tool/execute.ts +20 -7
  1473. package/src/registry/tool/portable.ts +1 -1
  1474. package/src/registry/tool/presentation.ts +1 -1
  1475. package/src/registry/tool/schema.ts +1 -1
  1476. package/src/registry/tool/screen.ts +3 -3
  1477. package/src/runtime/bidi/index.ts +2 -2
  1478. package/src/runtime/bidi/session.ts +45 -34
  1479. package/src/runtime/jobs/awaited-jobs.ts +13 -13
  1480. package/src/runtime/jobs/registry.ts +11 -11
  1481. package/src/runtime/query/abandon-turn.ts +110 -0
  1482. package/src/runtime/query/approval-policy.ts +13 -13
  1483. package/src/runtime/query/callback-inference.ts +16 -10
  1484. package/src/runtime/query/cancelled-before-start.ts +96 -79
  1485. package/src/runtime/query/checkpoint.ts +519 -420
  1486. package/src/runtime/query/compact-session.ts +92 -0
  1487. package/src/runtime/query/context.ts +80 -136
  1488. package/src/runtime/query/events.ts +159 -126
  1489. package/src/runtime/query/executor/tool-call-admission.ts +6 -5
  1490. package/src/runtime/query/executor.ts +206 -111
  1491. package/src/runtime/query/file-evidence-seed.ts +2 -2
  1492. package/src/runtime/query/finalize-turn.ts +209 -0
  1493. package/src/runtime/query/fork/list.ts +20 -0
  1494. package/src/runtime/query/fork/mutate.ts +82 -0
  1495. package/src/runtime/query/fork/prepare.ts +92 -0
  1496. package/src/runtime/query/guard.ts +22 -22
  1497. package/src/runtime/query/guardrail-presets.ts +12 -12
  1498. package/src/runtime/query/guardrails.ts +11 -11
  1499. package/src/runtime/query/index.ts +1607 -1533
  1500. package/src/runtime/query/iteration/index.ts +304 -253
  1501. package/src/runtime/query/iteration/outstanding-work.ts +65 -65
  1502. package/src/runtime/query/iteration/phases/advisory.ts +16 -16
  1503. package/src/runtime/query/iteration/phases/checkpoint.ts +26 -10
  1504. package/src/runtime/query/iteration/phases/compaction.ts +74 -72
  1505. package/src/runtime/query/iteration/phases/context.ts +57 -60
  1506. package/src/runtime/query/iteration/phases/plan.ts +9 -6
  1507. package/src/runtime/query/iteration/phases/tool-review.ts +141 -27
  1508. package/src/runtime/query/iteration/phases/working-memory.ts +57 -22
  1509. package/src/runtime/query/iteration/step-context.ts +17 -0
  1510. package/src/runtime/query/iteration/step-shaping.ts +21 -24
  1511. package/src/runtime/query/iteration/stream-turn.ts +36 -32
  1512. package/src/runtime/query/plugin-hooks.ts +1 -1
  1513. package/src/runtime/query/prepare-turn.ts +932 -0
  1514. package/src/runtime/query/project-instructions.ts +5 -4
  1515. package/src/runtime/query/prompt-cache.ts +1 -1
  1516. package/src/runtime/query/prompt.ts +5 -5
  1517. package/src/runtime/query/question-park.ts +7 -7
  1518. package/src/runtime/query/release-turn.ts +157 -0
  1519. package/src/runtime/query/repeat-call.ts +7 -7
  1520. package/src/runtime/query/result.ts +123 -131
  1521. package/src/runtime/query/resume-pending.ts +101 -44
  1522. package/src/runtime/query/resume-session.ts +153 -0
  1523. package/src/runtime/query/review-policy.ts +147 -19
  1524. package/src/runtime/query/sandbox-lifecycle.ts +5 -5
  1525. package/src/runtime/query/session-storage.ts +302 -0
  1526. package/src/runtime/query/steering.ts +17 -4
  1527. package/src/runtime/query/token-budget.ts +59 -93
  1528. package/src/runtime/query/tool-call-budget.ts +14 -14
  1529. package/src/runtime/query/tool-executions.ts +77 -0
  1530. package/src/runtime/query/tool-grants.ts +3 -3
  1531. package/src/runtime/query/tool-output-budget.ts +4 -4
  1532. package/src/runtime/query/tool-pause.ts +8 -6
  1533. package/src/runtime/query/tooling.ts +22 -14
  1534. package/src/runtime/query/turn-state.ts +153 -0
  1535. package/src/sandbox/isolation.ts +2 -2
  1536. package/src/sandbox/provider/local.ts +8 -8
  1537. package/src/scheduler/completion-inbox.ts +36 -36
  1538. package/src/scheduler/delegating.ts +27 -13
  1539. package/src/scheduler/local.ts +49 -21
  1540. package/src/session/events/index.ts +10 -14
  1541. package/src/session/handoff/broadcast.ts +7 -7
  1542. package/src/session/handoff/events.ts +1 -1
  1543. package/src/session/handoff/index.ts +1 -1
  1544. package/src/session/handoff/single.ts +21 -21
  1545. package/src/session/handoff/version.ts +11 -7
  1546. package/src/session/home.ts +66 -0
  1547. package/src/session/index.ts +1 -0
  1548. package/src/session/log-hash.ts +115 -0
  1549. package/src/session/messages.ts +39 -0
  1550. package/src/session/paths.ts +449 -0
  1551. package/src/session/retention/archive.ts +13 -5
  1552. package/src/session/status/derive.ts +21 -21
  1553. package/src/session/workspace/git-worktree.ts +31 -2
  1554. package/src/session/workspace/index.ts +5 -8
  1555. package/src/session/workspace/shared-session.ts +354 -0
  1556. package/src/session-query/index.ts +152 -0
  1557. package/src/skills/registry.ts +1 -1
  1558. package/src/store/activity/memory.ts +5 -5
  1559. package/src/store/attachment/index.ts +5 -5
  1560. package/src/store/budget/disk.ts +243 -0
  1561. package/src/store/budget/index.ts +24 -0
  1562. package/src/store/budget/ledger.ts +836 -0
  1563. package/src/store/budget/memory.ts +39 -0
  1564. package/src/store/checkpoint/contract.ts +225 -0
  1565. package/src/store/checkpoint/disk.ts +209 -0
  1566. package/src/store/checkpoint/index.ts +22 -0
  1567. package/src/store/checkpoint/memory.ts +112 -0
  1568. package/src/store/checkpoint/prune.ts +93 -0
  1569. package/src/store/config/index.ts +1 -1
  1570. package/src/store/evidence/disk.ts +185 -81
  1571. package/src/store/evidence/index-page.ts +67 -140
  1572. package/src/store/evidence/source-text.ts +23 -28
  1573. package/src/store/evidence/types.ts +51 -41
  1574. package/src/store/feedback/conformance.ts +37 -35
  1575. package/src/store/feedback/disk.ts +61 -63
  1576. package/src/store/feedback/index.ts +1 -1
  1577. package/src/store/feedback/memory.ts +0 -0
  1578. package/src/store/feedback/types.ts +14 -13
  1579. package/src/store/index.ts +24 -28
  1580. package/src/store/memory/digest.ts +35 -0
  1581. package/src/store/memory/disk.ts +66 -20
  1582. package/src/store/memory/index-file.ts +121 -0
  1583. package/src/store/memory/index.ts +4 -2
  1584. package/src/store/memory/links.ts +37 -0
  1585. package/src/store/memory/markdown-format.ts +276 -0
  1586. package/src/store/memory/markdown.ts +741 -0
  1587. package/src/store/memory/memory.ts +39 -17
  1588. package/src/store/memory/naming.ts +195 -0
  1589. package/src/store/memory/origin.ts +35 -0
  1590. package/src/store/session/disk.ts +27 -200
  1591. package/src/store/session/index.ts +5 -9
  1592. package/src/store/session/memory.ts +1 -78
  1593. package/src/store/session-claim.ts +101 -0
  1594. package/src/store/session-index/fts.ts +215 -0
  1595. package/src/store/session-index/index.ts +253 -0
  1596. package/src/store/session-index/rebuild.ts +869 -0
  1597. package/src/store/session-index/refs.ts +164 -0
  1598. package/src/store/session-index/scan.ts +273 -0
  1599. package/src/store/session-index/sqlite.ts +772 -0
  1600. package/src/store/session-log/chain.ts +314 -0
  1601. package/src/store/session-log/conformance.ts +487 -0
  1602. package/src/store/session-log/core.ts +809 -0
  1603. package/src/store/session-log/disk.ts +217 -0
  1604. package/src/store/session-log/fold.ts +368 -0
  1605. package/src/store/session-log/heal.ts +44 -0
  1606. package/src/store/session-log/held-leases.ts +103 -0
  1607. package/src/store/session-log/index.ts +87 -0
  1608. package/src/store/session-log/lease.ts +354 -0
  1609. package/src/store/session-log/memory.ts +111 -0
  1610. package/src/store/session-log/spill.ts +311 -0
  1611. package/src/store/task/context.ts +33 -0
  1612. package/src/store/task/disk.ts +122 -141
  1613. package/src/store/task/memory.ts +14 -8
  1614. package/src/store/topic/index.ts +2 -2
  1615. package/src/store/topic/objective.ts +12 -3
  1616. package/src/store/topic/state.ts +1 -1
  1617. package/src/streaming/coalesce.ts +8 -7
  1618. package/src/telemetry/attributes.ts +10 -9
  1619. package/src/telemetry/metrics.ts +6 -6
  1620. package/src/telemetry/runtime-accessors.ts +1 -1
  1621. package/src/test-support/ids.ts +5 -6
  1622. package/src/testing.ts +11 -16
  1623. package/src/tools/advisory/index.ts +1 -1
  1624. package/src/tools/builtins/bash.ts +43 -5
  1625. package/src/tools/builtins/content-fingerprint.ts +2 -2
  1626. package/src/tools/builtins/edit-apply.ts +1 -1
  1627. package/src/tools/builtins/edit.ts +3 -0
  1628. package/src/tools/builtins/glob.ts +3 -0
  1629. package/src/tools/builtins/grep.ts +3 -0
  1630. package/src/tools/builtins/job.ts +5 -5
  1631. package/src/tools/builtins/ls.ts +3 -0
  1632. package/src/tools/builtins/lsp.ts +5 -2
  1633. package/src/tools/builtins/read-file.ts +3 -0
  1634. package/src/tools/builtins/run-code.ts +11 -11
  1635. package/src/tools/builtins/skill.ts +3 -3
  1636. package/src/tools/builtins/wait-for-job-bounds.ts +6 -6
  1637. package/src/tools/builtins/wait-for-job.ts +3 -3
  1638. package/src/tools/builtins/web-guidance.ts +2 -2
  1639. package/src/tools/builtins/web.ts +3 -3
  1640. package/src/tools/builtins/write-file.ts +3 -0
  1641. package/src/tools/coordinator/agent.ts +8 -8
  1642. package/src/tools/coordinator/ask-user-question.ts +16 -14
  1643. package/src/tools/coordinator/index.ts +64 -54
  1644. package/src/tools/coordinator/outcome.ts +7 -7
  1645. package/src/tools/coordinator/plan-dependencies.ts +1 -1
  1646. package/src/tools/coordinator/wait-with-idle-bound.ts +6 -6
  1647. package/src/tools/defineTool.ts +9 -1
  1648. package/src/tools/env-scrub.ts +1 -1
  1649. package/src/tools/goal/index.ts +16 -12
  1650. package/src/tools/memory/fields.ts +26 -0
  1651. package/src/tools/memory/read.ts +75 -8
  1652. package/src/tools/memory/resolve.ts +37 -0
  1653. package/src/tools/memory/save.ts +54 -18
  1654. package/src/tools/memory/search.ts +9 -5
  1655. package/src/tools/memory/update.ts +43 -7
  1656. package/src/tools/paths.ts +87 -27
  1657. package/src/tools/posix-path.ts +1 -1
  1658. package/src/tools/resident-history.ts +1 -1
  1659. package/src/tools/resident-tool-evidence.ts +1 -1
  1660. package/src/tools/task/create.ts +7 -3
  1661. package/src/tools/task/index.ts +20 -4
  1662. package/src/tools/task/list.ts +12 -6
  1663. package/src/turn/LimitChecker.ts +99 -0
  1664. package/src/turn/command-gate.ts +294 -0
  1665. package/src/turn/drain.ts +324 -0
  1666. package/src/turn/evidence-query.ts +333 -0
  1667. package/src/turn/evidence-recall.ts +860 -0
  1668. package/src/turn/index.ts +38 -0
  1669. package/src/turn/json-claim-verifier.ts +298 -0
  1670. package/src/turn/memory-promoter.ts +160 -0
  1671. package/src/turn/memory-recall.ts +285 -0
  1672. package/src/turn/reporter.ts +469 -0
  1673. package/src/types/activity/index.ts +2 -2
  1674. package/src/types/advisory/config.ts +7 -7
  1675. package/src/types/agent/base.ts +74 -44
  1676. package/src/types/agent/core.ts +10 -10
  1677. package/src/types/agent/delegate.ts +2 -2
  1678. package/src/types/agent/factory.ts +8 -4
  1679. package/src/types/agent/manager.ts +6 -6
  1680. package/src/types/agent/pipeline.ts +5 -4
  1681. package/src/types/agent/reactive.ts +11 -10
  1682. package/src/types/agent/router.ts +1 -1
  1683. package/src/types/agent/scheduler.ts +28 -11
  1684. package/src/types/agent/supervisor.ts +13 -13
  1685. package/src/types/agent/task.ts +53 -12
  1686. package/src/types/agent/working-memory.ts +6 -4
  1687. package/src/types/bidi/index.ts +31 -12
  1688. package/src/types/bus/index.ts +32 -26
  1689. package/src/types/code-navigation/index.ts +1 -1
  1690. package/src/types/common/index.ts +12 -26
  1691. package/src/types/connector/core.ts +2 -2
  1692. package/src/types/connector/definition.ts +1 -1
  1693. package/src/types/connector/mcp.ts +1 -1
  1694. package/src/types/errors/catalog.ts +4 -4
  1695. package/src/types/errors/index.ts +5 -5
  1696. package/src/types/guardrail/index.ts +12 -10
  1697. package/src/types/hitl/index.ts +81 -125
  1698. package/src/types/hitl/policy.ts +8 -6
  1699. package/src/types/ids/brand.ts +10 -2
  1700. package/src/types/ids/index.ts +10 -4
  1701. package/src/types/memory/index.ts +53 -0
  1702. package/src/types/message/index.ts +4 -4
  1703. package/src/types/plan/index.ts +5 -3
  1704. package/src/types/plugin/index.ts +41 -24
  1705. package/src/types/probe/event-kind.ts +3 -3
  1706. package/src/types/probe/registry.ts +3 -2
  1707. package/src/types/project/entity.ts +3 -3
  1708. package/src/types/provider/config.ts +3 -3
  1709. package/src/types/provider/error.ts +1 -1
  1710. package/src/types/provider/errors.ts +3 -3
  1711. package/src/types/provider/interface.ts +5 -5
  1712. package/src/types/provider/model.ts +26 -2
  1713. package/src/types/router/task-router.ts +1 -1
  1714. package/src/types/sandbox/index.ts +12 -12
  1715. package/src/types/session/answer-review.ts +85 -0
  1716. package/src/types/session/audit.ts +167 -0
  1717. package/src/types/session/cancel-cause.ts +60 -0
  1718. package/src/types/session/checkpoint.ts +167 -0
  1719. package/src/types/session/config.ts +212 -0
  1720. package/src/types/session/derive-status.ts +61 -0
  1721. package/src/types/session/durable.ts +150 -0
  1722. package/src/types/session/entity.ts +1 -1
  1723. package/src/types/session/events.ts +1187 -0
  1724. package/src/types/session/fork.ts +52 -0
  1725. package/src/types/session/ids.ts +1 -1
  1726. package/src/types/session/index.ts +24 -4
  1727. package/src/types/session/lineage.ts +15 -0
  1728. package/src/types/session/log-cursor.ts +69 -0
  1729. package/src/types/session/memory-promotion.ts +116 -0
  1730. package/src/types/session/messages.ts +1 -1
  1731. package/src/types/session/prepare-step.ts +299 -0
  1732. package/src/types/session/records.ts +931 -0
  1733. package/src/types/session/step.ts +214 -0
  1734. package/src/types/session/stop-reason.ts +83 -0
  1735. package/src/types/session/store.ts +5 -52
  1736. package/src/types/session/tool-execution.ts +32 -0
  1737. package/src/types/session/turn-state.ts +136 -0
  1738. package/src/types/session/turn.ts +289 -0
  1739. package/src/types/structured-output/index.ts +4 -4
  1740. package/src/types/summary/deliverable.ts +4 -4
  1741. package/src/types/task/index.ts +8 -4
  1742. package/src/types/tool/index.ts +74 -27
  1743. package/src/types/topic/entity.ts +6 -6
  1744. package/src/types/topic/objective.ts +7 -5
  1745. package/src/types/topic/state.ts +4 -4
  1746. package/src/types/topic/store.ts +1 -1
  1747. package/src/types/workspace/index.ts +8 -8
  1748. package/src/types/workspace/ref.ts +3 -3
  1749. package/src/types/workspace/shared-session.ts +65 -0
  1750. package/src/utils/abort.ts +4 -4
  1751. package/src/utils/atomic-write.ts +67 -4
  1752. package/src/utils/cost.ts +11 -12
  1753. package/src/utils/env.ts +1 -1
  1754. package/src/utils/id.ts +25 -18
  1755. package/src/utils/log/attributes.ts +2 -2
  1756. package/src/utils/log/create-logger.ts +1 -1
  1757. package/src/utils/log/types.ts +1 -1
  1758. package/src/utils/shell-compress.ts +2 -2
  1759. package/src/utils/uuidv7.ts +107 -0
  1760. package/src/vault/instrumentation.ts +21 -8
  1761. package/dist/constants/emergency.d.ts +0 -4
  1762. package/dist/constants/emergency.d.ts.map +0 -1
  1763. package/dist/constants/emergency.js +0 -4
  1764. package/dist/constants/emergency.js.map +0 -1
  1765. package/dist/contracts/run-status.d.ts +0 -17
  1766. package/dist/contracts/run-status.d.ts.map +0 -1
  1767. package/dist/contracts/run-status.js +0 -41
  1768. package/dist/contracts/run-status.js.map +0 -1
  1769. package/dist/eval/from-run.d.ts +0 -30
  1770. package/dist/eval/from-run.d.ts.map +0 -1
  1771. package/dist/eval/from-run.js +0 -46
  1772. package/dist/eval/from-run.js.map +0 -1
  1773. package/dist/manager/run/emergency.d.ts +0 -19
  1774. package/dist/manager/run/emergency.d.ts.map +0 -1
  1775. package/dist/manager/run/emergency.js +0 -122
  1776. package/dist/manager/run/emergency.js.map +0 -1
  1777. package/dist/manager/run/persistence.d.ts +0 -312
  1778. package/dist/manager/run/persistence.d.ts.map +0 -1
  1779. package/dist/manager/run/persistence.js +0 -656
  1780. package/dist/manager/run/persistence.js.map +0 -1
  1781. package/dist/read-model/run-status.d.ts +0 -43
  1782. package/dist/read-model/run-status.d.ts.map +0 -1
  1783. package/dist/read-model/run-status.js +0 -89
  1784. package/dist/read-model/run-status.js.map +0 -1
  1785. package/dist/run/LimitChecker.d.ts +0 -30
  1786. package/dist/run/LimitChecker.d.ts.map +0 -1
  1787. package/dist/run/LimitChecker.js +0 -57
  1788. package/dist/run/LimitChecker.js.map +0 -1
  1789. package/dist/run/command-gate.d.ts +0 -107
  1790. package/dist/run/command-gate.d.ts.map +0 -1
  1791. package/dist/run/command-gate.js +0 -221
  1792. package/dist/run/command-gate.js.map +0 -1
  1793. package/dist/run/drain.d.ts +0 -204
  1794. package/dist/run/drain.d.ts.map +0 -1
  1795. package/dist/run/drain.js +0 -238
  1796. package/dist/run/drain.js.map +0 -1
  1797. package/dist/run/evidence-query.d.ts +0 -41
  1798. package/dist/run/evidence-query.d.ts.map +0 -1
  1799. package/dist/run/evidence-query.js +0 -270
  1800. package/dist/run/evidence-query.js.map +0 -1
  1801. package/dist/run/evidence-recall.d.ts +0 -99
  1802. package/dist/run/evidence-recall.d.ts.map +0 -1
  1803. package/dist/run/evidence-recall.js +0 -633
  1804. package/dist/run/evidence-recall.js.map +0 -1
  1805. package/dist/run/index.d.ts +0 -19
  1806. package/dist/run/index.d.ts.map +0 -1
  1807. package/dist/run/index.js +0 -11
  1808. package/dist/run/index.js.map +0 -1
  1809. package/dist/run/json-claim-verifier.d.ts +0 -83
  1810. package/dist/run/json-claim-verifier.d.ts.map +0 -1
  1811. package/dist/run/json-claim-verifier.js +0 -200
  1812. package/dist/run/json-claim-verifier.js.map +0 -1
  1813. package/dist/run/memory-promoter.d.ts +0 -38
  1814. package/dist/run/memory-promoter.d.ts.map +0 -1
  1815. package/dist/run/memory-promoter.js +0 -109
  1816. package/dist/run/memory-promoter.js.map +0 -1
  1817. package/dist/run/memory-recall.d.ts +0 -25
  1818. package/dist/run/memory-recall.d.ts.map +0 -1
  1819. package/dist/run/memory-recall.js +0 -228
  1820. package/dist/run/memory-recall.js.map +0 -1
  1821. package/dist/run/preparation-context-error.d.ts.map +0 -1
  1822. package/dist/run/preparation-context-error.js.map +0 -1
  1823. package/dist/run/reporter.d.ts +0 -8
  1824. package/dist/run/reporter.d.ts.map +0 -1
  1825. package/dist/run/reporter.js +0 -420
  1826. package/dist/run/reporter.js.map +0 -1
  1827. package/dist/run/token-budget.d.ts +0 -116
  1828. package/dist/run/token-budget.d.ts.map +0 -1
  1829. package/dist/run/token-budget.js +0 -626
  1830. package/dist/run/token-budget.js.map +0 -1
  1831. package/dist/run/workspace-fingerprint.d.ts.map +0 -1
  1832. package/dist/run/workspace-fingerprint.js.map +0 -1
  1833. package/dist/run-query/index.d.ts +0 -90
  1834. package/dist/run-query/index.d.ts.map +0 -1
  1835. package/dist/run-query/index.js +0 -127
  1836. package/dist/run-query/index.js.map +0 -1
  1837. package/dist/runtime/query/finalize-run.d.ts +0 -55
  1838. package/dist/runtime/query/finalize-run.d.ts.map +0 -1
  1839. package/dist/runtime/query/finalize-run.js +0 -113
  1840. package/dist/runtime/query/finalize-run.js.map +0 -1
  1841. package/dist/runtime/query/prepare-run.d.ts +0 -94
  1842. package/dist/runtime/query/prepare-run.d.ts.map +0 -1
  1843. package/dist/runtime/query/prepare-run.js +0 -589
  1844. package/dist/runtime/query/prepare-run.js.map +0 -1
  1845. package/dist/runtime/query/release-run.d.ts +0 -56
  1846. package/dist/runtime/query/release-run.d.ts.map +0 -1
  1847. package/dist/runtime/query/release-run.js +0 -101
  1848. package/dist/runtime/query/release-run.js.map +0 -1
  1849. package/dist/runtime/query/replay/list.d.ts +0 -40
  1850. package/dist/runtime/query/replay/list.d.ts.map +0 -1
  1851. package/dist/runtime/query/replay/list.js +0 -38
  1852. package/dist/runtime/query/replay/list.js.map +0 -1
  1853. package/dist/runtime/query/replay/mutate.d.ts +0 -17
  1854. package/dist/runtime/query/replay/mutate.d.ts.map +0 -1
  1855. package/dist/runtime/query/replay/mutate.js +0 -69
  1856. package/dist/runtime/query/replay/mutate.js.map +0 -1
  1857. package/dist/runtime/query/replay/prepare.d.ts +0 -66
  1858. package/dist/runtime/query/replay/prepare.d.ts.map +0 -1
  1859. package/dist/runtime/query/replay/prepare.js +0 -81
  1860. package/dist/runtime/query/replay/prepare.js.map +0 -1
  1861. package/dist/runtime/query/resume-run.d.ts +0 -103
  1862. package/dist/runtime/query/resume-run.d.ts.map +0 -1
  1863. package/dist/runtime/query/resume-run.js +0 -105
  1864. package/dist/runtime/query/resume-run.js.map +0 -1
  1865. package/dist/runtime/query/run-state.d.ts +0 -57
  1866. package/dist/runtime/query/run-state.d.ts.map +0 -1
  1867. package/dist/runtime/query/run-state.js +0 -96
  1868. package/dist/runtime/query/run-state.js.map +0 -1
  1869. package/dist/session/workspace/path-builder.d.ts +0 -50
  1870. package/dist/session/workspace/path-builder.d.ts.map +0 -1
  1871. package/dist/session/workspace/path-builder.js +0 -51
  1872. package/dist/session/workspace/path-builder.js.map +0 -1
  1873. package/dist/session/workspace/shared-run.d.ts +0 -112
  1874. package/dist/session/workspace/shared-run.d.ts.map +0 -1
  1875. package/dist/session/workspace/shared-run.js +0 -290
  1876. package/dist/session/workspace/shared-run.js.map +0 -1
  1877. package/dist/store/evidence/compaction-archive.d.ts +0 -109
  1878. package/dist/store/evidence/compaction-archive.d.ts.map +0 -1
  1879. package/dist/store/evidence/compaction-archive.js +0 -125
  1880. package/dist/store/evidence/compaction-archive.js.map +0 -1
  1881. package/dist/store/evidence/linked.d.ts +0 -9
  1882. package/dist/store/evidence/linked.d.ts.map +0 -1
  1883. package/dist/store/evidence/linked.js +0 -314
  1884. package/dist/store/evidence/linked.js.map +0 -1
  1885. package/dist/store/evidence/record-chain.d.ts +0 -42
  1886. package/dist/store/evidence/record-chain.d.ts.map +0 -1
  1887. package/dist/store/evidence/record-chain.js +0 -111
  1888. package/dist/store/evidence/record-chain.js.map +0 -1
  1889. package/dist/store/run/checkpoint-disk.d.ts +0 -98
  1890. package/dist/store/run/checkpoint-disk.d.ts.map +0 -1
  1891. package/dist/store/run/checkpoint-disk.js +0 -190
  1892. package/dist/store/run/checkpoint-disk.js.map +0 -1
  1893. package/dist/store/run/checkpoint-memory.d.ts +0 -51
  1894. package/dist/store/run/checkpoint-memory.d.ts.map +0 -1
  1895. package/dist/store/run/checkpoint-memory.js +0 -178
  1896. package/dist/store/run/checkpoint-memory.js.map +0 -1
  1897. package/dist/store/run/claim-disk.d.ts +0 -130
  1898. package/dist/store/run/claim-disk.d.ts.map +0 -1
  1899. package/dist/store/run/claim-disk.js +0 -570
  1900. package/dist/store/run/claim-disk.js.map +0 -1
  1901. package/dist/store/run/conformance.d.ts +0 -159
  1902. package/dist/store/run/conformance.d.ts.map +0 -1
  1903. package/dist/store/run/conformance.js +0 -466
  1904. package/dist/store/run/conformance.js.map +0 -1
  1905. package/dist/store/run/disk.d.ts +0 -189
  1906. package/dist/store/run/disk.d.ts.map +0 -1
  1907. package/dist/store/run/disk.js +0 -804
  1908. package/dist/store/run/disk.js.map +0 -1
  1909. package/dist/store/run/listing.d.ts +0 -118
  1910. package/dist/store/run/listing.d.ts.map +0 -1
  1911. package/dist/store/run/listing.js +0 -333
  1912. package/dist/store/run/listing.js.map +0 -1
  1913. package/dist/store/run/memory.d.ts +0 -55
  1914. package/dist/store/run/memory.d.ts.map +0 -1
  1915. package/dist/store/run/memory.js +0 -176
  1916. package/dist/store/run/memory.js.map +0 -1
  1917. package/dist/store/run/token-budget-disk.d.ts +0 -37
  1918. package/dist/store/run/token-budget-disk.d.ts.map +0 -1
  1919. package/dist/store/run/token-budget-disk.js +0 -211
  1920. package/dist/store/run/token-budget-disk.js.map +0 -1
  1921. package/dist/store/run/tool-executions.d.ts +0 -13
  1922. package/dist/store/run/tool-executions.d.ts.map +0 -1
  1923. package/dist/store/run/tool-executions.js +0 -99
  1924. package/dist/store/run/tool-executions.js.map +0 -1
  1925. package/dist/store/session/sqlite.d.ts +0 -57
  1926. package/dist/store/session/sqlite.d.ts.map +0 -1
  1927. package/dist/store/session/sqlite.js +0 -430
  1928. package/dist/store/session/sqlite.js.map +0 -1
  1929. package/dist/types/run/answer-review.d.ts +0 -79
  1930. package/dist/types/run/answer-review.d.ts.map +0 -1
  1931. package/dist/types/run/answer-review.js.map +0 -1
  1932. package/dist/types/run/audit.d.ts +0 -150
  1933. package/dist/types/run/audit.d.ts.map +0 -1
  1934. package/dist/types/run/audit.js +0 -39
  1935. package/dist/types/run/audit.js.map +0 -1
  1936. package/dist/types/run/cancel-cause.d.ts +0 -49
  1937. package/dist/types/run/cancel-cause.d.ts.map +0 -1
  1938. package/dist/types/run/cancel-cause.js +0 -39
  1939. package/dist/types/run/cancel-cause.js.map +0 -1
  1940. package/dist/types/run/checkpoint-store.d.ts +0 -511
  1941. package/dist/types/run/checkpoint-store.d.ts.map +0 -1
  1942. package/dist/types/run/checkpoint-store.js +0 -12
  1943. package/dist/types/run/checkpoint-store.js.map +0 -1
  1944. package/dist/types/run/config.d.ts +0 -207
  1945. package/dist/types/run/config.d.ts.map +0 -1
  1946. package/dist/types/run/config.js.map +0 -1
  1947. package/dist/types/run/derive-status.d.ts +0 -29
  1948. package/dist/types/run/derive-status.d.ts.map +0 -1
  1949. package/dist/types/run/derive-status.js +0 -49
  1950. package/dist/types/run/derive-status.js.map +0 -1
  1951. package/dist/types/run/emergency.d.ts +0 -32
  1952. package/dist/types/run/emergency.d.ts.map +0 -1
  1953. package/dist/types/run/emergency.js +0 -6
  1954. package/dist/types/run/emergency.js.map +0 -1
  1955. package/dist/types/run/entity.d.ts +0 -151
  1956. package/dist/types/run/entity.d.ts.map +0 -1
  1957. package/dist/types/run/entity.js +0 -2
  1958. package/dist/types/run/entity.js.map +0 -1
  1959. package/dist/types/run/event-cursor.d.ts +0 -90
  1960. package/dist/types/run/event-cursor.d.ts.map +0 -1
  1961. package/dist/types/run/event-cursor.js +0 -47
  1962. package/dist/types/run/event-cursor.js.map +0 -1
  1963. package/dist/types/run/events.d.ts +0 -1064
  1964. package/dist/types/run/events.d.ts.map +0 -1
  1965. package/dist/types/run/events.js +0 -31
  1966. package/dist/types/run/events.js.map +0 -1
  1967. package/dist/types/run/index.d.ts +0 -24
  1968. package/dist/types/run/index.d.ts.map +0 -1
  1969. package/dist/types/run/index.js +0 -23
  1970. package/dist/types/run/index.js.map +0 -1
  1971. package/dist/types/run/lineage.d.ts +0 -15
  1972. package/dist/types/run/lineage.d.ts.map +0 -1
  1973. package/dist/types/run/lineage.js.map +0 -1
  1974. package/dist/types/run/memory-promotion.d.ts +0 -90
  1975. package/dist/types/run/memory-promotion.d.ts.map +0 -1
  1976. package/dist/types/run/memory-promotion.js +0 -38
  1977. package/dist/types/run/memory-promotion.js.map +0 -1
  1978. package/dist/types/run/metadata.d.ts +0 -47
  1979. package/dist/types/run/metadata.d.ts.map +0 -1
  1980. package/dist/types/run/metadata.js +0 -2
  1981. package/dist/types/run/metadata.js.map +0 -1
  1982. package/dist/types/run/prepare-step.d.ts +0 -260
  1983. package/dist/types/run/prepare-step.d.ts.map +0 -1
  1984. package/dist/types/run/prepare-step.js.map +0 -1
  1985. package/dist/types/run/replay.d.ts +0 -53
  1986. package/dist/types/run/replay.d.ts.map +0 -1
  1987. package/dist/types/run/replay.js +0 -15
  1988. package/dist/types/run/replay.js.map +0 -1
  1989. package/dist/types/run/schema-version.d.ts +0 -19
  1990. package/dist/types/run/schema-version.d.ts.map +0 -1
  1991. package/dist/types/run/schema-version.js +0 -18
  1992. package/dist/types/run/schema-version.js.map +0 -1
  1993. package/dist/types/run/state.d.ts +0 -109
  1994. package/dist/types/run/state.d.ts.map +0 -1
  1995. package/dist/types/run/state.js +0 -109
  1996. package/dist/types/run/state.js.map +0 -1
  1997. package/dist/types/run/status.d.ts +0 -26
  1998. package/dist/types/run/status.d.ts.map +0 -1
  1999. package/dist/types/run/status.js +0 -2
  2000. package/dist/types/run/status.js.map +0 -1
  2001. package/dist/types/run/step.d.ts +0 -198
  2002. package/dist/types/run/step.d.ts.map +0 -1
  2003. package/dist/types/run/step.js +0 -26
  2004. package/dist/types/run/step.js.map +0 -1
  2005. package/dist/types/run/stop-reason.d.ts +0 -67
  2006. package/dist/types/run/stop-reason.d.ts.map +0 -1
  2007. package/dist/types/run/stop-reason.js.map +0 -1
  2008. package/dist/types/run/store.d.ts +0 -300
  2009. package/dist/types/run/store.d.ts.map +0 -1
  2010. package/dist/types/run/store.js +0 -2
  2011. package/dist/types/run/store.js.map +0 -1
  2012. package/dist/types/run/subsession-events.d.ts +0 -64
  2013. package/dist/types/run/subsession-events.d.ts.map +0 -1
  2014. package/dist/types/run/subsession-events.js +0 -2
  2015. package/dist/types/run/subsession-events.js.map +0 -1
  2016. package/dist/types/run/token-budget-store.d.ts +0 -29
  2017. package/dist/types/run/token-budget-store.d.ts.map +0 -1
  2018. package/dist/types/run/token-budget-store.js +0 -25
  2019. package/dist/types/run/token-budget-store.js.map +0 -1
  2020. package/dist/types/workspace/shared-run.d.ts +0 -61
  2021. package/dist/types/workspace/shared-run.d.ts.map +0 -1
  2022. package/dist/types/workspace/shared-run.js +0 -2
  2023. package/dist/types/workspace/shared-run.js.map +0 -1
  2024. package/src/constants/emergency.ts +0 -3
  2025. package/src/contracts/run-status.ts +0 -43
  2026. package/src/eval/from-run.ts +0 -48
  2027. package/src/manager/run/emergency.ts +0 -148
  2028. package/src/manager/run/persistence.ts +0 -746
  2029. package/src/read-model/run-status.ts +0 -127
  2030. package/src/run/LimitChecker.ts +0 -99
  2031. package/src/run/command-gate.ts +0 -294
  2032. package/src/run/drain.ts +0 -403
  2033. package/src/run/evidence-query.ts +0 -333
  2034. package/src/run/evidence-recall.ts +0 -854
  2035. package/src/run/index.ts +0 -42
  2036. package/src/run/json-claim-verifier.ts +0 -298
  2037. package/src/run/memory-promoter.ts +0 -147
  2038. package/src/run/memory-recall.ts +0 -254
  2039. package/src/run/reporter.ts +0 -469
  2040. package/src/run/token-budget.ts +0 -733
  2041. package/src/run-query/index.ts +0 -177
  2042. package/src/runtime/query/finalize-run.ts +0 -192
  2043. package/src/runtime/query/prepare-run.ts +0 -718
  2044. package/src/runtime/query/release-run.ts +0 -168
  2045. package/src/runtime/query/replay/list.ts +0 -66
  2046. package/src/runtime/query/replay/mutate.ts +0 -82
  2047. package/src/runtime/query/replay/prepare.ts +0 -147
  2048. package/src/runtime/query/resume-run.ts +0 -202
  2049. package/src/runtime/query/run-state.ts +0 -138
  2050. package/src/session/workspace/path-builder.ts +0 -72
  2051. package/src/session/workspace/shared-run.ts +0 -354
  2052. package/src/store/evidence/compaction-archive.ts +0 -139
  2053. package/src/store/evidence/linked.ts +0 -365
  2054. package/src/store/evidence/record-chain.ts +0 -108
  2055. package/src/store/run/checkpoint-disk.ts +0 -264
  2056. package/src/store/run/checkpoint-memory.ts +0 -216
  2057. package/src/store/run/claim-disk.ts +0 -638
  2058. package/src/store/run/conformance.ts +0 -728
  2059. package/src/store/run/disk.ts +0 -911
  2060. package/src/store/run/listing.ts +0 -422
  2061. package/src/store/run/memory.ts +0 -204
  2062. package/src/store/run/token-budget-disk.ts +0 -250
  2063. package/src/store/run/tool-executions.ts +0 -112
  2064. package/src/store/session/sqlite.ts +0 -584
  2065. package/src/types/run/answer-review.ts +0 -84
  2066. package/src/types/run/audit.ts +0 -164
  2067. package/src/types/run/cancel-cause.ts +0 -60
  2068. package/src/types/run/checkpoint-store.ts +0 -545
  2069. package/src/types/run/config.ts +0 -221
  2070. package/src/types/run/derive-status.ts +0 -62
  2071. package/src/types/run/emergency.ts +0 -28
  2072. package/src/types/run/entity.ts +0 -161
  2073. package/src/types/run/event-cursor.ts +0 -118
  2074. package/src/types/run/events.ts +0 -1146
  2075. package/src/types/run/index.ts +0 -32
  2076. package/src/types/run/lineage.ts +0 -15
  2077. package/src/types/run/memory-promotion.ts +0 -112
  2078. package/src/types/run/metadata.ts +0 -51
  2079. package/src/types/run/prepare-step.ts +0 -281
  2080. package/src/types/run/replay.ts +0 -61
  2081. package/src/types/run/schema-version.ts +0 -19
  2082. package/src/types/run/state.ts +0 -206
  2083. package/src/types/run/status.ts +0 -33
  2084. package/src/types/run/step.ts +0 -217
  2085. package/src/types/run/stop-reason.ts +0 -83
  2086. package/src/types/run/store.ts +0 -325
  2087. package/src/types/run/subsession-events.ts +0 -71
  2088. package/src/types/run/token-budget-store.ts +0 -54
  2089. package/src/types/workspace/shared-run.ts +0 -65
  2090. /package/dist/{run → turn}/preparation-context-error.d.ts +0 -0
  2091. /package/dist/{run → turn}/preparation-context-error.js +0 -0
  2092. /package/dist/{run → turn}/workspace-fingerprint.d.ts +0 -0
  2093. /package/dist/{run → turn}/workspace-fingerprint.js +0 -0
  2094. /package/dist/types/{run → session}/answer-review.js +0 -0
  2095. /package/dist/types/{run → session}/config.js +0 -0
  2096. /package/dist/types/{run → session}/lineage.js +0 -0
  2097. /package/dist/types/{run → session}/prepare-step.js +0 -0
  2098. /package/dist/types/{run → session}/stop-reason.js +0 -0
  2099. /package/src/{run → turn}/preparation-context-error.ts +0 -0
  2100. /package/src/{run → turn}/workspace-fingerprint.ts +0 -0
@@ -1,4 +1,3 @@
1
- import { join } from 'node:path';
2
1
  import { AdvisorRegistry, AdvisoryContext, AdvisoryExecutor, TriggerEvaluator, assertBudgetEnforceable, } from '../../advisory/index.js';
3
2
  import { AuthorizationGate } from '../../authorization/gate.js';
4
3
  import { repairToolMessageHistory, toolHistoryRepairChanged } from '../../compaction/dangling.js';
@@ -7,13 +6,13 @@ import { WorkingStateManager } from '../../compaction/manager.js';
7
6
  import { serializeState as serializeWorkingState } from '../../compaction/serializer.js';
8
7
  import { restoreWorkingState, snapshotWorkingState } from '../../compaction/wire.js';
9
8
  import { CompactionConfigSchema } from '../../config/runtime.js';
10
- import { TOOL_OUTPUT_DIR_NAME } from '../../constants/tools/index.js';
11
- import { EmergencySaveManager } from '../../manager/run/emergency.js';
9
+ import { childSessionLog } from '../../manager/agent/child-session.js';
10
+ import { recordedTurnStart } from '../../manager/session/turn-recorder.js';
12
11
  import { PromptContributionRegistry } from '../../prompt/contributions.js';
13
12
  import { resolveProviderCapabilities } from '../../provider/capabilities.js';
14
13
  import { withStreamIdleTimeout } from '../../provider/idle-timeout.js';
15
14
  import { withTokenBudget } from '../../provider/token-budget.js';
16
- import { GENAI, NAMZU, agentRunSpanName, parentContext, serializeSpan, } from '../../telemetry/attributes.js';
15
+ import { GENAI, NAMZU, agentTurnSpanName, parentContext, serializeSpan, } from '../../telemetry/attributes.js';
17
16
  import { getTracer } from '../../telemetry/runtime-accessors.js';
18
17
  import { buildAdvisoryTools } from '../../tools/advisory/index.js';
19
18
  import { SearchToolsTool } from '../../tools/builtins/search-tools.js';
@@ -23,22 +22,23 @@ import { isTerminalStatus } from '../../types/common/index.js';
23
22
  import { NamzuError } from '../../types/errors/index.js';
24
23
  import { autoApproveHandler, } from '../../types/hitl/index.js';
25
24
  import { createSystemMessage, } from '../../types/message/index.js';
25
+ import { isTurnInProgressError, } from '../../types/session/index.js';
26
26
  import { toErrorMessage } from '../../utils/error.js';
27
27
  import { errorAttributes } from '../../utils/log/exception.js';
28
28
  import { AwaitedJobs } from '../jobs/awaited-jobs.js';
29
29
  import { catchUpFromCursor, settlePreStartCancellation } from './cancelled-before-start.js';
30
30
  import { CheckpointManager, findPendingCheckpoint } from './checkpoint.js';
31
- import { finalizeRun } from './finalize-run.js';
31
+ import { finalizeTurn } from './finalize-turn.js';
32
32
  import { GuardCoordinator } from './guard.js';
33
33
  import { runInputGuardrails } from './guardrails.js';
34
34
  import { IterationOrchestrator } from './iteration/index.js';
35
35
  import { isCompactionMessage } from './iteration/phases/compaction.js';
36
36
  import { isWorkingMemoryMessage } from './iteration/phases/working-memory.js';
37
37
  import { applyLifecycleHookResults } from './plugin-hooks.js';
38
- import { prepareRun, projectStateBearingHistory, resolveProviderContextWindow, selectedResumeStates, } from './prepare-run.js';
38
+ import { prepareTurn, projectStateBearingHistory, resolveProviderContextWindow, selectedResumeStates, } from './prepare-turn.js';
39
39
  import { PromptBuilder } from './prompt.js';
40
40
  import { PendingAnswers, QuestionParkBinding } from './question-park.js';
41
- import { releaseRunResources } from './release-run.js';
41
+ import { releaseTurnResources } from './release-turn.js';
42
42
  import { RepeatCallTracker } from './repeat-call.js';
43
43
  import { ResultAssembler } from './result.js';
44
44
  import { answersParkOf, applyPendingResume, interruptedToolCalls, planCrashResume, planPendingResume, recoverCompletedCalls, supersededByRecovery, } from './resume-pending.js';
@@ -53,7 +53,7 @@ import { ToolingBootstrap } from './tooling.js';
53
53
  * The plan re-appends the exact assistant with real/denied/recovered results.
54
54
  * Generic history repair must not synthesize a competing result first. Any
55
55
  * partial results for that turn are removed too; the executor reconstructs
56
- * them from the durable run transcript through `recoveredResults`.
56
+ * them from the durable turn transcript through `recoveredResults`.
57
57
  */
58
58
  function withoutOwnedResumeTurn(messages, assistant) {
59
59
  const ownerIndex = messages.lastIndexOf(assistant);
@@ -112,1328 +112,1362 @@ function withOwnedResumeOutcomes(messages, assistant, recovered) {
112
112
  ];
113
113
  }
114
114
  export async function* query(params) {
115
- const prepared = await prepareRun(params);
116
- const { runConfig, budget, log, ctx, resilientProvider, serving, providerContextWindow, modelContextWindows, approvalPolicy, eventTranslator, executeUserInterruptHooks, pendingHistoryRepairs, initialMessages, queuedForThisRun, selectedResumeState, attachmentResolutionCancelled, streamIdleTimeoutMs, sandboxTeardownTimeoutMs, promptCache, taskScheduler, } = prepared;
115
+ const prepared = await prepareTurn(params);
116
+ const { turnConfig, budget, log, ctx, resilientProvider, serving, providerContextWindow, modelContextWindows, approvalPolicy, eventTranslator, executeUserInterruptHooks, pendingHistoryRepairs, initialMessages, historyIds, queuedForThisRun, selectedResumeState, attachmentResolutionCancelled, streamIdleTimeoutMs, sandboxTeardownTimeoutMs, promptCache, taskScheduler, } = prepared;
117
117
  if (attachmentResolutionCancelled) {
118
- return yield* settlePreStartCancellation(params, prepared);
119
- }
120
- const unsubscribeTaskStore = params.taskStore
121
- ? eventTranslator.wireTaskStore(params.taskStore, ctx.runId)
122
- : undefined;
123
- if (params.taskStore) {
124
- const taskTools = buildTaskTools(params.taskStore, ctx.runId);
125
- const overrides = params.runtimeToolOverrides;
126
- for (const tool of taskTools) {
127
- const override = overrides?.[tool.name];
128
- if (override === 'disabled')
129
- continue;
130
- params.tools.register(tool, override ?? 'deferred');
118
+ try {
119
+ return yield* settlePreStartCancellation(params, prepared);
131
120
  }
132
- }
133
- if (!params.tools.has(SearchToolsTool.name)) {
134
- const hasDeferred = params.tools
135
- .listNames()
136
- .some((n) => params.tools.getAvailability(n) === 'deferred');
137
- if (hasDeferred) {
138
- params.tools.register(SearchToolsTool);
121
+ finally {
122
+ await ctx.recorder.release();
139
123
  }
140
124
  }
141
- // Registered HERE, before the first turn, not when the model is nearly
142
- // done. Tools render at prefix position 0, so injecting one late would
143
- // invalidate the whole prompt cache for the rest of the run — the same
144
- // reason the forced-final turn keeps its tools array and uses
145
- // `toolChoice: 'none'` instead of dropping it.
146
- if (params.structuredOutput &&
147
- params.structuredOutput.mode !== 'native' &&
148
- !params.tools.has(STRUCTURED_OUTPUT_TOOL_NAME)) {
149
- params.tools.register(createStructuredOutputTool(params.structuredOutput.schema));
150
- }
151
- // ─── Provider capability negotiation (before tooling bootstrap) ────────
152
- // Compare what the request asks for with what the DRIVER declared it
153
- // does. Undeclared capabilities resolve permissively (today's behavior
154
- // for third-party providers); declared gaps degrade loudly instead of
155
- // silently.
156
- const capabilities = resolveProviderCapabilities(params.provider);
157
- const registeredToolCount = params.tools.listNames().length;
158
- const stripToolSurfaces = !capabilities.supportsTools && registeredToolCount > 0;
159
- // Counted separately because they are separate wire shapes: a driver can
160
- // map images and drop documents, and a vision warning would send the
161
- // reader looking at the wrong half.
162
- const carries = (m, kind) => m.role === 'user' && (m.attachments ?? []).some((a) => (a.type ?? 'image') === kind);
163
- const attachmentMessageCount = capabilities.supportsVision
164
- ? 0
165
- : params.messages.filter((m) => carries(m, 'image')).length;
166
- const documentMessageCount = capabilities.supportsDocuments
167
- ? 0
168
- : params.messages.filter((m) => carries(m, 'document')).length;
169
- if (stripToolSurfaces) {
170
- const message = `Provider '${params.provider.id}' declares supportsTools: false but ${registeredToolCount} tool(s) are registered — stripping all tool surfaces from the prompt and request so the model is never told about tools it cannot call. Pass strictCapabilities: true to fail instead, or use a tools-capable provider.`;
171
- if (params.strictCapabilities) {
172
- throw new NamzuError({
173
- code: 'capability_unavailable',
174
- message,
175
- details: {
176
- providerId: params.provider.id,
177
- capability: 'tools',
178
- registeredToolCount,
179
- },
125
+ // Everything from here to the turn body can refuse (a capability the
126
+ // provider lacks, a sandbox mode it does not offer); the lease the
127
+ // prelude took is given back on the way out.
128
+ let unsubscribeChildSessions;
129
+ try {
130
+ const unsubscribeTaskStore = params.taskStore
131
+ ? eventTranslator.wireTaskStore(params.taskStore, ctx.sessionId)
132
+ : undefined;
133
+ // The children this turn delegates to are recorded in this session's
134
+ // log: `child_session_spawned` when one starts, `child_session_ended`
135
+ // (read from the child's own log) when it goes idle. That is what lets
136
+ // the parent list and replay its children once the process is gone.
137
+ unsubscribeChildSessions = taskScheduler?.onChildSessionEvent?.((event) => {
138
+ // Looked up now, while the manager still holds the child's spawn record.
139
+ const childLog = event.type === 'child_session_idled' ? childSessionLog(event.childSessionId) : undefined;
140
+ void ctx.recorder.recordChildSessionEvent(event, childLog).catch((err) => {
141
+ ctx.log.warn('A child session record could not be appended', {
142
+ [NAMZU.TURN_ID]: ctx.turnId,
143
+ 'namzu.child_session.id': event.childSessionId,
144
+ 'exception.message': err instanceof Error ? err.message : String(err),
145
+ });
180
146
  });
181
- }
182
- ctx.log.warn('Capability mismatch: the provider declares no tool support', {
183
- 'namzu.capability.detail': message,
184
- [GENAI.SYSTEM]: params.provider.id,
185
- 'namzu.runtime.registered_tool_count': registeredToolCount,
186
147
  });
187
- }
188
- if (attachmentMessageCount > 0) {
189
- const message = `Provider '${params.provider.id}' declares supportsVision: false but ${attachmentMessageCount} user message(s) carry image attachments — the driver will not map them, so the model never sees the images. Pass strictCapabilities: true to fail instead, or use a vision-capable provider.`;
190
- if (params.strictCapabilities) {
191
- throw new NamzuError({
192
- code: 'capability_unavailable',
193
- message,
194
- details: {
195
- providerId: params.provider.id,
196
- capability: 'vision',
197
- attachmentMessageCount,
198
- },
148
+ if (params.taskStore) {
149
+ const taskTools = buildTaskTools(params.taskStore, {
150
+ sessionId: ctx.sessionId,
151
+ turnId: ctx.turnId,
152
+ // A resumed turn began when its `turn_started` was recorded, maybe
153
+ // in another process: tasks it closed before the pause are still
154
+ // "closed in this turn".
155
+ turnStartedAt: (params.resumeFromCheckpoint
156
+ ? await recordedTurnStart(ctx.recorder.log, ctx.turnId)
157
+ : undefined) ?? ctx.recorder.getTurn().startedAt,
199
158
  });
200
- }
201
- ctx.log.warn('Capability mismatch: the provider declares no vision support', {
202
- 'namzu.capability.detail': message,
203
- [GENAI.SYSTEM]: params.provider.id,
204
- 'namzu.runtime.attachment_message_count': attachmentMessageCount,
205
- });
206
- }
207
- if (documentMessageCount > 0) {
208
- const message = `Provider '${params.provider.id}' declares supportsDocuments: false but ${documentMessageCount} user message(s) carry document attachments — the driver will not map them, so the model never sees the documents. Pass strictCapabilities: true to fail instead, or use a document-capable provider.`;
209
- if (params.strictCapabilities) {
210
- throw new NamzuError({
211
- code: 'capability_unavailable',
212
- message,
213
- details: {
214
- providerId: params.provider.id,
215
- capability: 'documents',
216
- documentMessageCount,
217
- },
218
- });
219
- }
220
- ctx.log.warn('Capability mismatch: the provider declares no document support', {
221
- 'namzu.capability.detail': message,
222
- [GENAI.SYSTEM]: params.provider.id,
223
- 'namzu.runtime.document_message_count': documentMessageCount,
224
- });
225
- }
226
- // Denied names are subtracted LAST, after the allow-list is resolved
227
- // against the registry — so a deny reaches a run that named no
228
- // allow-list at all, which is the ordinary case for a delegated child.
229
- // Applied to `effectiveAllowedTools`, which `query()` binds to both the
230
- // request tool list AND the `ToolExecutor`: narrowing only the request
231
- // shows the model fewer tools and lets it call any of them by name.
232
- const allowedBeforeDenial = stripToolSurfaces
233
- ? []
234
- : withDeferredDiscoveryTool(params.tools, params.allowedTools);
235
- const denied = new Set(params.deniedTools ?? []);
236
- const effectiveAllowedTools = denied.size === 0
237
- ? allowedBeforeDenial
238
- : // An absent allow-list means "every registered tool", so a deny
239
- // with no allow-list has to be resolved against the registry
240
- // here — otherwise the subtraction would be from an empty list
241
- // and would deny nothing, which is the shape a delegated child
242
- // arrives in.
243
- [...(allowedBeforeDenial ?? params.tools.listNames())].filter((name) => !denied.has(name));
244
- // The two halves of a durable pause, owned by the RUN when the host
245
- // does not own them.
246
- //
247
- // `SupervisorAgent` builds both before the run exists, because the
248
- // tools it builds close over them, and it passes them in. Nothing else
249
- // could: neither type is exported from `public-runtime.ts`, so a host
250
- // on `ReactiveAgent`, `drainQuery` or `resumeRun` had no way to supply
251
- // either — and `ToolContext.requestPause`, which every tool author is
252
- // handed, silently wrote no checkpoint and could receive no answer on
253
- // those surfaces. Which agent class the host happened to pick is not
254
- // visible at the call site, so the degradation was invisible too.
255
- //
256
- // A run-local pair is enough for the general seam because `query()`
257
- // builds its `createToolPause` itself, below, and can hand it the
258
- // run's own. Pinned by the "a pause is durable on any surface" cases
259
- // in `__tests__/tool-pause-resume.test.ts`.
260
- const questionParks = params.questionParks ?? new QuestionParkBinding();
261
- const pendingAnswers = params.pendingAnswers ?? new PendingAnswers();
262
- // One gate instance owns both model-issued calls and calls dispatched by
263
- // another tool. Constructing it only inside the iteration review left the
264
- // nested registry path outside the operator's policy entirely.
265
- const gateConfig = params.authorizationGate;
266
- const verificationGate = gateConfig?.enabled
267
- ? new AuthorizationGate(gateConfig, ctx.log)
268
- : undefined;
269
- // The store is initialized when the async query starts, after tooling is
270
- // composed. Resolve lazily at execution time: capturing getRunDir() here
271
- // permanently disabled retention for fresh disk-backed invocations.
272
- const toolOutputDir = () => {
273
- const runDir = ctx.runMgr.getRunDir();
274
- return runDir ? join(runDir, TOOL_OUTPUT_DIR_NAME) : undefined;
275
- };
276
- // The same invocation-owned capability serves tools and optional preparation.
277
- // Local cancellation cannot override the run's cancellation or settled state.
278
- const captureRunEvidence = async (maxReadBytes, signal) => {
279
- const combined = signal
280
- ? AbortSignal.any([ctx.abortController.signal, signal])
281
- : ctx.abortController.signal;
282
- combined.throwIfAborted();
283
- const source = await eventTranslator.captureRunEvidence(maxReadBytes, combined);
284
- combined.throwIfAborted();
285
- return source;
286
- };
287
- // Whose jobs this run speaks for: its own by default, the session's when
288
- // the host said so. Resolved before the tools are built, because the
289
- // wait-intent recorder below is bound into them.
290
- const jobOwner = params.backgroundJobOwner ?? ctx.runId;
291
- // What the model reads when a job ends. Built up here, ahead of the
292
- // subscription that fills it below, because the wait-intent recorder needs
293
- // to ask whether its text has been read yet.
294
- const jobNotices = params.backgroundJobs ? new SteeringBinding() : undefined;
295
- // Jobs the model told `wait_for_job` it is waiting on, which is the only
296
- // thing that can hold this run open for a job. Built only where there is a
297
- // registry, so a host with no background mode carries no recorder and the
298
- // bound ref has no `markAwaited` to offer.
299
- const awaitedJobs = params.backgroundJobs
300
- ? new AwaitedJobs(params.backgroundJobs, jobOwner, () => jobNotices?.pending ?? false)
301
- : undefined;
302
- awaitedJobs?.attach();
303
- const toolExecutor = ToolingBootstrap.init({
304
- tools: params.tools,
305
- runId: ctx.runId,
306
- workingDirectory: ctx.cwd,
307
- ...(params.additionalDirectories?.length
308
- ? { additionalDirectories: params.additionalDirectories }
309
- : {}),
310
- permissionMode: () => ctx.permissionMode.current,
311
- env: runConfig.env ?? {},
312
- abortSignal: ctx.abortController.signal,
313
- allowedTools: effectiveAllowedTools,
314
- invocationState: params.invocationState,
315
- pluginManager: params.pluginManager,
316
- ...(params.backgroundJobs ? { backgroundJobs: params.backgroundJobs } : {}),
317
- ...(params.backgroundJobOwner ? { backgroundJobOwner: params.backgroundJobOwner } : {}),
318
- ...(awaitedJobs ? { onJobAwaited: (id) => awaitedJobs.expect(id) } : {}),
319
- // The `skill` tool's registry. Threaded from the run rather than
320
- // held by the tool, because a tool that reached for a module-level
321
- // registry would answer about whatever the last run configured.
322
- ...(params.skillRegistry ? { skills: params.skillRegistry } : {}),
323
- ...(params.web ? { web: params.web } : {}),
324
- ...(params.fileReadTracker ? { fileReadTracker: params.fileReadTracker } : {}),
325
- ...(params.toolTimeoutMs !== undefined ? { toolTimeoutMs: params.toolTimeoutMs } : {}),
326
- ...(params.toolRetryBackoff !== undefined
327
- ? { toolRetryBackoff: params.toolRetryBackoff }
328
- : {}),
329
- ...(params.maxToolCalls !== undefined
330
- ? {
331
- maxToolCalls: params.maxToolCalls,
332
- readToolCallBudgetEvents: () => eventTranslator.readEvents({ integrity: 'strict' }),
333
- }
334
- : {}),
335
- ...(params.maxToolConcurrency !== undefined
336
- ? { maxToolConcurrency: params.maxToolConcurrency }
337
- : {}),
338
- ...(params.maxToolOutputChars !== undefined
339
- ? { maxToolOutputChars: params.maxToolOutputChars }
340
- : {}),
341
- ...(params.toolResultGuardrails !== undefined
342
- ? { toolResultGuardrails: params.toolResultGuardrails }
343
- : {}),
344
- ...(params.retainedToolPreviewChars !== undefined
345
- ? { retainedToolPreviewChars: params.retainedToolPreviewChars }
346
- : {}),
347
- ...(params.maxToolContentBytes !== undefined
348
- ? { maxToolContentBytes: params.maxToolContentBytes }
349
- : {}),
350
- // Overflow lands beside the run's other artifacts, so it is
351
- // cleaned up with the run and reachable by the model's own
352
- // `read`/`grep` without a new affordance.
353
- toolOutputDir,
354
- captureRunEvidence,
355
- ...(params.repairToolCall ? { repairToolCall: params.repairToolCall } : {}),
356
- ...(verificationGate ? { authorizationGate: verificationGate } : {}),
357
- recordAudit: (input) => ctx.runMgr.recordAudit(input),
358
- // The durable pause, reachable from any tool rather than from the
359
- // four kernel-owned points that used to own it. Built here from
360
- // the machinery the run already holds; the recorder binds a few
361
- // lines below, and until it does a pause is in-process only —
362
- // the same degradation the built-in question tool has.
363
- toolPause: (toolUseId) => createToolPause({
364
- runId: ctx.runId,
365
- toolUseId,
366
- parkHandler: (request) => approvalPolicy.current.handler(request),
367
- recorder: questionParks,
368
- pendingAnswers,
369
- }),
370
- }, ctx.activityStore, eventTranslator.emitEvent, ctx.log);
371
- // A background job's exit reaches the model as a notice on its next tool
372
- // result, and the host as an event — without either polling. Subscribed
373
- // for the owner the run's jobs are bound to, so a session-owned job that
374
- // ends during this run is reported here too.
375
- const unsubscribeJobExits = params.backgroundJobs?.onExit((job) => {
376
- if (job.owner !== jobOwner)
377
- return;
378
- const outcome = job.status === 'killed'
379
- ? 'was stopped'
380
- : `exited with code ${job.exitCode ?? 'unknown'}${job.signal ? ` (${job.signal})` : ''}`;
381
- jobNotices?.steer(`Background job ${job.id} (${job.command}) ${outcome}. Read its output with the job tool if you need it.`);
382
- void eventTranslator
383
- .emitEvent({
384
- type: 'background_job_exited',
385
- runId: ctx.runId,
386
- jobId: job.id,
387
- command: job.command,
388
- status: job.status === 'killed' ? 'killed' : 'exited',
389
- ...(job.exitCode !== undefined ? { exitCode: job.exitCode } : {}),
390
- ...(job.signal ? { signal: job.signal } : {}),
391
- })
392
- .catch(() => { });
393
- });
394
- let workingStateManager;
395
- // Normalised once, defaults applied. A host that passes a partial
396
- // object — a strategy and a window, nothing else — used to reach the
397
- // phase with `triggerThreshold` undefined, and `usage < undefined` is
398
- // false: the pass ran on every iteration and the salience strategy fell
399
- // through to the stale-result clearing it exists to replace. The eval
400
- // suite that passed exactly that object found it.
401
- const compactionConfig = params.compactionConfig
402
- ? CompactionConfigSchema.parse(params.compactionConfig)
403
- : undefined;
404
- if (compactionConfig && compactionConfig.strategy !== 'disabled') {
405
- workingStateManager = new WorkingStateManager(compactionConfig);
406
- toolExecutor.setWorkingStateManager(workingStateManager);
407
- }
408
- // The run's own registry when the host passed none, so a hook's
409
- // annotation has somewhere to land.
410
- const promptContributions = params.promptContributions ?? new PromptContributionRegistry();
411
- const promptBuilder = new PromptBuilder({
412
- systemPrompt: params.systemPrompt,
413
- persona: params.persona,
414
- skills: params.skills,
415
- basePrompt: params.basePrompt,
416
- tools: params.tools,
417
- allowedTools: effectiveAllowedTools,
418
- runtimeContext: params.runtimeContext,
419
- contributions: promptContributions,
420
- });
421
- const guard = new GuardCoordinator({
422
- tokenBudget: runConfig.tokenBudget,
423
- timeoutMs: runConfig.timeoutMs,
424
- costLimitUsd: runConfig.costLimitUsd,
425
- maxIterations: runConfig.maxIterations,
426
- });
427
- const checkpointMgr = new CheckpointManager(ctx.runMgr.getCheckpointStore(), ctx.runMgr.getRunScope());
428
- // Every checkpoint carries compaction's accumulated state, so a run that
429
- // comes back in a new process can adopt it (see the restore block).
430
- // Without it, compaction's own justification for dropping the prior
431
- // `[COMPACTED CONTEXT]` block — that `serializeState` is cumulative —
432
- // holds within one process and fails across a resume.
433
- if (workingStateManager) {
434
- const manager = workingStateManager;
435
- checkpointMgr.setWorkingStateSource(() => snapshotWorkingState(manager));
436
- }
437
- const resultAssembler = new ResultAssembler({
438
- runMgr: ctx.runMgr,
439
- planManager: ctx.planManager,
440
- activityStore: ctx.activityStore,
441
- log: ctx.log,
442
- emitEvent: eventTranslator.emitEvent,
443
- drainPending: () => eventTranslator.drainPending(),
444
- // Read at settle time, not now: checkpoints are written per
445
- // iteration, so the answer changes as the run proceeds.
446
- resumeCheckpointId: () => checkpointMgr.lastCheckpointId,
447
- // Read only to recover WHY a cancellation happened. The run loop
448
- // already knows THAT it was cancelled; the origin lives on the abort
449
- // reason and nothing else carries it this far.
450
- signal: ctx.abortController.signal,
451
- });
452
- let advisoryCtx;
453
- if (params.advisory && params.advisory.advisors.length > 0) {
454
- // Advisors are model calls owned by this run even when they use a
455
- // different provider. Sending the raw definitions into the registry
456
- // lets a triggered or model-requested consultation bypass both the
457
- // finite stream-silence bound and Stop. Bind every advisor provider at
458
- // the query boundary, where the effective timeout and run signal are
459
- // already known; standalone AdvisoryExecutor callers retain their
460
- // explicitly chosen provider/cancellation policy.
461
- const boundedAdvisors = params.advisory.advisors.map((advisor) => ({
462
- ...advisor,
463
- provider: withTokenBudget(withStreamIdleTimeout(advisor.provider, {
464
- idleTimeoutMs: streamIdleTimeoutMs,
465
- log: ctx.log,
466
- }), budget),
467
- }));
468
- const advisorRegistry = new AdvisorRegistry(boundedAdvisors, params.advisory.defaultAdvisorId);
469
- // A budget the runtime cannot measure is refused here rather than
470
- // silently ignored for the length of the run.
471
- assertBudgetEnforceable(params.advisory);
472
- const advisoryExecutor = new AdvisoryExecutor(ctx.log, params.advisory.budget, ctx.abortController.signal);
473
- const triggerEvaluator = new TriggerEvaluator(params.advisory.triggers ?? [], params.advisory.budget);
474
- advisoryCtx = new AdvisoryContext(advisorRegistry, advisoryExecutor, triggerEvaluator, params.advisory.budget);
475
- // What the run looks like when the MODEL consults an advisor, as
476
- // opposed to when a trigger does. The trigger path has always passed
477
- // this; the tool path passed an empty context, so an advisor the model
478
- // asked for help saw the question and nothing else.
479
- //
480
- // `includeToolCatalog` and `useCompactedContext` are read here and
481
- // nowhere else. Both were declared on `AdvisoryConfig` /
482
- // `AdvisorDefinition` and consulted by nothing, so a host who turned
483
- // the catalogue off still paid for it in every advisory prompt.
484
- const advisoryConfig = params.advisory;
485
- advisoryCtx.setCallContextProvider(() => {
486
- const summary = workingStateManager && advisoryConfig.advisors.some((a) => a.useCompactedContext)
487
- ? serializeWorkingState(workingStateManager.getState())
488
- : undefined;
489
- return {
490
- messages: ctx.runMgr.messages,
491
- turn: iterationOrchestrator.getAdvisoryTurnContext(),
492
- ...(summary !== undefined ? { workingStateSummary: summary } : {}),
493
- ...(advisoryConfig.includeToolCatalog
494
- ? { toolCatalog: params.tools.toLLMTools(effectiveAllowedTools) }
495
- : {}),
496
- iteration: ctx.runMgr.currentIteration,
497
- };
498
- });
499
- if (params.advisory.enableAgentTool) {
500
- const advisoryTools = buildAdvisoryTools({ advisoryCtx });
501
159
  const overrides = params.runtimeToolOverrides;
502
- for (const tool of advisoryTools) {
160
+ for (const tool of taskTools) {
503
161
  const override = overrides?.[tool.name];
504
162
  if (override === 'disabled')
505
163
  continue;
506
- params.tools.register(tool, override ?? 'active');
164
+ params.tools.register(tool, override ?? 'deferred');
507
165
  }
508
166
  }
509
- }
510
- const iterationOrchestrator = new IterationOrchestrator({
511
- captureRunEvidence,
512
- provider: resilientProvider,
513
- providerCapabilities: capabilities,
514
- strictCapabilities: params.strictCapabilities === true,
515
- servingMember: () => serving.current,
516
- runConfig,
517
- ...(params.stopWhen ? { stopWhen: params.stopWhen } : {}),
518
- ...(params.prepareStep ? { prepareStep: params.prepareStep } : {}),
519
- ...(params.beforeStep ? { beforeStep: params.beforeStep } : {}),
520
- ...(params.onStepFinish ? { onStepFinish: params.onStepFinish } : {}),
521
- ...(params.reviewAnswer ? { reviewAnswer: params.reviewAnswer } : {}),
522
- ...(params.maxAnswerReviews !== undefined ? { maxAnswerReviews: params.maxAnswerReviews } : {}),
523
- ...(params.structuredOutput ? { structuredOutput: params.structuredOutput } : {}),
524
- ...(params.parkRecordDelayMs !== undefined
525
- ? { parkRecordDelayMs: params.parkRecordDelayMs }
526
- : {}),
527
- tools: params.tools,
528
- allowedTools: effectiveAllowedTools,
529
- runMgr: ctx.runMgr,
530
- toolExecutor,
531
- guard,
532
- activityStore: ctx.activityStore,
533
- emitEvent: eventTranslator.emitEvent,
534
- drainPending: () => eventTranslator.drainPending(),
535
- abortController: ctx.abortController,
536
- log: ctx.log,
537
- // Read through the box on every call, so a swap lands on the next
538
- // question rather than the next run.
539
- resumeHandler: (request) => approvalPolicy.current.handler(request),
540
- takeApprovalPolicyChange: () => approvalPolicy.takeUnannouncedChange(),
541
- promptContributions,
542
- ...(params.steering ? { steering: params.steering } : {}),
543
- ...(jobNotices ? { jobNotices } : {}),
544
- ...(awaitedJobs ? { awaitedJobs } : {}),
545
- checkpointMgr,
546
- planManager: ctx.planManager,
547
- taskGateway: taskScheduler,
548
- completionInbox: params.completionInbox,
549
- taskStore: params.taskStore,
550
- // Run-scoped. An approval is a statement about this run's work;
551
- // carrying one into a later run would be reuse nobody agreed to.
552
- toolGrants: new ToolGrantSet(),
553
- // Run-scoped for the same reason. A repeat count carried into a later
554
- // run is a claim about work nobody repeated, and a module-level map
555
- // would leak exactly that way.
556
- ...(params.repeatCallAdvisory === false ? {} : { repeatCalls: new RepeatCallTracker() }),
557
- compactionConfig,
558
- ...(params.inboundMessages ? { inboundMessages: params.inboundMessages } : {}),
559
- ...(params.resumeFromCheckpoint ? { resumedInput: queuedForThisRun } : {}),
560
- ...(params.waitForInbound ? { waitForInbound: params.waitForInbound } : {}),
561
- ...(params.projectInstructionContext
562
- ? { projectInstructionContext: params.projectInstructionContext }
563
- : {}),
564
- ...(providerContextWindow !== undefined ? { providerContextWindow } : {}),
565
- resolveModelContextWindow: async (model) => {
566
- if (!modelContextWindows.has(model)) {
567
- modelContextWindows.set(model, await resolveProviderContextWindow(resilientProvider, model, ctx.abortController.signal, runConfig.timeoutMs, log));
167
+ if (!params.tools.has(SearchToolsTool.name)) {
168
+ const hasDeferred = params.tools
169
+ .listNames()
170
+ .some((n) => params.tools.getAvailability(n) === 'deferred');
171
+ if (hasDeferred) {
172
+ params.tools.register(SearchToolsTool);
568
173
  }
569
- return modelContextWindows.get(model);
570
- },
571
- workingStateManager,
572
- taskRouter: params.taskRouter,
573
- contextReducer: params.contextReducer,
574
- workingMemoryProvider: params.workingMemoryProvider,
575
- advisoryCtx,
576
- agentBus: params.agentBus,
577
- verificationGate,
578
- pluginManager: params.pluginManager,
579
- });
580
- const tracer = getTracer();
581
- // Whether the run reached its settle. Read by the `finally` below, and
582
- // the only thing that distinguishes a run that finished from one whose
583
- // consumer walked away — see `settleAbandonedRun`.
584
- let settled = false;
585
- const runBody = (async function* () {
586
- // Parent explicitly when a caller supplied one. Without this every
587
- // run starts its OWN root trace, so a supervisor delegating to three
588
- // children produced four disconnected traces instead of one tree —
589
- // the same defect that made a 20-turn run show up as 21 roots before
590
- // iterations were parented, except across the spawn boundary, where
591
- // it is worse: the delegation structure is the thing you most want
592
- // to see.
593
- const runStartedAt = Date.now();
594
- // Read before the span is minted, because a parent can only be set
595
- // at creation. A resumed run used to start a brand-new trace with no
596
- // link to the one that crashed, so the failure and its recovery
597
- // could not be put on one timeline — the run id correlated them well
598
- // enough to find both by query and not well enough to see a single
599
- // waterfall, and for a replay fork (which mints a new run id) not
600
- // even that. An explicit caller-supplied parent still wins: it is
601
- // the more specific statement about where this run belongs.
602
- const resumedTrace = selectedResumeState
603
- ? selectedResumeState.traceContext
604
- : params.resumeFromCheckpoint
605
- ? await checkpointMgr.readTraceContext(params.resumeFromCheckpoint)
606
- : undefined;
607
- const rootSpan = tracer.startSpan(agentRunSpanName(params.agentName), {}, parentContext(params.parentSpan ?? resumedTrace));
608
- // Hand the run span to the loop so every iteration parents to it.
609
- iterationOrchestrator.setRootSpan(rootSpan);
610
- // Every checkpoint from here on records the trace it was taken
611
- // inside, so the next resume can join this one.
612
- checkpointMgr.setTraceSource(() => serializeSpan(rootSpan));
613
- // And every park it records carries an absolute deadline, so an
614
- // unanswered approval cannot outlive the worker that asked for it.
615
- checkpointMgr.setParkTtl(runConfig.hitlParkTtlMs);
616
- // The claim this worker holds, if it took one. Without this hop the
617
- // fence exists, the refusal exists, and no checkpoint a RUN writes ever
618
- // carries a number — so a stalled worker is refused nowhere.
619
- checkpointMgr.setClaimFence(params.claimFence);
620
- // A question raised from inside a tool becomes a real checkpoint
621
- // here. It used to park under a synthetic id nothing ever wrote, so
622
- // the checkpoint did not exist: nothing on disk said a human owed
623
- // this run an answer, and a remote host could not observe the
624
- // question at all.
625
- questionParks.bind({
626
- record: async (question) => {
627
- try {
628
- const checkpoint = await checkpointMgr.create(ctx.runMgr, ctx.runMgr.currentIteration);
629
- const parked = await checkpointMgr.park(checkpoint, {
630
- type: 'user_question',
631
- runId: ctx.runMgr.id,
632
- checkpointId: checkpoint.id,
633
- question,
634
- });
635
- await eventTranslator.emitEvent({
636
- type: 'user_question_asked',
637
- runId: ctx.runMgr.id,
638
- checkpointId: parked.id,
639
- questionId: question.questionId,
640
- question: question.question,
641
- });
642
- return parked.id;
643
- }
644
- catch (err) {
645
- // A store that cannot record the park must not take the
646
- // tool down with it: the in-process await is still valid
647
- // and only the cross-process handoff is lost. Loudly,
648
- // because a host building an approval queue from durable
649
- // state will not see this question.
650
- ctx.log.error('Failed to record a question park — it is not resumable', {
651
- [NAMZU.RUN_ID]: ctx.runMgr.id,
652
- 'namzu.runtime.question_id': question.questionId,
653
- 'exception.message': err instanceof Error ? err.message : String(err),
654
- });
655
- return null;
656
- }
657
- },
658
- resolve: async (checkpointId, decision) => {
659
- await checkpointMgr.unpark(checkpointId, decision).catch((err) => {
660
- ctx.log.error('Failed to clear a recorded question park', {
661
- [NAMZU.RUN_ID]: ctx.runMgr.id,
662
- 'namzu.checkpoint.id': checkpointId,
663
- 'exception.message': err instanceof Error ? err.message : String(err),
664
- });
665
- return null;
666
- });
667
- await eventTranslator.emitEvent({
668
- type: 'user_question_answered',
669
- runId: ctx.runMgr.id,
670
- checkpointId,
671
- ...(decision.action === 'answer_question' && decision.questionId !== undefined
672
- ? { questionId: decision.questionId }
673
- : {}),
674
- answered: decision.action === 'answer_question',
174
+ }
175
+ // Registered HERE, before the first turn, not when the model is nearly
176
+ // done. Tools render at prefix position 0, so injecting one late would
177
+ // invalidate the whole prompt cache for the rest of the turn — the same
178
+ // reason the forced-final turn keeps its tools array and uses
179
+ // `toolChoice: 'none'` instead of dropping it.
180
+ if (params.structuredOutput &&
181
+ params.structuredOutput.mode !== 'native' &&
182
+ !params.tools.has(STRUCTURED_OUTPUT_TOOL_NAME)) {
183
+ params.tools.register(createStructuredOutputTool(params.structuredOutput.schema));
184
+ }
185
+ // ─── Provider capability negotiation (before tooling bootstrap) ────────
186
+ // Compare what the request asks for with what the DRIVER declared it
187
+ // does. Undeclared capabilities resolve permissively (today's behavior
188
+ // for third-party providers); declared gaps degrade loudly instead of
189
+ // silently.
190
+ const capabilities = resolveProviderCapabilities(params.provider);
191
+ const registeredToolCount = params.tools.listNames().length;
192
+ const stripToolSurfaces = !capabilities.supportsTools && registeredToolCount > 0;
193
+ // Counted separately because they are separate wire shapes: a driver can
194
+ // map images and drop documents, and a vision warning would send the
195
+ // reader looking at the wrong half.
196
+ const carries = (m, kind) => m.role === 'user' && (m.attachments ?? []).some((a) => (a.type ?? 'image') === kind);
197
+ const attachmentMessageCount = capabilities.supportsVision
198
+ ? 0
199
+ : params.messages.filter((m) => carries(m, 'image')).length;
200
+ const documentMessageCount = capabilities.supportsDocuments
201
+ ? 0
202
+ : params.messages.filter((m) => carries(m, 'document')).length;
203
+ if (stripToolSurfaces) {
204
+ const message = `Provider '${params.provider.id}' declares supportsTools: false but ${registeredToolCount} tool(s) are registered — stripping all tool surfaces from the prompt and request so the model is never told about tools it cannot call. Pass strictCapabilities: true to fail instead, or use a tools-capable provider.`;
205
+ if (params.strictCapabilities) {
206
+ throw new NamzuError({
207
+ code: 'capability_unavailable',
208
+ message,
209
+ details: {
210
+ providerId: params.provider.id,
211
+ capability: 'tools',
212
+ registeredToolCount,
213
+ },
675
214
  });
676
- },
677
- });
678
- rootSpan.setAttributes({
679
- [NAMZU.RUN_ID]: ctx.runMgr.id,
680
- [GENAI.AGENT_NAME]: params.agentName,
681
- [GENAI.AGENT_ID]: params.agentId,
682
- [GENAI.REQUEST_MODEL]: runConfig.model,
683
- [GENAI.SYSTEM]: params.provider.id,
684
- });
685
- let sandbox;
686
- // Decided during checkpoint restore, executed after the sandbox
687
- // exists — the approved tools may well need it.
688
- let pendingResume = null;
689
- /**
690
- * The cadence park this resume answered, when the decision is one the
691
- * ordinary continue path carries out. See the restore path below.
692
- */
693
- let answeredParkId;
694
- /** Tool results recovered from the transcript; see the restore path. */
695
- let recoveredResults = new Map();
696
- let emergencyManager;
697
- try {
698
- await ctx.runMgr.init();
699
- // A consumer coming back gets what it missed BEFORE the run says
700
- // anything new, which is the only order that lets it fold one
701
- // stream into one state. It has to follow `init()` — that is what
702
- // binds the store and reads the log's head — and precede every
703
- // emit below.
704
- if (params.eventCursor) {
705
- yield* catchUpFromCursor(ctx.runMgr, params.eventCursor, params.onEventReplay, params.claimFence, (error) => {
706
- ctx.log.warn('Replay observer failed', {
707
- 'exception.message': toErrorMessage(error),
708
- });
215
+ }
216
+ ctx.log.warn('Capability mismatch: the provider declares no tool support', {
217
+ 'namzu.capability.detail': message,
218
+ [GENAI.SYSTEM]: params.provider.id,
219
+ 'namzu.runtime.registered_tool_count': registeredToolCount,
220
+ });
221
+ }
222
+ if (attachmentMessageCount > 0) {
223
+ const message = `Provider '${params.provider.id}' declares supportsVision: false but ${attachmentMessageCount} user message(s) carry image attachments — the driver will not map them, so the model never sees the images. Pass strictCapabilities: true to fail instead, or use a vision-capable provider.`;
224
+ if (params.strictCapabilities) {
225
+ throw new NamzuError({
226
+ code: 'capability_unavailable',
227
+ message,
228
+ details: {
229
+ providerId: params.provider.id,
230
+ capability: 'vision',
231
+ attachmentMessageCount,
232
+ },
709
233
  });
710
234
  }
711
- ctx.log.info('Starting query', {
712
- [NAMZU.RUN_ID]: ctx.runMgr.id,
713
- 'namzu.runtime.agent': params.agentName,
714
- [GENAI.REQUEST_MODEL]: runConfig.model,
715
- 'namzu.runtime.token_budget': runConfig.tokenBudget,
716
- 'namzu.runtime.activity_tracking': ctx.activityStore.enabled,
717
- 'namzu.runtime.permission_mode': ctx.permissionMode.current,
718
- 'namzu.runtime.resume_from_checkpoint': params.resumeFromCheckpoint ?? null,
235
+ ctx.log.warn('Capability mismatch: the provider declares no vision support', {
236
+ 'namzu.capability.detail': message,
237
+ [GENAI.SYSTEM]: params.provider.id,
238
+ 'namzu.runtime.attachment_message_count': attachmentMessageCount,
719
239
  });
720
- // The operator's prompt, before the model sees it. A hook may
721
- // refuse it — the run ends here, before a prompt is built — or add
722
- // to what the model is told; the addition rides the prompt as a
723
- // dynamic contribution so every iteration of the run carries it.
724
- if (params.pluginManager) {
725
- const hookResults = await params.pluginManager.executeHooks('user_prompt_submit', {
726
- runId: ctx.runId,
727
- sessionId: params.sessionId,
728
- prompt: lastUserPrompt(initialMessages),
729
- signal: ctx.abortController.signal,
730
- }, eventTranslator.emitEvent);
731
- const annotations = applyLifecycleHookResults('user_prompt_submit', hookResults);
732
- if (annotations.length > 0) {
733
- promptContributions.replace({
734
- id: 'hooks:user_prompt_submit',
735
- placement: 'dynamic',
736
- render: () => `Context from the operator's hooks:\n\n${annotations.join('\n\n')}`,
737
- });
738
- }
739
- yield* eventTranslator.drainPending();
240
+ }
241
+ if (documentMessageCount > 0) {
242
+ const message = `Provider '${params.provider.id}' declares supportsDocuments: false but ${documentMessageCount} user message(s) carry document attachments — the driver will not map them, so the model never sees the documents. Pass strictCapabilities: true to fail instead, or use a document-capable provider.`;
243
+ if (params.strictCapabilities) {
244
+ throw new NamzuError({
245
+ code: 'capability_unavailable',
246
+ message,
247
+ details: {
248
+ providerId: params.provider.id,
249
+ capability: 'documents',
250
+ documentMessageCount,
251
+ },
252
+ });
740
253
  }
741
- const contextLevel = params.contextLevel ?? 'full';
742
- const cacheInput = {
743
- systemPrompt: params.systemPrompt,
744
- persona: params.persona,
745
- skills: params.skills,
746
- basePrompt: contextLevel === 'full' ? params.basePrompt : undefined,
747
- tools: params.tools,
748
- allowedTools: effectiveAllowedTools,
749
- runtimeContext: params.runtimeContext,
750
- contributions: promptContributions,
751
- };
752
- const segments = promptCache
753
- ? promptCache.getSystemPromptSegmented(cacheInput, contextLevel, params.workingDirectory)
754
- : promptBuilder.buildSegmented(contextLevel, params.workingDirectory);
755
- ctx.log.info('Prompt segments assembled', {
756
- 'namzu.runtime.static_length': segments.static.length,
757
- 'namzu.runtime.dynamic_length': segments.dynamic.length,
254
+ ctx.log.warn('Capability mismatch: the provider declares no document support', {
255
+ 'namzu.capability.detail': message,
256
+ [GENAI.SYSTEM]: params.provider.id,
257
+ 'namzu.runtime.document_message_count': documentMessageCount,
758
258
  });
759
- const pushSystemMessages = () => {
760
- ctx.runMgr.pushMessage(createSystemMessage(segments.static, 'cache'));
761
- if (segments.dynamic.length > 0) {
762
- ctx.runMgr.pushMessage(createSystemMessage(segments.dynamic, 'ephemeral'));
259
+ }
260
+ // Denied names are subtracted LAST, after the allow-list is resolved
261
+ // against the registry — so a deny reaches a turn that named no
262
+ // allow-list at all, which is the ordinary case for a delegated child.
263
+ // Applied to `effectiveAllowedTools`, which `query()` binds to both the
264
+ // request tool list AND the `ToolExecutor`: narrowing only the request
265
+ // shows the model fewer tools and lets it call any of them by name.
266
+ const allowedBeforeDenial = stripToolSurfaces
267
+ ? []
268
+ : withDeferredDiscoveryTool(params.tools, params.allowedTools);
269
+ const denied = new Set(params.deniedTools ?? []);
270
+ const effectiveAllowedTools = denied.size === 0
271
+ ? allowedBeforeDenial
272
+ : // An absent allow-list means "every registered tool", so a deny
273
+ // with no allow-list has to be resolved against the registry
274
+ // here — otherwise the subtraction would be from an empty list
275
+ // and would deny nothing, which is the shape a delegated child
276
+ // arrives in.
277
+ [...(allowedBeforeDenial ?? params.tools.listNames())].filter((name) => !denied.has(name));
278
+ // The two halves of a durable pause, owned by the TURN when the host
279
+ // does not own them.
280
+ //
281
+ // `SupervisorAgent` builds both before the turn exists, because the
282
+ // tools it builds close over them, and it passes them in. Nothing else
283
+ // could: neither type is exported from `public-runtime.ts`, so a host
284
+ // on `ReactiveAgent`, `drainQuery` or `resumeSession` had no way to supply
285
+ // either — and `ToolContext.requestPause`, which every tool author is
286
+ // handed, silently wrote no checkpoint and could receive no answer on
287
+ // those surfaces. Which agent class the host happened to pick is not
288
+ // visible at the call site, so the degradation was invisible too.
289
+ //
290
+ // A run-local pair is enough for the general seam because `query()`
291
+ // builds its `createToolPause` itself, below, and can hand it the
292
+ // run's own. Pinned by the "a pause is durable on any surface" cases
293
+ // in `__tests__/tool-pause-resume.test.ts`.
294
+ const questionParks = params.questionParks ?? new QuestionParkBinding();
295
+ const pendingAnswers = params.pendingAnswers ?? new PendingAnswers();
296
+ // One gate instance owns both model-issued calls and calls dispatched by
297
+ // another tool. Constructing it only inside the iteration review left the
298
+ // nested registry path outside the operator's policy entirely.
299
+ const gateConfig = params.authorizationGate;
300
+ const verificationGate = gateConfig?.enabled
301
+ ? new AuthorizationGate(gateConfig, ctx.log)
302
+ : undefined;
303
+ // Oversized tool output is spilled beside the session log
304
+ // (`<session-id>/tool-results/`). An in-memory session has nowhere to
305
+ // spill it, so the ordinary output budget applies.
306
+ const toolOutputDir = () => ctx.toolResultsDir;
307
+ // The same invocation-owned capability serves tools and optional preparation.
308
+ // Local cancellation cannot override the turn's cancellation or settled state.
309
+ const captureSessionEvidence = async (maxReadBytes, signal) => {
310
+ const combined = signal
311
+ ? AbortSignal.any([ctx.abortController.signal, signal])
312
+ : ctx.abortController.signal;
313
+ combined.throwIfAborted();
314
+ const source = await eventTranslator.captureSessionEvidence(maxReadBytes, combined);
315
+ combined.throwIfAborted();
316
+ return source;
317
+ };
318
+ // Whose jobs this turn speaks for: its own by default, the session's when
319
+ // the host said so. Resolved before the tools are built, because the
320
+ // wait-intent recorder below is bound into them.
321
+ const jobOwner = params.backgroundJobOwner ?? ctx.turnId;
322
+ // What the model reads when a job ends. Built up here, ahead of the
323
+ // subscription that fills it below, because the wait-intent recorder needs
324
+ // to ask whether its text has been read yet.
325
+ const jobNotices = params.backgroundJobs ? new SteeringBinding() : undefined;
326
+ // Jobs the model told `wait_for_job` it is waiting on, which is the only
327
+ // thing that can hold this turn open for a job. Built only where there is a
328
+ // registry, so a host with no background mode carries no recorder and the
329
+ // bound ref has no `markAwaited` to offer.
330
+ const awaitedJobs = params.backgroundJobs
331
+ ? new AwaitedJobs(params.backgroundJobs, jobOwner, () => jobNotices?.pending ?? false)
332
+ : undefined;
333
+ awaitedJobs?.attach();
334
+ const toolExecutor = ToolingBootstrap.init({
335
+ tools: params.tools,
336
+ sessionId: ctx.sessionId,
337
+ turnId: ctx.turnId,
338
+ workingDirectory: ctx.cwd,
339
+ ...(params.additionalDirectories?.length
340
+ ? { additionalDirectories: params.additionalDirectories }
341
+ : {}),
342
+ ...(params.outsideRootAccess ? { outsideRootAccess: params.outsideRootAccess } : {}),
343
+ ...(params.sandboxEscape ? { sandboxEscape: params.sandboxEscape } : {}),
344
+ permissionMode: () => ctx.permissionMode.current,
345
+ env: turnConfig.env ?? {},
346
+ abortSignal: ctx.abortController.signal,
347
+ allowedTools: effectiveAllowedTools,
348
+ invocationState: params.invocationState,
349
+ pluginManager: params.pluginManager,
350
+ ...(params.backgroundJobs ? { backgroundJobs: params.backgroundJobs } : {}),
351
+ ...(params.backgroundJobOwner ? { backgroundJobOwner: params.backgroundJobOwner } : {}),
352
+ ...(awaitedJobs ? { onJobAwaited: (id) => awaitedJobs.expect(id) } : {}),
353
+ // The `skill` tool's registry. Threaded from the turn rather than
354
+ // held by the tool, because a tool that reached for a module-level
355
+ // registry would answer about whatever the last turn configured.
356
+ ...(params.skillRegistry ? { skills: params.skillRegistry } : {}),
357
+ ...(params.web ? { web: params.web } : {}),
358
+ ...(params.fileReadTracker ? { fileReadTracker: params.fileReadTracker } : {}),
359
+ ...(params.toolTimeoutMs !== undefined ? { toolTimeoutMs: params.toolTimeoutMs } : {}),
360
+ ...(params.toolRetryBackoff !== undefined
361
+ ? { toolRetryBackoff: params.toolRetryBackoff }
362
+ : {}),
363
+ ...(params.maxToolCalls !== undefined
364
+ ? {
365
+ maxToolCalls: params.maxToolCalls,
366
+ readToolCallBudgetRecords: () => eventTranslator.readRecords({ mode: 'strict' }),
763
367
  }
764
- };
765
- if (params.resumeFromCheckpoint) {
766
- const checkpoint = await checkpointMgr.restore(params.resumeFromCheckpoint);
767
- const projectedCheckpoint = {
768
- ...checkpoint,
769
- messages: projectStateBearingHistory(checkpoint.messages, {
770
- pinCompaction: false,
771
- }),
368
+ : {}),
369
+ ...(params.maxToolConcurrency !== undefined
370
+ ? { maxToolConcurrency: params.maxToolConcurrency }
371
+ : {}),
372
+ ...(params.maxToolOutputChars !== undefined
373
+ ? { maxToolOutputChars: params.maxToolOutputChars }
374
+ : {}),
375
+ ...(params.toolResultGuardrails !== undefined
376
+ ? { toolResultGuardrails: params.toolResultGuardrails }
377
+ : {}),
378
+ ...(params.retainedToolPreviewChars !== undefined
379
+ ? { retainedToolPreviewChars: params.retainedToolPreviewChars }
380
+ : {}),
381
+ ...(params.maxToolContentBytes !== undefined
382
+ ? { maxToolContentBytes: params.maxToolContentBytes }
383
+ : {}),
384
+ // Overflow lands beside the turn's other artifacts, so it is
385
+ // cleaned up with the turn and reachable by the model's own
386
+ // `read`/`grep` without a new affordance.
387
+ toolOutputDir,
388
+ captureSessionEvidence,
389
+ ...(params.repairToolCall ? { repairToolCall: params.repairToolCall } : {}),
390
+ ...(verificationGate ? { authorizationGate: verificationGate } : {}),
391
+ recordAudit: (input) => ctx.recorder.recordAudit(input),
392
+ // The durable pause, reachable from any tool rather than from the
393
+ // four kernel-owned points that used to own it. Built here from
394
+ // the machinery the turn already holds; the recorder binds a few
395
+ // lines below, and until it does a pause is in-process only —
396
+ // the same degradation the built-in question tool has.
397
+ toolPause: (toolUseId) => createToolPause({
398
+ sessionId: ctx.sessionId,
399
+ turnId: ctx.turnId,
400
+ toolUseId,
401
+ parkHandler: (request) => approvalPolicy.current.handler(request),
402
+ recorder: questionParks,
403
+ pendingAnswers,
404
+ }),
405
+ }, ctx.activityStore, eventTranslator.emitEvent, ctx.log);
406
+ // A background job's exit reaches the model as a notice on its next tool
407
+ // result, and the host as an event — without either polling. Subscribed
408
+ // for the owner the turn's jobs are bound to, so a session-owned job that
409
+ // ends during this turn is reported here too.
410
+ const unsubscribeJobExits = params.backgroundJobs?.onExit((job) => {
411
+ if (job.owner !== jobOwner)
412
+ return;
413
+ const outcome = job.status === 'killed'
414
+ ? 'was stopped'
415
+ : `exited with code ${job.exitCode ?? 'unknown'}${job.signal ? ` (${job.signal})` : ''}`;
416
+ jobNotices?.steer(`Background job ${job.id} (${job.command}) ${outcome}. Read its output with the job tool if you need it.`);
417
+ void eventTranslator
418
+ .emitEvent({
419
+ type: 'background_job_exited',
420
+ turnId: ctx.turnId,
421
+ jobId: job.id,
422
+ command: job.command,
423
+ status: job.status === 'killed' ? 'killed' : 'exited',
424
+ ...(job.exitCode !== undefined ? { exitCode: job.exitCode } : {}),
425
+ ...(job.signal ? { signal: job.signal } : {}),
426
+ })
427
+ .catch(() => { });
428
+ });
429
+ let workingStateManager;
430
+ // Normalised once, defaults applied. A host that passes a partial
431
+ // object — a strategy and a window, nothing else — used to reach the
432
+ // phase with `triggerThreshold` undefined, and `usage < undefined` is
433
+ // false: the pass ran on every iteration and the salience strategy fell
434
+ // through to the stale-result clearing it exists to replace. The eval
435
+ // suite that passed exactly that object found it.
436
+ const compactionConfig = params.compactionConfig
437
+ ? CompactionConfigSchema.parse(params.compactionConfig)
438
+ : undefined;
439
+ if (compactionConfig && compactionConfig.strategy !== 'disabled') {
440
+ workingStateManager = new WorkingStateManager(compactionConfig);
441
+ toolExecutor.setWorkingStateManager(workingStateManager);
442
+ }
443
+ // The turn's own registry when the host passed none, so a hook's
444
+ // annotation has somewhere to land.
445
+ const promptContributions = params.promptContributions ?? new PromptContributionRegistry();
446
+ const promptBuilder = new PromptBuilder({
447
+ systemPrompt: params.systemPrompt,
448
+ persona: params.persona,
449
+ skills: params.skills,
450
+ basePrompt: params.basePrompt,
451
+ tools: params.tools,
452
+ allowedTools: effectiveAllowedTools,
453
+ runtimeContext: params.runtimeContext,
454
+ contributions: promptContributions,
455
+ });
456
+ const guard = new GuardCoordinator({
457
+ tokenBudget: turnConfig.tokenBudget,
458
+ timeoutMs: turnConfig.timeoutMs,
459
+ costLimitUsd: turnConfig.costLimitUsd,
460
+ maxIterations: turnConfig.maxIterations,
461
+ });
462
+ const checkpointMgr = new CheckpointManager(ctx.recorder, ctx.storage.checkpoints, {
463
+ tenantId: ctx.tenantId,
464
+ projectId: ctx.projectId,
465
+ sessionId: ctx.sessionId,
466
+ turnId: ctx.turnId,
467
+ });
468
+ // Every checkpoint carries compaction's accumulated state, so a turn that
469
+ // comes back in a new process can adopt it (see the restore block).
470
+ // Without it, compaction's own justification for dropping the prior
471
+ // `[COMPACTED CONTEXT]` block — that `serializeState` is cumulative —
472
+ // holds within one process and fails across a resume.
473
+ if (workingStateManager) {
474
+ const manager = workingStateManager;
475
+ checkpointMgr.setWorkingStateSource(() => snapshotWorkingState(manager));
476
+ }
477
+ const resultAssembler = new ResultAssembler({
478
+ recorder: ctx.recorder,
479
+ planManager: ctx.planManager,
480
+ activityStore: ctx.activityStore,
481
+ log: ctx.log,
482
+ emitEvent: eventTranslator.emitEvent,
483
+ drainPending: () => eventTranslator.drainPending(),
484
+ // Read at settle time, not now: checkpoints are written per
485
+ // iteration, so the answer changes as the turn proceeds. A turn
486
+ // that fails before writing one (a 429 on its first request)
487
+ // commits the state its loop began from, so it pauses like any
488
+ // later failure rather than failing with nothing to resume.
489
+ resumeCheckpointId: async () => checkpointMgr.lastCheckpointId ?? (await checkpointMgr.createAtLoopStart(ctx.recorder))?.id,
490
+ // Read only to recover WHY a cancellation happened. The turn loop
491
+ // already knows THAT it was cancelled; the origin lives on the abort
492
+ // reason and nothing else carries it this far.
493
+ signal: ctx.abortController.signal,
494
+ });
495
+ let advisoryCtx;
496
+ if (params.advisory && params.advisory.advisors.length > 0) {
497
+ // Advisors are model calls owned by this turn even when they use a
498
+ // different provider. Sending the raw definitions into the registry
499
+ // lets a triggered or model-requested consultation bypass both the
500
+ // finite stream-silence bound and Stop. Bind every advisor provider at
501
+ // the query boundary, where the effective timeout and run signal are
502
+ // already known; standalone AdvisoryExecutor callers retain their
503
+ // explicitly chosen provider/cancellation policy.
504
+ const boundedAdvisors = params.advisory.advisors.map((advisor) => ({
505
+ ...advisor,
506
+ provider: withTokenBudget(withStreamIdleTimeout(advisor.provider, {
507
+ idleTimeoutMs: streamIdleTimeoutMs,
508
+ log: ctx.log,
509
+ }), budget),
510
+ }));
511
+ const advisorRegistry = new AdvisorRegistry(boundedAdvisors, params.advisory.defaultAdvisorId);
512
+ // A budget the runtime cannot measure is refused here rather than
513
+ // silently ignored for the length of the turn.
514
+ assertBudgetEnforceable(params.advisory);
515
+ const advisoryExecutor = new AdvisoryExecutor(ctx.log, params.advisory.budget, ctx.abortController.signal);
516
+ const triggerEvaluator = new TriggerEvaluator(params.advisory.triggers ?? [], params.advisory.budget);
517
+ advisoryCtx = new AdvisoryContext(advisorRegistry, advisoryExecutor, triggerEvaluator, params.advisory.budget);
518
+ // What the turn looks like when the MODEL consults an advisor, as
519
+ // opposed to when a trigger does. The trigger path has always passed
520
+ // this; the tool path passed an empty context, so an advisor the model
521
+ // asked for help saw the question and nothing else.
522
+ //
523
+ // `includeToolCatalog` and `useCompactedContext` are read here and
524
+ // nowhere else. Both were declared on `AdvisoryConfig` /
525
+ // `AdvisorDefinition` and consulted by nothing, so a host who turned
526
+ // the catalogue off still paid for it in every advisory prompt.
527
+ const advisoryConfig = params.advisory;
528
+ advisoryCtx.setCallContextProvider(() => {
529
+ const summary = workingStateManager && advisoryConfig.advisors.some((a) => a.useCompactedContext)
530
+ ? serializeWorkingState(workingStateManager.getState())
531
+ : undefined;
532
+ return {
533
+ messages: ctx.recorder.messages,
534
+ turn: iterationOrchestrator.getAdvisoryTurnContext(),
535
+ ...(summary !== undefined ? { workingStateSummary: summary } : {}),
536
+ ...(advisoryConfig.includeToolCatalog
537
+ ? { toolCatalog: params.tools.toLLMTools(effectiveAllowedTools) }
538
+ : {}),
539
+ iteration: ctx.recorder.currentIteration,
772
540
  };
773
- await eventTranslator.emitEvent({
774
- type: 'run_resuming',
775
- runId: ctx.runMgr.id,
776
- fromCheckpointId: checkpoint.id,
777
- });
778
- yield* eventTranslator.drainPending();
779
- // Budgets are properties of the RUN, not of the process hosting
780
- // it. The checkpoint already carried all three; they were
781
- // written and then discarded on the way back in, so a run
782
- // recalled at $4.80 of a $5 cap came back with a fresh $5 and
783
- // a fresh timeout clock. Restore before the first iteration so
784
- // a resumed run that is already over budget stops immediately.
785
- ctx.runMgr.restoreUsage(checkpoint.tokenUsage, checkpoint.costInfo, checkpoint.guardState.iterationCount);
786
- guard.restoreElapsed(checkpoint.guardState.elapsedMs);
787
- // Adopt the working state the earlier summary was built from.
788
- // The `[COMPACTED CONTEXT]` block below is preserved precisely
789
- // because it is the only surviving record of the history the
790
- // first pass deleted — and without this, the NEXT compaction
791
- // would drop it and replace it with a summary covering only
792
- // what happened after the resume, silently losing the run's
793
- // first hour.
794
- if (workingStateManager && checkpoint.workingState && compactionConfig) {
795
- const revived = restoreWorkingState(checkpoint.workingState, compactionConfig);
796
- workingStateManager.replaceState(revived.getState());
797
- ctx.log.info('Restored compaction working state from checkpoint', {
798
- [NAMZU.RUN_ID]: ctx.runMgr.id,
799
- 'namzu.checkpoint.id': checkpoint.id,
800
- 'namzu.runtime.slots': workingStateManager.slotCount(),
801
- });
541
+ });
542
+ if (params.advisory.enableAgentTool) {
543
+ const advisoryTools = buildAdvisoryTools({ advisoryCtx });
544
+ const overrides = params.runtimeToolOverrides;
545
+ for (const tool of advisoryTools) {
546
+ const override = overrides?.[tool.name];
547
+ if (override === 'disabled')
548
+ continue;
549
+ params.tools.register(tool, override ?? 'active');
802
550
  }
803
- ctx.log.info('Restored budgets from checkpoint', {
804
- [NAMZU.RUN_ID]: ctx.runMgr.id,
805
- 'namzu.checkpoint.id': checkpoint.id,
806
- 'namzu.usage.total_tokens': checkpoint.tokenUsage.totalTokens,
807
- 'namzu.runtime.total_cost': checkpoint.costInfo.totalCost,
808
- [NAMZU.ITERATION]: checkpoint.guardState.iterationCount,
809
- 'namzu.runtime.elapsed_ms': checkpoint.guardState.elapsedMs,
810
- });
811
- pushSystemMessages();
812
- // A human answered the park in a different process; apply that
813
- // answer to the tool calls they were actually shown. Without
814
- // this the repair below throws the approval away and the model
815
- // re-decides, so "yes, delete that row" degrades into "ask
816
- // again and hope it asks for the same thing".
817
- pendingResume =
818
- params.pendingDecision && projectedCheckpoint.pending
819
- ? planPendingResume(projectedCheckpoint, params.pendingDecision, ctx.log)
820
- : null;
821
- // The park this resume ANSWERS even though there is no plan to
822
- // carry the decision out through.
823
- //
824
- // `planPendingResume` covers the two arms whose decision has to
825
- // reach something — the calls a `tool_review` park is about, the
826
- // tool a `user_question` park is inside. An `iteration_checkpoint`
827
- // park has neither, so it returns no plan, and the unpark further
828
- // down — which ran only when there was one — never fired for it.
829
- // A run that parked on the cadence, was resumed with
830
- // `{action: 'continue'}` and went on to finish its work therefore
831
- // kept reporting an OUTSTANDING park to `findPendingCheckpoint`,
832
- // so a second resume of the finished run was refused with
833
- // `awaiting-decision` for a decision already taken, and because
834
- // `prune` skips an unresolved park the row could no longer be
835
- // collected by anything.
836
- //
837
- // The decision IS carried out here — continuing is exactly what
838
- // the loop below does, and a plan verdict is the answer to the
839
- // question the plan park asked — so the park is resolved at the
840
- // same point and with the same meaning "resolved" carries
841
- // everywhere else: the record stays, and only its pending state
842
- // ends. A `pause` is deliberately not resolved: it holds the
843
- // park rather than answering it, which is how the live path
844
- // treats it too. `answersParkOf` is the whole map, park type to
845
- // answering decision, so an arm cannot go missing by being
846
- // absent from a condition again — which is how the plan arm
847
- // leaked a finished run's park.
848
- //
849
- // Resolving it does not depend on the resumed process being able
850
- // to act on it, and that is deliberate: the plan's own fate is a
851
- // separate defect (nothing restores a plan on the resume path at
852
- // all, so the new process has none to approve, execute or
853
- // reject) and making the resolution wait for it would leave the
854
- // row outstanding for exactly the runs that need it cleared.
855
- const parked = projectedCheckpoint.pending;
856
- answeredParkId =
857
- params.pendingDecision &&
858
- parked !== undefined &&
859
- parked.resolvedAt === undefined &&
860
- answersParkOf(parked.request.type, params.pendingDecision)
861
- ? projectedCheckpoint.id
862
- : undefined;
863
- // Recover completed observations and explicitly unknown outcomes.
864
- // A recorded start is not proof that its external effect failed.
865
- const unanswered = interruptedToolCalls(projectedCheckpoint.messages);
866
- recoveredResults =
867
- unanswered.length > 0
868
- ? await recoverCompletedCalls(ctx.runMgr, unanswered, ctx.log, {
869
- answers: pendingResume?.answers,
870
- signal: ctx.abortController.signal,
871
- })
872
- : new Map();
873
- // Preserve both known and unknown outcomes before continuing calls
874
- // whose absence of a start was established by a complete scan.
875
- if (!pendingResume && recoveredResults.size > 0) {
876
- pendingResume = planCrashResume(projectedCheckpoint, recoveredResults, ctx.log);
551
+ }
552
+ }
553
+ const iterationOrchestrator = new IterationOrchestrator({
554
+ captureSessionEvidence,
555
+ provider: resilientProvider,
556
+ providerCapabilities: capabilities,
557
+ strictCapabilities: params.strictCapabilities === true,
558
+ servingMember: () => serving.current,
559
+ turnConfig,
560
+ ...(params.stopWhen ? { stopWhen: params.stopWhen } : {}),
561
+ ...(params.prepareStep ? { prepareStep: params.prepareStep } : {}),
562
+ ...(params.beforeStep ? { beforeStep: params.beforeStep } : {}),
563
+ ...(params.onStepFinish ? { onStepFinish: params.onStepFinish } : {}),
564
+ ...(params.reviewAnswer ? { reviewAnswer: params.reviewAnswer } : {}),
565
+ ...(params.maxAnswerReviews !== undefined
566
+ ? { maxAnswerReviews: params.maxAnswerReviews }
567
+ : {}),
568
+ ...(params.structuredOutput ? { structuredOutput: params.structuredOutput } : {}),
569
+ ...(params.parkRecordDelayMs !== undefined
570
+ ? { parkRecordDelayMs: params.parkRecordDelayMs }
571
+ : {}),
572
+ tools: params.tools,
573
+ allowedTools: effectiveAllowedTools,
574
+ recorder: ctx.recorder,
575
+ toolExecutor,
576
+ guard,
577
+ activityStore: ctx.activityStore,
578
+ emitEvent: eventTranslator.emitEvent,
579
+ drainPending: () => eventTranslator.drainPending(),
580
+ abortController: ctx.abortController,
581
+ log: ctx.log,
582
+ // Read through the box on every call, so a swap lands on the next
583
+ // question rather than the next turn.
584
+ resumeHandler: (request) => approvalPolicy.current.handler(request),
585
+ takeApprovalPolicyChange: () => approvalPolicy.takeUnannouncedChange(),
586
+ promptContributions,
587
+ ...(params.steering ? { steering: params.steering } : {}),
588
+ ...(jobNotices ? { jobNotices } : {}),
589
+ ...(awaitedJobs ? { awaitedJobs } : {}),
590
+ checkpointMgr,
591
+ planManager: ctx.planManager,
592
+ taskGateway: taskScheduler,
593
+ completionInbox: params.completionInbox,
594
+ taskStore: params.taskStore,
595
+ // Turn-scoped. An approval is a statement about this turn's work;
596
+ // carrying one into a later turn would be reuse nobody agreed to.
597
+ toolGrants: new ToolGrantSet(),
598
+ // Turn-scoped for the same reason. A repeat count carried into a later
599
+ // run is a claim about work nobody repeated, and a module-level map
600
+ // would leak exactly that way.
601
+ ...(params.repeatCallAdvisory === false ? {} : { repeatCalls: new RepeatCallTracker() }),
602
+ compactionConfig,
603
+ ...(params.inboundMessages ? { inboundMessages: params.inboundMessages } : {}),
604
+ ...(params.resumeFromCheckpoint ? { resumedInput: queuedForThisRun } : {}),
605
+ ...(params.waitForInbound ? { waitForInbound: params.waitForInbound } : {}),
606
+ ...(params.projectInstructionContext
607
+ ? { projectInstructionContext: params.projectInstructionContext }
608
+ : {}),
609
+ ...(providerContextWindow !== undefined ? { providerContextWindow } : {}),
610
+ resolveModelContextWindow: async (model) => {
611
+ if (!modelContextWindows.has(model)) {
612
+ modelContextWindows.set(model, await resolveProviderContextWindow(resilientProvider, model, ctx.abortController.signal, turnConfig.timeoutMs, log));
877
613
  }
878
- // An incomplete turn with a durable owner is NOT abandoned. A
879
- // pending decision or crash-resume plan re-appends that exact
880
- // assistant with real/denied/recovered results below. Remove it
881
- // from the generic pass so no synthetic result competes with the
882
- // authority that still owns the call. Everything else is abandoned
883
- // history and is repaired conservatively rather than deleted.
884
- const abandonedCheckpointMessages = pendingResume
885
- ? withoutOwnedResumeTurn(projectedCheckpoint.messages, pendingResume.assistant)
886
- : projectedCheckpoint.messages;
887
- const checkpointRepair = repairToolMessageHistory(abandonedCheckpointMessages);
888
- const restoredMessages = checkpointRepair.messages;
889
- if (toolHistoryRepairChanged(checkpointRepair.report)) {
890
- pendingHistoryRepairs.push({
891
- source: 'abandoned-checkpoint',
892
- report: checkpointRepair.report,
614
+ return modelContextWindows.get(model);
615
+ },
616
+ workingStateManager,
617
+ taskRouter: params.taskRouter,
618
+ contextReducer: params.contextReducer,
619
+ workingMemoryProvider: params.workingMemoryProvider,
620
+ advisoryCtx,
621
+ agentBus: params.agentBus,
622
+ verificationGate,
623
+ pluginManager: params.pluginManager,
624
+ });
625
+ const tracer = getTracer();
626
+ // Whether the turn reached its settle. Read by the `finally` below, and
627
+ // the only thing that distinguishes a turn that finished from one whose
628
+ // consumer walked away — see `settleAbandonedTurn`.
629
+ let settled = false;
630
+ const runBody = (async function* () {
631
+ // Parent explicitly when a caller supplied one. Without this every
632
+ // run starts its OWN root trace, so a supervisor delegating to three
633
+ // children produced four disconnected traces instead of one tree —
634
+ // the same defect that made a 20-turn run show up as 21 roots before
635
+ // iterations were parented, except across the spawn boundary, where
636
+ // it is worse: the delegation structure is the thing you most want
637
+ // to see.
638
+ const runStartedAt = Date.now();
639
+ // Read before the span is minted, because a parent can only be set
640
+ // at creation. A resumed turn used to start a brand-new trace with no
641
+ // link to the one that crashed, so the failure and its recovery
642
+ // could not be put on one timeline — the turn id correlated them well
643
+ // enough to find both by query and not well enough to see a single
644
+ // waterfall, and for a replay fork (which mints a new turn id) not
645
+ // even that. An explicit caller-supplied parent still wins: it is
646
+ // the more specific statement about where this turn belongs.
647
+ const resumedTrace = selectedResumeState
648
+ ? selectedResumeState.traceContext
649
+ : params.resumeFromCheckpoint
650
+ ? await checkpointMgr.readTraceContext(params.resumeFromCheckpoint)
651
+ : undefined;
652
+ const rootSpan = tracer.startSpan(agentTurnSpanName(params.agentName), {}, parentContext(params.parentSpan ?? resumedTrace));
653
+ // Hand the turn span to the loop so every iteration parents to it.
654
+ iterationOrchestrator.setRootSpan(rootSpan);
655
+ // Every checkpoint from here on records the trace it was taken
656
+ // inside, so the next resume can join this one.
657
+ checkpointMgr.setTraceSource(() => serializeSpan(rootSpan));
658
+ // And every park it records carries an absolute deadline, so an
659
+ // unanswered approval cannot outlive the worker that asked for it.
660
+ checkpointMgr.setParkTtl(turnConfig.hitlParkTtlMs);
661
+ // A question raised from inside a tool becomes a real checkpoint
662
+ // here. It used to park under a synthetic id nothing ever wrote, so
663
+ // the checkpoint did not exist: nothing on disk said a human owed
664
+ // this turn an answer, and a remote host could not observe the
665
+ // question at all.
666
+ questionParks.bind({
667
+ record: async (question) => {
668
+ try {
669
+ const checkpoint = await checkpointMgr.create(ctx.recorder, ctx.recorder.currentIteration);
670
+ await checkpointMgr.park(checkpoint, {
671
+ type: 'user_question',
672
+ sessionId: ctx.sessionId,
673
+ turnId: ctx.turnId,
674
+ checkpointId: checkpoint.id,
675
+ question,
676
+ });
677
+ await eventTranslator.emitEvent({
678
+ type: 'user_question_asked',
679
+ checkpointId: checkpoint.id,
680
+ questionId: question.questionId,
681
+ question: question.question,
682
+ });
683
+ return checkpoint.id;
684
+ }
685
+ catch (err) {
686
+ // A store that cannot record the park must not take the
687
+ // tool down with it: the in-process await is still valid
688
+ // and only the cross-process handoff is lost. Loudly,
689
+ // because a host building an approval queue from durable
690
+ // state will not see this question.
691
+ ctx.log.error('Failed to record a question park — it is not resumable', {
692
+ [NAMZU.TURN_ID]: ctx.recorder.turnId,
693
+ 'namzu.runtime.question_id': question.questionId,
694
+ 'exception.message': err instanceof Error ? err.message : String(err),
695
+ });
696
+ return null;
697
+ }
698
+ },
699
+ resolve: async (checkpointId, decision) => {
700
+ await checkpointMgr.unpark(checkpointId, decision).catch((err) => {
701
+ ctx.log.error('Failed to clear a recorded question park', {
702
+ [NAMZU.TURN_ID]: ctx.recorder.turnId,
703
+ 'namzu.checkpoint.id': checkpointId,
704
+ 'exception.message': err instanceof Error ? err.message : String(err),
705
+ });
706
+ return null;
893
707
  });
894
- ctx.log.warn('Repaired abandoned tool history while restoring a checkpoint', {
895
- [NAMZU.RUN_ID]: ctx.runMgr.id,
896
- 'namzu.checkpoint.id': checkpoint.id,
897
- 'namzu.history.source': 'abandoned-checkpoint',
898
- 'namzu.history.duplicate_tool_results_removed': checkpointRepair.report.duplicateToolResultsRemoved,
899
- 'namzu.history.orphaned_tool_results_removed': checkpointRepair.report.orphanedToolResultsRemoved,
900
- 'namzu.history.synthetic_tool_results_inserted': checkpointRepair.report.syntheticToolResultsInserted,
708
+ await eventTranslator.emitEvent({
709
+ type: 'user_question_answered',
710
+ checkpointId,
711
+ ...(decision.action === 'answer_question' && decision.questionId !== undefined
712
+ ? { questionId: decision.questionId }
713
+ : {}),
714
+ answered: decision.action === 'answer_question',
715
+ });
716
+ },
717
+ });
718
+ rootSpan.setAttributes({
719
+ [GENAI.CONVERSATION_ID]: ctx.sessionId,
720
+ [NAMZU.TURN_ID]: ctx.recorder.turnId,
721
+ ...(params.parentSessionId !== undefined && {
722
+ [NAMZU.SESSION_PARENT_ID]: params.parentSessionId,
723
+ }),
724
+ [GENAI.AGENT_NAME]: params.agentName,
725
+ [GENAI.AGENT_ID]: params.agentId,
726
+ [GENAI.REQUEST_MODEL]: turnConfig.model,
727
+ [GENAI.SYSTEM]: params.provider.id,
728
+ });
729
+ let sandbox;
730
+ // Decided during checkpoint restore, executed after the sandbox
731
+ // exists — the approved tools may well need it.
732
+ let pendingResume = null;
733
+ /** The record id of the parked assistant message the plan re-appends. */
734
+ let pendingResumeAssistantId;
735
+ /**
736
+ * The cadence park this resume answered, when the decision is one the
737
+ * ordinary continue path carries out. See the restore path below.
738
+ */
739
+ let answeredParkId;
740
+ /** Tool results recovered from the transcript; see the restore path. */
741
+ let recoveredResults = new Map();
742
+ try {
743
+ // A consumer coming back gets what it missed BEFORE the turn says
744
+ // anything new, which is the only order that lets it fold one
745
+ // stream into one state. It follows the prelude's `open()` — which
746
+ // took the lease and read the log's head — and precedes every emit
747
+ // below.
748
+ if (params.eventCursor) {
749
+ yield* catchUpFromCursor(ctx.recorder, params.eventCursor, params.onEventReplay, (error) => {
750
+ ctx.log.warn('Replay observer failed', {
751
+ 'exception.message': toErrorMessage(error),
752
+ });
901
753
  });
902
754
  }
903
- // The ledger is process state and a resumed run starts with an empty
904
- // one, so until something reads a file again this run knows nothing
905
- // about files the conversation already wrote in full — and re-reads
906
- // them. Rebuilt from the REPAIRED history, which is what the model
907
- // is about to be shown, rather than from the checkpoint's own
908
- // messages — plus whatever of the owned resume turn actually ran,
909
- // which the repaired list does not carry; see
910
- // `withOwnedResumeOutcomes`. Reads no file's content: every
911
- // fingerprint recovered here is still checked against the real one
912
- // at mutation time.
913
- try {
914
- await toolExecutor.seedFileObservations(pendingResume
915
- ? withOwnedResumeOutcomes(restoredMessages, pendingResume.assistant, recoveredResults)
916
- : restoredMessages, params.sandboxProvider !== undefined);
755
+ ctx.log.info('Starting query', {
756
+ [NAMZU.TURN_ID]: ctx.recorder.turnId,
757
+ 'namzu.runtime.agent': params.agentName,
758
+ [GENAI.REQUEST_MODEL]: turnConfig.model,
759
+ 'namzu.runtime.token_budget': turnConfig.tokenBudget,
760
+ 'namzu.runtime.activity_tracking': ctx.activityStore.enabled,
761
+ 'namzu.runtime.permission_mode': ctx.permissionMode.current,
762
+ 'namzu.runtime.resume_from_checkpoint': params.resumeFromCheckpoint ?? null,
763
+ });
764
+ // The operator's prompt, before the model sees it. A hook may
765
+ // refuse it — the turn ends here, before a prompt is built — or add
766
+ // to what the model is told; the addition rides the prompt as a
767
+ // dynamic contribution so every iteration of the turn carries it.
768
+ if (params.pluginManager) {
769
+ const hookResults = await params.pluginManager.executeHooks('user_prompt_submit', {
770
+ turnId: ctx.turnId,
771
+ sessionId: params.sessionId,
772
+ prompt: lastUserPrompt(initialMessages),
773
+ signal: ctx.abortController.signal,
774
+ }, eventTranslator.emitEvent);
775
+ const annotations = applyLifecycleHookResults('user_prompt_submit', hookResults);
776
+ if (annotations.length > 0) {
777
+ promptContributions.replace({
778
+ id: 'hooks:user_prompt_submit',
779
+ placement: 'dynamic',
780
+ render: () => `Context from the operator's hooks:\n\n${annotations.join('\n\n')}`,
781
+ });
782
+ }
783
+ yield* eventTranslator.drainPending();
917
784
  }
918
- catch (err) {
919
- // A ledger that could not be rebuilt is the empty one every resume
920
- // used to get, so the run continues without its witnesses and the
921
- // model reads what it needs. Failing the resume over it would trade
922
- // a conversation that works for one that does not, to protect an
923
- // optimisation. Said out loud all the same, because a seeding that
924
- // failed and one that found nothing are otherwise the same silence.
925
- ctx.log.debug('Could not rebuild the file observation ledger on resume', {
926
- [NAMZU.RUN_ID]: ctx.runMgr.id,
785
+ const contextLevel = params.contextLevel ?? 'full';
786
+ const cacheInput = {
787
+ systemPrompt: params.systemPrompt,
788
+ persona: params.persona,
789
+ skills: params.skills,
790
+ basePrompt: contextLevel === 'full' ? params.basePrompt : undefined,
791
+ tools: params.tools,
792
+ allowedTools: effectiveAllowedTools,
793
+ runtimeContext: params.runtimeContext,
794
+ contributions: promptContributions,
795
+ };
796
+ const segments = promptCache
797
+ ? promptCache.getSystemPromptSegmented(cacheInput, contextLevel, params.workingDirectory)
798
+ : promptBuilder.buildSegmented(contextLevel, params.workingDirectory);
799
+ ctx.log.info('Prompt segments assembled', {
800
+ 'namzu.runtime.static_length': segments.static.length,
801
+ 'namzu.runtime.dynamic_length': segments.dynamic.length,
802
+ });
803
+ // The prompt floor is rebuilt every turn and never recorded:
804
+ // `turn_started.systemPrompt` carries it.
805
+ const pushSystemMessages = () => {
806
+ ctx.recorder.pushMessage(createSystemMessage(segments.static, 'cache'), {
807
+ transient: true,
808
+ });
809
+ if (segments.dynamic.length > 0) {
810
+ ctx.recorder.pushMessage(createSystemMessage(segments.dynamic, 'ephemeral'), {
811
+ transient: true,
812
+ });
813
+ }
814
+ };
815
+ const pushRestored = (message, ids) => {
816
+ const messageId = ids.get(message);
817
+ ctx.recorder.pushMessage(message, messageId ? { messageId } : {});
818
+ };
819
+ if (params.resumeFromCheckpoint) {
820
+ const checkpoint = await checkpointMgr.restore(params.resumeFromCheckpoint);
821
+ const projectedCheckpoint = {
822
+ ...checkpoint,
823
+ messages: projectStateBearingHistory(checkpoint.messages, {
824
+ pinCompaction: false,
825
+ }),
826
+ };
827
+ await eventTranslator.resumeTurn(checkpoint.id);
828
+ yield* eventTranslator.drainPending();
829
+ // Budgets are properties of the TURN, not of the process hosting
830
+ // it. The checkpoint already carried all three; they were
831
+ // written and then discarded on the way back in, so a turn
832
+ // recalled at $4.80 of a $5 cap came back with a fresh $5 and
833
+ // a fresh timeout clock. Restore before the first iteration so
834
+ // a resumed turn that is already over budget stops immediately.
835
+ ctx.recorder.restoreUsage(checkpoint.document.tokenUsage, checkpoint.document.costInfo, checkpoint.document.guards.iteration);
836
+ guard.restoreElapsed(checkpoint.document.guards.elapsedMs);
837
+ // Adopt the working state the earlier summary was built from.
838
+ // The `[COMPACTED CONTEXT]` block below is preserved precisely
839
+ // because it is the only surviving record of the history the
840
+ // first pass deleted — and without this, the NEXT compaction
841
+ // would drop it and replace it with a summary covering only
842
+ // what happened after the resume, silently losing the turn's
843
+ // first hour.
844
+ if (workingStateManager && checkpoint.document.workingState && compactionConfig) {
845
+ const revived = restoreWorkingState(checkpoint.document.workingState, compactionConfig);
846
+ workingStateManager.replaceState(revived.getState());
847
+ ctx.log.info('Restored compaction working state from checkpoint', {
848
+ [NAMZU.TURN_ID]: ctx.recorder.turnId,
849
+ 'namzu.checkpoint.id': checkpoint.id,
850
+ 'namzu.runtime.slots': workingStateManager.slotCount(),
851
+ });
852
+ }
853
+ ctx.log.info('Restored budgets from checkpoint', {
854
+ [NAMZU.TURN_ID]: ctx.recorder.turnId,
927
855
  'namzu.checkpoint.id': checkpoint.id,
928
- 'exception.message': err instanceof Error ? err.message : String(err),
856
+ 'namzu.usage.total_tokens': checkpoint.document.tokenUsage.totalTokens,
857
+ 'namzu.runtime.total_cost': checkpoint.document.costInfo.totalCost,
858
+ [NAMZU.ITERATION]: checkpoint.document.guards.iteration,
859
+ 'namzu.runtime.elapsed_ms': checkpoint.document.guards.elapsedMs,
929
860
  });
930
- }
931
- for (const msg of restoredMessages) {
932
- if (msg.role === 'system') {
933
- // Re-push the FRESH static/dynamic floor (done above) but PRESERVE
934
- // the two system messages that carry irreplaceable run state: the
935
- // `[COMPACTED CONTEXT]` summary is the only surviving record of the
936
- // older history a compaction pass deleted, and the working-memory
937
- // slot pins the produced-artifact ledger. Dropping every system
938
- // message on restore silently lost both on resume.
939
- if (isCompactionMessage(msg.content) || isWorkingMemoryMessage(msg.content)) {
940
- ctx.runMgr.pushMessage(msg);
861
+ pushSystemMessages();
862
+ // A human answered the park in a different process; apply that
863
+ // answer to the tool calls they were actually shown. Without
864
+ // this the repair below throws the approval away and the model
865
+ // re-decides, so "yes, delete that row" degrades into "ask
866
+ // again and hope it asks for the same thing".
867
+ pendingResume =
868
+ params.pendingDecision && projectedCheckpoint.pending
869
+ ? planPendingResume(projectedCheckpoint, params.pendingDecision, ctx.log)
870
+ : null;
871
+ // The park this resume ANSWERS even though there is no plan to
872
+ // carry the decision out through.
873
+ //
874
+ // `planPendingResume` covers the two arms whose decision has to
875
+ // reach something — the calls a `tool_review` park is about, the
876
+ // tool a `user_question` park is inside. An `iteration_checkpoint`
877
+ // park has neither, so it returns no plan, and the unpark further
878
+ // down — which ran only when there was one — never fired for it.
879
+ // A turn that parked on the cadence, was resumed with
880
+ // `{action: 'continue'}` and went on to finish its work therefore
881
+ // kept reporting an OUTSTANDING park to `findPendingCheckpoint`,
882
+ // so a second resume of the finished turn was refused with
883
+ // `awaiting-decision` for a decision already taken, and because
884
+ // `prune` skips an unresolved park the row could no longer be
885
+ // collected by anything.
886
+ //
887
+ // The decision IS carried out here — continuing is exactly what
888
+ // the loop below does, and a plan verdict is the answer to the
889
+ // question the plan park asked — so the park is resolved at the
890
+ // same point and with the same meaning "resolved" carries
891
+ // everywhere else: the record stays, and only its pending state
892
+ // ends. A `pause` is deliberately not resolved: it holds the
893
+ // park rather than answering it, which is how the live path
894
+ // treats it too. `answersParkOf` is the whole map, park type to
895
+ // answering decision, so an arm cannot go missing by being
896
+ // absent from a condition again — which is how the plan arm
897
+ // leaked a finished turn's park.
898
+ //
899
+ // Resolving it does not depend on the resumed process being able
900
+ // to act on it, and that is deliberate: the plan's own fate is a
901
+ // separate defect (nothing restores a plan on the resume path at
902
+ // all, so the new process has none to approve, execute or
903
+ // reject) and making the resolution wait for it would leave the
904
+ // row outstanding for exactly the turns that need it cleared.
905
+ const parked = projectedCheckpoint.pending;
906
+ answeredParkId =
907
+ params.pendingDecision &&
908
+ parked !== undefined &&
909
+ parked.resolvedAt === undefined &&
910
+ answersParkOf(parked.request.type, params.pendingDecision)
911
+ ? projectedCheckpoint.id
912
+ : undefined;
913
+ // Recover completed observations and explicitly unknown outcomes.
914
+ // A recorded start is not proof that its external effect failed.
915
+ const unanswered = interruptedToolCalls(projectedCheckpoint.messages);
916
+ recoveredResults =
917
+ unanswered.length > 0
918
+ ? await recoverCompletedCalls(ctx.recorder, unanswered, ctx.log, {
919
+ answers: pendingResume?.answers,
920
+ signal: ctx.abortController.signal,
921
+ })
922
+ : new Map();
923
+ // Preserve both known and unknown outcomes before continuing calls
924
+ // whose absence of a start was established by a complete scan.
925
+ if (!pendingResume && recoveredResults.size > 0) {
926
+ pendingResume = planCrashResume(projectedCheckpoint, recoveredResults, ctx.log);
927
+ }
928
+ // An incomplete turn with a durable owner is NOT abandoned. A
929
+ // pending decision or crash-resume plan re-appends that exact
930
+ // assistant with real/denied/recovered results below. Remove it
931
+ // from the generic pass so no synthetic result competes with the
932
+ // authority that still owns the call. Everything else is abandoned
933
+ // history and is repaired conservatively rather than deleted.
934
+ pendingResumeAssistantId = pendingResume
935
+ ? checkpoint.messageIds.get(pendingResume.assistant)
936
+ : undefined;
937
+ const abandonedCheckpointMessages = pendingResume
938
+ ? withoutOwnedResumeTurn(projectedCheckpoint.messages, pendingResume.assistant)
939
+ : projectedCheckpoint.messages;
940
+ const checkpointRepair = repairToolMessageHistory(abandonedCheckpointMessages);
941
+ const restoredMessages = checkpointRepair.messages;
942
+ if (toolHistoryRepairChanged(checkpointRepair.report)) {
943
+ pendingHistoryRepairs.push({
944
+ source: 'abandoned-checkpoint',
945
+ report: checkpointRepair.report,
946
+ });
947
+ ctx.log.warn('Repaired abandoned tool history while restoring a checkpoint', {
948
+ [NAMZU.TURN_ID]: ctx.recorder.turnId,
949
+ 'namzu.checkpoint.id': checkpoint.id,
950
+ 'namzu.history.source': 'abandoned-checkpoint',
951
+ 'namzu.history.duplicate_tool_results_removed': checkpointRepair.report.duplicateToolResultsRemoved,
952
+ 'namzu.history.orphaned_tool_results_removed': checkpointRepair.report.orphanedToolResultsRemoved,
953
+ 'namzu.history.synthetic_tool_results_inserted': checkpointRepair.report.syntheticToolResultsInserted,
954
+ });
955
+ }
956
+ // The ledger is process state and a resumed turn starts with an empty
957
+ // one, so until something reads a file again this turn knows nothing
958
+ // about files the conversation already wrote in full — and re-reads
959
+ // them. Rebuilt from the REPAIRED history, which is what the model
960
+ // is about to be shown, rather than from the checkpoint's own
961
+ // messages — plus whatever of the owned resume turn actually ran,
962
+ // which the repaired list does not carry; see
963
+ // `withOwnedResumeOutcomes`. Reads no file's content: every
964
+ // fingerprint recovered here is still checked against the real one
965
+ // at mutation time.
966
+ try {
967
+ await toolExecutor.seedFileObservations(pendingResume
968
+ ? withOwnedResumeOutcomes(restoredMessages, pendingResume.assistant, recoveredResults)
969
+ : restoredMessages, params.sandboxProvider !== undefined);
970
+ }
971
+ catch (err) {
972
+ // A ledger that could not be rebuilt is the empty one every resume
973
+ // used to get, so the turn continues without its witnesses and the
974
+ // model reads what it needs. Failing the resume over it would trade
975
+ // a conversation that works for one that does not, to protect an
976
+ // optimisation. Said out loud all the same, because a seeding that
977
+ // failed and one that found nothing are otherwise the same silence.
978
+ ctx.log.debug('Could not rebuild the file observation ledger on resume', {
979
+ [NAMZU.TURN_ID]: ctx.recorder.turnId,
980
+ 'namzu.checkpoint.id': checkpoint.id,
981
+ 'exception.message': err instanceof Error ? err.message : String(err),
982
+ });
983
+ }
984
+ for (const msg of restoredMessages) {
985
+ if (msg.role === 'system') {
986
+ // Re-push the FRESH static/dynamic floor (done above) but PRESERVE
987
+ // the two system messages that carry irreplaceable run state: the
988
+ // `[COMPACTED CONTEXT]` summary is the only surviving record of the
989
+ // older history a compaction pass deleted, and the working-memory
990
+ // slot pins the produced-artifact ledger. Dropping every system
991
+ // message on restore silently lost both on resume.
992
+ if (isCompactionMessage(msg.content) || isWorkingMemoryMessage(msg.content)) {
993
+ pushRestored(msg, checkpoint.messageIds);
994
+ }
995
+ continue;
941
996
  }
942
- continue;
997
+ pushRestored(msg, checkpoint.messageIds);
943
998
  }
944
- ctx.runMgr.pushMessage(msg);
999
+ // The queue, on the resume path too. It is drained
1000
+ // unconditionally above, so leaving this out would take a
1001
+ // host's "start with this" off the record and deliver it
1002
+ // nowhere — the one outcome a durable queue must not have.
1003
+ //
1004
+ // AFTER the restored history rather than before it: on a
1005
+ // resume the conversation already exists, and a message left
1006
+ // for "the next turn" is the newest thing said, not the oldest.
1007
+ for (const queued of queuedForThisRun)
1008
+ ctx.recorder.pushMessage(queued);
945
1009
  }
946
- // The queue, on the resume path too. It is drained
947
- // unconditionally above, so leaving this out would take a
948
- // host's "start with this" off the record and deliver it
949
- // nowhere — the one outcome a durable queue must not have.
950
- //
951
- // AFTER the restored history rather than before it: on a
952
- // resume the conversation already exists, and a message left
953
- // for "the next run" is the newest thing said, not the oldest.
954
- for (const queued of queuedForThisRun)
955
- ctx.runMgr.pushMessage(queued);
956
- }
957
- else if (params.continuationMode) {
958
- for (const msg of initialMessages) {
959
- ctx.runMgr.pushMessage(msg);
1010
+ else if (params.continuationMode) {
1011
+ for (const msg of initialMessages)
1012
+ pushRestored(msg, historyIds);
960
1013
  }
961
- }
962
- else {
963
- pushSystemMessages();
964
- for (const msg of initialMessages) {
965
- if (msg.role === 'system') {
966
- // A fresh run rebuilds its current static/dynamic prompt above,
967
- // so arbitrary historical system messages stay out. These two
968
- // are different: they are conversation STATE, and dropping them
969
- // deletes the only surviving record of compacted history or the
970
- // produced-artifact ledger. A compaction summary arriving from a
971
- // prior run is pinned because this new WorkingStateManager cannot
972
- // prove it has reconstructed equivalent state yet.
973
- if (isCompactionMessage(msg.content)) {
974
- ctx.runMgr.pushMessage({ ...msg, retain: true });
975
- }
976
- else if (isWorkingMemoryMessage(msg.content)) {
977
- ctx.runMgr.pushMessage(msg);
1014
+ else {
1015
+ pushSystemMessages();
1016
+ for (const msg of initialMessages) {
1017
+ if (msg.role === 'system') {
1018
+ // A fresh turn rebuilds its current static/dynamic prompt above,
1019
+ // so arbitrary historical system messages stay out. These two
1020
+ // are different: they are conversation STATE, and dropping them
1021
+ // deletes the only surviving record of compacted history or the
1022
+ // produced-artifact ledger. A compaction summary arriving from a
1023
+ // prior turn is pinned because this new WorkingStateManager cannot
1024
+ // prove it has reconstructed equivalent state yet.
1025
+ if (isCompactionMessage(msg.content)) {
1026
+ // Pinned by the prelude already; a copy would lose its record id.
1027
+ pushRestored(msg.retain ? msg : { ...msg, retain: true }, historyIds);
1028
+ }
1029
+ else if (isWorkingMemoryMessage(msg.content)) {
1030
+ pushRestored(msg, historyIds);
1031
+ }
1032
+ continue;
978
1033
  }
979
- continue;
1034
+ pushRestored(msg, historyIds);
980
1035
  }
981
- ctx.runMgr.pushMessage(msg);
982
1036
  }
983
- }
984
- // Fresh and continuation histories seed the same operator state.
985
- // A worker report or project-policy message may have role `user`,
986
- // but it must not become the task or an operator requirement.
987
- // Resume restores this state and adopts only its newer queue arrivals.
988
- if (!params.resumeFromCheckpoint && workingStateManager) {
989
- let isFirstUserMessage = true;
990
- for (const message of initialMessages) {
991
- if (!isOperatorUserMessage(message) || !message.content.trim())
992
- continue;
993
- extractFromUserMessage(workingStateManager, message.content, isFirstUserMessage);
994
- isFirstUserMessage = false;
1037
+ // Fresh and continuation histories seed the same operator state.
1038
+ // A worker report or project-policy message may have role `user`,
1039
+ // but it must not become the task or an operator requirement.
1040
+ // Resume restores this state and adopts only its newer queue arrivals.
1041
+ if (!params.resumeFromCheckpoint && workingStateManager) {
1042
+ let isFirstUserMessage = true;
1043
+ for (const message of initialMessages) {
1044
+ if (!isOperatorUserMessage(message) || !message.content.trim())
1045
+ continue;
1046
+ extractFromUserMessage(workingStateManager, message.content, isFirstUserMessage);
1047
+ isFirstUserMessage = false;
1048
+ }
1049
+ }
1050
+ const assembledPrompt = segments.dynamic.length > 0
1051
+ ? `${segments.static}\n\n---\n\n${segments.dynamic}`
1052
+ : segments.static;
1053
+ ctx.recorder.markRunning();
1054
+ // A resumed turn already began; `turn_resuming` above continued it.
1055
+ if (!params.resumeFromCheckpoint) {
1056
+ await eventTranslator.beginTurn({
1057
+ systemPrompt: assembledPrompt,
1058
+ ...(params.origin ? { origin: params.origin } : {}),
1059
+ ...(params.abandonInterrupted ? { abandonInterrupted: true } : {}),
1060
+ });
995
1061
  }
996
- }
997
- const assembledPrompt = segments.dynamic.length > 0
998
- ? `${segments.static}\n\n---\n\n${segments.dynamic}`
999
- : segments.static;
1000
- ctx.runMgr.markRunning();
1001
- await eventTranslator.emitEvent({
1002
- type: 'run_started',
1003
- runId: ctx.runMgr.id,
1004
- systemPrompt: assembledPrompt,
1005
- });
1006
- yield* eventTranslator.drainPending();
1007
- // Pre-run materialization can observe cancellation before RunContext
1008
- // exists. The exact input has now been seeded and the run is writable;
1009
- // hand the cancellation to the normal terminal path before invoking
1010
- // any host callback, guardrail, plugin, sandbox, or provider. Those
1011
- // boundaries are not all cooperative and must not regain withdrawn
1012
- // authority merely because the run record still had to be created.
1013
- ctx.abortController.signal.throwIfAborted();
1014
- // Handed over here, and the position is load-bearing in three
1015
- // directions. It has to follow `wirePlanManager`, or a host that
1016
- // builds its plan in this callback does it into silence. It has to
1017
- // follow `runMgr.init()` and `run_started`, because plan events append
1018
- // to that durable run. It also has to follow the pre-model abort fence:
1019
- // a callback invoked after attachment resolution observed cancellation
1020
- // would regain withdrawn authority and could replace the cancellation
1021
- // with its own failure. This is still before the iteration loop, which
1022
- // is the guarantee the callback makes.
1023
- params.onContextCreated?.({ planManager: ctx.planManager });
1024
- // The box is handed out HERE, after `run_started`, and the position
1025
- // is load-bearing rather than tidy. It moved twice:
1026
- //
1027
- // 1. Beside the box's construction — a host that called `set`
1028
- // synchronously reached `eventTranslator` inside its temporal
1029
- // dead zone and killed the run before it started.
1030
- // 2. Beside the translator's construction — the translator existed,
1031
- // but the run directory did not, so the durable append hit
1032
- // ENOENT on `transcript.jsonl`.
1033
- //
1034
- // Both were found by the test that takes the box and immediately
1035
- // swaps the policy, which is not an exotic host: it is the shape of
1036
- // "start unattended" wiring. A policy change is durably recorded
1037
- // before it takes effect, so the handout cannot precede the run
1038
- // being writable.
1039
- params.onApprovalPolicy?.(approvalPolicy);
1040
- // History repair happens before the run manager sees the first model
1041
- // request, but its durable event cannot precede run_started: there is no
1042
- // writable run log until that event initializes it. Emit the measured
1043
- // counts here, still before any provider call, so hosts can tell that the
1044
- // model received a repaired projection rather than the raw history.
1045
- for (const repair of pendingHistoryRepairs) {
1046
- await eventTranslator.emitEvent({
1047
- type: 'message_history_repaired',
1048
- runId: ctx.runMgr.id,
1049
- source: repair.source,
1050
- ...repair.report,
1051
- });
1052
- yield* eventTranslator.drainPending();
1053
- }
1054
- // Surface capability degradation to the host as run events —
1055
- // explicit, not silent (the log.warn above fires at setup time;
1056
- // this is the machine-readable channel).
1057
- if (stripToolSurfaces) {
1058
- await eventTranslator.emitEvent({
1059
- type: 'capability_warning',
1060
- runId: ctx.runMgr.id,
1061
- capability: 'tools',
1062
- providerId: params.provider.id,
1063
- message: `Provider '${params.provider.id}' does not support tools — ${registeredToolCount} registered tool(s) were stripped from the prompt and request.`,
1064
- });
1065
- yield* eventTranslator.drainPending();
1066
- }
1067
- if (attachmentMessageCount > 0) {
1068
- await eventTranslator.emitEvent({
1069
- type: 'capability_warning',
1070
- runId: ctx.runMgr.id,
1071
- capability: 'vision',
1072
- providerId: params.provider.id,
1073
- message: `Provider '${params.provider.id}' does not support vision — image attachments on ${attachmentMessageCount} user message(s) will not reach the model.`,
1074
- });
1075
- yield* eventTranslator.drainPending();
1076
- }
1077
- if (documentMessageCount > 0) {
1078
- await eventTranslator.emitEvent({
1079
- type: 'capability_warning',
1080
- runId: ctx.runMgr.id,
1081
- capability: 'documents',
1082
- providerId: params.provider.id,
1083
- message: `Provider '${params.provider.id}' does not support documents — document attachments on ${documentMessageCount} user message(s) will not reach the model.`,
1084
- });
1085
- yield* eventTranslator.drainPending();
1086
- }
1087
- if (params.pluginManager) {
1088
- const hookResults = await params.pluginManager.executeHooks('run_start', { runId: ctx.runId, signal: ctx.abortController.signal }, eventTranslator.emitEvent);
1089
- applyLifecycleHookResults('run_start', hookResults);
1090
1062
  yield* eventTranslator.drainPending();
1091
- }
1092
- // --- Sandbox lifecycle: create before iteration loop ---
1093
- if (params.sandboxProvider) {
1094
- const rootAtCwd = runConfig.sandbox?.workspace === 'working-directory';
1095
- // Checked against what the CALLER passed, not against `ctx.cwd`.
1096
- // `ctx.cwd` falls back to `process.cwd()`, so reading it here
1097
- // would silently root the sandbox at whatever directory the
1098
- // host process happens to be in — which is not the directory
1099
- // anybody asked to confine, and is worse than the temp dir the
1100
- // caller declined. Refused before the sandbox exists, and not
1101
- // downgraded to ephemeral: a caller who asked for confinement
1102
- // of a specific tree and quietly got an empty one has been
1103
- // told their files are protected by something that is not
1104
- // looking at them.
1105
- if (rootAtCwd && params.workingDirectory === undefined) {
1106
- throw new NamzuError({
1107
- code: 'invalid_config',
1108
- message: "sandbox.workspace is 'working-directory' but this run has no workingDirectory. Pass one, or use the default 'ephemeral' — the kernel will not fall back to a temp directory, because that would confine a directory you did not name.",
1109
- details: { workspace: 'working-directory' },
1063
+ // Pre-run materialization can observe cancellation before TurnContext
1064
+ // exists. The exact input has now been seeded and the turn is writable;
1065
+ // hand the cancellation to the normal terminal path before invoking
1066
+ // any host callback, guardrail, plugin, sandbox, or provider. Those
1067
+ // boundaries are not all cooperative and must not regain withdrawn
1068
+ // authority merely because the turn record still had to be created.
1069
+ ctx.abortController.signal.throwIfAborted();
1070
+ // Handed over here, and the position is load-bearing in three
1071
+ // directions. It has to follow `wirePlanManager`, or a host that
1072
+ // builds its plan in this callback does it into silence. It has to
1073
+ // follow `recorder.init()` and `turn_started`, because plan events append
1074
+ // to that durable turn. It also has to follow the pre-model abort fence:
1075
+ // a callback invoked after attachment resolution observed cancellation
1076
+ // would regain withdrawn authority and could replace the cancellation
1077
+ // with its own failure. This is still before the iteration loop, which
1078
+ // is the guarantee the callback makes.
1079
+ params.onContextCreated?.({ planManager: ctx.planManager });
1080
+ // The box is handed out HERE, after `turn_started`, and the position
1081
+ // is load-bearing rather than tidy. It moved twice:
1082
+ //
1083
+ // 1. Beside the box's construction — a host that called `set`
1084
+ // synchronously reached `eventTranslator` inside its temporal
1085
+ // dead zone and killed the turn before it started.
1086
+ // 2. Beside the translator's construction — the translator existed,
1087
+ // but the turn directory did not, so the durable append hit
1088
+ // ENOENT on `transcript.jsonl`.
1089
+ //
1090
+ // Both were found by the test that takes the box and immediately
1091
+ // swaps the policy, which is not an exotic host: it is the shape of
1092
+ // "start unattended" wiring. A policy change is durably recorded
1093
+ // before it takes effect, so the handout cannot precede the turn
1094
+ // being writable.
1095
+ params.onApprovalPolicy?.(approvalPolicy);
1096
+ // History repair happens before the turn manager sees the first model
1097
+ // request, but its durable event cannot precede turn_started: there is no
1098
+ // writable run log until that event initializes it. Emit the measured
1099
+ // counts here, still before any provider call, so hosts can tell that the
1100
+ // model received a repaired projection rather than the raw history.
1101
+ for (const repair of pendingHistoryRepairs) {
1102
+ await eventTranslator.emitEvent({
1103
+ type: 'message_history_repaired',
1104
+ turnId: ctx.recorder.turnId,
1105
+ source: repair.source,
1106
+ ...repair.report,
1110
1107
  });
1108
+ yield* eventTranslator.drainPending();
1111
1109
  }
1112
- if (rootAtCwd && !params.sandboxProvider.workspaceModes?.includes('working-directory')) {
1113
- throw new NamzuError({
1114
- code: 'invalid_config',
1115
- message: `Sandbox provider '${params.sandboxProvider.id}' does not advertise working-directory workspace support. Refusing instead of passing a project path the provider may ignore.`,
1116
- details: {
1117
- providerId: params.sandboxProvider.id,
1118
- workspace: 'working-directory',
1119
- },
1110
+ // Surface capability degradation to the host as run events —
1111
+ // explicit, not silent (the log.warn above fires at setup time;
1112
+ // this is the machine-readable channel).
1113
+ if (stripToolSurfaces) {
1114
+ await eventTranslator.emitEvent({
1115
+ type: 'capability_warning',
1116
+ turnId: ctx.recorder.turnId,
1117
+ capability: 'tools',
1118
+ providerId: params.provider.id,
1119
+ message: `Provider '${params.provider.id}' does not support tools — ${registeredToolCount} registered tool(s) were stripped from the prompt and request.`,
1120
1120
  });
1121
+ yield* eventTranslator.drainPending();
1121
1122
  }
1122
- const acquisition = await acquireSandbox({
1123
- provider: params.sandboxProvider,
1124
- config: {
1125
- ...(rootAtCwd ? { workingDirectory: ctx.cwd } : {}),
1126
- ...(rootAtCwd && params.additionalDirectories?.length
1127
- ? { additionalDirectories: params.additionalDirectories }
1128
- : {}),
1129
- timeoutMs: runConfig.sandbox?.timeoutMs,
1130
- memoryLimitMb: runConfig.sandbox?.memoryLimitMb,
1131
- maxProcesses: runConfig.sandbox?.maxProcesses,
1132
- },
1133
- signal: ctx.abortController.signal,
1134
- timeoutMs: guard.remainingUntilTimeoutMs(),
1135
- teardownTimeoutMs: sandboxTeardownTimeoutMs,
1136
- onLateTeardown: (result) => {
1137
- if (result.kind === 'destroyed') {
1138
- ctx.log.info('Late sandbox allocation was destroyed after the run stopped', {
1139
- [NAMZU.RUN_ID]: ctx.runId,
1140
- });
1141
- return;
1142
- }
1143
- ctx.log.error('Late sandbox allocation did not stop cleanly', {
1144
- [NAMZU.RUN_ID]: ctx.runId,
1145
- ...errorAttributes(result.error),
1146
- });
1147
- },
1148
- });
1149
- if (acquisition.kind !== 'created') {
1150
- if (acquisition.createPending) {
1151
- ctx.log.warn('Sandbox creation was unsettled when the run stopped; any returned handle will be released, but a remote allocation hidden behind a lost response requires provider-side reconciliation or a fleet reaper', {
1152
- [NAMZU.RUN_ID]: ctx.runId,
1153
- 'namzu.sandbox.provider_id': params.sandboxProvider.id,
1123
+ if (attachmentMessageCount > 0) {
1124
+ await eventTranslator.emitEvent({
1125
+ type: 'capability_warning',
1126
+ turnId: ctx.recorder.turnId,
1127
+ capability: 'vision',
1128
+ providerId: params.provider.id,
1129
+ message: `Provider '${params.provider.id}' does not support vision — image attachments on ${attachmentMessageCount} user message(s) will not reach the model.`,
1130
+ });
1131
+ yield* eventTranslator.drainPending();
1132
+ }
1133
+ if (documentMessageCount > 0) {
1134
+ await eventTranslator.emitEvent({
1135
+ type: 'capability_warning',
1136
+ turnId: ctx.recorder.turnId,
1137
+ capability: 'documents',
1138
+ providerId: params.provider.id,
1139
+ message: `Provider '${params.provider.id}' does not support documents — document attachments on ${documentMessageCount} user message(s) will not reach the model.`,
1140
+ });
1141
+ yield* eventTranslator.drainPending();
1142
+ }
1143
+ if (params.pluginManager) {
1144
+ const hookResults = await params.pluginManager.executeHooks('turn_start', { sessionId: ctx.sessionId, turnId: ctx.turnId, signal: ctx.abortController.signal }, eventTranslator.emitEvent);
1145
+ applyLifecycleHookResults('turn_start', hookResults);
1146
+ yield* eventTranslator.drainPending();
1147
+ }
1148
+ // --- Sandbox lifecycle: create before iteration loop ---
1149
+ if (params.sandboxProvider) {
1150
+ const rootAtCwd = turnConfig.sandbox?.workspace === 'working-directory';
1151
+ // Checked against what the CALLER passed, not against `ctx.cwd`.
1152
+ // `ctx.cwd` falls back to `process.cwd()`, so reading it here
1153
+ // would silently root the sandbox at whatever directory the
1154
+ // host process happens to be in — which is not the directory
1155
+ // anybody asked to confine, and is worse than the temp dir the
1156
+ // caller declined. Refused before the sandbox exists, and not
1157
+ // downgraded to ephemeral: a caller who asked for confinement
1158
+ // of a specific tree and quietly got an empty one has been
1159
+ // told their files are protected by something that is not
1160
+ // looking at them.
1161
+ if (rootAtCwd && params.workingDirectory === undefined) {
1162
+ throw new NamzuError({
1163
+ code: 'invalid_config',
1164
+ message: "sandbox.workspace is 'working-directory' but this turn has no workingDirectory. Pass one, or use the default 'ephemeral' — the kernel will not fall back to a temp directory, because that would confine a directory you did not name.",
1165
+ details: { workspace: 'working-directory' },
1154
1166
  });
1155
1167
  }
1156
- if (acquisition.kind === 'cancelled') {
1157
- ctx.runMgr.markCancelled();
1158
- }
1159
- else {
1160
- ctx.runMgr.setStopReason('timeout');
1161
- ctx.log.warn('Sandbox creation exhausted the run timeout', {
1162
- [NAMZU.RUN_ID]: ctx.runId,
1163
- 'namzu.sandbox.provider_id': params.sandboxProvider.id,
1164
- ...errorAttributes(acquisition.error),
1168
+ if (rootAtCwd && !params.sandboxProvider.workspaceModes?.includes('working-directory')) {
1169
+ throw new NamzuError({
1170
+ code: 'invalid_config',
1171
+ message: `Sandbox provider '${params.sandboxProvider.id}' does not advertise working-directory workspace support. Refusing instead of passing a project path the provider may ignore.`,
1172
+ details: {
1173
+ providerId: params.sandboxProvider.id,
1174
+ workspace: 'working-directory',
1175
+ },
1165
1176
  });
1166
1177
  }
1167
- yield* resultAssembler.completeRun(rootSpan);
1168
- // The run HAS settled, so the outer `finally` must not read
1169
- // this as an abandonment — it would persist a second time.
1178
+ const acquisition = await acquireSandbox({
1179
+ provider: params.sandboxProvider,
1180
+ config: {
1181
+ ...(rootAtCwd ? { workingDirectory: ctx.cwd } : {}),
1182
+ ...(rootAtCwd && params.additionalDirectories?.length
1183
+ ? { additionalDirectories: params.additionalDirectories }
1184
+ : {}),
1185
+ timeoutMs: turnConfig.sandbox?.timeoutMs,
1186
+ memoryLimitMb: turnConfig.sandbox?.memoryLimitMb,
1187
+ maxProcesses: turnConfig.sandbox?.maxProcesses,
1188
+ },
1189
+ signal: ctx.abortController.signal,
1190
+ timeoutMs: guard.remainingUntilTimeoutMs(),
1191
+ teardownTimeoutMs: sandboxTeardownTimeoutMs,
1192
+ onLateTeardown: (result) => {
1193
+ if (result.kind === 'destroyed') {
1194
+ ctx.log.info('Late sandbox allocation was destroyed after the turn stopped', {
1195
+ [NAMZU.TURN_ID]: ctx.turnId,
1196
+ });
1197
+ return;
1198
+ }
1199
+ ctx.log.error('Late sandbox allocation did not stop cleanly', {
1200
+ [NAMZU.TURN_ID]: ctx.turnId,
1201
+ ...errorAttributes(result.error),
1202
+ });
1203
+ },
1204
+ });
1205
+ if (acquisition.kind !== 'created') {
1206
+ if (acquisition.createPending) {
1207
+ ctx.log.warn('Sandbox creation was unsettled when the turn stopped; any returned handle will be released, but a remote allocation hidden behind a lost response requires provider-side reconciliation or a fleet reaper', {
1208
+ [NAMZU.TURN_ID]: ctx.turnId,
1209
+ 'namzu.sandbox.provider_id': params.sandboxProvider.id,
1210
+ });
1211
+ }
1212
+ if (acquisition.kind === 'cancelled') {
1213
+ ctx.recorder.markCancelled();
1214
+ }
1215
+ else {
1216
+ ctx.recorder.setStopReason('timeout');
1217
+ ctx.log.warn('Sandbox creation exhausted the turn timeout', {
1218
+ [NAMZU.TURN_ID]: ctx.turnId,
1219
+ 'namzu.sandbox.provider_id': params.sandboxProvider.id,
1220
+ ...errorAttributes(acquisition.error),
1221
+ });
1222
+ }
1223
+ yield* resultAssembler.completeTurn(rootSpan);
1224
+ // The turn HAS settled, so the outer `finally` must not read
1225
+ // this as an abandonment — it would persist a second time.
1226
+ settled = true;
1227
+ return await resultAssembler.finalize();
1228
+ }
1229
+ sandbox = acquisition.sandbox;
1230
+ toolExecutor.setSandbox(sandbox);
1231
+ await eventTranslator.emitEvent({
1232
+ type: 'sandbox_created',
1233
+ turnId: ctx.turnId,
1234
+ sandboxId: sandbox.id,
1235
+ environment: sandbox.environment,
1236
+ });
1237
+ yield* eventTranslator.drainPending();
1238
+ ctx.log.info('Sandbox created for run', {
1239
+ 'namzu.sandbox.id': sandbox.id,
1240
+ 'namzu.execution.environment': sandbox.environment,
1241
+ 'namzu.runtime.root_dir': sandbox.rootDir,
1242
+ });
1243
+ }
1244
+ // Before the first model call: the cheapest place to refuse, since
1245
+ // nothing has been spent. Previously unreachable — `turn_start`
1246
+ // fires with only `{ sessionId, turnId }` and `turn_started` carries only the
1247
+ // system prompt, so no hook could see the user's message.
1248
+ const inputVerdict = await runInputGuardrails(params.inputGuardrails, {
1249
+ sessionId: ctx.sessionId,
1250
+ turnId: ctx.turnId,
1251
+ messages: ctx.recorder.messages,
1252
+ ...(segments?.static ? { systemPrompt: segments.static } : {}),
1253
+ }, ctx.log);
1254
+ if (inputVerdict.blocked) {
1255
+ await eventTranslator.emitEvent({
1256
+ type: 'guardrail_triggered',
1257
+ turnId: ctx.turnId,
1258
+ stage: 'input',
1259
+ action: 'block',
1260
+ ...(inputVerdict.name ? { guardrail: inputVerdict.name } : {}),
1261
+ ...(inputVerdict.reason ? { reason: inputVerdict.reason } : {}),
1262
+ });
1263
+ yield* eventTranslator.drainPending();
1264
+ // A guardrail block is a refusal — first-class in the audit trail
1265
+ // (LOG-14, design §5), not merely a SessionEvent a host happens to be
1266
+ // subscribed to when it fires.
1267
+ await ctx.recorder.recordAudit({
1268
+ what: { action: 'guardrail:input', resource: inputVerdict.name },
1269
+ outcome: 'refused',
1270
+ reason: inputVerdict.reason ?? 'blocked by an input guardrail',
1271
+ ...(params.persona?.identity.role ? { persona: params.persona.identity.role } : {}),
1272
+ });
1273
+ ctx.recorder.setStopReason('input_guardrail');
1274
+ ctx.recorder.setLastError(inputVerdict.reason ?? 'blocked by an input guardrail');
1275
+ yield* resultAssembler.completeTurn(rootSpan);
1276
+ // Same two lines as the sandbox path above, and for the same
1277
+ // reasons — with one that path does not have. This return used to
1278
+ // hand back `getRun()` without persisting, so the terminal state
1279
+ // reached the disk only because the abandonment path found
1280
+ // `settled` false and settled it a second time. A branch that
1281
+ // exists for runs which did NOT settle must not be the reason a
1282
+ // settled one is written down.
1170
1283
  settled = true;
1171
1284
  return await resultAssembler.finalize();
1172
1285
  }
1173
- sandbox = acquisition.sandbox;
1174
- toolExecutor.setSandbox(sandbox);
1175
- await eventTranslator.emitEvent({
1176
- type: 'sandbox_created',
1177
- runId: ctx.runId,
1178
- sandboxId: sandbox.id,
1179
- environment: sandbox.environment,
1180
- });
1181
- yield* eventTranslator.drainPending();
1182
- ctx.log.info('Sandbox created for run', {
1183
- 'namzu.sandbox.id': sandbox.id,
1184
- 'namzu.execution.environment': sandbox.environment,
1185
- 'namzu.runtime.root_dir': sandbox.rootDir,
1186
- });
1187
- }
1188
- // Crash-save handlers live for exactly the run's lifetime, and are
1189
- // removed in the `finally` below. Opt-in — see `emergencySave`.
1190
- if (params.emergencySave) {
1191
- const runDir = ctx.runMgr.getRunDir();
1192
- if (runDir) {
1193
- emergencyManager = EmergencySaveManager.instance(ctx.log);
1194
- emergencyManager.attach(ctx.runMgr, runDir, ctx.log);
1286
+ // Honor the approval a human already gave, before the loop's
1287
+ // first model call. The sandbox exists by now, so an approved
1288
+ // tool that needs one gets it.
1289
+ if (pendingResume) {
1290
+ ctx.log.info('Applying a pending HITL decision to the checkpointed tool calls', {
1291
+ [NAMZU.TURN_ID]: ctx.turnId,
1292
+ 'namzu.tool.names': pendingResume.response.message.toolCalls?.map((tc) => tc.function.name),
1293
+ 'namzu.runtime.denied': pendingResume.denials.size,
1294
+ });
1295
+ // Hand the recorded answer to the already-built tool. The tool
1296
+ // closed over its registry when the agent was constructed,
1297
+ // long before this turn existed, so the answers are copied in
1298
+ // rather than passed down.
1299
+ if (pendingResume.answers) {
1300
+ for (const [questionId, answer] of pendingResume.answers.entries()) {
1301
+ pendingAnswers.set(questionId, answer);
1302
+ }
1303
+ }
1304
+ await applyPendingResume(pendingResume, ctx.recorder, toolExecutor, recoveredResults, pendingResumeAssistantId);
1305
+ yield* eventTranslator.drainPending();
1195
1306
  }
1196
- else {
1197
- ctx.log.warn('emergencySave requested but the run has no output directory — crash dumps disabled', { [NAMZU.RUN_ID]: ctx.runId });
1307
+ // The decision has now actually been carried out, so the park it
1308
+ // answered is no longer outstanding. Without this the checkpoint
1309
+ // keeps reporting `pending` with no `resolvedAt`, and an approval
1310
+ // queue re-serves a call that already ran — or a question already
1311
+ // answered — which defeats the entire point of recording the park.
1312
+ //
1313
+ // Two arms reach this point, and being outside `if (pendingResume)`
1314
+ // is what the second one needs. One is a plan whose decision was
1315
+ // applied to a batch above. The other is the cadence arm, for which
1316
+ // `planPendingResume` rightly produces no plan because the loop
1317
+ // resuming IS its decision being carried out (`answeredParkId`, set
1318
+ // on the restore path). Resolving only the first left a finished turn
1319
+ // reporting `awaiting-decision` forever.
1320
+ //
1321
+ // What is RECORDED depends on which of the two produced the plan. A
1322
+ // recovery plan means the batch was answered by the crash path
1323
+ // rather than by the decision — the calls the human was asked about
1324
+ // were closed with explicitly unknown outcomes — so the human's
1325
+ // answer must not be written down as what ended the park. The park is
1326
+ // still resolved: the question is moot, and leaving it outstanding
1327
+ // would have `findPendingCheckpoint` serve it as the newest
1328
+ // outstanding park, so a host resuming it would rewind this turn to
1329
+ // the checkpoint the crash happened on and re-execute a batch the turn
1330
+ // has long since moved past.
1331
+ const resolvedCheckpointId = pendingResume?.checkpointId ?? answeredParkId;
1332
+ const recordedDecision = pendingResume?.source === 'recovery' && params.pendingDecision
1333
+ ? supersededByRecovery(params.pendingDecision)
1334
+ : params.pendingDecision;
1335
+ if (recordedDecision && resolvedCheckpointId) {
1336
+ await checkpointMgr
1337
+ .unpark(resolvedCheckpointId, recordedDecision)
1338
+ .catch((err) => {
1339
+ ctx.log.error('Applied a pending decision but failed to clear the park', {
1340
+ [NAMZU.TURN_ID]: ctx.turnId,
1341
+ 'namzu.checkpoint.id': resolvedCheckpointId,
1342
+ 'exception.message': err instanceof Error ? err.message : String(err),
1343
+ });
1344
+ return null;
1345
+ });
1198
1346
  }
1199
- }
1200
- // Before the first model call: the cheapest place to refuse, since
1201
- // nothing has been spent. Previously unreachable — `run_start`
1202
- // fires with only `{ runId }` and `run_started` carries only the
1203
- // system prompt, so no hook could see the user's message.
1204
- const inputVerdict = await runInputGuardrails(params.inputGuardrails, {
1205
- runId: ctx.runId,
1206
- messages: ctx.runMgr.messages,
1207
- ...(segments?.static ? { systemPrompt: segments.static } : {}),
1208
- }, ctx.log);
1209
- if (inputVerdict.blocked) {
1210
- await eventTranslator.emitEvent({
1211
- type: 'guardrail_triggered',
1212
- runId: ctx.runId,
1213
- stage: 'input',
1214
- action: 'block',
1215
- ...(inputVerdict.name ? { guardrail: inputVerdict.name } : {}),
1216
- ...(inputVerdict.reason ? { reason: inputVerdict.reason } : {}),
1347
+ yield* iterationOrchestrator.runLoop();
1348
+ yield* finalizeTurn({
1349
+ ctx,
1350
+ params,
1351
+ eventTranslator,
1352
+ takeSteps: () => iterationOrchestrator.getSteps(),
1353
+ workingStateManager,
1354
+ resultAssembler,
1355
+ rootSpan,
1217
1356
  });
1218
- yield* eventTranslator.drainPending();
1219
- // A guardrail block is a refusal — first-class in the audit trail
1220
- // (LOG-14, design §5), not merely a RunEvent a host happens to be
1221
- // subscribed to when it fires.
1222
- await ctx.runMgr.recordAudit({
1223
- what: { action: 'guardrail:input', resource: inputVerdict.name },
1224
- outcome: 'refused',
1225
- reason: inputVerdict.reason ?? 'blocked by an input guardrail',
1226
- ...(params.persona?.identity.role ? { persona: params.persona.identity.role } : {}),
1227
- });
1228
- ctx.runMgr.setStopReason('input_guardrail');
1229
- ctx.runMgr.setLastError(inputVerdict.reason ?? 'blocked by an input guardrail');
1230
- yield* resultAssembler.completeRun(rootSpan);
1231
- // Same two lines as the sandbox path above, and for the same
1232
- // reasons — with one that path does not have. This return used to
1233
- // hand back `getRun()` without persisting, so the terminal state
1234
- // reached the disk only because the abandonment path found
1235
- // `settled` false and settled it a second time. A branch that
1236
- // exists for runs which did NOT settle must not be the reason a
1237
- // settled one is written down.
1238
- settled = true;
1239
- return await resultAssembler.finalize();
1240
1357
  }
1241
- // Honor the approval a human already gave, before the loop's
1242
- // first model call. The sandbox exists by now, so an approved
1243
- // tool that needs one gets it.
1244
- if (pendingResume) {
1245
- ctx.log.info('Applying a pending HITL decision to the checkpointed tool calls', {
1246
- [NAMZU.RUN_ID]: ctx.runId,
1247
- 'namzu.tool.names': pendingResume.response.message.toolCalls?.map((tc) => tc.function.name),
1248
- 'namzu.runtime.denied': pendingResume.denials.size,
1249
- });
1250
- // Hand the recorded answer to the already-built tool. The tool
1251
- // closed over its registry when the agent was constructed,
1252
- // long before this run existed, so the answers are copied in
1253
- // rather than passed down.
1254
- if (pendingResume.answers) {
1255
- for (const [questionId, answer] of pendingResume.answers.entries()) {
1256
- pendingAnswers.set(questionId, answer);
1257
- }
1258
- }
1259
- await applyPendingResume(pendingResume, ctx.runMgr, toolExecutor, recoveredResults);
1358
+ catch (err) {
1359
+ // Another turn is active in this session: nothing of this turn was
1360
+ // written, so there is nothing to settle. The caller gets the
1361
+ // refusal itself.
1362
+ if (isTurnInProgressError(err) && !ctx.recorder.isActive)
1363
+ throw err;
1364
+ // A failed turn still spent its steps; report them.
1365
+ ctx.recorder.setSteps(iterationOrchestrator.getSteps());
1366
+ await executeUserInterruptHooks(err);
1260
1367
  yield* eventTranslator.drainPending();
1368
+ yield* resultAssembler.handleError(err, rootSpan);
1261
1369
  }
1262
- // The decision has now actually been carried out, so the park it
1263
- // answered is no longer outstanding. Without this the checkpoint
1264
- // keeps reporting `pending` with no `resolvedAt`, and an approval
1265
- // queue re-serves a call that already ran — or a question already
1266
- // answered — which defeats the entire point of recording the park.
1267
- //
1268
- // Two arms reach this point, and being outside `if (pendingResume)`
1269
- // is what the second one needs. One is a plan whose decision was
1270
- // applied to a batch above. The other is the cadence arm, for which
1271
- // `planPendingResume` rightly produces no plan because the loop
1272
- // resuming IS its decision being carried out (`answeredParkId`, set
1273
- // on the restore path). Resolving only the first left a finished run
1274
- // reporting `awaiting-decision` forever.
1275
- //
1276
- // What is RECORDED depends on which of the two produced the plan. A
1277
- // recovery plan means the batch was answered by the crash path
1278
- // rather than by the decision — the calls the human was asked about
1279
- // were closed with explicitly unknown outcomes — so the human's
1280
- // answer must not be written down as what ended the park. The park is
1281
- // still resolved: the question is moot, and leaving it outstanding
1282
- // would have `findPendingCheckpoint` serve it as the newest
1283
- // outstanding park, so a host resuming it would rewind this run to
1284
- // the checkpoint the crash happened on and re-execute a batch the run
1285
- // has long since moved past.
1286
- const resolvedCheckpointId = pendingResume?.checkpointId ?? answeredParkId;
1287
- const recordedDecision = pendingResume?.source === 'recovery' && params.pendingDecision
1288
- ? supersededByRecovery(params.pendingDecision)
1289
- : params.pendingDecision;
1290
- if (recordedDecision && resolvedCheckpointId) {
1291
- await checkpointMgr.unpark(resolvedCheckpointId, recordedDecision).catch((err) => {
1292
- ctx.log.error('Applied a pending decision but failed to clear the park', {
1293
- [NAMZU.RUN_ID]: ctx.runId,
1294
- 'namzu.checkpoint.id': resolvedCheckpointId,
1295
- 'exception.message': err instanceof Error ? err.message : String(err),
1296
- });
1297
- return null;
1370
+ finally {
1371
+ yield* releaseTurnResources({
1372
+ ctx,
1373
+ eventTranslator,
1374
+ unsubscribeJobExits,
1375
+ unsubscribeTaskStore,
1376
+ awaitedJobs,
1377
+ backgroundJobs: params.backgroundJobs,
1378
+ backgroundJobOwner: params.backgroundJobOwner,
1379
+ questionParks,
1380
+ workingStateManager,
1381
+ promoteMemory: params.promoteMemory,
1382
+ sandbox,
1383
+ sandboxTeardownTimeoutMs,
1384
+ runStartedAt,
1385
+ rootSpan,
1298
1386
  });
1299
1387
  }
1300
- yield* iterationOrchestrator.runLoop();
1301
- yield* finalizeRun({
1302
- ctx,
1303
- params,
1304
- eventTranslator,
1305
- takeSteps: () => iterationOrchestrator.getSteps(),
1306
- workingStateManager,
1307
- resultAssembler,
1308
- rootSpan,
1309
- });
1310
- }
1311
- catch (err) {
1312
- // A failed run still spent its steps; report them.
1313
- ctx.runMgr.setSteps(iterationOrchestrator.getSteps());
1314
- await executeUserInterruptHooks(err);
1315
- yield* eventTranslator.drainPending();
1316
- yield* resultAssembler.handleError(err, rootSpan);
1388
+ // Reached only by a turn that settled on its own terms. `finalize()` is
1389
+ // the only thing in this body that writes the durable half of the turn,
1390
+ // and a `return` completion arriving from a consumer (`break` out of
1391
+ // `for await`, `gen.return()`) runs the `finally` above and stops short
1392
+ // of here. The flag is what tells the two apart, and this is one of
1393
+ // three sites that set it — the sandbox-acquisition and input-guardrail
1394
+ // returns settle early and set it there. Set before the await rather
1395
+ // than after, because a store that throws on the way out must not send
1396
+ // the abandonment path over the same broken ground.
1397
+ settled = true;
1398
+ return await resultAssembler.finalize();
1399
+ })();
1400
+ try {
1401
+ return yield* runBody;
1317
1402
  }
1318
1403
  finally {
1319
- yield* releaseRunResources({
1320
- ctx,
1321
- eventTranslator,
1322
- emergencyManager,
1323
- unsubscribeJobExits,
1324
- unsubscribeTaskStore,
1325
- awaitedJobs,
1326
- backgroundJobs: params.backgroundJobs,
1327
- backgroundJobOwner: params.backgroundJobOwner,
1328
- questionParks,
1329
- workingStateManager,
1330
- promoteMemory: params.promoteMemory,
1331
- sandbox,
1332
- sandboxTeardownTimeoutMs,
1333
- runStartedAt,
1334
- rootSpan,
1335
- });
1404
+ if (!settled)
1405
+ await settleAbandonedTurn(ctx.recorder, eventTranslator, ctx.log);
1336
1406
  }
1337
- // Reached only by a run that settled on its own terms. `finalize()` is
1338
- // the only thing in this body that writes the durable half of the run,
1339
- // and a `return` completion arriving from a consumer (`break` out of
1340
- // `for await`, `gen.return()`) runs the `finally` above and stops short
1341
- // of here. The flag is what tells the two apart, and this is one of
1342
- // three sites that set it — the sandbox-acquisition and input-guardrail
1343
- // returns settle early and set it there. Set before the await rather
1344
- // than after, because a store that throws on the way out must not send
1345
- // the abandonment path over the same broken ground.
1346
- settled = true;
1347
- return await resultAssembler.finalize();
1348
- })();
1349
- try {
1350
- return yield* runBody;
1351
1407
  }
1352
1408
  finally {
1353
- if (!settled)
1354
- await settleAbandonedRun(ctx.runMgr, ctx.log);
1409
+ unsubscribeChildSessions?.();
1410
+ // The lease `open()` took in the prelude; a caller-supplied lease is the
1411
+ // caller's to give back.
1412
+ await ctx.recorder.release();
1355
1413
  }
1356
1414
  }
1357
1415
  /**
1358
- * Write a terminal durable record for a run whose consumer walked away.
1359
- *
1360
- * `for await (… ) break` and an explicit `gen.return()` both end the run
1361
- * body early. Everything the run's `finally` owns still happens — background
1362
- * jobs are killed, the sandbox is destroyed, the span ends, the duration is
1363
- * recorded — and then the generator stops. `finalize()` never runs, so
1364
- * `persist()` never runs, and the store keeps whatever `init()` wrote: a
1365
- * non-terminal status for a run that no longer exists. `deriveRunStatus`
1366
- * reads that record back as `queued`, work waiting to start, and a host
1367
- * rebuilding its view from the store believes it.
1368
- *
1369
- * There is nothing to emit here and nothing to emit it to: the consumer
1370
- * that would have received the events is the one that left. This is about
1371
- * the durable record only.
1416
+ * Write a durable record for a turn whose consumer walked away.
1372
1417
  *
1373
- * `cancelled` is the verdict, and it is chosen from the existing vocabulary
1374
- * because it is the one that is true. The run did not complete — no result
1375
- * was produced and no terminal event was ever delivered — and nothing
1376
- * failed, so `failed` would name an error that never happened; a run whose
1377
- * consumer stopped reading and whose processes were torn down under it is
1378
- * the same fact `markCancelled` already records when a run abort tears one
1379
- * down. It needs no new `RunExecutionStatus` and no new `StopReason`.
1418
+ * `for await (… ) break` and an explicit `gen.return()` both end the turn
1419
+ * body early. Everything the body's `finally` owns still happens — jobs are
1420
+ * killed, the sandbox is destroyed, the span ends — and then the generator
1421
+ * stops without settling. Without this the log would end mid-turn, and the
1422
+ * turn would read as `interrupted` for a process that is gone.
1380
1423
  *
1381
- * A verdict the run already reached is left standing. A run that failed,
1382
- * or was cancelled, before the consumer left still says so; what the
1383
- * abandonment adds is that the record reaches the disk at all.
1384
- *
1385
- * Neither is a verdict written over a PARK. A park is a promise to a human
1386
- * that outlives the consumer: the run is resumable and somebody is still owed
1387
- * an answer, and `deriveRunStatus` reads a terminal status BEFORE it reads the
1388
- * park — so recording `cancelled` turns `awaiting_hitl` into `cancelled` for a
1389
- * run nobody answered for, while the unanswered question stays on the record
1390
- * and the checkpoint it belongs to stays the place a resume starts from. The
1391
- * durable state is asked rather than the in-memory one because the in-memory
1392
- * one is the misleading half here: `handleHITLDecision` emits `run_paused` and
1393
- * drains it BEFORE it calls `setStopReason('paused')`, so a consumer that
1394
- * leaves on that event leaves a run whose status is `running` and whose stop
1395
- * reason is unset at the exact instant its park is already durable.
1396
- * `findPendingCheckpoint` is the same read an approval queue is built from,
1397
- * expired parks included in its judgement: a park nobody answered in time is
1398
- * not somebody still being asked.
1424
+ * - A turn that already settled, or already paused, is left as it stands.
1425
+ * - A turn parked on a decision (an open `decision_requested`) is PAUSED on
1426
+ * that checkpoint: a park is a promise to a human that outlives the
1427
+ * consumer, and `resumeSession` continues it once the answer arrives.
1428
+ * - Any other turn is settled `cancelled` (`turn_completed`): it did not
1429
+ * complete and nothing failed; its consumer stopped reading.
1399
1430
  *
1400
1431
  * Never throws. It runs while an exception may already be unwinding, and a
1401
- * store that cannot be written must not replace the run's real failure with
1402
- * its own.
1432
+ * log that cannot be written must not replace the turn's real failure.
1403
1433
  */
1404
- async function settleAbandonedRun(runMgr, log) {
1434
+ async function settleAbandonedTurn(recorder, eventTranslator, log) {
1405
1435
  try {
1406
- // A terminal verdict is written whatever the park says: `deriveRunStatus`
1407
- // settles a run that finished, failed or was cancelled BEFORE it looks at
1408
- // a park ("terminal beats parked"), so a settled run is not waiting for
1409
- // anybody and the row it already wrote must reach the disk. This ordering
1410
- // is also what keeps a stale park from suppressing the write.
1411
- if (!isTerminalStatus(runMgr.status)) {
1412
- const parked = await findPendingCheckpoint(runMgr.getCheckpointStore(), runMgr.getRunScope());
1413
- if (parked) {
1414
- // Left exactly as it stands: no verdict, no write. The park row is
1415
- // this run's durable state, and `persist()` here would add a
1416
- // second claim — `running`, for a process that is gone — beside it.
1417
- log.info('Abandoned run left parked for a human to answer', {
1418
- [NAMZU.RUN_ID]: runMgr.id,
1419
- 'namzu.checkpoint.id': parked.id,
1420
- 'namzu.runtime.park_type': parked.pending?.request.type,
1421
- });
1422
- return;
1423
- }
1424
- runMgr.markCancelled();
1436
+ if (recorder.isClosed || recorder.isPaused || !recorder.isActive)
1437
+ return;
1438
+ await recorder.flush();
1439
+ const parked = await findPendingCheckpoint(recorder.log, { turnId: recorder.turnId });
1440
+ if (parked) {
1441
+ recorder.setStopReason('paused');
1442
+ await eventTranslator.emitEvent({
1443
+ type: 'turn_paused',
1444
+ checkpointId: parked.checkpointId,
1445
+ reason: 'The consumer stopped reading while the turn was awaiting a decision.',
1446
+ });
1447
+ await recorder.persist();
1448
+ log.info('Abandoned turn left paused for a human to answer', {
1449
+ [NAMZU.TURN_ID]: recorder.turnId,
1450
+ 'namzu.checkpoint.id': parked.checkpointId,
1451
+ 'namzu.runtime.park_type': parked.pending.request.type,
1452
+ });
1453
+ return;
1425
1454
  }
1426
- // Once: the `finally` that calls this runs once, and every site in the
1427
- // run body that settles through `finalize()` sets `settled` before it
1428
- // returns, so the two can never both write.
1429
- await runMgr.persist();
1430
- log.info('Abandoned run recorded as cancelled', {
1431
- [NAMZU.RUN_ID]: runMgr.id,
1455
+ if (!isTerminalStatus(recorder.status))
1456
+ recorder.markCancelled();
1457
+ await eventTranslator.emitEvent({
1458
+ type: 'turn_completed',
1459
+ result: recorder.getTurn().result ?? '',
1460
+ ...(recorder.stopReason ? { stopReason: recorder.stopReason } : {}),
1461
+ settlement: recorder.settlement(recorder.status === 'cancelled' ? 'cancelled' : 'completed'),
1462
+ });
1463
+ await recorder.persist();
1464
+ log.info('Abandoned turn recorded as cancelled', {
1465
+ [NAMZU.TURN_ID]: recorder.turnId,
1432
1466
  });
1433
1467
  }
1434
1468
  catch (err) {
1435
- log.error('Failed to record the terminal state of an abandoned run', {
1436
- [NAMZU.RUN_ID]: runMgr.id,
1469
+ log.error('Failed to record the end of an abandoned turn', {
1470
+ [NAMZU.TURN_ID]: recorder.turnId,
1437
1471
  'exception.message': err instanceof Error ? err.message : String(err),
1438
1472
  });
1439
1473
  }
@@ -1465,7 +1499,7 @@ export async function drainQuery(params, listener) {
1465
1499
  };
1466
1500
  return await drainPreparedQuery(fullParams, listener);
1467
1501
  }
1468
- /** @internal Canonical resume state already selected by `resumeRun`. */
1502
+ /** @internal Canonical resume state already selected by `resumeSession`. */
1469
1503
  export async function drainQueryWithSelectedResumeState(params, state, listener) {
1470
1504
  const fullParams = {
1471
1505
  ...params,
@@ -1480,8 +1514,8 @@ export async function drainQueryWithSelectedResumeState(params, state, listener)
1480
1514
  }
1481
1515
  function assertSelectedResumeAttribution(params, state) {
1482
1516
  const mismatchedFields = [];
1483
- if (params.runId !== state.runId)
1484
- mismatchedFields.push('runId');
1517
+ if (params.turnId !== state.turnId)
1518
+ mismatchedFields.push('turnId');
1485
1519
  if (params.sessionId !== state.sessionId)
1486
1520
  mismatchedFields.push('sessionId');
1487
1521
  if (params.topicId !== state.topicId)
@@ -1490,13 +1524,13 @@ function assertSelectedResumeAttribution(params, state) {
1490
1524
  mismatchedFields.push('projectId');
1491
1525
  if (params.tenantId !== state.tenantId)
1492
1526
  mismatchedFields.push('tenantId');
1493
- if (params.parentRunId !== state.parentRunId)
1494
- mismatchedFields.push('parentRunId');
1527
+ if (params.parentSessionId !== state.parentSessionId)
1528
+ mismatchedFields.push('parentSessionId');
1495
1529
  if (mismatchedFields.length === 0)
1496
1530
  return;
1497
1531
  throw new NamzuError({
1498
1532
  code: 'invalid_config',
1499
- message: 'The selected resume state does not match the run attribution supplied to the query.',
1533
+ message: 'The selected resume state does not match the turn attribution supplied to the query.',
1500
1534
  details: { fields: mismatchedFields },
1501
1535
  });
1502
1536
  }