@stigmer/runner 3.15.1 → 3.15.2-dev.20260913223433

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 (518) hide show
  1. package/README.md +2 -4
  2. package/dist/.build-fingerprint +1 -1
  3. package/dist/__test-utils__/execution-record-fixture.d.ts +14 -0
  4. package/dist/__test-utils__/execution-record-fixture.js +4 -0
  5. package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
  6. package/dist/__test-utils__/file-review-projection.d.ts +40 -0
  7. package/dist/__test-utils__/file-review-projection.js +136 -0
  8. package/dist/__test-utils__/file-review-projection.js.map +1 -0
  9. package/dist/__test-utils__/harness-contract/types.d.ts +23 -1
  10. package/dist/__test-utils__/harness-contract/types.js +15 -0
  11. package/dist/__test-utils__/harness-contract/types.js.map +1 -1
  12. package/dist/__test-utils__/hermetic-activity.d.ts +44 -12
  13. package/dist/__test-utils__/hermetic-activity.js +52 -14
  14. package/dist/__test-utils__/hermetic-activity.js.map +1 -1
  15. package/dist/__test-utils__/model-registry-fixture.d.ts +32 -7
  16. package/dist/__test-utils__/model-registry-fixture.js +31 -7
  17. package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
  18. package/dist/__test-utils__/turn-input-fixture.d.ts +1 -1
  19. package/dist/__test-utils__/turn-input-fixture.js +1 -1
  20. package/dist/__test-utils__/turn-input-fixture.js.map +1 -1
  21. package/dist/activities/call-agent.js +2 -2
  22. package/dist/activities/call-agent.js.map +1 -1
  23. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +45 -3
  24. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -1
  25. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +0 -9
  26. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +2 -41
  27. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
  28. package/dist/activities/execute-cursor/adapter.d.ts +7 -5
  29. package/dist/activities/execute-cursor/adapter.js +7 -5
  30. package/dist/activities/execute-cursor/adapter.js.map +1 -1
  31. package/dist/activities/execute-cursor/approval-policy.d.ts +5 -2
  32. package/dist/activities/execute-cursor/approval-policy.js +5 -2
  33. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  34. package/dist/activities/execute-cursor/approval-state.d.ts +16 -8
  35. package/dist/activities/execute-cursor/approval-state.js +6 -3
  36. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  37. package/dist/activities/execute-cursor/cas-observations.d.ts +14 -2
  38. package/dist/activities/execute-cursor/cas-observations.js +19 -2
  39. package/dist/activities/execute-cursor/cas-observations.js.map +1 -1
  40. package/dist/activities/execute-cursor/cursor-capabilities.d.ts +8 -4
  41. package/dist/activities/execute-cursor/cursor-capabilities.js +21 -4
  42. package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -1
  43. package/dist/activities/execute-cursor/message-translator.d.ts +12 -20
  44. package/dist/activities/execute-cursor/message-translator.js +19 -32
  45. package/dist/activities/execute-cursor/message-translator.js.map +1 -1
  46. package/dist/activities/execute-cursor/prompt-builder.d.ts +48 -58
  47. package/dist/activities/execute-cursor/prompt-builder.js +76 -95
  48. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  49. package/dist/activities/execute-cursor/turn-boundary.d.ts +27 -55
  50. package/dist/activities/execute-cursor/turn-boundary.js +30 -90
  51. package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
  52. package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
  53. package/dist/activities/execute-cursor/turn-settle.js +37 -49
  54. package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
  55. package/dist/activities/execute-cursor/turn-setup.d.ts +16 -24
  56. package/dist/activities/execute-cursor/turn-setup.js +29 -59
  57. package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
  58. package/dist/activities/execute-cursor/turn-stream.d.ts +3 -8
  59. package/dist/activities/execute-cursor/turn-stream.js +9 -22
  60. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  61. package/dist/activities/execute-cursor/turn.js +5 -1
  62. package/dist/activities/execute-cursor/turn.js.map +1 -1
  63. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +93 -0
  64. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +348 -0
  65. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js.map +1 -0
  66. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +170 -0
  67. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +225 -0
  68. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -0
  69. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.d.ts +24 -0
  70. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +41 -0
  71. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -0
  72. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +54 -0
  73. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +72 -0
  74. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -0
  75. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +187 -23
  76. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +238 -27
  77. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
  78. package/dist/activities/execute-deep-agent/adapter.d.ts +41 -0
  79. package/dist/activities/execute-deep-agent/adapter.js +78 -0
  80. package/dist/activities/execute-deep-agent/adapter.js.map +1 -0
  81. package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +8 -0
  82. package/dist/activities/execute-deep-agent/cas-capture-observer.js +9 -0
  83. package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -1
  84. package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +31 -0
  85. package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +40 -0
  86. package/dist/activities/execute-deep-agent/deep-agent-capabilities.js.map +1 -0
  87. package/dist/activities/execute-deep-agent/execution-state.d.ts +4 -11
  88. package/dist/activities/execute-deep-agent/execution-state.js +4 -12
  89. package/dist/activities/execute-deep-agent/execution-state.js.map +1 -1
  90. package/dist/activities/execute-deep-agent/hitl.d.ts +49 -47
  91. package/dist/activities/execute-deep-agent/hitl.js +77 -103
  92. package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
  93. package/dist/activities/execute-deep-agent/prompt-builder.d.ts +51 -23
  94. package/dist/activities/execute-deep-agent/prompt-builder.js +115 -76
  95. package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
  96. package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +18 -32
  97. package/dist/activities/execute-deep-agent/status-builder-shared.js +10 -65
  98. package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
  99. package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +10 -8
  100. package/dist/activities/execute-deep-agent/streaming-side-effects.js +12 -14
  101. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  102. package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +36 -13
  103. package/dist/activities/execute-deep-agent/subagent-tracker.js +76 -39
  104. package/dist/activities/execute-deep-agent/subagent-tracker.js.map +1 -1
  105. package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -28
  106. package/dist/activities/execute-deep-agent/subagent-transformer.js +29 -82
  107. package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
  108. package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +3 -2
  109. package/dist/activities/execute-deep-agent/subagent-wiring.js +2 -2
  110. package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
  111. package/dist/activities/execute-deep-agent/turn-settle.d.ts +42 -0
  112. package/dist/activities/execute-deep-agent/turn-settle.js +146 -0
  113. package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -0
  114. package/dist/activities/execute-deep-agent/turn-setup.d.ts +212 -0
  115. package/dist/activities/execute-deep-agent/turn-setup.js +430 -0
  116. package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -0
  117. package/dist/activities/execute-deep-agent/turn-stream.d.ts +97 -0
  118. package/dist/activities/execute-deep-agent/turn-stream.js +242 -0
  119. package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -0
  120. package/dist/activities/execute-deep-agent/turn.d.ts +42 -0
  121. package/dist/activities/execute-deep-agent/turn.js +116 -0
  122. package/dist/activities/execute-deep-agent/turn.js.map +1 -0
  123. package/dist/activities/execute-deep-agent/v3-event-recorder.d.ts +6 -5
  124. package/dist/activities/execute-deep-agent/v3-event-recorder.js +6 -5
  125. package/dist/activities/execute-deep-agent/v3-event-recorder.js.map +1 -1
  126. package/dist/activities/execute-deep-agent/v3-events.d.ts +1 -1
  127. package/dist/activities/execute-deep-agent/v3-events.js +1 -1
  128. package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +60 -17
  129. package/dist/activities/execute-deep-agent/v3-status-builder.js +72 -57
  130. package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
  131. package/dist/harness/approval-decisions.d.ts +61 -0
  132. package/dist/harness/approval-decisions.js +102 -0
  133. package/dist/harness/approval-decisions.js.map +1 -0
  134. package/dist/harness/capabilities.d.ts +16 -5
  135. package/dist/harness/capabilities.js +9 -0
  136. package/dist/harness/capabilities.js.map +1 -1
  137. package/dist/harness/capture.d.ts +144 -0
  138. package/dist/harness/capture.js +219 -0
  139. package/dist/harness/capture.js.map +1 -0
  140. package/dist/harness/persist-chokepoint.d.ts +19 -4
  141. package/dist/harness/persist-chokepoint.js +17 -4
  142. package/dist/harness/persist-chokepoint.js.map +1 -1
  143. package/dist/harness/run-turn.js +115 -29
  144. package/dist/harness/run-turn.js.map +1 -1
  145. package/dist/harness/terminal-table.d.ts +40 -11
  146. package/dist/harness/terminal-table.js +58 -19
  147. package/dist/harness/terminal-table.js.map +1 -1
  148. package/dist/harness/turn-context.d.ts +141 -76
  149. package/dist/harness/turn-context.js +194 -99
  150. package/dist/harness/turn-context.js.map +1 -1
  151. package/dist/harness/types.d.ts +65 -12
  152. package/dist/harness/types.js +8 -2
  153. package/dist/harness/types.js.map +1 -1
  154. package/dist/harness-adapters.d.ts +12 -8
  155. package/dist/harness-adapters.js +17 -9
  156. package/dist/harness-adapters.js.map +1 -1
  157. package/dist/middleware/approval-gate.d.ts +1 -1
  158. package/dist/middleware/approval-gate.js +1 -1
  159. package/dist/middleware/approval-gate.js.map +1 -1
  160. package/dist/middleware/cost-advisory.d.ts +39 -0
  161. package/dist/middleware/{cost-cap.js → cost-advisory.js} +37 -55
  162. package/dist/middleware/cost-advisory.js.map +1 -0
  163. package/dist/middleware/index.d.ts +23 -12
  164. package/dist/middleware/index.js +26 -18
  165. package/dist/middleware/index.js.map +1 -1
  166. package/dist/middleware/types.d.ts +3 -2
  167. package/dist/runner-manager.js +1 -5
  168. package/dist/runner-manager.js.map +1 -1
  169. package/dist/runner.js +1 -5
  170. package/dist/runner.js.map +1 -1
  171. package/dist/shared/attachment-resolver.d.ts +41 -18
  172. package/dist/shared/attachment-resolver.js +178 -46
  173. package/dist/shared/attachment-resolver.js.map +1 -1
  174. package/dist/shared/attachment-zip.d.ts +85 -0
  175. package/dist/shared/attachment-zip.js +185 -0
  176. package/dist/shared/attachment-zip.js.map +1 -0
  177. package/dist/shared/connect-backfill.js +5 -4
  178. package/dist/shared/connect-backfill.js.map +1 -1
  179. package/dist/shared/cost-guard.d.ts +3 -3
  180. package/dist/shared/cost-guard.js +3 -3
  181. package/dist/shared/execution-status-writer.d.ts +5 -5
  182. package/dist/shared/execution-status-writer.js +5 -5
  183. package/dist/shared/extract-structured-output.d.ts +8 -7
  184. package/dist/shared/extract-structured-output.js +8 -7
  185. package/dist/shared/extract-structured-output.js.map +1 -1
  186. package/dist/shared/filereview/cas-progress.d.ts +1 -18
  187. package/dist/shared/filereview/cas-progress.js +4 -0
  188. package/dist/shared/filereview/cas-progress.js.map +1 -1
  189. package/dist/shared/filereview/cas-touched.d.ts +56 -0
  190. package/dist/shared/filereview/cas-touched.js +63 -0
  191. package/dist/shared/filereview/cas-touched.js.map +1 -0
  192. package/dist/shared/filereview/index.d.ts +2 -1
  193. package/dist/shared/filereview/index.js +2 -1
  194. package/dist/shared/filereview/index.js.map +1 -1
  195. package/dist/shared/mcp-resolver.d.ts +4 -5
  196. package/dist/shared/mcp-resolver.js +4 -5
  197. package/dist/shared/mcp-resolver.js.map +1 -1
  198. package/dist/shared/persist-decision.d.ts +3 -4
  199. package/dist/shared/persist-decision.js +3 -4
  200. package/dist/shared/persist-decision.js.map +1 -1
  201. package/dist/shared/plan-mode-permissions.d.ts +2 -2
  202. package/dist/shared/plan-mode-permissions.js +2 -2
  203. package/dist/shared/plan-mode-prompt.d.ts +1 -1
  204. package/dist/shared/plan-mode-prompt.js +1 -1
  205. package/dist/shared/prompt-sections.d.ts +163 -0
  206. package/dist/shared/prompt-sections.js +164 -0
  207. package/dist/shared/prompt-sections.js.map +1 -0
  208. package/dist/shared/skill-resolver.d.ts +4 -2
  209. package/dist/shared/skill-resolver.js +4 -2
  210. package/dist/shared/skill-resolver.js.map +1 -1
  211. package/dist/shared/tool-rounds.d.ts +32 -0
  212. package/dist/shared/tool-rounds.js +43 -0
  213. package/dist/shared/tool-rounds.js.map +1 -1
  214. package/dist/shared/tool-row.d.ts +34 -0
  215. package/dist/shared/tool-row.js +52 -0
  216. package/dist/shared/tool-row.js.map +1 -1
  217. package/dist/shared/workspace/session-provision.d.ts +3 -3
  218. package/dist/shared/workspace/session-provision.js +3 -3
  219. package/dist/shared/workspace/stigmer-link.d.ts +3 -3
  220. package/dist/shared/workspace/stigmer-link.js +3 -3
  221. package/dist/shared/workspace/writeback-coordinator.d.ts +15 -22
  222. package/dist/shared/workspace/writeback-coordinator.js +16 -53
  223. package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
  224. package/dist/tools/index.d.ts +1 -1
  225. package/dist/tools/index.js +1 -1
  226. package/package.json +4 -4
  227. package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +1 -0
  228. package/src/__test-utils__/execution-record-fixture.ts +18 -2
  229. package/src/__test-utils__/file-review-projection.ts +156 -0
  230. package/src/__test-utils__/git-workspace-fixture.ts +58 -0
  231. package/src/__test-utils__/harness-boot-order-child.ts +7 -2
  232. package/src/__test-utils__/harness-contract/contract.ts +33 -20
  233. package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
  234. package/src/__test-utils__/harness-contract/runtime-contract.ts +328 -10
  235. package/src/__test-utils__/harness-contract/scripted-adapter.ts +38 -6
  236. package/src/__test-utils__/harness-contract/types.ts +27 -3
  237. package/src/__test-utils__/hermetic-activity.ts +52 -14
  238. package/src/__test-utils__/model-registry-fixture.ts +32 -7
  239. package/src/__test-utils__/module-specifiers.ts +24 -0
  240. package/src/__test-utils__/turn-input-fixture.ts +2 -2
  241. package/src/__tests__/harness-boot-order.test.ts +9 -2
  242. package/src/activities/call-agent.ts +2 -2
  243. package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +47 -3
  244. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +2 -48
  245. package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +1 -1
  246. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +6 -1
  247. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +52 -27
  248. package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +25 -0
  249. package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.everything.prompt.md +166 -0
  250. package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.plan-mode.prompt.md +186 -0
  251. package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.recovery.prompt.md +191 -0
  252. package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.reinvocation.prompt.md +13 -0
  253. package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.prefixed.prompt.md +32 -0
  254. package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.raw.prompt.md +1 -0
  255. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -2
  256. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +4 -0
  257. package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +24 -4
  258. package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +6 -5
  259. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +9 -0
  260. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +11 -8
  261. package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +229 -0
  262. package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +3 -3
  263. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +2 -2
  264. package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +78 -234
  265. package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +1 -26
  266. package/src/activities/execute-cursor/adapter.ts +7 -5
  267. package/src/activities/execute-cursor/approval-policy.ts +5 -2
  268. package/src/activities/execute-cursor/approval-state.ts +16 -8
  269. package/src/activities/execute-cursor/cas-observations.ts +20 -2
  270. package/src/activities/execute-cursor/cursor-capabilities.ts +24 -5
  271. package/src/activities/execute-cursor/message-translator.ts +29 -41
  272. package/src/activities/execute-cursor/prompt-builder.ts +99 -157
  273. package/src/activities/execute-cursor/turn-boundary.ts +34 -140
  274. package/src/activities/execute-cursor/turn-settle.ts +37 -51
  275. package/src/activities/execute-cursor/turn-setup.ts +30 -70
  276. package/src/activities/execute-cursor/turn-stream.ts +8 -31
  277. package/src/activities/execute-cursor/turn.ts +5 -1
  278. package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +391 -0
  279. package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +313 -0
  280. package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +48 -0
  281. package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +85 -0
  282. package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +383 -36
  283. package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +76 -0
  284. package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +47 -0
  285. package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +80 -0
  286. package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +1 -1
  287. package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -2
  288. package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -3
  289. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +172 -0
  290. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +167 -0
  291. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.minimal.prompt.md +36 -0
  292. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +178 -0
  293. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +158 -0
  294. package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +210 -0
  295. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +74 -0
  296. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +104 -0
  297. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +78 -0
  298. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +138 -0
  299. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +68 -0
  300. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +154 -0
  301. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +116 -0
  302. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +69 -0
  303. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +67 -0
  304. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/plain-turn.status.json +47 -0
  305. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +68 -0
  306. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +280 -0
  307. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +77 -0
  308. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
  309. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +99 -0
  310. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +109 -0
  311. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +76 -0
  312. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.text-fallback.status.json +51 -0
  313. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tier2.status.json +51 -0
  314. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tool-strategy.status.json +56 -0
  315. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +90 -0
  316. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +70 -0
  317. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +71 -0
  318. package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +144 -0
  319. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +184 -0
  320. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +203 -0
  321. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +170 -0
  322. package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +175 -0
  323. package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +206 -0
  324. package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +142 -0
  325. package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +126 -0
  326. package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +139 -0
  327. package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +122 -0
  328. package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +236 -0
  329. package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +161 -0
  330. package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +157 -0
  331. package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +152 -0
  332. package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +50 -122
  333. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +8 -6
  334. package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +2 -2
  335. package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +35 -35
  336. package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +247 -0
  337. package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +329 -0
  338. package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +1 -20
  339. package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +78 -0
  340. package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +1 -1
  341. package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +2 -2
  342. package/src/activities/execute-deep-agent/__tests__/subagent-tracker.test.ts +57 -31
  343. package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +19 -79
  344. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +15 -15
  345. package/src/activities/execute-deep-agent/__tests__/summarization-verification.test.ts +1 -1
  346. package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +391 -0
  347. package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +343 -38
  348. package/src/activities/execute-deep-agent/__tests__/vision-input.test.ts +5 -5
  349. package/src/activities/execute-deep-agent/adapter.ts +94 -0
  350. package/src/activities/execute-deep-agent/cas-capture-observer.ts +11 -0
  351. package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +43 -0
  352. package/src/activities/execute-deep-agent/execution-state.ts +4 -13
  353. package/src/activities/execute-deep-agent/hitl.ts +100 -123
  354. package/src/activities/execute-deep-agent/prompt-builder.ts +141 -115
  355. package/src/activities/execute-deep-agent/status-builder-shared.ts +21 -84
  356. package/src/activities/execute-deep-agent/streaming-side-effects.ts +13 -19
  357. package/src/activities/execute-deep-agent/subagent-tracker.ts +77 -42
  358. package/src/activities/execute-deep-agent/subagent-transformer.ts +46 -105
  359. package/src/activities/execute-deep-agent/subagent-wiring.ts +5 -4
  360. package/src/activities/execute-deep-agent/turn-settle.ts +164 -0
  361. package/src/activities/execute-deep-agent/turn-setup.ts +541 -0
  362. package/src/activities/execute-deep-agent/turn-stream.ts +313 -0
  363. package/src/activities/execute-deep-agent/turn.ts +131 -0
  364. package/src/activities/execute-deep-agent/v3-event-recorder.ts +6 -5
  365. package/src/activities/execute-deep-agent/v3-events.ts +1 -1
  366. package/src/activities/execute-deep-agent/v3-status-builder.ts +84 -63
  367. package/src/harness/__tests__/approval-decisions.test.ts +116 -0
  368. package/src/harness/__tests__/capture.test.ts +268 -0
  369. package/src/harness/__tests__/mount-skills.test.ts +169 -0
  370. package/src/harness/__tests__/persist-chokepoint.test.ts +38 -2
  371. package/src/harness/__tests__/run-turn-deterministic.test.ts +94 -0
  372. package/src/harness/__tests__/run-turn.test.ts +39 -23
  373. package/src/harness/__tests__/turn-attachments-vision.test.ts +80 -0
  374. package/src/harness/__tests__/turn-context.test.ts +73 -26
  375. package/src/harness/approval-decisions.ts +104 -0
  376. package/src/harness/capabilities.ts +16 -5
  377. package/src/harness/capture.ts +301 -0
  378. package/src/harness/persist-chokepoint.ts +24 -4
  379. package/src/harness/run-turn.ts +120 -29
  380. package/src/harness/terminal-table.ts +61 -20
  381. package/src/harness/turn-context.ts +208 -111
  382. package/src/harness/types.ts +66 -12
  383. package/src/harness-adapters.ts +17 -9
  384. package/src/middleware/__tests__/approval-gate.test.ts +1 -1
  385. package/src/middleware/__tests__/cost-advisory.test.ts +113 -0
  386. package/src/middleware/approval-gate.ts +2 -2
  387. package/src/middleware/{cost-cap.ts → cost-advisory.ts} +40 -70
  388. package/src/middleware/index.ts +29 -29
  389. package/src/middleware/types.ts +3 -2
  390. package/src/runner-manager.ts +0 -8
  391. package/src/runner.ts +0 -8
  392. package/src/shared/__tests__/attachment-naming.test.ts +6 -19
  393. package/src/shared/__tests__/attachment-resolver.test.ts +158 -8
  394. package/src/shared/__tests__/attachment-zip.test.ts +236 -0
  395. package/src/shared/__tests__/bedrock-adapter.test.ts +1 -1
  396. package/src/shared/__tests__/blueprint-resolver.test.ts +43 -0
  397. package/src/shared/__tests__/cost-guard.test.ts +3 -3
  398. package/src/shared/__tests__/prompt-sections.test.ts +167 -0
  399. package/src/shared/__tests__/secret-leak-scan.test.ts +2 -2
  400. package/src/{activities/execute-deep-agent → shared}/__tests__/stamp-flowed-rows.test.ts +33 -10
  401. package/src/shared/__tests__/vertex-adapter.test.ts +1 -1
  402. package/src/shared/attachment-resolver.ts +218 -55
  403. package/src/shared/attachment-zip.ts +281 -0
  404. package/src/shared/connect-backfill.ts +9 -11
  405. package/src/shared/cost-guard.ts +3 -3
  406. package/src/shared/execution-status-writer.ts +5 -5
  407. package/src/shared/extract-structured-output.ts +8 -7
  408. package/src/shared/filereview/__tests__/capture.test.ts +86 -4
  409. package/src/shared/filereview/__tests__/cas-progress.test.ts +2 -1
  410. package/src/shared/filereview/cas-progress.ts +5 -19
  411. package/src/shared/filereview/cas-touched.ts +89 -0
  412. package/src/shared/filereview/index.ts +4 -2
  413. package/src/shared/mcp-resolver.ts +4 -5
  414. package/src/shared/persist-decision.ts +3 -4
  415. package/src/shared/plan-mode-permissions.ts +2 -2
  416. package/src/shared/plan-mode-prompt.ts +1 -1
  417. package/src/shared/prompt-sections.ts +256 -0
  418. package/src/shared/skill-resolver.ts +4 -2
  419. package/src/shared/tool-rounds.ts +48 -0
  420. package/src/shared/tool-row.ts +61 -0
  421. package/src/shared/workspace/__tests__/stigmer-link.test.ts +7 -22
  422. package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +20 -61
  423. package/src/shared/workspace/session-provision.ts +3 -3
  424. package/src/shared/workspace/stigmer-link.ts +3 -3
  425. package/src/shared/workspace/writeback-coordinator.ts +16 -64
  426. package/src/tools/index.ts +1 -1
  427. package/dist/activities/execute-cursor/capture-flow.d.ts +0 -142
  428. package/dist/activities/execute-cursor/capture-flow.js +0 -285
  429. package/dist/activities/execute-cursor/capture-flow.js.map +0 -1
  430. package/dist/activities/execute-cursor/command-provenance.d.ts +0 -48
  431. package/dist/activities/execute-cursor/command-provenance.js +0 -38
  432. package/dist/activities/execute-cursor/command-provenance.js.map +0 -1
  433. package/dist/activities/execute-deep-agent/attachment-injector.d.ts +0 -134
  434. package/dist/activities/execute-deep-agent/attachment-injector.js +0 -386
  435. package/dist/activities/execute-deep-agent/attachment-injector.js.map +0 -1
  436. package/dist/activities/execute-deep-agent/command-provenance.d.ts +0 -61
  437. package/dist/activities/execute-deep-agent/command-provenance.js +0 -72
  438. package/dist/activities/execute-deep-agent/command-provenance.js.map +0 -1
  439. package/dist/activities/execute-deep-agent/environment.d.ts +0 -24
  440. package/dist/activities/execute-deep-agent/environment.js +0 -58
  441. package/dist/activities/execute-deep-agent/environment.js.map +0 -1
  442. package/dist/activities/execute-deep-agent/event-recorder.d.ts +0 -21
  443. package/dist/activities/execute-deep-agent/event-recorder.js +0 -67
  444. package/dist/activities/execute-deep-agent/event-recorder.js.map +0 -1
  445. package/dist/activities/execute-deep-agent/index.d.ts +0 -15
  446. package/dist/activities/execute-deep-agent/index.js +0 -918
  447. package/dist/activities/execute-deep-agent/index.js.map +0 -1
  448. package/dist/activities/execute-deep-agent/mcp-gate.d.ts +0 -28
  449. package/dist/activities/execute-deep-agent/mcp-gate.js +0 -22
  450. package/dist/activities/execute-deep-agent/mcp-gate.js.map +0 -1
  451. package/dist/activities/execute-deep-agent/post-stream.d.ts +0 -23
  452. package/dist/activities/execute-deep-agent/post-stream.js +0 -71
  453. package/dist/activities/execute-deep-agent/post-stream.js.map +0 -1
  454. package/dist/activities/execute-deep-agent/setup.d.ts +0 -136
  455. package/dist/activities/execute-deep-agent/setup.js +0 -767
  456. package/dist/activities/execute-deep-agent/setup.js.map +0 -1
  457. package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +0 -36
  458. package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +0 -56
  459. package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +0 -1
  460. package/dist/activities/execute-deep-agent/status-builder.d.ts +0 -93
  461. package/dist/activities/execute-deep-agent/status-builder.js +0 -365
  462. package/dist/activities/execute-deep-agent/status-builder.js.map +0 -1
  463. package/dist/activities/execute-deep-agent/streaming-terminal.d.ts +0 -21
  464. package/dist/activities/execute-deep-agent/streaming-terminal.js +0 -80
  465. package/dist/activities/execute-deep-agent/streaming-terminal.js.map +0 -1
  466. package/dist/activities/execute-deep-agent/streaming-v3.d.ts +0 -13
  467. package/dist/activities/execute-deep-agent/streaming-v3.js +0 -174
  468. package/dist/activities/execute-deep-agent/streaming-v3.js.map +0 -1
  469. package/dist/activities/execute-deep-agent/streaming.d.ts +0 -81
  470. package/dist/activities/execute-deep-agent/streaming.js +0 -160
  471. package/dist/activities/execute-deep-agent/streaming.js.map +0 -1
  472. package/dist/middleware/cost-cap.d.ts +0 -22
  473. package/dist/middleware/cost-cap.js.map +0 -1
  474. package/dist/middleware/graceful-stop.d.ts +0 -17
  475. package/dist/middleware/graceful-stop.js +0 -63
  476. package/dist/middleware/graceful-stop.js.map +0 -1
  477. package/dist/shared/skill-writer.d.ts +0 -75
  478. package/dist/shared/skill-writer.js +0 -207
  479. package/dist/shared/skill-writer.js.map +0 -1
  480. package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +0 -1032
  481. package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +0 -240
  482. package/src/activities/execute-cursor/__tests__/progress-substrate.test.ts +0 -169
  483. package/src/activities/execute-cursor/capture-flow.ts +0 -379
  484. package/src/activities/execute-cursor/command-provenance.ts +0 -73
  485. package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +0 -1161
  486. package/src/activities/execute-deep-agent/__tests__/command-provenance.test.ts +0 -252
  487. package/src/activities/execute-deep-agent/__tests__/environment.test.ts +0 -108
  488. package/src/activities/execute-deep-agent/__tests__/event-recorder.test.ts +0 -150
  489. package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +0 -226
  490. package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +0 -318
  491. package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +0 -351
  492. package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +0 -293
  493. package/src/activities/execute-deep-agent/__tests__/index.test.ts +0 -99
  494. package/src/activities/execute-deep-agent/__tests__/mcp-gate.test.ts +0 -44
  495. package/src/activities/execute-deep-agent/__tests__/post-stream.test.ts +0 -112
  496. package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +0 -358
  497. package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +0 -1933
  498. package/src/activities/execute-deep-agent/__tests__/streaming-terminal.test.ts +0 -40
  499. package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +0 -597
  500. package/src/activities/execute-deep-agent/__tests__/streaming.test.ts +0 -508
  501. package/src/activities/execute-deep-agent/attachment-injector.ts +0 -627
  502. package/src/activities/execute-deep-agent/command-provenance.ts +0 -102
  503. package/src/activities/execute-deep-agent/environment.ts +0 -76
  504. package/src/activities/execute-deep-agent/event-recorder.ts +0 -95
  505. package/src/activities/execute-deep-agent/index.ts +0 -1072
  506. package/src/activities/execute-deep-agent/mcp-gate.ts +0 -37
  507. package/src/activities/execute-deep-agent/post-stream.ts +0 -109
  508. package/src/activities/execute-deep-agent/setup.ts +0 -1081
  509. package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +0 -64
  510. package/src/activities/execute-deep-agent/status-builder.ts +0 -481
  511. package/src/activities/execute-deep-agent/streaming-terminal.ts +0 -106
  512. package/src/activities/execute-deep-agent/streaming-v3.ts +0 -277
  513. package/src/activities/execute-deep-agent/streaming.ts +0 -313
  514. package/src/middleware/__tests__/cost-cap.test.ts +0 -192
  515. package/src/middleware/__tests__/graceful-stop.test.ts +0 -105
  516. package/src/middleware/graceful-stop.ts +0 -86
  517. package/src/shared/__tests__/skill-writer.test.ts +0 -372
  518. package/src/shared/skill-writer.ts +0 -266
