@namzu/sdk 38.1.0 → 39.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 (534) hide show
  1. package/CHANGELOG.md +758 -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/contracts/schemas.js +1 -1
  30. package/dist/contracts/schemas.js.map +1 -1
  31. package/dist/eval/harness-protection.d.ts +18 -0
  32. package/dist/eval/harness-protection.d.ts.map +1 -0
  33. package/dist/eval/harness-protection.js +58 -0
  34. package/dist/eval/harness-protection.js.map +1 -0
  35. package/dist/eval/harness-verification.d.ts +6 -1
  36. package/dist/eval/harness-verification.d.ts.map +1 -1
  37. package/dist/eval/harness-verification.js +19 -2
  38. package/dist/eval/harness-verification.js.map +1 -1
  39. package/dist/eval/index.d.ts +1 -0
  40. package/dist/eval/index.d.ts.map +1 -1
  41. package/dist/eval/index.js.map +1 -1
  42. package/dist/manager/resident/activity.d.ts +50 -0
  43. package/dist/manager/resident/activity.d.ts.map +1 -0
  44. package/dist/manager/resident/activity.js +125 -0
  45. package/dist/manager/resident/activity.js.map +1 -0
  46. package/dist/manager/resident/agenda.d.ts +137 -0
  47. package/dist/manager/resident/agenda.d.ts.map +1 -0
  48. package/dist/manager/resident/agenda.js +586 -0
  49. package/dist/manager/resident/agenda.js.map +1 -0
  50. package/dist/manager/resident/consumption.d.ts +104 -0
  51. package/dist/manager/resident/consumption.d.ts.map +1 -0
  52. package/dist/manager/resident/consumption.js +233 -0
  53. package/dist/manager/resident/consumption.js.map +1 -0
  54. package/dist/manager/resident/delivery-window.d.ts +22 -0
  55. package/dist/manager/resident/delivery-window.d.ts.map +1 -0
  56. package/dist/manager/resident/delivery-window.js +78 -0
  57. package/dist/manager/resident/delivery-window.js.map +1 -0
  58. package/dist/manager/resident/evidence-recall.d.ts +24 -0
  59. package/dist/manager/resident/evidence-recall.d.ts.map +1 -0
  60. package/dist/manager/resident/evidence-recall.js +295 -0
  61. package/dist/manager/resident/evidence-recall.js.map +1 -0
  62. package/dist/manager/resident/history-disk.d.ts +10 -0
  63. package/dist/manager/resident/history-disk.d.ts.map +1 -0
  64. package/dist/manager/resident/history-disk.js +50 -0
  65. package/dist/manager/resident/history-disk.js.map +1 -0
  66. package/dist/manager/resident/history.d.ts +79 -0
  67. package/dist/manager/resident/history.d.ts.map +1 -0
  68. package/dist/manager/resident/history.js +203 -0
  69. package/dist/manager/resident/history.js.map +1 -0
  70. package/dist/manager/resident/host.d.ts +78 -0
  71. package/dist/manager/resident/host.d.ts.map +1 -0
  72. package/dist/manager/resident/host.js +252 -0
  73. package/dist/manager/resident/host.js.map +1 -0
  74. package/dist/manager/resident/initiative.d.ts +111 -0
  75. package/dist/manager/resident/initiative.d.ts.map +1 -0
  76. package/dist/manager/resident/initiative.js +129 -0
  77. package/dist/manager/resident/initiative.js.map +1 -0
  78. package/dist/manager/resident/learning-cycle.d.ts +131 -0
  79. package/dist/manager/resident/learning-cycle.d.ts.map +1 -0
  80. package/dist/manager/resident/learning-cycle.js +306 -0
  81. package/dist/manager/resident/learning-cycle.js.map +1 -0
  82. package/dist/manager/resident/learning-observation.d.ts +80 -0
  83. package/dist/manager/resident/learning-observation.d.ts.map +1 -0
  84. package/dist/manager/resident/learning-observation.js +22 -0
  85. package/dist/manager/resident/learning-observation.js.map +1 -0
  86. package/dist/manager/resident/learning-store.d.ts +106 -0
  87. package/dist/manager/resident/learning-store.d.ts.map +1 -0
  88. package/dist/manager/resident/learning-store.js +598 -0
  89. package/dist/manager/resident/learning-store.js.map +1 -0
  90. package/dist/manager/resident/learning.d.ts +726 -0
  91. package/dist/manager/resident/learning.d.ts.map +1 -0
  92. package/dist/manager/resident/learning.js +353 -0
  93. package/dist/manager/resident/learning.js.map +1 -0
  94. package/dist/manager/resident/loop.d.ts +31 -0
  95. package/dist/manager/resident/loop.d.ts.map +1 -0
  96. package/dist/manager/resident/loop.js +69 -0
  97. package/dist/manager/resident/loop.js.map +1 -0
  98. package/dist/manager/resident/outbox.d.ts +180 -0
  99. package/dist/manager/resident/outbox.d.ts.map +1 -0
  100. package/dist/manager/resident/outbox.js +214 -0
  101. package/dist/manager/resident/outbox.js.map +1 -0
  102. package/dist/manager/resident/proposal.d.ts +91 -0
  103. package/dist/manager/resident/proposal.d.ts.map +1 -0
  104. package/dist/manager/resident/proposal.js +75 -0
  105. package/dist/manager/resident/proposal.js.map +1 -0
  106. package/dist/manager/resident/store.d.ts +182 -0
  107. package/dist/manager/resident/store.d.ts.map +1 -0
  108. package/dist/manager/resident/store.js +199 -0
  109. package/dist/manager/resident/store.js.map +1 -0
  110. package/dist/manager/resident/tool-evidence.d.ts +71 -0
  111. package/dist/manager/resident/tool-evidence.d.ts.map +1 -0
  112. package/dist/manager/resident/tool-evidence.js +285 -0
  113. package/dist/manager/resident/tool-evidence.js.map +1 -0
  114. package/dist/manager/run/persistence.d.ts.map +1 -1
  115. package/dist/manager/run/persistence.js +6 -0
  116. package/dist/manager/run/persistence.js.map +1 -1
  117. package/dist/plugin/loader.d.ts.map +1 -1
  118. package/dist/plugin/loader.js +5 -3
  119. package/dist/plugin/loader.js.map +1 -1
  120. package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
  121. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  122. package/dist/prompt/coding-agent-doctrine.js +2 -0
  123. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  124. package/dist/prompt/contributions.d.ts +5 -2
  125. package/dist/prompt/contributions.d.ts.map +1 -1
  126. package/dist/prompt/contributions.js.map +1 -1
  127. package/dist/prompt/index.d.ts +4 -0
  128. package/dist/prompt/index.d.ts.map +1 -1
  129. package/dist/prompt/index.js +2 -0
  130. package/dist/prompt/index.js.map +1 -1
  131. package/dist/prompt/resident-learning.d.ts +19 -0
  132. package/dist/prompt/resident-learning.d.ts.map +1 -0
  133. package/dist/prompt/resident-learning.js +125 -0
  134. package/dist/prompt/resident-learning.js.map +1 -0
  135. package/dist/prompt/resident-step.d.ts +36 -0
  136. package/dist/prompt/resident-step.d.ts.map +1 -0
  137. package/dist/prompt/resident-step.js +135 -0
  138. package/dist/prompt/resident-step.js.map +1 -0
  139. package/dist/provider/collect-chat-completion.d.ts +2 -1
  140. package/dist/provider/collect-chat-completion.d.ts.map +1 -1
  141. package/dist/provider/collect-chat-completion.js +7 -6
  142. package/dist/provider/collect-chat-completion.js.map +1 -1
  143. package/dist/provider/fallback.d.ts.map +1 -1
  144. package/dist/provider/fallback.js +2 -1
  145. package/dist/provider/fallback.js.map +1 -1
  146. package/dist/provider/stream-text.d.ts +16 -0
  147. package/dist/provider/stream-text.d.ts.map +1 -0
  148. package/dist/provider/stream-text.js +51 -0
  149. package/dist/provider/stream-text.js.map +1 -0
  150. package/dist/public-runtime.d.ts +22 -3
  151. package/dist/public-runtime.d.ts.map +1 -1
  152. package/dist/public-runtime.js +21 -3
  153. package/dist/public-runtime.js.map +1 -1
  154. package/dist/public-tools.d.ts +2 -0
  155. package/dist/public-tools.d.ts.map +1 -1
  156. package/dist/public-tools.js +2 -0
  157. package/dist/public-tools.js.map +1 -1
  158. package/dist/public-types.d.ts +29 -3
  159. package/dist/public-types.d.ts.map +1 -1
  160. package/dist/registry/index.d.ts +1 -1
  161. package/dist/registry/index.d.ts.map +1 -1
  162. package/dist/registry/tool/execute.d.ts +18 -0
  163. package/dist/registry/tool/execute.d.ts.map +1 -1
  164. package/dist/registry/tool/execute.js +43 -6
  165. package/dist/registry/tool/execute.js.map +1 -1
  166. package/dist/run/LimitChecker.js +3 -3
  167. package/dist/run/LimitChecker.js.map +1 -1
  168. package/dist/run/evidence-query.d.ts +41 -0
  169. package/dist/run/evidence-query.d.ts.map +1 -0
  170. package/dist/run/evidence-query.js +270 -0
  171. package/dist/run/evidence-query.js.map +1 -0
  172. package/dist/run/evidence-recall.d.ts +99 -0
  173. package/dist/run/evidence-recall.d.ts.map +1 -0
  174. package/dist/run/evidence-recall.js +633 -0
  175. package/dist/run/evidence-recall.js.map +1 -0
  176. package/dist/run/index.d.ts +2 -0
  177. package/dist/run/index.d.ts.map +1 -1
  178. package/dist/run/index.js +1 -0
  179. package/dist/run/index.js.map +1 -1
  180. package/dist/run/json-claim-verifier.d.ts +83 -0
  181. package/dist/run/json-claim-verifier.d.ts.map +1 -0
  182. package/dist/run/json-claim-verifier.js +200 -0
  183. package/dist/run/json-claim-verifier.js.map +1 -0
  184. package/dist/run/preparation-context-error.d.ts +10 -0
  185. package/dist/run/preparation-context-error.d.ts.map +1 -0
  186. package/dist/run/preparation-context-error.js +15 -0
  187. package/dist/run/preparation-context-error.js.map +1 -0
  188. package/dist/run-query/index.d.ts +3 -1
  189. package/dist/run-query/index.d.ts.map +1 -1
  190. package/dist/runtime/query/callback-inference.d.ts +8 -0
  191. package/dist/runtime/query/callback-inference.d.ts.map +1 -0
  192. package/dist/runtime/query/callback-inference.js +89 -0
  193. package/dist/runtime/query/callback-inference.js.map +1 -0
  194. package/dist/runtime/query/checkpoint.d.ts +4 -0
  195. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  196. package/dist/runtime/query/checkpoint.js +13 -0
  197. package/dist/runtime/query/checkpoint.js.map +1 -1
  198. package/dist/runtime/query/events.d.ts +7 -1
  199. package/dist/runtime/query/events.d.ts.map +1 -1
  200. package/dist/runtime/query/events.js +39 -12
  201. package/dist/runtime/query/events.js.map +1 -1
  202. package/dist/runtime/query/executor.d.ts +7 -1
  203. package/dist/runtime/query/executor.d.ts.map +1 -1
  204. package/dist/runtime/query/executor.js +38 -7
  205. package/dist/runtime/query/executor.js.map +1 -1
  206. package/dist/runtime/query/file-evidence-context.d.ts +5 -0
  207. package/dist/runtime/query/file-evidence-context.d.ts.map +1 -0
  208. package/dist/runtime/query/file-evidence-context.js +64 -0
  209. package/dist/runtime/query/file-evidence-context.js.map +1 -0
  210. package/dist/runtime/query/guard.d.ts.map +1 -1
  211. package/dist/runtime/query/guard.js +4 -0
  212. package/dist/runtime/query/guard.js.map +1 -1
  213. package/dist/runtime/query/index.d.ts +10 -1
  214. package/dist/runtime/query/index.d.ts.map +1 -1
  215. package/dist/runtime/query/index.js +40 -25
  216. package/dist/runtime/query/index.js.map +1 -1
  217. package/dist/runtime/query/iteration/index.d.ts +9 -31
  218. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  219. package/dist/runtime/query/iteration/index.js +231 -93
  220. package/dist/runtime/query/iteration/index.js.map +1 -1
  221. package/dist/runtime/query/iteration/phases/advisory.d.ts +2 -1
  222. package/dist/runtime/query/iteration/phases/advisory.d.ts.map +1 -1
  223. package/dist/runtime/query/iteration/phases/advisory.js +2 -1
  224. package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
  225. package/dist/runtime/query/iteration/phases/context.d.ts +2 -1
  226. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  227. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  228. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  229. package/dist/runtime/query/iteration/phases/tool-review.js +3 -0
  230. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  231. package/dist/runtime/query/iteration/provider-rejected-image.d.ts +2 -1
  232. package/dist/runtime/query/iteration/provider-rejected-image.d.ts.map +1 -1
  233. package/dist/runtime/query/iteration/provider-rejected-image.js +5 -2
  234. package/dist/runtime/query/iteration/provider-rejected-image.js.map +1 -1
  235. package/dist/runtime/query/iteration/stream-turn.d.ts +4 -1
  236. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  237. package/dist/runtime/query/iteration/stream-turn.js +22 -8
  238. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  239. package/dist/runtime/query/prompt-cache.d.ts.map +1 -1
  240. package/dist/runtime/query/prompt-cache.js +21 -42
  241. package/dist/runtime/query/prompt-cache.js.map +1 -1
  242. package/dist/runtime/query/resume-pending.d.ts +18 -33
  243. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  244. package/dist/runtime/query/resume-pending.js +59 -42
  245. package/dist/runtime/query/resume-pending.js.map +1 -1
  246. package/dist/runtime/query/review-policy.d.ts +4 -4
  247. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  248. package/dist/runtime/query/review-policy.js +10 -9
  249. package/dist/runtime/query/review-policy.js.map +1 -1
  250. package/dist/runtime/query/sandbox-lifecycle.d.ts.map +1 -1
  251. package/dist/runtime/query/sandbox-lifecycle.js +4 -0
  252. package/dist/runtime/query/sandbox-lifecycle.js.map +1 -1
  253. package/dist/runtime/query/tool-output-budget.d.ts +10 -6
  254. package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
  255. package/dist/runtime/query/tool-output-budget.js +54 -12
  256. package/dist/runtime/query/tool-output-budget.js.map +1 -1
  257. package/dist/runtime/query/tooling.d.ts +3 -1
  258. package/dist/runtime/query/tooling.d.ts.map +1 -1
  259. package/dist/runtime/query/tooling.js +4 -0
  260. package/dist/runtime/query/tooling.js.map +1 -1
  261. package/dist/scheduler/completion-inbox.d.ts +3 -0
  262. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  263. package/dist/scheduler/completion-inbox.js +28 -0
  264. package/dist/scheduler/completion-inbox.js.map +1 -1
  265. package/dist/store/evidence/compaction-archive.d.ts +109 -0
  266. package/dist/store/evidence/compaction-archive.d.ts.map +1 -0
  267. package/dist/store/evidence/compaction-archive.js +125 -0
  268. package/dist/store/evidence/compaction-archive.js.map +1 -0
  269. package/dist/store/evidence/compaction-provenance.d.ts +7 -0
  270. package/dist/store/evidence/compaction-provenance.d.ts.map +1 -0
  271. package/dist/store/evidence/compaction-provenance.js +49 -0
  272. package/dist/store/evidence/compaction-provenance.js.map +1 -0
  273. package/dist/store/evidence/compaction-text.d.ts +16 -0
  274. package/dist/store/evidence/compaction-text.d.ts.map +1 -0
  275. package/dist/store/evidence/compaction-text.js +51 -0
  276. package/dist/store/evidence/compaction-text.js.map +1 -0
  277. package/dist/store/evidence/disk.d.ts +11 -0
  278. package/dist/store/evidence/disk.d.ts.map +1 -0
  279. package/dist/store/evidence/disk.js +367 -0
  280. package/dist/store/evidence/disk.js.map +1 -0
  281. package/dist/store/evidence/format.d.ts +25 -0
  282. package/dist/store/evidence/format.d.ts.map +1 -0
  283. package/dist/store/evidence/format.js +115 -0
  284. package/dist/store/evidence/format.js.map +1 -0
  285. package/dist/store/evidence/index-page.d.ts +208 -0
  286. package/dist/store/evidence/index-page.d.ts.map +1 -0
  287. package/dist/store/evidence/index-page.js +262 -0
  288. package/dist/store/evidence/index-page.js.map +1 -0
  289. package/dist/store/evidence/io.d.ts +24 -0
  290. package/dist/store/evidence/io.d.ts.map +1 -0
  291. package/dist/store/evidence/io.js +69 -0
  292. package/dist/store/evidence/io.js.map +1 -0
  293. package/dist/store/evidence/linked.d.ts +9 -0
  294. package/dist/store/evidence/linked.d.ts.map +1 -0
  295. package/dist/store/evidence/linked.js +314 -0
  296. package/dist/store/evidence/linked.js.map +1 -0
  297. package/dist/store/evidence/passages.d.ts +15 -0
  298. package/dist/store/evidence/passages.d.ts.map +1 -0
  299. package/dist/store/evidence/passages.js +72 -0
  300. package/dist/store/evidence/passages.js.map +1 -0
  301. package/dist/store/evidence/record-chain.d.ts +42 -0
  302. package/dist/store/evidence/record-chain.d.ts.map +1 -0
  303. package/dist/store/evidence/record-chain.js +111 -0
  304. package/dist/store/evidence/record-chain.js.map +1 -0
  305. package/dist/store/evidence/search-input.d.ts +21 -0
  306. package/dist/store/evidence/search-input.d.ts.map +1 -0
  307. package/dist/store/evidence/search-input.js +44 -0
  308. package/dist/store/evidence/search-input.js.map +1 -0
  309. package/dist/store/evidence/selection.d.ts +9 -0
  310. package/dist/store/evidence/selection.d.ts.map +1 -0
  311. package/dist/store/evidence/selection.js +17 -0
  312. package/dist/store/evidence/selection.js.map +1 -0
  313. package/dist/store/evidence/source-kind.d.ts +11 -0
  314. package/dist/store/evidence/source-kind.d.ts.map +1 -0
  315. package/dist/store/evidence/source-kind.js +26 -0
  316. package/dist/store/evidence/source-kind.js.map +1 -0
  317. package/dist/store/evidence/source-text.d.ts +51 -0
  318. package/dist/store/evidence/source-text.d.ts.map +1 -0
  319. package/dist/store/evidence/source-text.js +213 -0
  320. package/dist/store/evidence/source-text.js.map +1 -0
  321. package/dist/store/evidence/types.d.ts +162 -0
  322. package/dist/store/evidence/types.d.ts.map +1 -0
  323. package/dist/store/evidence/types.js +2 -0
  324. package/dist/store/evidence/types.js.map +1 -0
  325. package/dist/store/memory/disk.d.ts +2 -0
  326. package/dist/store/memory/disk.d.ts.map +1 -1
  327. package/dist/store/memory/disk.js +2 -1
  328. package/dist/store/memory/disk.js.map +1 -1
  329. package/dist/store/run/disk.d.ts +10 -0
  330. package/dist/store/run/disk.d.ts.map +1 -1
  331. package/dist/store/run/disk.js +87 -7
  332. package/dist/store/run/disk.js.map +1 -1
  333. package/dist/store/run/memory.d.ts +1 -0
  334. package/dist/store/run/memory.d.ts.map +1 -1
  335. package/dist/store/run/memory.js +10 -0
  336. package/dist/store/run/memory.js.map +1 -1
  337. package/dist/store/run/tool-executions.d.ts +13 -0
  338. package/dist/store/run/tool-executions.d.ts.map +1 -0
  339. package/dist/store/run/tool-executions.js +99 -0
  340. package/dist/store/run/tool-executions.js.map +1 -0
  341. package/dist/store/session/index.d.ts +2 -0
  342. package/dist/store/session/index.d.ts.map +1 -1
  343. package/dist/store/session/index.js +1 -0
  344. package/dist/store/session/index.js.map +1 -1
  345. package/dist/store/session/sqlite.d.ts +57 -0
  346. package/dist/store/session/sqlite.d.ts.map +1 -0
  347. package/dist/store/session/sqlite.js +430 -0
  348. package/dist/store/session/sqlite.js.map +1 -0
  349. package/dist/tools/builtins/job.d.ts.map +1 -1
  350. package/dist/tools/builtins/job.js +4 -5
  351. package/dist/tools/builtins/job.js.map +1 -1
  352. package/dist/tools/builtins/write-file.js +2 -2
  353. package/dist/tools/builtins/write-file.js.map +1 -1
  354. package/dist/tools/defineTool.d.ts +2 -1
  355. package/dist/tools/defineTool.d.ts.map +1 -1
  356. package/dist/tools/defineTool.js +1 -1
  357. package/dist/tools/defineTool.js.map +1 -1
  358. package/dist/tools/file-read-tracker.d.ts.map +1 -1
  359. package/dist/tools/file-read-tracker.js +12 -3
  360. package/dist/tools/file-read-tracker.js.map +1 -1
  361. package/dist/tools/resident-history.d.ts +10 -0
  362. package/dist/tools/resident-history.d.ts.map +1 -0
  363. package/dist/tools/resident-history.js +80 -0
  364. package/dist/tools/resident-history.js.map +1 -0
  365. package/dist/tools/resident-tool-evidence.d.ts +5 -0
  366. package/dist/tools/resident-tool-evidence.d.ts.map +1 -0
  367. package/dist/tools/resident-tool-evidence.js +57 -0
  368. package/dist/tools/resident-tool-evidence.js.map +1 -0
  369. package/dist/types/advisory/config.d.ts +7 -0
  370. package/dist/types/advisory/config.d.ts.map +1 -1
  371. package/dist/types/agent/reactive.d.ts +1 -0
  372. package/dist/types/agent/reactive.d.ts.map +1 -1
  373. package/dist/types/authorization/index.d.ts +9 -9
  374. package/dist/types/authorization/index.d.ts.map +1 -1
  375. package/dist/types/authorization/index.js +1 -1
  376. package/dist/types/authorization/index.js.map +1 -1
  377. package/dist/types/hitl/index.d.ts +4 -0
  378. package/dist/types/hitl/index.d.ts.map +1 -1
  379. package/dist/types/hitl/index.js.map +1 -1
  380. package/dist/types/message/index.d.ts +16 -2
  381. package/dist/types/message/index.d.ts.map +1 -1
  382. package/dist/types/message/index.js +8 -1
  383. package/dist/types/message/index.js.map +1 -1
  384. package/dist/types/provider/chat.d.ts +2 -0
  385. package/dist/types/provider/chat.d.ts.map +1 -1
  386. package/dist/types/provider/stream.d.ts +4 -0
  387. package/dist/types/provider/stream.d.ts.map +1 -1
  388. package/dist/types/run/answer-review.d.ts +34 -3
  389. package/dist/types/run/answer-review.d.ts.map +1 -1
  390. package/dist/types/run/config.d.ts +3 -0
  391. package/dist/types/run/config.d.ts.map +1 -1
  392. package/dist/types/run/entity.d.ts +7 -0
  393. package/dist/types/run/entity.d.ts.map +1 -1
  394. package/dist/types/run/events.d.ts +31 -8
  395. package/dist/types/run/events.d.ts.map +1 -1
  396. package/dist/types/run/events.js.map +1 -1
  397. package/dist/types/run/prepare-step.d.ts +53 -8
  398. package/dist/types/run/prepare-step.d.ts.map +1 -1
  399. package/dist/types/run/store.d.ts +29 -4
  400. package/dist/types/run/store.d.ts.map +1 -1
  401. package/dist/types/run/store.js +0 -28
  402. package/dist/types/run/store.js.map +1 -1
  403. package/dist/types/tool/index.d.ts +15 -1
  404. package/dist/types/tool/index.d.ts.map +1 -1
  405. package/dist/types/tool/index.js.map +1 -1
  406. package/dist/utils/await-with-abort.d.ts +8 -0
  407. package/dist/utils/await-with-abort.d.ts.map +1 -0
  408. package/dist/utils/await-with-abort.js +28 -0
  409. package/dist/utils/await-with-abort.js.map +1 -0
  410. package/dist/utils/evidence-time.d.ts +3 -0
  411. package/dist/utils/evidence-time.d.ts.map +1 -0
  412. package/dist/utils/evidence-time.js +10 -0
  413. package/dist/utils/evidence-time.js.map +1 -0
  414. package/dist/utils/evidence-tokens.d.ts +13 -0
  415. package/dist/utils/evidence-tokens.d.ts.map +1 -0
  416. package/dist/utils/evidence-tokens.js +29 -0
  417. package/dist/utils/evidence-tokens.js.map +1 -0
  418. package/package.json +1 -1
  419. package/src/advisory/executor.ts +15 -30
  420. package/src/advisory/history.ts +126 -0
  421. package/src/advisory/index.ts +5 -1
  422. package/src/agents/ReactiveAgent.ts +3 -0
  423. package/src/agents/runAgent.ts +14 -1
  424. package/src/compaction/manual.ts +30 -2
  425. package/src/compaction/summary.ts +4 -1
  426. package/src/config/runtime.ts +2 -2
  427. package/src/contracts/schemas.ts +1 -1
  428. package/src/eval/harness-protection.ts +79 -0
  429. package/src/eval/harness-verification.ts +31 -1
  430. package/src/eval/index.ts +1 -0
  431. package/src/manager/resident/activity.ts +187 -0
  432. package/src/manager/resident/agenda.ts +907 -0
  433. package/src/manager/resident/consumption.ts +311 -0
  434. package/src/manager/resident/delivery-window.ts +93 -0
  435. package/src/manager/resident/evidence-recall.ts +363 -0
  436. package/src/manager/resident/history-disk.ts +63 -0
  437. package/src/manager/resident/history.ts +312 -0
  438. package/src/manager/resident/host.ts +356 -0
  439. package/src/manager/resident/initiative.ts +205 -0
  440. package/src/manager/resident/learning-cycle.ts +499 -0
  441. package/src/manager/resident/learning-observation.ts +39 -0
  442. package/src/manager/resident/learning-store.ts +813 -0
  443. package/src/manager/resident/learning.ts +493 -0
  444. package/src/manager/resident/loop.ts +101 -0
  445. package/src/manager/resident/outbox.ts +307 -0
  446. package/src/manager/resident/proposal.ts +105 -0
  447. package/src/manager/resident/store.ts +257 -0
  448. package/src/manager/resident/tool-evidence.ts +412 -0
  449. package/src/manager/run/persistence.ts +6 -0
  450. package/src/plugin/loader.ts +8 -3
  451. package/src/prompt/coding-agent-doctrine.ts +2 -0
  452. package/src/prompt/contributions.ts +5 -2
  453. package/src/prompt/index.ts +4 -0
  454. package/src/prompt/resident-learning.ts +143 -0
  455. package/src/prompt/resident-step.ts +176 -0
  456. package/src/provider/collect-chat-completion.ts +7 -6
  457. package/src/provider/fallback.ts +2 -1
  458. package/src/provider/stream-text.ts +56 -0
  459. package/src/public-runtime.ts +44 -0
  460. package/src/public-tools.ts +3 -0
  461. package/src/public-types.ts +165 -0
  462. package/src/registry/index.ts +1 -1
  463. package/src/registry/tool/execute.ts +56 -9
  464. package/src/run/LimitChecker.ts +3 -3
  465. package/src/run/evidence-query.ts +333 -0
  466. package/src/run/evidence-recall.ts +854 -0
  467. package/src/run/index.ts +11 -0
  468. package/src/run/json-claim-verifier.ts +298 -0
  469. package/src/run/preparation-context-error.ts +16 -0
  470. package/src/run-query/index.ts +1 -1
  471. package/src/runtime/query/callback-inference.ts +94 -0
  472. package/src/runtime/query/checkpoint.ts +14 -0
  473. package/src/runtime/query/events.ts +46 -14
  474. package/src/runtime/query/executor.ts +51 -9
  475. package/src/runtime/query/file-evidence-context.ts +65 -0
  476. package/src/runtime/query/guard.ts +2 -0
  477. package/src/runtime/query/index.ts +50 -27
  478. package/src/runtime/query/iteration/index.ts +269 -86
  479. package/src/runtime/query/iteration/phases/advisory.ts +3 -0
  480. package/src/runtime/query/iteration/phases/context.ts +2 -0
  481. package/src/runtime/query/iteration/phases/tool-review.ts +3 -0
  482. package/src/runtime/query/iteration/provider-rejected-image.ts +6 -1
  483. package/src/runtime/query/iteration/stream-turn.ts +35 -8
  484. package/src/runtime/query/prompt-cache.ts +24 -47
  485. package/src/runtime/query/resume-pending.ts +65 -40
  486. package/src/runtime/query/review-policy.ts +13 -9
  487. package/src/runtime/query/sandbox-lifecycle.ts +3 -0
  488. package/src/runtime/query/tool-output-budget.ts +65 -13
  489. package/src/runtime/query/tooling.ts +7 -1
  490. package/src/scheduler/completion-inbox.ts +26 -0
  491. package/src/store/evidence/compaction-archive.ts +139 -0
  492. package/src/store/evidence/compaction-provenance.ts +52 -0
  493. package/src/store/evidence/compaction-text.ts +61 -0
  494. package/src/store/evidence/disk.ts +461 -0
  495. package/src/store/evidence/format.ts +126 -0
  496. package/src/store/evidence/index-page.ts +292 -0
  497. package/src/store/evidence/io.ts +95 -0
  498. package/src/store/evidence/linked.ts +365 -0
  499. package/src/store/evidence/passages.ts +88 -0
  500. package/src/store/evidence/record-chain.ts +108 -0
  501. package/src/store/evidence/search-input.ts +62 -0
  502. package/src/store/evidence/selection.ts +25 -0
  503. package/src/store/evidence/source-kind.ts +36 -0
  504. package/src/store/evidence/source-text.ts +285 -0
  505. package/src/store/evidence/types.ts +177 -0
  506. package/src/store/memory/disk.ts +4 -1
  507. package/src/store/run/disk.ts +110 -8
  508. package/src/store/run/memory.ts +10 -0
  509. package/src/store/run/tool-executions.ts +112 -0
  510. package/src/store/session/index.ts +2 -0
  511. package/src/store/session/sqlite.ts +584 -0
  512. package/src/tools/builtins/job.ts +4 -5
  513. package/src/tools/builtins/write-file.ts +2 -2
  514. package/src/tools/defineTool.ts +4 -2
  515. package/src/tools/file-read-tracker.ts +8 -2
  516. package/src/tools/resident-history.ts +86 -0
  517. package/src/tools/resident-tool-evidence.ts +68 -0
  518. package/src/types/advisory/config.ts +7 -0
  519. package/src/types/agent/reactive.ts +1 -0
  520. package/src/types/authorization/index.ts +2 -2
  521. package/src/types/hitl/index.ts +4 -0
  522. package/src/types/message/index.ts +20 -0
  523. package/src/types/provider/chat.ts +2 -0
  524. package/src/types/provider/stream.ts +4 -0
  525. package/src/types/run/answer-review.ts +34 -3
  526. package/src/types/run/config.ts +3 -0
  527. package/src/types/run/entity.ts +7 -0
  528. package/src/types/run/events.ts +31 -8
  529. package/src/types/run/prepare-step.ts +59 -8
  530. package/src/types/run/store.ts +35 -4
  531. package/src/types/tool/index.ts +19 -1
  532. package/src/utils/await-with-abort.ts +26 -0
  533. package/src/utils/evidence-time.ts +9 -0
  534. 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.
