@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,6 +1,7 @@
1
1
  import { createHash } from 'node:crypto'
2
2
  import { mkdirSync, writeFileSync } from 'node:fs'
3
3
  import { join } from 'node:path'
4
+ import { digest, spillManifest } from '../../store/evidence/format.js'
4
5
 
5
6
  /**
6
7
  * Model-visible size cap for a single tool result.
@@ -104,6 +105,8 @@ export interface ToolOutputBudgetResult {
104
105
  readonly truncated: boolean
105
106
  /** Where the full output was written, when it was. */
106
107
  readonly spillPath?: string
108
+ /** Digest of the bounded chunk manifest, recorded at retention time. */
109
+ readonly spillIntegrity?: string
107
110
  }
108
111
 
109
112
  /**
@@ -155,6 +158,10 @@ export interface ApplyToolOutputBudgetOptions {
155
158
  readonly toolUseId: string
156
159
  readonly output: string
157
160
  readonly maxChars: number
161
+ /** Optional condensed presentation; used only after authenticated retention of output. */
162
+ readonly preview?: string
163
+ /** Smaller preview only after the full output and its integrity manifest are saved. */
164
+ readonly retainedPreviewChars?: number
158
165
  /** An omission notice that shares the text budget, never extends it. */
159
166
  readonly notice?: string