@@ -1,10 +1,14 @@
1
1
  import { describe, it, expect, beforeEach } from "vitest";
2
2
  import { create } from "@bufbuild/protobuf";
3
3
  import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
4
- import { ExecutionPhase, MessageType, ToolCallStatus, ToolKind, TodoStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
4
+ import { ApprovalAction, ExecutionPhase, MessageType, ToolCallStatus, ToolKind, TodoStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
5
+ import { AgentMessageSchema, ToolCallSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
6
+ import { ExecutionArtifactSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/artifact_pb";
7
+ import { WorkspaceWriteBackSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/writeback_pb";
5
8
  import { V3StatusBuilder } from "../v3-status-builder.js";
6
9
  import { normalize } from "../v3-protocol-normalizer.js";
7
- import type { ApprovalPolicyProvider } from "../status-builder.js";
10
+ import type { ApprovalPolicyProvider } from "../status-builder-shared.js";
11
+ import type { MergedToolPolicy } from "../../../shared/approval-policy.js";
8
12
  import {
9
13
  resetSeq,
10
14
  makeMessageStart,
@@ -20,8 +24,38 @@ import {
20
24
  } from "../__test-utils__/v3-event-fixtures.js";
21
25
  import type { V3ProtocolEvent } from "../v3-event-recorder.js";
22
26
 
27
+ /**
28
+ * What the builder REPORTED through `onUsage`, summed by the test the way an
29
+ * accountant would (the builder itself sums nothing and writes no
30
+ * `streamingUsage`; the runtime does, priced, through the sink).
31
+ */
32
+ interface ReportedUsage {
33
+ inputTokens: number;
34
+ outputTokens: number;
35
+ cacheReadTokens: number;
36
+ cacheWriteTokens: number;
37
+ turnCount: number;
38
+ }
39
+
40
+ const reportedByBuilder = new WeakMap<V3StatusBuilder, ReportedUsage>();
41
+
23
42
  function makeBuilder(): V3StatusBuilder {
24
- return new V3StatusBuilder("exec-test", create(AgentExecutionStatusSchema, {}));
43
+ const reported: ReportedUsage = { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, turnCount: 0 };
44
+ const sb = new V3StatusBuilder("exec-test", create(AgentExecutionStatusSchema, {}), {
45
+ onUsage: (usage) => {
46
+ reported.inputTokens += usage.input_tokens ?? 0;
47
+ reported.outputTokens += usage.output_tokens ?? 0;
48
+ reported.cacheReadTokens += usage.input_token_details?.cache_read ?? 0;
49
+ reported.cacheWriteTokens += usage.input_token_details?.cache_creation ?? 0;
50
+ reported.turnCount += 1;
51
+ },
52
+ });
53
+ reportedByBuilder.set(sb, reported);
54
+ return sb;
55
+ }
56
+
57
+ function reportedUsage(sb: V3StatusBuilder): ReportedUsage {
58
+ return reportedByBuilder.get(sb)!;
25
59
  }
26
60
 
27
61
  function feedAll(sb: V3StatusBuilder, events: V3ProtocolEvent[]): void {
@@ -39,14 +73,11 @@ describe("V3StatusBuilder", () => {
39
73
  // ── Initialization ───────────────────────────────────────────────
40
74
 
41
75
  describe("initialization", () => {
42
- it("sets phase to IN_PROGRESS on construction", () => {
76
+ it("writes neither phase nor startedAt (the turn runtime owns both; S3 M2a, Q-M2a-7)", () => {
43
77
  const sb = makeBuilder();
44
- expect(sb.currentStatus.phase).toBe(ExecutionPhase.EXECUTION_IN_PROGRESS);
45
- });
46
-
47
- it("sets startedAt on construction", () => {
48
- const sb = makeBuilder();
49
- expect(sb.currentStatus.startedAt).toBeTruthy();
78
+ expect(sb.currentStatus.phase).toBe(ExecutionPhase.EXECUTION_PHASE_UNSPECIFIED);
79
+ expect(sb.currentStatus.startedAt).toBe("");
80
+ expect(sb.awaitingApproval).toBe(false);
50
81
  });
51
82
 
52
83
  it("starts with forceNextUpdate = false", () => {
@@ -95,13 +126,11 @@ describe("V3StatusBuilder", () => {
95
126
  expect(status.messages[1].content).toBe("Here is more detail.");
96
127
  expect(status.messages[1].isStreaming).toBe(false);
97
128
 
98
- const usage = status.streamingUsage!;
99
- expect(usage.inputTokens).toBe(130n);
100
- expect(usage.outputTokens).toBe(20n);
129
+ const usage = reportedUsage(sb);
130
+ expect(usage.inputTokens).toBe(130);
131
+ expect(usage.outputTokens).toBe(20);
101
132
  expect(usage.turnCount).toBe(2);
102
- expect(usage.totalTokens).toBe(150n);
103
-
104
- expect(status.phase).toBe(ExecutionPhase.EXECUTION_IN_PROGRESS);
133
+ expect(status.streamingUsage, "the runtime owns streamingUsage; the builder reports").toBeUndefined();
105
134
  });
106
135
  });
107
136
 
@@ -144,12 +173,11 @@ describe("V3StatusBuilder", () => {
144
173
  expect(status.messages[2].content).toBe("Let me elaborate.");
145
174
  expect(status.messages[2].isStreaming).toBe(false);
146
175
 
147
- const usage = status.streamingUsage!;
148
- expect(usage.inputTokens).toBe(500n);
149
- expect(usage.outputTokens).toBe(120n);
150
- expect(usage.cacheReadTokens).toBe(50n);
176
+ const usage = reportedUsage(sb);
177
+ expect(usage.inputTokens).toBe(500);
178
+ expect(usage.outputTokens).toBe(120);
179
+ expect(usage.cacheReadTokens).toBe(50);
151
180
  expect(usage.turnCount).toBe(2);
152
- expect(usage.totalTokens).toBe(670n);
153
181
  });
154
182
  });
155
183
 
@@ -197,9 +225,9 @@ describe("V3StatusBuilder", () => {
197
225
  expect(secondMsg.content).toBe("The file contains a main function that logs 'hello'.");
198
226
  expect(secondMsg.toolCalls).toHaveLength(0);
199
227
 
200
- const usage = status.streamingUsage!;
201
- expect(usage.inputTokens).toBe(300n);
202
- expect(usage.outputTokens).toBe(35n);
228
+ const usage = reportedUsage(sb);
229
+ expect(usage.inputTokens).toBe(300);
230
+ expect(usage.outputTokens).toBe(35);
203
231
  expect(usage.turnCount).toBe(2);
204
232
  });
205
233
  });
@@ -293,7 +321,8 @@ describe("V3StatusBuilder", () => {
293
321
  ]);
294
322
 
295
323
  const status = sb.currentStatus;
296
- expect(status.phase).toBe(ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL);
324
+ expect(sb.awaitingApproval, "a fact for the caller, never a phase write").toBe(true);
325
+ expect(status.phase).toBe(ExecutionPhase.EXECUTION_PHASE_UNSPECIFIED);
297
326
 
298
327
  const tc = status.messages[0].toolCalls[0];
299
328
  expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_WAITING_APPROVAL);
@@ -338,14 +367,12 @@ describe("V3StatusBuilder", () => {
338
367
  }),
339
368
  ]);
340
369
 
341
- const usage = sb.currentStatus.streamingUsage!;
342
- expect(usage.inputTokens).toBe(600n);
343
- expect(usage.outputTokens).toBe(60n);
344
- expect(usage.cacheWriteTokens).toBe(80n);
345
- expect(usage.cacheReadTokens).toBe(150n);
370
+ const usage = reportedUsage(sb);
371
+ expect(usage.inputTokens).toBe(600);
372
+ expect(usage.outputTokens).toBe(60);
373
+ expect(usage.cacheWriteTokens).toBe(80);
374
+ expect(usage.cacheReadTokens).toBe(150);
346
375
  expect(usage.turnCount).toBe(3);
347
- expect(usage.totalTokens).toBe(890n);
348
- expect(usage.observedAt).toBeTruthy();
349
376
  });
350
377
  });
351
378
 
@@ -406,9 +433,9 @@ describe("V3StatusBuilder", () => {
406
433
  expect(status.messages[3].type).toBe(MessageType.MESSAGE_AI);
407
434
  expect(status.messages[3].content).toBe("The research is complete.");
408
435
 
409
- const usage = status.streamingUsage!;
410
- expect(usage.inputTokens).toBe(650n);
411
- expect(usage.outputTokens).toBe(50n);
436
+ const usage = reportedUsage(sb);
437
+ expect(usage.inputTokens).toBe(650);
438
+ expect(usage.outputTokens).toBe(50);
412
439
  expect(usage.turnCount).toBe(3);
413
440
  });
414
441
  });