@@ -47,8 +47,10 @@ export interface ToolingBootstrapConfig {
47
47
  maxToolCalls?: number
48
48
  readToolCallBudgetEvents?: () => Promise<readonly RunEvent[]>
49
49
  maxToolOutputChars?: number
50
+ retainedToolPreviewChars?: number
50
51
  maxToolContentBytes?: number
51
- toolOutputDir?: string
52
+ captureRunEvidence?: import('../../types/tool/index.js').ToolContext['captureRunEvidence']
53
+ toolOutputDir?: string | (() => string | undefined)
52
54
  repairToolCall?: RepairToolCall
53
55
  /** Operator authorization shared with the direct-call review path. */
54
56
  authorizationGate?: AuthorizationGate
@@ -79,6 +81,7 @@ export class ToolingBootstrap {
79
81
  abortSignal: config.abortSignal,
80
82
  allowedTools: config.allowedTools,
81
83
  invocationState: config.invocationState,
84
+ captureRunEvidence: config.captureRunEvidence,
82
85
  pluginManager: config.pluginManager,
83
86
  ...(config.backgroundJobs ? { backgroundJobs: config.backgroundJobs } : {}),
84
87
  ...(config.backgroundJobOwner ? { backgroundJobOwner: config.backgroundJobOwner } : {}),
@@ -98,6 +101,9 @@ export class ToolingBootstrap {
98
101
  ...(config.maxToolOutputChars !== undefined
99
102
  ? { maxToolOutputChars: config.maxToolOutputChars }
100
103
  : {}),
104
+ ...(config.retainedToolPreviewChars !== undefined
105
+ ? { retainedToolPreviewChars: config.retainedToolPreviewChars }
106
+ : {}),
101
107
  ...(config.maxToolContentBytes !== undefined
102
108
  ? { maxToolContentBytes: config.maxToolContentBytes }
103
109
  : {}),
@@ -77,6 +77,7 @@ export class CompletionInbox {
77
77
  * takes one, and a host that owns a gateway naturally reuses it.
78
78
  */
79
79
  private readonly ours = new Set<TaskId>()
80
+ private readonly recentOwned: TaskId[] = []
80
81
  /**
81
82
  * Announcements that arrived before anyone said whose task it was.
82
83
  *
@@ -192,6 +193,8 @@ export class CompletionInbox {
192
193
  launched(taskId: TaskId): void {
193
194
  if (this.ours.has(taskId)) return
194
195
  this.ours.add(taskId)
196
+ this.recentOwned.push(taskId)
197
+ if (this.recentOwned.length > 16) this.recentOwned.shift()
195
198
 
196
199
  if (this.claimed.has(taskId) || this.unheard.has(taskId)) return
197
200
 
@@ -278,6 +281,28 @@ export class CompletionInbox {
278
281
  return this.unheard.size > 0
279
282
  }
280
283
 
284
+ /** Bounded, non-consuming scheduler observations. Delivery never establishes user-facing completion. */
285
+ describeOwnedWork(): string | undefined {
286
+ if (this.ours.size === 0) return
287
+ const ids = this.recentOwned
288
+ const tasks = ids.map((taskId) => {
289
+ let handle = this.unheard.get(taskId)
290
+ try {
291
+ handle = this.gateway?.getTask(taskId) ?? handle
292
+ } catch {
293
+ // A broken observation must not block execution or invent a task state.
294
+ }
295
+ return {
296
+ taskId,
297
+ state: handle?.state ?? 'unknown',
298
+ ...(handle?.result?.status ? { runStatus: handle.result.status } : {}),
299
+ ...(handle?.result?.stopReason ? { stopReason: handle.result.stopReason } : {}),
300
+ resultDelivery: this.claimed.has(taskId) ? 'delivered-to-history' : 'not-delivered',
301
+ }
302
+ })
303
+ return `Owned delegated work (current scheduler observations). 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 })}`
304
+ }
305
+
281
306
  /**
282
307
  * Tasks this run launched that are still running.
283
308
  *
@@ -366,6 +391,7 @@ export class CompletionInbox {
366
391
  this.unheard.clear()
367
392
  this.outstanding.clear()
368
393
  this.ours.clear()
394
+ this.recentOwned.length = 0
369
395
  this.claimed.clear()
370
396
  this.unowned.clear()
371
397
  // 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
+ }