@namzu/sdk 38.2.1 → 40.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 (602) hide show
  1. package/CHANGELOG.md +851 -0
  2. package/dist/advisory/executor.d.ts +10 -1
  3. package/dist/advisory/executor.d.ts.map +1 -1
  4. package/dist/advisory/executor.js +5 -26
  5. package/dist/advisory/executor.js.map +1 -1
  6. package/dist/advisory/history.d.ts +9 -0
  7. package/dist/advisory/history.d.ts.map +1 -0
  8. package/dist/advisory/history.js +120 -0
  9. package/dist/advisory/history.js.map +1 -0
  10. package/dist/advisory/index.d.ts +1 -1
  11. package/dist/advisory/index.d.ts.map +1 -1
  12. package/dist/advisory/index.js.map +1 -1
  13. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  14. package/dist/agents/ReactiveAgent.js +3 -0
  15. package/dist/agents/ReactiveAgent.js.map +1 -1
  16. package/dist/agents/runAgent.d.ts +10 -0
  17. package/dist/agents/runAgent.d.ts.map +1 -1
  18. package/dist/agents/runAgent.js +3 -0
  19. package/dist/agents/runAgent.js.map +1 -1
  20. package/dist/compaction/manual.d.ts +6 -0
  21. package/dist/compaction/manual.d.ts.map +1 -1
  22. package/dist/compaction/manual.js +21 -2
  23. package/dist/compaction/manual.js.map +1 -1
  24. package/dist/compaction/summary.d.ts.map +1 -1
  25. package/dist/compaction/summary.js +4 -1
  26. package/dist/compaction/summary.js.map +1 -1
  27. package/dist/config/runtime.js +2 -2
  28. package/dist/config/runtime.js.map +1 -1
  29. package/dist/connector/mcp/adapter.d.ts.map +1 -1
  30. package/dist/connector/mcp/adapter.js +20 -6
  31. package/dist/connector/mcp/adapter.js.map +1 -1
  32. package/dist/contracts/schemas.js +1 -1
  33. package/dist/contracts/schemas.js.map +1 -1
  34. package/dist/eval/harness-protection.d.ts +18 -0
  35. package/dist/eval/harness-protection.d.ts.map +1 -0
  36. package/dist/eval/harness-protection.js +58 -0
  37. package/dist/eval/harness-protection.js.map +1 -0
  38. package/dist/eval/harness-verification.d.ts +6 -1
  39. package/dist/eval/harness-verification.d.ts.map +1 -1
  40. package/dist/eval/harness-verification.js +19 -2
  41. package/dist/eval/harness-verification.js.map +1 -1
  42. package/dist/eval/index.d.ts +1 -0
  43. package/dist/eval/index.d.ts.map +1 -1
  44. package/dist/eval/index.js.map +1 -1
  45. package/dist/manager/resident/activity.d.ts +50 -0
  46. package/dist/manager/resident/activity.d.ts.map +1 -0
  47. package/dist/manager/resident/activity.js +125 -0
  48. package/dist/manager/resident/activity.js.map +1 -0
  49. package/dist/manager/resident/agenda.d.ts +13 -1
  50. package/dist/manager/resident/agenda.d.ts.map +1 -1
  51. package/dist/manager/resident/agenda.js +40 -5
  52. package/dist/manager/resident/agenda.js.map +1 -1
  53. package/dist/manager/resident/consumption.d.ts +104 -0
  54. package/dist/manager/resident/consumption.d.ts.map +1 -0
  55. package/dist/manager/resident/consumption.js +233 -0
  56. package/dist/manager/resident/consumption.js.map +1 -0
  57. package/dist/manager/resident/evidence-recall.d.ts +24 -0
  58. package/dist/manager/resident/evidence-recall.d.ts.map +1 -0
  59. package/dist/manager/resident/evidence-recall.js +295 -0
  60. package/dist/manager/resident/evidence-recall.js.map +1 -0
  61. package/dist/manager/resident/history-disk.d.ts +10 -0
  62. package/dist/manager/resident/history-disk.d.ts.map +1 -0
  63. package/dist/manager/resident/history-disk.js +50 -0
  64. package/dist/manager/resident/history-disk.js.map +1 -0
  65. package/dist/manager/resident/history.d.ts +79 -0
  66. package/dist/manager/resident/history.d.ts.map +1 -0
  67. package/dist/manager/resident/history.js +203 -0
  68. package/dist/manager/resident/history.js.map +1 -0
  69. package/dist/manager/resident/initiative.d.ts.map +1 -1
  70. package/dist/manager/resident/initiative.js +11 -3
  71. package/dist/manager/resident/initiative.js.map +1 -1
  72. package/dist/manager/resident/learning-cycle.d.ts +131 -0
  73. package/dist/manager/resident/learning-cycle.d.ts.map +1 -0
  74. package/dist/manager/resident/learning-cycle.js +306 -0
  75. package/dist/manager/resident/learning-cycle.js.map +1 -0
  76. package/dist/manager/resident/learning-observation.d.ts +80 -0
  77. package/dist/manager/resident/learning-observation.d.ts.map +1 -0
  78. package/dist/manager/resident/learning-observation.js +22 -0
  79. package/dist/manager/resident/learning-observation.js.map +1 -0
  80. package/dist/manager/resident/learning-store.d.ts +106 -0
  81. package/dist/manager/resident/learning-store.d.ts.map +1 -0
  82. package/dist/manager/resident/learning-store.js +598 -0
  83. package/dist/manager/resident/learning-store.js.map +1 -0
  84. package/dist/manager/resident/learning.d.ts +246 -3
  85. package/dist/manager/resident/learning.d.ts.map +1 -1
  86. package/dist/manager/resident/learning.js +96 -6
  87. package/dist/manager/resident/learning.js.map +1 -1
  88. package/dist/manager/resident/outbox.d.ts +4 -4
  89. package/dist/manager/resident/store.d.ts +37 -4
  90. package/dist/manager/resident/store.d.ts.map +1 -1
  91. package/dist/manager/resident/store.js +27 -3
  92. package/dist/manager/resident/store.js.map +1 -1
  93. package/dist/manager/resident/tool-evidence.d.ts +71 -0
  94. package/dist/manager/resident/tool-evidence.d.ts.map +1 -0
  95. package/dist/manager/resident/tool-evidence.js +285 -0
  96. package/dist/manager/resident/tool-evidence.js.map +1 -0
  97. package/dist/manager/run/persistence.d.ts +8 -0
  98. package/dist/manager/run/persistence.d.ts.map +1 -1
  99. package/dist/manager/run/persistence.js +18 -0
  100. package/dist/manager/run/persistence.js.map +1 -1
  101. package/dist/plugin/loader.d.ts.map +1 -1
  102. package/dist/plugin/loader.js +5 -3
  103. package/dist/plugin/loader.js.map +1 -1
  104. package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
  105. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  106. package/dist/prompt/coding-agent-doctrine.js +2 -0
  107. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  108. package/dist/prompt/index.d.ts +2 -0
  109. package/dist/prompt/index.d.ts.map +1 -1
  110. package/dist/prompt/index.js +1 -0
  111. package/dist/prompt/index.js.map +1 -1
  112. package/dist/prompt/resident-learning.d.ts +19 -0
  113. package/dist/prompt/resident-learning.d.ts.map +1 -0
  114. package/dist/prompt/resident-learning.js +125 -0
  115. package/dist/prompt/resident-learning.js.map +1 -0
  116. package/dist/prompt/resident-step.d.ts +8 -1
  117. package/dist/prompt/resident-step.d.ts.map +1 -1
  118. package/dist/prompt/resident-step.js +65 -4
  119. package/dist/prompt/resident-step.js.map +1 -1
  120. package/dist/provider/collect-chat-completion.d.ts +2 -1
  121. package/dist/provider/collect-chat-completion.d.ts.map +1 -1
  122. package/dist/provider/collect-chat-completion.js +7 -6
  123. package/dist/provider/collect-chat-completion.js.map +1 -1
  124. package/dist/provider/fallback.d.ts.map +1 -1
  125. package/dist/provider/fallback.js +2 -1
  126. package/dist/provider/fallback.js.map +1 -1
  127. package/dist/provider/stream-text.d.ts +16 -0
  128. package/dist/provider/stream-text.d.ts.map +1 -0
  129. package/dist/provider/stream-text.js +51 -0
  130. package/dist/provider/stream-text.js.map +1 -0
  131. package/dist/public-runtime.d.ts +16 -4
  132. package/dist/public-runtime.d.ts.map +1 -1
  133. package/dist/public-runtime.js +17 -4
  134. package/dist/public-runtime.js.map +1 -1
  135. package/dist/public-tools.d.ts +13 -0
  136. package/dist/public-tools.d.ts.map +1 -1
  137. package/dist/public-tools.js +16 -0
  138. package/dist/public-tools.js.map +1 -1
  139. package/dist/public-types.d.ts +15 -3
  140. package/dist/public-types.d.ts.map +1 -1
  141. package/dist/registry/tool/execute.d.ts.map +1 -1
  142. package/dist/registry/tool/execute.js +2 -3
  143. package/dist/registry/tool/execute.js.map +1 -1
  144. package/dist/registry/tool/portable.d.ts +65 -0
  145. package/dist/registry/tool/portable.d.ts.map +1 -0
  146. package/dist/registry/tool/portable.js +244 -0
  147. package/dist/registry/tool/portable.js.map +1 -0
  148. package/dist/registry/tool/schema.d.ts +32 -5
  149. package/dist/registry/tool/schema.d.ts.map +1 -1
  150. package/dist/registry/tool/schema.js +35 -9
  151. package/dist/registry/tool/schema.js.map +1 -1
  152. package/dist/registry/toolset/catalog.js +8 -8
  153. package/dist/registry/toolset/catalog.js.map +1 -1
  154. package/dist/run/LimitChecker.js +3 -3
  155. package/dist/run/LimitChecker.js.map +1 -1
  156. package/dist/run/evidence-query.d.ts +41 -0
  157. package/dist/run/evidence-query.d.ts.map +1 -0
  158. package/dist/run/evidence-query.js +270 -0
  159. package/dist/run/evidence-query.js.map +1 -0
  160. package/dist/run/evidence-recall.d.ts +99 -0
  161. package/dist/run/evidence-recall.d.ts.map +1 -0
  162. package/dist/run/evidence-recall.js +633 -0
  163. package/dist/run/evidence-recall.js.map +1 -0
  164. package/dist/run/index.d.ts +2 -0
  165. package/dist/run/index.d.ts.map +1 -1
  166. package/dist/run/index.js +1 -0
  167. package/dist/run/index.js.map +1 -1
  168. package/dist/run/json-claim-verifier.d.ts +83 -0
  169. package/dist/run/json-claim-verifier.d.ts.map +1 -0
  170. package/dist/run/json-claim-verifier.js +200 -0
  171. package/dist/run/json-claim-verifier.js.map +1 -0
  172. package/dist/run/preparation-context-error.d.ts +10 -0
  173. package/dist/run/preparation-context-error.d.ts.map +1 -0
  174. package/dist/run/preparation-context-error.js +15 -0
  175. package/dist/run/preparation-context-error.js.map +1 -0
  176. package/dist/run-query/index.d.ts +3 -1
  177. package/dist/run-query/index.d.ts.map +1 -1
  178. package/dist/runtime/jobs/awaited-jobs.d.ts +215 -0
  179. package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -0
  180. package/dist/runtime/jobs/awaited-jobs.js +259 -0
  181. package/dist/runtime/jobs/awaited-jobs.js.map +1 -0
  182. package/dist/runtime/jobs/registry.d.ts +33 -2
  183. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  184. package/dist/runtime/jobs/registry.js +37 -0
  185. package/dist/runtime/jobs/registry.js.map +1 -1
  186. package/dist/runtime/query/callback-inference.d.ts +8 -0
  187. package/dist/runtime/query/callback-inference.d.ts.map +1 -0
  188. package/dist/runtime/query/callback-inference.js +89 -0
  189. package/dist/runtime/query/callback-inference.js.map +1 -0
  190. package/dist/runtime/query/checkpoint.d.ts +4 -0
  191. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  192. package/dist/runtime/query/checkpoint.js +13 -0
  193. package/dist/runtime/query/checkpoint.js.map +1 -1
  194. package/dist/runtime/query/events.d.ts +1 -0
  195. package/dist/runtime/query/events.d.ts.map +1 -1
  196. package/dist/runtime/query/events.js +18 -0
  197. package/dist/runtime/query/events.js.map +1 -1
  198. package/dist/runtime/query/executor.d.ts +35 -1
  199. package/dist/runtime/query/executor.d.ts.map +1 -1
  200. package/dist/runtime/query/executor.js +77 -8
  201. package/dist/runtime/query/executor.js.map +1 -1
  202. package/dist/runtime/query/file-evidence-context.d.ts +5 -0
  203. package/dist/runtime/query/file-evidence-context.d.ts.map +1 -0
  204. package/dist/runtime/query/file-evidence-context.js +180 -0
  205. package/dist/runtime/query/file-evidence-context.js.map +1 -0
  206. package/dist/runtime/query/file-evidence-replay.d.ts +260 -0
  207. package/dist/runtime/query/file-evidence-replay.d.ts.map +1 -0
  208. package/dist/runtime/query/file-evidence-replay.js +647 -0
  209. package/dist/runtime/query/file-evidence-replay.js.map +1 -0
  210. package/dist/runtime/query/file-evidence-seed.d.ts +50 -0
  211. package/dist/runtime/query/file-evidence-seed.d.ts.map +1 -0
  212. package/dist/runtime/query/file-evidence-seed.js +100 -0
  213. package/dist/runtime/query/file-evidence-seed.js.map +1 -0
  214. package/dist/runtime/query/guard.d.ts.map +1 -1
  215. package/dist/runtime/query/guard.js +4 -0
  216. package/dist/runtime/query/guard.js.map +1 -1
  217. package/dist/runtime/query/index.d.ts +10 -1
  218. package/dist/runtime/query/index.d.ts.map +1 -1
  219. package/dist/runtime/query/index.js +133 -26
  220. package/dist/runtime/query/index.js.map +1 -1
  221. package/dist/runtime/query/iteration/index.d.ts +92 -36
  222. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  223. package/dist/runtime/query/iteration/index.js +420 -117
  224. package/dist/runtime/query/iteration/index.js.map +1 -1
  225. package/dist/runtime/query/iteration/phases/advisory.d.ts +2 -1
  226. package/dist/runtime/query/iteration/phases/advisory.d.ts.map +1 -1
  227. package/dist/runtime/query/iteration/phases/advisory.js +2 -1
  228. package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
  229. package/dist/runtime/query/iteration/phases/context.d.ts +12 -1
  230. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  231. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  232. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  233. package/dist/runtime/query/iteration/phases/tool-review.js +8 -1
  234. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  235. package/dist/runtime/query/iteration/provider-rejected-image.d.ts +2 -1
  236. package/dist/runtime/query/iteration/provider-rejected-image.d.ts.map +1 -1
  237. package/dist/runtime/query/iteration/provider-rejected-image.js +5 -2
  238. package/dist/runtime/query/iteration/provider-rejected-image.js.map +1 -1
  239. package/dist/runtime/query/iteration/stream-turn.d.ts +4 -1
  240. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  241. package/dist/runtime/query/iteration/stream-turn.js +22 -8
  242. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  243. package/dist/runtime/query/plugin-hooks.d.ts +14 -0
  244. package/dist/runtime/query/plugin-hooks.d.ts.map +1 -1
  245. package/dist/runtime/query/plugin-hooks.js +18 -0
  246. package/dist/runtime/query/plugin-hooks.js.map +1 -1
  247. package/dist/runtime/query/repeat-call.d.ts +17 -4
  248. package/dist/runtime/query/repeat-call.d.ts.map +1 -1
  249. package/dist/runtime/query/repeat-call.js +26 -19
  250. package/dist/runtime/query/repeat-call.js.map +1 -1
  251. package/dist/runtime/query/resume-pending.d.ts +18 -33
  252. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  253. package/dist/runtime/query/resume-pending.js +59 -42
  254. package/dist/runtime/query/resume-pending.js.map +1 -1
  255. package/dist/runtime/query/review-policy.d.ts +4 -4
  256. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  257. package/dist/runtime/query/review-policy.js +10 -9
  258. package/dist/runtime/query/review-policy.js.map +1 -1
  259. package/dist/runtime/query/sandbox-lifecycle.d.ts.map +1 -1
  260. package/dist/runtime/query/sandbox-lifecycle.js +4 -0
  261. package/dist/runtime/query/sandbox-lifecycle.js.map +1 -1
  262. package/dist/runtime/query/steering.d.ts +11 -1
  263. package/dist/runtime/query/steering.d.ts.map +1 -1
  264. package/dist/runtime/query/steering.js +12 -1
  265. package/dist/runtime/query/steering.js.map +1 -1
  266. package/dist/runtime/query/tool-output-budget.d.ts +10 -6
  267. package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
  268. package/dist/runtime/query/tool-output-budget.js +54 -12
  269. package/dist/runtime/query/tool-output-budget.js.map +1 -1
  270. package/dist/runtime/query/tooling.d.ts +5 -1
  271. package/dist/runtime/query/tooling.d.ts.map +1 -1
  272. package/dist/runtime/query/tooling.js +5 -0
  273. package/dist/runtime/query/tooling.js.map +1 -1
  274. package/dist/scheduler/completion-inbox.d.ts +49 -0
  275. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  276. package/dist/scheduler/completion-inbox.js +122 -2
  277. package/dist/scheduler/completion-inbox.js.map +1 -1
  278. package/dist/store/evidence/compaction-archive.d.ts +109 -0
  279. package/dist/store/evidence/compaction-archive.d.ts.map +1 -0
  280. package/dist/store/evidence/compaction-archive.js +125 -0
  281. package/dist/store/evidence/compaction-archive.js.map +1 -0
  282. package/dist/store/evidence/compaction-provenance.d.ts +7 -0
  283. package/dist/store/evidence/compaction-provenance.d.ts.map +1 -0
  284. package/dist/store/evidence/compaction-provenance.js +49 -0
  285. package/dist/store/evidence/compaction-provenance.js.map +1 -0
  286. package/dist/store/evidence/compaction-text.d.ts +16 -0
  287. package/dist/store/evidence/compaction-text.d.ts.map +1 -0
  288. package/dist/store/evidence/compaction-text.js +51 -0
  289. package/dist/store/evidence/compaction-text.js.map +1 -0
  290. package/dist/store/evidence/disk.d.ts +11 -0
  291. package/dist/store/evidence/disk.d.ts.map +1 -0
  292. package/dist/store/evidence/disk.js +367 -0
  293. package/dist/store/evidence/disk.js.map +1 -0
  294. package/dist/store/evidence/format.d.ts +25 -0
  295. package/dist/store/evidence/format.d.ts.map +1 -0
  296. package/dist/store/evidence/format.js +115 -0
  297. package/dist/store/evidence/format.js.map +1 -0
  298. package/dist/store/evidence/index-page.d.ts +208 -0
  299. package/dist/store/evidence/index-page.d.ts.map +1 -0
  300. package/dist/store/evidence/index-page.js +262 -0
  301. package/dist/store/evidence/index-page.js.map +1 -0
  302. package/dist/store/evidence/io.d.ts +24 -0
  303. package/dist/store/evidence/io.d.ts.map +1 -0
  304. package/dist/store/evidence/io.js +69 -0
  305. package/dist/store/evidence/io.js.map +1 -0
  306. package/dist/store/evidence/linked.d.ts +9 -0
  307. package/dist/store/evidence/linked.d.ts.map +1 -0
  308. package/dist/store/evidence/linked.js +314 -0
  309. package/dist/store/evidence/linked.js.map +1 -0
  310. package/dist/store/evidence/passages.d.ts +15 -0
  311. package/dist/store/evidence/passages.d.ts.map +1 -0
  312. package/dist/store/evidence/passages.js +72 -0
  313. package/dist/store/evidence/passages.js.map +1 -0
  314. package/dist/store/evidence/record-chain.d.ts +42 -0
  315. package/dist/store/evidence/record-chain.d.ts.map +1 -0
  316. package/dist/store/evidence/record-chain.js +111 -0
  317. package/dist/store/evidence/record-chain.js.map +1 -0
  318. package/dist/store/evidence/search-input.d.ts +21 -0
  319. package/dist/store/evidence/search-input.d.ts.map +1 -0
  320. package/dist/store/evidence/search-input.js +44 -0
  321. package/dist/store/evidence/search-input.js.map +1 -0
  322. package/dist/store/evidence/selection.d.ts +9 -0
  323. package/dist/store/evidence/selection.d.ts.map +1 -0
  324. package/dist/store/evidence/selection.js +17 -0
  325. package/dist/store/evidence/selection.js.map +1 -0
  326. package/dist/store/evidence/source-kind.d.ts +11 -0
  327. package/dist/store/evidence/source-kind.d.ts.map +1 -0
  328. package/dist/store/evidence/source-kind.js +26 -0
  329. package/dist/store/evidence/source-kind.js.map +1 -0
  330. package/dist/store/evidence/source-text.d.ts +51 -0
  331. package/dist/store/evidence/source-text.d.ts.map +1 -0
  332. package/dist/store/evidence/source-text.js +213 -0
  333. package/dist/store/evidence/source-text.js.map +1 -0
  334. package/dist/store/evidence/types.d.ts +162 -0
  335. package/dist/store/evidence/types.d.ts.map +1 -0
  336. package/dist/store/evidence/types.js +2 -0
  337. package/dist/store/evidence/types.js.map +1 -0
  338. package/dist/store/memory/disk.d.ts +2 -0
  339. package/dist/store/memory/disk.d.ts.map +1 -1
  340. package/dist/store/memory/disk.js +2 -1
  341. package/dist/store/memory/disk.js.map +1 -1
  342. package/dist/store/run/disk.d.ts +10 -0
  343. package/dist/store/run/disk.d.ts.map +1 -1
  344. package/dist/store/run/disk.js +87 -7
  345. package/dist/store/run/disk.js.map +1 -1
  346. package/dist/store/run/memory.d.ts +1 -0
  347. package/dist/store/run/memory.d.ts.map +1 -1
  348. package/dist/store/run/memory.js +10 -0
  349. package/dist/store/run/memory.js.map +1 -1
  350. package/dist/store/run/tool-executions.d.ts +13 -0
  351. package/dist/store/run/tool-executions.d.ts.map +1 -0
  352. package/dist/store/run/tool-executions.js +99 -0
  353. package/dist/store/run/tool-executions.js.map +1 -0
  354. package/dist/store/session/index.d.ts +2 -0
  355. package/dist/store/session/index.d.ts.map +1 -1
  356. package/dist/store/session/index.js +1 -0
  357. package/dist/store/session/index.js.map +1 -1
  358. package/dist/store/session/sqlite.d.ts +57 -0
  359. package/dist/store/session/sqlite.d.ts.map +1 -0
  360. package/dist/store/session/sqlite.js +430 -0
  361. package/dist/store/session/sqlite.js.map +1 -0
  362. package/dist/tools/builtins/bash.d.ts.map +1 -1
  363. package/dist/tools/builtins/bash.js +4 -10
  364. package/dist/tools/builtins/bash.js.map +1 -1
  365. package/dist/tools/builtins/edit-apply.d.ts +126 -0
  366. package/dist/tools/builtins/edit-apply.d.ts.map +1 -0
  367. package/dist/tools/builtins/edit-apply.js +360 -0
  368. package/dist/tools/builtins/edit-apply.js.map +1 -0
  369. package/dist/tools/builtins/edit.d.ts +143 -1
  370. package/dist/tools/builtins/edit.d.ts.map +1 -1
  371. package/dist/tools/builtins/edit.js +37 -219
  372. package/dist/tools/builtins/edit.js.map +1 -1
  373. package/dist/tools/builtins/index.d.ts +1 -0
  374. package/dist/tools/builtins/index.d.ts.map +1 -1
  375. package/dist/tools/builtins/index.js +9 -3
  376. package/dist/tools/builtins/index.js.map +1 -1
  377. package/dist/tools/builtins/job.d.ts.map +1 -1
  378. package/dist/tools/builtins/job.js +5 -6
  379. package/dist/tools/builtins/job.js.map +1 -1
  380. package/dist/tools/builtins/read-file.d.ts +2 -2
  381. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  382. package/dist/tools/builtins/read-file.js +50 -65
  383. package/dist/tools/builtins/read-file.js.map +1 -1
  384. package/dist/tools/builtins/read-render.d.ts +56 -0
  385. package/dist/tools/builtins/read-render.d.ts.map +1 -0
  386. package/dist/tools/builtins/read-render.js +73 -0
  387. package/dist/tools/builtins/read-render.js.map +1 -0
  388. package/dist/tools/builtins/wait-for-job-bounds.d.ts +67 -0
  389. package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -0
  390. package/dist/tools/builtins/wait-for-job-bounds.js +108 -0
  391. package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -0
  392. package/dist/tools/builtins/wait-for-job.d.ts +6 -0
  393. package/dist/tools/builtins/wait-for-job.d.ts.map +1 -0
  394. package/dist/tools/builtins/wait-for-job.js +162 -0
  395. package/dist/tools/builtins/wait-for-job.js.map +1 -0
  396. package/dist/tools/builtins/write-file.js +7 -2
  397. package/dist/tools/builtins/write-file.js.map +1 -1
  398. package/dist/tools/coordinator/index.d.ts.map +1 -1
  399. package/dist/tools/coordinator/index.js +1 -7
  400. package/dist/tools/coordinator/index.js.map +1 -1
  401. package/dist/tools/defineTool.d.ts +2 -1
  402. package/dist/tools/defineTool.d.ts.map +1 -1
  403. package/dist/tools/defineTool.js +1 -1
  404. package/dist/tools/defineTool.js.map +1 -1
  405. package/dist/tools/file-read-tracker.d.ts.map +1 -1
  406. package/dist/tools/file-read-tracker.js +90 -3
  407. package/dist/tools/file-read-tracker.js.map +1 -1
  408. package/dist/tools/resident-history.d.ts +10 -0
  409. package/dist/tools/resident-history.d.ts.map +1 -0
  410. package/dist/tools/resident-history.js +80 -0
  411. package/dist/tools/resident-history.js.map +1 -0
  412. package/dist/tools/resident-tool-evidence.d.ts +5 -0
  413. package/dist/tools/resident-tool-evidence.d.ts.map +1 -0
  414. package/dist/tools/resident-tool-evidence.js +57 -0
  415. package/dist/tools/resident-tool-evidence.js.map +1 -0
  416. package/dist/types/advisory/config.d.ts +7 -0
  417. package/dist/types/advisory/config.d.ts.map +1 -1
  418. package/dist/types/agent/reactive.d.ts +1 -0
  419. package/dist/types/agent/reactive.d.ts.map +1 -1
  420. package/dist/types/authorization/index.d.ts +9 -9
  421. package/dist/types/authorization/index.d.ts.map +1 -1
  422. package/dist/types/authorization/index.js +1 -1
  423. package/dist/types/authorization/index.js.map +1 -1
  424. package/dist/types/hitl/index.d.ts +4 -0
  425. package/dist/types/hitl/index.d.ts.map +1 -1
  426. package/dist/types/hitl/index.js.map +1 -1
  427. package/dist/types/message/index.d.ts +16 -2
  428. package/dist/types/message/index.d.ts.map +1 -1
  429. package/dist/types/message/index.js +10 -1
  430. package/dist/types/message/index.js.map +1 -1
  431. package/dist/types/provider/chat.d.ts +2 -0
  432. package/dist/types/provider/chat.d.ts.map +1 -1
  433. package/dist/types/provider/stream.d.ts +4 -0
  434. package/dist/types/provider/stream.d.ts.map +1 -1
  435. package/dist/types/run/answer-review.d.ts +34 -3
  436. package/dist/types/run/answer-review.d.ts.map +1 -1
  437. package/dist/types/run/config.d.ts +3 -0
  438. package/dist/types/run/config.d.ts.map +1 -1
  439. package/dist/types/run/entity.d.ts +20 -0
  440. package/dist/types/run/entity.d.ts.map +1 -1
  441. package/dist/types/run/events.d.ts +31 -8
  442. package/dist/types/run/events.d.ts.map +1 -1
  443. package/dist/types/run/events.js.map +1 -1
  444. package/dist/types/run/prepare-step.d.ts +53 -8
  445. package/dist/types/run/prepare-step.d.ts.map +1 -1
  446. package/dist/types/run/store.d.ts +29 -4
  447. package/dist/types/run/store.d.ts.map +1 -1
  448. package/dist/types/run/store.js +0 -28
  449. package/dist/types/run/store.js.map +1 -1
  450. package/dist/types/sandbox/index.d.ts +15 -14
  451. package/dist/types/sandbox/index.d.ts.map +1 -1
  452. package/dist/types/sandbox/index.js.map +1 -1
  453. package/dist/types/tool/index.d.ts +124 -1
  454. package/dist/types/tool/index.d.ts.map +1 -1
  455. package/dist/types/tool/index.js.map +1 -1
  456. package/dist/utils/await-with-abort.d.ts +8 -0
  457. package/dist/utils/await-with-abort.d.ts.map +1 -0
  458. package/dist/utils/await-with-abort.js +28 -0
  459. package/dist/utils/await-with-abort.js.map +1 -0
  460. package/dist/utils/env.d.ts +19 -0
  461. package/dist/utils/env.d.ts.map +1 -0
  462. package/dist/utils/env.js +25 -0
  463. package/dist/utils/env.js.map +1 -0
  464. package/dist/utils/evidence-time.d.ts +3 -0
  465. package/dist/utils/evidence-time.d.ts.map +1 -0
  466. package/dist/utils/evidence-time.js +10 -0
  467. package/dist/utils/evidence-time.js.map +1 -0
  468. package/dist/utils/evidence-tokens.d.ts +13 -0
  469. package/dist/utils/evidence-tokens.d.ts.map +1 -0
  470. package/dist/utils/evidence-tokens.js +29 -0
  471. package/dist/utils/evidence-tokens.js.map +1 -0
  472. package/package.json +1 -1
  473. package/src/advisory/executor.ts +15 -30
  474. package/src/advisory/history.ts +126 -0
  475. package/src/advisory/index.ts +5 -1
  476. package/src/agents/ReactiveAgent.ts +3 -0
  477. package/src/agents/runAgent.ts +14 -1
  478. package/src/compaction/manual.ts +30 -2
  479. package/src/compaction/summary.ts +4 -1
  480. package/src/config/runtime.ts +2 -2
  481. package/src/connector/mcp/adapter.ts +20 -6
  482. package/src/contracts/schemas.ts +1 -1
  483. package/src/eval/harness-protection.ts +79 -0
  484. package/src/eval/harness-verification.ts +31 -1
  485. package/src/eval/index.ts +1 -0
  486. package/src/manager/resident/activity.ts +187 -0
  487. package/src/manager/resident/agenda.ts +59 -5
  488. package/src/manager/resident/consumption.ts +311 -0
  489. package/src/manager/resident/evidence-recall.ts +363 -0
  490. package/src/manager/resident/history-disk.ts +63 -0
  491. package/src/manager/resident/history.ts +312 -0
  492. package/src/manager/resident/initiative.ts +13 -3
  493. package/src/manager/resident/learning-cycle.ts +499 -0
  494. package/src/manager/resident/learning-observation.ts +39 -0
  495. package/src/manager/resident/learning-store.ts +813 -0
  496. package/src/manager/resident/learning.ts +132 -8
  497. package/src/manager/resident/store.ts +31 -3
  498. package/src/manager/resident/tool-evidence.ts +412 -0
  499. package/src/manager/run/persistence.ts +18 -0
  500. package/src/plugin/loader.ts +8 -3
  501. package/src/prompt/coding-agent-doctrine.ts +2 -0
  502. package/src/prompt/index.ts +2 -0
  503. package/src/prompt/resident-learning.ts +143 -0
  504. package/src/prompt/resident-step.ts +83 -3
  505. package/src/provider/collect-chat-completion.ts +7 -6
  506. package/src/provider/fallback.ts +2 -1
  507. package/src/provider/stream-text.ts +56 -0
  508. package/src/public-runtime.ts +39 -1
  509. package/src/public-tools.ts +21 -0
  510. package/src/public-types.ts +98 -0
  511. package/src/registry/tool/execute.ts +2 -4
  512. package/src/registry/tool/portable.ts +264 -0
  513. package/src/registry/tool/schema.ts +38 -8
  514. package/src/registry/toolset/catalog.ts +8 -9
  515. package/src/run/LimitChecker.ts +3 -3
  516. package/src/run/evidence-query.ts +333 -0
  517. package/src/run/evidence-recall.ts +854 -0
  518. package/src/run/index.ts +11 -0
  519. package/src/run/json-claim-verifier.ts +298 -0
  520. package/src/run/preparation-context-error.ts +16 -0
  521. package/src/run-query/index.ts +1 -1
  522. package/src/runtime/jobs/awaited-jobs.ts +271 -0
  523. package/src/runtime/jobs/registry.ts +50 -0
  524. package/src/runtime/query/callback-inference.ts +94 -0
  525. package/src/runtime/query/checkpoint.ts +14 -0
  526. package/src/runtime/query/events.ts +22 -0
  527. package/src/runtime/query/executor.ts +100 -10
  528. package/src/runtime/query/file-evidence-context.ts +209 -0
  529. package/src/runtime/query/file-evidence-replay.ts +776 -0
  530. package/src/runtime/query/file-evidence-seed.ts +126 -0
  531. package/src/runtime/query/guard.ts +2 -0
  532. package/src/runtime/query/index.ts +153 -27
  533. package/src/runtime/query/iteration/index.ts +467 -110
  534. package/src/runtime/query/iteration/phases/advisory.ts +3 -0
  535. package/src/runtime/query/iteration/phases/context.ts +12 -0
  536. package/src/runtime/query/iteration/phases/tool-review.ts +7 -0
  537. package/src/runtime/query/iteration/provider-rejected-image.ts +6 -1
  538. package/src/runtime/query/iteration/stream-turn.ts +35 -8
  539. package/src/runtime/query/plugin-hooks.ts +20 -0
  540. package/src/runtime/query/repeat-call.ts +28 -18
  541. package/src/runtime/query/resume-pending.ts +65 -40
  542. package/src/runtime/query/review-policy.ts +13 -9
  543. package/src/runtime/query/sandbox-lifecycle.ts +3 -0
  544. package/src/runtime/query/steering.ts +11 -0
  545. package/src/runtime/query/tool-output-budget.ts +65 -13
  546. package/src/runtime/query/tooling.ts +10 -1
  547. package/src/scheduler/completion-inbox.ts +124 -2
  548. package/src/store/evidence/compaction-archive.ts +139 -0
  549. package/src/store/evidence/compaction-provenance.ts +52 -0
  550. package/src/store/evidence/compaction-text.ts +61 -0
  551. package/src/store/evidence/disk.ts +461 -0
  552. package/src/store/evidence/format.ts +126 -0
  553. package/src/store/evidence/index-page.ts +292 -0
  554. package/src/store/evidence/io.ts +95 -0
  555. package/src/store/evidence/linked.ts +365 -0
  556. package/src/store/evidence/passages.ts +88 -0
  557. package/src/store/evidence/record-chain.ts +108 -0
  558. package/src/store/evidence/search-input.ts +62 -0
  559. package/src/store/evidence/selection.ts +25 -0
  560. package/src/store/evidence/source-kind.ts +36 -0
  561. package/src/store/evidence/source-text.ts +285 -0
  562. package/src/store/evidence/types.ts +177 -0
  563. package/src/store/memory/disk.ts +4 -1
  564. package/src/store/run/disk.ts +110 -8
  565. package/src/store/run/memory.ts +10 -0
  566. package/src/store/run/tool-executions.ts +112 -0
  567. package/src/store/session/index.ts +2 -0
  568. package/src/store/session/sqlite.ts +584 -0
  569. package/src/tools/builtins/bash.ts +4 -10
  570. package/src/tools/builtins/edit-apply.ts +456 -0
  571. package/src/tools/builtins/edit.ts +39 -270
  572. package/src/tools/builtins/index.ts +9 -3
  573. package/src/tools/builtins/job.ts +5 -6
  574. package/src/tools/builtins/read-file.ts +56 -77
  575. package/src/tools/builtins/read-render.ts +104 -0
  576. package/src/tools/builtins/wait-for-job-bounds.ts +179 -0
  577. package/src/tools/builtins/wait-for-job.ts +184 -0
  578. package/src/tools/builtins/write-file.ts +7 -2
  579. package/src/tools/coordinator/index.ts +1 -7
  580. package/src/tools/defineTool.ts +4 -2
  581. package/src/tools/file-read-tracker.ts +86 -2
  582. package/src/tools/resident-history.ts +86 -0
  583. package/src/tools/resident-tool-evidence.ts +68 -0
  584. package/src/types/advisory/config.ts +7 -0
  585. package/src/types/agent/reactive.ts +1 -0
  586. package/src/types/authorization/index.ts +2 -2
  587. package/src/types/hitl/index.ts +4 -0
  588. package/src/types/message/index.ts +22 -0
  589. package/src/types/provider/chat.ts +2 -0
  590. package/src/types/provider/stream.ts +4 -0
  591. package/src/types/run/answer-review.ts +34 -3
  592. package/src/types/run/config.ts +3 -0
  593. package/src/types/run/entity.ts +21 -0
  594. package/src/types/run/events.ts +31 -8
  595. package/src/types/run/prepare-step.ts +59 -8
  596. package/src/types/run/store.ts +35 -4
  597. package/src/types/sandbox/index.ts +15 -14
  598. package/src/types/tool/index.ts +123 -1
  599. package/src/utils/await-with-abort.ts +26 -0
  600. package/src/utils/env.ts +23 -0
  601. package/src/utils/evidence-time.ts +9 -0
  602. package/src/utils/evidence-tokens.ts +32 -0
