@draht/agent-core 2026.7.30 → 2026.10.4-2

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 (456) hide show
  1. package/dist/agent-loop.d.ts +27 -2
  2. package/dist/agent-loop.d.ts.map +1 -1
  3. package/dist/agent-loop.js +181 -63
  4. package/dist/agent-loop.js.map +1 -1
  5. package/dist/agent.d.ts +14 -4
  6. package/dist/agent.d.ts.map +1 -1
  7. package/dist/agent.js +68 -19
  8. package/dist/agent.js.map +1 -1
  9. package/dist/harness/agent-harness.d.ts +713 -91
  10. package/dist/harness/agent-harness.d.ts.map +1 -1
  11. package/dist/harness/agent-harness.js +5 -950
  12. package/dist/harness/agent-harness.js.map +1 -1
  13. package/dist/harness/compaction/branch-summarization.d.ts +23 -10
  14. package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
  15. package/dist/harness/compaction/branch-summarization.js +39 -36
  16. package/dist/harness/compaction/branch-summarization.js.map +1 -1
  17. package/dist/harness/compaction/compaction.d.ts +37 -18
  18. package/dist/harness/compaction/compaction.d.ts.map +1 -1
  19. package/dist/harness/compaction/compaction.js +74 -97
  20. package/dist/harness/compaction/compaction.js.map +1 -1
  21. package/dist/harness/config.d.ts +9 -0
  22. package/dist/harness/config.d.ts.map +1 -0
  23. package/dist/harness/config.js +35 -0
  24. package/dist/harness/config.js.map +1 -0
  25. package/dist/harness/context.d.ts +9 -0
  26. package/dist/harness/context.d.ts.map +1 -0
  27. package/dist/harness/context.js +13 -0
  28. package/dist/harness/context.js.map +1 -0
  29. package/dist/harness/env/nodejs.d.ts +25 -27
  30. package/dist/harness/env/nodejs.d.ts.map +1 -1
  31. package/dist/harness/env/nodejs.js +355 -110
  32. package/dist/harness/env/nodejs.js.map +1 -1
  33. package/dist/harness/events.d.ts +24 -0
  34. package/dist/harness/events.d.ts.map +1 -0
  35. package/dist/harness/events.js +233 -0
  36. package/dist/harness/events.js.map +1 -0
  37. package/dist/harness/execution/assistant.d.ts +42 -0
  38. package/dist/harness/execution/assistant.d.ts.map +1 -0
  39. package/dist/harness/execution/assistant.js +82 -0
  40. package/dist/harness/execution/assistant.js.map +1 -0
  41. package/dist/harness/execution/effect-gate.d.ts +22 -0
  42. package/dist/harness/execution/effect-gate.d.ts.map +1 -0
  43. package/dist/harness/execution/effect-gate.js +49 -0
  44. package/dist/harness/execution/effect-gate.js.map +1 -0
  45. package/dist/harness/execution/tools.d.ts +67 -0
  46. package/dist/harness/execution/tools.d.ts.map +1 -0
  47. package/dist/harness/execution/tools.js +119 -0
  48. package/dist/harness/execution/tools.js.map +1 -0
  49. package/dist/harness/hooks.d.ts +38 -0
  50. package/dist/harness/hooks.d.ts.map +1 -0
  51. package/dist/harness/hooks.js +406 -0
  52. package/dist/harness/hooks.js.map +1 -0
  53. package/dist/harness/messages.d.ts +4 -4
  54. package/dist/harness/messages.d.ts.map +1 -1
  55. package/dist/harness/messages.js +4 -3
  56. package/dist/harness/messages.js.map +1 -1
  57. package/dist/harness/pico3/bash.d.ts +10 -0
  58. package/dist/harness/pico3/bash.d.ts.map +1 -0
  59. package/dist/harness/pico3/bash.js +25 -0
  60. package/dist/harness/pico3/bash.js.map +1 -0
  61. package/dist/harness/pico3/bounded.d.ts +21 -0
  62. package/dist/harness/pico3/bounded.d.ts.map +1 -0
  63. package/dist/harness/pico3/bounded.js +98 -0
  64. package/dist/harness/pico3/bounded.js.map +1 -0
  65. package/dist/harness/pico3/chord.d.ts +41 -0
  66. package/dist/harness/pico3/chord.d.ts.map +1 -0
  67. package/dist/harness/pico3/chord.js +147 -0
  68. package/dist/harness/pico3/chord.js.map +1 -0
  69. package/dist/harness/pico3/context.d.ts +16 -0
  70. package/dist/harness/pico3/context.d.ts.map +1 -0
  71. package/dist/harness/pico3/context.js +88 -0
  72. package/dist/harness/pico3/context.js.map +1 -0
  73. package/dist/harness/pico3/harness.d.ts +198 -0
  74. package/dist/harness/pico3/harness.d.ts.map +1 -0
  75. package/dist/harness/pico3/harness.js +654 -0
  76. package/dist/harness/pico3/harness.js.map +1 -0
  77. package/dist/harness/pico3/hooks.d.ts +10 -0
  78. package/dist/harness/pico3/hooks.d.ts.map +1 -0
  79. package/dist/harness/pico3/hooks.js +33 -0
  80. package/dist/harness/pico3/hooks.js.map +1 -0
  81. package/dist/harness/pico3/index.d.ts +19 -0
  82. package/dist/harness/pico3/index.d.ts.map +1 -0
  83. package/dist/harness/pico3/index.js +15 -0
  84. package/dist/harness/pico3/index.js.map +1 -0
  85. package/dist/harness/pico3/jsonl.d.ts +58 -0
  86. package/dist/harness/pico3/jsonl.d.ts.map +1 -0
  87. package/dist/harness/pico3/jsonl.js +325 -0
  88. package/dist/harness/pico3/jsonl.js.map +1 -0
  89. package/dist/harness/pico3/kinds/collapse.d.ts +49 -0
  90. package/dist/harness/pico3/kinds/collapse.d.ts.map +1 -0
  91. package/dist/harness/pico3/kinds/collapse.js +191 -0
  92. package/dist/harness/pico3/kinds/collapse.js.map +1 -0
  93. package/dist/harness/pico3/kinds/entries.d.ts +78 -0
  94. package/dist/harness/pico3/kinds/entries.d.ts.map +1 -0
  95. package/dist/harness/pico3/kinds/entries.js +13 -0
  96. package/dist/harness/pico3/kinds/entries.js.map +1 -0
  97. package/dist/harness/pico3/kinds/frames.d.ts +9 -0
  98. package/dist/harness/pico3/kinds/frames.d.ts.map +1 -0
  99. package/dist/harness/pico3/kinds/frames.js +75 -0
  100. package/dist/harness/pico3/kinds/frames.js.map +1 -0
  101. package/dist/harness/pico3/kinds/generation.d.ts +94 -0
  102. package/dist/harness/pico3/kinds/generation.d.ts.map +1 -0
  103. package/dist/harness/pico3/kinds/generation.js +504 -0
  104. package/dist/harness/pico3/kinds/generation.js.map +1 -0
  105. package/dist/harness/pico3/kinds/job.d.ts +44 -0
  106. package/dist/harness/pico3/kinds/job.d.ts.map +1 -0
  107. package/dist/harness/pico3/kinds/job.js +143 -0
  108. package/dist/harness/pico3/kinds/job.js.map +1 -0
  109. package/dist/harness/pico3/kinds/plugin.d.ts +15 -0
  110. package/dist/harness/pico3/kinds/plugin.d.ts.map +1 -0
  111. package/dist/harness/pico3/kinds/plugin.js +35 -0
  112. package/dist/harness/pico3/kinds/plugin.js.map +1 -0
  113. package/dist/harness/pico3/kinds/post-tools.d.ts +22 -0
  114. package/dist/harness/pico3/kinds/post-tools.d.ts.map +1 -0
  115. package/dist/harness/pico3/kinds/post-tools.js +145 -0
  116. package/dist/harness/pico3/kinds/post-tools.js.map +1 -0
  117. package/dist/harness/pico3/kinds/task-api.d.ts +3 -0
  118. package/dist/harness/pico3/kinds/task-api.d.ts.map +1 -0
  119. package/dist/harness/pico3/kinds/task-api.js +45 -0
  120. package/dist/harness/pico3/kinds/task-api.js.map +1 -0
  121. package/dist/harness/pico3/kinds/tool.d.ts +43 -0
  122. package/dist/harness/pico3/kinds/tool.d.ts.map +1 -0
  123. package/dist/harness/pico3/kinds/tool.js +373 -0
  124. package/dist/harness/pico3/kinds/tool.js.map +1 -0
  125. package/dist/harness/pico3/legacy-tracker.d.ts +11 -0
  126. package/dist/harness/pico3/legacy-tracker.d.ts.map +1 -0
  127. package/dist/harness/pico3/legacy-tracker.js +41 -0
  128. package/dist/harness/pico3/legacy-tracker.js.map +1 -0
  129. package/dist/harness/pico3/membrane.d.ts +23 -0
  130. package/dist/harness/pico3/membrane.d.ts.map +1 -0
  131. package/dist/harness/pico3/membrane.js +141 -0
  132. package/dist/harness/pico3/membrane.js.map +1 -0
  133. package/dist/harness/pico3/memory.d.ts +53 -0
  134. package/dist/harness/pico3/memory.d.ts.map +1 -0
  135. package/dist/harness/pico3/memory.js +264 -0
  136. package/dist/harness/pico3/memory.js.map +1 -0
  137. package/dist/harness/pico3/scheduler.d.ts +49 -0
  138. package/dist/harness/pico3/scheduler.d.ts.map +1 -0
  139. package/dist/harness/pico3/scheduler.js +438 -0
  140. package/dist/harness/pico3/scheduler.js.map +1 -0
  141. package/dist/harness/pico3/session.d.ts +264 -0
  142. package/dist/harness/pico3/session.d.ts.map +1 -0
  143. package/dist/harness/pico3/session.js +1348 -0
  144. package/dist/harness/pico3/session.js.map +1 -0
  145. package/dist/harness/pico3/system.d.ts +126 -0
  146. package/dist/harness/pico3/system.d.ts.map +1 -0
  147. package/dist/harness/pico3/system.js +244 -0
  148. package/dist/harness/pico3/system.js.map +1 -0
  149. package/dist/harness/pico3/types.d.ts +973 -0
  150. package/dist/harness/pico3/types.d.ts.map +1 -0
  151. package/dist/harness/pico3/types.js +106 -0
  152. package/dist/harness/pico3/types.js.map +1 -0
  153. package/dist/harness/pico3/view.d.ts +34 -0
  154. package/dist/harness/pico3/view.d.ts.map +1 -0
  155. package/dist/harness/pico3/view.js +411 -0
  156. package/dist/harness/pico3/view.js.map +1 -0
  157. package/dist/harness/prompt-templates.d.ts +3 -2
  158. package/dist/harness/prompt-templates.d.ts.map +1 -1
  159. package/dist/harness/prompt-templates.js +18 -23
  160. package/dist/harness/prompt-templates.js.map +1 -1
  161. package/dist/harness/result.d.ts +133 -0
  162. package/dist/harness/result.d.ts.map +1 -0
  163. package/dist/harness/result.js +81 -0
  164. package/dist/harness/result.js.map +1 -0
  165. package/dist/harness/runtime/drive/boundary.d.ts +28 -0
  166. package/dist/harness/runtime/drive/boundary.d.ts.map +1 -0
  167. package/dist/harness/runtime/drive/boundary.js +173 -0
  168. package/dist/harness/runtime/drive/boundary.js.map +1 -0
  169. package/dist/harness/runtime/drive/checkpoint.d.ts +8 -0
  170. package/dist/harness/runtime/drive/checkpoint.d.ts.map +1 -0
  171. package/dist/harness/runtime/drive/checkpoint.js +133 -0
  172. package/dist/harness/runtime/drive/checkpoint.js.map +1 -0
  173. package/dist/harness/runtime/drive/deferred.d.ts +15 -0
  174. package/dist/harness/runtime/drive/deferred.d.ts.map +1 -0
  175. package/dist/harness/runtime/drive/deferred.js +179 -0
  176. package/dist/harness/runtime/drive/deferred.js.map +1 -0
  177. package/dist/harness/runtime/drive/generation.d.ts +8 -0
  178. package/dist/harness/runtime/drive/generation.d.ts.map +1 -0
  179. package/dist/harness/runtime/drive/generation.js +205 -0
  180. package/dist/harness/runtime/drive/generation.js.map +1 -0
  181. package/dist/harness/runtime/drive/reconcile.d.ts +5 -0
  182. package/dist/harness/runtime/drive/reconcile.d.ts.map +1 -0
  183. package/dist/harness/runtime/drive/reconcile.js +140 -0
  184. package/dist/harness/runtime/drive/reconcile.js.map +1 -0
  185. package/dist/harness/runtime/drive/recovery.d.ts +8 -0
  186. package/dist/harness/runtime/drive/recovery.d.ts.map +1 -0
  187. package/dist/harness/runtime/drive/recovery.js +85 -0
  188. package/dist/harness/runtime/drive/recovery.js.map +1 -0
  189. package/dist/harness/runtime/drive/response.d.ts +23 -0
  190. package/dist/harness/runtime/drive/response.d.ts.map +1 -0
  191. package/dist/harness/runtime/drive/response.js +394 -0
  192. package/dist/harness/runtime/drive/response.js.map +1 -0
  193. package/dist/harness/runtime/drive/retry.d.ts +4 -0
  194. package/dist/harness/runtime/drive/retry.d.ts.map +1 -0
  195. package/dist/harness/runtime/drive/retry.js +34 -0
  196. package/dist/harness/runtime/drive/retry.js.map +1 -0
  197. package/dist/harness/runtime/drive/structural.d.ts +32 -0
  198. package/dist/harness/runtime/drive/structural.d.ts.map +1 -0
  199. package/dist/harness/runtime/drive/structural.js +929 -0
  200. package/dist/harness/runtime/drive/structural.js.map +1 -0
  201. package/dist/harness/runtime/drive/terminal.d.ts +7 -0
  202. package/dist/harness/runtime/drive/terminal.d.ts.map +1 -0
  203. package/dist/harness/runtime/drive/terminal.js +49 -0
  204. package/dist/harness/runtime/drive/terminal.js.map +1 -0
  205. package/dist/harness/runtime/drive/tool-placement.d.ts +14 -0
  206. package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -0
  207. package/dist/harness/runtime/drive/tool-placement.js +219 -0
  208. package/dist/harness/runtime/drive/tool-placement.js.map +1 -0
  209. package/dist/harness/runtime/drive/tools.d.ts +6 -0
  210. package/dist/harness/runtime/drive/tools.d.ts.map +1 -0
  211. package/dist/harness/runtime/drive/tools.js +449 -0
  212. package/dist/harness/runtime/drive/tools.js.map +1 -0
  213. package/dist/harness/runtime/drive.d.ts +6 -0
  214. package/dist/harness/runtime/drive.d.ts.map +1 -0
  215. package/dist/harness/runtime/drive.js +93 -0
  216. package/dist/harness/runtime/drive.js.map +1 -0
  217. package/dist/harness/runtime/harness.d.ts +59 -0
  218. package/dist/harness/runtime/harness.d.ts.map +1 -0
  219. package/dist/harness/runtime/harness.js +311 -0
  220. package/dist/harness/runtime/harness.js.map +1 -0
  221. package/dist/harness/runtime/index.d.ts +2 -0
  222. package/dist/harness/runtime/index.d.ts.map +1 -0
  223. package/dist/harness/runtime/index.js +2 -0
  224. package/dist/harness/runtime/index.js.map +1 -0
  225. package/dist/harness/runtime/lane.d.ts +118 -0
  226. package/dist/harness/runtime/lane.d.ts.map +1 -0
  227. package/dist/harness/runtime/lane.js +1575 -0
  228. package/dist/harness/runtime/lane.js.map +1 -0
  229. package/dist/harness/runtime/progress.d.ts +15 -0
  230. package/dist/harness/runtime/progress.d.ts.map +1 -0
  231. package/dist/harness/runtime/progress.js +66 -0
  232. package/dist/harness/runtime/progress.js.map +1 -0
  233. package/dist/harness/runtime/reducer.d.ts +5 -0
  234. package/dist/harness/runtime/reducer.d.ts.map +1 -0
  235. package/dist/harness/runtime/reducer.js +240 -0
  236. package/dist/harness/runtime/reducer.js.map +1 -0
  237. package/dist/harness/runtime/restore.d.ts +24 -0
  238. package/dist/harness/runtime/restore.d.ts.map +1 -0
  239. package/dist/harness/runtime/restore.js +117 -0
  240. package/dist/harness/runtime/restore.js.map +1 -0
  241. package/dist/harness/runtime/transcript.d.ts +21 -0
  242. package/dist/harness/runtime/transcript.d.ts.map +1 -0
  243. package/dist/harness/runtime/transcript.js +72 -0
  244. package/dist/harness/runtime/transcript.js.map +1 -0
  245. package/dist/harness/runtime/types.d.ts +105 -0
  246. package/dist/harness/runtime/types.d.ts.map +1 -0
  247. package/dist/harness/runtime/types.js +61 -0
  248. package/dist/harness/runtime/types.js.map +1 -0
  249. package/dist/harness/session/commit.d.ts +53 -0
  250. package/dist/harness/session/commit.d.ts.map +1 -0
  251. package/dist/harness/session/commit.js +57 -0
  252. package/dist/harness/session/commit.js.map +1 -0
  253. package/dist/harness/session/context.d.ts +10 -0
  254. package/dist/harness/session/context.d.ts.map +1 -0
  255. package/dist/harness/session/context.js +49 -0
  256. package/dist/harness/session/context.js.map +1 -0
  257. package/dist/harness/session/fork-policy.d.ts +21 -0
  258. package/dist/harness/session/fork-policy.d.ts.map +1 -0
  259. package/dist/harness/session/fork-policy.js +55 -0
  260. package/dist/harness/session/fork-policy.js.map +1 -0
  261. package/dist/harness/session/fork.d.ts +16 -0
  262. package/dist/harness/session/fork.d.ts.map +1 -0
  263. package/dist/harness/session/fork.js +79 -0
  264. package/dist/harness/session/fork.js.map +1 -0
  265. package/dist/harness/session/in-memory-storage-state.d.ts +39 -0
  266. package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -0
  267. package/dist/harness/session/in-memory-storage-state.js +276 -0
  268. package/dist/harness/session/in-memory-storage-state.js.map +1 -0
  269. package/dist/harness/session/index.d.ts +11 -0
  270. package/dist/harness/session/index.d.ts.map +1 -0
  271. package/dist/harness/session/index.js +9 -0
  272. package/dist/harness/session/index.js.map +1 -0
  273. package/dist/harness/session/jsonl/codec.d.ts +21 -0
  274. package/dist/harness/session/jsonl/codec.d.ts.map +1 -0
  275. package/dist/harness/session/jsonl/codec.js +45 -0
  276. package/dist/harness/session/jsonl/codec.js.map +1 -0
  277. package/dist/harness/session/jsonl/fork.d.ts +38 -0
  278. package/dist/harness/session/jsonl/fork.d.ts.map +1 -0
  279. package/dist/harness/session/jsonl/fork.js +264 -0
  280. package/dist/harness/session/jsonl/fork.js.map +1 -0
  281. package/dist/harness/session/jsonl/index.d.ts +4 -0
  282. package/dist/harness/session/jsonl/index.d.ts.map +1 -0
  283. package/dist/harness/session/jsonl/index.js +4 -0
  284. package/dist/harness/session/jsonl/index.js.map +1 -0
  285. package/dist/harness/session/jsonl/io.d.ts +14 -0
  286. package/dist/harness/session/jsonl/io.d.ts.map +1 -0
  287. package/dist/harness/session/jsonl/io.js +86 -0
  288. package/dist/harness/session/jsonl/io.js.map +1 -0
  289. package/dist/harness/session/jsonl/legacy-v3.d.ts +44 -0
  290. package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -0
  291. package/dist/harness/session/jsonl/legacy-v3.js +462 -0
  292. package/dist/harness/session/jsonl/legacy-v3.js.map +1 -0
  293. package/dist/harness/session/jsonl/repo.d.ts +35 -0
  294. package/dist/harness/session/jsonl/repo.d.ts.map +1 -0
  295. package/dist/harness/session/jsonl/repo.js +301 -0
  296. package/dist/harness/session/jsonl/repo.js.map +1 -0
  297. package/dist/harness/session/jsonl/storage.d.ts +41 -0
  298. package/dist/harness/session/jsonl/storage.d.ts.map +1 -0
  299. package/dist/harness/session/jsonl/storage.js +200 -0
  300. package/dist/harness/session/jsonl/storage.js.map +1 -0
  301. package/dist/harness/session/jsonl/types.d.ts +39 -0
  302. package/dist/harness/session/jsonl/types.d.ts.map +1 -0
  303. package/dist/harness/session/jsonl/types.js +3 -0
  304. package/dist/harness/session/jsonl/types.js.map +1 -0
  305. package/dist/harness/session/memory.d.ts +48 -0
  306. package/dist/harness/session/memory.d.ts.map +1 -0
  307. package/dist/harness/session/memory.js +369 -0
  308. package/dist/harness/session/memory.js.map +1 -0
  309. package/dist/harness/session/mutation-line.d.ts +8 -0
  310. package/dist/harness/session/mutation-line.d.ts.map +1 -0
  311. package/dist/harness/session/mutation-line.js +21 -0
  312. package/dist/harness/session/mutation-line.js.map +1 -0
  313. package/dist/harness/session/session.d.ts +79 -46
  314. package/dist/harness/session/session.d.ts.map +1 -1
  315. package/dist/harness/session/session.js +320 -220
  316. package/dist/harness/session/session.js.map +1 -1
  317. package/dist/harness/session/testing/benchmark/datasets.d.ts +12 -0
  318. package/dist/harness/session/testing/benchmark/datasets.d.ts.map +1 -0
  319. package/dist/harness/session/testing/benchmark/datasets.js +24 -0
  320. package/dist/harness/session/testing/benchmark/datasets.js.map +1 -0
  321. package/dist/harness/session/testing/benchmark/session-repo.d.ts +42 -0
  322. package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +1 -0
  323. package/dist/harness/session/testing/benchmark/session-repo.js +127 -0
  324. package/dist/harness/session/testing/benchmark/session-repo.js.map +1 -0
  325. package/dist/harness/session/testing/benchmark/storage.d.ts +25 -0
  326. package/dist/harness/session/testing/benchmark/storage.d.ts.map +1 -0
  327. package/dist/harness/session/testing/benchmark/storage.js +114 -0
  328. package/dist/harness/session/testing/benchmark/storage.js.map +1 -0
  329. package/dist/harness/session/testing/conformance/session-repo.d.ts +23 -0
  330. package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -0
  331. package/dist/harness/session/testing/conformance/session-repo.js +809 -0
  332. package/dist/harness/session/testing/conformance/session-repo.js.map +1 -0
  333. package/dist/harness/session/testing/conformance/storage.d.ts +4 -0
  334. package/dist/harness/session/testing/conformance/storage.d.ts.map +1 -0
  335. package/dist/harness/session/testing/conformance/storage.js +600 -0
  336. package/dist/harness/session/testing/conformance/storage.js.map +1 -0
  337. package/dist/harness/session/testing/gating-storage.d.ts +26 -0
  338. package/dist/harness/session/testing/gating-storage.d.ts.map +1 -0
  339. package/dist/harness/session/testing/gating-storage.js +100 -0
  340. package/dist/harness/session/testing/gating-storage.js.map +1 -0
  341. package/dist/harness/session/testing/index.d.ts +10 -0
  342. package/dist/harness/session/testing/index.d.ts.map +1 -0
  343. package/dist/harness/session/testing/index.js +9 -0
  344. package/dist/harness/session/testing/index.js.map +1 -0
  345. package/dist/harness/session/testing/instrumented-storage.d.ts +11 -0
  346. package/dist/harness/session/testing/instrumented-storage.d.ts.map +1 -0
  347. package/dist/harness/session/testing/instrumented-storage.js +16 -0
  348. package/dist/harness/session/testing/instrumented-storage.js.map +1 -0
  349. package/dist/harness/session/testing/storage-decorator.d.ts +20 -0
  350. package/dist/harness/session/testing/storage-decorator.d.ts.map +1 -0
  351. package/dist/harness/session/testing/storage-decorator.js +41 -0
  352. package/dist/harness/session/testing/storage-decorator.js.map +1 -0
  353. package/dist/harness/session/testing/types.d.ts +12 -0
  354. package/dist/harness/session/testing/types.d.ts.map +1 -0
  355. package/dist/harness/session/testing/types.js +2 -0
  356. package/dist/harness/session/testing/types.js.map +1 -0
  357. package/dist/harness/session/types.d.ts +512 -0
  358. package/dist/harness/session/types.d.ts.map +1 -0
  359. package/dist/harness/session/types.js +9 -0
  360. package/dist/harness/session/types.js.map +1 -0
  361. package/dist/harness/session/values.d.ts +95 -0
  362. package/dist/harness/session/values.d.ts.map +1 -0
  363. package/dist/harness/session/values.js +81 -0
  364. package/dist/harness/session/values.js.map +1 -0
  365. package/dist/harness/skills.d.ts +6 -4
  366. package/dist/harness/skills.d.ts.map +1 -1
  367. package/dist/harness/skills.js +59 -44
  368. package/dist/harness/skills.js.map +1 -1
  369. package/dist/harness/telemetry.d.ts +1242 -0
  370. package/dist/harness/telemetry.d.ts.map +1 -0
  371. package/dist/harness/telemetry.js +527 -0
  372. package/dist/harness/telemetry.js.map +1 -0
  373. package/dist/harness/tools/bash.d.ts +4 -4
  374. package/dist/harness/tools/bash.d.ts.map +1 -1
  375. package/dist/harness/tools/bash.js +66 -93
  376. package/dist/harness/tools/bash.js.map +1 -1
  377. package/dist/harness/tools/edit.d.ts.map +1 -1
  378. package/dist/harness/tools/edit.js +24 -11
  379. package/dist/harness/tools/edit.js.map +1 -1
  380. package/dist/harness/tools/file-mutation-queue.d.ts +2 -1
  381. package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -1
  382. package/dist/harness/tools/file-mutation-queue.js +5 -5
  383. package/dist/harness/tools/file-mutation-queue.js.map +1 -1
  384. package/dist/harness/tools/image.js +1 -1
  385. package/dist/harness/tools/image.js.map +1 -1
  386. package/dist/harness/tools/path-utils.d.ts +3 -2
  387. package/dist/harness/tools/path-utils.d.ts.map +1 -1
  388. package/dist/harness/tools/path-utils.js +5 -5
  389. package/dist/harness/tools/path-utils.js.map +1 -1
  390. package/dist/harness/tools/read.d.ts +2 -1
  391. package/dist/harness/tools/read.d.ts.map +1 -1
  392. package/dist/harness/tools/read.js +4 -6
  393. package/dist/harness/tools/read.js.map +1 -1
  394. package/dist/harness/tools/write.d.ts.map +1 -1
  395. package/dist/harness/tools/write.js +7 -7
  396. package/dist/harness/tools/write.js.map +1 -1
  397. package/dist/harness/types.d.ts +126 -502
  398. package/dist/harness/types.d.ts.map +1 -1
  399. package/dist/harness/types.js +10 -16
  400. package/dist/harness/types.js.map +1 -1
  401. package/dist/harness/utils/adaptive-publisher.d.ts +24 -0
  402. package/dist/harness/utils/adaptive-publisher.d.ts.map +1 -0
  403. package/dist/harness/utils/adaptive-publisher.js +79 -0
  404. package/dist/harness/utils/adaptive-publisher.js.map +1 -0
  405. package/dist/harness/utils/output-capture.d.ts +31 -0
  406. package/dist/harness/utils/output-capture.d.ts.map +1 -0
  407. package/dist/harness/utils/output-capture.js +217 -0
  408. package/dist/harness/utils/output-capture.js.map +1 -0
  409. package/dist/harness/utils/shell-output.d.ts +12 -5
  410. package/dist/harness/utils/shell-output.d.ts.map +1 -1
  411. package/dist/harness/utils/shell-output.js +64 -174
  412. package/dist/harness/utils/shell-output.js.map +1 -1
  413. package/dist/harness/utils/truncate.d.ts +1 -0
  414. package/dist/harness/utils/truncate.d.ts.map +1 -1
  415. package/dist/harness/utils/truncate.js +1 -1
  416. package/dist/harness/utils/truncate.js.map +1 -1
  417. package/dist/harness/utils/usage.d.ts +4 -0
  418. package/dist/harness/utils/usage.d.ts.map +1 -0
  419. package/dist/harness/utils/usage.js +33 -0
  420. package/dist/harness/utils/usage.js.map +1 -0
  421. package/dist/index.d.ts +13 -9
  422. package/dist/index.d.ts.map +1 -1
  423. package/dist/index.js +9 -13
  424. package/dist/index.js.map +1 -1
  425. package/dist/proxy.d.ts +6 -3
  426. package/dist/proxy.d.ts.map +1 -1
  427. package/dist/proxy.js +42 -10
  428. package/dist/proxy.js.map +1 -1
  429. package/dist/search/index.d.ts +29 -0
  430. package/dist/search/index.d.ts.map +1 -0
  431. package/dist/search/index.js +2 -0
  432. package/dist/search/index.js.map +1 -0
  433. package/dist/types.d.ts +113 -31
  434. package/dist/types.d.ts.map +1 -1
  435. package/dist/types.js.map +1 -1
  436. package/package.json +50 -4
  437. package/dist/harness/session/jsonl-repo.d.ts +0 -26
  438. package/dist/harness/session/jsonl-repo.d.ts.map +0 -1
  439. package/dist/harness/session/jsonl-repo.js +0 -100
  440. package/dist/harness/session/jsonl-repo.js.map +0 -1
  441. package/dist/harness/session/jsonl-storage.d.ts +0 -42
  442. package/dist/harness/session/jsonl-storage.d.ts.map +0 -1
  443. package/dist/harness/session/jsonl-storage.js +0 -286
  444. package/dist/harness/session/jsonl-storage.js.map +0 -1
  445. package/dist/harness/session/memory-repo.d.ts +0 -18
  446. package/dist/harness/session/memory-repo.d.ts.map +0 -1
  447. package/dist/harness/session/memory-repo.js +0 -44
  448. package/dist/harness/session/memory-repo.js.map +0 -1
  449. package/dist/harness/session/memory-storage.d.ts +0 -33
  450. package/dist/harness/session/memory-storage.d.ts.map +0 -1
  451. package/dist/harness/session/memory-storage.js +0 -163
  452. package/dist/harness/session/memory-storage.js.map +0 -1
  453. package/dist/harness/session/repo-utils.d.ts +0 -11
  454. package/dist/harness/session/repo-utils.d.ts.map +0 -1
  455. package/dist/harness/session/repo-utils.js +0 -39
  456. package/dist/harness/session/repo-utils.js.map +0 -1