@@ -442,9 +469,9 @@ describe("V3StatusBuilder", () => {
442
469
  }),
443
470
  ]);
444
471
 
445
- const usage = sb.currentStatus.streamingUsage!;
446
- expect(usage.inputTokens).toBe(50n);
447
- expect(usage.outputTokens).toBe(10n);
472
+ const usage = reportedUsage(sb);
473
+ expect(usage.inputTokens).toBe(50);
474
+ expect(usage.outputTokens).toBe(10);
448
475
  expect(usage.turnCount).toBe(1);
449
476
  });
450
477
 
@@ -586,6 +613,26 @@ describe("V3StatusBuilder", () => {
586
613
  expect(todos["todo-0"].status).toBe(TodoStatus.TODO_COMPLETED);
587
614
  });
588
615
 
616
+ it("reports a sub-agent's usage through the same hook as the parent's (S3 M2b, Q-M2b-1)", () => {
617
+ const sb = makeBuilder();
618
+ const subNs = ["tools:task-1", "model_request:sub-run"];
619
+ feedAll(sb, [
620
+ ...[makeMessageStart("parent-1"), makeTextDelta("parent-1", "Delegating."), makeMessageFinish("parent-1", { usage: { input_tokens: 1_000, output_tokens: 10 } })],
621
+ makeToolStarted("task-1", "task", { subagent_type: "worker", description: "delegate" }),
622
+ makeMessageStart("sub-run", { namespace: subNs }),
623
+ makeTextDelta("sub-run", "Working on it.", { namespace: subNs }),
624
+ makeMessageFinish("sub-run", { namespace: subNs, usage: { input_tokens: 600, output_tokens: 12 } }),
625
+ ]);
626
+
627
+ const usage = reportedUsage(sb);
628
+ expect(usage.inputTokens, "the parent's 1,000 and the sub-agent's 600").toBe(1_600);
629
+ expect(usage.outputTokens).toBe(22);
630
+ expect(usage.turnCount).toBe(2);
631
+ // The transcript still routes the sub-agent's message to its own row, never the parent's.
632
+ expect(sb.currentStatus.messages.map((m) => m.content)).toEqual(["Delegating."]);
633
+ expect(sb.currentStatus.subAgentExecutions).toHaveLength(1);
634
+ });
635
+
589
636
  it("does not project a sub-agent's write_todos into parent status.todos", () => {
590
637
  const sb = makeBuilder();
591
638
  const subNs = ["tools:task-1", "tools:sub-todo"];
@@ -608,4 +655,262 @@ describe("V3StatusBuilder", () => {
608
655
  expect(Object.keys(sb.currentStatus.todos)).toHaveLength(0);
609
656
  });
610
657
  });
