@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
@@ -1,767 +0,0 @@
1
- /**
2
- * Execution setup pipeline for the deep agent activity.
3
- *
4
- * Hydrates the execution from the database, resolves the full resource
5
- * chain (session -> agentInstance -> agent), provisions workspace, loads
6
- * MCP servers / environment, creates the LangGraph agent graph with the
7
- * full middleware stack, and returns a SetupResult containing everything
8
- * the streaming phase needs.
9
- */
10
- import { createDeepAgent } from "deepagents";
11
- import { InteractionMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
12
- import { TimingRecorder, emitTimingLog } from "../../shared/cold-start-timing.js";
13
- import { createCheckpointer } from "../../shared/checkpointer/factory.js";
14
- import { readContextBridge } from "../../shared/context-bridge.js";
15
- import { readConversationCatchup } from "../../shared/conversation-catchup.js";
16
- import { readSenderIdentity } from "../../shared/sender-identity.js";
17
- import { injectCallerIdentityEnv, resolveCallerIdentity, } from "../../shared/caller-identity.js";
18
- import { readSessionContext } from "../../shared/session-context.js";
19
- import { readDeclaredPreferences } from "../../shared/declared-preferences.js";
20
- import { selectRecalledFacts } from "../../shared/memory-retrieval.js";
21
- import { connectMcpServers } from "../../shared/mcp-manager.js";
22
- import { mergeMcpServerUsages, resolveMcpServers } from "../../shared/mcp-resolver.js";
23
- import { resolveMcpTransportPosture } from "../../shared/mcp-transport-guard.js";
24
- import { backfillMcpServersIfNeeded } from "../../shared/connect-backfill.js";
25
- import { discoverChannelMessaging, formatChannelTemplatesSection, synthesizeChannelAttachment, } from "../../shared/channel-attachment.js";
26
- import { readChannelConversationId, synthesizeConversationAttachment, } from "../../shared/conversation-attachment.js";
27
- import { memoryCaptureEnabled, synthesizeMemoryAttachment, } from "../../shared/memory-attachment.js";
28
- import { injectSynthesizedAttachment } from "../../shared/synthesized-attachment.js";
29
- import { shouldConnectMcp } from "./mcp-gate.js";
30
- import { WorkspaceProvisioner } from "../../shared/workspace/provisioner.js";
31
- import { LocalWorkspaceBackend } from "../../shared/workspace/local-backend.js";
32
- import { createCasCaptureBackend } from "./cas-capture-backend.js";
33
- import { buildShellEnv } from "./shell-env.js";
34
- import { buildPlanModePermissions } from "../../shared/plan-mode-permissions.js";
35
- import { CasCaptureObserver } from "./cas-capture-observer.js";
36
- import { isGitWorkTree, isPathCapturable } from "../../shared/filereview/git-substrate.js";
37
- import { deriveCaptureMode } from "../../shared/filereview/capture.js";
38
- import { resolveWorkspacePath } from "../../shared/file-change.js";
39
- import { ensurePlatformDir, ensureCheckpointDbPath } from "../../shared/workspace/platform-dir.js";
40
- import { resolveSessionWorkspaceRoot } from "../../shared/workspace/session-root.js";
41
- import { reportSetupProgress } from "../../shared/status.js";
42
- import { resolveEnvironment } from "./environment.js";
43
- import { buildEnhancedSystemPrompt, composeUserMessage } from "./prompt-builder.js";
44
- import { buildMiddlewareStack } from "../../middleware/index.js";
45
- import { createThinkTool, createWebFetchTool, resolveGuardPosture } from "../../tools/index.js";
46
- import { deriveExecutionFingerprintKey } from "../../shared/approval-fingerprint.js";
47
- import { getRunnerHitlMasterSecret } from "../../shared/fingerprint-secret.js";
48
- import { getModelPricing, ensureLoaded as ensurePricingLoaded } from "../../shared/model-pricing.js";
49
- import { getDefaultModel, getModelVisionCapability } from "../../shared/model-registry.js";
50
- import { buildChatModel } from "../../shared/model-client.js";
51
- import { resolveEffectiveServiceTier } from "../../shared/service-tier.js";
52
- import { loadArtifactStorageConfig, resolveUsableArtifactStorage, } from "../../shared/artifact-storage.js";
53
- import { mergeApprovalPolicies, deriveActiveLeases, isUnattendedApprovalMode, } from "../../shared/approval-policy.js";
54
- import { mergeSkillRefs, fetchSkillsByRefs, mountSkills, generatePromptSection, generateAlsoAvailableSection, } from "../../shared/skill-writer.js";
55
- import { filterSkills, SKILL_COUNT_THRESHOLD } from "../../shared/skill-relevance.js";
56
- import { injectAttachments } from "./attachment-injector.js";
57
- import { DEEP_AGENT_VISION_PROFILE, VisionBudget, toLangChainImageBlocks, } from "../../shared/attachment-vision.js";
58
- import { transformAndCompileSubagents } from "./subagent-transformer.js";
59
- import { resolveRecursionLimit, UNBOUNDED_ADVISORY_RECURSION_LIMIT, } from "../../shared/tool-rounds.js";
60
- /**
61
- * Execute all setup phases and return resources for the streaming phase.
62
- *
63
- * On failure, partial resources (MCP connections, workspace backend) are
64
- * cleaned up internally before re-throwing.
65
- */
66
- export async function performSetup(deps) {
67
- const { config, client, executionId, threadId } = deps;
68
- let mcpConnection = null;
69
- // Cold-start timeline of this setup (warm-agent-surfaces Phase 0): one mark
70
- // after each phase, emitted as a single structured log line before return.
71
- const timing = new TimingRecorder();
72
- try {
73
- // Step 1: Hydrate execution
74
- await reportSetupProgress(client, executionId, "Fetching execution…");
75
- const execution = await client.getExecution(executionId);
76
- console.log(`[setup] Execution fetched: agent_id=${execution.spec?.agentId}`);
77
- timing.mark("fetch_execution");
78
- // Step 2: Resolve chain — execution → session → agentInstance → agent
79
- await reportSetupProgress(client, executionId, "Resolving agent…");
80
- const sessionId = execution.spec.sessionId;
81
- if (!sessionId) {
82
- throw new Error(`Session ID is required for execution ${executionId}. ` +
83
- "Execution must have a valid session_id.");
84
- }
85
- const session = await client.getSession(sessionId);
86
- const agentInstance = await client.getAgentInstance(session.spec.agentInstanceId);
87
- const agent = await client.getAgent(agentInstance.spec.agentId);
88
- const instructions = agent.spec.instructions || "You are a helpful AI assistant.";
89
- console.log(`[setup] Chain resolved: session=${sessionId}, ` +
90
- `agent=${agent.metadata.name}`);
91
- timing.mark("resolve_chain");
92
- // Step 3: Resolve model
93
- const modelName = execution.spec.executionConfig?.modelName
94
- || await getDefaultModel();
95
- // Step 4: Create checkpointer. The durable local (sqlite) backend keys its
96
- // file per session — a session has exactly one thread (`thread-{sessionId}`),
97
- // so checkpoint lifetime tracks session lifetime. The saver is closed in the
98
- // activity cleanup (see index.ts), alongside the MCP connection.
99
- const checkpointer = await createCheckpointer({
100
- type: config.checkpointerType,
101
- proxyEndpoint: config.checkpointerProxyEndpoint ?? undefined,
102
- authToken: config.stigmerToken ?? undefined,
103
- sqlitePath: config.checkpointerType === "sqlite"
104
- ? await ensureCheckpointDbPath(sessionId)
105
- : undefined,
106
- });
107
- timing.mark("create_checkpointer");
108
- // Step 5: Resolve environment
109
- await reportSetupProgress(client, executionId, "Resolving environment…");
110
- const envResult = await resolveEnvironment(client, executionId);
111
- timing.mark("resolve_environment");
112
- // Step 6: Resolve a usable artifact store (shared with the Cursor harness so
113
- // both degrade identically). Returns `undefined` — never throws — when there
114
- // is no working substrate: a proxy misconfig OR an unwritable local path
115
- // (which `createArtifactStorage` cannot detect, since it just holds a path).
116
- // An absent store flips capture mode off (deny-gate fallback below) and
117
- // disables offload, instead of flowing writes then crashing at the boundary.
118
- const artifactStorage = await resolveUsableArtifactStorage(loadArtifactStorageConfig(config), { executionId });
119
- timing.mark("resolve_artifact_storage");
120
- // Step 7: Provision workspace
121
- await reportSetupProgress(client, executionId, "Initializing workspace…");
122
- const { workspaceBackend, provisionResults } = await provisionWorkspace(config, session, envResult.mergedEnvVars, sessionId);
123
- timing.mark("provision_workspace");
124
- // Apply-then-review is the file-review model whenever there is a capture
125
- // SUBSTRATE (DD-21 D2, Slice 2b): file edits flow during the turn and are
126
- // reviewed post-hoc as a captured `FileChangeSet` (reconciled byte-exactly on
127
- // resume), never gated before they run. The substrate is selected by
128
- // `gitWorkspace`:
129
- // - a git work tree diffs a pinned baseline -> candidate tree (git-substrate,
130
- // needs no artifact storage), and routes its .gitignored edits into the
131
- // path-scoped CAS observer;
132
- // - a non-git workspace has no git snapshot at all, so EVERY touched path is
133
- // captured into the content-addressed CAS manifest (cas-substrate), which
134
- // needs artifact storage to persist blobs.
135
- // So a non-git workspace with NO artifact storage has no substrate: capture
136
- // degrades to the deny-gate (file writes gated pre-execution), exactly like the
137
- // Cursor harness (DD-22). `deriveCaptureMode` is the shared decision so both
138
- // harnesses degrade identically. When capture is on, the deny-gate survives only
139
- // for shell/MCP/irreversible tools.
140
- const gitWorkspace = await isGitWorkTree(workspaceBackend.rootDir);
141
- const captureMode = deriveCaptureMode(workspaceBackend.rootDir, gitWorkspace, !!artifactStorage);
142
- // Git-tracked capturability, consulted by the gate to route a file write to
143
- // disk-and-git-diff (tracked) vs into CAS (ignored). Only meaningful in a git
144
- // work tree. In a non-git workspace nothing is "git-capturable" (there is no
145
- // snapshot), so this resolves false for every path and the gate routes all
146
- // file writes through its captureIgnored (CAS) arm.
147
- const isCapturablePath = gitWorkspace
148
- ? (rawPath) => isPathCapturable(workspaceBackend.rootDir, resolveWorkspacePath(rawPath, workspaceBackend.rootDir, true).path)
149
- : (_rawPath) => Promise.resolve(false);
150
- // CAS capture (design docs 08/11/12): the content-addressed half of
151
- // apply-then-review. The single per-turn observer owns the before-bytes of
152
- // first-touched CAS-owned paths AND the secret-blocked paths, keyed
153
- // workspace-root-relative so they align with the CAS reconcile's
154
- // `join(workspaceRoot, path)`. It is shared by the parent AND every sub-agent
155
- // CAS backend, giving race-free first-touch-wins across concurrent graphs.
156
- // Its ownership predicate is memoized, so `git check-ignore` runs at most once
157
- // per distinct path.
158
- const casObserver = new CasCaptureObserver({
159
- rootDir: workspaceBackend.rootDir,
160
- // Which touched paths the observer owns (records pre-turn bytes for). In a
161
- // git work tree that is the .gitignored set only — git captures the tracked
162
- // ones. In a non-git workspace there is no git substrate, so the observer
163
- // owns EVERY touched path; the CAS manifest is the sole capture surface.
164
- isIgnored: gitWorkspace
165
- ? async (relPath) => !(await isPathCapturable(workspaceBackend.rootDir, relPath))
166
- : async () => true,
167
- });
168
- // Step 7: Resolve and connect MCP servers. Session-wins-per-slug merge
169
- // (the Cursor harness's blueprint semantics, shared so a duplicate slug
170
- // resolves identically in both harnesses — one usage per server, whose
171
- // enabled_tools is the one the connect-time filter honors).
172
- const mcpServerUsages = mergeMcpServerUsages(agent.spec.mcpServerUsages || [], session.spec.mcpServerUsages || []);
173
- // The synthesized attachments' credential story (DD-006 D4): the
174
- // exchanged token authenticates the discovery reads per-call (the
175
- // messaging reach refuses a desktop runner's ambient embedded_runner
176
- // credential; undefined lets the ambient credential apply). The
177
- // attachment header falls back to the ambient credential. Unlike the
178
- // env read (which hard-fails on a broken exchange — secrets are
179
- // load-bearing there), this exchange is opportunistic: every consumer
180
- // below degrades to an empty answer by contract, and the server
181
- // refuses the ambient fallback safely, so a failed exchange must not
182
- // kill the run.
183
- let exchangedRunnerToken;
184
- try {
185
- exchangedRunnerToken =
186
- await client.acquireScopedRunnerToken({ agentExecutionId: executionId });
187
- }
188
- catch (err) {
189
- console.warn("[execute-deep-agent] Scoped-token exchange failed for attachment/discovery " +
190
- `reads; degrading to the ambient credential: ${err instanceof Error ? err.message : err}`);
191
- }
192
- const attachmentCredential = exchangedRunnerToken
193
- ?? config.stigmerTokenRef?.current
194
- ?? config.stigmerToken;
195
- // The channel discovery read runs BEFORE the MCP gate below: an
196
- // agent whose ONLY tool source is a proactive channel would
197
- // otherwise never enter MCP resolution and never connect the
198
- // attachment (DD-006 D7). Every failure mode degrades to an empty
199
- // answer — no tool, no section, execution unharmed.
200
- const channelMessaging = await discoverChannelMessaging(client, exchangedRunnerToken);
201
- // The conversation-attachment decision (DD-008 D-c): the channel-id
202
- // session label, stamped server-side on every channel session — a
203
- // free, synchronous read, so no hoisted discovery needed.
204
- const conversationChannelId = readChannelConversationId(session.metadata?.labels);
205
- // The memory-attachment decision (DD-005 D1): the recall snapshot's
206
- // enabled bit, stamped server-side at execution create — like the
207
- // conversation attachment, a free, synchronous spec read.
208
- const captureMemories = memoryCaptureEnabled(execution.spec?.recalledMemories);
209
- let resolvedMcpServers = null;
210
- if (shouldConnectMcp({
211
- mcpServerUsageCount: mcpServerUsages.length,
212
- channelMessagingCount: channelMessaging.length,
213
- conversationChannelId,
214
- memoryCaptureEnabled: captureMemories,
215
- })) {
216
- await reportSetupProgress(client, executionId, "Connecting tools…");
217
- const transportPosture = resolveMcpTransportPosture(config.mode);
218
- // The MCP-bound env map (and ONLY it) carries the reserved
219
- // caller-identity keys — mirror of the Cursor harness's Phase 4
220
- // injection; filterEnvToDeclaredKeys keeps undeclared servers blind.
221
- const mcpEnvVars = injectCallerIdentityEnv(envResult.mergedEnvVars, resolveCallerIdentity(session.spec.metadata, session.status?.audit?.specAudit?.createdBy), sessionId);
222
- resolvedMcpServers = await resolveMcpServers(client, mcpServerUsages, mcpEnvVars, transportPosture);
223
- timing.mark("resolve_mcp_servers");
224
- const sessionOrg = session.metadata?.org ?? "";
225
- let backfilledServers = await backfillMcpServersIfNeeded(client, resolvedMcpServers.resolvedServers, mcpServerUsages, mcpEnvVars, sessionOrg, transportPosture, undefined, envResult.secretKeys);
226
- // The channel messaging attachment (DD-006 D7/D8) — injected AFTER
227
- // resolve + backfill so the destructiveHint tightener can never gate
228
- // it; empty approval maps keep it approval-free by construction.
229
- if (channelMessaging.length > 0) {
230
- const attachment = synthesizeChannelAttachment(channelMessaging, {
231
- bridgeEndpoint: config.mcpBridgeEndpoint,
232
- credential: attachmentCredential,
233
- backendEndpoint: config.stigmerBackendEndpoint,
234
- });
235
- if (attachment) {
236
- backfilledServers = injectSynthesizedAttachment(backfilledServers, attachment, "channel messaging");
237
- }
238
- }
239
- // The conversation participation attachment (DD-008 D-c) — the
240
- // channel attachment's sibling, same after-backfill rule. HTTP-only:
241
- // synthesize answers undefined with no bridge endpoint by design (see
242
- // shared/conversation-attachment.ts).
243
- const conversationAttachment = synthesizeConversationAttachment(conversationChannelId, {
244
- bridgeEndpoint: config.mcpBridgeEndpoint,
245
- credential: attachmentCredential,
246
- backendEndpoint: config.stigmerBackendEndpoint,
247
- });
248
- if (conversationAttachment) {
249
- backfilledServers = injectSynthesizedAttachment(backfilledServers, conversationAttachment, "conversation participation");
250
- }
251
- // The memory capture attachment (DD-005 D1) — same after-backfill
252
- // rule. The capture context is attribution the server verifies or
253
- // trusts per edition (Stage 3 provenance decision); the subject is
254
- // never threaded — it derives from the credential.
255
- if (captureMemories) {
256
- const memoryAttachment = synthesizeMemoryAttachment(execution.spec?.recalledMemories, {
257
- org: session.metadata?.org ?? "",
258
- agentId: agent.metadata?.id ?? "",
259
- sessionId,
260
- agentExecutionId: executionId,
261
- }, {
262
- bridgeEndpoint: config.mcpBridgeEndpoint,
263
- credential: attachmentCredential,
264
- backendEndpoint: config.stigmerBackendEndpoint,
265
- });
266
- if (memoryAttachment) {
267
- backfilledServers = injectSynthesizedAttachment(backfilledServers, memoryAttachment, "memory capture");
268
- }
269
- }
270
- resolvedMcpServers = { resolvedServers: backfilledServers };
271
- timing.mark("backfill_mcp");
272
- // connect_mcp covers the whole fan-out: stdio servers spawn npx/uvx
273
- // subprocesses here, so on-demand package installs land in this span.
274
- mcpConnection = await connectMcpServers(resolvedMcpServers.resolvedServers);
275
- timing.mark("connect_mcp");
276
- }
277
- // Step 7b: Resolve and write skills
278
- const skillRefs = mergeSkillRefs(agent.spec.skillRefs || [], session.spec.skillRefs || []);
279
- let skillsPromptSection = "";
280
- if (skillRefs.length > 0) {
281
- await reportSetupProgress(client, executionId, "Loading skills…");
282
- const skills = await fetchSkillsByRefs(client, skillRefs);
283
- if (skills.length > 0) {
284
- // platformDir is an invariant of this path: provisionWorkspace below
285
- // threads ensurePlatformDir into every backend it constructs.
286
- const { paths: skillPaths } = await mountSkills(client, skills, workspaceBackend.platformDir);
287
- const userMessage = execution.spec.message || "";
288
- const skillNames = skills.map(s => s.spec?.name || s.metadata?.slug || "unknown");
289
- const skillDescriptions = skills.map(s => s.spec?.description || "");
290
- if (skills.length >= SKILL_COUNT_THRESHOLD) {
291
- const filterResult = filterSkills(userMessage, skillNames, skillDescriptions);
292
- if (filterResult.excludedNames.length > 0) {
293
- const includedSkills = filterResult.includedIndices.map(i => skills[i]);
294
- console.log(`[setup] Skill relevance filter: ${includedSkills.length} included, ` +
295
- `${filterResult.excludedNames.length} excluded: ${filterResult.excludedNames.join(", ")}`);
296
- skillsPromptSection =
297
- generatePromptSection(includedSkills, skillPaths) +
298
- generateAlsoAvailableSection(filterResult.excludedNames);
299
- }
300
- else {
301
- skillsPromptSection = generatePromptSection(skills, skillPaths);
302
- }
303
- }
304
- else {
305
- skillsPromptSection = generatePromptSection(skills, skillPaths);
306
- }
307
- console.log(`[setup] Skills loaded: ${skills.length} total, prompt section ${skillsPromptSection.length} chars`);
308
- }
309
- timing.mark("resolve_skills");
310
- }
311
- // Step 7c: Inject attachments. The vision budget rides along so image
312
- // attachments are selected for inline delivery while their bytes are
313
- // already in hand (attachment-vision.ts owns all policy). The budget
314
- // also carries the root model's registry vision capability — the root
315
- // model is the only one that ever receives inline image blocks
316
- // (sub-agents get a fresh task description, summarization reuses this
317
- // same model instance) — so a model flagged `vision: false` degrades
318
- // images honestly instead of shipping a payload its provider rejects.
319
- const attachments = execution.spec.attachments || [];
320
- const visionBudget = new VisionBudget(DEEP_AGENT_VISION_PROFILE, {
321
- modelVision: await getModelVisionCapability(modelName),
322
- });
323
- const injectedFiles = await injectAttachments({
324
- backend: workspaceBackend,
325
- attachments,
326
- storage: artifactStorage,
327
- isLocalMode: config.mode === "local",
328
- visionBudget,
329
- });
330
- // Vision facts, derived once from the single injection result: the images
331
- // the model will see inline (in attachment order) and the ones that
332
- // degraded to path-only, disclosed in the system prompt's Input Files
333
- // section.
334
- const visionImages = injectedFiles.flatMap((f) => (f.vision ? [f.vision] : []));
335
- const visionNotViewable = injectedFiles.flatMap((f) => f.visionDegraded ? [{ path: f.path, reason: f.visionDegraded }] : []);
336
- const visionPromptInfo = visionImages.length > 0 || visionNotViewable.length > 0
337
- ? {
338
- inlineFilenames: visionImages.map((v) => v.filename),
339
- notViewable: visionNotViewable,
340
- }
341
- : undefined;
342
- if (visionPromptInfo) {
343
- console.log(`[attachment-vision] execution=${executionId} inline=${visionImages.length} ` +
344
- `(${visionImages.reduce((n, v) => n + v.byteSize, 0)} bytes) ` +
345
- `degraded=${JSON.stringify(visionNotViewable.map((d) => `${d.path}:${d.reason}`))}`);
346
- }
347
- timing.mark("inject_attachments");
348
- // Step 8: Build enhanced system prompt.
349
- //
350
- // Recalled memories go through the semantic retriever (DD-008), not the
351
- // raw snapshot read: above the activation threshold it selects the
352
- // top-k facts for THIS turn's message (one batched embeddings call);
353
- // otherwise — and on any failure — it injects the full candidate set,
354
- // exactly the Phase 2 behavior. A re-invocation of this execution
355
- // (approval resume) replays the outcome recorded on the execution's
356
- // status instead of re-selecting, so the prompt never shifts
357
- // mid-execution. The report returned here is stamped onto the turn's
358
- // status by the activity (index.ts) — setup has no status object yet.
359
- const memorySelection = await selectRecalledFacts(execution.spec.recalledMemories, execution.spec.message, {
360
- proxyEndpoint: config.proxyEndpoint,
361
- stigmerToken: config.stigmerToken,
362
- executionId,
363
- priorReport: execution.status?.recalledMemoriesReport,
364
- });
365
- const systemPrompt = buildEnhancedSystemPrompt({
366
- instructions,
367
- provisionResults,
368
- containerRoot: workspaceBackend.rootDir,
369
- skillsPromptSection,
370
- // "" (nothing sendable) threads as undefined: the tool alone still
371
- // serves text sends inside a 24-hour window (DD-006 D6).
372
- channelTemplatesPromptSection: channelMessaging.length > 0
373
- ? formatChannelTemplatesSection(channelMessaging) || undefined
374
- : undefined,
375
- workspaceFileRefs: execution.spec.workspaceFileRefs || [],
376
- workspaceRoot: workspaceBackend.rootDir,
377
- injectedFiles,
378
- vision: visionPromptInfo,
379
- downloadUrlKind: artifactStorage?.downloadUrlKind,
380
- interactionMode: execution.spec.executionConfig?.interactionMode,
381
- buildFromPlan: execution.spec.executionConfig?.buildFromPlan,
382
- contextBridge: readContextBridge(session.spec.metadata),
383
- senderIdentity: readSenderIdentity(session.spec.metadata),
384
- sessionContext: readSessionContext(session.spec.metadata),
385
- declaredPreferences: readDeclaredPreferences(execution.spec.declaredPreferences),
386
- recalledMemories: memorySelection.content,
387
- });
388
- // Step 9: Construct the LLM model. Resolution to the provider API id
389
- // happens inside buildChatModel; modelName stays the registry id for
390
- // pricing, the native-thinking heuristic, and sub-agent inheritance.
391
- // The operator's STIGMER_LLM_REQUEST_TIMEOUT_MS bound is applied inside
392
- // buildChatModel (#468) — the sub-agent modelFactory below silently
393
- // dropped it when each caller parsed the env itself.
394
- //
395
- // The service tier resolves ONCE here (UNSPECIFIED → explicit
396
- // STANDARD, shared/service-tier.ts) and rides every model this
397
- // execution constructs — the primary below AND the sub-agent factory —
398
- // so the provider account's default can never pick the price of any
399
- // turn (#361, the native half of #357's contract). Sub-agents inherit
400
- // it because the tier is an attribute of the EXECUTION's bill, and
401
- // sub-agent calls land on the same ledger.
402
- const serviceTier = resolveEffectiveServiceTier(execution.spec.executionConfig?.serviceTier);
403
- const { model } = await buildChatModel({
404
- modelName,
405
- proxyEndpoint: config.proxyEndpoint ?? undefined,
406
- stigmerToken: config.stigmerToken ?? undefined,
407
- headerScope: { executionId },
408
- serviceTier,
409
- });
410
- timing.mark("build_model");
411
- // Step 10: Build middleware stack
412
- await ensurePricingLoaded();
413
- const pricing = getModelPricing(modelName);
414
- const execConfig = execution.spec.executionConfig;
415
- const isPlanMode = execConfig?.interactionMode === InteractionMode.PLAN;
416
- const shellEnv = isPlanMode ? undefined : buildShellEnv(envResult.mergedEnvVars);
417
- // Plan mode's filesystem permission rules, hoisted once: the parent graph
418
- // and every sub-agent graph carry this single value. The rules are the
419
- // write-deny half of plan mode only — the read boundary is structural
420
- // (virtual-rooted backends, issue #754), and the path-normalization shim
421
- // is no longer tied to the rules: every native graph installs it (see
422
- // buildMiddlewareStack below) so the whole harness speaks one dialect.
423
- const planModePermissions = isPlanMode ? buildPlanModePermissions() : undefined;
424
- const toolServerMap = new Map();
425
- if (mcpConnection) {
426
- for (const [serverName, serverTools] of Object.entries(mcpConnection.serverToolMap)) {
427
- for (const t of serverTools) {
428
- toolServerMap.set(t.name, serverName);
429
- }
430
- }
431
- }
432
- // Step 10b: Resolve approval policies + leases.
433
- //
434
- // Two distinct bypasses (see ActiveLeases): the pre-armed
435
- // spec.auto_approve_all is the one whole-run global bypass; an interactive
436
- // APPROVE_ALL grants a run-lifetime lease scoped to that action's class (its
437
- // built-in category, or its MCP server). Server leases shape the policy map
438
- // (leased servers dropped); built-in category leases are applied inside the
439
- // gate. Both flow into sub-agents via the shared config below.
440
- const leases = deriveActiveLeases(execution);
441
- const globalBypass = leases.global;
442
- // Layer-3 overrides ride each resolved server from its (session-wins
443
- // merged) usage — see ResolvedMcpServer.toolApprovalOverrides (issue
444
- // #349) — so there is no separate override input to pass here.
445
- const approvalPolicies = mergeApprovalPolicies(resolvedMcpServers?.resolvedServers ?? [], leases);
446
- // Unattended approval mode (DD-014): approver-less surfaces (channels,
447
- // guest shares) stamp APPROVAL_MODE_UNATTENDED, and the gate resolves
448
- // gated tools as automatic skips instead of interrupting. The registry is
449
- // the gate→reconciler channel for the skipped tool-call ids; one instance
450
- // is shared with sub-agent gates via the inherited config.
451
- const unattended = isUnattendedApprovalMode(execution);
452
- const unattendedSkips = new Set();
453
- // The approval gate config is the single source of truth for HITL gating,
454
- // built once and inherited verbatim by sub-agents (so a mutating tool inside
455
- // a sub-agent is gated identically to one in the parent). Null under the
456
- // global pre-arm, where the gate is inert; under scoped leases the gate stays
457
- // active and clears only leased categories. The per-execution fingerprint key
458
- // (runner master secret + execution_id) drives the shadow ExecutionReceipt.
459
- const approvalGateConfig = !globalBypass
460
- ? {
461
- policies: approvalPolicies,
462
- leasedCategories: leases.categories,
463
- toolServerMap,
464
- fingerprintKey: deriveExecutionFingerprintKey(getRunnerHitlMasterSecret(), executionId),
465
- executionId,
466
- // Capture mode: file edits flow and are reviewed post-hoc. In a git work
467
- // tree, git-tracked edits flow to the git diff and .gitignored edits flow
468
- // into CAS (captureIgnored) on THIS parent gate; in a non-git workspace
469
- // isCapturablePath is always false, so ALL file writes take the CAS arm.
470
- // Secret-like paths are hard-blocked (DD-E) and recorded for a
471
- // DIFF_UNREVIEWABLE entry. shell/MCP stay gated. Sub-agents inherit this
472
- // config; buildSubAgentMiddleware sets their captureIgnored explicitly
473
- // from whether a CAS observer backs the sub-agent (Session 26, DD-19),
474
- // so their captured edits flow into the SAME observer.
475
- //
476
- // When captureMode is false (no substrate — non-git + no storage),
477
- // fileCaptureMode is false so file writes take the plain deny-gate. The
478
- // CAS arm additionally requires storage: captureIgnored gates gitignored
479
- // writes onto CAS only when a store exists to persist their blobs (the
480
- // git+no-storage case), matching the Cursor harness's
481
- // `captureMode && !!artifactStorage`.
482
- fileCaptureMode: captureMode,
483
- isCapturablePath,
484
- captureIgnored: captureMode && !!artifactStorage,
485
- recordBlockedSecret: (rawPath) => casObserver.recordBlockedSecret(rawPath),
486
- // Pre-delete byte capture (issue #303): deepagents has no backend
487
- // delete method for the CAS backend to observe, so a flowing delete's
488
- // before-bytes are recorded by the gate at authorization time, through
489
- // the SAME shared observer — the turn boundary then reads after=null
490
- // and authors a reviewable, restorable DELETE. recordBefore's own
491
- // ownership predicate (gitignored-only in a git tree, everything in
492
- // non-git) agrees with the gate's not-capturable condition.
493
- captureDeleteBefore: (rawPath) => casObserver.recordBefore(rawPath),
494
- unattended,
495
- unattendedSkips,
496
- }
497
- : null;
498
- const maxCostUsd = execConfig?.maxCostUsd ?? 0;
499
- // max_tool_rounds → recursion limit (proto contract: 0/unset = unlimited,
500
- // set = clamped 10–1000 and enforced). One resolved value feeds BOTH the
501
- // hard stop on the invoke config below and the budget middleware's ~80%
502
- // wrap-up advisory, so the warning and the enforcement can never disagree.
503
- const recursionLimit = resolveRecursionLimit(execConfig?.maxToolRounds);
504
- const { middleware, gracefulStop, costCap: costCapMiddleware } = buildMiddlewareStack({
505
- loopDetection: {
506
- historySize: 20,
507
- consecutiveThreshold: 7,
508
- totalThreshold: 20,
509
- },
510
- executionBudget: {
511
- recursionLimit: recursionLimit ?? UNBOUNDED_ADVISORY_RECURSION_LIMIT,
512
- warningPct: 80,
513
- },
514
- toolTruncation: {
515
- maxChars: execConfig?.maxToolResultChars || 30_000,
516
- },
517
- costCap: maxCostUsd > 0 ? {
518
- maxCostUsd,
519
- inputPricePerMillion: pricing.inputPricePerMillion,
520
- outputPricePerMillion: pricing.outputPricePerMillion,
521
- cacheReadPricePerMillion: pricing.cacheReadPricePerMillion,
522
- warningPct: 80,
523
- } : null,
524
- otelSpans: { toolServerMap },
525
- approvalGate: approvalGateConfig,
526
- // Every graph, every mode (issue #754): the dialect-repair seam that
527
- // keeps model-supplied paths canonical for the virtual-rooted backend
528
- // and every downstream consumer (gate, capture, spans).
529
- pathNormalization: { rootDir: workspaceBackend.rootDir },
530
- });
531
- timing.mark("build_middleware");
532
- // Step 11: Build tools list (MCP tools + native built-in tools).
533
- //
534
- // web_fetch is always-on for every native run — the same posture as the
535
- // Cursor harness, whose WebFetch is a CLI built-in that no configuration
536
- // removes (issue #214 parity). It is auto-approved by design (see
537
- // toolApprovalCategory in shared/tool-kind.ts), so its URL guard posture
538
- // — strict on managed cloud runners, relaxed on user-owned machines — is
539
- // the entire safety boundary. Derived from config.mode, NOT the
540
- // cloudModeEnabled Cursor feature flag.
541
- const webFetchPosture = resolveGuardPosture(config.mode);
542
- const tools = [
543
- ...(mcpConnection?.tools ?? []),
544
- createThinkTool(),
545
- createWebFetchTool({ posture: webFetchPosture }),
546
- ];
547
- // Step 11b: Transform and compile subagents
548
- const subAgentProtos = agent.spec.subAgents || [];
549
- let compiledSubagents;
550
- if (subAgentProtos.length > 0 || workspaceBackend.rootDir) {
551
- await reportSetupProgress(client, executionId, "Configuring sub-agents…");
552
- const parentMcpServerToolMap = new Map();
553
- if (mcpConnection) {
554
- for (const [serverName, serverTools] of Object.entries(mcpConnection.serverToolMap)) {
555
- parentMcpServerToolMap.set(serverName, serverTools);
556
- }
557
- }
558
- compiledSubagents = await transformAndCompileSubagents({
559
- subAgents: subAgentProtos,
560
- parentMcpTools: mcpConnection?.tools ?? [],
561
- parentMcpServerToolMap,
562
- parentMcpUsages: mcpServerUsages,
563
- skillClient: client,
564
- workspaceBackend,
565
- approvalGate: approvalGateConfig,
566
- // Capture is universal (Slice 2b), so every sub-agent gets a CAS-observing
567
- // backend wired to the SAME per-turn observer as the parent — their
568
- // captured writes (.gitignored in a git tree, all touched paths in a
569
- // non-git one) compose into the parent's change set (Session 26, DD-19).
570
- casObserver,
571
- parentModelName: modelName,
572
- parentHasNativeThinking: _modelHasNativeThinking(modelName),
573
- webFetchPosture,
574
- costCap: costCapMiddleware ?? undefined,
575
- modelFactory: async (m) => (await buildChatModel({
576
- modelName: m,
577
- proxyEndpoint: config.proxyEndpoint ?? undefined,
578
- stigmerToken: config.stigmerToken ?? undefined,
579
- headerScope: { executionId },
580
- // The execution's tier, inherited: sub-agent calls bill to the
581
- // same execution (#361 — see the Step 9 resolution comment).
582
- serviceTier,
583
- })).model,
584
- // Presence of shellEnv is the shell-capability switch for sub-agent
585
- // backends too (undefined in plan mode; see buildShellEnv above).
586
- shellEnv,
587
- // Plan mode's deny-all-writes rule, mirrored onto every sub-agent graph
588
- // (issue #255) — pre-built CompiledSubAgents never inherit the parent's
589
- // permissions, so read-only-by-construction must be baked in here.
590
- // compileSubagents derives each sub-agent's path-normalization shim
591
- // from this same value (issue #429).
592
- ...(planModePermissions ? { permissions: planModePermissions } : {}),
593
- });
594
- timing.mark("compile_subagents");
595
- }
596
- // Step 12: Create the agent graph with middleware
597
- await reportSetupProgress(client, executionId, "Creating agent…");
598
- const outputSchema = execution.spec.executionConfig?.structuredOutputSchema;
599
- let responseFormat;
600
- if (outputSchema) {
601
- responseFormat = jsonSchemaToZod(outputSchema);
602
- }
603
- // File capture point. Apply-then-review is universal (Slice 2b), so the
604
- // CAS-observing backend: git-tracked edits flow to disk (the turn-boundary
605
- // git diff is authoritative), and the shared CAS observer records the pre-turn
606
- // bytes of every CAS-owned path — .gitignored paths in a git work tree, all
607
- // touched paths in a non-git one — so the boundary can capture them into CAS.
608
- // It is gate-independent, so it holds even under the global bypass.
609
- const fileBackend = await createCasCaptureBackend({
610
- rootDir: workspaceBackend.rootDir,
611
- observer: casObserver,
612
- shellEnv,
613
- });
614
- const agentGraph = await createDeepAgent({
615
- model,
616
- checkpointer: checkpointer,
617
- backend: fileBackend,
618
- systemPrompt,
619
- tools,
620
- middleware: middleware,
621
- subagents: compiledSubagents ?? undefined,
622
- ...(responseFormat ? { responseFormat } : {}),
623
- ...(planModePermissions ? { permissions: planModePermissions } : {}),
624
- });
625
- // Step 11: Prepare invocation input and config. The conversation catchup
626
- // (cloud DD-006) rides the USER MESSAGE, not the system prompt — see
627
- // composeUserMessage for the durability rationale (A27).
628
- let userMessage = composeUserMessage(execution.spec.message, readConversationCatchup(execution.spec.conversationCatchup));
629
- if (outputSchema) {
630
- userMessage += `\n\n---\nIMPORTANT: When your analysis is complete, provide your findings as structured output matching the required schema. The system will capture your structured response automatically.`;
631
- }
632
- // With inline images the user message becomes a multimodal content-block
633
- // array — image blocks (with filename labels) FIRST, the composed text
634
- // last, per Anthropic's images-before-text guidance. Without images the
635
- // content stays a plain string, byte-identical to the pre-vision shape.
636
- // The LangGraph messages reducer coerces either form into a HumanMessage
637
- // untouched (verified against the installed @langchain/langgraph).
638
- const langgraphInput = {
639
- messages: [
640
- {
641
- role: "user",
642
- content: visionImages.length > 0
643
- ? [
644
- ...toLangChainImageBlocks(visionImages),
645
- { type: "text", text: userMessage },
646
- ]
647
- : userMessage,
648
- },
649
- ],
650
- };
651
- const langgraphConfig = {
652
- configurable: { thread_id: threadId },
653
- // Hard enforcement of max_tool_rounds (null = unlimited, the default):
654
- // when the graph exhausts this, the streaming loop's GraphRecursionError
655
- // handler terminates gracefully with work saved ("send another message
656
- // to continue"). The middleware's wrap-up advisory fires at ~80% of the
657
- // same value, so a healthy run finishes normally before ever hitting it.
658
- ...(recursionLimit !== null ? { recursionLimit } : {}),
659
- };
660
- const streamVersion = process.env.LANGGRAPH_STREAM_EVENTS_VERSION === "v2" ? "v2" : "v3";
661
- console.log(`[setup] Complete: model=${modelName}, ` +
662
- `tools=${tools.length}, middleware=${middleware.length}, ` +
663
- `thread_id=${threadId}, streamVersion=${streamVersion}`);
664
- timing.mark("create_agent_graph");
665
- emitTimingLog("execution_setup", {
666
- execution_id: executionId,
667
- session_id: sessionId,
668
- harness: "native",
669
- mcp_server_count: mcpServerUsages.length,
670
- skill_count: skillRefs.length,
671
- workspace_entry_count: session.spec.workspaceEntries?.length ?? 0,
672
- }, timing);
673
- return {
674
- agentGraph,
675
- checkpointer,
676
- langgraphConfig,
677
- langgraphInput,
678
- execution,
679
- agent,
680
- session,
681
- workspaceBackend,
682
- mcpConnection,
683
- mergedEnvVars: envResult.mergedEnvVars,
684
- secretKeys: envResult.secretKeys,
685
- modelName,
686
- gracefulStop,
687
- artifactStorage,
688
- provisionResults,
689
- approvalPolicies,
690
- toolServerMap,
691
- leasedCategories: leases.categories,
692
- globalBypass,
693
- unattended,
694
- unattendedSkips,
695
- hasStructuredOutput: !!outputSchema,
696
- streamVersion,
697
- casObserver,
698
- captureMode,
699
- gitWorkspace,
700
- recalledMemoriesReport: memorySelection.report,
701
- };
702
- }
703
- catch (err) {
704
- if (mcpConnection) {
705
- try {
706
- await mcpConnection.client.close();
707
- }
708
- catch { /* swallow */ }
709
- }
710
- throw err;
711
- }
712
- }
713
- /**
714
- * Provision workspace from session workspace entries.
715
- *
716
- * A session with no entries gets its own empty per-session directory (see
717
- * shared/workspace/session-root.ts) — never the shared root, which would
718
- * leak other sessions' files into it. Mirrors shared/workspace/
719
- * session-provision.ts `provisionSessionWorkspace` exactly; S3 of the
720
- * harness runtime program retires this twin in favor of that one.
721
- */
722
- async function provisionWorkspace(config, session, mergedEnvVars, sessionId) {
723
- const platformDir = await ensurePlatformDir(sessionId);
724
- const workspaceEntries = session.spec.workspaceEntries || [];
725
- if (workspaceEntries.length === 0) {
726
- const sessionRoot = await resolveSessionWorkspaceRoot(config.workspaceRootDir, workspaceEntries, sessionId);
727
- return {
728
- workspaceBackend: new LocalWorkspaceBackend(sessionRoot, platformDir),
729
- provisionResults: [],
730
- };
731
- }
732
- const workspaceBackend = new LocalWorkspaceBackend(config.workspaceRootDir, platformDir);
733
- const provisioner = new WorkspaceProvisioner();
734
- const provisionResults = await provisioner.provisionAll(workspaceEntries.map(entry => ({
735
- name: entry.name,
736
- source: entry.source,
737
- })), workspaceBackend, mergedEnvVars, config.mode === "local", config.mode !== "local");
738
- // If single entry changed root dir, create a new backend with the same platformDir
739
- if (provisionResults.length === 1 &&
740
- provisionResults[0].rootDir !== workspaceBackend.rootDir) {
741
- return {
742
- workspaceBackend: new LocalWorkspaceBackend(provisionResults[0].rootDir, platformDir),
743
- provisionResults,
744
- };
745
- }
746
- return { workspaceBackend, provisionResults };
747
- }
748
- // Shared JSON Schema → Zod converter (consolidated from 3 duplicate copies).
749
- import { jsonSchemaToZod } from "../../shared/json-schema-to-zod.js";
750
- /**
751
- * Heuristic check for native extended thinking support.
752
- * Models with thinking support don't need the explicit think tool.
753
- */
754
- function _modelHasNativeThinking(modelId) {
755
- const lower = modelId.toLowerCase();
756
- if (lower.includes("haiku"))
757
- return false;
758
- if (lower.includes("gpt-4o-mini"))
759
- return false;
760
- if (lower.includes("claude") && (lower.includes("sonnet") || lower.includes("opus")))
761
- return true;
762
- if (lower.includes("o1") || lower.includes("o3") || lower.includes("o4")) {
763
- return true;
764
- }
765
- return false;
766
- }
767
- //# sourceMappingURL=setup.js.map