160
167
  /**
@@ -168,12 +175,10 @@ export interface ApplyToolOutputBudgetOptions {
168
175
  /**
169
176
  * Bound a tool result to the model-visible budget.
170
177
  *
171
- * Spilling beats truncating on every axis that matters: nothing is lost,
172
- * tokens are paid only if the agent decides the rest is worth re-reading,
173
- * and retrieval uses `read`/`grep` — tools it already has — rather than a
174
- * new affordance. A hosted agent runtime does the same thing above 100k
175
- * characters. Middle-elision is the fallback for a run with no directory
176
- * to write to.
178
+ * Retention keeps the original while bounding its model-visible preview.
179
+ * The host owns the recovery route and its permissions; a spill path is not
180
+ * proof that workspace read/grep tools can access it. Middle-elision is the
181
+ * fallback for a run with no directory to write to.
177
182
  *
178
183
  * The preview keeps head AND tail because the two ends carry different
179
184
  * information: the head has the schema/opening of a document, the tail has
@@ -194,26 +199,65 @@ export function applyToolOutputBudget(opts: ApplyToolOutputBudgetOptions): ToolO
194
199
  : Math.max(0, limit - notice.length - (notice && output ? 2 : 0))
195
200
  const withNotice = (text: string) => [text, notice].filter(Boolean).join('\n\n')
196
201
 
197
- if (textBudget === undefined || originalLength <= textBudget) {
202
+ const preview =
203
+ opts.preview !== undefined && opts.preview.length < originalLength ? opts.preview : undefined
204
+ if (preview === undefined && (textBudget === undefined || originalLength <= textBudget)) {
198
205
  return { output: withNotice(output), originalLength, truncated: false }
199
206
  }
200
207
 
201
- const spillPath = opts.spillDir
208
+ const retained = opts.spillDir
202
209
  ? spill(opts.spillDir, opts.toolUseId, output, opts.onError)
203
210
  : undefined
204
211
 
212
+ const spillPath = retained?.path
205
213
  const recovery = spillPath
206
214
  ? [
207
215
  `${SPILL_MARKER} ${spillPath}`,
208
- 'Read a specific window with `read` (offset/limit) or search it with `grep`. Do NOT read it whole — that is what exceeded the budget.',
216
+ 'This path identifies retained output, not the original input. Use the host-authorized retained-output recovery tools when available; the path does not grant filesystem access. A fresh observation of the original input cannot recover its earlier contents. If recovery is unavailable, report the missing detail; do not replay the original action.',
209
217
  ].join('\n')
210
218
  : 'The full output was not retained. Use a saved artifact or a read-only observation; do not repeat a state-changing action to recover its output.'
219
+ const requestedPreview = opts.retainedPreviewChars
220
+ // Separate the spill threshold from the cost of carrying its preview on every
221
+ // later request. Failed retention must not silently discard additional text.
222
+ // A small configured preview still needs room for the durable recovery path.
223
+ const previewLimit =
224
+ retained?.integrity &&
225
+ requestedPreview !== undefined &&
226
+ Number.isFinite(requestedPreview) &&
227
+ requestedPreview > 0
228
+ ? Math.min(limit as number, Math.floor(requestedPreview))
229
+ : (limit as number)
230
+ const previewTextBudget = Math.max(0, previewLimit - notice.length - (notice && output ? 2 : 0))
231
+ const minimumRecoveryChars = `\n[... omitted ...]\n${SPILL_MARKER} ${spillPath}\n`.length
232
+ const effectiveTextBudget =
233
+ previewTextBudget > minimumRecoveryChars ? previewTextBudget : textBudget
234
+ // Condensation is a display choice, not permission to discard evidence. The
235
+ // original can be under the ordinary cap while still losing distinct rows.
236
+ // Failed retention falls back to the original, bounded by the usual cap.
237
+ if (preview !== undefined && retained?.integrity) {
238
+ const condensed = [preview, recovery].filter(Boolean).join('\n\n')
239
+ if (effectiveTextBudget === undefined || condensed.length <= effectiveTextBudget) {
240
+ return {
241
+ output: withNotice(condensed),
242
+ originalLength,
243
+ truncated: true,
244
+ spillPath,
245
+ spillIntegrity: retained.integrity,
246
+ }
247
+ }
248
+ }
249
+ if (textBudget === undefined || originalLength <= textBudget) {
250
+ return { output: withNotice(output), originalLength, truncated: false }
251
+ }
211
252
 
212
253
  return {
213
- output: withNotice(boundedPreview(output, textBudget, opts.toolName, recovery)),
254
+ output: withNotice(
255
+ boundedPreview(output, effectiveTextBudget ?? textBudget, opts.toolName, recovery),
256
+ ),
214
257
  originalLength,
215
258
  truncated: true,
216
259
  ...(spillPath ? { spillPath } : {}),
260
+ ...(retained?.integrity ? { spillIntegrity: retained.integrity } : {}),
217
261
  }
218
262
  }
219
263
 
@@ -222,7 +266,7 @@ function spill(
222
266
  toolUseId: string,
223
267
  content: string,
224
268
  onError?: (message: string) => void,
225
- ): string | undefined {
269
+ ): { path: string; integrity?: string } | undefined {
226
270
  try {
227
271
  // `0o700` on the directory and `0o600` on the file: a spilled output is
228
272
  // routinely the largest and most sensitive thing a run produces — whole
@@ -250,8 +294,16 @@ function spill(
250
294
  // so randomising the filename would add nothing this does not already
251
295
  // have. Do not "improve" it back to a random name and a plain `w` —
252
296
  // that trades a guarantee for a guess.
253
- writeFileSync(path, content, { encoding: 'utf-8', flag: 'wx', mode: 0o600 })
254
- return path
297
+ const bytes = Buffer.from(content, 'utf8')
298
+ writeFileSync(path, bytes, { flag: 'wx', mode: 0o600 })
299
+ try {
300
+ const manifest = spillManifest(bytes)
301
+ writeFileSync(`${path}.manifest.json`, manifest, { flag: 'wx', mode: 0o600 })
302
+ return { path, integrity: digest(manifest) }
303
+ } catch {
304
+ onError?.('The full output was retained, but its integrity manifest could not be written.')
305
+ return { path }
306
+ }
255
307
  } catch (err) {
256
308
  // A spill failure must never fail the tool call — the model still
257
309
  // gets the preview, just without a path to recover the rest.
@@ -38,6 +38,8 @@ export interface ToolingBootstrapConfig {
38
38
  backgroundJobs?: BackgroundJobRegistry
39
39
  /** See `QueryParams.backgroundJobOwner`. */
