@stigmer/runner 3.15.0 → 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
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Hermetic goldens: STRUCTURED OUTPUT — an execution whose config carries a
3
+ * JSON schema, through the three paths a native turn has:
4
+ *
5
+ * 1. The engine's `structuredResponse`. langchain 1.4.1 turns a bare schema
6
+ * into `toolStrategy` when the model's profile does not declare native
7
+ * structured output (`agents/responses.js`): a synthetic function tool is
8
+ * bound (named `extract-N` from a per-module counter — deepagents passes
9
+ * no name and the schema's `title` is not consulted, so the script selects
10
+ * it by pattern rather than by name), the model calls it with the answer
11
+ * as arguments, and the graph's `run.output.structuredResponse` holds the
12
+ * parsed object. The adapter folds it onto the status (`turn-settle.ts`).
13
+ * 2. The text fallback (the runtime's tier 1): the model answers in prose
14
+ * with a fenced JSON block and `shared/extract-json.ts` recovers the
15
+ * object from the final text (`run-turn.ts` `extractStructuredOutputFromText`).
16
+ * 3. The LLM fallback (the runtime's tier 2, Q-S3-7): the final text carries
17
+ * no JSON at all, so the runtime asks a second model — the registry's
18
+ * economy tier for the primary's provider — to extract it through
19
+ * `withStructuredOutput` (`shared/extract-structured-output.ts`). Native
20
+ * gained this arm at S3 M2a, when the turn runtime took the epilogue
21
+ * over; it is pinned here since M2b (F-M2b-14), where every other ruled
22
+ * alignment is. Two facts the golden records: the extraction call is a
23
+ * SECOND model build (`maxTokens: 4096`, on the primary — the fixture
24
+ * registry declares no economy row, `getEconomyModel`'s last resort),
25
+ * and its tool call never reaches the transcript (it is not a graph
26
+ * step). The arm runs in the OSS direct-credential posture
27
+ * (`ANTHROPIC_API_KEY` stubbed for the arm only): without a proxy the
28
+ * runtime refuses tier 2 when no credential path exists, and that
29
+ * refusal is a log line, never a lost run.
30
+ *
31
+ * Whatever each path yields is recorded as found: `status.structuredOutput`
32
+ * and the slim's `structured`.
33
+ *
34
+ * The `extract-N` name is deterministic per test FILE (vitest isolates each
35
+ * file's module graph, so the counter starts at 1), and only the tool-strategy
36
+ * arm compiles a graph with a schema tool in this file, so its row — if one
37
+ * is persisted — is `extract-1`. Tier 2's tool is `@langchain/core`'s default
38
+ * `extract` (`withStructuredOutput` with no name), bound on the extraction
39
+ * model alone, which is how the script tells the two calls apart.
40
+ *
41
+ * Since S3 M2a the activity is the turn runtime over the native adapter, and
42
+ * `streamingUsage` carries the runtime accountant's fields — `model`,
43
+ * `estimatedCostUsd` priced at the registry's rates, the requested tier and
44
+ * thinking mode (Q-M2a-2: one writer of the summary, the runtime). Nothing
45
+ * else in this golden moved with the flip.
46
+ *
47
+ * Regenerate ONLY after a deliberate behavior change:
48
+ * npx vitest run src/activities/execute-deep-agent/__tests__/hermetic -u
49
+ */
50
+
51
+ import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
52
+ import { toJson } from "@bufbuild/protobuf";
53
+ import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
54
+ import { ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
55
+
56
+ vi.mock("../../../../shared/model-client.js", async () =>
57
+ (await import("../../__test-utils__/scripted-model-module.js")).scriptedModelClientModule(),
58
+ );
59
+ vi.mock("../../../../client/stigmer-client.js", async () =>
60
+ (await import("../../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule(),
61
+ );
62
+
63
+ import {
64
+ ScriptedClock,
65
+ createHermeticEnvironment,
66
+ type HermeticEnvironment,
67
+ } from "../../../../__test-utils__/hermetic-activity.js";
68
+ import { stubRegistryFetch } from "../../../../__test-utils__/model-registry-fixture.js";
69
+ import {
70
+ beginDeepAgentScenario,
71
+ deepAgentExecutionRecord,
72
+ runDeepAgentTurn,
73
+ } from "../../__test-utils__/hermetic-deep-agent.js";
74
+ import { recordedModelBuilds } from "../../__test-utils__/scripted-model-module.js";
75
+ import { FIXTURE_NATIVE_MODEL } from "../../../../__test-utils__/model-registry-fixture.js";
76
+
77
+ const SCHEMA = {
78
+ type: "object",
79
+ properties: { answer: { type: "string" }, score: { type: "number" } },
80
+ required: ["answer", "score"],
81
+ };
82
+ const ANSWER = { answer: "forty-two", score: 42 };
83
+ const SCHEMA_TOOL_PATTERN = /^extract-\d+$/;
84
+
85
+ describe("ExecuteDeepAgent hermetic — structured output", () => {
86
+ let env: HermeticEnvironment;
87
+ let registry: ReturnType<typeof stubRegistryFetch>;
88
+ const clock = new ScriptedClock();
89
+
90
+ beforeAll(() => {
91
+ env = createHermeticEnvironment();
92
+ registry = stubRegistryFetch();
93
+ clock.install();
94
+ });
95
+
96
+ afterAll(() => {
97
+ clock.uninstall();
98
+ registry.restore();
99
+ env.dispose();
100
+ });
101
+
102
+ it("tool strategy: the model calls the bound schema tool", async () => {
103
+ // ── Arrange ──────────────────────────────────────────────────────────────
104
+ clock.reset();
105
+ const record = deepAgentExecutionRecord({ message: "Give me the answer.", structuredOutputSchema: SCHEMA });
106
+ const boundSchemaTools: string[] = [];
107
+ const scenario = beginDeepAgentScenario({
108
+ env,
109
+ clock,
110
+ record,
111
+ script: (tools) => {
112
+ const schemaTool = tools.find((t) => SCHEMA_TOOL_PATTERN.test(t));
113
+ if (schemaTool) boundSchemaTools.push(schemaTool);
114
+ return {
115
+ turns: [
116
+ {
117
+ text: "Here is the structured answer.",
118
+ toolCalls: schemaTool ? [{ id: "call-hermetic-extract-0001", name: schemaTool, args: ANSWER }] : [],
119
+ usage: { inputTokens: 1_300, outputTokens: 40 },
120
+ },
121
+ { text: "Recorded.", usage: { inputTokens: 1_500, outputTokens: 10 } },
122
+ ],
123
+ };
124
+ },
125
+ });
126
+
127
+ // ── Act ──────────────────────────────────────────────────────────────────
128
+ const invocation = await runDeepAgentTurn(scenario);
129
+
130
+ // ── Assert ───────────────────────────────────────────────────────────────
131
+ expect(invocation.outcome.kind).toBe("returned");
132
+ const slim = (invocation.outcome as { value: Record<string, unknown> }).value;
133
+ expect(slim.phase).toBe("EXECUTION_COMPLETED");
134
+ expect(boundSchemaTools[0], "langchain bound the toolStrategy schema tool").toBe("extract-1");
135
+ expect(record.persistedPhases.at(-1)).toBe(ExecutionPhase.EXECUTION_COMPLETED);
136
+ const final = record.lastFullStatus!;
137
+ expect(final.structuredOutput, "the engine's structuredResponse reaches the status").toEqual(ANSWER);
138
+ expect(slim.structured).toEqual(ANSWER);
139
+
140
+ const json = JSON.stringify(toJson(AgentExecutionStatusSchema, final), null, 2) + "\n";
141
+ await expect(json).toMatchFileSnapshot("./goldens/structured-output.tool-strategy.status.json");
142
+ });
143
+
144
+ it("text fallback: a fenced JSON block in the final text", async () => {
145
+ // ── Arrange ──────────────────────────────────────────────────────────────
146
+ clock.reset();
147
+ const record = deepAgentExecutionRecord({ message: "Give me the answer.", structuredOutputSchema: SCHEMA });
148
+ const scenario = beginDeepAgentScenario({
149
+ env,
150
+ clock,
151
+ record,
152
+ script: () => ({
153
+ turns: [
154
+ {
155
+ text: "Here you go:\n```json\n" + JSON.stringify(ANSWER) + "\n```",
156
+ usage: { inputTokens: 1_300, outputTokens: 40 },
157
+ },
158
+ ],
159
+ }),
160
+ });
161
+
162
+ // ── Act ──────────────────────────────────────────────────────────────────
163
+ const invocation = await runDeepAgentTurn(scenario);
164
+
165
+ // ── Assert ───────────────────────────────────────────────────────────────
166
+ expect(invocation.outcome.kind).toBe("returned");
167
+ const slim = (invocation.outcome as { value: Record<string, unknown> }).value;
168
+ expect(slim.phase).toBe("EXECUTION_COMPLETED");
169
+ const final = record.lastFullStatus!;
170
+ expect(final.structuredOutput, "extracted from the final text").toEqual(ANSWER);
171
+ expect(slim.structured).toEqual(ANSWER);
172
+ expect(record.toolCalls(), "no tool was involved").toHaveLength(0);
173
+
174
+ expect(registry.urls.every((u) => u.includes("/model-registry"))).toBe(true);
175
+ const json = JSON.stringify(toJson(AgentExecutionStatusSchema, final), null, 2) + "\n";
176
+ await expect(json).toMatchFileSnapshot("./goldens/structured-output.text-fallback.status.json");
177
+ });
178
+
179
+ it("LLM fallback (tier 2): prose with no JSON is extracted by a second model call the transcript never sees (Q-S3-7)", async () => {
180
+ // ── Arrange ──────────────────────────────────────────────────────────────
181
+ clock.reset();
182
+ // The OSS direct-credential posture, for this arm only: with no proxy the
183
+ // runtime refuses tier 2 unless a credential path exists.
184
+ vi.stubEnv("ANTHROPIC_API_KEY", "hermetic-tier2-credential");
185
+ const PROSE = "The answer is forty-two, and I would score it a perfect forty-two out of the same.";
186
+ const record = deepAgentExecutionRecord({ message: "Give me the answer.", structuredOutputSchema: SCHEMA });
187
+ const extractionCalls: string[][] = [];
188
+ const scenario = beginDeepAgentScenario({
189
+ env,
190
+ clock,
191
+ record,
192
+ script: (tools) => {
193
+ // The extraction model binds exactly one tool, core's default `extract`;
194
+ // the agent's graph never binds a tool of that name.
195
+ if (tools.length === 1 && tools[0] === "extract") {
196
+ extractionCalls.push([...tools]);
197
+ return { turns: [{ text: "", toolCalls: [{ id: "call-hermetic-tier2-0001", name: "extract", args: ANSWER }] }] };
198
+ }
199
+ return { turns: [{ text: PROSE, usage: { inputTokens: 1_300, outputTokens: 40 } }] };
200
+ },
201
+ });
202
+
203
+ try {
204
+ // ── Act ────────────────────────────────────────────────────────────────
205
+ const invocation = await runDeepAgentTurn(scenario);
206
+
207
+ // ── Assert ─────────────────────────────────────────────────────────────
208
+ expect(invocation.outcome.kind).toBe("returned");
209
+ const slim = (invocation.outcome as { value: Record<string, unknown> }).value;
210
+ expect(slim.phase).toBe("EXECUTION_COMPLETED");
211
+ const final = record.lastFullStatus!;
212
+ expect(final.structuredOutput, "extracted by the second model").toEqual(ANSWER);
213
+ expect(slim.structured).toEqual(ANSWER);
214
+ expect(record.toolCalls(), "the extraction tool call is not a graph step and never reaches the transcript").toHaveLength(0);
215
+ expect(extractionCalls, "the extractor was asked exactly once").toHaveLength(1);
216
+
217
+ // The agent's build, the sub-agent factory's builds (every registered
218
+ // profile sub-agent is compiled, invoked or not), then — last, after the
219
+ // graph has ended — the extractor's: the one build that caps its output
220
+ // (`maxTokens: 4096`) and carries no execution header scope.
221
+ const builds = recordedModelBuilds();
222
+ const extractorBuilds = builds.filter((b) => b.maxTokens === 4096);
223
+ expect(extractorBuilds, "exactly one extraction build").toHaveLength(1);
224
+ expect(builds.at(-1), "the extractor is built after the graph's run, never before").toBe(extractorBuilds[0]);
225
+ expect(extractorBuilds[0]!.headerScope).toBeUndefined();
226
+ // The fixture registry declares no economy row, so `getEconomyModel`
227
+ // falls back to the primary (its last resort).
228
+ expect(extractorBuilds[0]!.modelName).toBe(FIXTURE_NATIVE_MODEL);
229
+
230
+ const json = JSON.stringify(toJson(AgentExecutionStatusSchema, final), null, 2) + "\n";
231
+ await expect(json).toMatchFileSnapshot("./goldens/structured-output.tier2.status.json");
232
+ } finally {
233
+ vi.unstubAllEnvs();
234
+ }
235
+ });
236
+ });
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Hermetic golden: SUB-AGENT DELEGATION — the root agent hands a task to a
3
+ * declared sub-agent through deepagents' `task` tool, and the sub-agent's
4
+ * own turn is tracked as a `SubAgentExecution`.
5
+ *
6
+ * Invariant pinned: `transformAndCompileSubagents` compiles the agent's
7
+ * declared sub-agent (plus deepagents' built-in `general-purpose` and the
8
+ * runner's `shell`) on the SAME model double through `modelFactory`; the root
9
+ * proposes `task({ subagent_type, description })`; the tools node runs the
10
+ * sub-agent graph under a nested namespace (`tools:<uuid>|...`); the
11
+ * `SubAgentTracker` opens a `SubAgentExecution` keyed by the `task` call id
12
+ * (not by the namespace uuid, which never reaches the status), routes the
13
+ * nested model events into its own transcript, and closes it COMPLETED when
14
+ * the `task` tool finishes; the root's transcript carries the `task` row and
15
+ * its closing text. The golden (`goldens/sub-agent-delegation.status.json`)
16
+ * pins the nested transcript shape S4 must reproduce.
17
+ *
18
+ * Role selection: `createDeepAgent` gives the sub-agent the same tool set as
19
+ * its parent (`task` included), so the script tells the roles apart by the
20
+ * system prompt (`ScriptRoleContext.systemPrompt`), which carries the
21
+ * sub-agent's own instructions — the one thing that differs.
22
+ *
23
+ * Since S3 M2a the activity is the turn runtime over the native adapter, and
24
+ * `streamingUsage` carries the runtime accountant's fields — `model`,
25
+ * `estimatedCostUsd` priced at the registry's rates, the requested tier and
26
+ * thinking mode (Q-M2a-2: one writer of the summary, the runtime). Nothing
27
+ * else in this golden moved with the flip.
28
+ *
29
+ * Since S3 M2b (Q-M2b-1, owner ruling 2026-09-13) the sub-agent's spend is
30
+ * the execution's spend: the helper's one turn (600 in, 12 out) is reported
31
+ * through the same hook as the root's, so `streamingUsage` reads 3,900 in /
32
+ * 102 out / 3 turns where it read 3,300 / 90 / 2, and `estimatedCostUsd`
33
+ * 0.00441 where it read 0.00375 — the helper's 660 micro-dollars at the
34
+ * PARENT's rate (per-sub-agent pricing is an S5 item; the in-graph cost cap
35
+ * this replaces priced sub-agents the same way). The five lines of
36
+ * `streamingUsage` are the whole diff; the transcript and the sub-agent row
37
+ * are byte-identical. `max_cost_usd` is now enforced over this total by the
38
+ * runtime, the one enforcement since the cost middleware became advisory
39
+ * (Q-S3-3).
40
+ *
41
+ * Regenerate ONLY after a deliberate behavior change:
42
+ * npx vitest run src/activities/execute-deep-agent/__tests__/hermetic -u
43
+ */
44
+
45
+ import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
46
+ import { create, toJson } from "@bufbuild/protobuf";
47
+ import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
48
+ import {
49
+ ExecutionPhase,
50
+ MessageType,
51
+ SubAgentStatus,
52
+ ToolCallStatus,
53
+ } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
54
+ import { SubAgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb";
55
+
56
+ vi.mock("../../../../shared/model-client.js", async () =>
57
+ (await import("../../__test-utils__/scripted-model-module.js")).scriptedModelClientModule(),
58
+ );
59
+ vi.mock("../../../../client/stigmer-client.js", async () =>
60
+ (await import("../../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule(),
61
+ );
62
+
63
+ import {
64
+ ScriptedClock,
65
+ createHermeticEnvironment,
66
+ type HermeticEnvironment,
67
+ } from "../../../../__test-utils__/hermetic-activity.js";
68
+ import { stubRegistryFetch } from "../../../../__test-utils__/model-registry-fixture.js";
69
+ import {
70
+ beginDeepAgentScenario,
71
+ deepAgentExecutionRecord,
72
+ runDeepAgentTurn,
73
+ } from "../../__test-utils__/hermetic-deep-agent.js";
74
+ import { recordedModelBuilds } from "../../__test-utils__/scripted-model-module.js";
75
+
76
+ const HELPER_INSTRUCTIONS = "You are the hermetic helper. Answer in one line.";
77
+ const TASK_CALL_ID = "call-hermetic-task-0001";
78
+ const TASK_DESCRIPTION = "Look up the fixture value.";
79
+ const HELPER_ANSWER = "The fixture value is forty-two.";
80
+ const ROOT_CLOSING = "The helper reports the fixture value is forty-two.";
81
+
82
+ describe("ExecuteDeepAgent hermetic — sub-agent delegation", () => {
83
+ let env: HermeticEnvironment;
84
+ let registry: ReturnType<typeof stubRegistryFetch>;
85
+ const clock = new ScriptedClock();
86
+
87
+ beforeAll(() => {
88
+ env = createHermeticEnvironment();
89
+ registry = stubRegistryFetch();
90
+ clock.install();
91
+ });
92
+
93
+ afterAll(() => {
94
+ clock.uninstall();
95
+ registry.restore();
96
+ env.dispose();
97
+ });
98
+
99
+ it("tracks the delegated turn as a SubAgentExecution keyed by the task call and completes", async () => {
100
+ // ── Arrange ──────────────────────────────────────────────────────────────
101
+ const helper = create(SubAgentSchema, {
102
+ name: "helper",
103
+ description: "Looks up fixture values.",
104
+ instructions: HELPER_INSTRUCTIONS,
105
+ });
106
+ const record = deepAgentExecutionRecord({ message: "Ask the helper for the fixture value.", subAgents: [helper] });
107
+ const scenario = beginDeepAgentScenario({
108
+ env,
109
+ clock,
110
+ record,
111
+ script: (_tools, context) =>
112
+ context.systemPrompt.includes(HELPER_INSTRUCTIONS)
113
+ ? { turns: [{ text: HELPER_ANSWER, usage: { inputTokens: 600, outputTokens: 12 } }] }
114
+ : {
115
+ turns: [
116
+ {
117
+ text: "Delegating to the helper.",
118
+ toolCalls: [{ id: TASK_CALL_ID, name: "task", args: { description: TASK_DESCRIPTION, subagent_type: "helper" } }],
119
+ usage: { inputTokens: 1_500, outputTokens: 60 },
120
+ },
121
+ { text: ROOT_CLOSING, usage: { inputTokens: 1_800, outputTokens: 30 } },
122
+ ],
123
+ },
124
+ });
125
+
126
+ // ── Act ──────────────────────────────────────────────────────────────────
127
+ const invocation = await runDeepAgentTurn(scenario);
128
+
129
+ // ── Assert: outcome ──────────────────────────────────────────────────────
130
+ expect(invocation.outcome.kind).toBe("returned");
131
+ expect((invocation.outcome as { value: Record<string, unknown> }).value.phase).toBe("EXECUTION_COMPLETED");
132
+ expect(record.persistedPhases.at(-1)).toBe(ExecutionPhase.EXECUTION_COMPLETED);
133
+
134
+ // ── Assert: the root transcript ──────────────────────────────────────────
135
+ const final = record.lastFullStatus!;
136
+ const rows = record.toolCalls();
137
+ expect(rows.map((tc) => [tc.id, tc.name, tc.status])).toEqual([[TASK_CALL_ID, "task", ToolCallStatus.TOOL_CALL_COMPLETED]]);
138
+ expect(final.messages.filter((m) => m.type === MessageType.MESSAGE_AI).map((m) => m.content)).toEqual([
139
+ "Delegating to the helper.",
140
+ "",
141
+ ROOT_CLOSING,
142
+ ]);
143
+
144
+ // ── Assert: the sub-agent execution ──────────────────────────────────────
145
+ expect(final.subAgentExecutions).toHaveLength(1);
146
+ const sub = final.subAgentExecutions[0];
147
+ expect(sub.id, "keyed by the task call id, never by the namespace uuid").toBe(TASK_CALL_ID);
148
+ expect(sub.name).toBe("helper");
149
+ expect(sub.subject).toBe(TASK_DESCRIPTION);
150
+ expect(sub.status).toBe(SubAgentStatus.SUB_AGENT_COMPLETED);
151
+ expect(sub.messages.map((m) => [m.type, m.content])).toEqual([[MessageType.MESSAGE_AI, HELPER_ANSWER]]);
152
+
153
+ // ── Assert: the model double was built for every compiled role ──────────
154
+ expect(recordedModelBuilds().length, "the primary plus one per compiled sub-agent").toBeGreaterThanOrEqual(2);
155
+ expect(registry.urls.every((u) => u.includes("/model-registry"))).toBe(true);
156
+
157
+ // ── Assert: the golden ───────────────────────────────────────────────────
158
+ const json = JSON.stringify(toJson(AgentExecutionStatusSchema, final), null, 2) + "\n";
159
+ await expect(json).toMatchFileSnapshot("./goldens/sub-agent-delegation.status.json");
160
+ });
161
+ });
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Hermetic golden: a turn with an UNGATED TOOL CALL through the whole
3
+ * `ExecuteDeepAgent` activity — the deepagents built-in `read_file` on a
4
+ * file seeded in the session workspace.
5
+ *
6
+ * Invariant pinned: the model's turn ("Let me read it." plus one `read_file`
7
+ * proposal), the tools node's `tool-started` / `tool-finished` events (status
8
+ * RUNNING then COMPLETED, `result` from the tool's output, `startedAt` /
9
+ * `completedAt` on the scripted clock), and the follow-up assistant turn fold
10
+ * into ONE tool row, and the turn ends COMPLETED. A read-only built-in is never
11
+ * gated (`shared/tool-kind.ts` FILE_READ), so no approval fields are set. The
12
+ * mid-stream persist the tool-call boundary forces (`persist-decision.ts`
13
+ * `contentDirty`) is what the platform-stop arm relies on.
14
+ *
15
+ * What the golden shows about TODAY's transcript shape, recorded as found
16
+ * (S3 M0 finding F-M0-1; a transcript-shape fact for S4): the row does NOT sit on
17
+ * the AI message that carries the text of the same LLM turn. LangGraph 1.3.2
18
+ * stamps the model's events with namespace `["model_request:<uuid>"]` and the
19
+ * tools node's with `["tools:<uuid>"]`; `V3StatusBuilder.ensureAiMessage`
20
+ * files the text under the raw namespace while `handleToolStarted` looks the
21
+ * parent up under `resolveAgentNamespace(...)`, which strips only `tools:`
22
+ * segments and so resolves to `""` — a miss, and `ensureAiMessageForToolCall`
23
+ * appends an EMPTY AI message for the row. So the transcript is THREE AI
24
+ * messages: the text, an empty one carrying the row, the closing text. The
25
+ * hand-authored fixtures in `v3-event-fixtures.ts` use `namespace: []` and
26
+ * never reached this arm; this golden, on the real graph, does. The golden
27
+ * (`goldens/tool-call.status.json`) is the shape S4's canonical transcript
28
+ * builder is measured against, and the shape any fix must change on purpose.
29
+ *
30
+ * Since S3 M2a the activity is the turn runtime over the native adapter, and
31
+ * `streamingUsage` carries the runtime accountant's fields — `model`,
32
+ * `estimatedCostUsd` priced at the registry's rates, the requested tier and
33
+ * thinking mode (Q-M2a-2: one writer of the summary, the runtime). Nothing
34
+ * else in this golden moved with the flip.
35
+ *
36
+ * Regenerate ONLY after a deliberate behavior change:
37
+ * npx vitest run src/activities/execute-deep-agent/__tests__/hermetic -u
38
+ */
39
+
40
+ import { mkdirSync, writeFileSync } from "node:fs";
41
+ import { join } from "node:path";
42
+ import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
43
+ import { toJson } from "@bufbuild/protobuf";
44
+ import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
45
+ import { ExecutionPhase, MessageType, ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
46
+
47
+ vi.mock("../../../../shared/model-client.js", async () =>
48
+ (await import("../../__test-utils__/scripted-model-module.js")).scriptedModelClientModule(),
49
+ );
50
+ vi.mock("../../../../client/stigmer-client.js", async () =>
51
+ (await import("../../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule(),
52
+ );
53
+
54
+ import {
55
+ ScriptedClock,
56
+ createHermeticEnvironment,
57
+ type HermeticEnvironment,
58
+ } from "../../../../__test-utils__/hermetic-activity.js";
59
+ import { stubRegistryFetch } from "../../../../__test-utils__/model-registry-fixture.js";
60
+ import {
61
+ beginDeepAgentScenario,
62
+ deepAgentExecutionRecord,
63
+ runDeepAgentTurn,
64
+ sessionWorkspaceDir,
65
+ } from "../../__test-utils__/hermetic-deep-agent.js";
66
+
67
+ const CALL_ID = "call-hermetic-read-0001";
68
+ const USER_MESSAGE = "What is in README.md?";
69
+ const README = "# Hermetic\n\nA fixture readme.\n";
70
+ const ASSISTANT_TEXT = "README.md holds a one-line fixture description.";
71
+
72
+ describe("ExecuteDeepAgent hermetic — ungated tool call", () => {
73
+ let env: HermeticEnvironment;
74
+ let registry: ReturnType<typeof stubRegistryFetch>;
75
+ const clock = new ScriptedClock();
76
+
77
+ beforeAll(() => {
78
+ env = createHermeticEnvironment();
79
+ registry = stubRegistryFetch();
80
+ clock.install();
81
+ });
82
+
83
+ afterAll(() => {
84
+ clock.uninstall();
85
+ registry.restore();
86
+ env.dispose();
87
+ });
88
+
89
+ it("folds the proposal and the tools node's events into one COMPLETED tool row and completes", async () => {
90
+ // ── Arrange ──────────────────────────────────────────────────────────────
91
+ const record = deepAgentExecutionRecord({ message: USER_MESSAGE });
92
+ const scenario = beginDeepAgentScenario({
93
+ env,
94
+ clock,
95
+ record,
96
+ script: () => ({
97
+ turns: [
98
+ {
99
+ text: "Let me read it.",
100
+ toolCalls: [{ id: CALL_ID, name: "read_file", args: { file_path: "/README.md" } }],
101
+ usage: { inputTokens: 1_500, outputTokens: 60 },
102
+ },
103
+ { text: ASSISTANT_TEXT, usage: { inputTokens: 1_700, outputTokens: 30 } },
104
+ ],
105
+ }),
106
+ });
107
+ // Seeded AFTER the scenario begins: beginning a scenario clears the
108
+ // session workspace so every scenario starts where a new session starts.
109
+ const workspace = sessionWorkspaceDir(env);
110
+ mkdirSync(workspace, { recursive: true });
111
+ writeFileSync(join(workspace, "README.md"), README, "utf-8");
112
+
113
+ // ── Act ──────────────────────────────────────────────────────────────────
114
+ const invocation = await runDeepAgentTurn(scenario);
115
+
116
+ // ── Assert: outcome and phases ───────────────────────────────────────────
117
+ expect(invocation.outcome.kind).toBe("returned");
118
+ const slim = (invocation.outcome as { value: Record<string, unknown> }).value;
119
+ expect(slim.phase).toBe("EXECUTION_COMPLETED");
120
+ expect(record.persistedPhases).toEqual([
121
+ ExecutionPhase.EXECUTION_IN_PROGRESS,
122
+ ExecutionPhase.EXECUTION_COMPLETED,
123
+ ]);
124
+ expect(record.persisted.length, "the tool-call boundary forces a mid-stream persist").toBeGreaterThan(2);
125
+
126
+ // ── Assert: the one tool-call row ────────────────────────────────────────
127
+ const rows = record.toolCalls();
128
+ expect(rows, "proposal + started + finished fold into ONE row, never two").toHaveLength(1);
129
+ const row = rows[0];
130
+ expect(row.id).toBe(CALL_ID);
131
+ expect(row.name).toBe("read_file");
132
+ expect(row.status).toBe(ToolCallStatus.TOOL_CALL_COMPLETED);
133
+ expect(row.args).toEqual({ file_path: "/README.md" });
134
+ expect(row.result, "the built-in's numbered listing of the seeded file").toContain("A fixture readme.");
135
+ expect(row.requiresApproval, "a read-only built-in is not gated").toBe(false);
136
+
137
+ // ── Assert: the transcript, as it is today (F-M0-1 in the header) ────────
138
+ const final = record.lastFullStatus!;
139
+ const ai = final.messages.filter((m) => m.type === MessageType.MESSAGE_AI);
140
+ expect(ai.map((m) => m.content), "text, an EMPTY message carrying the row, closing text").toEqual([
141
+ "Let me read it.",
142
+ "",
143
+ ASSISTANT_TEXT,
144
+ ]);
145
+ expect(ai[1].toolCalls.map((tc) => tc.id), "the row sits on the empty message, not beside its text").toEqual([
146
+ CALL_ID,
147
+ ]);
148
+ expect(final.streamingUsage?.turnCount).toBe(2);
149
+
150
+ // ── Assert: hermeticity ──────────────────────────────────────────────────
151
+ expect(registry.urls.every((u) => u.includes("/model-registry"))).toBe(true);
152
+
153
+ // ── Assert: the golden ───────────────────────────────────────────────────
154
+ const json = JSON.stringify(toJson(AgentExecutionStatusSchema, final), null, 2) + "\n";
155
+ await expect(json).toMatchFileSnapshot("./goldens/tool-call.status.json");
156
+ });
157
+ });