@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
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CursorTranslator — the Cursor harness's translator: the `@cursor/sdk`'s two
|
|
3
|
+
* event channels in, the canonical `TranscriptEvent` union out
|
|
4
|
+
* (`harness/transcript/events.ts`).
|
|
5
|
+
*
|
|
6
|
+
* The one module that knows the SDK's wire shape:
|
|
7
|
+
* the shared `TranscriptBuilder` folds what comes out of here and nothing of
|
|
8
|
+
* the engine reaches it otherwise. Until #1097 the Cursor harness folded its
|
|
9
|
+
* own transcript — the message accumulator (the second copy of the folding
|
|
10
|
+
* rule the memo counted), the delta enricher (row writes from the delta
|
|
11
|
+
* channel) and the todo tracker (a third writer of `status.todos`) — and
|
|
12
|
+
* every rule they held
|
|
13
|
+
* is either the builder's now or answered here. The same word, the same
|
|
14
|
+
* `translate(raw)` signature and the same seat in its adapter as
|
|
15
|
+
* `execute-deep-agent/translator.ts`, so a third harness's author finds one
|
|
16
|
+
* shape in both.
|
|
17
|
+
*
|
|
18
|
+
* TWO CHANNELS, ONE DISCIPLINE. The SDK streams `SDKMessage`s from
|
|
19
|
+
* `run.stream()` (the source of truth for messages and rows) and fires
|
|
20
|
+
* `InteractionUpdate`s through `onDelta` between them (tool-call timings, live
|
|
21
|
+
* shell output, a completion's status — facts the stream delivers later or
|
|
22
|
+
* never). A delta lands while the loop may be awaiting a persist, and a row
|
|
23
|
+
* write mid-persist would land on a row the offload is replacing, so this
|
|
24
|
+
* translator never hands a delta's events to anyone
|
|
25
|
+
* directly: {@link observeDelta} QUEUES them and the loop applies
|
|
26
|
+
* {@link drainDeltas} after each stream event, and once more before
|
|
27
|
+
* `finalize()`. A delta for a call the stream has not announced yet (the
|
|
28
|
+
* output that beats the `running` event) is HELD and replayed right after the
|
|
29
|
+
* `tool_started` that announces it. Because the fold is later than
|
|
30
|
+
* the observation, a completion learned from a delta carries `observedAt` —
|
|
31
|
+
* the instant the tool actually finished — and the builder stamps that, not
|
|
32
|
+
* the fold's moment. Rows are CREATED by the stream alone: the
|
|
33
|
+
* delta channel amends (output, completion), never announces.
|
|
34
|
+
*
|
|
35
|
+
* WHAT THIS TRANSLATOR ANSWERS, per event:
|
|
36
|
+
*
|
|
37
|
+
* - The MESSAGE BOUNDARY. Cursor has one `run_id` per `send()`,
|
|
38
|
+
* and its message boundary is a tool call: text after a tool call is a new
|
|
39
|
+
* message. So `runId` here is a minted SEGMENT id, `<run_id>:<n>`, advanced
|
|
40
|
+
* on the first text or thinking after a tool call; a tool call emits
|
|
41
|
+
* `message_finish` for the open segment (closing its text and thinking).
|
|
42
|
+
* - The row's IDENTITY. An MCP call arrives as `name: "mcp"` with the real
|
|
43
|
+
* tool packed in `args` (`{ providerIdentifier, toolName, args }`); the row
|
|
44
|
+
* is the inner tool. A resumed agent re-runs an approved tool under a
|
|
45
|
+
* BRAND-NEW call id; the seeded WAITING row it belongs to is found by the
|
|
46
|
+
* identity token the hook and the grants already share, the
|
|
47
|
+
* `tool_started` is emitted with the SEEDED id so the builder's by-id flip
|
|
48
|
+
* does the rest, and every later event for the new id is aliased onto it.
|
|
49
|
+
* The seeded rows that can match exist only in the seed (nothing created
|
|
50
|
+
* mid-stream is WAITING until the boundary runs), so they are indexed once
|
|
51
|
+
* at construction and consumed on match (a declined row is a
|
|
52
|
+
* closed gate and never matched).
|
|
53
|
+
* - The GATE and the PROVENANCE. `gate` is the POLICY's word —
|
|
54
|
+
* this MCP tool's merged policy, or this built-in's category, requires
|
|
55
|
+
* approval — resolved exactly as the accumulator did, lease- and
|
|
56
|
+
* bypass-blind; it is NOT the hook's verdict (the hook has arms this side
|
|
57
|
+
* cannot evaluate: capture mode, grants, bypass, secret blocks — the
|
|
58
|
+
* lesson behind dropping a parked-at-creation arm that had no producer).
|
|
59
|
+
* A gated call that STARTED runs until the boundary parks
|
|
60
|
+
* it through `approval_proposed`. Provenance is the shared read-side
|
|
61
|
+
* `resolveApprovalProvenance` over the same policies and the run's leases.
|
|
62
|
+
* - The RESULT string (`tool-result.ts`): a failure's text is its `error`
|
|
63
|
+
* alone.
|
|
64
|
+
* - The SUB-AGENT: a `task` tool call opens a sub-agent keyed by
|
|
65
|
+
* the call id (`sub_agent_started` before the row's own `tool_started`);
|
|
66
|
+
* its completion emits the row's `tool_finished`, the child's transcript
|
|
67
|
+
* as scoped events (`sub-agent-steps.ts` — Cursor delivers it whole, at
|
|
68
|
+
* completion), then `sub_agent_finished` with the same output string; an
|
|
69
|
+
* error, `tool_error` then `sub_agent_failed`.
|
|
70
|
+
* - The `task` SDK event → `system_note`; a todo write is an
|
|
71
|
+
* ordinary tool call the builder keys on `ToolKind.TODO` and projects;
|
|
72
|
+
* `system`, `status`, `user`, `request` and `usage` carry no
|
|
73
|
+
* transcript fact (usage is the loop's, priced from the `turn-ended`
|
|
74
|
+
* delta in `turn-stream.ts` — the same division as native's `usageOf`).
|
|
75
|
+
*
|
|
76
|
+
* Stateful, one per turn, shared by the primary stream and the recovery
|
|
77
|
+
* retries exactly as the accumulator was (the segment map is keyed by
|
|
78
|
+
* `run_id`, and a retry's send has its own).
|
|
79
|
+
*/
|
|
80
|
+
import type { InteractionUpdate, SDKMessage } from "@cursor/sdk";
|
|
81
|
+
import type { AgentMessage } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
82
|
+
import type { TranscriptEvent } from "../../harness/transcript/events.js";
|
|
83
|
+
import { type MergedToolPolicy } from "../../shared/approval-policy.js";
|
|
84
|
+
import type { ToolApprovalCategory } from "../../shared/tool-kind.js";
|
|
85
|
+
type ToolCallEvent = Extract<SDKMessage, {
|
|
86
|
+
type: "tool_call";
|
|
87
|
+
}>;
|
|
88
|
+
/** The run's approval posture the translator answers `gate` and `provenance` from. */
|
|
89
|
+
export interface CursorTranslatorOptions {
|
|
90
|
+
/** The merged four-level MCP policy map (`mergeApprovalPolicies`). */
|
|
91
|
+
readonly policies: ReadonlyMap<string, MergedToolPolicy>;
|
|
92
|
+
/** The run-lifetime leases: the pre-armed global bypass and the built-in categories approved for the run. */
|
|
93
|
+
readonly leases: {
|
|
94
|
+
readonly global: boolean;
|
|
95
|
+
readonly categories: ReadonlySet<ToolApprovalCategory>;
|
|
96
|
+
};
|
|
97
|
+
/** The transcript as seeded at turn start (`status.messages`): the WAITING rows a resumed agent's re-issued call may belong to. */
|
|
98
|
+
readonly seeded: readonly AgentMessage[];
|
|
99
|
+
}
|
|
100
|
+
export declare class CursorTranslator {
|
|
101
|
+
private readonly options;
|
|
102
|
+
private readonly segments;
|
|
103
|
+
/** Row ids the stream has announced (a `tool_started` was emitted for them). */
|
|
104
|
+
private readonly announced;
|
|
105
|
+
/** A resumed agent's fresh call id → the seeded row it re-runs. */
|
|
106
|
+
private readonly aliases;
|
|
107
|
+
/** Identity token → the seeded WAITING rows with it, in transcript order; consumed on match. */
|
|
108
|
+
private readonly resumable;
|
|
109
|
+
/** The `task` rows whose completion closes a sub-agent. */
|
|
110
|
+
private readonly taskCalls;
|
|
111
|
+
/** Delta-derived events for announced rows, awaiting the loop's drain. */
|
|
112
|
+
private queue;
|
|
113
|
+
/**
|
|
114
|
+
* Delta-derived events for calls the stream has not announced yet, keyed by
|
|
115
|
+
* the delta's own call id and kept as makers: the row they belong to is
|
|
116
|
+
* known only when the stream announces the call (a resumed agent's re-run
|
|
117
|
+
* is aliased onto a seeded row then), so each is materialized at replay.
|
|
118
|
+
*/
|
|
119
|
+
private readonly held;
|
|
120
|
+
/** The most recent shell call the delta channel started — the home of an output delta that names no call. */
|
|
121
|
+
private lastShellCallId;
|
|
122
|
+
constructor(options: CursorTranslatorOptions);
|
|
123
|
+
/** One stream event to its canonical events — `translate(raw)` is the one signature every harness's translator shares. */
|
|
124
|
+
translate(event: SDKMessage): TranscriptEvent[];
|
|
125
|
+
/**
|
|
126
|
+
* One delta, queued — never applied here (see the header). The loop drains
|
|
127
|
+
* the queue after the stream event it is processing.
|
|
128
|
+
*/
|
|
129
|
+
observeDelta(update: InteractionUpdate): void;
|
|
130
|
+
/** The delta-derived events ready to apply, in arrival order; empties the queue. */
|
|
131
|
+
drainDeltas(): TranscriptEvent[];
|
|
132
|
+
/** The segment id text or thinking streams into now, and the `message_start` that opens it if none is open. */
|
|
133
|
+
private openSegment;
|
|
134
|
+
/** A tool call ends the open segment: its text and thinking are finished, and the next text starts a new message. */
|
|
135
|
+
private closeSegment;
|
|
136
|
+
private segmentOf;
|
|
137
|
+
private translateToolCall;
|
|
138
|
+
/**
|
|
139
|
+
* The row a call's events fold into: the id the stream gave it, unless the
|
|
140
|
+
* call is a resumed agent's re-run of a seeded WAITING row (the same
|
|
141
|
+
* identity token), in which case the seeded id — aliased for every
|
|
142
|
+
* later event of this call.
|
|
143
|
+
*/
|
|
144
|
+
private resolveRowId;
|
|
145
|
+
private toolStarted;
|
|
146
|
+
/**
|
|
147
|
+
* The policy's word that this call requires approval, and the card's
|
|
148
|
+
* message — or nothing for an ungated call. An MCP call (the `mcp` envelope,
|
|
149
|
+
* whatever its provider field says) is governed by the merged policy map
|
|
150
|
+
* alone; a built-in by its category.
|
|
151
|
+
*/
|
|
152
|
+
private gateOf;
|
|
153
|
+
private rowIdOf;
|
|
154
|
+
private enqueue;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Details extracted from an MCP tool call event's args.
|
|
158
|
+
*
|
|
159
|
+
* When Cursor invokes an MCP tool, the SDK stream reports event.name as
|
|
160
|
+
* "mcp" and packs the real tool identity into event.args:
|
|
161
|
+
* { providerIdentifier: "planton", toolName: "search_services", args: {...} }
|
|
162
|
+
*/
|
|
163
|
+
export interface McpToolDetails {
|
|
164
|
+
providerIdentifier: string;
|
|
165
|
+
toolName: string;
|
|
166
|
+
innerArgs: Record<string, unknown>;
|
|
167
|
+
}
|
|
168
|
+
/** The MCP tool a `tool_call` event names, or undefined for a built-in. */
|
|
169
|
+
export declare function extractMcpToolDetails(event: ToolCallEvent): McpToolDetails | undefined;
|
|
170
|
+
/**
|
|
171
|
+
* The sub-agent's name from the task tool's args, in both the legacy string
|
|
172
|
+
* form (`"generalPurpose"`) and the SDK's object form
|
|
173
|
+
* (`{ kind: "generalPurpose", name?: "..." }`); `description` (always set by
|
|
174
|
+
* the SDK) before the generic `"task"`. The `kind` value `"unspecified"` is
|
|
175
|
+
* treated as absent — the SDK's default when the blueprint names no type.
|
|
176
|
+
*/
|
|
177
|
+
export declare function extractSubagentName(args: unknown): string;
|
|
178
|
+
export {};
|
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CursorTranslator — the Cursor harness's translator: the `@cursor/sdk`'s two
|
|
3
|
+
* event channels in, the canonical `TranscriptEvent` union out
|
|
4
|
+
* (`harness/transcript/events.ts`).
|
|
5
|
+
*
|
|
6
|
+
* The one module that knows the SDK's wire shape:
|
|
7
|
+
* the shared `TranscriptBuilder` folds what comes out of here and nothing of
|
|
8
|
+
* the engine reaches it otherwise. Until #1097 the Cursor harness folded its
|
|
9
|
+
* own transcript — the message accumulator (the second copy of the folding
|
|
10
|
+
* rule the memo counted), the delta enricher (row writes from the delta
|
|
11
|
+
* channel) and the todo tracker (a third writer of `status.todos`) — and
|
|
12
|
+
* every rule they held
|
|
13
|
+
* is either the builder's now or answered here. The same word, the same
|
|
14
|
+
* `translate(raw)` signature and the same seat in its adapter as
|
|
15
|
+
* `execute-deep-agent/translator.ts`, so a third harness's author finds one
|
|
16
|
+
* shape in both.
|
|
17
|
+
*
|
|
18
|
+
* TWO CHANNELS, ONE DISCIPLINE. The SDK streams `SDKMessage`s from
|
|
19
|
+
* `run.stream()` (the source of truth for messages and rows) and fires
|
|
20
|
+
* `InteractionUpdate`s through `onDelta` between them (tool-call timings, live
|
|
21
|
+
* shell output, a completion's status — facts the stream delivers later or
|
|
22
|
+
* never). A delta lands while the loop may be awaiting a persist, and a row
|
|
23
|
+
* write mid-persist would land on a row the offload is replacing, so this
|
|
24
|
+
* translator never hands a delta's events to anyone
|
|
25
|
+
* directly: {@link observeDelta} QUEUES them and the loop applies
|
|
26
|
+
* {@link drainDeltas} after each stream event, and once more before
|
|
27
|
+
* `finalize()`. A delta for a call the stream has not announced yet (the
|
|
28
|
+
* output that beats the `running` event) is HELD and replayed right after the
|
|
29
|
+
* `tool_started` that announces it. Because the fold is later than
|
|
30
|
+
* the observation, a completion learned from a delta carries `observedAt` —
|
|
31
|
+
* the instant the tool actually finished — and the builder stamps that, not
|
|
32
|
+
* the fold's moment. Rows are CREATED by the stream alone: the
|
|
33
|
+
* delta channel amends (output, completion), never announces.
|
|
34
|
+
*
|
|
35
|
+
* WHAT THIS TRANSLATOR ANSWERS, per event:
|
|
36
|
+
*
|
|
37
|
+
* - The MESSAGE BOUNDARY. Cursor has one `run_id` per `send()`,
|
|
38
|
+
* and its message boundary is a tool call: text after a tool call is a new
|
|
39
|
+
* message. So `runId` here is a minted SEGMENT id, `<run_id>:<n>`, advanced
|
|
40
|
+
* on the first text or thinking after a tool call; a tool call emits
|
|
41
|
+
* `message_finish` for the open segment (closing its text and thinking).
|
|
42
|
+
* - The row's IDENTITY. An MCP call arrives as `name: "mcp"` with the real
|
|
43
|
+
* tool packed in `args` (`{ providerIdentifier, toolName, args }`); the row
|
|
44
|
+
* is the inner tool. A resumed agent re-runs an approved tool under a
|
|
45
|
+
* BRAND-NEW call id; the seeded WAITING row it belongs to is found by the
|
|
46
|
+
* identity token the hook and the grants already share, the
|
|
47
|
+
* `tool_started` is emitted with the SEEDED id so the builder's by-id flip
|
|
48
|
+
* does the rest, and every later event for the new id is aliased onto it.
|
|
49
|
+
* The seeded rows that can match exist only in the seed (nothing created
|
|
50
|
+
* mid-stream is WAITING until the boundary runs), so they are indexed once
|
|
51
|
+
* at construction and consumed on match (a declined row is a
|
|
52
|
+
* closed gate and never matched).
|
|
53
|
+
* - The GATE and the PROVENANCE. `gate` is the POLICY's word —
|
|
54
|
+
* this MCP tool's merged policy, or this built-in's category, requires
|
|
55
|
+
* approval — resolved exactly as the accumulator did, lease- and
|
|
56
|
+
* bypass-blind; it is NOT the hook's verdict (the hook has arms this side
|
|
57
|
+
* cannot evaluate: capture mode, grants, bypass, secret blocks — the
|
|
58
|
+
* lesson behind dropping a parked-at-creation arm that had no producer).
|
|
59
|
+
* A gated call that STARTED runs until the boundary parks
|
|
60
|
+
* it through `approval_proposed`. Provenance is the shared read-side
|
|
61
|
+
* `resolveApprovalProvenance` over the same policies and the run's leases.
|
|
62
|
+
* - The RESULT string (`tool-result.ts`): a failure's text is its `error`
|
|
63
|
+
* alone.
|
|
64
|
+
* - The SUB-AGENT: a `task` tool call opens a sub-agent keyed by
|
|
65
|
+
* the call id (`sub_agent_started` before the row's own `tool_started`);
|
|
66
|
+
* its completion emits the row's `tool_finished`, the child's transcript
|
|
67
|
+
* as scoped events (`sub-agent-steps.ts` — Cursor delivers it whole, at
|
|
68
|
+
* completion), then `sub_agent_finished` with the same output string; an
|
|
69
|
+
* error, `tool_error` then `sub_agent_failed`.
|
|
70
|
+
* - The `task` SDK event → `system_note`; a todo write is an
|
|
71
|
+
* ordinary tool call the builder keys on `ToolKind.TODO` and projects;
|
|
72
|
+
* `system`, `status`, `user`, `request` and `usage` carry no
|
|
73
|
+
* transcript fact (usage is the loop's, priced from the `turn-ended`
|
|
74
|
+
* delta in `turn-stream.ts` — the same division as native's `usageOf`).
|
|
75
|
+
*
|
|
76
|
+
* Stateful, one per turn, shared by the primary stream and the recovery
|
|
77
|
+
* retries exactly as the accumulator was (the segment map is keyed by
|
|
78
|
+
* `run_id`, and a retry's send has its own).
|
|
79
|
+
*/
|
|
80
|
+
import { ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
81
|
+
import { resolveApprovalProvenance } from "../../shared/approval-policy.js";
|
|
82
|
+
import { utcTimestamp } from "../../shared/status.js";
|
|
83
|
+
import { isDeclinedRow } from "../../shared/tool-row.js";
|
|
84
|
+
import { builtInRequiresApproval, getBuiltInApprovalMessage, lookupMcpToolPolicy, resolveApprovalMessage } from "./approval-policy.js";
|
|
85
|
+
import { toolCallIdentityToken, toolIdentity, primaryToken } from "./approval-state.js";
|
|
86
|
+
import { contentDigest } from "../../shared/file-tools.js";
|
|
87
|
+
import { subAgentStepEvents } from "./sub-agent-steps.js";
|
|
88
|
+
import { toResultString } from "./tool-result.js";
|
|
89
|
+
/** The delegation tool: the one tool name this translator knows, because its start opens a sub-agent. */
|
|
90
|
+
const TASK_TOOL = "task";
|
|
91
|
+
// ── The translator ────────────────────────────────────────────────
|
|
92
|
+
export class CursorTranslator {
|
|
93
|
+
options;
|
|
94
|
+
segments = new Map();
|
|
95
|
+
/** Row ids the stream has announced (a `tool_started` was emitted for them). */
|
|
96
|
+
announced = new Set();
|
|
97
|
+
/** A resumed agent's fresh call id → the seeded row it re-runs. */
|
|
98
|
+
aliases = new Map();
|
|
99
|
+
/** Identity token → the seeded WAITING rows with it, in transcript order; consumed on match. */
|
|
100
|
+
resumable = new Map();
|
|
101
|
+
/** The `task` rows whose completion closes a sub-agent. */
|
|
102
|
+
taskCalls = new Set();
|
|
103
|
+
/** Delta-derived events for announced rows, awaiting the loop's drain. */
|
|
104
|
+
queue = [];
|
|
105
|
+
/**
|
|
106
|
+
* Delta-derived events for calls the stream has not announced yet, keyed by
|
|
107
|
+
* the delta's own call id and kept as makers: the row they belong to is
|
|
108
|
+
* known only when the stream announces the call (a resumed agent's re-run
|
|
109
|
+
* is aliased onto a seeded row then), so each is materialized at replay.
|
|
110
|
+
*/
|
|
111
|
+
held = new Map();
|
|
112
|
+
/** The most recent shell call the delta channel started — the home of an output delta that names no call. */
|
|
113
|
+
lastShellCallId;
|
|
114
|
+
constructor(options) {
|
|
115
|
+
this.options = options;
|
|
116
|
+
for (const message of options.seeded) {
|
|
117
|
+
for (const tc of message.toolCalls) {
|
|
118
|
+
if (tc.status !== ToolCallStatus.TOOL_CALL_WAITING_APPROVAL || isDeclinedRow(tc))
|
|
119
|
+
continue;
|
|
120
|
+
const token = toolCallIdentityToken(tc);
|
|
121
|
+
const ids = this.resumable.get(token);
|
|
122
|
+
if (ids)
|
|
123
|
+
ids.push(tc.id);
|
|
124
|
+
else
|
|
125
|
+
this.resumable.set(token, [tc.id]);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/** One stream event to its canonical events — `translate(raw)` is the one signature every harness's translator shares. */
|
|
130
|
+
translate(event) {
|
|
131
|
+
switch (event.type) {
|
|
132
|
+
case "assistant": {
|
|
133
|
+
const text = event.message.content
|
|
134
|
+
.filter((b) => b.type === "text")
|
|
135
|
+
.map((b) => b.text)
|
|
136
|
+
.join("");
|
|
137
|
+
if (!text)
|
|
138
|
+
return [];
|
|
139
|
+
const { runId, opened } = this.openSegment(event.run_id);
|
|
140
|
+
return [...opened, { kind: "text_delta", runId, text }];
|
|
141
|
+
}
|
|
142
|
+
case "thinking": {
|
|
143
|
+
if (!event.text)
|
|
144
|
+
return [];
|
|
145
|
+
const { runId, opened } = this.openSegment(event.run_id);
|
|
146
|
+
return [...opened, { kind: "reasoning_delta", runId, text: event.text }];
|
|
147
|
+
}
|
|
148
|
+
case "tool_call":
|
|
149
|
+
return this.translateToolCall(event);
|
|
150
|
+
case "task":
|
|
151
|
+
return event.text ? [{ kind: "system_note", text: event.text }] : [];
|
|
152
|
+
// Carried by the wire, not by the transcript (see the header).
|
|
153
|
+
case "system":
|
|
154
|
+
case "status":
|
|
155
|
+
case "user":
|
|
156
|
+
case "request":
|
|
157
|
+
case "usage":
|
|
158
|
+
return [];
|
|
159
|
+
default: {
|
|
160
|
+
const exhaustive = event;
|
|
161
|
+
throw new Error(`CursorTranslator: unknown SDK message ${String(exhaustive.type)}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* One delta, queued — never applied here (see the header). The loop drains
|
|
167
|
+
* the queue after the stream event it is processing.
|
|
168
|
+
*/
|
|
169
|
+
observeDelta(update) {
|
|
170
|
+
switch (update.type) {
|
|
171
|
+
case "tool-call-started":
|
|
172
|
+
// The row's `startedAt` is the stream's (every row has one from its
|
|
173
|
+
// first stream event); the delta only tells us which shell an
|
|
174
|
+
// output delta that names no call belongs to.
|
|
175
|
+
if (update.toolCall.type === "shell")
|
|
176
|
+
this.lastShellCallId = update.callId;
|
|
177
|
+
return;
|
|
178
|
+
case "shell-output-delta": {
|
|
179
|
+
// Right by the SDK's type and exercised by the scripted double; the
|
|
180
|
+
// live run behind #1097 (SDK 1.0.31) sent no `shell-output-delta` for
|
|
181
|
+
// a 1.2 s or a 4 s command, so until the SDK sends one this arm has
|
|
182
|
+
// no live evidence of its own.
|
|
183
|
+
const text = shellOutputText(update.event);
|
|
184
|
+
const callId = shellOutputCallId(update.event) ?? this.lastShellCallId;
|
|
185
|
+
if (!text || !callId)
|
|
186
|
+
return;
|
|
187
|
+
this.enqueue(callId, (rowId) => ({ kind: "tool_output_delta", callId: rowId, delta: text }));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
case "tool-call-completed": {
|
|
191
|
+
// The completion, at the instant it was observed, with the
|
|
192
|
+
// OUTCOME the typed delta carries (since #1097): a `result.status`
|
|
193
|
+
// of `error` is a failure, not a completion — until then the enricher
|
|
194
|
+
// promoted every completion delta to COMPLETED, and a tool that failed
|
|
195
|
+
// ended COMPLETED carrying an `error` when the delta beat the stream's
|
|
196
|
+
// own `error` event. The stream's event follows with the text or the
|
|
197
|
+
// result, and the builder's upsert merges the two; an
|
|
198
|
+
// empty message or result never clears anything.
|
|
199
|
+
const observedAt = utcTimestamp();
|
|
200
|
+
const failed = completionFailed(update.toolCall);
|
|
201
|
+
this.enqueue(update.callId, (rowId) => failed
|
|
202
|
+
? { kind: "tool_error", callId: rowId, message: "", observedAt }
|
|
203
|
+
: { kind: "tool_finished", callId: rowId, result: "", observedAt });
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
default:
|
|
207
|
+
// `turn-ended` (the loop prices it), `text-delta`/`thinking-delta` (the
|
|
208
|
+
// stream carries the text), `thinking-completed`, the step and summary
|
|
209
|
+
// markers, `partial-tool-call`: no transcript fact.
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/** The delta-derived events ready to apply, in arrival order; empties the queue. */
|
|
214
|
+
drainDeltas() {
|
|
215
|
+
const out = this.queue;
|
|
216
|
+
this.queue = [];
|
|
217
|
+
return out;
|
|
218
|
+
}
|
|
219
|
+
// ── Messages ────────────────────────────────────────────────────
|
|
220
|
+
/** The segment id text or thinking streams into now, and the `message_start` that opens it if none is open. */
|
|
221
|
+
openSegment(runId) {
|
|
222
|
+
const segment = this.segmentOf(runId);
|
|
223
|
+
if (segment.advance) {
|
|
224
|
+
segment.n += 1;
|
|
225
|
+
segment.advance = false;
|
|
226
|
+
}
|
|
227
|
+
const id = segmentId(runId, segment.n);
|
|
228
|
+
if (segment.open)
|
|
229
|
+
return { runId: id, opened: [] };
|
|
230
|
+
segment.open = true;
|
|
231
|
+
return { runId: id, opened: [{ kind: "message_start", runId: id }] };
|
|
232
|
+
}
|
|
233
|
+
/** A tool call ends the open segment: its text and thinking are finished, and the next text starts a new message. */
|
|
234
|
+
closeSegment(runId) {
|
|
235
|
+
const segment = this.segmentOf(runId);
|
|
236
|
+
segment.advance = true;
|
|
237
|
+
if (!segment.open)
|
|
238
|
+
return [];
|
|
239
|
+
segment.open = false;
|
|
240
|
+
return [{ kind: "message_finish", runId: segmentId(runId, segment.n) }];
|
|
241
|
+
}
|
|
242
|
+
segmentOf(runId) {
|
|
243
|
+
let segment = this.segments.get(runId);
|
|
244
|
+
if (!segment) {
|
|
245
|
+
segment = { n: 0, open: false, advance: false };
|
|
246
|
+
this.segments.set(runId, segment);
|
|
247
|
+
}
|
|
248
|
+
return segment;
|
|
249
|
+
}
|
|
250
|
+
// ── Tool calls ──────────────────────────────────────────────────
|
|
251
|
+
translateToolCall(event) {
|
|
252
|
+
const out = this.closeSegment(event.run_id);
|
|
253
|
+
const mcp = extractMcpToolDetails(event);
|
|
254
|
+
const name = mcp?.toolName ?? event.name;
|
|
255
|
+
const mcpServerSlug = mcp?.providerIdentifier ?? "";
|
|
256
|
+
const input = mcp?.innerArgs ?? parseArgs(event.args);
|
|
257
|
+
const rowId = this.resolveRowId(event.call_id, name, mcpServerSlug, input);
|
|
258
|
+
const isTask = event.name === TASK_TOOL;
|
|
259
|
+
if (!this.announced.has(rowId)) {
|
|
260
|
+
if (isTask) {
|
|
261
|
+
this.taskCalls.add(rowId);
|
|
262
|
+
out.push({
|
|
263
|
+
kind: "sub_agent_started",
|
|
264
|
+
subAgentId: rowId,
|
|
265
|
+
name: extractSubagentName(event.args),
|
|
266
|
+
subject: stringArg(event.args, "description"),
|
|
267
|
+
input: stringArg(event.args, "prompt"),
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
this.announced.add(rowId);
|
|
271
|
+
}
|
|
272
|
+
out.push(this.toolStarted(rowId, name, mcp !== undefined, mcpServerSlug, input));
|
|
273
|
+
// Deltas that arrived before the stream announced this call follow its
|
|
274
|
+
// start, targeted at the row it resolved to.
|
|
275
|
+
const heldMakers = this.held.get(event.call_id);
|
|
276
|
+
if (heldMakers) {
|
|
277
|
+
this.held.delete(event.call_id);
|
|
278
|
+
for (const make of heldMakers)
|
|
279
|
+
this.queue.push(make(rowId));
|
|
280
|
+
}
|
|
281
|
+
switch (event.status) {
|
|
282
|
+
case "running":
|
|
283
|
+
break;
|
|
284
|
+
case "completed": {
|
|
285
|
+
const result = toResultString(event.result);
|
|
286
|
+
out.push({ kind: "tool_finished", callId: rowId, result });
|
|
287
|
+
if (this.taskCalls.has(rowId)) {
|
|
288
|
+
out.push(...subAgentStepEvents(event.result, rowId));
|
|
289
|
+
out.push({ kind: "sub_agent_finished", subAgentId: rowId, output: result });
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
case "error": {
|
|
294
|
+
const message = typeof event.result === "string" ? event.result : "Tool call failed";
|
|
295
|
+
out.push({ kind: "tool_error", callId: rowId, message });
|
|
296
|
+
if (this.taskCalls.has(rowId)) {
|
|
297
|
+
out.push({ kind: "sub_agent_failed", subAgentId: rowId, error: message });
|
|
298
|
+
}
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
default: {
|
|
302
|
+
const exhaustive = event.status;
|
|
303
|
+
throw new Error(`CursorTranslator: unknown tool_call status ${String(exhaustive)}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return out;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* The row a call's events fold into: the id the stream gave it, unless the
|
|
310
|
+
* call is a resumed agent's re-run of a seeded WAITING row (the same
|
|
311
|
+
* identity token), in which case the seeded id — aliased for every
|
|
312
|
+
* later event of this call.
|
|
313
|
+
*/
|
|
314
|
+
resolveRowId(callId, name, mcpServerSlug, input) {
|
|
315
|
+
const known = this.aliases.get(callId);
|
|
316
|
+
if (known)
|
|
317
|
+
return known;
|
|
318
|
+
if (this.announced.has(callId))
|
|
319
|
+
return callId;
|
|
320
|
+
const identity = toolIdentity(name, mcpServerSlug, input);
|
|
321
|
+
const token = primaryToken(identity.key, identity.salient, contentDigest(input));
|
|
322
|
+
const candidates = this.resumable.get(token);
|
|
323
|
+
const seededId = candidates?.shift();
|
|
324
|
+
if (seededId === undefined)
|
|
325
|
+
return callId;
|
|
326
|
+
this.aliases.set(callId, seededId);
|
|
327
|
+
return seededId;
|
|
328
|
+
}
|
|
329
|
+
toolStarted(callId, name, isMcp, mcpServerSlug, input) {
|
|
330
|
+
const { policies, leases } = this.options;
|
|
331
|
+
const provenance = resolveApprovalProvenance(name, mcpServerSlug, policies, leases.categories, leases.global);
|
|
332
|
+
const gate = this.gateOf(name, isMcp, mcpServerSlug, input);
|
|
333
|
+
return {
|
|
334
|
+
kind: "tool_started",
|
|
335
|
+
callId,
|
|
336
|
+
name,
|
|
337
|
+
input,
|
|
338
|
+
mcpServerSlug,
|
|
339
|
+
...(provenance !== undefined ? { provenance } : {}),
|
|
340
|
+
...(gate !== undefined ? { gate } : {}),
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* The policy's word that this call requires approval, and the card's
|
|
345
|
+
* message — or nothing for an ungated call. An MCP call (the `mcp` envelope,
|
|
346
|
+
* whatever its provider field says) is governed by the merged policy map
|
|
347
|
+
* alone; a built-in by its category.
|
|
348
|
+
*/
|
|
349
|
+
gateOf(name, isMcp, mcpServerSlug, input) {
|
|
350
|
+
if (isMcp) {
|
|
351
|
+
const policy = lookupMcpToolPolicy(name, mcpServerSlug, this.options.policies);
|
|
352
|
+
return policy ? { message: resolveApprovalMessage(policy.approvalMessage, name, input) } : undefined;
|
|
353
|
+
}
|
|
354
|
+
if (!builtInRequiresApproval(name))
|
|
355
|
+
return undefined;
|
|
356
|
+
const template = getBuiltInApprovalMessage(name);
|
|
357
|
+
return template ? { message: resolveApprovalMessage(template, name, input) } : undefined;
|
|
358
|
+
}
|
|
359
|
+
// ── The delta queue ─────────────────────────────────────────────
|
|
360
|
+
rowIdOf(callId) {
|
|
361
|
+
return this.aliases.get(callId) ?? callId;
|
|
362
|
+
}
|
|
363
|
+
enqueue(callId, make) {
|
|
364
|
+
const rowId = this.rowIdOf(callId);
|
|
365
|
+
if (this.announced.has(rowId)) {
|
|
366
|
+
this.queue.push(make(rowId));
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const pending = this.held.get(callId);
|
|
370
|
+
if (pending)
|
|
371
|
+
pending.push(make);
|
|
372
|
+
else
|
|
373
|
+
this.held.set(callId, [make]);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function segmentId(runId, n) {
|
|
377
|
+
return `${runId}:${n}`;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Whether a `tool-call-completed` delta reports a FAILURE. Every tool family in
|
|
381
|
+
* the SDK's discriminated union carries `result?: { status: "success" | "error", … }`
|
|
382
|
+
* for the outcome; read structurally so a family the SDK adds is judged the
|
|
383
|
+
* same way, and an absent result (a tool that reports nothing) is a success.
|
|
384
|
+
*/
|
|
385
|
+
function completionFailed(toolCall) {
|
|
386
|
+
const result = toolCall.result;
|
|
387
|
+
return typeof result === "object" && result !== null && result.status === "error";
|
|
388
|
+
}
|
|
389
|
+
/** The MCP tool a `tool_call` event names, or undefined for a built-in. */
|
|
390
|
+
export function extractMcpToolDetails(event) {
|
|
391
|
+
if (event.name !== "mcp")
|
|
392
|
+
return undefined;
|
|
393
|
+
const args = event.args;
|
|
394
|
+
if (args == null || typeof args !== "object")
|
|
395
|
+
return undefined;
|
|
396
|
+
const obj = args;
|
|
397
|
+
const providerIdentifier = typeof obj.providerIdentifier === "string" ? obj.providerIdentifier : "";
|
|
398
|
+
const toolName = typeof obj.toolName === "string" ? obj.toolName : "";
|
|
399
|
+
if (!toolName)
|
|
400
|
+
return undefined;
|
|
401
|
+
const innerArgs = (typeof obj.args === "object" && obj.args !== null)
|
|
402
|
+
? obj.args
|
|
403
|
+
: {};
|
|
404
|
+
return { providerIdentifier, toolName, innerArgs };
|
|
405
|
+
}
|
|
406
|
+
// ── Args ──────────────────────────────────────────────────────────
|
|
407
|
+
/**
|
|
408
|
+
* A `tool_call` event's `args` as the row's input: the object as it came, a
|
|
409
|
+
* JSON string parsed when it parses (a truncated one does not — the SDK marks
|
|
410
|
+
* `truncated.args`), anything else nothing.
|
|
411
|
+
*/
|
|
412
|
+
function parseArgs(raw) {
|
|
413
|
+
if (raw != null && typeof raw === "object" && !Array.isArray(raw))
|
|
414
|
+
return raw;
|
|
415
|
+
if (typeof raw === "string") {
|
|
416
|
+
try {
|
|
417
|
+
const parsed = JSON.parse(raw);
|
|
418
|
+
if (parsed != null && typeof parsed === "object" && !Array.isArray(parsed))
|
|
419
|
+
return parsed;
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
// Not JSON (or cut short by the SDK's truncation): the row has no args.
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return {};
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* The sub-agent's name from the task tool's args, in both the legacy string
|
|
429
|
+
* form (`"generalPurpose"`) and the SDK's object form
|
|
430
|
+
* (`{ kind: "generalPurpose", name?: "..." }`); `description` (always set by
|
|
431
|
+
* the SDK) before the generic `"task"`. The `kind` value `"unspecified"` is
|
|
432
|
+
* treated as absent — the SDK's default when the blueprint names no type.
|
|
433
|
+
*/
|
|
434
|
+
export function extractSubagentName(args) {
|
|
435
|
+
if (args == null || typeof args !== "object")
|
|
436
|
+
return TASK_TOOL;
|
|
437
|
+
const obj = args;
|
|
438
|
+
const subagentType = obj.subagentType ?? obj.subagent_type;
|
|
439
|
+
if (typeof subagentType === "string" && subagentType)
|
|
440
|
+
return subagentType;
|
|
441
|
+
if (subagentType != null && typeof subagentType === "object") {
|
|
442
|
+
const typed = subagentType;
|
|
443
|
+
if (typeof typed.name === "string" && typed.name)
|
|
444
|
+
return typed.name;
|
|
445
|
+
if (typeof typed.kind === "string" && typed.kind && typed.kind !== "unspecified") {
|
|
446
|
+
return typed.kind;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (typeof obj.description === "string" && obj.description)
|
|
450
|
+
return obj.description;
|
|
451
|
+
return TASK_TOOL;
|
|
452
|
+
}
|
|
453
|
+
function stringArg(args, key) {
|
|
454
|
+
if (args != null && typeof args === "object" && key in args) {
|
|
455
|
+
const val = args[key];
|
|
456
|
+
return typeof val === "string" ? val : "";
|
|
457
|
+
}
|
|
458
|
+
return "";
|
|
459
|
+
}
|
|
460
|
+
// ── The shell-output delta's payload ──────────────────────────────
|
|
461
|
+
/**
|
|
462
|
+
* The SDK's `shell-output-delta` carries a generic `Record<string, unknown>`;
|
|
463
|
+
* observed payloads are `{ type: "stdout" | "stderr", data }`, sometimes
|
|
464
|
+
* `{ output }`. Read defensively.
|
|
465
|
+
*/
|
|
466
|
+
function shellOutputText(event) {
|
|
467
|
+
if (typeof event.data === "string")
|
|
468
|
+
return event.data;
|
|
469
|
+
if (typeof event.output === "string")
|
|
470
|
+
return event.output;
|
|
471
|
+
if (typeof event.text === "string")
|
|
472
|
+
return event.text;
|
|
473
|
+
return "";
|
|
474
|
+
}
|
|
475
|
+
/** The call an output delta names, when it names one (`{ callId, type, data }` observed). */
|
|
476
|
+
function shellOutputCallId(event) {
|
|
477
|
+
if (typeof event.callId === "string")
|
|
478
|
+
return event.callId;
|
|
479
|
+
if (typeof event.call_id === "string")
|
|
480
|
+
return event.call_id;
|
|
481
|
+
if (typeof event.id === "string")
|
|
482
|
+
return event.id;
|
|
483
|
+
return undefined;
|
|
484
|
+
}
|
|
485
|
+
//# sourceMappingURL=translator.js.map
|