658
+ // ═══════════════════════════════════════════════════════════════════
659
+ // Carried from the v2 StatusBuilder's suite when that builder retired
660
+ // with the v2 stream (S3 M2b, Q-S3-1 / Q-M2b-5): every rule below is the
661
+ // builder's own — how a policy decides a row's status, what the row
662
+ // carries, how a seeded row is resolved, how artifacts and write-backs
663
+ // are upserted — and had no v3 twin. The sanitizer's own rules
664
+ // (redaction, truncation) are `shared/__tests__/args-preview.test.ts`'s.
665
+ // ═══════════════════════════════════════════════════════════════════
666
+
667
+ function providerWith(overrides: Partial<ApprovalPolicyProvider> = {}): ApprovalPolicyProvider {
668
+ return { policies: new Map(), toolServerMap: new Map(), globalBypass: false, ...overrides };
669
+ }
670
+
671
+ function policyFor(serverSlug: string, toolName: string, message = "Approve?"): [string, MergedToolPolicy] {
672
+ return [
673
+ `${serverSlug}/${toolName}`,
674
+ { toolName, mcpServerSlug: serverSlug, requiresApproval: true, approvalMessage: message, source: "classifier_default" },
675
+ ];
676
+ }
677
+
678
+ /** A text turn, then one tool start, on a builder with the given provider. */
679
+ function firstToolCallUnder(provider: ApprovalPolicyProvider, toolName: string, input: Record<string, unknown> = {}) {
680
+ const sb = makeBuilder();
681
+ sb.setApprovalProvider(provider);
682
+ feedAll(sb, [
683
+ makeMessageStart("run-1"),
684
+ makeTextDelta("run-1", "Working."),
685
+ makeMessageFinish("run-1", { usage: { input_tokens: 10, output_tokens: 5 } }),
686
+ makeToolStarted("toolu_1", toolName, input),
687
+ ]);
688
+ return { sb, tc: sb.currentStatus.messages[0].toolCalls[0] };
689
+ }
690
+
691
+ describe("approval provider: what decides a row's status", () => {
692
+ it("a policy that requires approval leaves the row WAITING_APPROVAL with its message and server", () => {
693
+ const [key, policy] = policyFor("github", "create_issue");
694
+ const { sb, tc } = firstToolCallUnder(
695
+ providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["create_issue", "github"]]) }),
696
+ "create_issue",
697
+ { title: "Bug fix" },
698
+ );
699
+ expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_WAITING_APPROVAL);
700
+ expect(tc.requiresApproval).toBe(true);
701
+ expect(tc.approvalMessage).toBe("Approve?");
702
+ expect(tc.mcpServerSlug).toBe("github");
703
+ expect(tc.approvalRequestedAt, "stamped when approval is required").toContain("T");
704
+ expect(sb.awaitingApproval).toBe(true);
705
+ });
706
+
707
+ it("the global bypass (spec.auto_approve_all) runs a gated tool without approval", () => {
708
+ const [key, policy] = policyFor("github", "delete_repo");
709
+ const { sb, tc } = firstToolCallUnder(
710
+ providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["delete_repo", "github"]]), globalBypass: true }),
711
+ "delete_repo",
712
+ );
713
+ expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_RUNNING);
714
+ expect(tc.requiresApproval).toBe(false);
715
+ expect(sb.awaitingApproval).toBe(false);
716
+ });
717
+
718
+ it("the global bypass still attributes the row to its MCP server", () => {
719
+ const { tc } = firstToolCallUnder(
720
+ providerWith({ toolServerMap: new Map([["echo", "test-mcp-server"]]), globalBypass: true }),
721
+ "echo",
722
+ { input: "hello" },
723
+ );
724
+ expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_RUNNING);
725
+ expect(tc.mcpServerSlug).toBe("test-mcp-server");
726
+ });
727
+
728
+ it("a tool with no policy runs, attributed to its server", () => {
729
+ const { tc } = firstToolCallUnder(providerWith({ toolServerMap: new Map([["read", "filesystem"]]) }), "read");
730
+ expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_RUNNING);
731
+ expect(tc.mcpServerSlug).toBe("filesystem");
732
+ });
733
+
734
+ it("a policy whose tool is not in the server map does not gate (the policy key needs the server)", () => {
735
+ const [key, policy] = policyFor("github", "create_pr");
736
+ const { tc } = firstToolCallUnder(providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map() }), "create_pr");
737
+ expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_RUNNING);
738
+ });
739
+
740
+ it("resolves {{args.field}} placeholders in the approval message", () => {
741
+ const [key, policy] = policyFor("github", "create_issue", "Create issue '{{args.title}}' in {{args.repo}}?");
742
+ const { tc } = firstToolCallUnder(
743
+ providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["create_issue", "github"]]) }),
744
+ "create_issue",
745
+ { title: "Fix crash", repo: "stigmer/stigmer" },
746
+ );
747
+ expect(tc.approvalMessage).toBe("Create issue 'Fix crash' in stigmer/stigmer?");
748
+ });
749
+ });
750
+
751
+ describe("args preview: when the builder writes one", () => {
752
+ it("a gated row carries a sanitized preview; an ungated row carries none", () => {
753
+ const [key, policy] = policyFor("db", "connect");
754
+ const gated = firstToolCallUnder(
755
+ providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["connect", "db"]]) }),
756
+ "connect",
757
+ { host: "localhost", password: "super-secret" },
758
+ );
759
+ const preview = JSON.parse(gated.tc.argsPreview) as Record<string, string>;
760
+ expect(preview.host).toBe("localhost");
761
+ expect(preview.password, "the shared sanitizer redacts secret keys").toBe("[REDACTED]");
762
+
763
+ const ungated = firstToolCallUnder(providerWith(), "read", { path: "/foo" });
764
+ expect(ungated.tc.argsPreview).toBe("");
765
+ });
766
+
767
+ it("an unserializable input leaves the preview empty instead of failing the row", () => {
768
+ const [key, policy] = policyFor("api", "call");
769
+ const circular: Record<string, unknown> = {};
770
+ circular.self = circular;
771
+ const { tc } = firstToolCallUnder(
772
+ providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["call", "api"]]) }),
773
+ "call",
774
+ circular,
775
+ );
776
+ expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_WAITING_APPROVAL);
777
+ expect(tc.argsPreview).toBe("");
778
+ });
779
+ });
780
+
781
+ describe("tool rows without a preceding text turn, and interleaving", () => {
782
+ it("a tool start with no prior text creates the AI message that carries it", () => {
783
+ const sb = makeBuilder();
784
+ feedAll(sb, [makeToolStarted("orphan", "read", {})]);
785
+ expect(sb.currentStatus.messages).toHaveLength(1);
786
+ expect(sb.currentStatus.messages[0].toolCalls[0].name).toBe("read");
787
+ });
788
+
789
+ it("interleaved start/finish pairs settle each row independently", () => {
790
+ const sb = makeBuilder();
791
+ feedAll(sb, [
792
+ makeMessageStart("run-1"),
793
+ makeTextDelta("run-1", "working"),
794
+ makeMessageFinish("run-1", { usage: { input_tokens: 1, output_tokens: 1 } }),
795
+ makeToolStarted("toolu_a", "read", {}),
796
+ makeToolFinished("toolu_a", "data 1"),
797
+ makeToolStarted("toolu_b", "write", {}),
798
+ makeToolFinished("toolu_b", "done"),
799
+ ]);
800
+ const rows = sb.currentStatus.messages.flatMap((m) => m.toolCalls);
801
+ expect(rows.map((r) => r.status)).toEqual([ToolCallStatus.TOOL_CALL_COMPLETED, ToolCallStatus.TOOL_CALL_COMPLETED]);
802
+ });
803
+ });
804
+
805
+ describe("a handler that throws", () => {
806
+ it("is logged with the execution, the event kind and its seq, and never escapes processEvent", () => {
807
+ const sb = makeBuilder();
808
+ const errors: string[] = [];
809
+ const original = console.error;
810
+ console.error = (msg: unknown) => { errors.push(String(msg)); };
811
+ try {
812
+ const poisoned = normalize(makeToolFinished("toolu_x", "ok"))[0]!;
813
+ // A getter that throws where the handler reads the output.
814
+ const event = { ...poisoned, get output(): unknown { throw new Error("property access failed"); } };
815
+ expect(() => sb.processEvent(event as typeof poisoned)).not.toThrow();
816
+ } finally {
817
+ console.error = original;
818
+ }
819
+ expect(errors).toHaveLength(1);
820
+ expect(errors[0]).toContain("exec-test");
821
+ expect(errors[0]).toContain("kind=tool_finished");
822
+ expect(errors[0]).toMatch(/seq=\d+/);
823
+ });
824
+ });
825
+
826
+ describe("resume reconciliation (a seeded WAITING row on a durable checkpoint)", () => {
827
+ const GATED_ID = "toolu_seeded_01";
828
+
829
+ it("resolves the seeded gated row in place — no duplicate, history kept, no re-gate", () => {
830
+ const status = create(AgentExecutionStatusSchema, {
831
+ phase: ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
832
+ messages: [
833
+ create(AgentMessageSchema, {
834
+ type: MessageType.MESSAGE_AI,
835
+ content: "I'll call the gated tool.",
836
+ toolCalls: [
837
+ create(ToolCallSchema, {
838
+ id: GATED_ID,
839
+ name: "dangerous_tool",
840
+ status: ToolCallStatus.TOOL_CALL_WAITING_APPROVAL,
841
+ requiresApproval: true,
842
+ approvalAction: ApprovalAction.APPROVE,
843
+ mcpServerSlug: "my-server",
844
+ }),
845
+ ],
846
+ }),
847
+ ],
848
+ });
849
+ const sb = new V3StatusBuilder("exec-resume", status);
850
+ const [key, policy] = policyFor("my-server", "dangerous_tool", "Execute dangerous_tool");
851
+ sb.setApprovalProvider(providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["dangerous_tool", "my-server"]]) }));
852
+
853
+ // The durable checkpoint re-emits the SAME tool_call_id now that approval is granted.
854
+ feedAll(sb, [
855
+ makeToolStarted(GATED_ID, "dangerous_tool", { target: "prod" }),
856
+ makeToolFinished(GATED_ID, "tool executed ok"),
857
+ makeMessageStart("llm-after"),
858
+ makeTextDelta("llm-after", "All done."),
859
+ makeMessageFinish("llm-after", { usage: { input_tokens: 1, output_tokens: 1 } }),
860
+ ]);
861
+
862
+ const gated = sb.currentStatus.messages.flatMap((m) => m.toolCalls).filter((tc) => tc.id === GATED_ID);
863
+ expect(gated).toHaveLength(1);
864
+ expect(gated[0].status).toBe(ToolCallStatus.TOOL_CALL_COMPLETED);
865
+ expect(gated[0].result).toContain("tool executed ok");
866
+ expect(gated[0].args, "the resumed start fills the args the seed lacked").toEqual({ target: "prod" });
867
+ const allText = sb.currentStatus.messages.map((m) => m.content).join("\n");
868
+ expect(allText).toContain("I'll call the gated tool.");
869
+ expect(allText).toContain("All done.");
870
+ expect(sb.awaitingApproval, "a resumed tool never re-gates").toBe(false);
871
+ });
872
+ });
873
+
874
+ describe("artifacts and write-backs (the ExecutionStatusWriter face)", () => {
875
+ const artifact = (sandboxPath: string, contentHash: string) =>
876
+ create(ExecutionArtifactSchema, { sandboxPath, contentHash, storageKey: `k/${contentHash}` });
877
+
878
+ it("appends a new artifact and forces the next persist", () => {
879
+ const sb = makeBuilder();
880
+ sb.addArtifact(artifact("out/a.txt", "h1"));
881
+ expect(sb.currentStatus.artifacts).toHaveLength(1);
882
+ expect(sb.forceNextUpdate).toBe(true);
883
+ });
884
+
885
+ it("deduplicates by sandboxPath: the same contentHash is a no-op that does not force a persist", () => {
886
+ const sb = makeBuilder();
887
+ sb.addArtifact(artifact("out/a.txt", "h1"));
888
+ sb.clearForceFlag();
889
+ sb.addArtifact(artifact("out/a.txt", "h1"));
890
+ expect(sb.currentStatus.artifacts).toHaveLength(1);
891
+ expect(sb.forceNextUpdate).toBe(false);
892
+ });
893
+
894
+ it("replaces the artifact in place when its contentHash changes", () => {
895
+ const sb = makeBuilder();
896
+ sb.addArtifact(artifact("out/a.txt", "h1"));
897
+ sb.clearForceFlag();
898
+ sb.addArtifact(artifact("out/a.txt", "h2"));
899
+ expect(sb.currentStatus.artifacts).toHaveLength(1);
900
+ expect(sb.currentStatus.artifacts[0].contentHash).toBe("h2");
901
+ expect(sb.forceNextUpdate).toBe(true);
902
+ });
903
+
904
+ it("upserts write-backs by workspaceEntryName, tracking entries independently", () => {
905
+ const sb = makeBuilder();
906
+ sb.addWriteBack(create(WorkspaceWriteBackSchema, { workspaceEntryName: "repo-a", branchName: "stigmer/s1" }));
907
+ sb.addWriteBack(create(WorkspaceWriteBackSchema, { workspaceEntryName: "repo-b", branchName: "stigmer/s1" }));
908
+ sb.clearForceFlag();
909
+ sb.addWriteBack(create(WorkspaceWriteBackSchema, { workspaceEntryName: "repo-a", branchName: "stigmer/s1", pullRequestUrl: "https://example/pr/1" }));
910
+ const backs = sb.currentStatus.workspaceWriteBacks;
911
+ expect(backs.map((b) => b.workspaceEntryName)).toEqual(["repo-a", "repo-b"]);
912
+ expect(backs[0].pullRequestUrl).toBe("https://example/pr/1");
913
+ expect(sb.forceNextUpdate).toBe(true);
914
+ });
915
+ });
611
916
  });
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Proves the T04 vision input path end-to-end through the REAL framework
3
- * stack: the exact `{ role: "user", content: [...] }` shape that setup.ts
3
+ * stack: the exact `{ role: "user", content: [...] }` shape that turn-setup.ts
4
4
  * builds is driven through `createDeepAgent` (the production graph factory,
5
5
  * default middleware included) and the test asserts what the chat model's