40
40
  backgroundJobOwner?: string
41
+ /** Where `wait_for_job` records wait-intent; see the executor's own field. */
42
+ onJobAwaited?: (id: string) => void
41
43
  /** Where the `skill` tool reads from. */
42
44
  skills?: SkillRegistryRef
43
45
  /** How this run reaches the web. */
@@ -47,8 +49,10 @@ export interface ToolingBootstrapConfig {
47
49
  maxToolCalls?: number
48
50
  readToolCallBudgetEvents?: () => Promise<readonly RunEvent[]>
49
51
  maxToolOutputChars?: number
52
+ retainedToolPreviewChars?: number
50
53
  maxToolContentBytes?: number
51
- toolOutputDir?: string
54
+ captureRunEvidence?: import('../../types/tool/index.js').ToolContext['captureRunEvidence']
55
+ toolOutputDir?: string | (() => string | undefined)
52
56
  repairToolCall?: RepairToolCall
53
57
  /** Operator authorization shared with the direct-call review path. */
54
58
  authorizationGate?: AuthorizationGate
@@ -79,9 +83,11 @@ export class ToolingBootstrap {
79
83
  abortSignal: config.abortSignal,
80
84
  allowedTools: config.allowedTools,
81
85
  invocationState: config.invocationState,
86
+ captureRunEvidence: config.captureRunEvidence,
82
87
  pluginManager: config.pluginManager,
83
88
  ...(config.backgroundJobs ? { backgroundJobs: config.backgroundJobs } : {}),
84
89
  ...(config.backgroundJobOwner ? { backgroundJobOwner: config.backgroundJobOwner } : {}),
90
+ ...(config.onJobAwaited ? { onJobAwaited: config.onJobAwaited } : {}),
85
91
  ...(config.skills ? { skills: config.skills } : {}),
86
92
  ...(config.web ? { web: config.web } : {}),
87
93
  ...(config.toolTimeoutMs !== undefined ? { toolTimeoutMs: config.toolTimeoutMs } : {}),
@@ -98,6 +104,9 @@ export class ToolingBootstrap {
98
104
  ...(config.maxToolOutputChars !== undefined
99
105
  ? { maxToolOutputChars: config.maxToolOutputChars }
100
106
  : {}),
107
+ ...(config.retainedToolPreviewChars !== undefined
108
+ ? { retainedToolPreviewChars: config.retainedToolPreviewChars }
109
+ : {}),
101
110
  ...(config.maxToolContentBytes !== undefined
102
111
  ? { maxToolContentBytes: config.maxToolContentBytes }
103
112
  : {}),
@@ -26,6 +26,23 @@ import { type Logger, resolveLogger } from '../utils/logger.js'
26
26
  */
27
27
  const UNOWNED_BUFFER_LIMIT = 32
28
28
 
29
+ /**
30
+ * How many owned tasks {@link CompletionInbox.describeOwnedWork} can name at
31
+ * once.
32
+ *
33
+ * Unrelated to {@link UNOWNED_BUFFER_LIMIT} — that one bounds a memory leak;
34
+ * this one bounds a request payload. `describeOwnedWork`'s output is admitted
35
+ * into the request through `appendWorkContext`'s 8,000-character / ~2,000-token
36
+ * gate (`runtime/query/iteration/index.ts`), and 16 tasks' worth of scheduler
37
+ * state fits that with room to spare, including the overflow note below.
38
+ *
39
+ * Running tasks fill these slots first — see {@link CompletionInbox.runningOwned}
40
+ * — so a task still going is never bumped out by launch count alone the way a
41
+ * single FIFO over every owned task used to bump it. Only once every running
42
+ * task has a slot do the most recently SETTLED tasks take what is left.
43
+ */
44
+ const OWNED_WORK_DISPLAY_LIMIT = 16
45
+
29
46
  /**
30
47
  * Completions that finished with nobody left to hear them.
31
48
  *
@@ -77,6 +94,30 @@ export class CompletionInbox {
77
94
  * takes one, and a host that owns a gateway naturally reuses it.
78
95
  */
79
96
  private readonly ours = new Set<TaskId>()
97
+ /**
98
+ * Owned tasks not yet observed to have settled, in launch order.
99
+ *
100
+ * A `Set`'s iteration order is insertion order, so the most recently
101
+ * launched entry is always last — {@link describeOwnedWork} reads that
102
+ * order back to front. An id leaves this set the moment its completion is
103
+ * observed, by whichever of the three paths sees it first: the gateway's
104
+ * broadcast, an announcement recovered from {@link unowned}, or a launch
105
+ * that finds the task already terminal. It is never evicted for any other
106
+ * reason, so a long-running task stays in here — and therefore visible —
107
+ * for exactly as long as it is actually running, regardless of how many
108
+ * other tasks this run launches meanwhile.
109
+ */
110
+ private readonly runningOwned = new Set<TaskId>()
111
+ /**
112
+ * Owned tasks observed to have settled, oldest first, bounded to
113
+ * {@link OWNED_WORK_DISPLAY_LIMIT}.
114
+ *
115
+ * This bound is display-driven, not a memory concern the way
116
+ * {@link UNOWNED_BUFFER_LIMIT} is: a settled task's own result already
117
+ * reached the model once (inline or as a notification), so dropping it
118
+ * from here loses a convenience, not the only record of it.
119
+ */
120
+ private readonly settledOwned: TaskId[] = []
80
121
  /**
81
122
  * Announcements that arrived before anyone said whose task it was.
82
123
  *
@@ -129,6 +170,7 @@ export class CompletionInbox {
129
170
  // finished its wait faster than the listener ran — is already
130
171
  // delivered. Nothing to queue.
131
172
  this.outstanding.delete(handle.taskId)
173
+ this.markSettled(handle.taskId)
132
174
  if (this.claimed.has(handle.taskId)) return
133
175
  this.unheard.set(handle.taskId, handle)
134
176
  for (const wake of this.arrivals) wake()
@@ -193,22 +235,48 @@ export class CompletionInbox {
193
235
  if (this.ours.has(taskId)) return
194
236
  this.ours.add(taskId)
195
237
 
196
- if (this.claimed.has(taskId) || this.unheard.has(taskId)) return
238
+ if (this.claimed.has(taskId) || this.unheard.has(taskId)) {
239
+ this.markSettled(taskId)
240
+ return
241
+ }
197
242
 
198
243
  const parked = this.unowned.get(taskId)
199
244
  if (parked) {
200
245
  this.unowned.delete(taskId)
201
246
  this.unheard.set(taskId, parked)
247
+ this.markSettled(taskId)
202
248
  for (const wake of [...this.arrivals]) wake()
203
249
  return
204
250
  }
205
251
 
206
252
  const settled = this.gateway?.getTask(taskId)
207
- if (!settled || !isTerminalAgentTaskState(settled.state)) return
253
+ if (!settled || !isTerminalAgentTaskState(settled.state)) {
254
+ // Not observed terminal by any of the checks above: still running,
255
+ // as far as this inbox knows.
256
+ this.runningOwned.add(taskId)
257
+ return
258
+ }
208
259
  this.unheard.set(taskId, settled)
260
+ this.markSettled(taskId)
209
261
  for (const wake of [...this.arrivals]) wake()
210
262
  }
211
263
 
264
+ /**
265
+ * Move an owned task from {@link runningOwned} to {@link settledOwned}.
266
+ *
267
+ * Idempotent: `claim` and the completion listener can both observe the
268
+ * same settlement (the race either can win), and re-marking a task that
269
+ * is already in {@link settledOwned} moves it to the most-recently-settled
270
+ * end rather than duplicating it there.
271
+ */
272
+ private markSettled(taskId: TaskId): void {
273
+ this.runningOwned.delete(taskId)
274
+ const at = this.settledOwned.indexOf(taskId)
275
+ if (at !== -1) this.settledOwned.splice(at, 1)
276
+ this.settledOwned.push(taskId)
277
+ if (this.settledOwned.length > OWNED_WORK_DISPLAY_LIMIT) this.settledOwned.shift()
278
+ }
279
+
212
280
  /**
213
281
  * Say that a task was launched with nothing waiting on it.
214
282
  *
@@ -271,6 +339,13 @@ export class CompletionInbox {
271
339
  this.claimed.add(taskId)
272
340
  this.unheard.delete(taskId)
273
341
  this.outstanding.delete(taskId)
342
+ // A tool only claims a result it is already holding, so a claim is
343
+ // itself proof of settlement — independent of whether the gateway's
344
+ // own broadcast has reached this inbox yet. Without this, a task
345
+ // claimed ahead of its announcement (see the race above) stayed in
346
+ // {@link runningOwned} until that announcement arrived, understating
347
+ // its own "still running" count in the meantime.
348
+ this.markSettled(taskId)
274
349
  }
275
350
 
276
351
  /** Whether anything is waiting to be told. */
@@ -278,6 +353,51 @@ export class CompletionInbox {
278
353
  return this.unheard.size > 0
279
354
  }
280
355
 
356
+ /**
357
+ * Bounded, non-consuming scheduler observations. Delivery never
358
+ * establishes user-facing completion.
359
+ *
360
+ * Running tasks — most recently launched first, matching the order the
361
+ * rest of this projection has always used — fill the {@link
362
+ * OWNED_WORK_DISPLAY_LIMIT} slots first, so a task still going is named
363
+ * here for as long as it keeps running, no matter how many other tasks
364
+ * this run has since launched. The most recently SETTLED tasks fill
365
+ * whatever slots running tasks leave over. A settled task bumped out
366
+ * entirely is not reported missing — its own result already reached the
367
+ * model once — but a RUNNING task that does not fit is: the preamble
368
+ * says exactly how many, so the model never mistakes the cap for the
369
+ * task having ended.
370
+ */
371
+ describeOwnedWork(): string | undefined {
372
+ if (this.ours.size === 0) return
373
+ const running = [...this.runningOwned].reverse()
374
+ const shownRunning = running.slice(0, OWNED_WORK_DISPLAY_LIMIT)
375
+ const stillRunningNotShown = running.length - shownRunning.length
376
+ const settled = [...this.settledOwned].reverse()
377
+ const shownSettled = settled.slice(0, OWNED_WORK_DISPLAY_LIMIT - shownRunning.length)
378
+ const ids = [...shownRunning, ...shownSettled]
379
+ const tasks = ids.map((taskId) => {
380
+ let handle = this.unheard.get(taskId)
381
+ try {
382
+ handle = this.gateway?.getTask(taskId) ?? handle
383
+ } catch {
384
+ // A broken observation must not block execution or invent a task state.
385
+ }
386
+ return {
387
+ taskId,
388
+ state: handle?.state ?? 'unknown',
389
+ ...(handle?.result?.status ? { runStatus: handle.result.status } : {}),
390
+ ...(handle?.result?.stopReason ? { stopReason: handle.result.stopReason } : {}),
391
+ resultDelivery: this.claimed.has(taskId) ? 'delivered-to-history' : 'not-delivered',
392
+ }
393
+ })
394
+ const overflow =
395
+ stillRunningNotShown > 0
396
+ ? ` ${shownRunning.length} running tasks are shown below, and ${stillRunningNotShown} more still running.`
397
+ : ''
398
+ return `Owned delegated work (current scheduler observations).${overflow} Result delivery is not proof that you answered the original request. Answer the latest operator message and complete the requested synthesis of available results unless the operator cancelled or changed that request. Reuse delivered results when sufficient; do not relaunch completed work. If a delivered result is no longer visible, retrieve it by task ID. A terminal state with a non-end_turn stop reason is not successful task completion. Do not repeat a synthesis already given.\n${JSON.stringify({ tasks, omitted: this.ours.size - ids.length })}`
399
+ }
400
+
281
401
  /**
282
402
  * Tasks this run launched that are still running.
283
403
  *
@@ -366,6 +486,8 @@ export class CompletionInbox {
366
486
  this.unheard.clear()
367
487
  this.outstanding.clear()
368
488
  this.ours.clear()
489
+ this.runningOwned.clear()
490
+ this.settledOwned.length = 0
369
491
  this.claimed.clear()
370
492
  this.unowned.clear()
371
493
  // Release anyone still waiting. A closed inbox would otherwise hold
@@ -0,0 +1,139 @@
1
+ import { randomUUID } from 'node:crypto'
2
+ import { lstat, mkdir, writeFile } from 'node:fs/promises'
3
+ import { join } from 'node:path'
4
+ import { z } from 'zod'
5
+ import type { RunEvent } from '../../types/run/events.js'
6
+ import type { CompactedToolMetadata } from './compaction-provenance.js'
7
+ import { compactedTexts } from './compaction-text.js'
8
+ import { digest, spillManifest } from './format.js'
9
+ import { RECORD_BYTES, decode, noLinks, openEvidence, stamp } from './io.js'
10
+
11
+ const integer = z.number().int().nonnegative().safe()
12
+ const hash = z.string().regex(/^[a-f0-9]{64}$/)
13
+ const role = z.enum(['system', 'user', 'assistant', 'tool'])
14
+ export const compactionArchiveSchema = z.object({
15
+ type: z.literal('compaction_archive'),
16
+ runId: z.string().uuid(),
17
+ seq: integer.positive().optional(),
18
+ iteration: integer,
19
+ reason: z.enum(['threshold', 'overflow', 'manual']),
20
+ archive: z.object({
21
+ version: z.literal(1),
22
+ id: z.string().uuid(),
23
+ bytes: integer,
24
+ sha256: hash,
25
+ messageCount: integer,
26
+ parts: z
27
+ .array(
28
+ z.object({
29
+ role,
30
+ summary: z.literal(true).optional(),
31
+ manifest: hash,
32
+ toolName: z.string().min(1).max(1024).optional(),
33
+ isError: z.boolean().optional(),
34
+ }),
35
+ )
36
+ .max(8192),
37
+ }),
38
+ })
39
+
40
+ /** Internal storage encoding only; RunStore readers restore compaction_shed. */
41
+ export function compactionArchiveDirectory(runDir: string, id: string): string {
42
+ return join(runDir, 'compaction-output', z.string().uuid().parse(id))
43
+ }
44
+
45
+ export function compactionPartPath(runDir: string, id: string, part: number): string {
46
+ return join(compactionArchiveDirectory(runDir, id), `${integer.parse(part)}.txt`)
47
+ }
48
+
49
+ /** Keep JSONL index records bounded while preserving whole original messages. */
50
+ export async function retainCompactionRecord(
51
+ event: RunEvent,
52
+ runDir: string,
53
+ ): Promise<RunEvent | z.infer<typeof compactionArchiveSchema>> {
54
+ if (event.type !== 'compaction_shed') return event
55
+ const { messages: removed, type: _type, ...envelope } = event
56
+ const messageCount = removed.length
57
+ const original = Buffer.from(JSON.stringify(event.messages), 'utf8')
58
+ if (original.length <= 3 * 1024 * 1024) return event
59
+ const texts = compactedTexts(event.messages)
60
+ if (texts.length > 8192) throw new Error('Compaction archive exceeds 8192 textual parts.')
61
+ // The same 4096-chunk ceiling the reader enforces for retained tool text.
62
+ if (texts.some((part) => Buffer.byteLength(part.text, 'utf8') > 256 * 1024 * 1024))
63
+ throw new Error('Compaction archive text exceeds 256 MiB per part.')
64
+ const id = randomUUID()
65
+ const dir = compactionArchiveDirectory(runDir, id)
66
+ await noLinks(runDir)
67
+ await mkdir(join(runDir, 'compaction-output'), { recursive: true, mode: 0o700 })
68
+ await noLinks(join(runDir, 'compaction-output'))
69
+ await mkdir(dir, { mode: 0o700 })
70
+ await writeFile(join(dir, 'messages.json'), original, { flag: 'wx', mode: 0o600 })
71
+ const parts: ({
72
+ role: z.infer<typeof role>
73
+ manifest: string
74
+ summary?: true
75
+ } & CompactedToolMetadata)[] = []
76
+ for (const [part, value] of texts.entries()) {
77
+ const bytes = Buffer.from(value.text, 'utf8')
78
+ const manifest = spillManifest(bytes)
79
+ if (Buffer.byteLength(manifest, 'utf8') > RECORD_BYTES)
80
+ throw new Error('Compaction text manifest exceeds its 4 MiB read limit.')
81
+ const path = compactionPartPath(runDir, id, part)
82
+ await writeFile(path, bytes, { flag: 'wx', mode: 0o600 })
83
+ await writeFile(`${path}.manifest.json`, manifest, { flag: 'wx', mode: 0o600 })
84
+ parts.push({
85
+ role: value.role,
86
+ summary: value.summary,
87
+ manifest: digest(manifest),
88
+ toolName: value.toolName,
89
+ isError: value.isError,
90
+ })
91
+ }
92
+ return {
93
+ ...envelope,
94
+ ...compactionArchiveSchema.parse({
95
+ type: 'compaction_archive',
96
+ runId: event.runId,
97
+ seq: event.seq,
98
+ iteration: event.iteration,
99
+ reason: event.reason,
100
+ archive: {
101
+ version: 1,
102
+ id,
103
+ bytes: original.length,
104
+ sha256: digest(original),
105
+ messageCount,
106
+ parts,
107
+ },
108
+ }),
109
+ }
110
+ }
111
+
112
+ /** Full event readback is explicit and may load large bodies; search never calls this. */
113
+ export async function restoreCompactionRecord(
114
+ record: Record<string, unknown>,
115
+ runDir: string,
116
+ ): Promise<Record<string, unknown>> {
117
+ if (record.type !== 'compaction_archive') return record
118
+ const saved = compactionArchiveSchema.parse(record)
119
+ const path = join(compactionArchiveDirectory(runDir, saved.archive.id), 'messages.json')
120
+ const file = await openEvidence(path)
121
+ try {
122
+ const before = await file.stat()
123
+ if (before.size !== saved.archive.bytes) throw new Error('Compaction archive size changed.')
124
+ const bytes = await file.readFile()
125
+ if (
126
+ stamp(before) !== stamp(await file.stat()) ||
127
+ stamp(before) !== stamp(await lstat(path)) ||
128
+ digest(bytes) !== saved.archive.sha256
129
+ )
130
+ throw new Error('Compaction archive bytes changed.')
131
+ const messages: unknown = JSON.parse(decode(bytes))
132
+ if (!Array.isArray(messages) || messages.length !== saved.archive.messageCount)
133
+ throw new Error('Compaction archive message count changed.')
134
+ const { archive: _archive, ...rest } = record
135
+ return { ...rest, type: 'compaction_shed', messages }
136
+ } finally {
137
+ await file.close()
138
+ }
139
+ }
@@ -0,0 +1,52 @@
1
+ export interface CompactedToolMetadata {
2
+ toolName?: string
3
+ isError?: boolean
4
+ }
5
+
6
+ function record(value: unknown): Record<string, unknown> | undefined {
7
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
8
+ ? (value as Record<string, unknown>)
9
+ : undefined
10
+ }
11
+
12
+ /** A copy keeps its own source/time; this only identifies an unambiguous local tool pair. */
13
+ export function compactedToolMetadata(messages: readonly unknown[]): CompactedToolMetadata[] {
14
+ const calls = new Map<string, { index: number; name?: string; count: number }>()
15
+ const results = new Map<string, number>()
16
+ for (const [index, value] of messages.entries()) {
17
+ const message = record(value)
18
+ if (message?.role === 'tool' && typeof message.toolCallId === 'string')
19
+ results.set(message.toolCallId, (results.get(message.toolCallId) ?? 0) + 1)
20
+ if (message?.role !== 'assistant' || !Array.isArray(message.toolCalls)) continue
21
+ for (const value of message.toolCalls) {
22
+ const call = record(value)
23
+ if (typeof call?.id !== 'string' || !call.id || call.id.length > 1024) continue
24
+ const name = call.type === 'function' ? record(call.function)?.name : undefined
25
+ calls.set(call.id, {
26
+ index,
27
+ name: typeof name === 'string' && name.length > 0 && name.length <= 1024 ? name : undefined,
28
+ count: (calls.get(call.id)?.count ?? 0) + 1,
29
+ })
30
+ }
31
+ }
32
+ let ownerIndex = -1
33
+ return messages.map((value, index) => {
34
+ const message = record(value)
35
+ if (message?.role !== 'tool') {
36
+ ownerIndex = index
37
+ return {}
38
+ }
39
+ const id = typeof message.toolCallId === 'string' ? message.toolCallId : undefined
40
+ const call = id === undefined ? undefined : calls.get(id)
41
+ return {
42
+ ...(id !== undefined &&
43
+ call?.count === 1 &&
44
+ call.index === ownerIndex &&
45
+ results.get(id) === 1 &&
46
+ call.name
47
+ ? { toolName: call.name }
48
+ : {}),
49
+ ...(typeof message.isError === 'boolean' ? { isError: message.isError } : {}),
50
+ }
51
+ })
52
+ }
@@ -0,0 +1,61 @@
1
+ import type { MessageRole } from '../../types/message/index.js'
2
+ import { type CompactedToolMetadata, compactedToolMetadata } from './compaction-provenance.js'
3
+
4
+ interface CompactedText extends CompactedToolMetadata {
5
+ role: MessageRole
6
+ text: string
7
+ summary?: true
8
+ }
9
+
10
+ function record(value: unknown): Record<string, unknown> | undefined {
11
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
12
+ ? (value as Record<string, unknown>)
13
+ : undefined
14
+ }
15
+
16
+ /**
17
+ * Exact text only: do not stringify binary blocks or invent separators.
18
+ * Plain-string parts keep their historical ordinals. Block text is appended
19
+ * after that prefix, in message/block order, so durable seq/part addresses
20
+ * from before block indexing still resolve to the same original text.
21
+ */
22
+ export function compactedTexts(messages: unknown): CompactedText[] {
23
+ if (!Array.isArray(messages)) throw new Error('Invalid shed messages.')
24
+ const strings: CompactedText[] = []
25
+ const blocks: CompactedText[] = []
26
+ const metadata = compactedToolMetadata(messages)
27
+ for (const [index, value] of messages.entries()) {
28
+ const message = record(value)
29
+ if (
30
+ !message ||
31
+ typeof message.role !== 'string' ||
32
+ !['system', 'user', 'assistant', 'tool'].includes(message.role)
33
+ )
34
+ throw new Error('Invalid shed message.')
35
+ const role = message.role as MessageRole
36
+ if (typeof message.content === 'string') {
37
+ strings.push({
38
+ role,
39
+ text: message.content,
40
+ ...metadata[index],
41
+ ...(role === 'system' && record(message.source)?.type === 'compaction-summary'
42
+ ? { summary: true as const }
43
+ : {}),
44
+ })
45
+ } else if (role === 'tool' && Array.isArray(message.content)) {
46
+ for (const value of message.content) {
47
+ const block = record(value)
48
+ if (block?.type === 'text' && typeof block.text === 'string')
49
+ blocks.push({ role, text: block.text, ...metadata[index] })
50
+ else if (
51
+ !block ||
52
+ (block.type !== 'image' && block.type !== 'document') ||
53
+ typeof block.data !== 'string' ||
54
+ typeof block.mediaType !== 'string'
55
+ )
56
+ throw new Error('Invalid shed tool content block.')
57
+ }
58
+ }
59
+ }
60
+ return strings.concat(blocks)
61
+ }