@stigmer/runner 3.15.3-dev.20260914100347 → 3.15.3-dev.20260916211208
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 +1 -0
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/approval-contract/types.d.ts +1 -1
- package/dist/__test-utils__/hermetic-activity.d.ts +61 -7
- package/dist/__test-utils__/hermetic-activity.js +100 -9
- package/dist/__test-utils__/hermetic-activity.js.map +1 -1
- package/dist/__test-utils__/model-registry-fixture.d.ts +22 -3
- package/dist/__test-utils__/model-registry-fixture.js +22 -7
- package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.d.ts +2 -2
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +14 -11
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +61 -0
- package/dist/activities/execute-cursor/__test-utils__/fold.js +94 -0
- package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +1 -1
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +52 -14
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +46 -12
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +21 -28
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +27 -11
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.d.ts +70 -26
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js +82 -32
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +8 -7
- package/dist/activities/execute-cursor/adapter.js +13 -9
- package/dist/activities/execute-cursor/adapter.js.map +1 -1
- package/dist/activities/execute-cursor/approval-policy.d.ts +10 -10
- package/dist/activities/execute-cursor/approval-policy.js +12 -23
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +35 -1
- package/dist/activities/execute-cursor/approval-state.js +65 -0
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/{message-translator.d.ts → boundary-rows.d.ts} +45 -341
- package/dist/activities/execute-cursor/boundary-rows.js +1018 -0
- package/dist/activities/execute-cursor/boundary-rows.js.map +1 -0
- package/dist/activities/execute-cursor/cursor-capabilities.d.ts +1 -1
- package/dist/activities/execute-cursor/cursor-capabilities.js +1 -1
- package/dist/activities/execute-cursor/cursor-event-recorder.d.ts +33 -14
- package/dist/activities/execute-cursor/cursor-event-recorder.js +43 -21
- package/dist/activities/execute-cursor/cursor-event-recorder.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +3 -3
- package/dist/activities/execute-cursor/prompt-builder.js +4 -4
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/sdk-warmup.d.ts +15 -6
- package/dist/activities/execute-cursor/sdk-warmup.js +15 -6
- package/dist/activities/execute-cursor/sdk-warmup.js.map +1 -1
- package/dist/activities/execute-cursor/service-tier.js +1 -2
- package/dist/activities/execute-cursor/service-tier.js.map +1 -1
- package/dist/activities/execute-cursor/session-lifecycle.d.ts +38 -59
- package/dist/activities/execute-cursor/session-lifecycle.js +59 -96
- package/dist/activities/execute-cursor/session-lifecycle.js.map +1 -1
- package/dist/activities/execute-cursor/session-store.d.ts +100 -0
- package/dist/activities/execute-cursor/session-store.js +157 -0
- package/dist/activities/execute-cursor/session-store.js.map +1 -0
- package/dist/activities/execute-cursor/sub-agent-steps.d.ts +79 -0
- package/dist/activities/execute-cursor/sub-agent-steps.js +180 -0
- package/dist/activities/execute-cursor/sub-agent-steps.js.map +1 -0
- package/dist/activities/execute-cursor/tool-result.d.ts +49 -0
- package/dist/activities/execute-cursor/tool-result.js +130 -0
- package/dist/activities/execute-cursor/tool-result.js.map +1 -0
- package/dist/activities/execute-cursor/translator.d.ts +178 -0
- package/dist/activities/execute-cursor/translator.js +485 -0
- package/dist/activities/execute-cursor/translator.js.map +1 -0
- package/dist/activities/execute-cursor/turn-boundary.d.ts +15 -5
- package/dist/activities/execute-cursor/turn-boundary.js +10 -14
- 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 +47 -34
- package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-setup.d.ts +2 -2
- package/dist/activities/execute-cursor/turn-setup.js +5 -5
- package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
- package/dist/activities/execute-cursor/turn-stream.d.ts +23 -14
- package/dist/activities/execute-cursor/turn-stream.js +41 -28
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-cursor/turn.d.ts +4 -4
- package/dist/activities/execute-cursor/turn.js +5 -5
- package/dist/activities/execute-cursor/usage-pricing.d.ts +2 -2
- package/dist/activities/execute-cursor/usage-pricing.js +2 -2
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +2 -2
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +2 -2
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +16 -11
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -10
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +2 -3
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +2 -3
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +12 -3
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +18 -4
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.d.ts +10 -1
- package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js +24 -11
- package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js.map +1 -1
- package/dist/activities/execute-deep-agent/adapter.d.ts +1 -1
- package/dist/activities/execute-deep-agent/adapter.js +1 -1
- package/dist/activities/execute-deep-agent/approval-file-change.d.ts +19 -19
- package/dist/activities/execute-deep-agent/approval-file-change.js +16 -15
- package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -1
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +2 -2
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +2 -2
- package/dist/activities/execute-deep-agent/hitl.d.ts +2 -2
- package/dist/activities/execute-deep-agent/hitl.js +2 -2
- package/dist/activities/execute-deep-agent/inline-publisher.d.ts +13 -3
- package/dist/activities/execute-deep-agent/inline-publisher.js +3 -3
- package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +3 -3
- package/dist/activities/execute-deep-agent/prompt-builder.js +6 -7
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +16 -8
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +20 -33
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +3 -3
- package/dist/activities/execute-deep-agent/subagent-transformer.js +1 -1
- package/dist/activities/execute-deep-agent/translator.d.ts +134 -0
- package/dist/activities/execute-deep-agent/translator.js +418 -0
- package/dist/activities/execute-deep-agent/translator.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-settle.d.ts +13 -7
- package/dist/activities/execute-deep-agent/turn-settle.js +34 -45
- package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +8 -8
- package/dist/activities/execute-deep-agent/turn-setup.js +7 -7
- package/dist/activities/execute-deep-agent/turn-stream.d.ts +13 -10
- package/dist/activities/execute-deep-agent/turn-stream.js +44 -41
- package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn.d.ts +3 -3
- package/dist/activities/execute-deep-agent/turn.js +3 -3
- package/dist/config.d.ts +2 -2
- package/dist/harness/approval-decisions.d.ts +1 -1
- package/dist/harness/approval-decisions.js +1 -1
- package/dist/harness/capabilities.d.ts +21 -11
- package/dist/harness/capabilities.js +2 -2
- package/dist/harness/capture.d.ts +4 -4
- package/dist/harness/capture.js +4 -4
- package/dist/harness/persist-chokepoint.d.ts +3 -3
- package/dist/harness/persist-chokepoint.js +3 -3
- package/dist/harness/registry.d.ts +2 -2
- package/dist/harness/registry.js +2 -2
- package/dist/harness/run-turn.d.ts +6 -4
- package/dist/harness/run-turn.js +31 -9
- package/dist/harness/run-turn.js.map +1 -1
- package/dist/harness/stop-controller.d.ts +1 -1
- package/dist/harness/stop-controller.js +1 -1
- package/dist/harness/terminal-table.d.ts +7 -7
- package/dist/harness/terminal-table.js +7 -7
- package/dist/harness/transcript/builder.d.ts +182 -0
- package/dist/harness/transcript/builder.js +693 -0
- package/dist/harness/transcript/builder.js.map +1 -0
- package/dist/harness/transcript/events.d.ts +218 -0
- package/dist/harness/transcript/events.js +50 -0
- package/dist/harness/transcript/events.js.map +1 -0
- package/dist/harness/transcript/state.d.ts +110 -0
- package/dist/harness/transcript/state.js +148 -0
- package/dist/harness/transcript/state.js.map +1 -0
- package/dist/harness/turn-context.d.ts +54 -38
- package/dist/harness/turn-context.js +42 -43
- package/dist/harness/turn-context.js.map +1 -1
- package/dist/harness/types.d.ts +63 -22
- package/dist/harness/types.js +12 -11
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage-accumulator.d.ts +2 -2
- package/dist/harness/usage-accumulator.js +2 -2
- package/dist/harness-adapters.d.ts +5 -4
- package/dist/harness-adapters.js +5 -4
- package/dist/harness-adapters.js.map +1 -1
- package/dist/middleware/approval-gate.d.ts +6 -0
- package/dist/middleware/approval-gate.js +7 -57
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/middleware/cost-advisory.d.ts +3 -3
- package/dist/middleware/cost-advisory.js +3 -3
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/runner-manager.js +1 -1
- package/dist/runner-manager.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +53 -0
- package/dist/shared/approval-policy.js +76 -0
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/args-preview.d.ts +45 -22
- package/dist/shared/args-preview.js +51 -41
- package/dist/shared/args-preview.js.map +1 -1
- package/dist/shared/attachment-resolver.d.ts +4 -4
- package/dist/shared/attachment-resolver.js +4 -4
- package/dist/shared/attachment-vision.d.ts +2 -1
- package/dist/shared/attachment-vision.js.map +1 -1
- package/dist/shared/attachment-zip.d.ts +2 -2
- package/dist/shared/attachment-zip.js +2 -2
- package/dist/shared/cost-guard.d.ts +2 -2
- package/dist/shared/cost-guard.js +2 -2
- package/dist/shared/exact-apply.d.ts +1 -1
- package/dist/shared/exact-apply.js +1 -1
- package/dist/shared/execution-context.d.ts +2 -2
- package/dist/shared/execution-context.js +2 -2
- package/dist/shared/extract-structured-output.d.ts +2 -2
- package/dist/shared/extract-structured-output.js +2 -2
- package/dist/shared/filereview/cas-touched.d.ts +2 -2
- package/dist/shared/filereview/cas-touched.js +2 -2
- package/dist/shared/heartbeat.d.ts +1 -1
- package/dist/shared/heartbeat.js +1 -1
- package/dist/shared/llm-backend.d.ts +0 -4
- package/dist/shared/llm-backend.js +0 -4
- package/dist/shared/llm-backend.js.map +1 -1
- package/dist/shared/model-error.d.ts +1 -2
- package/dist/shared/model-error.js +1 -2
- package/dist/shared/model-error.js.map +1 -1
- package/dist/shared/persist-decision.d.ts +18 -24
- package/dist/shared/persist-decision.js +19 -11
- package/dist/shared/persist-decision.js.map +1 -1
- package/dist/shared/prompt-sections.d.ts +4 -4
- package/dist/shared/prompt-sections.js +4 -4
- package/dist/shared/skill-resolver.d.ts +3 -3
- package/dist/shared/skill-resolver.js +3 -3
- package/dist/shared/status-offload.d.ts +1 -1
- package/dist/shared/status-offload.js +2 -2
- package/dist/shared/status-offload.js.map +1 -1
- package/dist/shared/streaming-scheduler.d.ts +2 -7
- package/dist/shared/streaming-scheduler.js +6 -14
- package/dist/shared/streaming-scheduler.js.map +1 -1
- package/dist/shared/subagent-rows.d.ts +2 -2
- package/dist/shared/subagent-rows.js +2 -2
- package/dist/shared/todos.d.ts +3 -3
- package/dist/shared/todos.js +3 -3
- package/dist/shared/tool-row.d.ts +19 -1
- package/dist/shared/tool-row.js +36 -2
- package/dist/shared/tool-row.js.map +1 -1
- package/dist/shared/worker-shutdown.d.ts +1 -1
- package/dist/shared/worker-shutdown.js +1 -1
- package/dist/shared/workspace/session-provision.d.ts +1 -1
- package/dist/shared/workspace/session-provision.js +1 -1
- package/dist/shared/workspace/sources/empty.d.ts +1 -1
- package/dist/shared/workspace/sources/empty.js +1 -2
- package/dist/shared/workspace/sources/empty.js.map +1 -1
- package/dist/shared/workspace/sources/git.js +4 -4
- package/dist/shared/workspace/sources/git.js.map +1 -1
- package/dist/shared/workspace/sources/local-path.js +6 -6
- package/dist/shared/workspace/sources/local-path.js.map +1 -1
- package/dist/shared/workspace/stigmer-link.d.ts +1 -1
- package/dist/shared/workspace/stigmer-link.js +1 -1
- package/dist/shared/workspace/types.d.ts +2 -5
- package/dist/shared/workspace/types.js +0 -6
- package/dist/shared/workspace/types.js.map +1 -1
- package/dist/shared/workspace/writeback-coordinator.d.ts +17 -4
- package/dist/shared/workspace/writeback-coordinator.js +7 -9
- package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
- package/package.json +5 -5
- package/src/__test-utils__/__tests__/execution-record-barrier.test.ts +70 -0
- package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +35 -1
- package/src/__test-utils__/approval-contract/contract.ts +1 -1
- package/src/__test-utils__/approval-contract/types.ts +1 -1
- package/src/__test-utils__/harness-boot-order-child.ts +1 -1
- package/src/__test-utils__/harness-contract/contract.ts +8 -8
- package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
- package/src/__test-utils__/harness-contract/runtime-contract.ts +52 -16
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +47 -43
- package/src/__test-utils__/hermetic-activity.ts +113 -9
- package/src/__test-utils__/model-registry-fixture.ts +31 -7
- package/src/__test-utils__/module-specifiers.ts +32 -3
- package/src/__tests__/harness-boot-order.test.ts +1 -1
- package/src/__tests__/harness-contract.test.ts +1 -1
- package/src/__tests__/runner-manager.test.ts +1 -1
- package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +32 -8
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +12 -10
- package/src/activities/execute-cursor/__test-utils__/fold.ts +116 -0
- package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +1 -1
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +72 -19
- package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +35 -29
- package/src/activities/execute-cursor/__test-utils__/scripted-sdk.ts +94 -38
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/approval-state.test.ts +14 -21
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +3 -3
- package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/cursor-baseurl-routing.test.ts +10 -8
- package/src/activities/execute-cursor/__tests__/cursor-event-recorder.test.ts +142 -0
- package/src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts +24 -12
- package/src/activities/execute-cursor/__tests__/cursor-generate-image-live.test.ts +7 -2
- package/src/activities/execute-cursor/__tests__/cursor-hook-protocol-live.test.ts +163 -0
- package/src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts +23 -20
- package/src/activities/execute-cursor/__tests__/cursor-transcript-live.test.ts +298 -0
- package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +4 -2
- package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +5 -2
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +5 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/mcp-tool-call.status.json +71 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-task-note.status.json +73 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +78 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +72 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +72 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sub-agent-delegation.status.json +109 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/thinking-turn.status.json +78 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/todo-write.status.json +119 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-error.status.json +68 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-only-step.status.json +67 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +10 -7
- package/src/activities/execute-cursor/__tests__/hermetic/mcp-tool-call.test.ts +146 -0
- package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +8 -5
- package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +6 -2
- package/src/activities/execute-cursor/__tests__/hermetic/recovery-fresh-agent.test.ts +4 -1
- package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +6 -2
- package/src/activities/execute-cursor/__tests__/hermetic/sdk-task-note.test.ts +122 -0
- package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +276 -0
- package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +12 -9
- package/src/activities/execute-cursor/__tests__/hermetic/sub-agent-delegation.test.ts +196 -0
- package/src/activities/execute-cursor/__tests__/hermetic/thinking-turn.test.ts +145 -0
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +4 -1
- package/src/activities/execute-cursor/__tests__/hermetic/todo-write.test.ts +165 -0
- package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +7 -4
- package/src/activities/execute-cursor/__tests__/hermetic/tool-error.test.ts +138 -0
- package/src/activities/execute-cursor/__tests__/hermetic/tool-only-step.test.ts +130 -0
- package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +17 -2
- package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -2
- package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +43 -60
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +23 -28
- package/src/activities/execute-cursor/__tests__/hook-script.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +5 -5
- package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +11 -13
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +8 -11
- package/src/activities/execute-cursor/__tests__/session-lifecycle.test.ts +86 -58
- package/src/activities/execute-cursor/__tests__/session-store.test.ts +220 -0
- package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +8 -22
- package/src/activities/execute-cursor/__tests__/translator.test.ts +594 -0
- package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +8 -5
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +87 -63
- package/src/activities/execute-cursor/adapter.ts +13 -9
- package/src/activities/execute-cursor/approval-policy.ts +12 -24
- package/src/activities/execute-cursor/approval-state.ts +66 -1
- package/src/activities/execute-cursor/boundary-rows.ts +1132 -0
- package/src/activities/execute-cursor/cursor-capabilities.ts +1 -1
- package/src/activities/execute-cursor/cursor-event-recorder.ts +57 -28
- package/src/activities/execute-cursor/fetch-interceptor.ts +1 -1
- package/src/activities/execute-cursor/http2-interceptor.ts +1 -1
- package/src/activities/execute-cursor/prompt-builder.ts +6 -6
- package/src/activities/execute-cursor/sdk-warmup.ts +15 -6
- package/src/activities/execute-cursor/service-tier.ts +1 -2
- package/src/activities/execute-cursor/session-lifecycle.ts +63 -109
- package/src/activities/execute-cursor/session-store.ts +187 -0
- package/src/activities/execute-cursor/sub-agent-steps.ts +188 -0
- package/src/activities/execute-cursor/tool-result.ts +128 -0
- package/src/activities/execute-cursor/translator.ts +541 -0
- package/src/activities/execute-cursor/turn-boundary.ts +21 -14
- package/src/activities/execute-cursor/turn-settle.ts +46 -34
- package/src/activities/execute-cursor/turn-setup.ts +5 -5
- package/src/activities/execute-cursor/turn-stream.ts +49 -46
- package/src/activities/execute-cursor/turn.ts +5 -5
- package/src/activities/execute-cursor/usage-pricing.ts +2 -2
- package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +2 -2
- package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +23 -11
- package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +1 -1
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +2 -3
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +25 -4
- package/src/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.ts +25 -11
- package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +6 -17
- package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +25 -8
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +2 -7
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +4 -14
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +4 -7
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +2 -9
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +2 -9
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +109 -76
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +2 -10
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +2 -10
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +3 -6
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/write-todos.status.json +92 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +3 -3
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +9 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +3 -3
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +3 -3
- package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +7 -6
- package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +10 -11
- package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +4 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +9 -8
- package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +21 -13
- package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +7 -7
- package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +28 -12
- package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +21 -21
- package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/write-todos.test.ts +160 -0
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +35 -30
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +3 -4
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +12 -10
- package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +13 -3
- package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +26 -18
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/{subagent-tracker.test.ts → translator-subagents.test.ts} +76 -57
- package/src/activities/execute-deep-agent/__tests__/{v3-status-builder.test.ts → translator-through-builder.test.ts} +213 -299
- package/src/activities/execute-deep-agent/__tests__/translator.test.ts +505 -0
- package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +11 -29
- package/src/activities/execute-deep-agent/adapter.ts +1 -1
- package/src/activities/execute-deep-agent/approval-file-change.ts +20 -22
- package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +2 -2
- package/src/activities/execute-deep-agent/hitl.ts +2 -2
- package/src/activities/execute-deep-agent/inline-publisher.ts +16 -5
- package/src/activities/execute-deep-agent/prompt-builder.ts +6 -7
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +22 -31
- package/src/activities/execute-deep-agent/subagent-transformer.ts +3 -3
- package/src/activities/execute-deep-agent/translator.ts +463 -0
- package/src/activities/execute-deep-agent/turn-settle.ts +35 -43
- package/src/activities/execute-deep-agent/turn-setup.ts +8 -8
- package/src/activities/execute-deep-agent/turn-stream.ts +53 -51
- package/src/activities/execute-deep-agent/turn.ts +3 -3
- package/src/config.ts +2 -2
- package/src/harness/README.md +335 -0
- package/src/harness/__tests__/approval-decisions.test.ts +2 -2
- package/src/harness/__tests__/capture.test.ts +3 -3
- package/src/harness/__tests__/import-direction.test.ts +3 -2
- package/src/harness/__tests__/mount-skills.test.ts +4 -1
- package/src/harness/__tests__/readme-index.test.ts +339 -0
- package/src/harness/__tests__/run-turn.test.ts +131 -6
- package/src/harness/__tests__/transcript-is-engine-free.test.ts +83 -0
- package/src/harness/__tests__/transcript-writers.test.ts +191 -0
- package/src/harness/__tests__/turn-attachments-vision.test.ts +5 -2
- package/src/harness/__tests__/turn-context.test.ts +5 -5
- package/src/harness/approval-decisions.ts +1 -1
- package/src/harness/capabilities.ts +21 -11
- package/src/harness/capture.ts +4 -4
- package/src/harness/persist-chokepoint.ts +3 -3
- package/src/harness/registry.ts +2 -2
- package/src/harness/run-turn.ts +33 -9
- package/src/harness/stop-controller.ts +1 -1
- package/src/harness/terminal-table.ts +7 -7
- package/src/harness/transcript/__tests__/builder.test.ts +975 -0
- package/src/harness/transcript/__tests__/state.test.ts +143 -0
- package/src/harness/transcript/builder.ts +755 -0
- package/src/harness/transcript/events.ts +262 -0
- package/src/harness/transcript/state.ts +167 -0
- package/src/harness/turn-context.ts +61 -46
- package/src/harness/types.ts +64 -22
- package/src/harness/usage-accumulator.ts +2 -2
- package/src/harness-adapters.ts +5 -4
- package/src/middleware/__tests__/cost-advisory.test.ts +2 -2
- package/src/middleware/approval-gate.ts +7 -74
- package/src/middleware/cost-advisory.ts +3 -3
- package/src/middleware/index.ts +1 -1
- package/src/runner-manager.ts +1 -1
- package/src/shared/__tests__/approval-policy.test.ts +45 -0
- package/src/shared/__tests__/args-preview.test.ts +40 -20
- package/src/shared/__tests__/attachment-naming.test.ts +1 -1
- package/src/shared/__tests__/attachment-resolver.test.ts +5 -5
- package/src/shared/__tests__/attachment-zip.test.ts +1 -1
- package/src/shared/__tests__/blueprint-resolver.test.ts +1 -1
- package/src/shared/__tests__/cost-guard.test.ts +1 -1
- package/src/shared/__tests__/exact-apply.test.ts +2 -1
- package/src/shared/__tests__/persist-decision.test.ts +19 -33
- package/src/shared/__tests__/prompt-sections.test.ts +1 -1
- package/src/shared/__tests__/stamp-flowed-rows.test.ts +1 -1
- package/src/shared/__tests__/status-offload.test.ts +1 -1
- package/src/shared/__tests__/streaming-scheduler.test.ts +8 -9
- package/src/shared/__tests__/todos.test.ts +1 -1
- package/src/shared/__tests__/tool-row.test.ts +1 -1
- package/src/shared/approval-policy.ts +95 -0
- package/src/shared/args-preview.ts +51 -42
- package/src/shared/attachment-resolver.ts +4 -4
- package/src/shared/attachment-vision.ts +2 -1
- package/src/shared/attachment-zip.ts +2 -2
- package/src/shared/cost-guard.ts +2 -2
- package/src/shared/exact-apply.ts +1 -1
- package/src/shared/execution-context.ts +2 -2
- package/src/shared/extract-structured-output.ts +2 -2
- package/src/shared/filereview/__tests__/capture.test.ts +9 -5
- package/src/shared/filereview/__tests__/git-substrate.test.ts +4 -1
- package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +3 -3
- package/src/shared/filereview/cas-touched.ts +2 -2
- package/src/shared/heartbeat.ts +1 -1
- package/src/shared/llm-backend.ts +0 -4
- package/src/shared/model-error.ts +1 -2
- package/src/shared/persist-decision.ts +19 -28
- package/src/shared/prompt-sections.ts +4 -4
- package/src/shared/skill-resolver.ts +3 -3
- package/src/shared/status-offload.ts +2 -2
- package/src/shared/streaming-scheduler.ts +8 -13
- package/src/shared/subagent-rows.ts +2 -2
- package/src/shared/todos.ts +3 -3
- package/src/shared/tool-row.ts +38 -2
- package/src/shared/worker-shutdown.ts +1 -1
- package/src/shared/workspace/__tests__/git-source.test.ts +3 -3
- package/src/shared/workspace/__tests__/provisioner.test.ts +5 -5
- package/src/shared/workspace/__tests__/session-provision.test.ts +2 -2
- package/src/shared/workspace/__tests__/writeback-coordinator.integration.test.ts +8 -9
- package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +25 -25
- package/src/shared/workspace/provisioner.ts +1 -1
- package/src/shared/workspace/session-provision.ts +1 -1
- package/src/shared/workspace/sources/empty.ts +2 -2
- package/src/shared/workspace/sources/git.ts +3 -4
- package/src/shared/workspace/sources/local-path.ts +5 -6
- package/src/shared/workspace/stigmer-link.ts +1 -1
- package/src/shared/workspace/types.ts +2 -5
- package/src/shared/workspace/writeback-coordinator.ts +23 -12
- package/dist/activities/execute-cursor/delta-enricher.d.ts +0 -87
- package/dist/activities/execute-cursor/delta-enricher.js +0 -265
- package/dist/activities/execute-cursor/delta-enricher.js.map +0 -1
- package/dist/activities/execute-cursor/message-translator.js +0 -2040
- package/dist/activities/execute-cursor/message-translator.js.map +0 -1
- package/dist/activities/execute-cursor/todo-tracker.d.ts +0 -40
- package/dist/activities/execute-cursor/todo-tracker.js +0 -80
- package/dist/activities/execute-cursor/todo-tracker.js.map +0 -1
- package/dist/activities/execute-deep-agent/execution-state.d.ts +0 -54
- package/dist/activities/execute-deep-agent/execution-state.js +0 -68
- package/dist/activities/execute-deep-agent/execution-state.js.map +0 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +0 -65
- package/dist/activities/execute-deep-agent/status-builder-shared.js +0 -90
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +0 -1
- package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +0 -113
- package/dist/activities/execute-deep-agent/subagent-tracker.js +0 -400
- package/dist/activities/execute-deep-agent/subagent-tracker.js.map +0 -1
- package/dist/activities/execute-deep-agent/v3-events.d.ts +0 -102
- package/dist/activities/execute-deep-agent/v3-events.js +0 -35
- package/dist/activities/execute-deep-agent/v3-events.js.map +0 -1
- package/dist/activities/execute-deep-agent/v3-protocol-normalizer.d.ts +0 -15
- package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js +0 -235
- package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js.map +0 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +0 -111
- package/dist/activities/execute-deep-agent/v3-status-builder.js +0 -457
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +0 -1
- package/dist/shared/execution-status-writer.d.ts +0 -31
- package/dist/shared/execution-status-writer.js +0 -43
- package/dist/shared/execution-status-writer.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/delta-enricher.test.ts +0 -310
- package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -1033
- package/src/activities/execute-cursor/__tests__/todo-tracker.test.ts +0 -498
- package/src/activities/execute-cursor/delta-enricher.ts +0 -307
- package/src/activities/execute-cursor/message-translator.ts +0 -2319
- package/src/activities/execute-cursor/todo-tracker.ts +0 -91
- package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -148
- package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -154
- package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +0 -47
- package/src/activities/execute-deep-agent/__tests__/v3-protocol-normalizer.test.ts +0 -324
- package/src/activities/execute-deep-agent/execution-state.ts +0 -78
- package/src/activities/execute-deep-agent/status-builder-shared.ts +0 -142
- package/src/activities/execute-deep-agent/subagent-tracker.ts +0 -479
- package/src/activities/execute-deep-agent/v3-events.ts +0 -153
- package/src/activities/execute-deep-agent/v3-protocol-normalizer.ts +0 -264
- package/src/activities/execute-deep-agent/v3-status-builder.ts +0 -565
- package/src/shared/execution-status-writer.ts +0 -56
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* with the engine that will run it: the execution and its session, the
|
|
7
7
|
* agent blueprint, the environment, the workspace and its lock, what the
|
|
8
8
|
* previous turn left waiting for approval, the MCP servers and their
|
|
9
|
-
* approval policies, the attachments, the standing context. Until
|
|
9
|
+
* approval policies, the attachments, the standing context. Until #1070
|
|
10
10
|
* that sequence lived inline in the Cursor orchestrator
|
|
11
11
|
* (`activities/execute-cursor/index.ts` `executeCursorInner`, phases 1 to
|
|
12
12
|
* 9c); the native orchestrator carried a second copy in its `performSetup`.
|
|
@@ -16,16 +16,16 @@
|
|
|
16
16
|
* sequences them, and the adapter runs its own harness-specific steps after
|
|
17
17
|
* the whole record exists.
|
|
18
18
|
*
|
|
19
|
-
* Shape, chosen against the native orchestrator's `setup.ts` (deleted
|
|
20
|
-
*
|
|
19
|
+
* Shape, chosen against the native orchestrator's `setup.ts` (deleted in
|
|
20
|
+
* #1096): a typed record built from small functions (the `SetupResult` mold),
|
|
21
21
|
* never one 775-line `performSetup`. The record is the adapter contract's `TurnInput`
|
|
22
22
|
* (`types.ts`): every phase returns a named slice of it, and
|
|
23
23
|
* {@link resolveTurnContext} composes the whole. There is no wider
|
|
24
24
|
* "runtime-private" record beside it — the lock release and the write-back
|
|
25
25
|
* coordinator a phase produces are the caller's `TurnFrame` resources, set
|
|
26
|
-
* the instant they exist so a `finally` sees them on every path (
|
|
27
|
-
* `TurnContext extends TurnInput` for them; once the groups lifted,
|
|
28
|
-
* read the extension after composition, so
|
|
26
|
+
* the instant they exist so a `finally` sees them on every path (a first cut
|
|
27
|
+
* had a `TurnContext extends TurnInput` for them; once the groups lifted,
|
|
28
|
+
* nothing read the extension after composition, so #1070 shipped without it).
|
|
29
29
|
*
|
|
30
30
|
* Three rules every phase obeys:
|
|
31
31
|
*
|
|
@@ -41,17 +41,17 @@
|
|
|
41
41
|
* - Its heartbeat pulse and its cold-start timing marks are its own: the
|
|
42
42
|
* step name it enters under is the mark name it emits, one vocabulary for
|
|
43
43
|
* "where in setup are we" in Temporal heartbeat details and the
|
|
44
|
-
* `execution_setup` log
|
|
44
|
+
* `execution_setup` log.
|
|
45
45
|
*
|
|
46
46
|
* What is deliberately NOT here, and where it is instead:
|
|
47
47
|
*
|
|
48
48
|
* - Cursor's catalog validation of the requested model (`resolveModelId`),
|
|
49
49
|
* the pricing preload and the MCP env pre-flight warning stay in the
|
|
50
|
-
* Cursor adapter
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
50
|
+
* Cursor adapter: each reads a module that is the adapter's own, and the
|
|
51
|
+
* runtime carries the REQUESTED model name so every harness validates
|
|
52
|
+
* against its own catalog. The skill mount was in that list until #1070
|
|
53
|
+
* found it reads the control plane, which only the runtime holds; it is
|
|
54
|
+
* {@link mountSkills}.
|
|
55
55
|
* - The approval grants, the HITL gate, the capture baseline pin and the
|
|
56
56
|
* Cursor agent itself (phases 5c, 7, 8a, 9) are the adapter's.
|
|
57
57
|
* - The memory selection is a memoized thunk, not a value: whether a prompt
|
|
@@ -81,7 +81,6 @@ import { resolveBlueprint, type ResolvedBlueprint } from "../shared/blueprint-re
|
|
|
81
81
|
import { resolveExecutionEnv } from "../shared/env-resolver.js";
|
|
82
82
|
import { provisionSessionWorkspace } from "../shared/workspace/session-provision.js";
|
|
83
83
|
import { WriteBackCoordinator } from "../shared/workspace/writeback-coordinator.js";
|
|
84
|
-
import { statusProtoWriter } from "../shared/execution-status-writer.js";
|
|
85
84
|
import { isGitWorkTree } from "../shared/filereview/git-substrate.js";
|
|
86
85
|
import { applyCaptureDecisions, deriveCaptureMode } from "../shared/filereview/capture.js";
|
|
87
86
|
import { casBlobReader } from "../shared/filereview/cas-substrate.js";
|
|
@@ -116,6 +115,7 @@ import { readConversationCatchup } from "../shared/conversation-catchup.js";
|
|
|
116
115
|
import { selectRecalledFacts } from "../shared/memory-retrieval.js";
|
|
117
116
|
import type { RecalledMemoriesContent } from "../shared/recalled-memories.js";
|
|
118
117
|
import type { FileReviewIdentity, HarnessCapabilities, PausePrimitive, StateIdSource } from "./capabilities.js";
|
|
118
|
+
import type { TranscriptBuilder } from "./transcript/builder.js";
|
|
119
119
|
import type {
|
|
120
120
|
TurnAttachments,
|
|
121
121
|
TurnEnvironment,
|
|
@@ -135,7 +135,7 @@ import type {
|
|
|
135
135
|
* What every phase reads from its caller. The activity's identity and the
|
|
136
136
|
* runtime's own seams; nothing harness-specific. The four function members
|
|
137
137
|
* are the caller's, injected so the phase bodies are the same code under
|
|
138
|
-
* the Cursor orchestrator
|
|
138
|
+
* the Cursor orchestrator it left and under `run-turn.ts` (only the
|
|
139
139
|
* binding changes), and so a test can drive a phase without a Temporal
|
|
140
140
|
* activity context.
|
|
141
141
|
*/
|
|
@@ -151,10 +151,20 @@ export interface ResolutionDeps {
|
|
|
151
151
|
readonly config: Config;
|
|
152
152
|
/**
|
|
153
153
|
* The one execution status this turn folds into. Phases that carry state
|
|
154
|
-
* across invocations write
|
|
155
|
-
* reconcile's events, the memory-selection report
|
|
154
|
+
* across invocations write the runtime's OWN fields here (the file-review
|
|
155
|
+
* reconcile's events, the memory-selection report, the seeded singletons);
|
|
156
|
+
* nothing else does.
|
|
156
157
|
*/
|
|
157
158
|
readonly status: AgentExecutionStatus;
|
|
159
|
+
/**
|
|
160
|
+
* The one transcript builder over `status`, the caller's, born with the
|
|
161
|
+
* status. Two phases hand it on: the seed appends a reinvocation's prior
|
|
162
|
+
* rows through it (so they are indexed as they land), and the workspace
|
|
163
|
+
* phase gives it to the write-back coordinator as the place a write-back
|
|
164
|
+
* record is registered. No phase folds an event into it — no engine has
|
|
165
|
+
* run yet.
|
|
166
|
+
*/
|
|
167
|
+
readonly transcript: TranscriptBuilder;
|
|
158
168
|
/** Resolved once by the caller before any phase; absent when no substrate works. */
|
|
159
169
|
readonly artifactStorage: ArtifactStorage | undefined;
|
|
160
170
|
/** The cold-start timeline; each phase marks its own segment(s) exactly as before. */
|
|
@@ -199,7 +209,7 @@ export interface TurnReinvocation {
|
|
|
199
209
|
* A turn that ended during resolution, before any harness ran. Each arm
|
|
200
210
|
* names what was decided and carries only the facts the caller's status
|
|
201
211
|
* writes need; the copy, the phase flip, the persist and the slim return are
|
|
202
|
-
* the caller's (the
|
|
212
|
+
* the caller's (the runtime's terminal table).
|
|
203
213
|
*
|
|
204
214
|
* - `workspace-lock-timeout`: another turn held the primary tree past
|
|
205
215
|
* `Config.workspaceLockTimeoutMs`. FAILED, returned (a Temporal retry
|
|
@@ -238,7 +248,7 @@ export type ReinvocationOutcome =
|
|
|
238
248
|
/**
|
|
239
249
|
* Whether the engine already holds state for this execution, so this
|
|
240
250
|
* invocation resumes rather than begins. One function keyed on how the
|
|
241
|
-
* harness mints its state id
|
|
251
|
+
* harness mints its state id:
|
|
242
252
|
*
|
|
243
253
|
* - `engine-minted` (Cursor: the agent id): the runtime knows nothing until
|
|
244
254
|
* the adapter binds an id, so a non-empty `threadId` IS the evidence.
|
|
@@ -260,7 +270,7 @@ export type ReinvocationOutcome =
|
|
|
260
270
|
* the exact-apply). An adapter that needs create-vs-resume for its ENGINE
|
|
261
271
|
* reads `input.threadId` itself — for an engine-minted harness that is the
|
|
262
272
|
* same bit, for a deterministic one the engine's checkpoint is the adapter's
|
|
263
|
-
* to consult — so the contract carries no flag with two meanings
|
|
273
|
+
* to consult — so the contract carries no flag with two meanings.
|
|
264
274
|
*/
|
|
265
275
|
export function isReinvocation(
|
|
266
276
|
stateIdSource: StateIdSource,
|
|
@@ -299,10 +309,10 @@ export interface ReinvocationFacts {
|
|
|
299
309
|
* nothing else is complete, because keeping or discarding a file never
|
|
300
310
|
* re-prompts the agent (Cursor-like). `undefined` means "run the agent".
|
|
301
311
|
*
|
|
302
|
-
* Until
|
|
312
|
+
* Until #1096 a REJECT failed the turn here with its own FAILED arm, Cursor's
|
|
303
313
|
* legacy; the proto (`APPROVAL_ACTION_REJECT`: "does NOT fail the run"), the
|
|
304
314
|
* conformance suite and the native harness said otherwise since stigmer#197,
|
|
305
|
-
* and the runtime now agrees
|
|
315
|
+
* and the runtime now agrees.
|
|
306
316
|
*/
|
|
307
317
|
export function decideReinvocation(
|
|
308
318
|
facts: ReinvocationFacts,
|
|
@@ -326,14 +336,15 @@ export function decideReinvocation(
|
|
|
326
336
|
*
|
|
327
337
|
* Why the transcript must be seeded: a resumed engine re-issues the
|
|
328
338
|
* previously gated tool calls with brand-new call ids. Without seeding, the
|
|
329
|
-
* harness's
|
|
339
|
+
* harness's transcript builder would rebuild the transcript from empty and emit a
|
|
330
340
|
* status that drops the already-committed tool-call ids. The backend's
|
|
331
341
|
* append-only-at-identity guard rejects any non-terminal update that drops a
|
|
332
342
|
* committed tool-call id, so the resumed progress would never persist: the
|
|
333
343
|
* run stalls in WAITING_FOR_APPROVAL with no pending approvals and the
|
|
334
344
|
* workflow watchdog fails it. Seeding makes the resume status a strict
|
|
335
345
|
* superset; the re-runs are then reconciled in place onto these seeded calls
|
|
336
|
-
* by canonical identity inside the
|
|
346
|
+
* by canonical identity inside the harness's translator (the Cursor translator's
|
|
347
|
+
* seeded-row match; the native builder's by-id flip).
|
|
337
348
|
*
|
|
338
349
|
* Why the OTHER collections must be seeded too — the server's merge rule
|
|
339
350
|
* (`stigmer-server/src/domain/agentexecution/update-status.ts`): every list
|
|
@@ -355,28 +366,32 @@ export function decideReinvocation(
|
|
|
355
366
|
* `phase`, `startedAt`, `completedAt`, `error` are this turn's fresh
|
|
356
367
|
* terminal, written by the runtime.
|
|
357
368
|
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
369
|
+
* The transcript half — messages, sub-agent rows, artifacts, write-backs,
|
|
370
|
+
* todos — goes through the builder's `seed()`, which appends every
|
|
371
|
+
* collection IN PLACE (the status's own arrays, so every wrapper of the
|
|
372
|
+
* status keeps seeing every row) and indexes the rows as it appends, so the
|
|
373
|
+
* upcoming turn's re-issued call reconciles onto its seeded row. The three
|
|
374
|
+
* singletons are the runtime's own and are set here. The persisted protos
|
|
375
|
+
* are cloned so the input execution stays immutable.
|
|
364
376
|
*
|
|
365
377
|
* Moved from `execute-cursor/index.ts` `seedCursorTranscriptFromExecution`
|
|
366
|
-
* (messages only) and widened
|
|
378
|
+
* (messages only) and widened in #1096 to what native's whole-status clone
|
|
367
379
|
* (`execute-deep-agent/index.ts` `seedStatusFromExecution`, retired with its
|
|
368
380
|
* orchestrator) always carried, minus the fields above that it carried by
|
|
369
|
-
* accident
|
|
381
|
+
* accident. Until #1097 the transcript half was pushed straight
|
|
382
|
+
* onto the status here and the adapters constructed their builders after
|
|
383
|
+
* this ran — an ordering the builder's index depended on and nothing
|
|
384
|
+
* enforced; the seed through the builder makes it a non-question.
|
|
370
385
|
*/
|
|
371
|
-
export function seedFromPersistedStatus(
|
|
386
|
+
export function seedFromPersistedStatus(
|
|
387
|
+
status: AgentExecutionStatus,
|
|
388
|
+
transcript: TranscriptBuilder,
|
|
389
|
+
execution: AgentExecution,
|
|
390
|
+
): void {
|
|
372
391
|
const persisted = execution.status;
|
|
373
392
|
if (!persisted || persisted.messages.length === 0) return;
|
|
374
393
|
const seed = clone(AgentExecutionStatusSchema, persisted);
|
|
375
|
-
|
|
376
|
-
status.subAgentExecutions.push(...seed.subAgentExecutions);
|
|
377
|
-
status.artifacts.push(...seed.artifacts);
|
|
378
|
-
status.workspaceWriteBacks.push(...seed.workspaceWriteBacks);
|
|
379
|
-
for (const [id, todo] of Object.entries(seed.todos)) status.todos[id] = todo;
|
|
394
|
+
transcript.seed(seed);
|
|
380
395
|
if (seed.streamingUsage !== undefined) status.streamingUsage = seed.streamingUsage;
|
|
381
396
|
if (seed.recalledMemoriesReport !== undefined) status.recalledMemoriesReport = seed.recalledMemoriesReport;
|
|
382
397
|
if (seed.structuredOutput !== undefined) status.structuredOutput = seed.structuredOutput;
|
|
@@ -459,7 +474,7 @@ export async function provisionWorkspace(
|
|
|
459
474
|
|
|
460
475
|
const writeback = provision.provisionResults.length > 0
|
|
461
476
|
? new WriteBackCoordinator({
|
|
462
|
-
|
|
477
|
+
writeBacks: deps.transcript,
|
|
463
478
|
executionId: deps.input.executionId,
|
|
464
479
|
sessionId: args.sessionId,
|
|
465
480
|
githubToken: args.envVars.GITHUB_TOKEN ?? "",
|
|
@@ -550,7 +565,7 @@ export async function bindTelemetryBaggage(
|
|
|
550
565
|
*
|
|
551
566
|
* On a reinvocation, first seed the in-progress status from the persisted
|
|
552
567
|
* execution ({@link seedFromPersistedStatus}), BEFORE the harness's
|
|
553
|
-
*
|
|
568
|
+
* transcript builder wraps `status.messages`. Then the file-review reconcile (the
|
|
554
569
|
* dual-source half): every change set the server projected as DECIDED is
|
|
555
570
|
* reconciled from the ledger decisions and the pinned git refs (approved
|
|
556
571
|
* kept at their "after" bytes, rejected snapped back to baseline, all
|
|
@@ -583,7 +598,7 @@ export async function reconcileReinvocation(
|
|
|
583
598
|
|
|
584
599
|
if (reinvoked) {
|
|
585
600
|
const existingStatus = args.execution.status;
|
|
586
|
-
seedFromPersistedStatus(deps.status, args.execution);
|
|
601
|
+
seedFromPersistedStatus(deps.status, deps.transcript, args.execution);
|
|
587
602
|
|
|
588
603
|
if (args.workspace.captureMode && args.workspace.primaryDir) {
|
|
589
604
|
const decidedSets = (existingStatus?.fileChangeSets ?? []).filter(
|
|
@@ -782,10 +797,10 @@ export async function resolveMcpServersAndPolicies(
|
|
|
782
797
|
* its to render. One progress label for the whole phase, as before.
|
|
783
798
|
*
|
|
784
799
|
* The `.stigmer` link this and the attachment phase create is removed in
|
|
785
|
-
* the runtime's finally, after the harness's own teardown. Until
|
|
800
|
+
* the runtime's finally, after the harness's own teardown. Until #1096 the
|
|
786
801
|
* native orchestrator fetched and mounted sub-agent skills itself
|
|
787
802
|
* (`subagent-transformer.ts` with a client); this phase is where that read
|
|
788
|
-
* lives now
|
|
803
|
+
* lives now.
|
|
789
804
|
*/
|
|
790
805
|
export async function mountSkills(
|
|
791
806
|
deps: ResolutionDeps,
|
|
@@ -824,8 +839,8 @@ export async function mountSkills(
|
|
|
824
839
|
* actually see the image. Full model validation is not needed for this. The
|
|
825
840
|
* Cursor harness with no model named builds its own catalog default instead
|
|
826
841
|
* (`resolveModelId("default")`), so for it this is an approximation: today
|
|
827
|
-
* both answers read as sighted, and the exact per-harness default is
|
|
828
|
-
*
|
|
842
|
+
* both answers read as sighted, and the exact per-harness default is not yet
|
|
843
|
+
* declared. The vision profile is the harness's
|
|
829
844
|
* (each engine accepts different image shapes), so it arrives as an
|
|
830
845
|
* argument.
|
|
831
846
|
*/
|
|
@@ -878,9 +893,9 @@ export async function resolveTurnAttachments(
|
|
|
878
893
|
* re-attempts the call — both regenerate. An `interrupt` engine checkpoints
|
|
879
894
|
* AT the call and applies its exact args on `approve`, so a runner-side
|
|
880
895
|
* write would land the same bytes twice and pre-empt a row the engine is
|
|
881
|
-
* about to execute; `none` gates nothing. Until
|
|
896
|
+
* about to execute; `none` gates nothing. Until #1096 the phase ran for
|
|
882
897
|
* every harness — a deny-and-retry mechanism the native harness would have
|
|
883
|
-
* met on its first deny-gated file approval
|
|
898
|
+
* met on its first deny-gated file approval.
|
|
884
899
|
*/
|
|
885
900
|
export function regeneratesApprovedWrites(pausePrimitive: PausePrimitive): boolean {
|
|
886
901
|
switch (pausePrimitive) {
|
package/src/harness/types.ts
CHANGED
|
@@ -21,9 +21,8 @@
|
|
|
21
21
|
* (`execute-cursor/turn-stream.ts` `CursorTurnStreamDeps`) or a fact the
|
|
22
22
|
* runtime cannot read anywhere else. Nothing here is speculative: where the
|
|
23
23
|
* program's original sketch and the code disagreed, the code won, and the
|
|
24
|
-
* disagreement was ruled
|
|
25
|
-
*
|
|
26
|
-
* for S1; `20260911.03.sp.turn-runtime-extraction/` M3 for the growth below).
|
|
24
|
+
* disagreement was ruled before the code landed (#1064; the growth below in
|
|
25
|
+
* #1070).
|
|
27
26
|
*
|
|
28
27
|
* What is deliberately NOT on this contract, and why:
|
|
29
28
|
*
|
|
@@ -31,11 +30,13 @@
|
|
|
31
30
|
* (`maxConcurrentActivities`), so a per-turn teardown method on the
|
|
32
31
|
* adapter is a race. The adapter owns its per-turn teardown in its own
|
|
33
32
|
* `finally` inside `runTurn` (the Cursor harness parks its agent there).
|
|
34
|
-
* - No `isCancelled()`, no `heartbeat(details)`,
|
|
35
|
-
*
|
|
36
|
-
* `recordActivity()` or `requestPersist()` already
|
|
37
|
-
*
|
|
38
|
-
*
|
|
33
|
+
* - No `isCancelled()`, no `heartbeat(details)`, and the sink does not
|
|
34
|
+
* EXTEND a status-writer interface. Each would be a second way of saying
|
|
35
|
+
* something `stopSignal`, `recordActivity()` or `requestPersist()` already
|
|
36
|
+
* says, and two writers of one fact drift. The transcript builder rides
|
|
37
|
+
* the sink as a MEMBER (`transcript`), and the distinction holds: its
|
|
38
|
+
* `dirty` is a fact the adapter's persist decision reads, `requestPersist()`
|
|
39
|
+
* is the act; one fact, one act, no second writer.
|
|
39
40
|
* - No `reason` on `interrupted`, no payload on `completed`, no `retryable`
|
|
40
41
|
* on `failed`. Every cause of stopping is the runtime's own evidence; the
|
|
41
42
|
* final text and structured output are already folded onto the status;
|
|
@@ -53,9 +54,9 @@
|
|
|
53
54
|
* propagates it.
|
|
54
55
|
* - No persist cadence. The runtime's chokepoint is single-flight and
|
|
55
56
|
* unconditional at settle; WHEN a streaming turn asks for a write is the
|
|
56
|
-
* adapter's (`shared/persist-decision.ts` over
|
|
57
|
-
*
|
|
58
|
-
* both loops in view
|
|
57
|
+
* adapter's (`shared/persist-decision.ts` over the builder's `dirty`
|
|
58
|
+
* flag, since WHEN to ask is engine cadence). Revisited with
|
|
59
|
+
* both loops in view in #1096 and kept: the cadence RULE is
|
|
59
60
|
* shared, the timing is the engine's.
|
|
60
61
|
* - No capture. The file-review capture is the runtime's whole
|
|
61
62
|
* (`harness/capture.ts`): the baseline before `runTurn`, the candidate
|
|
@@ -90,6 +91,7 @@ import type { DeclaredPreferencesContent } from "../shared/declared-preferences.
|
|
|
90
91
|
import type { RecalledMemoriesContent } from "../shared/recalled-memories.js";
|
|
91
92
|
import type { CasTouchedReader } from "../shared/filereview/cas-touched.js";
|
|
92
93
|
import type { HarnessCapabilities } from "./capabilities.js";
|
|
94
|
+
import type { TranscriptBuilder } from "./transcript/builder.js";
|
|
93
95
|
|
|
94
96
|
/**
|
|
95
97
|
* One harness, as the runtime sees it. ONE adapter object exists per worker
|
|
@@ -325,14 +327,36 @@ export interface TurnInput extends NormalizedActivityInput {
|
|
|
325
327
|
* one status it folds into. One sink per turn, owned by the runtime; the
|
|
326
328
|
* adapter never constructs one.
|
|
327
329
|
*
|
|
328
|
-
* Field ownership on `status`
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
* `harness/
|
|
335
|
-
*
|
|
330
|
+
* Field ownership on `status` (since #1097, the canonical transcript):
|
|
331
|
+
*
|
|
332
|
+
* - Transcript rows — messages, tool-call rows, sub-agent rows, todos — are
|
|
333
|
+
* CREATED through `transcript` and nowhere else: the adapter translates
|
|
334
|
+
* its engine's events and applies them; a reinvocation's prior rows are
|
|
335
|
+
* seeded through it by the runtime. The one exception, the runtime's own
|
|
336
|
+
* terminal system rows (`harness/terminal-table.ts`), is the second name
|
|
337
|
+
* on the writer fence's allow-list (`__tests__/transcript-writers.test.ts`).
|
|
338
|
+
* - Artifacts and write-backs a turn produces register through `transcript`
|
|
339
|
+
* too (the native inline publisher; the runtime's write-back coordinator),
|
|
340
|
+
* each dedupe rule owned once. The one artifact written beside it is the
|
|
341
|
+
* epilogue's plan artifact (`shared/plan-artifact.ts`), the runtime's,
|
|
342
|
+
* which supersedes by the plan's own name rule.
|
|
343
|
+
* - Rows may be AMENDED by identity, never created, by the modules that own
|
|
344
|
+
* a fact the builder cannot know, and this is the whole list: the runtime's
|
|
345
|
+
* `harness/approval-decisions.ts` (a SKIP or REJECT settles its row),
|
|
346
|
+
* `harness/capture.ts` (the change-set stamp on a flowed edit row),
|
|
347
|
+
* `shared/exact-apply.ts` (an approved whole-file write applied by the
|
|
348
|
+
* runtime completes its row), `shared/subagent-rows.ts` (a stopped turn's
|
|
349
|
+
* sub-agents CANCELLED); the Cursor boundary (`execute-cursor/
|
|
350
|
+
* boundary-rows.ts`: the identity-token collapses, #205, #965, the
|
|
351
|
+
* unattended stamp); the native settle (`execute-deep-agent/hitl.ts`: the
|
|
352
|
+
* gate's unattended skips). A harness that amends says so in its settle's
|
|
353
|
+
* header.
|
|
354
|
+
* - The runtime alone writes the phase, `startedAt`, `completedAt`,
|
|
355
|
+
* `error`, the terminal system rows, `streamingUsage`,
|
|
356
|
+
* `fileChangeProgress`, the file-review ledger events and the change-set
|
|
357
|
+
* stamp (`harness/capture.ts`, since #1096), and closes every streaming flag
|
|
358
|
+
* once `runTurn` returns. An adapter never writes a phase or a terminal
|
|
359
|
+
* copy: those are Temporal semantics the runtime owns once.
|
|
336
360
|
*/
|
|
337
361
|
export interface TurnSink {
|
|
338
362
|
/**
|
|
@@ -342,6 +366,24 @@ export interface TurnSink {
|
|
|
342
366
|
*/
|
|
343
367
|
readonly status: AgentExecutionStatus;
|
|
344
368
|
|
|
369
|
+
/**
|
|
370
|
+
* The one transcript builder over `status`, constructed by the runtime
|
|
371
|
+
* per turn and already holding a reinvocation's seeded rows. The ONE way
|
|
372
|
+
* a transcript row is created: a harness translates its engine's events
|
|
373
|
+
* into `TranscriptEvent`s and `apply`s them; its post-stream facts (a
|
|
374
|
+
* gate parked by a boundary, a disclosure) go in as events too. Artifacts
|
|
375
|
+
* and write-backs a turn produces register here as well (`addArtifact`,
|
|
376
|
+
* `addWriteBack`, one dedupe rule each). Read `dirty` to decide a
|
|
377
|
+
* streaming persist and call `markPersisted()` as you request it; read
|
|
378
|
+
* `awaitingApproval` to learn a proposal was parked. The runtime calls
|
|
379
|
+
* `finalize()` once `runTurn` returns, on every path, so no streaming flag
|
|
380
|
+
* outlives a turn; a harness may call it earlier when it persists on the
|
|
381
|
+
* settled rows itself. A source-walking fence
|
|
382
|
+
* (`harness/__tests__/transcript-writers.test.ts`) refuses any other
|
|
383
|
+
* creator of a row.
|
|
384
|
+
*/
|
|
385
|
+
readonly transcript: TranscriptBuilder;
|
|
386
|
+
|
|
345
387
|
/**
|
|
346
388
|
* The ONE way a turn is told to stop, whatever the cause: user pause,
|
|
347
389
|
* worker shutdown, stall, cost cap, platform STOP. The runtime knows why
|
|
@@ -402,7 +444,7 @@ export interface TurnSink {
|
|
|
402
444
|
* step only the adapter knows ("Initializing Cursor agent"). The runtime
|
|
403
445
|
* reports its own resolution labels itself; the adapter reports the labels
|
|
404
446
|
* of its setup steps exactly as the orchestrator did, so the UI's spinner
|
|
405
|
-
* copy is unchanged by the extraction
|
|
447
|
+
* copy is unchanged by the extraction. Resolves once the label is
|
|
406
448
|
* written; the write carries no phase, so it never advances the execution.
|
|
407
449
|
*/
|
|
408
450
|
reportProgress(label: string): Promise<void>;
|
|
@@ -415,7 +457,7 @@ export interface TurnSink {
|
|
|
415
457
|
* cleared, the agnostic quirk of `BuildUpdateStateStep`); the adapter may
|
|
416
458
|
* set its own harness-specific `SessionSpec` fields on that record before
|
|
417
459
|
* binding, one writer per field (`harnessStateId` the runtime's,
|
|
418
|
-
* `cursorMode` the adapter's
|
|
460
|
+
* `cursorMode` the adapter's). Called only by adapters whose
|
|
419
461
|
* `capabilities.stateIdSource` is `"engine-minted"`, and before their first
|
|
420
462
|
* `requestPersist`; a `deterministic` harness never calls it. Rejects when
|
|
421
463
|
* the session write fails; the adapter then ends the turn `failed` with
|
|
@@ -448,7 +490,7 @@ export interface TurnSink {
|
|
|
448
490
|
* Token counts for one engine turn, priced. The four counts are what the
|
|
449
491
|
* Cursor loop reads from the SDK's `turn-ended` delta; `estimatedCostUsd` is
|
|
450
492
|
* the adapter's price for them at its vendor's rates (the runtime cannot
|
|
451
|
-
* price without the vendor's table and must not import it
|
|
493
|
+
* price without the vendor's table and must not import it), and
|
|
452
494
|
* `model` / `requestedModelParams` name the basis it priced against, which
|
|
453
495
|
* the runtime records into `streamingUsage` (`model` is the catalog-validated
|
|
454
496
|
* id, `requestedModelParams` the JSON of the params sent — a string on the
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* the persist chokepoint writes before every status write, and the running
|
|
5
5
|
* cost the `max_cost_usd` cap is enforced against.
|
|
6
6
|
*
|
|
7
|
-
* Who owns what
|
|
7
|
+
* Who owns what: the ADAPTER prices, because only it has its
|
|
8
8
|
* vendor's rate table and variant semantics (`execute-cursor/usage-pricing.ts`
|
|
9
9
|
* for Cursor); the RUNTIME accounts and enforces, because the cap and the
|
|
10
10
|
* summary are the platform's, the same for every engine. A delta therefore
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* preferences (`TurnInput.model`), the audit trail that the account default
|
|
15
15
|
* was never left in control (#357, #772).
|
|
16
16
|
*
|
|
17
|
-
* Moved from `activities/execute-cursor/usage-accumulator.ts`
|
|
17
|
+
* Moved from `activities/execute-cursor/usage-accumulator.ts` in #1070, the
|
|
18
18
|
* pricing call split out; the sums, the snapshot shape and the empty
|
|
19
19
|
* snapshot are unchanged, so `streamingUsage` is byte-for-byte what the
|
|
20
20
|
* Cursor orchestrator wrote.
|
package/src/harness-adapters.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* adapter's interceptors must patch `node:http2` before anything dials the
|
|
15
15
|
* control plane, so it boots first. The native deep-agent adapter boots
|
|
16
16
|
* second; its `boot` registers the deepagents harness profiles and loads
|
|
17
|
-
* LangChain, both after the patch (
|
|
17
|
+
* LangChain, both after the patch (#1096, 2026-09-13; until then the roots
|
|
18
18
|
* imported the native orchestrator directly beside this table).
|
|
19
19
|
*
|
|
20
20
|
* THIS MODULE'S STATIC GRAPH MUST STAY CONNECT- AND SDK-FREE. The roots
|
|
@@ -22,9 +22,10 @@
|
|
|
22
22
|
* where `node:http2` is patched and `@cursor/sdk` first loaded; an adapter
|
|
23
23
|
* factory that imported its SDK statically would defeat both. Every adapter
|
|
24
24
|
* named here loads its vendor SDK inside `boot` (`execute-cursor/adapter.ts`
|
|
25
|
-
* and `execute-deep-agent/adapter.ts` show the shape;
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* and `execute-deep-agent/adapter.ts` show the shape; the native adapter's
|
|
26
|
+
* `__tests__/adapter-graph-is-sdk-free.test.ts` walks its static graph off
|
|
27
|
+
* the syntax tree). `__tests__/harness-boot-order.test.ts` boots a fresh
|
|
28
|
+
* process through this module — both rows — and fails if either graph
|
|
28
29
|
* regresses.
|
|
29
30
|
*/
|
|
30
31
|
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* running total the sub-agent views share, and warns the model ONCE at the
|
|
4
4
|
* configured share of `max_cost_usd`. Nothing here caps: the enforcement is
|
|
5
5
|
* the turn runtime's (`shared/__tests__/cost-guard.test.ts`,
|
|
6
|
-
* `harness/__tests__/run-turn.test.ts`'s cost-cap arm). Until
|
|
6
|
+
* `harness/__tests__/run-turn.test.ts`'s cost-cap arm). Until #1096 this
|
|
7
7
|
* file was `cost-cap.test.ts` and also pinned the in-graph tool block and
|
|
8
|
-
* the "exceeded" message — retired with that half
|
|
8
|
+
* the "exceeded" message — retired with that half.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { describe, it, expect } from "vitest";
|
|
@@ -24,6 +24,12 @@
|
|
|
24
24
|
* unrecognized mutating built-in (e.g. `bash`, `overwrite_file`) is therefore
|
|
25
25
|
* gated by what it does, not by whether someone remembered to list it.
|
|
26
26
|
*
|
|
27
|
+
* The decision itself — `resolveToolApproval` — lives in
|
|
28
|
+
* `shared/approval-policy.ts` beside its provenance twin since #1097:
|
|
29
|
+
* the native translator reports the same answer on every
|
|
30
|
+
* `tool_started`, so the transcript row and this gate can never disagree
|
|
31
|
+
* about whether a call waits. This module is where the decision is ACTED on.
|
|
32
|
+
*
|
|
27
33
|
* Gateway invariant (Phase 2): this middleware IS the in-process execution
|
|
28
34
|
* gateway for the deep-agent harness — `handler(request)` is the side effect. A
|
|
29
35
|
* side effect runs only with a backing authorization: either (a) the tool was
|
|
@@ -50,7 +56,7 @@ import {
|
|
|
50
56
|
type MergedToolPolicy,
|
|
51
57
|
type PolicySource,
|
|
52
58
|
POLICY_ENGINE_VERSION,
|
|
53
|
-
|
|
59
|
+
resolveToolApproval,
|
|
54
60
|
unattendedSkipMessage,
|
|
55
61
|
} from "../shared/approval-policy.js";
|
|
56
62
|
import { toolApprovalCategory, type ToolApprovalCategory } from "../shared/tool-kind.js";
|
|
@@ -164,16 +170,6 @@ interface ApprovalDecision {
|
|
|
164
170
|
readonly comment?: string;
|
|
165
171
|
}
|
|
166
172
|
|
|
167
|
-
// Approval-message template per mutating category. Keyed by category (not raw
|
|
168
|
-
// tool name) so every alias of a mutation renders one message; placeholders
|
|
169
|
-
// resolve against the deep-agent stream arg shape (`path`/`command`). Mirrors
|
|
170
|
-
// the Cursor side's CATEGORY_APPROVAL_MESSAGE.
|
|
171
|
-
const CATEGORY_APPROVAL_MESSAGE: Record<ToolApprovalCategory, string> = {
|
|
172
|
-
write: "Write file: {{args.path}}",
|
|
173
|
-
delete: "Delete: {{args.path}}",
|
|
174
|
-
shell: "Execute command: {{args.command}}",
|
|
175
|
-
};
|
|
176
|
-
|
|
177
173
|
/**
|
|
178
174
|
* The ToolMessage returned when a secret-like write is hard-blocked (DD-E /
|
|
179
175
|
* DD-26 #2): the write is NEVER applied and the graph continues (this replaces
|
|
@@ -383,69 +379,6 @@ export function createApprovalGateMiddleware(
|
|
|
383
379
|
};
|
|
384
380
|
}
|
|
385
381
|
|
|
386
|
-
interface ApprovalRequirement {
|
|
387
|
-
readonly requiresApproval: boolean;
|
|
388
|
-
readonly message: string;
|
|
389
|
-
/** Which policy layer determined this verdict — stamped on the shadow receipt. */
|
|
390
|
-
readonly source: PolicySource;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
function resolveToolApproval(
|
|
394
|
-
toolName: string,
|
|
395
|
-
serverSlug: string,
|
|
396
|
-
args: Record<string, unknown>,
|
|
397
|
-
policies: ReadonlyMap<string, MergedToolPolicy>,
|
|
398
|
-
leasedCategories: ReadonlySet<ToolApprovalCategory>,
|
|
399
|
-
): ApprovalRequirement {
|
|
400
|
-
if (serverSlug) {
|
|
401
|
-
// MCP tools stay governed by the connect-flow classifier + four-level policy
|
|
402
|
-
// chain. The policy map carries only the tools that REQUIRE approval, so an
|
|
403
|
-
// absent entry means the classifier already auto-approved it — fail-OPEN is
|
|
404
|
-
// correct here (a fail-closed default would re-gate everything the classifier
|
|
405
|
-
// cleared). This is deliberately NOT changed by the built-in fail-closed flip.
|
|
406
|
-
//
|
|
407
|
-
// A server-scoped lease surfaces here as an absent entry too: the leased
|
|
408
|
-
// server's tools are dropped from `policies` upstream (mergeApprovalPolicies),
|
|
409
|
-
// so a lease-cleared MCP tool takes this same auto-approve path. (Its shadow
|
|
410
|
-
// receipt therefore reads classifier_default rather than approval_lease; a
|
|
411
|
-
// faithful per-server lease provenance would need the lease set threaded here
|
|
412
|
-
// and is deferred with the rest of the persisted-receipt work.)
|
|
413
|
-
const key = `${serverSlug}/${toolName}`;
|
|
414
|
-
const policy = policies.get(key);
|
|
415
|
-
if (policy) {
|
|
416
|
-
return {
|
|
417
|
-
requiresApproval: policy.requiresApproval,
|
|
418
|
-
message: resolveApprovalMessage(policy.approvalMessage, toolName, args),
|
|
419
|
-
source: policy.source,
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
// Absent = cleared by the MCP four-level chain (classifier base) or by a
|
|
423
|
-
// server-scoped lease (dropped upstream).
|
|
424
|
-
return { requiresApproval: false, message: "", source: "classifier_default" };
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// Built-in/platform tool: gate exactly the mutating categories via the shared
|
|
428
|
-
// classifier. Fail-CLOSED for the mutating set — any built-in classifyTool
|
|
429
|
-
// deems write/edit/delete/shell requires approval. Read-only and unclassified
|
|
430
|
-
// built-ins are not mutating, so they remain fail-open.
|
|
431
|
-
const category = toolApprovalCategory(toolName);
|
|
432
|
-
if (category) {
|
|
433
|
-
// Run-lifetime category lease: the user chose "approve all <category>"
|
|
434
|
-
// earlier in this run, so every built-in of that category is auto-approved
|
|
435
|
-
// for the rest of the run (the scoped successor to auto-approve-all).
|
|
436
|
-
if (leasedCategories.has(category)) {
|
|
437
|
-
return { requiresApproval: false, message: "", source: "approval_lease" };
|
|
438
|
-
}
|
|
439
|
-
return {
|
|
440
|
-
requiresApproval: true,
|
|
441
|
-
message: resolveApprovalMessage(CATEGORY_APPROVAL_MESSAGE[category], toolName, args),
|
|
442
|
-
source: "builtin_category",
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
return { requiresApproval: false, message: "", source: "builtin_category" };
|
|
447
|
-
}
|
|
448
|
-
|
|
449
382
|
/** Shared empty set so a config without leases allocates nothing per call. */
|
|
450
383
|
const EMPTY_CATEGORY_SET: ReadonlySet<ToolApprovalCategory> = new Set();
|
|
451
384
|
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
* shape `execution-budget.ts` already has beside LangGraph's `recursionLimit`:
|
|
12
12
|
* the middleware warns inside the graph, the engine's own limit enforces.
|
|
13
13
|
*
|
|
14
|
-
* Until
|
|
14
|
+
* Until #1096 this module was `cost-cap.ts` and did both: it also
|
|
15
15
|
* blocked every tool call once the running cost passed the cap and gave the
|
|
16
16
|
* model one tool-free round to summarize. That second enforcement lived
|
|
17
17
|
* inside the graph, where the runtime could not see it, and a platform STOP
|
|
18
18
|
* had a sibling (`graceful-stop.ts`, deleted with it) that let the run spend
|
|
19
19
|
* a summary round after the platform said stop. Both went when the runtime
|
|
20
|
-
* became the one place a turn is stopped
|
|
20
|
+
* became the one place a turn is stopped.
|
|
21
21
|
*
|
|
22
22
|
* afterModel — reads `usage_metadata` off the latest AIMessage, prices the
|
|
23
23
|
* call at the parent's rates (a sub-agent on its own model is priced the
|
|
24
|
-
* same way the enforcement prices it; per-sub-agent pricing is
|
|
24
|
+
* same way the enforcement prices it; per-sub-agent pricing is #1121),
|
|
25
25
|
* accumulates the running total, and injects the warning SystemMessage once
|
|
26
26
|
* at `warningPct` of the cap.
|
|
27
27
|
*
|
package/src/middleware/index.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* Every middleware here either shapes the graph's tool surface or ADVISES
|
|
22
22
|
* the model; none of them stops the run. A stop — the platform's, the
|
|
23
23
|
* cost cap's, a stall's — is the turn runtime's, delivered to the graph
|
|
24
|
-
* through its abort signal (
|
|
24
|
+
* through its abort signal (since #1096; until then a
|
|
25
25
|
* graceful-stop middleware and the cost cap's tool block were second stops
|
|
26
26
|
* inside the graph that the runtime could not see).
|
|
27
27
|
*
|
package/src/runner-manager.ts
CHANGED
|
@@ -701,7 +701,7 @@ export function mapManagerOptionsToConfig(
|
|
|
701
701
|
// The manager's proxy credential is the minted runner token once adopted
|
|
702
702
|
// (the control-plane token in lockstep before that), so it is this ref and
|
|
703
703
|
// not `tokenRef`: binding `tokenRef` would keep sending the desktop's own
|
|
704
|
-
// Auth0 token as x-stigmer-auth after the mint
|
|
704
|
+
// Auth0 token as x-stigmer-auth after the mint.
|
|
705
705
|
proxyTokenRef: runnerTokenRef,
|
|
706
706
|
cursorApiKey: proxyActive
|
|
707
707
|
? (options.cursorApiKey ?? "proxy-managed")
|