6
6
  * `_generate` actually received.
@@ -60,9 +60,9 @@ class CapturingModel extends ScriptedModel {
60
60
  return next as unknown as this;
61
61
  }
62
62
 
63
- override async _generate(messages: BaseMessage[]): Promise<ChatResult> {
63
+ override async _generate(messages: BaseMessage[], options: this["ParsedCallOptions"]): Promise<ChatResult> {
64
64
  this.captured.push(messages);
65
- return super._generate(messages);
65
+ return super._generate(messages, options);
66
66
  }
67
67
  }
68
68
 
@@ -92,7 +92,7 @@ describe("deep-agent vision input through the real graph", () => {
92
92
  });
93
93
 
94
94
  /**
95
- * `content` is exactly what setup.ts puts on the user message: a plain
95
+ * `content` is exactly what turn-setup.ts puts on the user message: a plain
96
96
  * string, or the content-block array built by toLangChainImageBlocks plus
97
97
  * the composed text block.
98
98
  */
@@ -111,7 +111,7 @@ describe("deep-agent vision input through the real graph", () => {
111
111
  backend,
112
112
  } as Parameters<typeof createDeepAgent>[0]);
113
113
 
114
- // The EXACT input shape setup.ts constructs (plain role/content dict, not
114
+ // The EXACT input shape turn-setup.ts constructs (plain role/content dict, not
115
115
  // a HumanMessage instance — the reducer does the coercion in production).