@@ -0,0 +1,133 @@
1
+ import { insertEntry } from "../../session/commit.js";
2
+ import { SessionInvariantError } from "../../session/session.js";
3
+ import { operationScopeOf, } from "../../session/types.js";
4
+ import { branchTip, operationPreparation, setValue } from "../../session/values.js";
5
+ import { chainEntries, committedEntryEvents } from "../transcript.js";
6
+ import { assistantReadyAtBoundary, boundaryPlacementEvents, finishRunBoundary, planBoundaryInbox, } from "./boundary.js";
7
+ import { prepareCompactionThreshold } from "./structural.js";
8
+ /** Consume before_run and commit the initial checkpoint. */
9
+ export async function startRun(lane, drive, run) {
10
+ const prompt = await lane.continueOperation(run, async (_state, _current, meta, reader) => {
11
+ if (meta.intent.kind !== "run")
12
+ throw new SessionInvariantError("Run operation has non-run intent");
13
+ const entries = await reader.getEntries(meta.intent.promptEntryIds, drive.context);
14
+ const messages = meta.intent.promptEntryIds.map((id) => {
15
+ const entry = entries.get(id);
16
+ if (entry?.type !== "message") {
17
+ throw new SessionInvariantError(`Run prompt entry ${id} is missing its message`);
18
+ }
19
+ return entry.message;
20
+ });
21
+ return { kind: "return", result: messages };
22
+ }, drive.context);
23
+ if (prompt.kind === "cancel_requested")
24
+ return { kind: "continue" };
25
+ const hook = await lane.hooks.runWithGate("before_run", { lane: lane.name, runId: drive.operationId, prompt: prompt.value, resources: lane.readConfig().resources }, drive.gate, drive.context);
26
+ const injected = hook?.messages ?? [];
27
+ for (const message of injected) {
28
+ if (message.role === "assistant" && message.stopReason === "pending") {
29
+ throw new SessionInvariantError("before_run returned a pending assistant message");
30
+ }
31
+ }
32
+ const reserved = injected.map((message) => ({ id: lane.session.idGenerator.next(), message }));
33
+ const result = await lane.continueOperation(run, (state, current) => {
34
+ const entries = chainEntries(state.tipId, reserved.map(({ id, message }) => ({ id, type: "message", message })));
35
+ const triggerEntryId = entries.at(-1)?.id ?? state.tipId;
36
+ if (triggerEntryId === null)
37
+ throw new SessionInvariantError("Run start has no trigger entry");
38
+ const nextState = {
39
+ ...operationScopeOf(current),
40
+ at: "checkpoint",
41
+ continuation: { kind: "need_assistant", overflowRecoveryUsed: false },
42
+ triggerEntryId,
43
+ };
44
+ return {
45
+ kind: "commit",
46
+ writes: [
47
+ ...entries.map((entry) => insertEntry(entry)),
48
+ ...(entries.length === 0 ? [] : [setValue(branchTip(lane.name), triggerEntryId)]),
49
+ ],
50
+ operationState: nextState,
51
+ lane: { tipId: triggerEntryId },
52
+ materialize: () => ({ kind: "continue" }),
53
+ events: (commit) => committedEntryEvents(entries, commit, lane.name, drive.operationId),
54
+ };
55
+ }, drive.context);
56
+ return result.kind === "cancel_requested" ? { kind: "continue" } : result.value;
57
+ }
58
+ /** Advance one durable run boundary with at most one commit. */
59
+ export async function runCheckpoint(lane, drive, run) {
60
+ const threshold = await prepareCompactionThreshold(lane, drive, run);
61
+ if (threshold.kind === "cancel_requested")
62
+ return { kind: "continue" };
63
+ const planned = await lane.continueOperation(run, async (state, current, _meta, reader) => {
64
+ const placement = await planBoundaryInbox(lane, drive, state, current, reader, state.tipId, threshold.value === undefined && current.continuation.kind === "may_finish");
65
+ if (placement.triggerEntryId !== undefined) {
66
+ return {
67
+ kind: "commit",
68
+ writes: placement.writes,
69
+ operationState: assistantReadyAtBoundary(lane, state, current, placement.triggerEntryId, false),
70
+ lane: { tipId: placement.tipId, inbox: placement.inbox },
71
+ materialize: () => ({ kind: "continue" }),
72
+ events: (commit) => boundaryPlacementEvents(placement, commit, 0, lane.name, drive.operationId),
73
+ };
74
+ }
75
+ if (threshold.value !== undefined) {
76
+ const structural = {
77
+ ...operationScopeOf(current),
78
+ at: "summary.deciding",
79
+ task: {
80
+ taskId: threshold.value.taskId,
81
+ reason: "threshold",
82
+ boundary: {
83
+ kind: "resume_checkpoint",
84
+ resumeAfter: { continuation: current.continuation, triggerEntryId: current.triggerEntryId },
85
+ },
86
+ },
87
+ };
88
+ return {
89
+ kind: "commit",
90
+ writes: [
91
+ ...placement.writes,
92
+ setValue(operationPreparation(drive.operationId, threshold.value.taskId), threshold.value.preparation),
93
+ ],
94
+ operationState: structural,
95
+ lane: { tipId: placement.tipId, inbox: placement.inbox },
96
+ materialize: () => ({ kind: "continue" }),
97
+ events: (commit) => [
98
+ ...boundaryPlacementEvents(placement, commit, 0, lane.name, drive.operationId),
99
+ {
100
+ type: "compaction_start",
101
+ lane: lane.name,
102
+ runId: drive.operationId,
103
+ reason: "threshold",
104
+ startedAt: commit.timestamp,
105
+ },
106
+ ],
107
+ };
108
+ }
109
+ if (current.continuation.kind === "need_assistant") {
110
+ return {
111
+ kind: "commit",
112
+ writes: placement.writes,
113
+ operationState: assistantReadyAtBoundary(lane, state, current, current.triggerEntryId, current.continuation.overflowRecoveryUsed),
114
+ lane: { tipId: placement.tipId, inbox: placement.inbox },
115
+ materialize: () => ({ kind: "continue" }),
116
+ events: (commit) => boundaryPlacementEvents(placement, commit, 0, lane.name, drive.operationId),
117
+ };
118
+ }
119
+ return {
120
+ kind: "return",
121
+ result: { kind: "finish_pending", entryIds: placement.entries.map((entry) => entry.id) },
122
+ };
123
+ }, drive.context);
124
+ if (planned.kind === "cancel_requested")
125
+ return { kind: "continue" };
126
+ if (planned.value.kind !== "finish_pending")
127
+ return planned.value;
128
+ if (run.continuation.kind !== "may_finish") {
129
+ throw new SessionInvariantError("Checkpoint finish mediation requires a finish continuation");
130
+ }
131
+ return finishRunBoundary(lane, drive, run, run.continuation, planned.value.entryIds);
132
+ }
133
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../../../src/harness/runtime/drive/checkpoint.ts"],"names":[],"mappings":"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","sourcesContent":["import { insertEntry } from \"../../session/commit.ts\";\nimport { SessionInvariantError } from \"../../session/session.ts\";\nimport {\n\ttype CheckpointOperation,\n\ttype MessageEntry,\n\ttype NewEntry,\n\toperationScopeOf,\n\ttype StartingOperation,\n\ttype SummaryDecidingOperation,\n} from \"../../session/types.ts\";\nimport { branchTip, operationPreparation, setValue } from \"../../session/values.ts\";\nimport type { Lane } from \"../lane.ts\";\nimport { chainEntries, committedEntryEvents } from \"../transcript.ts\";\nimport type { Drive, ProcedureResult } from \"../types.ts\";\nimport {\n\tassistantReadyAtBoundary,\n\ttype BoundaryFinishPending,\n\tboundaryPlacementEvents,\n\tfinishRunBoundary,\n\tplanBoundaryInbox,\n} from \"./boundary.ts\";\nimport { prepareCompactionThreshold } from \"./structural.ts\";\n\n/** Consume before_run and commit the initial checkpoint. */\nexport async function startRun<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\trun: StartingOperation,\n): Promise<ProcedureResult> {\n\tconst prompt = await lane.continueOperation(\n\t\trun,\n\t\tasync (_state, _current, meta, reader) => {\n\t\t\tif (meta.intent.kind !== \"run\") throw new SessionInvariantError(\"Run operation has non-run intent\");\n\t\t\tconst entries = await reader.getEntries(meta.intent.promptEntryIds, drive.context);\n\t\t\tconst messages = meta.intent.promptEntryIds.map((id) => {\n\t\t\t\tconst entry = entries.get(id);\n\t\t\t\tif (entry?.type !== \"message\") {\n\t\t\t\t\tthrow new SessionInvariantError(`Run prompt entry ${id} is missing its message`);\n\t\t\t\t}\n\t\t\t\treturn entry.message;\n\t\t\t});\n\t\t\treturn { kind: \"return\", result: messages };\n\t\t},\n\t\tdrive.context,\n\t);\n\tif (prompt.kind === \"cancel_requested\") return { kind: \"continue\" };\n\n\tconst hook = await lane.hooks.runWithGate(\n\t\t\"before_run\",\n\t\t{ lane: lane.name, runId: drive.operationId, prompt: prompt.value, resources: lane.readConfig().resources },\n\t\tdrive.gate,\n\t\tdrive.context,\n\t);\n\tconst injected = hook?.messages ?? [];\n\tfor (const message of injected) {\n\t\tif (message.role === \"assistant\" && message.stopReason === \"pending\") {\n\t\t\tthrow new SessionInvariantError(\"before_run returned a pending assistant message\");\n\t\t}\n\t}\n\tconst reserved = injected.map((message) => ({ id: lane.session.idGenerator.next(), message }));\n\n\tconst result = await lane.continueOperation(\n\t\trun,\n\t\t(state, current) => {\n\t\t\tconst entries: NewEntry<MessageEntry>[] = chainEntries(\n\t\t\t\tstate.tipId,\n\t\t\t\treserved.map(({ id, message }) => ({ id, type: \"message\" as const, message })),\n\t\t\t);\n\t\t\tconst triggerEntryId = entries.at(-1)?.id ?? state.tipId;\n\t\t\tif (triggerEntryId === null) throw new SessionInvariantError(\"Run start has no trigger entry\");\n\t\t\tconst nextState: CheckpointOperation = {\n\t\t\t\t...operationScopeOf(current),\n\t\t\t\tat: \"checkpoint\",\n\t\t\t\tcontinuation: { kind: \"need_assistant\", overflowRecoveryUsed: false },\n\t\t\t\ttriggerEntryId,\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tkind: \"commit\",\n\t\t\t\twrites: [\n\t\t\t\t\t...entries.map((entry) => insertEntry(entry)),\n\t\t\t\t\t...(entries.length === 0 ? [] : [setValue(branchTip(lane.name), triggerEntryId)]),\n\t\t\t\t],\n\t\t\t\toperationState: nextState,\n\t\t\t\tlane: { tipId: triggerEntryId },\n\t\t\t\tmaterialize: () => ({ kind: \"continue\" }) as const,\n\t\t\t\tevents: (commit) => committedEntryEvents(entries, commit, lane.name, drive.operationId),\n\t\t\t};\n\t\t},\n\t\tdrive.context,\n\t);\n\treturn result.kind === \"cancel_requested\" ? { kind: \"continue\" } : result.value;\n}\n\n/** Advance one durable run boundary with at most one commit. */\nexport async function runCheckpoint<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\trun: CheckpointOperation,\n): Promise<ProcedureResult> {\n\tconst threshold = await prepareCompactionThreshold(lane, drive, run);\n\tif (threshold.kind === \"cancel_requested\") return { kind: \"continue\" };\n\tconst planned = await lane.continueOperation<CheckpointOperation, ProcedureResult | BoundaryFinishPending>(\n\t\trun,\n\t\tasync (state, current, _meta, reader) => {\n\t\t\tconst placement = await planBoundaryInbox(\n\t\t\t\tlane,\n\t\t\t\tdrive,\n\t\t\t\tstate,\n\t\t\t\tcurrent,\n\t\t\t\treader,\n\t\t\t\tstate.tipId,\n\t\t\t\tthreshold.value === undefined && current.continuation.kind === \"may_finish\",\n\t\t\t);\n\t\t\tif (placement.triggerEntryId !== undefined) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"commit\",\n\t\t\t\t\twrites: placement.writes,\n\t\t\t\t\toperationState: assistantReadyAtBoundary(lane, state, current, placement.triggerEntryId, false),\n\t\t\t\t\tlane: { tipId: placement.tipId, inbox: placement.inbox },\n\t\t\t\t\tmaterialize: () => ({ kind: \"continue\" }) as const,\n\t\t\t\t\tevents: (commit) => boundaryPlacementEvents(placement, commit, 0, lane.name, drive.operationId),\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (threshold.value !== undefined) {\n\t\t\t\tconst structural: SummaryDecidingOperation = {\n\t\t\t\t\t...operationScopeOf(current),\n\t\t\t\t\tat: \"summary.deciding\",\n\t\t\t\t\ttask: {\n\t\t\t\t\t\ttaskId: threshold.value.taskId,\n\t\t\t\t\t\treason: \"threshold\",\n\t\t\t\t\t\tboundary: {\n\t\t\t\t\t\t\tkind: \"resume_checkpoint\",\n\t\t\t\t\t\t\tresumeAfter: { continuation: current.continuation, triggerEntryId: current.triggerEntryId },\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"commit\",\n\t\t\t\t\twrites: [\n\t\t\t\t\t\t...placement.writes,\n\t\t\t\t\t\tsetValue(\n\t\t\t\t\t\t\toperationPreparation(drive.operationId, threshold.value.taskId),\n\t\t\t\t\t\t\tthreshold.value.preparation,\n\t\t\t\t\t\t),\n\t\t\t\t\t],\n\t\t\t\t\toperationState: structural,\n\t\t\t\t\tlane: { tipId: placement.tipId, inbox: placement.inbox },\n\t\t\t\t\tmaterialize: () => ({ kind: \"continue\" }) as const,\n\t\t\t\t\tevents: (commit) => [\n\t\t\t\t\t\t...boundaryPlacementEvents(placement, commit, 0, lane.name, drive.operationId),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"compaction_start\",\n\t\t\t\t\t\t\tlane: lane.name,\n\t\t\t\t\t\t\trunId: drive.operationId,\n\t\t\t\t\t\t\treason: \"threshold\",\n\t\t\t\t\t\t\tstartedAt: commit.timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (current.continuation.kind === \"need_assistant\") {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"commit\",\n\t\t\t\t\twrites: placement.writes,\n\t\t\t\t\toperationState: assistantReadyAtBoundary(\n\t\t\t\t\t\tlane,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\tcurrent,\n\t\t\t\t\t\tcurrent.triggerEntryId,\n\t\t\t\t\t\tcurrent.continuation.overflowRecoveryUsed,\n\t\t\t\t\t),\n\t\t\t\t\tlane: { tipId: placement.tipId, inbox: placement.inbox },\n\t\t\t\t\tmaterialize: () => ({ kind: \"continue\" }) as const,\n\t\t\t\t\tevents: (commit) => boundaryPlacementEvents(placement, commit, 0, lane.name, drive.operationId),\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tkind: \"return\",\n\t\t\t\tresult: { kind: \"finish_pending\", entryIds: placement.entries.map((entry) => entry.id) } as const,\n\t\t\t};\n\t\t},\n\t\tdrive.context,\n\t);\n\tif (planned.kind === \"cancel_requested\") return { kind: \"continue\" };\n\tif (planned.value.kind !== \"finish_pending\") return planned.value;\n\tif (run.continuation.kind !== \"may_finish\") {\n\t\tthrow new SessionInvariantError(\"Checkpoint finish mediation requires a finish continuation\");\n\t}\n\treturn finishRunBoundary(lane, drive, run, run.continuation, planned.value.entryIds);\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import type { DeferredHandle } from "@draht/ai";
2
+ import { type Context } from "../../context.ts";
3
+ import { type DeferredEffectPendingOperation, type DeferredSuspendedOperation, type SessionReader } from "../../session/types.ts";
4
+ import type { Lane } from "../lane.ts";
5
+ import type { Drive, ProcedureResult } from "../types.ts";
6
+ type DeferredLeaf = DeferredSuspendedOperation | DeferredEffectPendingOperation;
7
+ export declare function readDeferredSourceHandle(reader: SessionReader, deferred: DeferredLeaf, context: Context): Promise<DeferredHandle>;
8
+ /** Poll one durably suspended deferred response when this pass carries a permit. */
9
+ export declare function runDeferredSuspended<TContext extends object | undefined>(lane: Lane<TContext>, drive: Drive, deferred: DeferredSuspendedOperation): Promise<ProcedureResult>;
10
+ /** Replace one orphaned unknown-outcome poll under fresh ids when this pass carries a permit. */
11
+ export declare function recoverDeferredPoll<TContext extends object | undefined>(lane: Lane<TContext>, drive: Drive, deferred: DeferredEffectPendingOperation): Promise<ProcedureResult>;
12
+ /** Advance or report the wait for one deferred run phase. */
13
+ export declare function runDeferred<TContext extends object | undefined>(lane: Lane<TContext>, drive: Drive, deferred: DeferredSuspendedOperation | DeferredEffectPendingOperation): Promise<ProcedureResult>;
14
+ export {};
15
+ //# sourceMappingURL=deferred.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deferred.d.ts","sourceRoot":"","sources":["../../../../src/harness/runtime/drive/deferred.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAO,cAAc,EAAS,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,KAAK,OAAO,EAAwC,MAAM,kBAAkB,CAAC;AAItF,OAAO,EACN,KAAK,8BAA8B,EACnC,KAAK,0BAA0B,EAK/B,KAAK,aAAa,EAElB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAA2B,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnF,KAAK,YAAY,GAAG,0BAA0B,GAAG,8BAA8B,CAAC;AA0BhF,wBAAsB,wBAAwB,CAC7C,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,cAAc,CAAC,CAqBzB;AA2LD,oFAAoF;AACpF,wBAAgB,oBAAoB,CAAC,QAAQ,SAAS,MAAM,GAAG,SAAS,EACvE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,0BAA0B,GAClC,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED,iGAAiG;AACjG,wBAAgB,mBAAmB,CAAC,QAAQ,SAAS,MAAM,GAAG,SAAS,EACtE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,QAAQ,SAAS,MAAM,GAAG,SAAS,EAC9D,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,0BAA0B,GAAG,8BAA8B,GACnE,OAAO,CAAC,eAAe,CAAC,CAI1B"}
@@ -0,0 +1,179 @@
1
+ import { getTelemetryContext, withAbortSignal } from "../../context.js";
2
+ import { consumeAssistantStream } from "../../execution/assistant.js";
3
+ import { applyStreamOptionsPatch } from "../../hooks.js";
4
+ import { SessionInvariantError } from "../../session/session.js";
5
+ import { operationScopeOf, } from "../../session/types.js";
6
+ import { deleteList, pendingAssistantFrames } from "../../session/values.js";
7
+ import { openAssistantResponse, publishConfigurationFailure, publishResponse } from "./response.js";
8
+ function configurationError(identity) {
9
+ return {
10
+ code: "model_unavailable",
11
+ message: "The configured model is unavailable in this process",
12
+ details: identity,
13
+ };
14
+ }
15
+ export async function readDeferredSourceHandle(reader, deferred, context) {
16
+ const source = (await reader.getEntries([deferred.sourceEntryId], context)).get(deferred.sourceEntryId);
17
+ if (source?.type !== "message" ||
18
+ source.message.role !== "assistant" ||
19
+ source.message.stopReason !== "deferred" ||
20
+ source.message.deferred === undefined) {
21
+ throw new SessionInvariantError(`Deferred source ${deferred.sourceEntryId} is missing its assistant handle`);
22
+ }
23
+ const handle = source.message.deferred;
24
+ const identity = deferred.configuration.model;
25
+ if (handle.id.length === 0 ||
26
+ handle.provider !== identity.provider ||
27
+ handle.modelId !== identity.modelId ||
28
+ handle.api !== source.message.api) {
29
+ throw new SessionInvariantError(`Deferred source ${deferred.sourceEntryId} has an invalid handle`);
30
+ }
31
+ return handle;
32
+ }
33
+ async function readSourceHandle(lane, drive, deferred) {
34
+ return lane.continueOperation(deferred, async (_state, _current, _meta, reader) => ({
35
+ kind: "return",
36
+ result: await readDeferredSourceHandle(reader, deferred, drive.context),
37
+ }), drive.context);
38
+ }
39
+ async function prepareDeferredPoll(lane, drive, expected) {
40
+ const source = await readSourceHandle(lane, drive, expected);
41
+ if (source.kind === "cancel_requested")
42
+ return source;
43
+ if (drive.deferredPermits === 0)
44
+ return { kind: "waiting", source: source.value };
45
+ const identity = expected.configuration.model;
46
+ const model = lane.models.getModel(identity.provider, identity.modelId);
47
+ if (model === undefined)
48
+ return { kind: "configuration_failure" };
49
+ const baseOptions = { ...expected.streamOptions, deferred: false };
50
+ const poll = expected.at === "deferred.suspended" ? expected.poll + 1 : expected.poll;
51
+ const beforeRequest = await lane.hooks.runWithGate("before_request", {
52
+ lane: lane.name,
53
+ runId: drive.operationId,
54
+ model,
55
+ step: "deferred",
56
+ attempt: poll,
57
+ streamOptions: baseOptions,
58
+ }, drive.gate, drive.context);
59
+ return {
60
+ kind: "ready",
61
+ source: source.value,
62
+ model,
63
+ poll,
64
+ streamOptions: {
65
+ ...(beforeRequest?.streamOptions === undefined
66
+ ? baseOptions
67
+ : applyStreamOptionsPatch(baseOptions, beforeRequest.streamOptions)),
68
+ deferred: false,
69
+ },
70
+ };
71
+ }
72
+ async function publishPollIntent(lane, drive, deferred, prepared, recovery) {
73
+ const at = Date.now();
74
+ const next = {
75
+ at: "deferred.effect_pending",
76
+ stepId: deferred.stepId,
77
+ sourceEntryId: deferred.sourceEntryId,
78
+ poll: prepared.poll,
79
+ responseEntryId: lane.session.idGenerator.next(at),
80
+ usageId: lane.session.idGenerator.next(at),
81
+ configuration: deferred.configuration,
82
+ streamOptions: deferred.streamOptions,
83
+ };
84
+ return lane.continueOperation(deferred, (_state, current) => {
85
+ const nextState = { ...operationScopeOf(current), ...next };
86
+ return {
87
+ kind: "commit",
88
+ writes: deferred.at === "deferred.effect_pending"
89
+ ? [deleteList(pendingAssistantFrames(drive.operationId, deferred.responseEntryId))]
90
+ : [],
91
+ operationState: nextState,
92
+ materialize: () => {
93
+ drive.deferredPermits--;
94
+ return nextState;
95
+ },
96
+ events: () => [
97
+ {
98
+ type: "run_resume",
99
+ lane: lane.name,
100
+ runId: drive.operationId,
101
+ ...(recovery ? { recovery: true } : {}),
102
+ },
103
+ {
104
+ type: "turn_start",
105
+ lane: lane.name,
106
+ runId: drive.operationId,
107
+ turnId: `${next.stepId}:poll:${next.poll}`,
108
+ ...(recovery ? { recovery: true } : {}),
109
+ },
110
+ ],
111
+ };
112
+ }, drive.context);
113
+ }
114
+ async function performDeferredPoll(lane, drive, prepared, intent, recovery) {
115
+ const response = openAssistantResponse(lane, drive, intent.responseEntryId, recovery);
116
+ let metadata = {};
117
+ const admitted = withAbortSignal(drive.gate.signal, drive.context);
118
+ const stream = drive.gate.admit(() => lane.models.streamDeferred(prepared.model, prepared.source, {
119
+ wait: 0,
120
+ signal: admitted.abortSignal,
121
+ telemetryContext: getTelemetryContext(admitted),
122
+ timeoutMs: prepared.streamOptions.timeoutMs,
123
+ maxRetries: prepared.streamOptions.maxRetries,
124
+ maxRetryDelayMs: prepared.streamOptions.maxRetryDelayMs,
125
+ headers: prepared.streamOptions.headers,
126
+ onPayload: async (payload, requestModel) => {
127
+ const result = await lane.hooks.runWithGate("before_payload", { lane: lane.name, runId: drive.operationId, model: requestModel, payload }, drive.gate, drive.context);
128
+ return result?.payload;
129
+ },
130
+ onResponse: (response) => {
131
+ metadata = { status: response.status, headers: response.headers };
132
+ },
133
+ }));
134
+ try {
135
+ return await consumeAssistantStream(stream, response.observer, (message, context) => response.afterResponse(message, metadata, context), drive.context);
136
+ }
137
+ finally {
138
+ await response.close();
139
+ }
140
+ }
141
+ async function pollDeferred(lane, drive, expected, recovery) {
142
+ const prepared = await prepareDeferredPoll(lane, drive, expected);
143
+ if (prepared.kind === "cancel_requested")
144
+ return { kind: "continue" };
145
+ if (prepared.kind === "waiting") {
146
+ return {
147
+ kind: "waiting",
148
+ outcome: {
149
+ kind: "waiting",
150
+ operationId: drive.operationId,
151
+ reason: "deferred",
152
+ deferred: prepared.source,
153
+ },
154
+ };
155
+ }
156
+ if (prepared.kind === "configuration_failure") {
157
+ return publishConfigurationFailure(lane, drive, expected, configurationError(expected.configuration.model));
158
+ }
159
+ const intent = await publishPollIntent(lane, drive, expected, prepared, recovery);
160
+ if (intent.kind === "cancel_requested")
161
+ return { kind: "continue" };
162
+ const response = await performDeferredPoll(lane, drive, prepared, intent.value, recovery);
163
+ return publishResponse(lane, drive, intent.value, response, recovery ? { recovery: true } : {});
164
+ }
165
+ /** Poll one durably suspended deferred response when this pass carries a permit. */
166
+ export function runDeferredSuspended(lane, drive, deferred) {
167
+ return pollDeferred(lane, drive, deferred, false);
168
+ }
169
+ /** Replace one orphaned unknown-outcome poll under fresh ids when this pass carries a permit. */
170
+ export function recoverDeferredPoll(lane, drive, deferred) {
171
+ return pollDeferred(lane, drive, deferred, true);
172
+ }
173
+ /** Advance or report the wait for one deferred run phase. */
174
+ export function runDeferred(lane, drive, deferred) {
175
+ return deferred.at === "deferred.suspended"
176
+ ? runDeferredSuspended(lane, drive, deferred)
177
+ : recoverDeferredPoll(lane, drive, deferred);
178
+ }
179
+ //# sourceMappingURL=deferred.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deferred.js","sourceRoot":"","sources":["../../../../src/harness/runtime/drive/deferred.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, DeferredHandle, Model } from \"@draht/ai\";\nimport { type Context, getTelemetryContext, withAbortSignal } from \"../../context.ts\";\nimport { consumeAssistantStream } from \"../../execution/assistant.ts\";\nimport { applyStreamOptionsPatch } from \"../../hooks.ts\";\nimport { SessionInvariantError } from \"../../session/session.ts\";\nimport {\n\ttype DeferredEffectPendingOperation,\n\ttype DeferredSuspendedOperation,\n\ttype LaneConfiguration,\n\ttype OperationError,\n\ttype OperationScope,\n\toperationScopeOf,\n\ttype SessionReader,\n\ttype SettledAssistantMessage,\n} from \"../../session/types.ts\";\nimport { deleteList, pendingAssistantFrames } from \"../../session/values.ts\";\nimport type { AgentHarnessStreamOptions } from \"../../types.ts\";\nimport type { Lane } from \"../lane.ts\";\nimport type { ContinueOperationResult, Drive, ProcedureResult } from \"../types.ts\";\nimport { openAssistantResponse, publishConfigurationFailure, publishResponse } from \"./response.ts\";\n\ntype DeferredLeaf = DeferredSuspendedOperation | DeferredEffectPendingOperation;\n/** Deferred effect payload without the run-wide scope fields. */\ntype EffectPendingFields = Omit<DeferredEffectPendingOperation, keyof OperationScope>;\n\ntype PreparedDeferredPoll = {\n\tkind: \"ready\";\n\tsource: DeferredHandle;\n\tmodel: Model<Api>;\n\tpoll: number;\n\tstreamOptions: AgentHarnessStreamOptions;\n};\n\ntype DeferredPreparation =\n\t| PreparedDeferredPoll\n\t| { kind: \"cancel_requested\" }\n\t| { kind: \"waiting\"; source: DeferredHandle }\n\t| { kind: \"configuration_failure\" };\n\nfunction configurationError(identity: LaneConfiguration[\"model\"]): OperationError {\n\treturn {\n\t\tcode: \"model_unavailable\",\n\t\tmessage: \"The configured model is unavailable in this process\",\n\t\tdetails: identity,\n\t};\n}\n\nexport async function readDeferredSourceHandle(\n\treader: SessionReader,\n\tdeferred: DeferredLeaf,\n\tcontext: Context,\n): Promise<DeferredHandle> {\n\tconst source = (await reader.getEntries([deferred.sourceEntryId], context)).get(deferred.sourceEntryId);\n\tif (\n\t\tsource?.type !== \"message\" ||\n\t\tsource.message.role !== \"assistant\" ||\n\t\tsource.message.stopReason !== \"deferred\" ||\n\t\tsource.message.deferred === undefined\n\t) {\n\t\tthrow new SessionInvariantError(`Deferred source ${deferred.sourceEntryId} is missing its assistant handle`);\n\t}\n\tconst handle = source.message.deferred;\n\tconst identity = deferred.configuration.model;\n\tif (\n\t\thandle.id.length === 0 ||\n\t\thandle.provider !== identity.provider ||\n\t\thandle.modelId !== identity.modelId ||\n\t\thandle.api !== source.message.api\n\t) {\n\t\tthrow new SessionInvariantError(`Deferred source ${deferred.sourceEntryId} has an invalid handle`);\n\t}\n\treturn handle;\n}\n\nasync function readSourceHandle<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\tdeferred: DeferredLeaf,\n): Promise<ContinueOperationResult<DeferredHandle>> {\n\treturn lane.continueOperation(\n\t\tdeferred,\n\t\tasync (_state, _current, _meta, reader) => ({\n\t\t\tkind: \"return\",\n\t\t\tresult: await readDeferredSourceHandle(reader, deferred, drive.context),\n\t\t}),\n\t\tdrive.context,\n\t);\n}\n\nasync function prepareDeferredPoll<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\texpected: DeferredLeaf,\n): Promise<DeferredPreparation> {\n\tconst source = await readSourceHandle(lane, drive, expected);\n\tif (source.kind === \"cancel_requested\") return source;\n\tif (drive.deferredPermits === 0) return { kind: \"waiting\", source: source.value };\n\n\tconst identity = expected.configuration.model;\n\tconst model = lane.models.getModel(identity.provider, identity.modelId);\n\tif (model === undefined) return { kind: \"configuration_failure\" };\n\tconst baseOptions: AgentHarnessStreamOptions = { ...expected.streamOptions, deferred: false };\n\tconst poll = expected.at === \"deferred.suspended\" ? expected.poll + 1 : expected.poll;\n\tconst beforeRequest = await lane.hooks.runWithGate(\n\t\t\"before_request\",\n\t\t{\n\t\t\tlane: lane.name,\n\t\t\trunId: drive.operationId,\n\t\t\tmodel,\n\t\t\tstep: \"deferred\",\n\t\t\tattempt: poll,\n\t\t\tstreamOptions: baseOptions,\n\t\t},\n\t\tdrive.gate,\n\t\tdrive.context,\n\t);\n\treturn {\n\t\tkind: \"ready\",\n\t\tsource: source.value,\n\t\tmodel,\n\t\tpoll,\n\t\tstreamOptions: {\n\t\t\t...(beforeRequest?.streamOptions === undefined\n\t\t\t\t? baseOptions\n\t\t\t\t: applyStreamOptionsPatch(baseOptions, beforeRequest.streamOptions)),\n\t\t\tdeferred: false,\n\t\t},\n\t};\n}\n\nasync function publishPollIntent<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\tdeferred: DeferredLeaf,\n\tprepared: PreparedDeferredPoll,\n\trecovery: boolean,\n): Promise<ContinueOperationResult<DeferredEffectPendingOperation>> {\n\tconst at = Date.now();\n\tconst next: EffectPendingFields = {\n\t\tat: \"deferred.effect_pending\",\n\t\tstepId: deferred.stepId,\n\t\tsourceEntryId: deferred.sourceEntryId,\n\t\tpoll: prepared.poll,\n\t\tresponseEntryId: lane.session.idGenerator.next(at),\n\t\tusageId: lane.session.idGenerator.next(at),\n\t\tconfiguration: deferred.configuration,\n\t\tstreamOptions: deferred.streamOptions,\n\t};\n\treturn lane.continueOperation(\n\t\tdeferred,\n\t\t(_state, current) => {\n\t\t\tconst nextState: DeferredEffectPendingOperation = { ...operationScopeOf(current), ...next };\n\t\t\treturn {\n\t\t\t\tkind: \"commit\",\n\t\t\t\twrites:\n\t\t\t\t\tdeferred.at === \"deferred.effect_pending\"\n\t\t\t\t\t\t? [deleteList(pendingAssistantFrames(drive.operationId, deferred.responseEntryId))]\n\t\t\t\t\t\t: [],\n\t\t\t\toperationState: nextState,\n\t\t\t\tmaterialize: () => {\n\t\t\t\t\tdrive.deferredPermits--;\n\t\t\t\t\treturn nextState;\n\t\t\t\t},\n\t\t\t\tevents: () => [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"run_resume\",\n\t\t\t\t\t\tlane: lane.name,\n\t\t\t\t\t\trunId: drive.operationId,\n\t\t\t\t\t\t...(recovery ? { recovery: true as const } : {}),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"turn_start\",\n\t\t\t\t\t\tlane: lane.name,\n\t\t\t\t\t\trunId: drive.operationId,\n\t\t\t\t\t\tturnId: `${next.stepId}:poll:${next.poll}`,\n\t\t\t\t\t\t...(recovery ? { recovery: true as const } : {}),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t\tdrive.context,\n\t);\n}\n\nasync function performDeferredPoll<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\tprepared: PreparedDeferredPoll,\n\tintent: DeferredEffectPendingOperation,\n\trecovery: boolean,\n): Promise<SettledAssistantMessage> {\n\tconst response = openAssistantResponse(lane, drive, intent.responseEntryId, recovery);\n\tlet metadata: { status?: number; headers?: Record<string, string> } = {};\n\tconst admitted = withAbortSignal(drive.gate.signal, drive.context);\n\tconst stream = drive.gate.admit(() =>\n\t\tlane.models.streamDeferred(prepared.model, prepared.source, {\n\t\t\twait: 0,\n\t\t\tsignal: admitted.abortSignal,\n\t\t\ttelemetryContext: getTelemetryContext(admitted),\n\t\t\ttimeoutMs: prepared.streamOptions.timeoutMs,\n\t\t\tmaxRetries: prepared.streamOptions.maxRetries,\n\t\t\tmaxRetryDelayMs: prepared.streamOptions.maxRetryDelayMs,\n\t\t\theaders: prepared.streamOptions.headers,\n\t\t\tonPayload: async (payload, requestModel) => {\n\t\t\t\tconst result = await lane.hooks.runWithGate(\n\t\t\t\t\t\"before_payload\",\n\t\t\t\t\t{ lane: lane.name, runId: drive.operationId, model: requestModel, payload },\n\t\t\t\t\tdrive.gate,\n\t\t\t\t\tdrive.context,\n\t\t\t\t);\n\t\t\t\treturn result?.payload;\n\t\t\t},\n\t\t\tonResponse: (response) => {\n\t\t\t\tmetadata = { status: response.status, headers: response.headers };\n\t\t\t},\n\t\t}),\n\t);\n\n\ttry {\n\t\treturn await consumeAssistantStream(\n\t\t\tstream,\n\t\t\tresponse.observer,\n\t\t\t(message, context) => response.afterResponse(message, metadata, context),\n\t\t\tdrive.context,\n\t\t);\n\t} finally {\n\t\tawait response.close();\n\t}\n}\n\nasync function pollDeferred<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\texpected: DeferredLeaf,\n\trecovery: boolean,\n): Promise<ProcedureResult> {\n\tconst prepared = await prepareDeferredPoll(lane, drive, expected);\n\tif (prepared.kind === \"cancel_requested\") return { kind: \"continue\" };\n\tif (prepared.kind === \"waiting\") {\n\t\treturn {\n\t\t\tkind: \"waiting\",\n\t\t\toutcome: {\n\t\t\t\tkind: \"waiting\",\n\t\t\t\toperationId: drive.operationId,\n\t\t\t\treason: \"deferred\",\n\t\t\t\tdeferred: prepared.source,\n\t\t\t},\n\t\t};\n\t}\n\tif (prepared.kind === \"configuration_failure\") {\n\t\treturn publishConfigurationFailure(lane, drive, expected, configurationError(expected.configuration.model));\n\t}\n\n\tconst intent = await publishPollIntent(lane, drive, expected, prepared, recovery);\n\tif (intent.kind === \"cancel_requested\") return { kind: \"continue\" };\n\tconst response = await performDeferredPoll(lane, drive, prepared, intent.value, recovery);\n\treturn publishResponse(lane, drive, intent.value, response, recovery ? { recovery: true } : {});\n}\n\n/** Poll one durably suspended deferred response when this pass carries a permit. */\nexport function runDeferredSuspended<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\tdeferred: DeferredSuspendedOperation,\n): Promise<ProcedureResult> {\n\treturn pollDeferred(lane, drive, deferred, false);\n}\n\n/** Replace one orphaned unknown-outcome poll under fresh ids when this pass carries a permit. */\nexport function recoverDeferredPoll<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\tdeferred: DeferredEffectPendingOperation,\n): Promise<ProcedureResult> {\n\treturn pollDeferred(lane, drive, deferred, true);\n}\n\n/** Advance or report the wait for one deferred run phase. */\nexport function runDeferred<TContext extends object | undefined>(\n\tlane: Lane<TContext>,\n\tdrive: Drive,\n\tdeferred: DeferredSuspendedOperation | DeferredEffectPendingOperation,\n): Promise<ProcedureResult> {\n\treturn deferred.at === \"deferred.suspended\"\n\t\t? runDeferredSuspended(lane, drive, deferred)\n\t\t: recoverDeferredPoll(lane, drive, deferred);\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import { type AssistantReadyOperation, type AssistantRetryWaitOperation } from "../../session/types.ts";
2
+ import type { Lane } from "../lane.ts";
3
+ import type { Drive, ProcedureResult } from "../types.ts";
4
+ /** Advance one durable assistant retry wait according to this pass's local wait policy. */
5
+ export declare function runRetryWait<TContext extends object | undefined>(lane: Lane<TContext>, drive: Drive, generation: AssistantRetryWaitOperation): Promise<ProcedureResult>;
6
+ /** Execute one ready assistant generation or advance its durable retry wait. */
7
+ export declare function runGeneration<TContext extends object | undefined>(lane: Lane<TContext>, drive: Drive, generation: AssistantReadyOperation | AssistantRetryWaitOperation): Promise<ProcedureResult>;
8
+ //# sourceMappingURL=generation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../../../../src/harness/runtime/drive/generation.ts"],"names":[],"mappings":"AAMA,OAAO,EAEN,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAMhC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,KAAK,EAA2B,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAqNnF,2FAA2F;AAC3F,wBAAsB,YAAY,CAAC,QAAQ,SAAS,MAAM,GAAG,SAAS,EACrE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,2BAA2B,GACrC,OAAO,CAAC,eAAe,CAAC,CA4C1B;AAED,gFAAgF;AAChF,wBAAsB,aAAa,CAAC,QAAQ,SAAS,MAAM,GAAG,SAAS,EACtE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,uBAAuB,GAAG,2BAA2B,GAC/D,OAAO,CAAC,eAAe,CAAC,CAa1B"}
@@ -0,0 +1,205 @@
1
+ import { getTelemetryContext, withAbortSignal } from "../../context.js";
2
+ import { streamHarnessAssistant } from "../../execution/assistant.js";
3
+ import { applyStreamOptionsPatch } from "../../hooks.js";
4
+ import { SessionInvariantError } from "../../session/session.js";
5
+ import { operationScopeOf, } from "../../session/types.js";
6
+ import { readBoundedContext } from "../transcript.js";
7
+ import { openAssistantResponse, publishConfigurationFailure, publishResponse } from "./response.js";
8
+ import { waitUntil } from "./retry.js";
9
+ function configurationError(code, details) {
10
+ return {
11
+ code,
12
+ message: code === "model_unavailable"
13
+ ? "The configured model is unavailable in this process"
14
+ : "One or more configured tools are unavailable in this process",
15
+ details,
16
+ };
17
+ }
18
+ async function resolveSystemPrompt(lane, context) {
19
+ const config = lane.readConfig();
20
+ if (config.systemPrompt === undefined)
21
+ return "";
22
+ if (typeof config.systemPrompt === "string")
23
+ return config.systemPrompt;
24
+ const source = config.toolContext;
25
+ const toolContext = typeof source === "function" ? await source(context) : source;
26
+ return config.systemPrompt(toolContext, context);
27
+ }
28
+ async function prepareGeneration(lane, drive, generation) {
29
+ const identity = generation.generationContext.configuration.model;
30
+ const model = lane.models.getModel(identity.provider, identity.modelId);
31
+ if (model === undefined) {
32
+ return { kind: "configuration_failure", error: configurationError("model_unavailable", identity) };
33
+ }
34
+ const config = lane.readConfig();
35
+ const toolsByName = new Map(config.tools.map((tool) => [tool.name, tool]));
36
+ const missingTools = generation.generationContext.configuration.activeToolNames.filter((name) => !toolsByName.has(name));
37
+ if (missingTools.length !== 0) {
38
+ return {
39
+ kind: "configuration_failure",
40
+ error: configurationError("configured_tools_unavailable", { tools: missingTools }),
41
+ };
42
+ }
43
+ const tools = generation.generationContext.configuration.activeToolNames.map((name) => {
44
+ const tool = toolsByName.get(name);
45
+ if (tool === undefined)
46
+ throw new SessionInvariantError(`Configured tool ${name} disappeared during resolution`);
47
+ return {
48
+ name: tool.name,
49
+ description: tool.description,
50
+ parameters: tool.parameters,
51
+ ...(tool.constrainedSampling === undefined ? {} : { constrainedSampling: tool.constrainedSampling }),
52
+ };
53
+ });
54
+ const messages = await readBoundedContext(lane, drive, generation);
55
+ if (messages.kind === "cancel_requested")
56
+ return messages;
57
+ const systemPrompt = await resolveSystemPrompt(lane, drive.context);
58
+ const beforeRequest = await lane.hooks.runWithGate("before_request", {
59
+ lane: lane.name,
60
+ runId: drive.operationId,
61
+ model,
62
+ step: "assistant",
63
+ attempt: generation.nextAttempt,
64
+ streamOptions: generation.generationContext.streamOptions,
65
+ }, drive.gate, drive.context);
66
+ const streamOptions = beforeRequest?.streamOptions === undefined
67
+ ? generation.generationContext.streamOptions
68
+ : applyStreamOptionsPatch(generation.generationContext.streamOptions, beforeRequest.streamOptions);
69
+ return {
70
+ kind: "ready",
71
+ model,
72
+ tools,
73
+ messages: messages.value,
74
+ systemPrompt,
75
+ streamOptions,
76
+ toProviderMessages: config.toProviderMessages,
77
+ };
78
+ }
79
+ async function publishGenerationIntent(lane, drive, ready, prepared) {
80
+ const at = Date.now();
81
+ const pending = {
82
+ at: "assistant.effect_pending",
83
+ generationContext: ready.generationContext,
84
+ attempt: ready.nextAttempt,
85
+ responseEntryId: lane.session.idGenerator.next(at),
86
+ usageId: lane.session.idGenerator.next(at),
87
+ intendedOutputLimit: prepared.model.maxTokens,
88
+ contextWindow: prepared.model.contextWindow,
89
+ };
90
+ return lane.continueOperation(ready, (_state, current) => {
91
+ const nextState = { ...operationScopeOf(current), ...pending };
92
+ return {
93
+ kind: "commit",
94
+ writes: [],
95
+ operationState: nextState,
96
+ materialize: () => nextState,
97
+ events: () => ready.nextAttempt === 1
98
+ ? [
99
+ {
100
+ type: "turn_start",
101
+ lane: lane.name,
102
+ runId: drive.operationId,
103
+ turnId: ready.generationContext.stepId,
104
+ },
105
+ ]
106
+ : [],
107
+ };
108
+ }, drive.context);
109
+ }
110
+ async function performGeneration(lane, drive, intent, prepared) {
111
+ const response = openAssistantResponse(lane, drive, intent.responseEntryId);
112
+ try {
113
+ return await streamHarnessAssistant(prepared.messages, {
114
+ model: prepared.model,
115
+ systemPrompt: prepared.systemPrompt,
116
+ tools: prepared.tools,
117
+ thinkingLevel: intent.generationContext.configuration.thinkingLevel,
118
+ streamOptions: prepared.streamOptions,
119
+ transformContext: async (requestContext, context) => {
120
+ const result = await lane.hooks.runWithGate("transform_context", { lane: lane.name, runId: drive.operationId, ...requestContext }, drive.gate, context);
121
+ return {
122
+ messages: result?.messages ?? requestContext.messages,
123
+ systemPrompt: result?.systemPrompt ?? requestContext.systemPrompt,
124
+ };
125
+ },
126
+ toProviderMessages: prepared.toProviderMessages,
127
+ beforePayload: async (payload, requestModel, context) => {
128
+ const result = await lane.hooks.runWithGate("before_payload", { lane: lane.name, runId: drive.operationId, model: requestModel, payload }, drive.gate, context);
129
+ return result?.payload;
130
+ },
131
+ afterResponse: response.afterResponse,
132
+ request: (aiContext, options, context) => {
133
+ const admitted = withAbortSignal(drive.gate.signal, context);
134
+ return drive.gate.admit(() => lane.models.streamSimple(prepared.model, aiContext, {
135
+ ...options,
136
+ sessionId: `${lane.session.metadata.id}:${lane.name}`,
137
+ signal: admitted.abortSignal,
138
+ telemetryContext: getTelemetryContext(admitted),
139
+ }));
140
+ },
141
+ observer: response.observer,
142
+ }, drive.context);
143
+ }
144
+ finally {
145
+ await response.close();
146
+ }
147
+ }
148
+ /** Advance one durable assistant retry wait according to this pass's local wait policy. */
149
+ export async function runRetryWait(lane, drive, generation) {
150
+ if (Date.now() < generation.notBefore) {
151
+ if (!drive.waitForRetry) {
152
+ return {
153
+ kind: "waiting",
154
+ outcome: {
155
+ kind: "waiting",
156
+ operationId: drive.operationId,
157
+ reason: "retry",
158
+ notBefore: generation.notBefore,
159
+ },
160
+ };
161
+ }
162
+ await drive.gate.admit(() => waitUntil(generation.notBefore, drive.gate.signal));
163
+ }
164
+ const result = await lane.continueOperation(generation, (_state, current) => {
165
+ const nextState = {
166
+ ...operationScopeOf(current),
167
+ at: "assistant.ready",
168
+ generationContext: generation.generationContext,
169
+ nextAttempt: generation.nextAttempt,
170
+ };
171
+ return {
172
+ kind: "commit",
173
+ writes: [],
174
+ operationState: nextState,
175
+ materialize: () => ({ kind: "continue" }),
176
+ events: () => [
177
+ {
178
+ type: "retry_start",
179
+ lane: lane.name,
180
+ runId: drive.operationId,
181
+ step: generation.generationContext.stepId,
182
+ attempt: generation.nextAttempt,
183
+ },
184
+ ],
185
+ };
186
+ }, drive.context);
187
+ return result.kind === "cancel_requested" ? { kind: "continue" } : result.value;
188
+ }
189
+ /** Execute one ready assistant generation or advance its durable retry wait. */
190
+ export async function runGeneration(lane, drive, generation) {
191
+ if (generation.at === "assistant.retry_wait")
192
+ return runRetryWait(lane, drive, generation);
193
+ const prepared = await prepareGeneration(lane, drive, generation);
194
+ if (prepared.kind === "configuration_failure") {
195
+ return publishConfigurationFailure(lane, drive, generation, prepared.error);
196
+ }
197
+ if (prepared.kind === "cancel_requested")
198
+ return { kind: "continue" };
199
+ const intent = await publishGenerationIntent(lane, drive, generation, prepared);
200
+ if (intent.kind === "cancel_requested")
201
+ return { kind: "continue" };
202
+ const response = await performGeneration(lane, drive, intent.value, prepared);
203
+ return publishResponse(lane, drive, intent.value, response);
204
+ }
205
+ //# sourceMappingURL=generation.js.map