@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
@@ -0,0 +1,312 @@
1
+ import { z } from 'zod'
2
+ import type { ResidentAgendaState } from './agenda.js'
3
+ import { ResidentHistoryPageLimit, type ResidentHistoryReadBudget } from './history-disk.js'
4
+
5
+ const SCAN_BYTES = 8 * 1024 * 1024
6
+ const SCAN_REVISIONS = 32
7
+ const TEXT_PAGE_CHARS = 6_000
8
+
9
+ /** @experimental Host-bound historical scope; the upper revision never advances implicitly. */
10
+ export interface ResidentHistoryScope {
11
+ readonly tenantId: string
12
+ readonly agentKey: string
13
+ readonly pursuitId: string
14
+ readonly throughRevision: number
15
+ }
16
+
17
+ /** @experimental Revision plus part identifies retained text within one pursuit. */
18
+ export interface ResidentHistoryAddress {
19
+ readonly revision: number
20
+ readonly part: number
21
+ }
22
+
23
+ /** @experimental Summary or accepted wake input from a settled historical step. */
24
+ export interface ResidentHistoryMatch extends ResidentHistoryAddress {
25
+ readonly step: number
26
+ readonly claimId: string
27
+ readonly kind: 'wait' | 'complete' | 'blocked'
28
+ readonly source: 'summary' | 'wake'
29
+ readonly excerpt: string
30
+ readonly matchingParts: readonly number[]
31
+ }
32
+
33
+ /** @experimental Empty query browses recent steps; cursor is the next inclusive revision. */
34
+ export interface ResidentHistorySearchOptions {
35
+ /** Optional per-call ceiling, 1 byte–8 MiB. Defaults to 8 MiB. */
36
+ readonly maxReadBytes?: number
37
+ readonly query?: string
38
+ readonly cursor?: number
39
+ readonly limit?: number
40
+ }
41
+
42
+ /** @experimental Counts describe this page, not the whole history. */
43
+ export interface ResidentHistorySearchResult {
44
+ readonly matches: readonly ResidentHistoryMatch[]
45
+ readonly nextCursor: number | null
46
+ readonly scannedRevisions: number
47
+ readonly scannedBytes: number
48
+ readonly unavailableRevisions: readonly number[]
49
+ readonly incomplete: boolean
50
+ }
51
+
52
+ /** @experimental Use the returned nextOffset to continue exact Unicode-safe text. */
53
+ export interface ResidentHistoryReadOptions extends ResidentHistoryAddress {
54
+ readonly offset?: number
55
+ /** Optional per-call ceiling, 1 byte–8 MiB. Defaults to 8 MiB. */
56
+ readonly maxReadBytes?: number
57
+ }
58
+
59
+ /** @experimental A recorded claim remains historical evidence, not proof of current validity. */
60
+ export interface ResidentHistoryText extends ResidentHistoryAddress {
61
+ readonly step: number
62
+ readonly claimId: string
63
+ readonly kind: 'wait' | 'complete' | 'blocked'
64
+ readonly source: 'summary' | 'wake'
65
+ readonly receivedAt?: number
66
+ readonly text: string
67
+ readonly offset: number
68
+ readonly totalChars: number
69
+ readonly nextOffset: number | null
70
+ }
71
+
72
+ /** @experimental Null with unavailable revisions means unreadable evidence, not proven absence. */
73
+ export interface ResidentHistoryReadResult {
74
+ readonly entry: ResidentHistoryText | null
75
+ readonly scannedRevisions: number
76
+ readonly scannedBytes: number
77
+ readonly unavailableRevisions: readonly number[]
78
+ }
79
+
80
+ /** @experimental A backend must enforce its bound scope and bounded reads. */
81
+ export interface ResidentHistorySource {
82
+ readonly scope: ResidentHistoryScope
83
+ search(
84
+ options?: ResidentHistorySearchOptions,
85
+ signal?: AbortSignal,
86
+ ): Promise<ResidentHistorySearchResult>
87
+ read(
88
+ options: ResidentHistoryReadOptions,
89
+ signal?: AbortSignal,
90
+ ): Promise<ResidentHistoryReadResult>
91
+ }
92
+
93
+ type LoadRevision = (
94
+ revision: number,
95
+ budget: ResidentHistoryReadBudget,
96
+ ) => Promise<ResidentAgendaState>
97
+ interface Part {
98
+ source: 'summary' | 'wake'
99
+ text: string
100
+ receivedAt?: number
101
+ }
102
+ interface Episode {
103
+ step: number
104
+ claimId: string
105
+ kind: 'wait' | 'complete' | 'blocked'
106
+ parts: Part[]
107
+ }
108
+
109
+ function episode(
110
+ before: ResidentAgendaState | null,
111
+ after: ResidentAgendaState | null,
112
+ id: string,
113
+ ): Episode | null {
114
+ const previous = before?.pursuits.find((p) => p.id === id)?.state
115
+ const current = after?.pursuits.find((p) => p.id === id)?.state
116
+ if (
117
+ !before ||
118
+ !after ||
119
+ !previous ||
120
+ !current ||
121
+ previous.phase !== 'running' ||
122
+ !previous.claimId ||
123
+ current.phase === 'running' ||
124
+ current.claimId !== null ||
125
+ current.summary === null ||
126
+ current.stepsAdmitted !== previous.stepsAdmitted ||
127
+ current.revision !== previous.revision + 1
128
+ )
129
+ return null
130
+ return {
131
+ step: current.stepsAdmitted,
132
+ claimId: previous.claimId,
133
+ kind: current.phase === 'waiting' ? 'wait' : current.phase,
134
+ parts: [
135
+ { source: 'summary', text: current.summary },
136
+ ...(previous.wakeEvidence ?? []).map((entry) => ({
137
+ source: 'wake' as const,
138
+ text: entry.reason,
139
+ receivedAt: entry.receivedAt,
140
+ })),
141
+ ],
142
+ }
143
+ }
144
+
145
+ function boundary(text: string, offset: number): boolean {
146
+ const current = text.charCodeAt(offset)
147
+ const previous = text.charCodeAt(offset - 1)
148
+ return !(current >= 0xdc00 && current <= 0xdfff && previous >= 0xd800 && previous <= 0xdbff)
149
+ }
150
+
151
+ function textSlice(text: string, offset: number, maxChars: number): string {
152
+ let end = Math.min(text.length, offset + maxChars)
153
+ if (!boundary(text, end)) end--
154
+ return text.slice(offset, end)
155
+ }
156
+
157
+ /** Internal disk adapter. Other backends may implement ResidentHistorySource directly. */
158
+ export function createResidentHistorySource(
159
+ scopeInput: ResidentHistoryScope,
160
+ identity: { identity: string; objective: string },
161
+ load: LoadRevision,
162
+ ): ResidentHistorySource {
163
+ const scope = Object.freeze({ ...scopeInput })
164
+ const expected = { ...identity }
165
+ const revisionSchema = z.number().int().min(1).max(scope.throughRevision).safe()
166
+ function page(signal: AbortSignal | undefined, requestedBytes: number | undefined) {
167
+ const limit = z
168
+ .number()
169
+ .int()
170
+ .min(1)
171
+ .max(SCAN_BYTES)
172
+ .parse(requestedBytes ?? SCAN_BYTES)
173
+ const budget: ResidentHistoryReadBudget = { remaining: limit, bytesRead: 0, signal }
174
+ const unavailable = new Set<number>()
175
+ let scanned = 0
176
+ const cache = new Map<number, ResidentAgendaState | null>()
177
+ return {
178
+ budget,
179
+ async load(revision: number) {
180
+ signal?.throwIfAborted()
181
+ if (cache.has(revision)) return cache.get(revision) ?? null
182
+ if (scanned >= SCAN_REVISIONS) throw new ResidentHistoryPageLimit()
183
+ scanned++
184
+ let record: ResidentAgendaState | null = null
185
+ try {
186
+ record = await load(revision, budget)
187
+ const pursuit = record.pursuits.find((p) => p.id === scope.pursuitId)
188
+ if (
189
+ record.revision !== revision ||
190
+ record.tenantId !== scope.tenantId ||
191
+ record.agentKey !== scope.agentKey ||
192
+ (pursuit &&
193
+ (pursuit.state.identity !== expected.identity ||
194
+ pursuit.state.objective !== expected.objective))
195
+ )
196
+ throw new Error('History identity does not match its bound pursuit.')
197
+ } catch (error) {
198
+ signal?.throwIfAborted()
199
+ if (error instanceof ResidentHistoryPageLimit) throw error
200
+ unavailable.add(revision)
201
+ record = null
202
+ }
203
+ // Adjacent revisions are reused on the next scan iteration, without
204
+ // keeping the whole archive in memory.
205
+ if (cache.size >= 2) cache.delete(cache.keys().next().value as number)
206
+ cache.set(revision, record)
207
+ return record
208
+ },
209
+ counts: () => ({
210
+ scannedRevisions: scanned,
211
+ scannedBytes: budget.bytesRead,
212
+ unavailableRevisions: [...unavailable],
213
+ }),
214
+ }
215
+ }
216
+ return Object.freeze({
217
+ scope,
218
+ async search(options: ResidentHistorySearchOptions = {}, signal?: AbortSignal) {
219
+ signal?.throwIfAborted()
220
+ const query = z
221
+ .string()
222
+ .max(256)
223
+ .parse(options.query ?? '')
224
+ const limit = z
225
+ .number()
226
+ .int()
227
+ .min(1)
228
+ .max(8)
229
+ .parse(options.limit ?? 5)
230
+ let revision = revisionSchema.parse(options.cursor ?? scope.throughRevision)
231
+ const reader = page(signal, options.maxReadBytes)
232
+ const matches: ResidentHistoryMatch[] = []
233
+ while (revision >= 2 && matches.length < limit) {
234
+ let found: Episode | null
235
+ try {
236
+ const after = await reader.load(revision)
237
+ const before = await reader.load(revision - 1)
238
+ found = episode(before, after, scope.pursuitId)
239
+ } catch (error) {
240
+ if (!(error instanceof ResidentHistoryPageLimit)) throw error
241
+ break
242
+ }
243
+ if (found) {
244
+ const matchingParts = found.parts.flatMap((part, index) =>
245
+ part.text.includes(query) ? [index] : [],
246
+ )
247
+ const part = matchingParts[0]
248
+ const matched = part === undefined ? undefined : found.parts[part]
249
+ if (matched && part !== undefined) {
250
+ let start = Math.max(0, matched.text.indexOf(query) - 120)
251
+ if (!boundary(matched.text, start)) start--
252
+ matches.push({
253
+ revision,
254
+ part,
255
+ step: found.step,
256
+ claimId: found.claimId,
257
+ kind: found.kind,
258
+ source: matched.source,
259
+ excerpt: textSlice(matched.text, start, 512),
260
+ matchingParts,
261
+ })
262
+ }
263
+ }
264
+ revision--
265
+ }
266
+ const nextCursor = revision >= 2 ? revision : null
267
+ const counts = reader.counts()
268
+ return {
269
+ matches,
270
+ nextCursor,
271
+ ...counts,
272
+ incomplete: nextCursor !== null || counts.unavailableRevisions.length > 0,
273
+ }
274
+ },
275
+ async read(options: ResidentHistoryReadOptions, signal?: AbortSignal) {
276
+ const revision = revisionSchema.parse(options.revision)
277
+ const part = z.number().int().min(0).max(16).parse(options.part)
278
+ const offset = z
279
+ .number()
280
+ .int()
281
+ .nonnegative()
282
+ .safe()
283
+ .parse(options.offset ?? 0)
284
+ const reader = page(signal, options.maxReadBytes)
285
+ const after = await reader.load(revision)
286
+ const before = revision >= 2 ? await reader.load(revision - 1) : null
287
+ const found = episode(before, after, scope.pursuitId)
288
+ const selected = found?.parts[part]
289
+ if (!selected || !found) return { entry: null, ...reader.counts() }
290
+ if (offset > selected.text.length || !boundary(selected.text, offset))
291
+ throw new Error('Invalid retained text offset; use nextOffset from the previous page.')
292
+ const text = textSlice(selected.text, offset, TEXT_PAGE_CHARS)
293
+ const end = offset + text.length
294
+ return {
295
+ entry: {
296
+ revision,
297
+ part,
298
+ step: found.step,
299
+ claimId: found.claimId,
300
+ kind: found.kind,
301
+ source: selected.source,
302
+ ...(selected.receivedAt !== undefined ? { receivedAt: selected.receivedAt } : {}),
303
+ text,
304
+ offset,
305
+ totalChars: selected.text.length,
306
+ nextOffset: end < selected.text.length ? end : null,
307
+ },
308
+ ...reader.counts(),
309
+ }
310
+ },
311
+ })
312
+ }
@@ -0,0 +1,356 @@
1
+ import { setTimeout as sleep } from 'node:timers/promises'
2
+ import type { ResidentAgendaState, ResidentAgendaStore, ResidentPursuit } from './agenda.js'
3
+ import {
4
+ type ResidentObservation,
5
+ type ResidentSelection,
6
+ type ResidentSelector,
7
+ residentObservationSchema,
8
+ } from './initiative.js'
9
+ import { type ResidentLearningState, freezeResidentLearning } from './learning.js'
10
+ import { type ResidentStep, stepResident } from './loop.js'
11
+ import { type ResidentMessageInput, residentMessageInputSchema } from './outbox.js'
12
+ import { ResidentConflictError, type ResidentDecision, residentDecisionSchema } from './store.js'
13
+
14
+ /** @experimental Host result describes execution, not external-effect rollback. */
15
+ export interface ResidentHostResult {
16
+ readonly status: 'idle' | 'paused' | 'unresolved' | 'cancelled' | 'limit' | 'contended'
17
+ readonly stepsSettled: number
18
+ readonly nextWakeAt: number | null
19
+ readonly selection?: ResidentSelection
20
+ }
21
+
22
+ /** @experimental Explicit authorization to drive a finite number of background steps. */
23
+ export interface ResidentHostRunOptions {
24
+ readonly signal: AbortSignal
25
+ readonly maxSteps: number
26
+ /** Maximum single idle wait; with keepAlive, also bounds local agenda polling. */
27
+ readonly maxIdleMs?: number
28
+ /** Keep waiting for useful work within this invocation's finite step cap. Default false. */
29
+ readonly keepAlive?: boolean
30
+ }
31
+
32
+ /** @experimental Immutable context from the agenda snapshot that authorized this admission. */
33
+ export interface ResidentStepContext {
34
+ readonly agendaRevision: number
35
+ readonly learning?: ResidentLearningState
36
+ }
37
+
38
+ /** @experimental A developer callback may bind a different SDK run for each pursuit. */
39
+ export type ResidentPursuitStep = (
40
+ pursuit: ResidentPursuit,
41
+ signal: AbortSignal,
42
+ ) => ReturnType<ResidentStep>
43
+
44
+ /** @experimental Context-aware callback; existing two-argument steps remain assignable. */
45
+ export type ResidentContextualStep = (
46
+ pursuit: ResidentPursuit,
47
+ signal: AbortSignal,
48
+ context: ResidentStepContext,
49
+ ) => ReturnType<ResidentStep>
50
+
51
+ /** @experimental Inspect actual outcomes and resource receipts independently of model prose. */
52
+ export type ResidentObserver = (
53
+ pursuit: ResidentPursuit,
54
+ decision: ResidentDecision,
55
+ signal: AbortSignal,
56
+ ) => Promise<ResidentObservation>
57
+
58
+ /** @experimental Host validates content and destination; null means no communication. */
59
+ export type ResidentMessageFactory = (
60
+ pursuit: ResidentPursuit,
61
+ decision: ResidentDecision,
62
+ signal: AbortSignal,
63
+ ) => Promise<ResidentMessageInput | null>
64
+
65
+ /** @experimental Opt-in local selection, observed settlement and atomic outbound intent. */
66
+ export interface ResidentHostOptions {
67
+ readonly select?: ResidentSelector
68
+ readonly observe?: ResidentObserver
69
+ readonly prepareMessage?: ResidentMessageFactory
70
+ /** Bind approved learning to the exact admission snapshot. Default false. */
71
+ readonly learning?: boolean
72
+ }
73
+
74
+ /**
75
+ * @experimental Local driver for one durable agenda. Shared agenda admission
76
+ * prevents overlapping pursuits across processes. Notifications are local;
77
+ * opt-in keepAlive also rereads durable state on bounded idle timers.
78
+ */
79
+ export class ResidentHost {
80
+ private controller: AbortController | undefined
81
+ private active: Promise<ResidentHostResult> | undefined
82
+ private idle: AbortController | undefined
83
+ private generation = 0
84
+ private controls: Promise<void> = Promise.resolve()
85
+ private controlsPending = 0
86
+ private readonly options: ResidentHostOptions
87
+
88
+ constructor(
89
+ private readonly agenda: ResidentAgendaStore,
90
+ private readonly step: ResidentContextualStep,
91
+ options: ResidentHostOptions = {},
92
+ ) {
93
+ if (options.learning !== undefined && typeof options.learning !== 'boolean')
94
+ throw new TypeError('Resident learning must be explicitly enabled with a boolean.')
95
+ if ((options.select || options.learning) && !agenda.executionAt)
96
+ throw new TypeError('Resident selection or learning requires atomic executionAt support.')
97
+ if (options.observe && !agenda.settleObserved)
98
+ throw new TypeError('Resident observation requires atomic settleObserved support.')
99
+ if (options.prepareMessage && !agenda.settleWithMessage)
100
+ throw new TypeError('Resident messages require atomic settleWithMessage support.')
101
+ this.options = Object.freeze({ ...options })
102
+ }
103
+
104
+ /** Interrupt local idle waiting after the host learns of new durable state. */
105
+ notify(): void {
106
+ this.generation++
107
+ this.idle?.abort()
108
+ }
109
+
110
+ private async snapshot(): Promise<ResidentAgendaState> {
111
+ const state = await this.agenda.read()
112
+ if (!state) throw new Error('Create the resident agenda before running the host.')
113
+ return state
114
+ }
115
+
116
+ private async paused(value: boolean): Promise<void> {
117
+ for (let attempt = 0; attempt < 8; attempt++) {
118
+ const state = await this.snapshot()
119
+ if (state.paused === value) return
120
+ try {
121
+ await this.agenda.setPaused(state, value)
122
+ return
123
+ } catch (error) {
124
+ if (!(error instanceof ResidentConflictError) || attempt === 7) throw error
125
+ }
126
+ }
127
+ }
128
+
129
+ private control(update: () => Promise<void>): Promise<void> {
130
+ this.controlsPending++
131
+ const pending = this.controls.then(update)
132
+ this.controls = pending.catch(() => {})
133
+ return pending.finally(() => {
134
+ this.controlsPending--
135
+ })
136
+ }
137
+
138
+ /**
139
+ * Signal current work and durably close future admission. Resolving this method
140
+ * is NOT quiescence: await the run promise before claiming the callback stopped.
141
+ * An interrupted admitted pursuit remains unresolved until reconciled explicitly.
142
+ */
143
+ async pause(): Promise<void> {
144
+ this.controller?.abort()
145
+ this.notify()
146
+ await this.control(() => this.paused(true))
147
+ }
148
+
149
+ /** Reauthorize future work only after this host's previous invocation drained. */
150
+ async resume(): Promise<void> {
151
+ if (this.controlsPending) throw new Error('Wait for pending resident controls before resuming.')
152
+ if (this.active)
153
+ throw new Error('Wait for the active resident invocation to drain before resuming.')
154
+ await this.control(() => this.paused(false))
155
+ this.notify()
156
+ }
157
+
158
+ /** Persist fresh evidence and interrupt this host's idle timer. */
159
+ async wake(id: string, reason: string): Promise<void> {
160
+ const state = await this.snapshot()
161
+ const pursuit = state.pursuits.find((p) => p.id === id)
162
+ if (!pursuit) throw new Error('Unknown resident pursuit.')
163
+ await this.agenda.wake(id, pursuit.state, reason, Date.now())
164
+ this.notify()
165
+ }
166
+
167
+ run(options: ResidentHostRunOptions): Promise<ResidentHostResult> {
168
+ if (this.controlsPending) throw new Error('Wait for pending resident controls before running.')
169
+ if (this.active) throw new Error('A resident host invocation is already active.')
170
+ const maxIdleMs = options.maxIdleMs ?? 60_000
171
+ const keepAlive = options.keepAlive ?? false
172
+ if (options.keepAlive !== undefined && typeof options.keepAlive !== 'boolean')
173
+ throw new TypeError('Resident keepAlive must be explicitly enabled with a boolean.')
174
+ if (
175
+ !Number.isSafeInteger(options.maxSteps) ||
176
+ options.maxSteps < 1 ||
177
+ !Number.isSafeInteger(maxIdleMs) ||
178
+ maxIdleMs < 0 ||
179
+ maxIdleMs > 2_147_483_647 ||
180
+ (keepAlive && maxIdleMs === 0)
181
+ )
182
+ throw new TypeError('Invalid resident host limits.')
183
+ const controller = new AbortController()
184
+ this.controller = controller
185
+ const signal = AbortSignal.any([controller.signal, options.signal])
186
+ this.active = this.drive(options.maxSteps, maxIdleMs, keepAlive, signal).finally(() => {
187
+ this.active = undefined
188
+ this.controller = undefined
189
+ this.idle = undefined
190
+ })
191
+ return this.active
192
+ }
193
+
194
+ private async drive(
195
+ maxSteps: number,
196
+ maxIdleMs: number,
197
+ keepAlive: boolean,
198
+ signal: AbortSignal,
199
+ ): Promise<ResidentHostResult> {
200
+ let stepsSettled = 0
201
+ try {
202
+ while (true) {
203
+ signal.throwIfAborted()
204
+ const observed = this.generation
205
+ const state = await this.snapshot()
206
+ signal.throwIfAborted()
207
+ if (state.paused) return { status: 'paused', stepsSettled, nextWakeAt: null }
208
+ if (state.pursuits.some((p) => p.state.phase === 'running'))
209
+ return { status: 'unresolved', stepsSettled, nextWakeAt: null }
210
+ const waiting = state.pursuits.filter(
211
+ (p) => p.state.phase === 'waiting' && p.state.wakeAt !== null,
212
+ )
213
+ const now = Date.now()
214
+ // Fair, deterministic baseline; this is not model-authored initiative.
215
+ let due = waiting
216
+ .filter((p) => (p.state.wakeAt ?? 0) <= now)
217
+ .sort(
218
+ (a, b) =>
219
+ a.state.stepsAdmitted - b.state.stepsAdmitted ||
220
+ (a.state.wakeAt ?? 0) - (b.state.wakeAt ?? 0) ||
221
+ a.id.localeCompare(b.id),
222
+ )[0]
223
+ let selection: ResidentSelection | undefined
224
+ if (due && this.options.select) {
225
+ selection = this.options.select(state, now)
226
+ signal.throwIfAborted()
227
+ if (selection.agendaRevision !== state.revision)
228
+ throw new Error('Resident selector returned a stale agenda revision.')
229
+ if (selection.pursuitId === null) due = undefined
230
+ else {
231
+ const selectedId = selection.pursuitId
232
+ due = waiting.find((p) => p.id === selectedId && (p.state.wakeAt ?? 0) <= now)
233
+ if (!due) throw new Error('Resident selector chose an ineligible pursuit.')
234
+ }
235
+ }
236
+
237
+ if (due) {
238
+ const selected = due
239
+ const context: ResidentStepContext = Object.freeze({
240
+ agendaRevision: state.revision,
241
+ ...(this.options.learning && state.learning
242
+ ? { learning: freezeResidentLearning(state.learning) }
243
+ : {}),
244
+ })
245
+ const execution =
246
+ this.options.select || this.options.learning
247
+ ? this.agenda.executionAt?.(selected.id, state)
248
+ : this.agenda.execution(selected.id)
249
+ if (!execution) throw new Error('Resident executionAt support was removed.')
250
+ const observe = this.options.observe
251
+ const prepareMessage = this.options.prepareMessage
252
+ const observedExecution =
253
+ observe || prepareMessage
254
+ ? {
255
+ read: () => execution.read(),
256
+ claim: (...args: Parameters<typeof execution.claim>) => execution.claim(...args),
257
+ settle: async (
258
+ current: Parameters<typeof execution.settle>[0],
259
+ decision: ResidentDecision,
260
+ at: number,
261
+ ) => {
262
+ const disposition = Object.freeze(residentDecisionSchema.parse(decision))
263
+ const observed = await observe?.(
264
+ { ...selected, state: current },
265
+ disposition,
266
+ signal,
267
+ )
268
+ signal.throwIfAborted()
269
+ const observation = observe
270
+ ? Object.freeze(residentObservationSchema.parse(observed))
271
+ : undefined
272
+ const prepared = await prepareMessage?.(
273
+ { ...selected, state: current },
274
+ disposition,
275
+ signal,
276
+ )
277
+ signal.throwIfAborted()
278
+ const message =
279
+ prepareMessage && prepared !== null
280
+ ? Object.freeze(residentMessageInputSchema.parse(prepared))
281
+ : null
282
+ if (message !== null) {
283
+ if (!this.agenda.settleWithMessage)
284
+ throw new Error('Resident settleWithMessage support was removed.')
285
+ return this.agenda.settleWithMessage(
286
+ selected.id,
287
+ current,
288
+ disposition,
289
+ message,
290
+ at,
291
+ observation,
292
+ )
293
+ }
294
+ if (observation) {
295
+ if (!this.agenda.settleObserved)
296
+ throw new Error('Resident settleObserved support was removed.')
297
+ return this.agenda.settleObserved(
298
+ selected.id,
299
+ current,
300
+ disposition,
301
+ observation,
302
+ at,
303
+ )
304
+ }
305
+ return execution.settle(current, disposition, at)
306
+ },
307
+ }
308
+ : execution
309
+ const result = await stepResident(
310
+ observedExecution,
311
+ (current, abort) => this.step({ ...selected, state: current }, abort, context),
312
+ signal,
313
+ )
314
+ if (result.status === 'idle')
315
+ return {
316
+ status: result.reason === 'unresolved' ? 'unresolved' : 'contended',
317
+ stepsSettled,
318
+ nextWakeAt: null,
319
+ }
320
+ stepsSettled++
321
+ if (stepsSettled >= maxSteps) return { status: 'limit', stepsSettled, nextWakeAt: null }
322
+ continue
323
+ }
324
+ const scheduled =
325
+ selection?.pursuitId === null
326
+ ? waiting.filter((p) => (p.state.wakeAt ?? 0) > now)
327
+ : waiting
328
+ const nextWakeAt =
329
+ scheduled.length === 0 ? null : Math.min(...scheduled.map((p) => p.state.wakeAt ?? now))
330
+ if (observed !== this.generation) continue
331
+ if (!keepAlive && (nextWakeAt === null || nextWakeAt - now > maxIdleMs))
332
+ return { status: 'idle', stepsSettled, nextWakeAt, ...(selection ? { selection } : {}) }
333
+ const delay =
334
+ nextWakeAt === null
335
+ ? maxIdleMs
336
+ : keepAlive
337
+ ? Math.min(maxIdleMs, nextWakeAt - now)
338
+ : nextWakeAt - now
339
+ const idle = new AbortController()
340
+ this.idle = idle
341
+ try {
342
+ await sleep(Math.max(1, delay), undefined, {
343
+ signal: AbortSignal.any([signal, idle.signal]),
344
+ })
345
+ } catch (error) {
346
+ if (!idle.signal.aborted || signal.aborted) throw error
347
+ } finally {
348
+ if (this.idle === idle) this.idle = undefined
349
+ }
350
+ }
351
+ } catch (error) {
352
+ if (!signal.aborted) throw error
353
+ return { status: 'cancelled', stepsSettled, nextWakeAt: null }
354
+ }
355
+ }
356
+ }