@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.
- package/README.md +2 -4
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/execution-record-fixture.d.ts +14 -0
- package/dist/__test-utils__/execution-record-fixture.js +4 -0
- package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
- package/dist/__test-utils__/file-review-projection.d.ts +40 -0
- package/dist/__test-utils__/file-review-projection.js +136 -0
- package/dist/__test-utils__/file-review-projection.js.map +1 -0
- package/dist/__test-utils__/harness-contract/types.d.ts +23 -1
- package/dist/__test-utils__/harness-contract/types.js +15 -0
- package/dist/__test-utils__/harness-contract/types.js.map +1 -1
- package/dist/__test-utils__/hermetic-activity.d.ts +44 -12
- package/dist/__test-utils__/hermetic-activity.js +52 -14
- package/dist/__test-utils__/hermetic-activity.js.map +1 -1
- package/dist/__test-utils__/model-registry-fixture.d.ts +32 -7
- package/dist/__test-utils__/model-registry-fixture.js +31 -7
- package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
- package/dist/__test-utils__/turn-input-fixture.d.ts +1 -1
- package/dist/__test-utils__/turn-input-fixture.js +1 -1
- package/dist/__test-utils__/turn-input-fixture.js.map +1 -1
- package/dist/activities/call-agent.js +2 -2
- package/dist/activities/call-agent.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +45 -3
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +0 -9
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +2 -41
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +7 -5
- package/dist/activities/execute-cursor/adapter.js +7 -5
- package/dist/activities/execute-cursor/adapter.js.map +1 -1
- package/dist/activities/execute-cursor/approval-policy.d.ts +5 -2
- package/dist/activities/execute-cursor/approval-policy.js +5 -2
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +16 -8
- package/dist/activities/execute-cursor/approval-state.js +6 -3
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/cas-observations.d.ts +14 -2
- package/dist/activities/execute-cursor/cas-observations.js +19 -2
- package/dist/activities/execute-cursor/cas-observations.js.map +1 -1
- package/dist/activities/execute-cursor/cursor-capabilities.d.ts +8 -4
- package/dist/activities/execute-cursor/cursor-capabilities.js +21 -4
- package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -1
- package/dist/activities/execute-cursor/message-translator.d.ts +12 -20
- package/dist/activities/execute-cursor/message-translator.js +19 -32
- package/dist/activities/execute-cursor/message-translator.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +48 -58
- package/dist/activities/execute-cursor/prompt-builder.js +76 -95
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/turn-boundary.d.ts +27 -55
- package/dist/activities/execute-cursor/turn-boundary.js +30 -90
- package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
- package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
- package/dist/activities/execute-cursor/turn-settle.js +37 -49
- package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-setup.d.ts +16 -24
- package/dist/activities/execute-cursor/turn-setup.js +29 -59
- package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
- package/dist/activities/execute-cursor/turn-stream.d.ts +3 -8
- package/dist/activities/execute-cursor/turn-stream.js +9 -22
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-cursor/turn.js +5 -1
- package/dist/activities/execute-cursor/turn.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +93 -0
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +348 -0
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +170 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +225 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.d.ts +24 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +41 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +54 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +72 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +187 -23
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +238 -27
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
- package/dist/activities/execute-deep-agent/adapter.d.ts +41 -0
- package/dist/activities/execute-deep-agent/adapter.js +78 -0
- package/dist/activities/execute-deep-agent/adapter.js.map +1 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +8 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js +9 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -1
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +31 -0
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +40 -0
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js.map +1 -0
- package/dist/activities/execute-deep-agent/execution-state.d.ts +4 -11
- package/dist/activities/execute-deep-agent/execution-state.js +4 -12
- package/dist/activities/execute-deep-agent/execution-state.js.map +1 -1
- package/dist/activities/execute-deep-agent/hitl.d.ts +49 -47
- package/dist/activities/execute-deep-agent/hitl.js +77 -103
- package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +51 -23
- package/dist/activities/execute-deep-agent/prompt-builder.js +115 -76
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +18 -32
- package/dist/activities/execute-deep-agent/status-builder-shared.js +10 -65
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +10 -8
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +12 -14
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +36 -13
- package/dist/activities/execute-deep-agent/subagent-tracker.js +76 -39
- package/dist/activities/execute-deep-agent/subagent-tracker.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -28
- package/dist/activities/execute-deep-agent/subagent-transformer.js +29 -82
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +3 -2
- package/dist/activities/execute-deep-agent/subagent-wiring.js +2 -2
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-settle.d.ts +42 -0
- package/dist/activities/execute-deep-agent/turn-settle.js +146 -0
- package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +212 -0
- package/dist/activities/execute-deep-agent/turn-setup.js +430 -0
- package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-stream.d.ts +97 -0
- package/dist/activities/execute-deep-agent/turn-stream.js +242 -0
- package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn.d.ts +42 -0
- package/dist/activities/execute-deep-agent/turn.js +116 -0
- package/dist/activities/execute-deep-agent/turn.js.map +1 -0
- package/dist/activities/execute-deep-agent/v3-event-recorder.d.ts +6 -5
- package/dist/activities/execute-deep-agent/v3-event-recorder.js +6 -5
- package/dist/activities/execute-deep-agent/v3-event-recorder.js.map +1 -1
- package/dist/activities/execute-deep-agent/v3-events.d.ts +1 -1
- package/dist/activities/execute-deep-agent/v3-events.js +1 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +60 -17
- package/dist/activities/execute-deep-agent/v3-status-builder.js +72 -57
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
- package/dist/harness/approval-decisions.d.ts +61 -0
- package/dist/harness/approval-decisions.js +102 -0
- package/dist/harness/approval-decisions.js.map +1 -0
- package/dist/harness/capabilities.d.ts +16 -5
- package/dist/harness/capabilities.js +9 -0
- package/dist/harness/capabilities.js.map +1 -1
- package/dist/harness/capture.d.ts +144 -0
- package/dist/harness/capture.js +219 -0
- package/dist/harness/capture.js.map +1 -0
- package/dist/harness/persist-chokepoint.d.ts +19 -4
- package/dist/harness/persist-chokepoint.js +17 -4
- package/dist/harness/persist-chokepoint.js.map +1 -1
- package/dist/harness/run-turn.js +115 -29
- package/dist/harness/run-turn.js.map +1 -1
- package/dist/harness/terminal-table.d.ts +40 -11
- package/dist/harness/terminal-table.js +58 -19
- package/dist/harness/terminal-table.js.map +1 -1
- package/dist/harness/turn-context.d.ts +141 -76
- package/dist/harness/turn-context.js +194 -99
- package/dist/harness/turn-context.js.map +1 -1
- package/dist/harness/types.d.ts +65 -12
- package/dist/harness/types.js +8 -2
- package/dist/harness/types.js.map +1 -1
- package/dist/harness-adapters.d.ts +12 -8
- package/dist/harness-adapters.js +17 -9
- package/dist/harness-adapters.js.map +1 -1
- package/dist/middleware/approval-gate.d.ts +1 -1
- package/dist/middleware/approval-gate.js +1 -1
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/middleware/cost-advisory.d.ts +39 -0
- package/dist/middleware/{cost-cap.js → cost-advisory.js} +37 -55
- package/dist/middleware/cost-advisory.js.map +1 -0
- package/dist/middleware/index.d.ts +23 -12
- package/dist/middleware/index.js +26 -18
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/types.d.ts +3 -2
- package/dist/runner-manager.js +1 -5
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.js +1 -5
- package/dist/runner.js.map +1 -1
- package/dist/shared/attachment-resolver.d.ts +41 -18
- package/dist/shared/attachment-resolver.js +178 -46
- package/dist/shared/attachment-resolver.js.map +1 -1
- package/dist/shared/attachment-zip.d.ts +85 -0
- package/dist/shared/attachment-zip.js +185 -0
- package/dist/shared/attachment-zip.js.map +1 -0
- package/dist/shared/connect-backfill.js +5 -4
- package/dist/shared/connect-backfill.js.map +1 -1
- package/dist/shared/cost-guard.d.ts +3 -3
- package/dist/shared/cost-guard.js +3 -3
- package/dist/shared/execution-status-writer.d.ts +5 -5
- package/dist/shared/execution-status-writer.js +5 -5
- package/dist/shared/extract-structured-output.d.ts +8 -7
- package/dist/shared/extract-structured-output.js +8 -7
- package/dist/shared/extract-structured-output.js.map +1 -1
- package/dist/shared/filereview/cas-progress.d.ts +1 -18
- package/dist/shared/filereview/cas-progress.js +4 -0
- package/dist/shared/filereview/cas-progress.js.map +1 -1
- package/dist/shared/filereview/cas-touched.d.ts +56 -0
- package/dist/shared/filereview/cas-touched.js +63 -0
- package/dist/shared/filereview/cas-touched.js.map +1 -0
- package/dist/shared/filereview/index.d.ts +2 -1
- package/dist/shared/filereview/index.js +2 -1
- package/dist/shared/filereview/index.js.map +1 -1
- package/dist/shared/mcp-resolver.d.ts +4 -5
- package/dist/shared/mcp-resolver.js +4 -5
- package/dist/shared/mcp-resolver.js.map +1 -1
- package/dist/shared/persist-decision.d.ts +3 -4
- package/dist/shared/persist-decision.js +3 -4
- package/dist/shared/persist-decision.js.map +1 -1
- package/dist/shared/plan-mode-permissions.d.ts +2 -2
- package/dist/shared/plan-mode-permissions.js +2 -2
- package/dist/shared/plan-mode-prompt.d.ts +1 -1
- package/dist/shared/plan-mode-prompt.js +1 -1
- package/dist/shared/prompt-sections.d.ts +163 -0
- package/dist/shared/prompt-sections.js +164 -0
- package/dist/shared/prompt-sections.js.map +1 -0
- package/dist/shared/skill-resolver.d.ts +4 -2
- package/dist/shared/skill-resolver.js +4 -2
- package/dist/shared/skill-resolver.js.map +1 -1
- package/dist/shared/tool-rounds.d.ts +32 -0
- package/dist/shared/tool-rounds.js +43 -0
- package/dist/shared/tool-rounds.js.map +1 -1
- package/dist/shared/tool-row.d.ts +34 -0
- package/dist/shared/tool-row.js +52 -0
- package/dist/shared/tool-row.js.map +1 -1
- package/dist/shared/workspace/session-provision.d.ts +3 -3
- package/dist/shared/workspace/session-provision.js +3 -3
- package/dist/shared/workspace/stigmer-link.d.ts +3 -3
- package/dist/shared/workspace/stigmer-link.js +3 -3
- package/dist/shared/workspace/writeback-coordinator.d.ts +15 -22
- package/dist/shared/workspace/writeback-coordinator.js +16 -53
- package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/package.json +4 -4
- package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +1 -0
- package/src/__test-utils__/execution-record-fixture.ts +18 -2
- package/src/__test-utils__/file-review-projection.ts +156 -0
- package/src/__test-utils__/git-workspace-fixture.ts +58 -0
- package/src/__test-utils__/harness-boot-order-child.ts +7 -2
- package/src/__test-utils__/harness-contract/contract.ts +33 -20
- package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
- package/src/__test-utils__/harness-contract/runtime-contract.ts +328 -10
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +38 -6
- package/src/__test-utils__/harness-contract/types.ts +27 -3
- package/src/__test-utils__/hermetic-activity.ts +52 -14
- package/src/__test-utils__/model-registry-fixture.ts +32 -7
- package/src/__test-utils__/module-specifiers.ts +24 -0
- package/src/__test-utils__/turn-input-fixture.ts +2 -2
- package/src/__tests__/harness-boot-order.test.ts +9 -2
- package/src/activities/call-agent.ts +2 -2
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +47 -3
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +2 -48
- package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +6 -1
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +52 -27
- package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +25 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.everything.prompt.md +166 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.plan-mode.prompt.md +186 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.recovery.prompt.md +191 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.reinvocation.prompt.md +13 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.prefixed.prompt.md +32 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.raw.prompt.md +1 -0
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +4 -0
- package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +24 -4
- package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +6 -5
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +9 -0
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +11 -8
- package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +229 -0
- package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +3 -3
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +2 -2
- package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +78 -234
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +1 -26
- package/src/activities/execute-cursor/adapter.ts +7 -5
- package/src/activities/execute-cursor/approval-policy.ts +5 -2
- package/src/activities/execute-cursor/approval-state.ts +16 -8
- package/src/activities/execute-cursor/cas-observations.ts +20 -2
- package/src/activities/execute-cursor/cursor-capabilities.ts +24 -5
- package/src/activities/execute-cursor/message-translator.ts +29 -41
- package/src/activities/execute-cursor/prompt-builder.ts +99 -157
- package/src/activities/execute-cursor/turn-boundary.ts +34 -140
- package/src/activities/execute-cursor/turn-settle.ts +37 -51
- package/src/activities/execute-cursor/turn-setup.ts +30 -70
- package/src/activities/execute-cursor/turn-stream.ts +8 -31
- package/src/activities/execute-cursor/turn.ts +5 -1
- package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +391 -0
- package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +313 -0
- package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +48 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +85 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +383 -36
- package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +76 -0
- package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +47 -0
- package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +80 -0
- package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -2
- package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -3
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +172 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +167 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.minimal.prompt.md +36 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +178 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +158 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +210 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +74 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +104 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +78 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +138 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +68 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +154 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +116 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +69 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +67 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/plain-turn.status.json +47 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +68 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +280 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +77 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +99 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +109 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +76 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.text-fallback.status.json +51 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tier2.status.json +51 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tool-strategy.status.json +56 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +90 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +70 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +71 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +144 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +184 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +203 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +170 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +175 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +206 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +142 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +126 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +139 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +122 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +236 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +161 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +157 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +152 -0
- package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +50 -122
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +8 -6
- package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +35 -35
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +247 -0
- package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +329 -0
- package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +1 -20
- package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +78 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/subagent-tracker.test.ts +57 -31
- package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +19 -79
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +15 -15
- package/src/activities/execute-deep-agent/__tests__/summarization-verification.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +391 -0
- package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +343 -38
- package/src/activities/execute-deep-agent/__tests__/vision-input.test.ts +5 -5
- package/src/activities/execute-deep-agent/adapter.ts +94 -0
- package/src/activities/execute-deep-agent/cas-capture-observer.ts +11 -0
- package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +43 -0
- package/src/activities/execute-deep-agent/execution-state.ts +4 -13
- package/src/activities/execute-deep-agent/hitl.ts +100 -123
- package/src/activities/execute-deep-agent/prompt-builder.ts +141 -115
- package/src/activities/execute-deep-agent/status-builder-shared.ts +21 -84
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +13 -19
- package/src/activities/execute-deep-agent/subagent-tracker.ts +77 -42
- package/src/activities/execute-deep-agent/subagent-transformer.ts +46 -105
- package/src/activities/execute-deep-agent/subagent-wiring.ts +5 -4
- package/src/activities/execute-deep-agent/turn-settle.ts +164 -0
- package/src/activities/execute-deep-agent/turn-setup.ts +541 -0
- package/src/activities/execute-deep-agent/turn-stream.ts +313 -0
- package/src/activities/execute-deep-agent/turn.ts +131 -0
- package/src/activities/execute-deep-agent/v3-event-recorder.ts +6 -5
- package/src/activities/execute-deep-agent/v3-events.ts +1 -1
- package/src/activities/execute-deep-agent/v3-status-builder.ts +84 -63
- package/src/harness/__tests__/approval-decisions.test.ts +116 -0
- package/src/harness/__tests__/capture.test.ts +268 -0
- package/src/harness/__tests__/mount-skills.test.ts +169 -0
- package/src/harness/__tests__/persist-chokepoint.test.ts +38 -2
- package/src/harness/__tests__/run-turn-deterministic.test.ts +94 -0
- package/src/harness/__tests__/run-turn.test.ts +39 -23
- package/src/harness/__tests__/turn-attachments-vision.test.ts +80 -0
- package/src/harness/__tests__/turn-context.test.ts +73 -26
- package/src/harness/approval-decisions.ts +104 -0
- package/src/harness/capabilities.ts +16 -5
- package/src/harness/capture.ts +301 -0
- package/src/harness/persist-chokepoint.ts +24 -4
- package/src/harness/run-turn.ts +120 -29
- package/src/harness/terminal-table.ts +61 -20
- package/src/harness/turn-context.ts +208 -111
- package/src/harness/types.ts +66 -12
- package/src/harness-adapters.ts +17 -9
- package/src/middleware/__tests__/approval-gate.test.ts +1 -1
- package/src/middleware/__tests__/cost-advisory.test.ts +113 -0
- package/src/middleware/approval-gate.ts +2 -2
- package/src/middleware/{cost-cap.ts → cost-advisory.ts} +40 -70
- package/src/middleware/index.ts +29 -29
- package/src/middleware/types.ts +3 -2
- package/src/runner-manager.ts +0 -8
- package/src/runner.ts +0 -8
- package/src/shared/__tests__/attachment-naming.test.ts +6 -19
- package/src/shared/__tests__/attachment-resolver.test.ts +158 -8
- package/src/shared/__tests__/attachment-zip.test.ts +236 -0
- package/src/shared/__tests__/bedrock-adapter.test.ts +1 -1
- package/src/shared/__tests__/blueprint-resolver.test.ts +43 -0
- package/src/shared/__tests__/cost-guard.test.ts +3 -3
- package/src/shared/__tests__/prompt-sections.test.ts +167 -0
- package/src/shared/__tests__/secret-leak-scan.test.ts +2 -2
- package/src/{activities/execute-deep-agent → shared}/__tests__/stamp-flowed-rows.test.ts +33 -10
- package/src/shared/__tests__/vertex-adapter.test.ts +1 -1
- package/src/shared/attachment-resolver.ts +218 -55
- package/src/shared/attachment-zip.ts +281 -0
- package/src/shared/connect-backfill.ts +9 -11
- package/src/shared/cost-guard.ts +3 -3
- package/src/shared/execution-status-writer.ts +5 -5
- package/src/shared/extract-structured-output.ts +8 -7
- package/src/shared/filereview/__tests__/capture.test.ts +86 -4
- package/src/shared/filereview/__tests__/cas-progress.test.ts +2 -1
- package/src/shared/filereview/cas-progress.ts +5 -19
- package/src/shared/filereview/cas-touched.ts +89 -0
- package/src/shared/filereview/index.ts +4 -2
- package/src/shared/mcp-resolver.ts +4 -5
- package/src/shared/persist-decision.ts +3 -4
- package/src/shared/plan-mode-permissions.ts +2 -2
- package/src/shared/plan-mode-prompt.ts +1 -1
- package/src/shared/prompt-sections.ts +256 -0
- package/src/shared/skill-resolver.ts +4 -2
- package/src/shared/tool-rounds.ts +48 -0
- package/src/shared/tool-row.ts +61 -0
- package/src/shared/workspace/__tests__/stigmer-link.test.ts +7 -22
- package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +20 -61
- package/src/shared/workspace/session-provision.ts +3 -3
- package/src/shared/workspace/stigmer-link.ts +3 -3
- package/src/shared/workspace/writeback-coordinator.ts +16 -64
- package/src/tools/index.ts +1 -1
- package/dist/activities/execute-cursor/capture-flow.d.ts +0 -142
- package/dist/activities/execute-cursor/capture-flow.js +0 -285
- package/dist/activities/execute-cursor/capture-flow.js.map +0 -1
- package/dist/activities/execute-cursor/command-provenance.d.ts +0 -48
- package/dist/activities/execute-cursor/command-provenance.js +0 -38
- package/dist/activities/execute-cursor/command-provenance.js.map +0 -1
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +0 -134
- package/dist/activities/execute-deep-agent/attachment-injector.js +0 -386
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +0 -1
- package/dist/activities/execute-deep-agent/command-provenance.d.ts +0 -61
- package/dist/activities/execute-deep-agent/command-provenance.js +0 -72
- package/dist/activities/execute-deep-agent/command-provenance.js.map +0 -1
- package/dist/activities/execute-deep-agent/environment.d.ts +0 -24
- package/dist/activities/execute-deep-agent/environment.js +0 -58
- package/dist/activities/execute-deep-agent/environment.js.map +0 -1
- package/dist/activities/execute-deep-agent/event-recorder.d.ts +0 -21
- package/dist/activities/execute-deep-agent/event-recorder.js +0 -67
- package/dist/activities/execute-deep-agent/event-recorder.js.map +0 -1
- package/dist/activities/execute-deep-agent/index.d.ts +0 -15
- package/dist/activities/execute-deep-agent/index.js +0 -918
- package/dist/activities/execute-deep-agent/index.js.map +0 -1
- package/dist/activities/execute-deep-agent/mcp-gate.d.ts +0 -28
- package/dist/activities/execute-deep-agent/mcp-gate.js +0 -22
- package/dist/activities/execute-deep-agent/mcp-gate.js.map +0 -1
- package/dist/activities/execute-deep-agent/post-stream.d.ts +0 -23
- package/dist/activities/execute-deep-agent/post-stream.js +0 -71
- package/dist/activities/execute-deep-agent/post-stream.js.map +0 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +0 -136
- package/dist/activities/execute-deep-agent/setup.js +0 -767
- package/dist/activities/execute-deep-agent/setup.js.map +0 -1
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +0 -36
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +0 -56
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +0 -1
- package/dist/activities/execute-deep-agent/status-builder.d.ts +0 -93
- package/dist/activities/execute-deep-agent/status-builder.js +0 -365
- package/dist/activities/execute-deep-agent/status-builder.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming-terminal.d.ts +0 -21
- package/dist/activities/execute-deep-agent/streaming-terminal.js +0 -80
- package/dist/activities/execute-deep-agent/streaming-terminal.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming-v3.d.ts +0 -13
- package/dist/activities/execute-deep-agent/streaming-v3.js +0 -174
- package/dist/activities/execute-deep-agent/streaming-v3.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming.d.ts +0 -81
- package/dist/activities/execute-deep-agent/streaming.js +0 -160
- package/dist/activities/execute-deep-agent/streaming.js.map +0 -1
- package/dist/middleware/cost-cap.d.ts +0 -22
- package/dist/middleware/cost-cap.js.map +0 -1
- package/dist/middleware/graceful-stop.d.ts +0 -17
- package/dist/middleware/graceful-stop.js +0 -63
- package/dist/middleware/graceful-stop.js.map +0 -1
- package/dist/shared/skill-writer.d.ts +0 -75
- package/dist/shared/skill-writer.js +0 -207
- package/dist/shared/skill-writer.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +0 -1032
- package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +0 -240
- package/src/activities/execute-cursor/__tests__/progress-substrate.test.ts +0 -169
- package/src/activities/execute-cursor/capture-flow.ts +0 -379
- package/src/activities/execute-cursor/command-provenance.ts +0 -73
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +0 -1161
- package/src/activities/execute-deep-agent/__tests__/command-provenance.test.ts +0 -252
- package/src/activities/execute-deep-agent/__tests__/environment.test.ts +0 -108
- package/src/activities/execute-deep-agent/__tests__/event-recorder.test.ts +0 -150
- package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +0 -226
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +0 -318
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +0 -351
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +0 -293
- package/src/activities/execute-deep-agent/__tests__/index.test.ts +0 -99
- package/src/activities/execute-deep-agent/__tests__/mcp-gate.test.ts +0 -44
- package/src/activities/execute-deep-agent/__tests__/post-stream.test.ts +0 -112
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +0 -358
- package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +0 -1933
- package/src/activities/execute-deep-agent/__tests__/streaming-terminal.test.ts +0 -40
- package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +0 -597
- package/src/activities/execute-deep-agent/__tests__/streaming.test.ts +0 -508
- package/src/activities/execute-deep-agent/attachment-injector.ts +0 -627
- package/src/activities/execute-deep-agent/command-provenance.ts +0 -102
- package/src/activities/execute-deep-agent/environment.ts +0 -76
- package/src/activities/execute-deep-agent/event-recorder.ts +0 -95
- package/src/activities/execute-deep-agent/index.ts +0 -1072
- package/src/activities/execute-deep-agent/mcp-gate.ts +0 -37
- package/src/activities/execute-deep-agent/post-stream.ts +0 -109
- package/src/activities/execute-deep-agent/setup.ts +0 -1081
- package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +0 -64
- package/src/activities/execute-deep-agent/status-builder.ts +0 -481
- package/src/activities/execute-deep-agent/streaming-terminal.ts +0 -106
- package/src/activities/execute-deep-agent/streaming-v3.ts +0 -277
- package/src/activities/execute-deep-agent/streaming.ts +0 -313
- package/src/middleware/__tests__/cost-cap.test.ts +0 -192
- package/src/middleware/__tests__/graceful-stop.test.ts +0 -105
- package/src/middleware/graceful-stop.ts +0 -86
- package/src/shared/__tests__/skill-writer.test.ts +0 -372
- 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
|