@@ -1,3 +1,4 @@
1
+ import type { AdvisoryTurnContext } from '../../../../advisory/executor.js'
1
2
  import { serializeState } from '../../../../compaction/serializer.js'
2
3
  import { NAMZU } from '../../../../constants/telemetry/index.js'
3
4
  import type { AdvisoryRequest, TriggerEvaluationState } from '../../../../types/advisory/index.js'
@@ -47,6 +48,7 @@ export async function runAdvisoryPhase(
47
48
  ctx: IterationContext,
48
49
  iterationNum: number,
49
50
  response: ChatCompletionResponse,
51
+ turn?: AdvisoryTurnContext,
50
52
  ): Promise<void> {
51
53
  const advisoryCtx = ctx.advisoryCtx
52
54
  if (!advisoryCtx) return
@@ -105,6 +107,7 @@ export async function runAdvisoryPhase(
105
107
  try {
106
108
  const executionResult = await advisoryCtx.executor.consult(advisor, request, {
107
109
  messages: ctx.runMgr.messages,
110
+ ...(turn ? { turn } : {}),
108
111
  workingStateSummary,
109
112
  toolCatalog: ctx.tools.toLLMTools(ctx.allowedTools),
110
113
  iteration: iterationNum,
@@ -26,6 +26,7 @@ import type {
26
26
  AgentRunConfig,
27
27
  BeforeStep,
28
28
  PrepareStepChain,
29
+ PrepareStepContext,
29
30
  RunEvent,
30
31
  StepResult,
31
32
  StopCondition,
@@ -34,6 +35,7 @@ import type { StructuredOutputConfig } from '../../../../types/structured-output
34
35
  import type { TaskStore } from '../../../../types/task/index.js'
35
36
  import type { ToolRegistryContract } from '../../../../types/tool/index.js'
36
37
  import type { Logger } from '../../../../utils/logger.js'
38
+ import type { AwaitedJobs } from '../../../jobs/awaited-jobs.js'
37
39
  import type { CheckpointManager } from '../../checkpoint.js'
38
40
  import type { EmitEvent } from '../../events.js'
39
41
  import type { ToolExecutor } from '../../executor.js'
@@ -135,6 +137,15 @@ export interface IterationContext {
135
137
  readonly onSteeringDelivered?: (text: string) => void
136
138
  /** Exit notices for the run's background jobs, drained into the next tool result. */
137
139
  readonly jobNotices?: SteeringChannel
140
+ /**
141
+ * Background jobs the model said it is waiting on, which is the only kind
142
+ * the loop holds a finishing run open for.
143
+ *
144
+ * Absent means the loop behaves exactly as it did before this existed: a
145
+ * job's exit still reaches the model as a notice on the next tool result,
146
+ * and a run whose model stopped calling tools settles without waiting.
147
+ */
148
+ readonly awaitedJobs?: AwaitedJobs
138
149
  readonly checkpointMgr: CheckpointManager
139
150
  readonly planManager: PlanManager
140
151
 
@@ -229,6 +240,7 @@ export interface IterationContext {
229
240
 
230
241
  /** Host hook that shapes each step before the model call. */
231
242
  readonly prepareStep?: PrepareStepChain
243
+ readonly captureRunEvidence?: PrepareStepContext['captureRunEvidence']
232
244
  readonly beforeStep?: BeforeStep
233
245
  }
234
246
 
@@ -150,6 +150,10 @@ export async function* runToolReview(
150
150
  attachSteering(batch.messages, ctx.steering, ctx.onSteeringDelivered),
151
151
  ctx.jobNotices,
152
152
  formatJobNote,
153
+ // The exits that text accounts for have now been read, so the
154
+ // record of them stops being pending work. Left standing, it
155
+ // buys the model a turn the next time any job queues a notice.
156
+ () => ctx.awaitedJobs?.noticesDelivered(),
153
157
  ),
154
158
  notices,
155
159
  )) {
@@ -220,6 +224,9 @@ export async function* runToolReview(
220
224
  toolCall.authorization = {
221
225
  decision: gateResult.decision,
222
226
  ...(gateResult.reason ? { reason: gateResult.reason } : {}),
227
+ ...(gateResult.decision === 'review' && gateResult.matchedRule
228
+ ? { explicitReview: true as const }
229
+ : {}),
223
230
  }
224
231
  }
225
232
 
@@ -1,4 +1,5 @@
1
1
  import { isProviderRequestError } from '../../../provider/errors.js'
2
+ import type { Message } from '../../../types/message/index.js'
2
3
  import type {
3
4
  ChatCompletionParams,
4
5
  LLMProvider,
@@ -42,7 +43,8 @@ function isAcceptedChunk(chunk: StreamChunk): boolean {
42
43
  chunk.delta.citation ||
43
44
  chunk.finishReason !== undefined ||
44
45
  chunk.usage !== undefined ||
45
- chunk.replayState !== undefined,
46
+ chunk.replayState !== undefined ||
47
+ chunk.textParts !== undefined,
46
48
  )
47
49
  }
48
50
 
@@ -62,8 +64,10 @@ export async function* streamWithProviderRejectedImageRecovery(
62
64
  provider: LLMProvider,
63
65
  params: ChatCompletionParams,
64
66
  onAccepted: (identity: RequestImageIdentity) => Promise<void>,
67
+ onRequest?: (messages: readonly Message[]) => void,
65
68
  ): AsyncIterable<StreamChunk> {
66
69
  const candidate = findSingleRequestImage(params.messages)
70
+ onRequest?.(params.messages)
67
71
  if (candidate === null) {
68
72
  yield* provider.chatStream(params)
69
73
  return
@@ -90,6 +94,7 @@ export async function* streamWithProviderRejectedImageRecovery(
90
94
  }
91
95
  let accepted = false
92
96
  let retryReportedError = false
97
+ onRequest?.(retryParams.messages)
93
98
  for await (const chunk of provider.chatStream(retryParams)) {
94
99
  if (chunk.error !== undefined) retryReportedError = true
95
100
  if (!accepted && isAcceptedChunk(chunk)) {
@@ -4,6 +4,7 @@ import {
4
4
  assertNativeStructuredOutputSupported,
5
5
  } from '../../../provider/capabilities.js'
6
6
  import { isProviderRequestError } from '../../../provider/errors.js'
7
+ import { StreamTextAccumulator } from '../../../provider/stream-text.js'
7
8
  import { GENAI, NAMZU, chatSpanName, parentContext } from '../../../telemetry/attributes.js'
8
9
  import {
9
10
  recordModelDuration,
@@ -14,7 +15,12 @@ import { getTracer } from '../../../telemetry/runtime-accessors.js'
14
15
  import { mergeTokenUsage } from '../../../types/common/index.js'
15
16
  import { NamzuError } from '../../../types/errors/index.js'
16
17
  import type { ToolUseId } from '../../../types/ids/index.js'
17
- import type { Citation, ReasoningBlock } from '../../../types/message/index.js'
18
+ import type {
19
+ AssistantTextPart,
20
+ Citation,
21
+ Message,
22
+ ReasoningBlock,
23
+ } from '../../../types/message/index.js'
18
24
  import { ProviderError } from '../../../types/provider/errors.js'
19
25
  import type {
20
26
  ChatCompletionResponse,
@@ -54,6 +60,8 @@ function synthesizeMessageStopReason(
54
60
  export interface StreamingTurnResult {
55
61
  response: ChatCompletionResponse
56
62
  messageId: import('../../../types/ids/index.js').MessageId
63
+ /** Captured only for host review, at the provider-chain dispatch boundary. */
64
+ requestMessages?: readonly Message[]
57
65
  }
58
66
 
59
67
  /**
@@ -100,6 +108,7 @@ async function settleCancelledTurn(args: {
100
108
  messageId: import('../../../types/ids/index.js').MessageId
101
109
  usage: ChatCompletionResponse['usage']
102
110
  text: string
111
+ textParts?: readonly AssistantTextPart[]
103
112
  model: string
104
113
  startedAt: number
105
114
  span: Span
@@ -124,6 +133,7 @@ async function settleCancelledTurn(args: {
124
133
  stopReason: 'cancelled',
125
134
  usage: args.usage,
126
135
  content: args.text || undefined,
136
+ ...(args.textParts ? { textParts: args.textParts } : {}),
127
137
  })
128
138
  } catch {
129
139
  // Best effort. The cancellation is the news.
@@ -156,6 +166,7 @@ export async function* streamProviderTurn(
156
166
  imageRecovery?: {
157
167
  readonly onAccepted: (identity: RequestImageIdentity) => Promise<void>
158
168
  },
169
+ captureRequest = false,
159
170
  ): AsyncGenerator<RunEvent, StreamingTurnResult> {
160
171
  assertNativeStructuredOutputSupported(provider, params)
161
172
  assertHostedWebSearchSupported(provider, params)
@@ -181,7 +192,7 @@ export async function* streamProviderTurn(
181
192
 
182
193
  let id = ''
183
194
  const model = ''
184
- let textBuf = ''
195
+ const text = new StreamTextAccumulator()
185
196
  let finishReason: ChatCompletionResponse['finishReason'] = 'stop'
186
197
  let usage: ChatCompletionResponse['usage'] = {
187
198
  promptTokens: 0,
@@ -239,9 +250,21 @@ export async function* streamProviderTurn(
239
250
  ...params,
240
251
  stream: true,
241
252
  } satisfies import('../../../types/provider/index.js').ChatCompletionParams
253
+ let requestMessages: readonly Message[] | undefined
254
+ const observeRequest = captureRequest
255
+ ? (messages: readonly Message[]) => {
256
+ requestMessages = structuredClone(messages)
257
+ }
258
+ : undefined
259
+ if (!imageRecovery) observeRequest?.(streamParams.messages)
242
260
  const stream = (
243
261
  imageRecovery
244
- ? streamWithProviderRejectedImageRecovery(provider, streamParams, imageRecovery.onAccepted)
262
+ ? streamWithProviderRejectedImageRecovery(
263
+ provider,
264
+ streamParams,
265
+ imageRecovery.onAccepted,
266
+ observeRequest,
267
+ )
245
268
  : provider.chatStream(streamParams)
246
269
  ) as AsyncIterable<StreamChunk>
247
270
 
@@ -328,6 +351,7 @@ export async function* streamProviderTurn(
328
351
  }
329
352
  if (!id && chunk.id) id = chunk.id
330
353
  if (chunk.replayState !== undefined) replayState = chunk.replayState
354
+ text.push(chunk)
331
355
 
332
356
  // The first delta of the turn, of ANY kind — text, reasoning or a
333
357
  // tool call. namzu streams, so perceived latency is dominated by
@@ -401,13 +425,13 @@ export async function* streamProviderTurn(
401
425
  }
402
426
 
403
427
  if (chunk.delta.content) {
404
- textBuf += chunk.delta.content
405
428
  await emitEvent({
406
429
  type: 'text_delta',
407
430
  runId,
408
431
  iteration,
409
432
  messageId,
410
433
  text: chunk.delta.content,
434
+ ...(chunk.delta.textPart ? { textPart: chunk.delta.textPart } : {}),
411
435
  })
412
436
  yield* drainPending()
413
437
  }
@@ -518,7 +542,8 @@ export async function* streamProviderTurn(
518
542
  iteration,
519
543
  messageId,
520
544
  usage,
521
- text: textBuf,
545
+ text: text.text,
546
+ textParts: text.textParts,
522
547
  model: params.model,
523
548
  startedAt: callStartedAt,
524
549
  span: chatSpan,
@@ -661,7 +686,8 @@ export async function* streamProviderTurn(
661
686
  messageId,
662
687
  stopReason,
663
688
  usage,
664
- content: textBuf || undefined,
689
+ content: text.text || undefined,
690
+ ...(text.textParts ? { textParts: text.textParts } : {}),
665
691
  })
666
692
  yield* drainPending()
667
693
 
@@ -714,7 +740,8 @@ export async function* streamProviderTurn(
714
740
  model: model || params.model,
715
741
  message: {
716
742
  role: 'assistant',
717
- content: textBuf.length > 0 ? textBuf : null,
743
+ content: text.text || null,
744
+ ...(text.textParts ? { textParts: text.textParts } : {}),
718
745
  toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
719
746
  ...(reasoningBlocks.length > 0 ? { reasoning: reasoningBlocks } : {}),
720
747
  ...(replayState !== undefined ? { replayState } : {}),
@@ -746,5 +773,5 @@ export async function* streamProviderTurn(
746
773
  chatSpan.setStatus({ code: SpanStatusCode.OK })
747
774
  chatSpan.end()
748
775
 
749
- return { response, messageId }
776
+ return { response, messageId, ...(requestMessages ? { requestMessages } : {}) }
750
777
  }
@@ -59,3 +59,23 @@ export function applyLifecycleHookResults(
59
59
  }
60
60
  return annotations
61
61
  }
62
+
63
+ /**
64
+ * What a `pre_tool_use` hook's SKIP goes back to the model as.
65
+ *
66
+ * A function rather than a template at the one call site, because the text is
67
+ * a SIGNAL as well as prose. A skipped call gets a non-error receipt — the
68
+ * hook refused it, nothing failed — so the transcript's only record that the
69
+ * tool never ran is this sentence. `file-evidence-replay.ts` reads it back to
70
+ * keep a skipped `write` from being replayed as a body the file now holds,
71
+ * and it can only do that while one function owns both the writing and the
72
+ * recognising.
73
+ */
74
+ export function skippedToolResultText(toolName: string, reason: string): string {
75
+ return `Tool ${toolName} skipped by plugin: ${reason}`
76
+ }
77
+
78
+ /** Whether `content` is the receipt {@link skippedToolResultText} writes for `toolName`. */
79
+ export function isSkippedToolResult(toolName: string, content: string): boolean {
80
+ return content.startsWith(skippedToolResultText(toolName, ''))
81
+ }
@@ -1,3 +1,4 @@
1
+ import { createRuntimeContextMessage } from '../../types/message/index.js'
1
2
  import type { Message } from '../../types/message/index.js'
2
3
  import { stableStringify } from './tool-grants.js'
3
4
 
@@ -128,11 +129,24 @@ export class RepeatCallTracker {
128
129
  }
129
130
 
130
131
  /**
131
- * Rides the notice out on the last `tool_result` of the batch.
132
+ * Rides the notice out on the last `tool_result` of the batch, same slot
133
+ * steering uses: a `tool_use` block must be answered by a `tool_result` with
134
+ * the same id, so a user message wedged between them is rejected by the
135
+ * provider outright.
132
136
  *
133
- * The same and only legal slot steering uses: a `tool_use` block must be
134
- * answered by a `tool_result` with the same id, so a user message wedged
135
- * between them is rejected by the provider outright.
137
+ * That slot only exists when the trailing result's content is plain text. A
138
+ * result answered with structured content (an image, a document, an MCP
139
+ * block) has a shape the model reads positionally, and appending a string to
140
+ * it is either dropped or corrupts the block — this used to mean the notice
141
+ * was simply dropped, on the theory that an advisory costs nothing to lose.
142
+ * It costs more than a refusal would: `RepeatCallTracker.record` already
143
+ * marked the threshold as announced the moment it fired, so a notice lost
144
+ * here never comes back, unlike steering, which can requeue and wait for a
145
+ * later plain-text result. The fallback instead rides out as its own
146
+ * `runtime-context` message placed AFTER the complete tool-result batch —
147
+ * never between a `tool_use` and its `tool_result`, so provider-required
148
+ * adjacency still holds — carrying that provenance so it is never mistaken
149
+ * for operator input (see `isOperatorUserMessage` in `steering.ts`).
136
150
  */
137
151
  export function attachRepeatNotice(
138
152
  messages: readonly Message[],
@@ -140,6 +154,8 @@ export function attachRepeatNotice(
140
154
  ): readonly Message[] {
141
155
  if (notices.length === 0) return messages
142
156
 
157
+ const noticeText = notices.map((n) => n.text).join('\n')
158
+
143
159
  let lastToolIndex = -1
144
160
  for (let index = messages.length - 1; index >= 0; index--) {
145
161
  if (messages[index]?.role === 'tool') {
@@ -147,19 +163,13 @@ export function attachRepeatNotice(
147
163
  break
148
164
  }
149
165
  }
150
- if (lastToolIndex === -1) return messages
151
-
152
- const target = messages[lastToolIndex] as Message
153
- // Text only, for the reason `attachSteering` gives: a result answered
154
- // with structured content has a shape the model reads positionally, and
155
- // appending a string to it is either dropped or corrupts the block. The
156
- // notice is advisory, so dropping it costs nothing a refusal would.
157
- if (typeof target.content !== 'string') return messages
158
-
159
- const next = [...messages]
160
- next[lastToolIndex] = {
161
- ...target,
162
- content: `${target.content}\n\n${notices.map((n) => n.text).join('\n')}`,
166
+ const target = lastToolIndex === -1 ? undefined : (messages[lastToolIndex] as Message)
167
+
168
+ if (target && typeof target.content === 'string') {
169
+ const next = [...messages]
170
+ next[lastToolIndex] = { ...target, content: `${target.content}\n\n${noticeText}` }
171
+ return next
163
172
  }
164
- return next
173
+
174
+ return [...messages, createRuntimeContextMessage(noticeText, 'repeat-call')]
165
175
  }
@@ -1,6 +1,7 @@
1
1
  import { isDeepStrictEqual } from 'node:util'
2
2
 
3
3
  import type { RunPersistence } from '../../manager/run/persistence.js'
4
+ import { ToolExecutionCollector } from '../../store/run/tool-executions.js'
4
5
  import type {
5
6
  CheckpointId,
6
7
  HITLResumeDecision,
@@ -9,6 +10,7 @@ import type {
9
10
  } from '../../types/hitl/index.js'
10
11
  import type { AssistantMessage, Message, ToolCall } from '../../types/message/index.js'
11
12
  import type { ChatCompletionResponse } from '../../types/provider/index.js'
13
+ import type { ToolExecutionSnapshot } from '../../types/run/store.js'
12
14
  import type { Logger } from '../../utils/logger.js'
13
15
  import type { PriorToolResults, ToolCallDenials, ToolExecutor } from './executor.js'
14
16
  import { PendingAnswers } from './question-park.js'
@@ -192,24 +194,11 @@ function planQuestionResume(
192
194
  }
193
195
 
194
196
  /**
195
- * Decide whether a checkpoint left behind a batch that was PART-WAY
196
- * through executing when the process died.
197
- *
198
- * The ordinary repair for an unanswered assistant turn — strip it and let
199
- * the model re-decide — is right when nothing ran: the calls were still
200
- * awaiting a decision, so re-deciding costs only a round trip. It is
201
- * exactly wrong when some of them already ran, because re-deciding means
202
- * re-executing, and a tool that charged a card does not become idempotent
203
- * on the second attempt.
204
- *
205
- * The discriminator is the transcript: a tool-review park records the
206
- * checkpoint BEFORE any execution, so it has no completed calls and takes
207
- * the cheap path unchanged. One or more completions means execution had
208
- * begun, which is a resume, not a fresh decision.
209
- *
210
- * The calls that did NOT complete are executed here for the first time,
211
- * through the ordinary executor — so every guard, permission check and
212
- * probe still applies to them.
197
+ * Preserve a restored batch's recorded and explicitly unknown outcomes.
198
+ * `completed` comes from recoverCompletedCalls: missing entries are eligible
199
+ * only after a complete scan establishes that they have no recorded start.
200
+ * A started tool with no trustworthy completion is carried as an unknown
201
+ * outcome, not executed again. An untouched batch uses ordinary history repair.
213
202
  */
214
203
  export function planCrashResume(
215
204
  checkpoint: IterationCheckpoint,
@@ -219,13 +208,19 @@ export function planCrashResume(
219
208
  const assistant = lastUnansweredBatch(checkpoint.messages)?.assistant
220
209
  const calls = assistant?.toolCalls
221
210
  if (!assistant || !calls || calls.length === 0) return null
211
+ // Only the current tail can be resumed in place. An older incomplete
212
+ // batch belongs to history repair; re-appending it would move its action
213
+ // past a newer operator message and silently reorder the conversation.
214
+ const ownerIndex = checkpoint.messages.lastIndexOf(assistant)
215
+ if (checkpoint.messages.slice(ownerIndex + 1).some((message) => message.role !== 'tool'))
216
+ return null
222
217
 
223
218
  const done = calls.filter((tc) => completed.has(tc.id))
224
219
  if (done.length === 0) return null
225
220
 
226
221
  log.warn('Checkpoint holds a tool batch that was part-way through executing', {
227
222
  'namzu.checkpoint.id': checkpoint.id,
228
- 'namzu.runtime.completed': done.length,
223
+ 'namzu.runtime.recovered': done.length,
229
224
  'namzu.runtime.total': calls.length,
230
225
  'namzu.runtime.remaining': calls
231
226
  .filter((tc) => !completed.has(tc.id))
@@ -336,37 +331,67 @@ function modifiedCallIds(decision: HITLResumeDecision): ReadonlySet<string> {
336
331
  }
337
332
 
338
333
  /**
339
- * Results the run already produced for calls in `toolCalls`.
340
- *
341
- * Read from the transcript, which records a `tool_completed` per tool as
342
- * it finishes — durable long before the batch settles. Scoped to the calls
343
- * being resumed so an id from an earlier turn can never answer this one.
344
- *
345
- * A failure to read is not fatal: the worst case is the behaviour that
346
- * existed before this recovery, and refusing to resume because a log could
347
- * not be read would be a strictly worse trade.
334
+ * Recover completed results and close interrupted calls with unknown outcomes.
335
+ * Only a complete execution scan can authorize the absence of a start record.
336
+ * Unreadable, partial or contradictory evidence never becomes permission to
337
+ * replay; an explicitly answered durable question may re-enter its own tool.
348
338
  */
349
339
  export async function recoverCompletedCalls(
350
340
  runMgr: RunPersistence,
351
341
  toolCalls: readonly ToolCall[],
352
342
  log: Logger,
343
+ options: { answers?: PendingAnswers; signal?: AbortSignal } = {},
353
344
  ): Promise<Map<string, { result: string; isError: boolean }>> {
354
345
  const recovered = new Map<string, { result: string; isError: boolean }>()
346
+ let snapshot: ToolExecutionSnapshot | undefined
355
347
  try {
356
- const completed = await runMgr.getRunStore().readCompletedTools()
357
- for (const call of toolCalls) {
358
- const record = completed.get(call.id)
359
- if (record) recovered.set(call.id, { result: record.result, isError: record.isError })
348
+ const store = runMgr.getRunStore()
349
+ if (store.readToolExecutions) {
350
+ snapshot = await store.readToolExecutions(
351
+ toolCalls.map((call) => call.id),
352
+ options.signal,
353
+ )
354
+ } else {
355
+ const collector = new ToolExecutionCollector(
356
+ runMgr.id,
357
+ toolCalls.map((call) => call.id),
358
+ )
359
+ for (const event of await store.readEvents({ integrity: 'strict' })) {
360
+ options.signal?.throwIfAborted()
361
+ collector.accept(event)
362
+ }
363
+ snapshot = collector.finish()
360
364
  }
361
365
  } catch (error) {
366
+ if (options.signal?.aborted) throw error
362
367
  log.warn('Could not read the transcript to recover completed tool calls', {
363
368
  'exception.message': error instanceof Error ? error.message : String(error),
364
369
  })
365
- return new Map()
370
+ }
371
+ for (const call of toolCalls) {
372
+ const record = snapshot?.records.get(call.id)
373
+ if (
374
+ snapshot?.complete &&
375
+ (!record || (record.toolName === call.function.name && record.toolUseId === call.id))
376
+ ) {
377
+ if (!record) continue // Complete evidence proves this call has no recorded start.
378
+ if (record.status === 'completed') {
379
+ recovered.set(call.id, { result: record.result, isError: record.isError })
380
+ continue
381
+ }
382
+ }
383
+ // The validated checkpoint and explicit answer own this re-entry even
384
+ // when the prior event store is unavailable. No sibling inherits it.
385
+ if ([...(options.answers?.entries() ?? [])].some(([id]) => isPauseForCall(id, call.id)))
386
+ continue
387
+ recovered.set(call.id, {
388
+ result: `Tool execution was interrupted and no trustworthy completion is available for \`${call.function.name}\`. Its outcome is unknown. This resume did not execute it again. Verify external state before deciding whether another call is needed; do not replay a state-changing action to recover its output.`,
389
+ isError: true,
390
+ })
366
391
  }
367
392
 
368
393
  if (recovered.size > 0) {
369
- log.info('Recovered tool results from the transcript instead of re-executing', {
394
+ log.info('Restored recorded or unknown tool outcomes without re-executing', {
370
395
  'namzu.runtime.recovered': recovered.size,
371
396
  'namzu.runtime.of_calls': toolCalls.length,
372
397
  })
@@ -452,13 +477,13 @@ function synthesizeResponse(assistant: AssistantMessage): ChatCompletionResponse
452
477
  }
453
478
 
454
479
  /**
455
- * Tool calls in the history that no `tool_result` answers.
456
- *
457
- * The set worth asking the transcript about: an already-answered call's
458
- * result is in the history and needs no recovery.
480
+ * All calls owned by the last incomplete batch. Applying a resume plan
481
+ * reconstructs that entire batch, including any partial results already in
482
+ * the checkpoint. Those answered siblings must also be recovered, or their
483
+ * missing prior-result entries would let the executor repeat them.
459
484
  */
460
- export function unansweredToolCalls(messages: readonly Message[]): ToolCall[] {
461
- return lastUnansweredBatch(messages)?.unanswered ?? []
485
+ export function interruptedToolCalls(messages: readonly Message[]): ToolCall[] {
486
+ return lastUnansweredBatch(messages)?.assistant.toolCalls ?? []
462
487
  }
463
488
 
464
489
  function lastUnansweredBatch(
@@ -1,9 +1,9 @@
1
1
  /**
2
- * How a run resolves the calls no rule decided.
2
+ * How a run resolves calls routed to review.
3
3
  *
4
4
  * An authorization rule says what a tool may do. A review policy says what
5
- * happens to everything the rules did not cover: the batch the gate routed
6
- * to REVIEW. The two axes are separate on purpose — a rule is a durable
5
+ * happens to calls the rules did not cover or explicitly routed to REVIEW.
6
+ * The two axes are separate on purpose — a rule is a durable
7
7
  * statement an operator reviewed, and a mode is a property of ONE run, the
8
8
  * difference between "we never force-push" and "this run is unattended".
9
9
  *
@@ -132,12 +132,14 @@ export function isReviewExempt(
132
132
 
133
133
  export type ReviewExemption = (name: string, input: unknown) => boolean
134
134
 
135
- /** A batch needs review when any call mutates state: flagged destructive, or not exempt. */
135
+ /** Review explicit requests and calls that are destructive or not exempt. */
136
136
  export function batchNeedsReview(
137
137
  toolCalls: readonly ToolCallSummary[],
138
138
  exempt: ReviewExemption,
139
139
  ): boolean {
140
- return toolCalls.some((tc) => tc.isDestructive || !exempt(tc.name, tc.input))
140
+ return toolCalls.some(
141
+ (tc) => tc.authorization?.explicitReview || tc.isDestructive || !exempt(tc.name, tc.input),
142
+ )
141
143
  }
142
144
 
143
145
  /** The batch a person is asked about. */
@@ -194,14 +196,16 @@ export function createReviewHandler(options: ReviewPolicyOptions = {}): ResumeHa
194
196
  if (
195
197
  mode === 'accept-edits' &&
196
198
  request.toolCalls.every(
197
- (tc) => !tc.isDestructive && (ACCEPT_EDITS_TOOLS.has(tc.name) || exempt(tc.name, tc.input)),
199
+ (tc) =>
200
+ !tc.authorization?.explicitReview &&
201
+ !tc.isDestructive &&
202
+ (ACCEPT_EDITS_TOOLS.has(tc.name) || exempt(tc.name, tc.input)),
198
203
  )
199
204
  ) {
200
205
  return { action: 'approve_tools' }
201
206
  }
202
- // Reads were approved above. Anything that reached here would change
203
- // something, and plan mode's answer is the same every time: not now,
204
- // tell the user what you would do.
207
+ // Ordinary reads were approved above. Remaining calls either change
208
+ // state or carry explicit review; plan mode does not grant that authority.
205
209
  if (mode === 'plan') return { action: 'reject_tools', feedback: PLAN_MODE_REFUSAL }
206
210
  if (mode === 'strict') return { action: 'reject_tools', feedback: STRICT_MODE_REFUSAL }
207
211
  if (mode === 'auto' || !prompt || remembered.all) {
@@ -138,6 +138,9 @@ export async function acquireSandbox(options: {
138
138
  runSignal.addEventListener('abort', onAbort, { once: true })
139
139
  })
140
140
  const timedOut = new Promise<{ readonly kind: 'timed_out'; readonly error: Error }>((resolve) => {
141
+ // An unlimited run still observes cancellation; Infinity must never reach
142
+ // setTimeout, where Node would coerce it to a one-millisecond deadline.
143
+ if (options.timeoutMs === Number.POSITIVE_INFINITY) return
141
144
  timer = setTimeout(() => {
142
145
  timeoutError = acquisitionTimeoutError(options.timeoutMs)
143
146
  operationController.abort(timeoutError)
@@ -100,6 +100,16 @@ export function attachNotice(
100
100
  messages: readonly Message[],
101
101
  channel: SteeringChannel | undefined,
102
102
  format: (text: string) => string,
103
+ /**
104
+ * Told only when the text actually landed on a result the model will read.
105
+ *
106
+ * Not on the two paths above it: a batch with no tool result leaves the
107
+ * notice queued, and a result whose content is not a string puts it back.
108
+ * Draining is therefore not delivery, which matters to the caller that
109
+ * keeps its own record of what the text accounts for — `AwaitedJobs`
110
+ * drops an exit's entry here, and a premature drop would strand the exit.
111
+ */
112
+ onDelivered?: () => void,
103
113
  ): readonly Message[] {
104
114
  if (!channel?.pending) return messages
105
115
  let lastToolIndex = -1
@@ -119,6 +129,7 @@ export function attachNotice(
119
129
  }
120
130
  const next = [...messages]
121
131
  next[lastToolIndex] = { ...target, content: target.content + format(text) }
132
+ onDelivered?.()
122
133
  return next
123
134
  }
124
135