@stigmer/runner 3.15.1 → 3.15.2-dev.20260913223433

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (518) hide show
  1. package/README.md +2 -4
  2. package/dist/.build-fingerprint +1 -1
  3. package/dist/__test-utils__/execution-record-fixture.d.ts +14 -0
  4. package/dist/__test-utils__/execution-record-fixture.js +4 -0
  5. package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
  6. package/dist/__test-utils__/file-review-projection.d.ts +40 -0
  7. package/dist/__test-utils__/file-review-projection.js +136 -0
  8. package/dist/__test-utils__/file-review-projection.js.map +1 -0
  9. package/dist/__test-utils__/harness-contract/types.d.ts +23 -1
  10. package/dist/__test-utils__/harness-contract/types.js +15 -0
  11. package/dist/__test-utils__/harness-contract/types.js.map +1 -1
  12. package/dist/__test-utils__/hermetic-activity.d.ts +44 -12
  13. package/dist/__test-utils__/hermetic-activity.js +52 -14
  14. package/dist/__test-utils__/hermetic-activity.js.map +1 -1
  15. package/dist/__test-utils__/model-registry-fixture.d.ts +32 -7
  16. package/dist/__test-utils__/model-registry-fixture.js +31 -7
  17. package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
  18. package/dist/__test-utils__/turn-input-fixture.d.ts +1 -1
  19. package/dist/__test-utils__/turn-input-fixture.js +1 -1
  20. package/dist/__test-utils__/turn-input-fixture.js.map +1 -1
  21. package/dist/activities/call-agent.js +2 -2
  22. package/dist/activities/call-agent.js.map +1 -1
  23. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +45 -3
  24. package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -1
  25. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +0 -9
  26. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +2 -41
  27. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
  28. package/dist/activities/execute-cursor/adapter.d.ts +7 -5
  29. package/dist/activities/execute-cursor/adapter.js +7 -5
  30. package/dist/activities/execute-cursor/adapter.js.map +1 -1
  31. package/dist/activities/execute-cursor/approval-policy.d.ts +5 -2
  32. package/dist/activities/execute-cursor/approval-policy.js +5 -2
  33. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  34. package/dist/activities/execute-cursor/approval-state.d.ts +16 -8
  35. package/dist/activities/execute-cursor/approval-state.js +6 -3
  36. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  37. package/dist/activities/execute-cursor/cas-observations.d.ts +14 -2
  38. package/dist/activities/execute-cursor/cas-observations.js +19 -2
  39. package/dist/activities/execute-cursor/cas-observations.js.map +1 -1
  40. package/dist/activities/execute-cursor/cursor-capabilities.d.ts +8 -4
  41. package/dist/activities/execute-cursor/cursor-capabilities.js +21 -4
  42. package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -1
  43. package/dist/activities/execute-cursor/message-translator.d.ts +12 -20
  44. package/dist/activities/execute-cursor/message-translator.js +19 -32
  45. package/dist/activities/execute-cursor/message-translator.js.map +1 -1
  46. package/dist/activities/execute-cursor/prompt-builder.d.ts +48 -58
  47. package/dist/activities/execute-cursor/prompt-builder.js +76 -95
  48. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  49. package/dist/activities/execute-cursor/turn-boundary.d.ts +27 -55
  50. package/dist/activities/execute-cursor/turn-boundary.js +30 -90
  51. package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
  52. package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
  53. package/dist/activities/execute-cursor/turn-settle.js +37 -49
  54. package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
  55. package/dist/activities/execute-cursor/turn-setup.d.ts +16 -24
  56. package/dist/activities/execute-cursor/turn-setup.js +29 -59
  57. package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
  58. package/dist/activities/execute-cursor/turn-stream.d.ts +3 -8
  59. package/dist/activities/execute-cursor/turn-stream.js +9 -22
  60. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  61. package/dist/activities/execute-cursor/turn.js +5 -1
  62. package/dist/activities/execute-cursor/turn.js.map +1 -1
  63. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +93 -0
  64. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +348 -0
  65. package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js.map +1 -0
  66. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +170 -0
  67. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +225 -0
  68. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -0
  69. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.d.ts +24 -0
  70. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +41 -0
  71. package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -0
  72. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +54 -0
  73. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +72 -0
  74. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -0
  75. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +187 -23
  76. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +238 -27
  77. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
  78. package/dist/activities/execute-deep-agent/adapter.d.ts +41 -0
  79. package/dist/activities/execute-deep-agent/adapter.js +78 -0
  80. package/dist/activities/execute-deep-agent/adapter.js.map +1 -0
  81. package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +8 -0
  82. package/dist/activities/execute-deep-agent/cas-capture-observer.js +9 -0
  83. package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -1
  84. package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +31 -0
  85. package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +40 -0
  86. package/dist/activities/execute-deep-agent/deep-agent-capabilities.js.map +1 -0
  87. package/dist/activities/execute-deep-agent/execution-state.d.ts +4 -11
  88. package/dist/activities/execute-deep-agent/execution-state.js +4 -12
  89. package/dist/activities/execute-deep-agent/execution-state.js.map +1 -1
  90. package/dist/activities/execute-deep-agent/hitl.d.ts +49 -47
  91. package/dist/activities/execute-deep-agent/hitl.js +77 -103
  92. package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
  93. package/dist/activities/execute-deep-agent/prompt-builder.d.ts +51 -23
  94. package/dist/activities/execute-deep-agent/prompt-builder.js +115 -76
  95. package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
  96. package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +18 -32
  97. package/dist/activities/execute-deep-agent/status-builder-shared.js +10 -65
  98. package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
  99. package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +10 -8
  100. package/dist/activities/execute-deep-agent/streaming-side-effects.js +12 -14
  101. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  102. package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +36 -13
  103. package/dist/activities/execute-deep-agent/subagent-tracker.js +76 -39
  104. package/dist/activities/execute-deep-agent/subagent-tracker.js.map +1 -1
  105. package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -28
  106. package/dist/activities/execute-deep-agent/subagent-transformer.js +29 -82
  107. package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
  108. package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +3 -2
  109. package/dist/activities/execute-deep-agent/subagent-wiring.js +2 -2
  110. package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
  111. package/dist/activities/execute-deep-agent/turn-settle.d.ts +42 -0
  112. package/dist/activities/execute-deep-agent/turn-settle.js +146 -0
  113. package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -0
  114. package/dist/activities/execute-deep-agent/turn-setup.d.ts +212 -0
  115. package/dist/activities/execute-deep-agent/turn-setup.js +430 -0
  116. package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -0
  117. package/dist/activities/execute-deep-agent/turn-stream.d.ts +97 -0
  118. package/dist/activities/execute-deep-agent/turn-stream.js +242 -0
  119. package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -0
  120. package/dist/activities/execute-deep-agent/turn.d.ts +42 -0
  121. package/dist/activities/execute-deep-agent/turn.js +116 -0
  122. package/dist/activities/execute-deep-agent/turn.js.map +1 -0
  123. package/dist/activities/execute-deep-agent/v3-event-recorder.d.ts +6 -5
  124. package/dist/activities/execute-deep-agent/v3-event-recorder.js +6 -5
  125. package/dist/activities/execute-deep-agent/v3-event-recorder.js.map +1 -1
  126. package/dist/activities/execute-deep-agent/v3-events.d.ts +1 -1
  127. package/dist/activities/execute-deep-agent/v3-events.js +1 -1
  128. package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +60 -17
  129. package/dist/activities/execute-deep-agent/v3-status-builder.js +72 -57
  130. package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
  131. package/dist/harness/approval-decisions.d.ts +61 -0
  132. package/dist/harness/approval-decisions.js +102 -0
  133. package/dist/harness/approval-decisions.js.map +1 -0
  134. package/dist/harness/capabilities.d.ts +16 -5
  135. package/dist/harness/capabilities.js +9 -0
  136. package/dist/harness/capabilities.js.map +1 -1
  137. package/dist/harness/capture.d.ts +144 -0
  138. package/dist/harness/capture.js +219 -0
  139. package/dist/harness/capture.js.map +1 -0
  140. package/dist/harness/persist-chokepoint.d.ts +19 -4
  141. package/dist/harness/persist-chokepoint.js +17 -4
  142. package/dist/harness/persist-chokepoint.js.map +1 -1
  143. package/dist/harness/run-turn.js +115 -29
  144. package/dist/harness/run-turn.js.map +1 -1
  145. package/dist/harness/terminal-table.d.ts +40 -11
  146. package/dist/harness/terminal-table.js +58 -19
  147. package/dist/harness/terminal-table.js.map +1 -1
  148. package/dist/harness/turn-context.d.ts +141 -76
  149. package/dist/harness/turn-context.js +194 -99
  150. package/dist/harness/turn-context.js.map +1 -1
  151. package/dist/harness/types.d.ts +65 -12
  152. package/dist/harness/types.js +8 -2
  153. package/dist/harness/types.js.map +1 -1
  154. package/dist/harness-adapters.d.ts +12 -8
  155. package/dist/harness-adapters.js +17 -9
  156. package/dist/harness-adapters.js.map +1 -1
  157. package/dist/middleware/approval-gate.d.ts +1 -1
  158. package/dist/middleware/approval-gate.js +1 -1
  159. package/dist/middleware/approval-gate.js.map +1 -1
  160. package/dist/middleware/cost-advisory.d.ts +39 -0
  161. package/dist/middleware/{cost-cap.js → cost-advisory.js} +37 -55
  162. package/dist/middleware/cost-advisory.js.map +1 -0
  163. package/dist/middleware/index.d.ts +23 -12
  164. package/dist/middleware/index.js +26 -18
  165. package/dist/middleware/index.js.map +1 -1
  166. package/dist/middleware/types.d.ts +3 -2
  167. package/dist/runner-manager.js +1 -5
  168. package/dist/runner-manager.js.map +1 -1
  169. package/dist/runner.js +1 -5
  170. package/dist/runner.js.map +1 -1
  171. package/dist/shared/attachment-resolver.d.ts +41 -18
  172. package/dist/shared/attachment-resolver.js +178 -46
  173. package/dist/shared/attachment-resolver.js.map +1 -1
  174. package/dist/shared/attachment-zip.d.ts +85 -0
  175. package/dist/shared/attachment-zip.js +185 -0
  176. package/dist/shared/attachment-zip.js.map +1 -0
  177. package/dist/shared/connect-backfill.js +5 -4
  178. package/dist/shared/connect-backfill.js.map +1 -1
  179. package/dist/shared/cost-guard.d.ts +3 -3
  180. package/dist/shared/cost-guard.js +3 -3
  181. package/dist/shared/execution-status-writer.d.ts +5 -5
  182. package/dist/shared/execution-status-writer.js +5 -5
  183. package/dist/shared/extract-structured-output.d.ts +8 -7
  184. package/dist/shared/extract-structured-output.js +8 -7
  185. package/dist/shared/extract-structured-output.js.map +1 -1
  186. package/dist/shared/filereview/cas-progress.d.ts +1 -18
  187. package/dist/shared/filereview/cas-progress.js +4 -0
  188. package/dist/shared/filereview/cas-progress.js.map +1 -1
  189. package/dist/shared/filereview/cas-touched.d.ts +56 -0
  190. package/dist/shared/filereview/cas-touched.js +63 -0
  191. package/dist/shared/filereview/cas-touched.js.map +1 -0
  192. package/dist/shared/filereview/index.d.ts +2 -1
  193. package/dist/shared/filereview/index.js +2 -1
  194. package/dist/shared/filereview/index.js.map +1 -1
  195. package/dist/shared/mcp-resolver.d.ts +4 -5
  196. package/dist/shared/mcp-resolver.js +4 -5
  197. package/dist/shared/mcp-resolver.js.map +1 -1
  198. package/dist/shared/persist-decision.d.ts +3 -4
  199. package/dist/shared/persist-decision.js +3 -4
  200. package/dist/shared/persist-decision.js.map +1 -1
  201. package/dist/shared/plan-mode-permissions.d.ts +2 -2
  202. package/dist/shared/plan-mode-permissions.js +2 -2
  203. package/dist/shared/plan-mode-prompt.d.ts +1 -1
  204. package/dist/shared/plan-mode-prompt.js +1 -1
  205. package/dist/shared/prompt-sections.d.ts +163 -0
  206. package/dist/shared/prompt-sections.js +164 -0
  207. package/dist/shared/prompt-sections.js.map +1 -0
  208. package/dist/shared/skill-resolver.d.ts +4 -2
  209. package/dist/shared/skill-resolver.js +4 -2
  210. package/dist/shared/skill-resolver.js.map +1 -1
  211. package/dist/shared/tool-rounds.d.ts +32 -0
  212. package/dist/shared/tool-rounds.js +43 -0
  213. package/dist/shared/tool-rounds.js.map +1 -1
  214. package/dist/shared/tool-row.d.ts +34 -0
  215. package/dist/shared/tool-row.js +52 -0
  216. package/dist/shared/tool-row.js.map +1 -1
  217. package/dist/shared/workspace/session-provision.d.ts +3 -3
  218. package/dist/shared/workspace/session-provision.js +3 -3
  219. package/dist/shared/workspace/stigmer-link.d.ts +3 -3
  220. package/dist/shared/workspace/stigmer-link.js +3 -3
  221. package/dist/shared/workspace/writeback-coordinator.d.ts +15 -22
  222. package/dist/shared/workspace/writeback-coordinator.js +16 -53
  223. package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
  224. package/dist/tools/index.d.ts +1 -1
  225. package/dist/tools/index.js +1 -1
  226. package/package.json +4 -4
  227. package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +1 -0
  228. package/src/__test-utils__/execution-record-fixture.ts +18 -2
  229. package/src/__test-utils__/file-review-projection.ts +156 -0
  230. package/src/__test-utils__/git-workspace-fixture.ts +58 -0
  231. package/src/__test-utils__/harness-boot-order-child.ts +7 -2
  232. package/src/__test-utils__/harness-contract/contract.ts +33 -20
  233. package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
  234. package/src/__test-utils__/harness-contract/runtime-contract.ts +328 -10
  235. package/src/__test-utils__/harness-contract/scripted-adapter.ts +38 -6
  236. package/src/__test-utils__/harness-contract/types.ts +27 -3
  237. package/src/__test-utils__/hermetic-activity.ts +52 -14
  238. package/src/__test-utils__/model-registry-fixture.ts +32 -7
  239. package/src/__test-utils__/module-specifiers.ts +24 -0
  240. package/src/__test-utils__/turn-input-fixture.ts +2 -2
  241. package/src/__tests__/harness-boot-order.test.ts +9 -2
  242. package/src/activities/call-agent.ts +2 -2
  243. package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +47 -3
  244. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +2 -48
  245. package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +1 -1
  246. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +6 -1
  247. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +52 -27
  248. package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +25 -0
  249. package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.everything.prompt.md +166 -0
  250. package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.plan-mode.prompt.md +186 -0
  251. package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.recovery.prompt.md +191 -0
  252. package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.reinvocation.prompt.md +13 -0
  253. package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.prefixed.prompt.md +32 -0
  254. package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.raw.prompt.md +1 -0
  255. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -2
  256. package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +4 -0
  257. package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +24 -4
  258. package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +6 -5
  259. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +9 -0
  260. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +11 -8
  261. package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +229 -0
  262. package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +3 -3
  263. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +2 -2
  264. package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +78 -234
  265. package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +1 -26
  266. package/src/activities/execute-cursor/adapter.ts +7 -5
  267. package/src/activities/execute-cursor/approval-policy.ts +5 -2
  268. package/src/activities/execute-cursor/approval-state.ts +16 -8
  269. package/src/activities/execute-cursor/cas-observations.ts +20 -2
  270. package/src/activities/execute-cursor/cursor-capabilities.ts +24 -5
  271. package/src/activities/execute-cursor/message-translator.ts +29 -41
  272. package/src/activities/execute-cursor/prompt-builder.ts +99 -157
  273. package/src/activities/execute-cursor/turn-boundary.ts +34 -140
  274. package/src/activities/execute-cursor/turn-settle.ts +37 -51
  275. package/src/activities/execute-cursor/turn-setup.ts +30 -70
  276. package/src/activities/execute-cursor/turn-stream.ts +8 -31
  277. package/src/activities/execute-cursor/turn.ts +5 -1
  278. package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +391 -0
  279. package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +313 -0
  280. package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +48 -0
  281. package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +85 -0
  282. package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +383 -36
  283. package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +76 -0
  284. package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +47 -0
  285. package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +80 -0
  286. package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +1 -1
  287. package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -2
  288. package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -3
  289. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +172 -0
  290. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +167 -0
  291. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.minimal.prompt.md +36 -0
  292. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +178 -0
  293. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +158 -0
  294. package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +210 -0
  295. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +74 -0
  296. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +104 -0
  297. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +78 -0
  298. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +138 -0
  299. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +68 -0
  300. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +154 -0
  301. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +116 -0
  302. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +69 -0
  303. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +67 -0
  304. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/plain-turn.status.json +47 -0
  305. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +68 -0
  306. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +280 -0
  307. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +77 -0
  308. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
  309. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +99 -0
  310. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +109 -0
  311. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +76 -0
  312. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.text-fallback.status.json +51 -0
  313. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tier2.status.json +51 -0
  314. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tool-strategy.status.json +56 -0
  315. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +90 -0
  316. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +70 -0
  317. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +71 -0
  318. package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +144 -0
  319. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +184 -0
  320. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +203 -0
  321. package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +170 -0
  322. package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +175 -0
  323. package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +206 -0
  324. package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +142 -0
  325. package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +126 -0
  326. package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +139 -0
  327. package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +122 -0
  328. package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +236 -0
  329. package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +161 -0
  330. package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +157 -0
  331. package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +152 -0
  332. package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +50 -122
  333. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +8 -6
  334. package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +2 -2
  335. package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +35 -35
  336. package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +247 -0
  337. package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +329 -0
  338. package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +1 -20
  339. package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +78 -0
  340. package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +1 -1
  341. package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +2 -2
  342. package/src/activities/execute-deep-agent/__tests__/subagent-tracker.test.ts +57 -31
  343. package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +19 -79
  344. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +15 -15
  345. package/src/activities/execute-deep-agent/__tests__/summarization-verification.test.ts +1 -1
  346. package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +391 -0
  347. package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +343 -38
  348. package/src/activities/execute-deep-agent/__tests__/vision-input.test.ts +5 -5
  349. package/src/activities/execute-deep-agent/adapter.ts +94 -0
  350. package/src/activities/execute-deep-agent/cas-capture-observer.ts +11 -0
  351. package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +43 -0
  352. package/src/activities/execute-deep-agent/execution-state.ts +4 -13
  353. package/src/activities/execute-deep-agent/hitl.ts +100 -123
  354. package/src/activities/execute-deep-agent/prompt-builder.ts +141 -115
  355. package/src/activities/execute-deep-agent/status-builder-shared.ts +21 -84
  356. package/src/activities/execute-deep-agent/streaming-side-effects.ts +13 -19
  357. package/src/activities/execute-deep-agent/subagent-tracker.ts +77 -42
  358. package/src/activities/execute-deep-agent/subagent-transformer.ts +46 -105
  359. package/src/activities/execute-deep-agent/subagent-wiring.ts +5 -4
  360. package/src/activities/execute-deep-agent/turn-settle.ts +164 -0
  361. package/src/activities/execute-deep-agent/turn-setup.ts +541 -0
  362. package/src/activities/execute-deep-agent/turn-stream.ts +313 -0
  363. package/src/activities/execute-deep-agent/turn.ts +131 -0
  364. package/src/activities/execute-deep-agent/v3-event-recorder.ts +6 -5
  365. package/src/activities/execute-deep-agent/v3-events.ts +1 -1
  366. package/src/activities/execute-deep-agent/v3-status-builder.ts +84 -63
  367. package/src/harness/__tests__/approval-decisions.test.ts +116 -0
  368. package/src/harness/__tests__/capture.test.ts +268 -0
  369. package/src/harness/__tests__/mount-skills.test.ts +169 -0
  370. package/src/harness/__tests__/persist-chokepoint.test.ts +38 -2
  371. package/src/harness/__tests__/run-turn-deterministic.test.ts +94 -0
  372. package/src/harness/__tests__/run-turn.test.ts +39 -23
  373. package/src/harness/__tests__/turn-attachments-vision.test.ts +80 -0
  374. package/src/harness/__tests__/turn-context.test.ts +73 -26
  375. package/src/harness/approval-decisions.ts +104 -0
  376. package/src/harness/capabilities.ts +16 -5
  377. package/src/harness/capture.ts +301 -0
  378. package/src/harness/persist-chokepoint.ts +24 -4
  379. package/src/harness/run-turn.ts +120 -29
  380. package/src/harness/terminal-table.ts +61 -20
  381. package/src/harness/turn-context.ts +208 -111
  382. package/src/harness/types.ts +66 -12
  383. package/src/harness-adapters.ts +17 -9
  384. package/src/middleware/__tests__/approval-gate.test.ts +1 -1
  385. package/src/middleware/__tests__/cost-advisory.test.ts +113 -0
  386. package/src/middleware/approval-gate.ts +2 -2
  387. package/src/middleware/{cost-cap.ts → cost-advisory.ts} +40 -70
  388. package/src/middleware/index.ts +29 -29
  389. package/src/middleware/types.ts +3 -2
  390. package/src/runner-manager.ts +0 -8
  391. package/src/runner.ts +0 -8
  392. package/src/shared/__tests__/attachment-naming.test.ts +6 -19
  393. package/src/shared/__tests__/attachment-resolver.test.ts +158 -8
  394. package/src/shared/__tests__/attachment-zip.test.ts +236 -0
  395. package/src/shared/__tests__/bedrock-adapter.test.ts +1 -1
  396. package/src/shared/__tests__/blueprint-resolver.test.ts +43 -0
  397. package/src/shared/__tests__/cost-guard.test.ts +3 -3
  398. package/src/shared/__tests__/prompt-sections.test.ts +167 -0
  399. package/src/shared/__tests__/secret-leak-scan.test.ts +2 -2
  400. package/src/{activities/execute-deep-agent → shared}/__tests__/stamp-flowed-rows.test.ts +33 -10
  401. package/src/shared/__tests__/vertex-adapter.test.ts +1 -1
  402. package/src/shared/attachment-resolver.ts +218 -55
  403. package/src/shared/attachment-zip.ts +281 -0
  404. package/src/shared/connect-backfill.ts +9 -11
  405. package/src/shared/cost-guard.ts +3 -3
  406. package/src/shared/execution-status-writer.ts +5 -5
  407. package/src/shared/extract-structured-output.ts +8 -7
  408. package/src/shared/filereview/__tests__/capture.test.ts +86 -4
  409. package/src/shared/filereview/__tests__/cas-progress.test.ts +2 -1
  410. package/src/shared/filereview/cas-progress.ts +5 -19
  411. package/src/shared/filereview/cas-touched.ts +89 -0
  412. package/src/shared/filereview/index.ts +4 -2
  413. package/src/shared/mcp-resolver.ts +4 -5
  414. package/src/shared/persist-decision.ts +3 -4
  415. package/src/shared/plan-mode-permissions.ts +2 -2
  416. package/src/shared/plan-mode-prompt.ts +1 -1
  417. package/src/shared/prompt-sections.ts +256 -0
  418. package/src/shared/skill-resolver.ts +4 -2
  419. package/src/shared/tool-rounds.ts +48 -0
  420. package/src/shared/tool-row.ts +61 -0
  421. package/src/shared/workspace/__tests__/stigmer-link.test.ts +7 -22
  422. package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +20 -61
  423. package/src/shared/workspace/session-provision.ts +3 -3
  424. package/src/shared/workspace/stigmer-link.ts +3 -3
  425. package/src/shared/workspace/writeback-coordinator.ts +16 -64
  426. package/src/tools/index.ts +1 -1
  427. package/dist/activities/execute-cursor/capture-flow.d.ts +0 -142
  428. package/dist/activities/execute-cursor/capture-flow.js +0 -285
  429. package/dist/activities/execute-cursor/capture-flow.js.map +0 -1
  430. package/dist/activities/execute-cursor/command-provenance.d.ts +0 -48
  431. package/dist/activities/execute-cursor/command-provenance.js +0 -38
  432. package/dist/activities/execute-cursor/command-provenance.js.map +0 -1
  433. package/dist/activities/execute-deep-agent/attachment-injector.d.ts +0 -134
  434. package/dist/activities/execute-deep-agent/attachment-injector.js +0 -386
  435. package/dist/activities/execute-deep-agent/attachment-injector.js.map +0 -1
  436. package/dist/activities/execute-deep-agent/command-provenance.d.ts +0 -61
  437. package/dist/activities/execute-deep-agent/command-provenance.js +0 -72
  438. package/dist/activities/execute-deep-agent/command-provenance.js.map +0 -1
  439. package/dist/activities/execute-deep-agent/environment.d.ts +0 -24
  440. package/dist/activities/execute-deep-agent/environment.js +0 -58
  441. package/dist/activities/execute-deep-agent/environment.js.map +0 -1
  442. package/dist/activities/execute-deep-agent/event-recorder.d.ts +0 -21
  443. package/dist/activities/execute-deep-agent/event-recorder.js +0 -67
  444. package/dist/activities/execute-deep-agent/event-recorder.js.map +0 -1
  445. package/dist/activities/execute-deep-agent/index.d.ts +0 -15
  446. package/dist/activities/execute-deep-agent/index.js +0 -918
  447. package/dist/activities/execute-deep-agent/index.js.map +0 -1
  448. package/dist/activities/execute-deep-agent/mcp-gate.d.ts +0 -28
  449. package/dist/activities/execute-deep-agent/mcp-gate.js +0 -22
  450. package/dist/activities/execute-deep-agent/mcp-gate.js.map +0 -1
  451. package/dist/activities/execute-deep-agent/post-stream.d.ts +0 -23
  452. package/dist/activities/execute-deep-agent/post-stream.js +0 -71
  453. package/dist/activities/execute-deep-agent/post-stream.js.map +0 -1
  454. package/dist/activities/execute-deep-agent/setup.d.ts +0 -136
  455. package/dist/activities/execute-deep-agent/setup.js +0 -767
  456. package/dist/activities/execute-deep-agent/setup.js.map +0 -1
  457. package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +0 -36
  458. package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +0 -56
  459. package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +0 -1
  460. package/dist/activities/execute-deep-agent/status-builder.d.ts +0 -93
  461. package/dist/activities/execute-deep-agent/status-builder.js +0 -365
  462. package/dist/activities/execute-deep-agent/status-builder.js.map +0 -1
  463. package/dist/activities/execute-deep-agent/streaming-terminal.d.ts +0 -21
  464. package/dist/activities/execute-deep-agent/streaming-terminal.js +0 -80
  465. package/dist/activities/execute-deep-agent/streaming-terminal.js.map +0 -1
  466. package/dist/activities/execute-deep-agent/streaming-v3.d.ts +0 -13
  467. package/dist/activities/execute-deep-agent/streaming-v3.js +0 -174
  468. package/dist/activities/execute-deep-agent/streaming-v3.js.map +0 -1
  469. package/dist/activities/execute-deep-agent/streaming.d.ts +0 -81
  470. package/dist/activities/execute-deep-agent/streaming.js +0 -160
  471. package/dist/activities/execute-deep-agent/streaming.js.map +0 -1
  472. package/dist/middleware/cost-cap.d.ts +0 -22
  473. package/dist/middleware/cost-cap.js.map +0 -1
  474. package/dist/middleware/graceful-stop.d.ts +0 -17
  475. package/dist/middleware/graceful-stop.js +0 -63
  476. package/dist/middleware/graceful-stop.js.map +0 -1
  477. package/dist/shared/skill-writer.d.ts +0 -75
  478. package/dist/shared/skill-writer.js +0 -207
  479. package/dist/shared/skill-writer.js.map +0 -1
  480. package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +0 -1032
  481. package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +0 -240
  482. package/src/activities/execute-cursor/__tests__/progress-substrate.test.ts +0 -169
  483. package/src/activities/execute-cursor/capture-flow.ts +0 -379
  484. package/src/activities/execute-cursor/command-provenance.ts +0 -73
  485. package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +0 -1161
  486. package/src/activities/execute-deep-agent/__tests__/command-provenance.test.ts +0 -252
  487. package/src/activities/execute-deep-agent/__tests__/environment.test.ts +0 -108
  488. package/src/activities/execute-deep-agent/__tests__/event-recorder.test.ts +0 -150
  489. package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +0 -226
  490. package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +0 -318
  491. package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +0 -351
  492. package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +0 -293
  493. package/src/activities/execute-deep-agent/__tests__/index.test.ts +0 -99
  494. package/src/activities/execute-deep-agent/__tests__/mcp-gate.test.ts +0 -44
  495. package/src/activities/execute-deep-agent/__tests__/post-stream.test.ts +0 -112
  496. package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +0 -358
  497. package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +0 -1933
  498. package/src/activities/execute-deep-agent/__tests__/streaming-terminal.test.ts +0 -40
  499. package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +0 -597
  500. package/src/activities/execute-deep-agent/__tests__/streaming.test.ts +0 -508
  501. package/src/activities/execute-deep-agent/attachment-injector.ts +0 -627
  502. package/src/activities/execute-deep-agent/command-provenance.ts +0 -102
  503. package/src/activities/execute-deep-agent/environment.ts +0 -76
  504. package/src/activities/execute-deep-agent/event-recorder.ts +0 -95
  505. package/src/activities/execute-deep-agent/index.ts +0 -1072
  506. package/src/activities/execute-deep-agent/mcp-gate.ts +0 -37
  507. package/src/activities/execute-deep-agent/post-stream.ts +0 -109
  508. package/src/activities/execute-deep-agent/setup.ts +0 -1081
  509. package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +0 -64
  510. package/src/activities/execute-deep-agent/status-builder.ts +0 -481
  511. package/src/activities/execute-deep-agent/streaming-terminal.ts +0 -106
  512. package/src/activities/execute-deep-agent/streaming-v3.ts +0 -277
  513. package/src/activities/execute-deep-agent/streaming.ts +0 -313
  514. package/src/middleware/__tests__/cost-cap.test.ts +0 -192
  515. package/src/middleware/__tests__/graceful-stop.test.ts +0 -105
  516. package/src/middleware/graceful-stop.ts +0 -86
  517. package/src/shared/__tests__/skill-writer.test.ts +0 -372
  518. package/src/shared/skill-writer.ts +0 -266