116
116
  await agent.invoke(
117
117
  { messages: [{ role: "user", content }] },
@@ -0,0 +1,94 @@
1
+ /**
2
+ * The native deep-agent harness as a `HarnessAdapter` — the worker- and
3
+ * session-lifetime half of its LangGraph slice, behind the turn runtime's
4
+ * contract (`harness/types.ts`). One engine turn is `turn.ts`'s
5
+ * `runDeepAgentTurn`; this module boots and delegates.
6
+ *
7
+ * What this adapter owns: the deepagents harness profiles (worker lifetime,
8
+ * registered once before the first `createDeepAgent`), and one engine turn
9
+ * (`runTurn`, through `turn.ts`). Everything else about a turn is the
10
+ * runtime's (`harness/run-turn.ts`).
11
+ *
12
+ * THIS MODULE'S STATIC GRAPH IS SDK-FREE, ON PURPOSE. The composition roots
13
+ * import the harness table (`src/harness-adapters.ts`) BEFORE they boot it,
14
+ * and that table's static graph must stay connect- and SDK-free (the Cursor
15
+ * adapter's boot patches `node:http2` before anything dials the control
16
+ * plane). So `deepagents` and `@langchain/*` — this harness's whole engine —
17
+ * are loaded with a dynamic import INSIDE `boot`, after the profiles are
18
+ * registered; a worker that does not serve this harness never pays for
19
+ * LangChain. `__tests__/adapter-graph-is-sdk-free.test.ts` pins it.
20
+ *
21
+ * Nothing is parked per session, and the header says so where the contract
22
+ * asks: the sqlite saver is opened and closed per turn and the MCP
23
+ * subprocesses are connected and closed per turn (`turn.ts`), so
24
+ * `shutdown` and `releaseSession` resolve as no-ops.
25
+ *
26
+ * What this adapter never does: throw out of `runTurn` (an engine failure is
27
+ * `failed` on the `internal` surface; the recursion limit is
28
+ * `tool_call_limit`; a `CancelledFailure` never exists here), branch on why
29
+ * `stopSignal` aborted, write a phase or a terminal copy, bind a state id
30
+ * (the thread id is the runtime's, `deterministic`), or import
31
+ * `@temporalio/*` (`__tests__/adapter-is-temporal-free.test.ts`).
32
+ *
33
+ * Extracted from `index.ts` `createDeepAgentActivities` at S3 M2a on the
34
+ * Cursor adapter's layout (`execute-cursor/adapter.ts`).
35
+ */
36
+
37
+ import type { Config } from "../../config.js";
38
+ import type { HarnessAdapter, TurnInput, TurnOutcome, TurnSink } from "../../harness/types.js";
39
+ import { DEEP_AGENT_CAPABILITIES } from "./deep-agent-capabilities.js";
40
+ import type { DeepAgentAdapterConfig } from "./turn-setup.js";
41
+
42
+ /** The config slice this adapter reads per turn, taken at `boot`; a whole `Config` satisfies it. */
43
+ export function resolveDeepAgentConfig(config: Config): DeepAgentAdapterConfig {
44
+ return {
45
+ checkpointerType: config.checkpointerType,
46
+ checkpointerProxyEndpoint: config.checkpointerProxyEndpoint,
47
+ stigmerToken: config.stigmerToken,
48
+ proxyEndpoint: config.proxyEndpoint,
49
+ mode: config.mode,
50
+ };
51
+ }
52
+
53
+ /** What `boot` leaves behind for the turns: the config slice and the engine turn, loaded after the profiles. */
54
+ interface BootedDeepAgentHarness {
55
+ readonly config: DeepAgentAdapterConfig;
56
+ readonly runDeepAgentTurn: typeof import("./turn.js").runDeepAgentTurn;
57
+ }
58
+
59
+ export function createDeepAgentAdapter(): HarnessAdapter {
60
+ let booted: BootedDeepAgentHarness | undefined;
61
+
62
+ return {
63
+ name: "deep-agent",
64
+ capabilities: DEEP_AGENT_CAPABILITIES,
65
+
66
+ /**
67
+ * Register the harness profiles (deepagents would otherwise auto-inject
68
+ * an ungated `general-purpose` sub-agent into every graph), then load
69
+ * the engine slice. Idempotent: a re-boot re-reads the slice; the
70
+ * registration is once-guarded.
71
+ */
72
+ async boot(bootConfig: Config): Promise<void> {
73
+ // `deepagents-profiles.ts` imports the SDK to register against it, so
74
+ // it too is loaded here and not at the top of this module.
75
+ const { registerStigmerDeepagentsProfiles } = await import("./deepagents-profiles.js");
76
+ registerStigmerDeepagentsProfiles();
77
+ const { runDeepAgentTurn } = await import("./turn.js");
78
+ booted = { config: resolveDeepAgentConfig(bootConfig), runDeepAgentTurn };
79
+ },
80
+
81
+ /** Nothing is held across turns (see the header). */
82
+ async shutdown(): Promise<void> {},
83
+
84
+ /** Nothing is parked per session (see the header); an unknown id is a no-op by construction. */
85
+ async releaseSession(_sessionId: string): Promise<void> {},
86
+
87
+ async runTurn(input: TurnInput, sink: TurnSink): Promise<TurnOutcome> {
88
+ if (booted === undefined) {
89
+ throw new Error("deep-agent adapter: runTurn before boot (the registry boots every adapter before the worker polls)");
90
+ }
91
+ return booted.runDeepAgentTurn(input, sink, booted.config);
92
+ },
93
+ };
94
+ }
@@ -39,6 +39,7 @@
39
39
 
40
40
  import { readFile } from "node:fs/promises";
41
41
  import { resolveWorkspacePath } from "../../shared/file-change.js";
42
+ import type { CasTouchedSnapshot } from "../../shared/filereview/cas-touched.js";
42
43
 
43
44
  /**
44
45
  * Pre-turn bytes of each first-touched gitignored path, keyed by workspace-root-
@@ -75,6 +76,16 @@ export class CasCaptureObserver {
75
76
  return this.blocked;
76
77
  }
77
78
 
79
+ /**
80
+ * An atomic copy of what has been observed so far — the shape the progress
81
+ * slice and the turn-boundary capture read (`shared/filereview/cas-touched.ts`).
82
+ * Copied synchronously, so a sub-agent's concurrent `recordBefore` landing
83
+ * mid-capture cannot mutate a snapshot a reader is walking.
84
+ */
85
+ snapshot(): CasTouchedSnapshot {
86
+ return { before: new Map(this.before), blockedSecretPaths: new Set(this.blocked) };
87
+ }
88
+
78
89
  /**
79
90
  * Record the pre-turn bytes of `rawPath` when it is a first-touched gitignored
80
91
  * path. First-touch-wins across ALL backends sharing this observer: the slot is
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The native deep-agent harness's capability flags — the facts about the
3
+ * LangGraph engine the turn runtime branches on, declared once
4
+ * (`harness/capabilities.ts` has the matrix and the meaning of each flag).
5
+ *
6
+ * - `interrupt`: the approval gate (`middleware/approval-gate.ts`) calls
7
+ * LangGraph's `interrupt()` at a gated tool; the graph checkpoints and
8
+ * stops, and the adapter resumes it with a `Command(resume)` carrying
9
+ * the decisions (`hitl.ts`). No engine re-run, no exact-apply.
10
+ * - `deterministic`: the thread id is the runtime's, minted from the
11
+ * session before the first turn (`ensure-thread.ts`), so the adapter
12
+ * never binds a state id and the runtime's reinvocation fact is the
13
+ * persisted transcript.
14
+ * - A system prompt: instructions, skills, input files and standing context
15
+ * ride `createDeepAgent`'s `systemPrompt` (`prompt-builder.ts`).
16
+ * - Sub-agents as compiled sub-graphs (`subagent-transformer.ts`), each
17
+ * with its own mounted skills from the runtime (`TurnSkills.bySubAgent`).
18
+ * - Tool restriction by tool list: an MCP server's `enabled_tools` is
19
+ * honoured at connect time, so the engine never sees a disabled tool.
20
+ * - PNG, JPEG, WebP and GIF inline (`shared/attachment-vision.ts`).
21
+ * - File review under the `deep-agent` harness id with nothing excluded:
22
+ * this harness writes no transient file into the repo (the `.stigmer`
23
+ * link is the runtime's, created before its baseline pin and git-excluded
24
+ * at provision). The capture is the runtime's (`harness/capture.ts`, S3
25
+ * M4); this harness binds its `CasCaptureObserver`'s snapshot as the
26
+ * runtime's CAS observations (`turn.ts`).
27
+ */
28
+
29
+ import type { HarnessCapabilities } from "../../harness/capabilities.js";
30
+ import { DEEP_AGENT_VISION_PROFILE } from "../../shared/attachment-vision.js";
31
+
32
+ /** The harness id stamped on the deep-agent's file-review ledger events. */
33
+ export const DEEP_AGENT_HARNESS_ID = "deep-agent";
34
+
35
+ export const DEEP_AGENT_CAPABILITIES: HarnessCapabilities = {
36
+ pausePrimitive: "interrupt",
37
+ stateIdSource: "deterministic",
38
+ systemPrompt: true,
39
+ subAgents: true,
40
+ toolRestriction: true,
41
+ visionProfile: DEEP_AGENT_VISION_PROFILE,
42
+ fileReview: { harnessId: DEEP_AGENT_HARNESS_ID, excludePaths: [] },
43
+ };