@@ -0,0 +1,541 @@
1
+ /**
2
+ * The native deep-agent harness's setup — what the LangGraph engine needs
3
+ * before it can run a turn, as small named steps over the runtime's resolved
4
+ * `TurnInput`, each returning a typed slice (the Cursor adapter's
5
+ * `turn-setup.ts` mold; never one long function).
6
+ *
7
+ * Everything harness-agnostic has already happened when these run: the
8
+ * execution, session and blueprint are fetched, the workspace is provisioned
9
+ * and locked, the MCP servers and approval policies are merged, the skills
10
+ * are mounted per owner, the attachments are resolved, the transcript is
11
+ * seeded. What remains is this engine's own reading of that record: the
12
+ * checkpointer; the deepagents backend and the CAS observer, rooted at the
13
+ * tree the runtime locked; the MCP connection that turns resolved servers
14
+ * into LangChain tools; the model; the middleware stack with the approval
15
+ * gate over the runtime's policies; the compiled sub-agents; the system
16
+ * prompt and the user message; `createDeepAgent`; and the checkpoint read
17
+ * that decides between a `Command(resume)` and a fresh message. The
18
+ * file-review capture is the runtime's (`harness/capture.ts`); this harness
19
+ * hands it only what its CAS observer saw (`turn.ts`).
20
+ *
21
+ * Every step reads `TurnInput` and the sink and nothing else of the
22
+ * runtime's. The `execution_setup` cold-start line is emitted here, once the
23
+ * graph exists, over the runtime's timeline (`sink.setupTiming`), so the one
24
+ * timeline reads end to end. The three progress labels only this harness
25
+ * knows are reported through the sink exactly as the orchestrator reported
26
+ * them (the resolution labels are the runtime's).
27
+ *
28
+ * One root for everything (Q-S3-8): the deepagents backend, the CAS
29
+ * observer, the gate's path normalization and the publisher are all rooted
30
+ * at `workspace.primaryDir` — the same tree the runtime locks, links and
31
+ * captures. For zero or one workspace entry this is byte-identical to the
32
+ * orchestrator's `workspaceBackend.rootDir`.
33
+ *
34
+ * Moved from `setup.ts` `performSetup` (the LangGraph half; the resolution
35
+ * half is the runtime's twelve phases) at S3 M2a; the step bodies are the
36
+ * orchestrator's, verbatim where nothing changed.
37
+ */
38
+
39
+ import type { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
40
+ import type { DynamicStructuredTool } from "@langchain/core/tools";
41
+ import type { Command } from "@langchain/langgraph";
42
+ import { createDeepAgent } from "deepagents";
43
+ import { InteractionMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
44
+
45
+ import type { Config } from "../../config.js";
46
+ import type { TurnInput, TurnSink } from "../../harness/types.js";
47
+ import { emitTimingLog } from "../../shared/cold-start-timing.js";
48
+ import { createCheckpointer } from "../../shared/checkpointer/factory.js";
49
+ import { ensureCheckpointDbPath } from "../../shared/workspace/platform-dir.js";
50
+ import { LocalWorkspaceBackend } from "../../shared/workspace/local-backend.js";
51
+ import type { WorkspaceBackend } from "../../shared/workspace/types.js";
52
+ import { connectMcpServers, type McpConnectionResult } from "../../shared/mcp-manager.js";
53
+ import { formatChannelTemplatesSection } from "../../shared/channel-attachment.js";
54
+ import { isPathCapturable } from "../../shared/filereview/git-substrate.js";
55
+ import { resolveWorkspacePath } from "../../shared/file-change.js";
56
+ import { buildPlanModePermissions } from "../../shared/plan-mode-permissions.js";
57
+ import { buildMiddlewareStack } from "../../middleware/index.js";
58
+ import type { ApprovalGateConfig } from "../../middleware/approval-gate.js";
59
+ import { createThinkTool, createWebFetchTool, resolveGuardPosture } from "../../tools/index.js";
60
+ import { deriveExecutionFingerprintKey } from "../../shared/approval-fingerprint.js";
61
+ import { getRunnerHitlMasterSecret } from "../../shared/fingerprint-secret.js";
62
+ import { getModelPricing, ensureLoaded as ensurePricingLoaded, type ModelPricing } from "../../shared/model-pricing.js";
63
+ import { getDefaultModel } from "../../shared/model-registry.js";
64
+ import { buildChatModel } from "../../shared/model-client.js";
65
+ import { isUnattendedApprovalMode, type MergedToolPolicy } from "../../shared/approval-policy.js";
66
+ import type { ToolApprovalCategory } from "../../shared/tool-kind.js";
67
+ import { alsoAvailableSkillsNote, selectSkillsForPrompt, visionPromptInfoOf } from "../../shared/prompt-sections.js";
68
+ import type { RecalledMemoriesContent } from "../../shared/recalled-memories.js";
69
+ import { toLangChainImageBlocks } from "../../shared/attachment-vision.js";
70
+ import { resolveRecursionLimit, UNBOUNDED_ADVISORY_RECURSION_LIMIT } from "../../shared/tool-rounds.js";
71
+ import { jsonSchemaToZod } from "../../shared/json-schema-to-zod.js";
72
+ import { CasCaptureObserver } from "./cas-capture-observer.js";
73
+ import { createCasCaptureBackend } from "./cas-capture-backend.js";
74
+ import { resolveResumeInput, type GraphStateSnapshot } from "./hitl.js";
75
+ import { buildEnhancedSystemPrompt, composeUserMessage, renderSkillsSection } from "./prompt-builder.js";
76
+ import { buildShellEnv } from "./shell-env.js";
77
+ import { modelHasNativeThinking, transformAndCompileSubagents } from "./subagent-transformer.js";
78
+
79
+ /**
80
+ * The runner config this harness reads per turn, as a named slice
81
+ * (`execute-cursor/turn-setup.ts` `CursorAdapterConfig` is the idiom): a
82
+ * whole `Config` satisfies it, a test constructs these fields and nothing
83
+ * else. Smaller than the orchestrator's reach — the synthesized attachments'
84
+ * endpoints it read are the runtime's now (S3 M2a, F-M2a-10).
85
+ */
86
+ export type DeepAgentAdapterConfig = Pick<
87
+ Config,
88
+ "checkpointerType" | "checkpointerProxyEndpoint" | "stigmerToken" | "proxyEndpoint" | "mode"
89
+ >;
90
+
91
+ /** The deepagents graph as this module holds it; deepagents exports no stable type for the compiled agent. */
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ export type AgentGraph = any;
94
+
95
+ /** The workspace as this engine sees it: one backend and one CAS observer, both rooted at the runtime's primary tree. */
96
+ export interface DeepAgentWorkspace {
97
+ readonly backend: WorkspaceBackend;
98
+ readonly casObserver: CasCaptureObserver;
99
+ /** Git-tracked capturability, consulted by the gate to route a file write to git-diff (tracked) vs CAS (ignored). */
100
+ readonly isCapturablePath: (rawPath: string) => Promise<boolean>;
101
+ }
102
+
103
+ /** The tool surface once connected: LangChain tools plus the tool → server map the builders attribute by. */
104
+ export interface DeepAgentTools {
105
+ /** Absent when the turn has no servers to connect: `MultiServerMCPClient` refuses an empty config. */
106
+ readonly connection: McpConnectionResult | undefined;
107
+ readonly mcpTools: readonly DynamicStructuredTool[];
108
+ readonly serverToolMap: ReadonlyMap<string, readonly DynamicStructuredTool[]>;
109
+ readonly toolServerMap: ReadonlyMap<string, string>;
110
+ }
111
+
112
+ /** The gate's posture for this turn, read once and shared by the builders, the reconciler and the sub-agents. */
113
+ export interface DeepAgentGateState {
114
+ readonly policies: ReadonlyMap<string, MergedToolPolicy>;
115
+ readonly toolServerMap: ReadonlyMap<string, string>;
116
+ readonly leasedCategories: ReadonlySet<ToolApprovalCategory>;
117
+ /** Pre-armed spec.auto_approve_all — the one unscoped, whole-run bypass; the gate is not installed under it. */
118
+ readonly globalBypass: boolean;
119
+ /** Unattended approval mode (DD-014): the gate auto-skips instead of interrupting. */
120
+ readonly unattended: boolean;
121
+ /** Tool-call ids the gate auto-skipped this turn; written by the gate, read by `reconcileUnattendedSkips`. */
122
+ readonly unattendedSkips: Set<string>;
123
+ }
124
+
125
+ /** The engine this turn runs on and everything the stream and the settle read from it. */
126
+ export interface DeepAgentEngine {
127
+ readonly graph: AgentGraph;
128
+ readonly checkpointer: BaseCheckpointSaver;
129
+ readonly langgraphConfig: Record<string, unknown>;
130
+ /** The registry id the turn runs on (pricing, the thinking heuristic, sub-agent inheritance key on it). */
131
+ readonly modelName: string;
132
+ readonly pricing: ModelPricing;
133
+ readonly gate: DeepAgentGateState;
134
+ readonly hasStructuredOutput: boolean;
135
+ }
136
+
137
+ /** What the graph is invoked with: a resume of the paused gate, or the turn's user message. */
138
+ export type DeepAgentGraphInput =
139
+ | { readonly kind: "resume"; readonly command: Command }
140
+ | { readonly kind: "message"; readonly input: Record<string, unknown> };
141
+
142
+ // ── Steps ───────────────────────────────────────────────────────────────────
143
+
144
+ /**
145
+ * The registry id the turn runs on: what the execution asked for, as the
146
+ * runtime already resolved it (`input.model.requested`, `"default"` when the
147
+ * spec named none — the one reader of `spec.executionConfig.modelName`, which
148
+ * the Cursor adapter reads too), or the registry's default for `"default"`.
149
+ * The same reading the runtime's attachment phase made for the vision budget,
150
+ * so the model that sees the images is the model that runs. (Until S3 M5 this
151
+ * read the spec field beside the runtime's resolved copy; F-M3-P7.)
152
+ */
153
+ export async function resolveModelName(input: TurnInput): Promise<string> {
154
+ return input.model.requested === "default" ? await getDefaultModel() : input.model.requested;
155
+ }
156
+
157
+ /**
158
+ * The checkpoint saver. The durable local (sqlite) backend keys its file
159
+ * per session — a session has exactly one thread (`thread-{sessionId}`), so
160
+ * checkpoint lifetime tracks session lifetime. Opened per turn and closed
161
+ * in the adapter's `finally` (`turn.ts`).
162
+ */
163
+ export async function openCheckpointer(input: TurnInput, sink: TurnSink, config: DeepAgentAdapterConfig): Promise<BaseCheckpointSaver> {
164
+ const checkpointer = await createCheckpointer({
165
+ type: config.checkpointerType,
166
+ proxyEndpoint: config.checkpointerProxyEndpoint ?? undefined,
167
+ authToken: config.stigmerToken ?? undefined,
168
+ sqlitePath: config.checkpointerType === "sqlite" ? await ensureCheckpointDbPath(input.sessionId) : undefined,
169
+ });
170
+ sink.setupTiming.mark("create_checkpointer");
171
+ return checkpointer;
172
+ }
173
+
174
+ /**
175
+ * The workspace as the engine sees it, rooted at the runtime's primary tree
176
+ * (Q-S3-8). The platform dir the shared provision ensured rides along so
177
+ * the backend routes `.stigmer/…` reads to it.
178
+ *
179
+ * CAS capture (design docs 08/11/12): the single per-turn observer owns the
180
+ * before-bytes of first-touched CAS-owned paths AND the secret-blocked
181
+ * paths, keyed workspace-root-relative. Shared by the parent AND every
182
+ * sub-agent CAS backend, giving race-free first-touch-wins across
183
+ * concurrent graphs. In a git work tree it owns the .gitignored set only
184
+ * (git captures the tracked ones); in a non-git workspace it owns every
185
+ * touched path. Its ownership predicate is memoized, so `git check-ignore`
186
+ * runs at most once per distinct path.
187
+ */
188
+ export function buildDeepAgentWorkspace(input: TurnInput): DeepAgentWorkspace {
189
+ const { primaryDir, gitWorkspace, provision } = input.workspace;
190
+ const backend = new LocalWorkspaceBackend(primaryDir, provision.workspaceBackend.platformDir);
191
+ const isCapturablePath = gitWorkspace
192
+ ? (rawPath: string): Promise<boolean> =>
193
+ isPathCapturable(primaryDir, resolveWorkspacePath(rawPath, primaryDir, true).path)
194
+ : (_rawPath: string): Promise<boolean> => Promise.resolve(false);
195
+ const casObserver = new CasCaptureObserver({
196
+ rootDir: primaryDir,
197
+ isIgnored: gitWorkspace
198
+ ? async (relPath) => !(await isPathCapturable(primaryDir, relPath))
199
+ : async () => true,
200
+ });
201
+ return { backend, casObserver, isCapturablePath };
202
+ }
203
+
204
+ /**
205
+ * Connect the runtime's resolved servers (synthesized attachments included)
206
+ * into LangChain tools. The connect covers the whole fan-out — stdio servers
207
+ * spawn npx/uvx subprocesses here, so on-demand package installs land in
208
+ * this span. A turn with no servers connects nothing: `MultiServerMCPClient`
209
+ * refuses an empty config, which is what the orchestrator's MCP gate
210
+ * (`mcp-gate.ts`) guarded against beside its channel-only reason; the
211
+ * runtime resolves unconditionally, so the one remaining question is
212
+ * "anything to connect?" (S3 M2a, F-M2a-17).
213
+ */
214
+ export async function connectTools(input: TurnInput, sink: TurnSink): Promise<DeepAgentTools> {
215
+ if (input.mcp.servers.length === 0) {
216
+ return { connection: undefined, mcpTools: [], serverToolMap: new Map(), toolServerMap: new Map() };
217
+ }
218
+ await sink.reportProgress("Connecting tools…");
219
+ const connection = await connectMcpServers([...input.mcp.servers]);
220
+ const serverToolMap = new Map<string, readonly DynamicStructuredTool[]>();
221
+ const toolServerMap = new Map<string, string>();
222
+ for (const [serverName, serverTools] of Object.entries(connection.serverToolMap)) {
223
+ serverToolMap.set(serverName, serverTools as DynamicStructuredTool[]);
224
+ for (const t of serverTools) toolServerMap.set(t.name, serverName);
225
+ }
226
+ sink.setupTiming.mark("connect_mcp");
227
+ sink.recordActivity();
228
+ return { connection, mcpTools: connection.tools as DynamicStructuredTool[], serverToolMap, toolServerMap };
229
+ }
230
+
231
+ /**
232
+ * The gate's posture. Two distinct bypasses (`shared/approval-policy.ts`
233
+ * `ActiveLeases`): the pre-armed spec.auto_approve_all is the one whole-run
234
+ * global bypass; an interactive APPROVE_ALL grants a run-lifetime lease
235
+ * scoped to that action's class. Server leases shaped the runtime's policy
236
+ * map (leased servers dropped); built-in category leases are applied inside
237
+ * the gate. Both flow into sub-agents via the shared gate config.
238
+ */
239
+ export function readGateState(input: TurnInput, tools: DeepAgentTools): DeepAgentGateState {
240
+ return {
241
+ policies: input.mcp.policies,
242
+ toolServerMap: tools.toolServerMap,
243
+ leasedCategories: input.mcp.leases.categories,
244
+ globalBypass: input.mcp.leases.global,
245
+ unattended: isUnattendedApprovalMode(input.execution),
246
+ unattendedSkips: new Set<string>(),
247
+ };
248
+ }
249
+
250
+ /**
251
+ * The `## Skills` section of the root prompt: the skills the shared selection
252
+ * highlights for this turn's message (`shared/prompt-sections.ts`
253
+ * `selectSkillsForPrompt`: every skill below the threshold, the relevant ones
254
+ * at and above it), rendered with this engine's activation protocol, plus —
255
+ * when the selection left any out — an `### Also Available` note naming them
256
+ * (the sentence is the shared, tool-neutral one; the heading is this
257
+ * harness's markdown framing).
258
+ */
259
+ export function renderRootSkillsSection(input: TurnInput): string {
260
+ const { highlighted, alsoAvailable } = selectSkillsForPrompt(input.execution.spec?.message ?? "", input.skills.root);
261
+ if (alsoAvailable.length === 0) return renderSkillsSection(highlighted);
262
+ console.log(
263
+ `[turn-setup] Skill relevance filter: ${highlighted.length} included, ` +
264
+ `${alsoAvailable.length} excluded: ${alsoAvailable.join(", ")}`,
265
+ );
266
+ return renderSkillsSection(highlighted) + "\n### Also Available\n\n" + alsoAvailableSkillsNote(alsoAvailable) + "\n";
267
+ }
268
+
269
+ /**
270
+ * The system prompt over the runtime's resolved record: every input the
271
+ * builder renders is read from `TurnInput` here, in one place, so the mapping
272
+ * is a pure step a test can pin whole (`__tests__/prompt-goldens.test.ts`
273
+ * calls exactly this) rather than a stretch of `buildEngine`. The one input
274
+ * that is not on the record is the memoized memory selection, which the
275
+ * caller awaits (the runtime stamps the report on the status the first time
276
+ * it is pulled, before this turn's first persist).
277
+ */
278
+ export function composeSystemPrompt(input: TurnInput, recalledMemories: RecalledMemoriesContent | undefined): string {
279
+ const spec = input.execution.spec!;
280
+ const execConfig = spec.executionConfig;
281
+ const primaryDir = input.workspace.primaryDir;
282
+ return buildEnhancedSystemPrompt({
283
+ instructions: input.blueprint.instructions,
284
+ provisionResults: input.workspace.provision.provisionResults,
285
+ containerRoot: primaryDir,
286
+ skillsPromptSection: renderRootSkillsSection(input),
287
+ // "" (nothing sendable) threads as undefined: the tool alone still serves
288
+ // text sends inside a 24-hour window (DD-006 D6).
289
+ channelTemplatesPromptSection: input.mcp.channelMessaging.length > 0
290
+ ? formatChannelTemplatesSection(input.mcp.channelMessaging) || undefined
291
+ : undefined,
292
+ workspaceFileRefs: spec.workspaceFileRefs ?? [],
293
+ workspaceRoot: primaryDir,
294
+ inputFiles: input.attachments.results,
295
+ vision: visionPromptInfoOf(input.attachments),
296
+ downloadUrlKind: input.artifactStorage?.downloadUrlKind,
297
+ interactionMode: execConfig?.interactionMode,
298
+ buildFromPlan: execConfig?.buildFromPlan,
299
+ contextBridge: input.standing.contextBridge,
300
+ senderIdentity: input.standing.senderIdentity,
301
+ sessionContext: input.standing.sessionContext,
302
+ declaredPreferences: input.standing.declaredPreferences,
303
+ recalledMemories,
304
+ });
305
+ }
306
+
307
+ /**
308
+ * Build the engine: the model, the middleware stack with the gate, the
309
+ * tools, the compiled sub-agents, the system prompt and `createDeepAgent`.
310
+ *
311
+ * The service tier resolved ONCE by the runtime rides every model this
312
+ * execution constructs — the primary AND the sub-agent factory — so the
313
+ * provider account's default can never pick the price of any turn (#361).
314
+ * `max_tool_rounds` resolves to one recursion limit that feeds BOTH the hard
315
+ * stop on the invoke config and the budget middleware's ~80% advisory, so
316
+ * the warning and the enforcement can never disagree.
317
+ *
318
+ * Nothing in the middleware stack stops the run (Q-S3-3, landed at S3 M2b):
319
+ * the runtime's abort is the platform's one stop, and its TERMINATED arm the
320
+ * one enforcement of `max_cost_usd`; the cost advisory warns the model at
321
+ * ~80% of the cap the way the budget middleware warns at ~80% of the
322
+ * recursion limit.
323
+ */
324
+ export async function buildEngine(
325
+ input: TurnInput,
326
+ sink: TurnSink,
327
+ config: DeepAgentAdapterConfig,
328
+ args: {
329
+ readonly modelName: string;
330
+ readonly checkpointer: BaseCheckpointSaver;
331
+ readonly workspace: DeepAgentWorkspace;
332
+ readonly tools: DeepAgentTools;
333
+ readonly gate: DeepAgentGateState;
334
+ },
335
+ ): Promise<DeepAgentEngine> {
336
+ const { modelName, checkpointer, workspace, tools, gate } = args;
337
+ const { executionId, sessionId, blueprint, artifactStorage } = input;
338
+ const execConfig = input.execution.spec!.executionConfig;
339
+ const primaryDir = input.workspace.primaryDir;
340
+
341
+ // The model. Resolution to the provider API id happens inside
342
+ // buildChatModel; modelName stays the registry id for pricing, the
343
+ // native-thinking heuristic, and sub-agent inheritance.
344
+ const buildModelFor = async (name: string) =>
345
+ (await buildChatModel({
346
+ modelName: name,
347
+ proxyEndpoint: config.proxyEndpoint ?? undefined,
348
+ stigmerToken: config.stigmerToken ?? undefined,
349
+ headerScope: { executionId },
350
+ serviceTier: input.model.serviceTier,
351
+ })).model;
352
+ const model = await buildModelFor(modelName);
353
+ sink.setupTiming.mark("build_model");
354
+
355
+ await ensurePricingLoaded();
356
+ const pricing = getModelPricing(modelName);
357
+ const isPlanMode = execConfig?.interactionMode === InteractionMode.PLAN;
358
+ const shellEnv = isPlanMode ? undefined : buildShellEnv(input.environment.envVars);
359
+ // Plan mode's filesystem permission rules, hoisted once: the parent graph
360
+ // and every sub-agent graph carry this single value (the write-deny half
361
+ // of plan mode; the read boundary is structural, issue #754).
362
+ const planModePermissions = isPlanMode ? buildPlanModePermissions() : undefined;
363
+
364
+ // The approval gate config is the single source of truth for HITL gating,
365
+ // built once and inherited verbatim by sub-agents. Null under the global
366
+ // pre-arm, where the gate is inert. Capture mode: file edits flow (tracked
367
+ // to the git diff, ignored into CAS on THIS gate); secret-like paths are
368
+ // hard-blocked (DD-E); shell/MCP stay gated. The CAS arm additionally
369
+ // requires storage to persist its blobs.
370
+ const captureMode = input.workspace.captureMode;
371
+ const approvalGateConfig: ApprovalGateConfig | null = !gate.globalBypass
372
+ ? {
373
+ policies: gate.policies,
374
+ leasedCategories: gate.leasedCategories,
375
+ toolServerMap: gate.toolServerMap,
376
+ fingerprintKey: deriveExecutionFingerprintKey(getRunnerHitlMasterSecret(), executionId),
377
+ executionId,
378
+ fileCaptureMode: captureMode,
379
+ isCapturablePath: workspace.isCapturablePath,
380
+ captureIgnored: captureMode && !!artifactStorage,
381
+ recordBlockedSecret: (rawPath: string) => workspace.casObserver.recordBlockedSecret(rawPath),
382
+ // Pre-delete byte capture (issue #303): a flowing delete's before-bytes
383
+ // are recorded by the gate at authorization time through the SAME
384
+ // shared observer, so the boundary authors a restorable DELETE.
385
+ captureDeleteBefore: (rawPath: string) => workspace.casObserver.recordBefore(rawPath),
386
+ unattended: gate.unattended,
387
+ unattendedSkips: gate.unattendedSkips,
388
+ }
389
+ : null;
390
+
391
+ const maxCostUsd = execConfig?.maxCostUsd ?? 0;
392
+ const recursionLimit = resolveRecursionLimit(execConfig?.maxToolRounds);
393
+ const { middleware, costAdvisory } = buildMiddlewareStack({
394
+ loopDetection: { historySize: 20, consecutiveThreshold: 7, totalThreshold: 20 },
395
+ executionBudget: { recursionLimit: recursionLimit ?? UNBOUNDED_ADVISORY_RECURSION_LIMIT, warningPct: 80 },
396
+ toolTruncation: { maxChars: execConfig?.maxToolResultChars || 30_000 },
397
+ costAdvisory: maxCostUsd > 0
398
+ ? {
399
+ maxCostUsd,
400
+ inputPricePerMillion: pricing.inputPricePerMillion,
401
+ outputPricePerMillion: pricing.outputPricePerMillion,
402
+ cacheReadPricePerMillion: pricing.cacheReadPricePerMillion,
403
+ warningPct: 80,
404
+ }
405
+ : null,
406
+ otelSpans: { toolServerMap: gate.toolServerMap },
407
+ approvalGate: approvalGateConfig,
408
+ // Every graph, every mode (issue #754): the dialect-repair seam that keeps
409
+ // model-supplied paths canonical for the virtual-rooted backend and every
410
+ // downstream consumer (gate, capture, spans).
411
+ pathNormalization: { rootDir: primaryDir },
412
+ });
413
+ sink.setupTiming.mark("build_middleware");
414
+
415
+ // web_fetch is always-on for every native run (issue #214 parity with the
416
+ // Cursor harness); its URL guard posture — strict on managed cloud runners,
417
+ // relaxed on user-owned machines — is derived from the runner mode.
418
+ const webFetchPosture = resolveGuardPosture(config.mode);
419
+ const graphTools = [...tools.mcpTools, createThinkTool(), createWebFetchTool({ posture: webFetchPosture })];
420
+
421
+ await sink.reportProgress("Configuring sub-agents…");
422
+ const compiledSubagents = await transformAndCompileSubagents({
423
+ subAgents: blueprint.subAgents,
424
+ parentMcpTools: tools.mcpTools,
425
+ parentMcpServerToolMap: tools.serverToolMap,
426
+ parentMcpUsages: blueprint.mergedMcpServerUsages,
427
+ skills: input.skills.bySubAgent,
428
+ workspaceBackend: workspace.backend,
429
+ approvalGate: approvalGateConfig,
430
+ // Capture is universal: every sub-agent gets a CAS-observing backend wired
431
+ // to the SAME per-turn observer as the parent (Session 26, DD-19).
432
+ casObserver: workspace.casObserver,
433
+ parentModelName: modelName,
434
+ parentHasNativeThinking: modelHasNativeThinking(modelName),
435
+ webFetchPosture,
436
+ costAdvisory: costAdvisory ?? undefined,
437
+ modelFactory: buildModelFor,
438
+ shellEnv,
439
+ ...(planModePermissions ? { permissions: planModePermissions } : {}),
440
+ });
441
+ sink.setupTiming.mark("compile_subagents");
442
+ sink.recordActivity();
443
+
444
+ await sink.reportProgress("Creating agent…");
445
+ // The runtime's memoized memory selection; it stamps the report on the
446
+ // status the first time it is pulled, before this turn's first persist.
447
+ const systemPrompt = composeSystemPrompt(input, await input.standing.selectRecalledMemories());
448
+
449
+ const outputSchema = input.structuredOutputSchema;
450
+ const responseFormat = outputSchema ? jsonSchemaToZod(outputSchema) : undefined;
451
+
452
+ // File capture point: the CAS-observing backend — git-tracked edits flow to
453
+ // disk (the boundary's git diff is authoritative) and the shared observer
454
+ // records the pre-turn bytes of every CAS-owned path. Gate-independent, so
455
+ // it holds even under the global bypass.
456
+ const fileBackend = await createCasCaptureBackend({ rootDir: primaryDir, observer: workspace.casObserver, shellEnv });
457
+ const graph = await createDeepAgent({
458
+ model,
459
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
460
+ checkpointer: checkpointer as any,
461
+ backend: fileBackend,
462
+ systemPrompt,
463
+ tools: graphTools,
464
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
465
+ middleware: middleware as any,
466
+ subagents: compiledSubagents ?? undefined,
467
+ ...(responseFormat ? { responseFormat } : {}),
468
+ ...(planModePermissions ? { permissions: planModePermissions } : {}),
469
+ } as Parameters<typeof createDeepAgent>[0]);
470
+
471
+ const langgraphConfig: Record<string, unknown> = {
472
+ configurable: { thread_id: input.threadId },
473
+ // Hard enforcement of max_tool_rounds (null = unlimited): when the graph
474
+ // exhausts this, the stream throws GraphRecursionError and the adapter
475
+ // ends the turn `tool_call_limit` with the work checkpointed.
476
+ ...(recursionLimit !== null ? { recursionLimit } : {}),
477
+ };
478
+
479
+ console.log(
480
+ `[turn-setup] Complete: model=${modelName}, tools=${graphTools.length}, ` +
481
+ `middleware=${middleware.length}, thread_id=${input.threadId}`,
482
+ );
483
+ sink.setupTiming.mark("create_agent_graph");
484
+ emitTimingLog("execution_setup", {
485
+ execution_id: executionId,
486
+ session_id: sessionId,
487
+ harness: "native",
488
+ mcp_server_count: blueprint.mergedMcpServerUsages.length,
489
+ skill_count: blueprint.mergedSkillRefs.length,
490
+ workspace_entry_count: input.session.spec?.workspaceEntries?.length ?? 0,
491
+ }, sink.setupTiming);
492
+ sink.recordActivity();
493
+
494
+ return {
495
+ graph,
496
+ checkpointer,
497
+ langgraphConfig,
498
+ modelName,
499
+ pricing,
500
+ gate,
501
+ hasStructuredOutput: !!outputSchema,
502
+ };
503
+ }
504
+
505
+ /**
506
+ * What the graph is invoked with. The checkpoint is read once (on the
507
+ * durable http saver an extra `getState` is a network round-trip): pending
508
+ * interrupts that the runtime's decisions answer make a `Command(resume)`;
509
+ * anything else is the turn's user message — the conversation catchup
510
+ * framed before it (cloud DD-006; in the USER MESSAGE so it enters the
511
+ * checkpointer with the turn), the structured-output contract appended, and
512
+ * the inline images FIRST as content blocks when the turn carries any (per
513
+ * Anthropic's images-before-text guidance; a plain string otherwise).
514
+ */
515
+ export async function composeGraphInput(input: TurnInput, engine: DeepAgentEngine): Promise<DeepAgentGraphInput> {
516
+ const graphState: GraphStateSnapshot = await engine.graph.getState(engine.langgraphConfig);
517
+ const resume = resolveResumeInput(input.approvalDecisions, graphState);
518
+ if (resume.isResumeFromApproval) {
519
+ return { kind: "resume", command: resume.graphInput };
520
+ }
521
+
522
+ const spec = input.execution.spec!;
523
+ let userMessage = composeUserMessage(spec.message, input.standing.conversationCatchup);
524
+ if (engine.hasStructuredOutput) {
525
+ 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.`;
526
+ }
527
+ const { visionImages } = input.attachments;
528
+ return {
529
+ kind: "message",
530
+ input: {
531
+ messages: [
532
+ {
533
+ role: "user",
534
+ content: visionImages.length > 0
535
+ ? [...toLangChainImageBlocks(visionImages), { type: "text", text: userMessage }]
536
+ : userMessage,
537
+ },
538
+ ],
539
+ },
540
+ };
541
+ }