@stigmer/runner 3.15.3-dev.20260914121148 → 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- 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 +2 -2
- 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 +47 -12
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +41 -10
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +15 -6
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +17 -4
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +4 -4
- package/dist/activities/execute-cursor/adapter.js +4 -4
- 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/service-tier.js +1 -2
- package/dist/activities/execute-cursor/service-tier.js.map +1 -1
- 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/activities/generate-session-subject.d.ts +25 -4
- package/dist/activities/generate-session-subject.js +17 -7
- package/dist/activities/generate-session-subject.js.map +1 -1
- package/dist/client/stigmer-client.d.ts +17 -6
- package/dist/client/stigmer-client.js +47 -14
- package/dist/client/stigmer-client.js.map +1 -1
- package/dist/config.d.ts +6 -3
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- 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/interceptors/run-credential-activity.d.ts +28 -0
- package/dist/interceptors/run-credential-activity.js +56 -0
- package/dist/interceptors/run-credential-activity.js.map +1 -0
- 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 +10 -4
- package/dist/runner-manager.js.map +1 -1
- package/dist/shared/activity-input.d.ts +9 -0
- package/dist/shared/activity-input.js +17 -0
- package/dist/shared/activity-input.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-zip.d.ts +2 -2
- package/dist/shared/attachment-zip.js +2 -2
- package/dist/shared/channel-attachment.d.ts +8 -5
- package/dist/shared/channel-attachment.js +10 -6
- package/dist/shared/channel-attachment.js.map +1 -1
- 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/filereview/progress.d.ts +13 -0
- package/dist/shared/filereview/progress.js +13 -0
- package/dist/shared/filereview/progress.js.map +1 -1
- 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/memory-attachment.d.ts +16 -9
- package/dist/shared/memory-attachment.js +18 -10
- package/dist/shared/memory-attachment.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/run-credential-store.d.ts +32 -0
- package/dist/shared/run-credential-store.js +39 -0
- package/dist/shared/run-credential-store.js.map +1 -0
- package/dist/shared/run-credential.d.ts +61 -0
- package/dist/shared/run-credential.js +68 -0
- package/dist/shared/run-credential.js.map +1 -0
- 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/synthesized-attachment.d.ts +30 -3
- package/dist/shared/synthesized-attachment.js +26 -0
- package/dist/shared/synthesized-attachment.js.map +1 -1
- 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/dist/worker.js +10 -3
- package/dist/worker.js.map +1 -1
- package/dist/workflow-source.d.ts +10 -0
- package/dist/workflow-source.js +12 -0
- package/dist/workflow-source.js.map +1 -1
- package/dist/workflows/execute-from-execution.d.ts +15 -0
- package/dist/workflows/execute-from-execution.js +11 -0
- package/dist/workflows/execute-from-execution.js.map +1 -1
- package/dist/workflows/index.d.ts +5 -3
- package/dist/workflows/index.js +5 -3
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/interceptors/run-credential.d.ts +34 -0
- package/dist/workflows/interceptors/run-credential.js +71 -0
- package/dist/workflows/interceptors/run-credential.js.map +1 -0
- package/package.json +4 -4
- 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__/run-credential-e2e.test.ts +233 -0
- package/src/__tests__/run-credential-registration.test.ts +80 -0
- package/src/__tests__/runner-manager.test.ts +1 -1
- package/src/activities/__tests__/generate-session-subject-wire.test.ts +119 -0
- package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +1 -1
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +2 -2
- 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 +67 -17
- package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +19 -5
- 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-event-recorder.test.ts +142 -0
- package/src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts +19 -8
- package/src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts +10 -8
- 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 +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -1
- 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 +7 -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 +5 -5
- package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +2 -1
- 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 +8 -8
- 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 +1 -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 +3 -3
- 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 +13 -1
- package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +2 -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__/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 +4 -4
- 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/service-tier.ts +1 -2
- 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/activities/generate-session-subject.ts +29 -4
- package/src/client/__tests__/stigmer-client.test.ts +92 -0
- package/src/client/stigmer-client.ts +48 -14
- package/src/config.ts +6 -3
- 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/interceptors/__tests__/run-credential-activity.test.ts +133 -0
- package/src/interceptors/run-credential-activity.ts +67 -0
- 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 +14 -4
- 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__/channel-attachment.test.ts +12 -0
- package/src/shared/__tests__/cost-guard.test.ts +1 -1
- package/src/shared/__tests__/exact-apply.test.ts +2 -1
- package/src/shared/__tests__/memory-attachment.test.ts +17 -0
- package/src/shared/__tests__/persist-decision.test.ts +19 -33
- package/src/shared/__tests__/prompt-sections.test.ts +1 -1
- package/src/shared/__tests__/run-credential.test.ts +111 -0
- 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/activity-input.ts +21 -0
- 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-zip.ts +2 -2
- package/src/shared/channel-attachment.ts +14 -6
- 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/filereview/progress.ts +13 -0
- package/src/shared/heartbeat.ts +1 -1
- package/src/shared/llm-backend.ts +0 -4
- package/src/shared/memory-attachment.ts +22 -10
- 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/run-credential-store.ts +45 -0
- package/src/shared/run-credential.ts +70 -0
- 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/synthesized-attachment.ts +38 -3
- 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/src/worker.ts +15 -3
- package/src/workflow-source.ts +15 -0
- package/src/workflows/__tests__/run-credential-interceptor.test.ts +178 -0
- package/src/workflows/execute-from-execution.ts +17 -0
- package/src/workflows/index.ts +5 -3
- package/src/workflows/interceptors/run-credential.ts +101 -0
- 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,463 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepAgentTranslator — the native harness's translator: LangGraph's v3
|
|
3
|
+
* protocol events in, the canonical `TranscriptEvent` union out
|
|
4
|
+
* (`harness/transcript/events.ts`).
|
|
5
|
+
*
|
|
6
|
+
* The one module that knows LangGraph's wire shape:
|
|
7
|
+
* the shared builder folds what comes out of here and nothing of the engine
|
|
8
|
+
* reaches it otherwise. Every engine fact the builder used to read is
|
|
9
|
+
* answered on this side now (since #1097):
|
|
10
|
+
*
|
|
11
|
+
* - the tool's result, rendered to the string the row carries — the
|
|
12
|
+
* LangChain ToolMessage envelope and the LangGraph Command unwrapped;
|
|
13
|
+
* - the tool's attribution (`mcpServerSlug`) and authorization provenance,
|
|
14
|
+
* from the gate's posture (`resolveApprovalProvenance`, the gate's
|
|
15
|
+
* read-side twin);
|
|
16
|
+
* - the SCOPE of every event — the root's transcript or one sub-agent's —
|
|
17
|
+
* from LangGraph's namespace grammar, and the sub-agent's own lifecycle
|
|
18
|
+
* (`sub_agent_started/finished/failed`) from deepagents' `task` tool
|
|
19
|
+
* Until #1097 the builder read the namespace and the
|
|
20
|
+
* tool's name itself, and kept a second copy of every handler for the
|
|
21
|
+
* sub-agents' transcripts.
|
|
22
|
+
*
|
|
23
|
+
* What this translator deliberately does NOT answer: whether the gate holds
|
|
24
|
+
* a call. On native it never has to. LangGraph's `interrupt()` runs inside
|
|
25
|
+
* the gate middleware BEFORE the tool handler, so a held call emits no
|
|
26
|
+
* `tool-started` at all; the `tool-started` that does arrive is the engine's
|
|
27
|
+
* own word that the call was authorized — capture mode let the file write
|
|
28
|
+
* flow, a lease or the policy chain cleared it, or the user approved it on a
|
|
29
|
+
* resume. The gate's decision has arms this side cannot evaluate (capture
|
|
30
|
+
* mode asks the workspace's git state, asynchronously;
|
|
31
|
+
* `middleware/approval-gate.ts`), and duplicating them would be a second copy
|
|
32
|
+
* of the decision — exactly the drift one writer per fact exists to end. So
|
|
33
|
+
* native emits no `tool_started.gate`; the held call reaches the transcript
|
|
34
|
+
* as `approval_proposed` from the post-stream seed. Until #1097 the builder
|
|
35
|
+
* carried a copy of the decision that gated MCP tools only, a path
|
|
36
|
+
* production never took.
|
|
37
|
+
*
|
|
38
|
+
* Attribution and provenance are answered for ROOT-scope calls only: a
|
|
39
|
+
* sub-agent's rows carry none on either harness today (#1133), and one
|
|
40
|
+
* handler set would otherwise stamp them as a side effect.
|
|
41
|
+
*
|
|
42
|
+
* The scope, in LangGraph 1.3.2's grammar (mirrors deepagents'
|
|
43
|
+
* `createSubagentTransformer`): the root's model events arrive under
|
|
44
|
+
* `["model_request:<uuid>"]` and its tool events under `["tools:<uuid>"]`
|
|
45
|
+
* (one segment); a `task` tool start at that depth opens a sub-agent, and
|
|
46
|
+
* the segment it arrived under is the prefix every event of that sub-agent's
|
|
47
|
+
* graph carries first (`["tools:<uuid>", "model_request:<inner>"]`, two or
|
|
48
|
+
* more segments). An event with a REGISTERED first segment and two or more
|
|
49
|
+
* segments is the sub-agent's; everything else is the root's — including a
|
|
50
|
+
* nested namespace whose prefix nobody registered, which folds into the
|
|
51
|
+
* root as it always did (a sub-agent resumed inside its own gate
|
|
52
|
+
* with no re-emitted `task` start is the production case). A `task` inside
|
|
53
|
+
* a sub-agent is an ordinary row of that sub-agent's transcript: one level
|
|
54
|
+
* of delegation is tracked, as before.
|
|
55
|
+
*
|
|
56
|
+
* Beside the transcript, {@link usageOf} answers the loop's one
|
|
57
|
+
* non-transcript question about the wire — the usage a
|
|
58
|
+
* `message-finish` carries — so the loop never parses a raw event itself.
|
|
59
|
+
* What the wire carries that the transcript does not: `lifecycle` and
|
|
60
|
+
* `provider` events, the standalone `usage` event, each event's `seq` and
|
|
61
|
+
* `node`. None of it was ever folded; the recorder keeps the raw event for
|
|
62
|
+
* a replay.
|
|
63
|
+
*
|
|
64
|
+
* The file was `v3-protocol-normalizer.ts` (a stateless `normalize`) until
|
|
65
|
+
* #1097 made it stateful — the same word as `execute-cursor/translator.ts`,
|
|
66
|
+
* so a third harness's author finds one shape in both.
|
|
67
|
+
*
|
|
68
|
+
* Defensive parsing: handles both snake_case and camelCase field names
|
|
69
|
+
* for tool IDs/names (protocol spec uses camelCase but recordings show
|
|
70
|
+
* snake_case). Uses `data.event` as canonical discriminator, with
|
|
71
|
+
* `data.type` as fallback (CP04 finding).
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
import type { V3ProtocolEvent } from "./v3-event-recorder.js";
|
|
75
|
+
import type { ToolStartedEvent, TranscriptEvent } from "../../harness/transcript/events.js";
|
|
76
|
+
import { resolveApprovalProvenance, type PolicySource } from "../../shared/approval-policy.js";
|
|
77
|
+
import type { DeepAgentGateState } from "./turn-setup.js";
|
|
78
|
+
|
|
79
|
+
const loggedUnknowns = new Set<string>();
|
|
80
|
+
|
|
81
|
+
/** deepagents' delegation tool: the one tool name this translator knows, because its start opens a sub-agent. */
|
|
82
|
+
const TASK_TOOL = "task";
|
|
83
|
+
|
|
84
|
+
// ── The translator ────────────────────────────────────────────────
|
|
85
|
+
|
|
86
|
+
export class DeepAgentTranslator {
|
|
87
|
+
/** First namespace segment → the sub-agent (its `task` call id) whose graph runs under it. */
|
|
88
|
+
private readonly subAgentByPrefix = new Map<string, string>();
|
|
89
|
+
/** The `task` call ids whose completion closes a sub-agent. */
|
|
90
|
+
private readonly taskCalls = new Set<string>();
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param gate the turn's gate posture, for attribution and provenance;
|
|
94
|
+
* `null` where a turn runs with none (the unit arms that drive the
|
|
95
|
+
* builder bare), and then every call is unattributed.
|
|
96
|
+
*/
|
|
97
|
+
constructor(private readonly gate: DeepAgentGateState | null) {}
|
|
98
|
+
|
|
99
|
+
/** One raw event to its canonical events — `translate(raw)` is the one signature every harness's translator shares. */
|
|
100
|
+
translate(raw: V3ProtocolEvent): TranscriptEvent[] {
|
|
101
|
+
const namespace = raw.params.namespace;
|
|
102
|
+
const subAgentId = this.scopeOf(namespace);
|
|
103
|
+
const out: TranscriptEvent[] = [];
|
|
104
|
+
for (const event of normalize(raw)) {
|
|
105
|
+
if (subAgentId !== undefined) {
|
|
106
|
+
out.push({ ...event, subAgentId });
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
switch (event.kind) {
|
|
110
|
+
case "tool_started":
|
|
111
|
+
if (event.name === TASK_TOOL && namespace.length <= 1) {
|
|
112
|
+
out.push(this.openSubAgent(event, namespace));
|
|
113
|
+
}
|
|
114
|
+
out.push(this.attribute(event));
|
|
115
|
+
break;
|
|
116
|
+
case "tool_finished":
|
|
117
|
+
out.push(event);
|
|
118
|
+
if (this.taskCalls.has(event.callId)) {
|
|
119
|
+
out.push({ kind: "sub_agent_finished", subAgentId: event.callId, output: event.result });
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
case "tool_error":
|
|
123
|
+
out.push(event);
|
|
124
|
+
if (this.taskCalls.has(event.callId)) {
|
|
125
|
+
out.push({ kind: "sub_agent_failed", subAgentId: event.callId, error: event.message });
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
out.push(event);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** The sub-agent an event belongs to, or `undefined` for the root (see the header for the grammar). */
|
|
136
|
+
private scopeOf(namespace: readonly string[]): string | undefined {
|
|
137
|
+
if (namespace.length < 2) return undefined;
|
|
138
|
+
return this.subAgentByPrefix.get(namespace[0]);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* A `task` start at the root opens a sub-agent keyed by the call id, with
|
|
143
|
+
* the segment it arrived under as the routing prefix (a depth-0 start —
|
|
144
|
+
* tests — gets a synthetic one so its children can still name it).
|
|
145
|
+
*/
|
|
146
|
+
private openSubAgent(event: ToolStartedEvent, namespace: readonly string[]): TranscriptEvent {
|
|
147
|
+
const prefix = namespace[0] ?? `tools:${event.callId}`;
|
|
148
|
+
this.subAgentByPrefix.set(prefix, event.callId);
|
|
149
|
+
this.taskCalls.add(event.callId);
|
|
150
|
+
const description = stringArg(event.input, "description");
|
|
151
|
+
return {
|
|
152
|
+
kind: "sub_agent_started",
|
|
153
|
+
subAgentId: event.callId,
|
|
154
|
+
name: stringArg(event.input, "subagent_type") || TASK_TOOL,
|
|
155
|
+
subject: description,
|
|
156
|
+
input: description,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** The attribution and provenance for one root-scope tool start. */
|
|
161
|
+
private attribute(event: ToolStartedEvent): ToolStartedEvent {
|
|
162
|
+
const gate = this.gate;
|
|
163
|
+
if (!gate) return event;
|
|
164
|
+
const mcpServerSlug = gate.toolServerMap.get(event.name) ?? "";
|
|
165
|
+
const provenance: PolicySource | undefined = resolveApprovalProvenance(
|
|
166
|
+
event.name,
|
|
167
|
+
mcpServerSlug,
|
|
168
|
+
gate.policies,
|
|
169
|
+
gate.leasedCategories,
|
|
170
|
+
gate.globalBypass,
|
|
171
|
+
);
|
|
172
|
+
return {
|
|
173
|
+
...event,
|
|
174
|
+
mcpServerSlug,
|
|
175
|
+
...(provenance !== undefined ? { provenance } : {}),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function stringArg(input: Record<string, unknown>, key: string): string {
|
|
181
|
+
const value = input[key];
|
|
182
|
+
return typeof value === "string" ? value : "";
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ── The wire, event by event ──────────────────────────────────────
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The stateless core: one raw event to its canonical events, root-scoped
|
|
189
|
+
* (no `subAgentId`) and unattributed (`mcpServerSlug: ""`, no provenance, no
|
|
190
|
+
* gate). The translator layers scope and the gate's answers on top; the arms
|
|
191
|
+
* that pin the wire's shape read this directly.
|
|
192
|
+
*/
|
|
193
|
+
export function normalize(event: V3ProtocolEvent): TranscriptEvent[] {
|
|
194
|
+
const method = event.method;
|
|
195
|
+
|
|
196
|
+
switch (method) {
|
|
197
|
+
case "messages": return normalizeMessage(event);
|
|
198
|
+
case "tools": return normalizeTool(event);
|
|
199
|
+
default:
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// ── Usage ─────────────────────────────────────────────────────────
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* The token usage as LangChain's v3 protocol delivers it on a
|
|
208
|
+
* `message-finish`. `input_tokens` already INCLUDES the cache buckets (the
|
|
209
|
+
* Anthropic adapter folds them in); the loop prices over the disjoint parts.
|
|
210
|
+
*/
|
|
211
|
+
export interface V3UsagePayload {
|
|
212
|
+
readonly input_tokens?: number;
|
|
213
|
+
readonly output_tokens?: number;
|
|
214
|
+
readonly total_tokens?: number;
|
|
215
|
+
readonly input_token_details?: {
|
|
216
|
+
readonly cache_creation?: number;
|
|
217
|
+
readonly cache_read?: number;
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* The usage one raw event carries, or `undefined`. Read from `message-finish`
|
|
223
|
+
* ONLY — v3 also emits a standalone `usage` event for the same turn, and
|
|
224
|
+
* reading both would double-count. Every namespace's finish counts: a
|
|
225
|
+
* sub-agent's spend is the execution's spend (since #1096), and the cost
|
|
226
|
+
* cap the runtime enforces reads the whole execution.
|
|
227
|
+
*
|
|
228
|
+
* A loop concern, deliberately NOT a `TranscriptEvent`:
|
|
229
|
+
* usage is neither a row nor a message, and `translate`'s return type stays
|
|
230
|
+
* the one signature every harness's translator shares. The Cursor loop reads
|
|
231
|
+
* its usage from the SDK's `turn-ended` delta — the same division.
|
|
232
|
+
*/
|
|
233
|
+
export function usageOf(event: V3ProtocolEvent): V3UsagePayload | undefined {
|
|
234
|
+
if (event.method !== "messages") return undefined;
|
|
235
|
+
const data = event.params.data as Record<string, unknown> | undefined;
|
|
236
|
+
if (!data || readEventType(data) !== "message-finish") return undefined;
|
|
237
|
+
return normalizeUsagePayload(data.usage as Record<string, unknown> | undefined);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ── Messages Channel ──────────────────────────────────────────────
|
|
241
|
+
|
|
242
|
+
function normalizeMessage(event: V3ProtocolEvent): TranscriptEvent[] {
|
|
243
|
+
const data = event.params.data as Record<string, unknown> | undefined;
|
|
244
|
+
if (!data) return [];
|
|
245
|
+
|
|
246
|
+
const eventType = readEventType(data);
|
|
247
|
+
const runId = (data.run_id ?? "") as string;
|
|
248
|
+
|
|
249
|
+
switch (eventType) {
|
|
250
|
+
case "message-start":
|
|
251
|
+
return [{ kind: "message_start" as const, runId }];
|
|
252
|
+
|
|
253
|
+
case "content-block-delta":
|
|
254
|
+
return normalizeContentBlockDelta(data, runId);
|
|
255
|
+
|
|
256
|
+
case "message-finish":
|
|
257
|
+
return [{ kind: "message_finish" as const, runId }];
|
|
258
|
+
|
|
259
|
+
// Carried by the wire, not by the transcript (see the header).
|
|
260
|
+
case "usage":
|
|
261
|
+
case "provider":
|
|
262
|
+
case "content-block-start":
|
|
263
|
+
case "content-block-finish":
|
|
264
|
+
return [];
|
|
265
|
+
|
|
266
|
+
default:
|
|
267
|
+
logUnknown("messages", eventType);
|
|
268
|
+
return [];
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function normalizeContentBlockDelta(
|
|
273
|
+
data: Record<string, unknown>,
|
|
274
|
+
runId: string,
|
|
275
|
+
): TranscriptEvent[] {
|
|
276
|
+
const delta = data.delta as Record<string, unknown> | undefined;
|
|
277
|
+
if (!delta) return [];
|
|
278
|
+
|
|
279
|
+
const deltaType = delta.type as string | undefined;
|
|
280
|
+
|
|
281
|
+
if (deltaType === "text-delta") {
|
|
282
|
+
const text = (delta.text ?? "") as string;
|
|
283
|
+
if (!text) return [];
|
|
284
|
+
return [{ kind: "text_delta" as const, runId, text }];
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (deltaType === "reasoning-delta") {
|
|
288
|
+
const text = (delta.reasoning ?? "") as string;
|
|
289
|
+
if (!text) return [];
|
|
290
|
+
return [{ kind: "reasoning_delta" as const, runId, text }];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (deltaType === "block-delta") {
|
|
294
|
+
const fields = delta.fields as Record<string, unknown> | undefined;
|
|
295
|
+
if (!fields) return [];
|
|
296
|
+
if (fields.type === "tool_call_chunk") {
|
|
297
|
+
const callId = (fields.id ?? "") as string;
|
|
298
|
+
const argsChunk = (fields.args ?? "") as string;
|
|
299
|
+
if (!argsChunk && !callId) return [];
|
|
300
|
+
return [{ kind: "tool_arg_delta" as const, callId, argsChunk }];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return [];
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ── Tools Channel ─────────────────────────────────────────────────
|
|
308
|
+
|
|
309
|
+
function normalizeTool(event: V3ProtocolEvent): TranscriptEvent[] {
|
|
310
|
+
const data = event.params.data as Record<string, unknown> | undefined;
|
|
311
|
+
if (!data) return [];
|
|
312
|
+
|
|
313
|
+
const eventType = readEventType(data);
|
|
314
|
+
|
|
315
|
+
switch (eventType) {
|
|
316
|
+
case "tool-started": {
|
|
317
|
+
const callId = readToolCallId(data);
|
|
318
|
+
const name = readToolName(data);
|
|
319
|
+
const input = parseToolInput(data.input);
|
|
320
|
+
return [{ kind: "tool_started" as const, callId, name, input, mcpServerSlug: "" }];
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
case "tool-finished": {
|
|
324
|
+
const callId = readToolCallId(data);
|
|
325
|
+
return [{ kind: "tool_finished" as const, callId, result: extractToolResult(data.output) }];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
case "tool-error": {
|
|
329
|
+
const callId = readToolCallId(data);
|
|
330
|
+
const message = (data.message ?? data.error ?? "") as string;
|
|
331
|
+
return [{ kind: "tool_error" as const, callId, message }];
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
case "tool-output-delta": {
|
|
335
|
+
const callId = readToolCallId(data);
|
|
336
|
+
const delta = (data.delta ?? "") as string;
|
|
337
|
+
return [{ kind: "tool_output_delta" as const, callId, delta: String(delta) }];
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
default:
|
|
341
|
+
logUnknown("tools", eventType);
|
|
342
|
+
return [];
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// ── Tool Result ───────────────────────────────────────────────────
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Serialize a LangChain message `content` field into the canonical tool-result
|
|
350
|
+
* string.
|
|
351
|
+
*
|
|
352
|
+
* Text-only content is a plain string and passes through unchanged. Multimodal
|
|
353
|
+
* content (image, or mixed text+image — e.g. a computer-use screenshot) is an
|
|
354
|
+
* array of content blocks; we serialize the blocks array ITSELF, not the
|
|
355
|
+
* surrounding message envelope, so the result lands in the exact top-level-array
|
|
356
|
+
* shape the persist-time offload (`detectImagePayload`/`contentBlocks` in
|
|
357
|
+
* status-offload.ts) consumes to lift the image out into a renderable
|
|
358
|
+
* `ToolCallOutputRef`. Serializing the envelope instead would bury the base64
|
|
359
|
+
* one level deeper and defeat that detection.
|
|
360
|
+
*
|
|
361
|
+
* Returns undefined when `content` is neither a string nor an array, letting the
|
|
362
|
+
* caller fall back to serializing whatever else it holds.
|
|
363
|
+
*/
|
|
364
|
+
function serializeToolContent(content: unknown): string | undefined {
|
|
365
|
+
if (typeof content === "string") return content;
|
|
366
|
+
if (Array.isArray(content)) return JSON.stringify(content);
|
|
367
|
+
return undefined;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* The `result: string` a `tool_finished` carries, from the v3 `tool-finished`
|
|
372
|
+
* output — engine knowledge that stays on this side of the union (it was
|
|
373
|
+
* `extractToolResultV3` in `harness/transcript/tool-result.ts` for a few
|
|
374
|
+
* commits of #1097). v3 wraps a LangChain `ToolMessage` in a constructor
|
|
375
|
+
* envelope, `{ lc, type, id, kwargs: { content, status, ... } }`; the content
|
|
376
|
+
* is what the row shows. Anything else is serialized as it came.
|
|
377
|
+
*
|
|
378
|
+
* A state-mutating tool returns a LangGraph `Command` instead —
|
|
379
|
+
* `{ lg_name: "Command", update: { ..., messages: [ToolMessage] }, goto }` —
|
|
380
|
+
* with its ToolMessage nested in the update (deepagents' `write_todos` and
|
|
381
|
+
* `task` both do). The row shows that ToolMessage's content, not the whole
|
|
382
|
+
* Command (since #1097; until then the row carried the serialized
|
|
383
|
+
* Command, the todos array twice over).
|
|
384
|
+
*/
|
|
385
|
+
function extractToolResult(output: unknown): string {
|
|
386
|
+
if (typeof output === "string") return output;
|
|
387
|
+
if (typeof output === "object" && output !== null) {
|
|
388
|
+
const obj = output as Record<string, unknown>;
|
|
389
|
+
const commandMessage = toolMessageOfCommand(obj);
|
|
390
|
+
if (commandMessage !== undefined) return extractToolResult(commandMessage);
|
|
391
|
+
const kwargs = obj.kwargs as Record<string, unknown> | undefined;
|
|
392
|
+
if (kwargs) {
|
|
393
|
+
const fromKwargs = serializeToolContent(kwargs.content);
|
|
394
|
+
if (fromKwargs !== undefined) return fromKwargs;
|
|
395
|
+
}
|
|
396
|
+
const fromContent = serializeToolContent(obj.content);
|
|
397
|
+
if (fromContent !== undefined) return fromContent;
|
|
398
|
+
}
|
|
399
|
+
try {
|
|
400
|
+
return JSON.stringify(output);
|
|
401
|
+
} catch {
|
|
402
|
+
return "[serialization error]";
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* The ToolMessage a LangGraph `Command` carries in `update.messages`, or
|
|
408
|
+
* `undefined` when the object is not a Command or carries none. The LAST
|
|
409
|
+
* message is the tool's own reply (a Command may prepend others); a Command
|
|
410
|
+
* with no message falls through to plain serialization, so nothing is lost.
|
|
411
|
+
*/
|
|
412
|
+
function toolMessageOfCommand(obj: Record<string, unknown>): unknown {
|
|
413
|
+
if (obj.lg_name !== "Command") return undefined;
|
|
414
|
+
const update = obj.update as Record<string, unknown> | undefined;
|
|
415
|
+
const messages = update?.messages;
|
|
416
|
+
if (!Array.isArray(messages) || messages.length === 0) return undefined;
|
|
417
|
+
return messages[messages.length - 1];
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// ── Defensive Field Parsers ───────────────────────────────────────
|
|
421
|
+
|
|
422
|
+
function readEventType(data: Record<string, unknown>): string {
|
|
423
|
+
return ((data.event ?? data.type) as string) ?? "";
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function readToolCallId(data: Record<string, unknown>): string {
|
|
427
|
+
return ((data.tool_call_id ?? data.toolCallId) as string) ?? "";
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function readToolName(data: Record<string, unknown>): string {
|
|
431
|
+
return ((data.tool_name ?? data.toolName ?? data.name) as string) ?? "unknown_tool";
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function parseToolInput(raw: unknown): Record<string, unknown> {
|
|
435
|
+
if (raw === undefined || raw === null) return {};
|
|
436
|
+
if (typeof raw === "object" && !Array.isArray(raw)) return raw as Record<string, unknown>;
|
|
437
|
+
if (typeof raw === "string") {
|
|
438
|
+
try { return JSON.parse(raw) as Record<string, unknown>; }
|
|
439
|
+
catch { return {}; }
|
|
440
|
+
}
|
|
441
|
+
return {};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function normalizeUsagePayload(raw: Record<string, unknown> | undefined): V3UsagePayload | undefined {
|
|
445
|
+
if (!raw) return undefined;
|
|
446
|
+
const details = raw.input_token_details as Record<string, unknown> | undefined;
|
|
447
|
+
return {
|
|
448
|
+
input_tokens: raw.input_tokens as number | undefined,
|
|
449
|
+
output_tokens: raw.output_tokens as number | undefined,
|
|
450
|
+
total_tokens: raw.total_tokens as number | undefined,
|
|
451
|
+
input_token_details: details ? {
|
|
452
|
+
cache_creation: details.cache_creation as number | undefined,
|
|
453
|
+
cache_read: details.cache_read as number | undefined,
|
|
454
|
+
} : undefined,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function logUnknown(method: string, eventType: string): void {
|
|
459
|
+
const key = `${method}:${eventType}`;
|
|
460
|
+
if (loggedUnknowns.has(key)) return;
|
|
461
|
+
loggedUnknowns.add(key);
|
|
462
|
+
console.debug(`[DeepAgentTranslator] Unknown event: method=${method} event=${eventType}`);
|
|
463
|
+
}
|
|
@@ -8,37 +8,38 @@
|
|
|
8
8
|
* the runtime's stop, mark in-flight sub-agent rows through the shared act
|
|
9
9
|
* and settle `interrupted` with nothing further; the graph's
|
|
10
10
|
* `structuredResponse` folded onto the status; the interrupts a completed
|
|
11
|
-
* stream left pending
|
|
11
|
+
* stream left pending proposed through the builder as WAITING rows; and the
|
|
12
|
+
* outcome.
|
|
12
13
|
*
|
|
13
14
|
* What this module never does: write a phase, a terminal copy or
|
|
14
15
|
* `completedAt` — those are the runtime's (`harness/run-turn.ts`,
|
|
15
|
-
* `terminal-table.ts`);
|
|
16
|
+
* `terminal-table.ts`); close the transcript's streaming flags — the
|
|
17
|
+
* runtime's, once `runTurn` returns, on every path (since #1097; until then this
|
|
18
|
+
* settle finalized the builder itself, and a turn that threw before
|
|
19
|
+
* reaching it left its last message streaming); settle SKIP and REJECT rows — the runtime's
|
|
16
20
|
* (`harness/approval-decisions.ts`, after every outcome); withhold secret
|
|
17
21
|
* content — the runtime's chokepoint does it on every write; finalize the
|
|
18
22
|
* write-back — the runtime's epilogue; capture the turn's file changes or
|
|
19
23
|
* decide whether a review is pending — the runtime's (`harness/capture.ts`,
|
|
20
24
|
* once, over whatever the whole turn left on the tree, after this settle
|
|
21
|
-
* returns;
|
|
22
|
-
*
|
|
25
|
+
* returns; since #1096). Transcript rows it CREATES go through the builder
|
|
26
|
+
* (`approval_proposed`, since #1097); the one row it AMENDS by identity is the
|
|
27
|
+
* gate's unattended skip (`reconcileUnattendedSkips`), whose evidence exists
|
|
28
|
+
* only inside this harness.
|
|
23
29
|
*
|
|
24
30
|
* The structured response is folded BEFORE the outcome is decided, so a turn
|
|
25
31
|
* the runtime then pauses for file review persists it and the pure
|
|
26
32
|
* file-review resume completes with it (the runtime's text fallback runs on
|
|
27
|
-
* the review-pending path too
|
|
33
|
+
* the review-pending path too).
|
|
28
34
|
*
|
|
29
|
-
* Moved from `index.ts` (post-stream through the terminal arms)
|
|
30
|
-
* the capture boundary left for the runtime
|
|
35
|
+
* Moved from `index.ts` (post-stream through the terminal arms) in #1096,
|
|
36
|
+
* where the capture boundary also left for the runtime.
|
|
31
37
|
*/
|
|
32
38
|
|
|
33
|
-
import {
|
|
34
|
-
import { AgentMessageSchema, ToolCallSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
35
|
-
import { MessageType, ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
39
|
+
import type { JsonObject } from "@bufbuild/protobuf";
|
|
36
40
|
|
|
37
41
|
import type { TurnInput, TurnOutcome, TurnSink } from "../../harness/types.js";
|
|
38
|
-
import { POLICY_ENGINE_VERSION, toProtoPolicySource } from "../../shared/approval-policy.js";
|
|
39
|
-
import { utcTimestamp } from "../../shared/status.js";
|
|
40
42
|
import { cancelInProgressSubAgentProtos } from "../../shared/subagent-rows.js";
|
|
41
|
-
import { classifyTool } from "../../shared/tool-kind.js";
|
|
42
43
|
import { captureApprovalArtifacts } from "./approval-file-change.js";
|
|
43
44
|
import { autoPublishWrittenFiles } from "./auto-publish.js";
|
|
44
45
|
import { detectPendingInterrupts, reconcileUnattendedSkips, type GraphStateSnapshot } from "./hitl.js";
|
|
@@ -82,10 +83,9 @@ export async function settleDeepAgentTurn(deps: DeepAgentSettleDeps): Promise<Tu
|
|
|
82
83
|
if (stream.reason === "interrupted") {
|
|
83
84
|
// A stopped turn aborted the graph run, so any sub-agent the parent had
|
|
84
85
|
// delegated is no longer executing: CANCELLED through the one shared act
|
|
85
|
-
// (the runtime marks them itself only on its thrown arms)
|
|
86
|
-
//
|
|
86
|
+
// (the runtime marks them itself only on its thrown arms). There is no
|
|
87
|
+
// review to open.
|
|
87
88
|
cancelInProgressSubAgentProtos(status.subAgentExecutions);
|
|
88
|
-
transcript.builder.finalizeSubAgentStreaming();
|
|
89
89
|
return { kind: "interrupted" };
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -118,11 +118,17 @@ export async function settleDeepAgentTurn(deps: DeepAgentSettleDeps): Promise<Tu
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
121
|
+
* Propose, through the builder, one approval per interrupt the graph left
|
|
122
|
+
* pending — the gate's hold reaching the transcript as `approval_proposed`
|
|
123
|
+
* (since #1097). LangGraph's `interrupt()` ran before the tool
|
|
124
|
+
* handler, so the stream showed no row for the call; the builder creates
|
|
125
|
+
* the WAITING row on the message whose text proposed it, with the redacted
|
|
126
|
+
* args read from the AI message in graph state (the single source of truth
|
|
127
|
+
* for the proposed call; issue #754: a placeholder without args rendered a
|
|
128
|
+
* pathless header). Until #1097 this settle built the message and the rows
|
|
129
|
+
* itself, on a new empty AI message of its own, with no by-id check against
|
|
130
|
+
* rows the stream had created (the upsert closes it).
|
|
131
|
+
* Returns whether any was proposed.
|
|
126
132
|
*/
|
|
127
133
|
async function seedPendingInterrupts(deps: DeepAgentSettleDeps): Promise<boolean> {
|
|
128
134
|
const { input, sink, engine } = deps;
|
|
@@ -134,31 +140,17 @@ async function seedPendingInterrupts(deps: DeepAgentSettleDeps): Promise<boolean
|
|
|
134
140
|
const aiMessages = Array.isArray(graphMessages) ? graphMessages : [];
|
|
135
141
|
console.log(`[turn-settle] Detected ${pending.length} pending interrupt(s) for execution ${input.executionId} — awaiting approval`);
|
|
136
142
|
|
|
137
|
-
const aiMsg = create(AgentMessageSchema, {
|
|
138
|
-
type: MessageType.MESSAGE_AI,
|
|
139
|
-
content: "",
|
|
140
|
-
timestamp: utcTimestamp(),
|
|
141
|
-
isStreaming: false,
|
|
142
|
-
});
|
|
143
143
|
for (const intr of pending) {
|
|
144
|
-
const
|
|
145
|
-
|
|
144
|
+
const { args } = captureApprovalArtifacts({ toolCallId: intr.toolCallId, messages: aiMessages });
|
|
145
|
+
sink.transcript.apply({
|
|
146
|
+
kind: "approval_proposed",
|
|
147
|
+
callId: intr.toolCallId,
|
|
146
148
|
name: intr.toolName,
|
|
147
|
-
status: ToolCallStatus.TOOL_CALL_WAITING_APPROVAL,
|
|
148
|
-
requiresApproval: true,
|
|
149
|
-
approvalMessage: intr.message,
|
|
150
|
-
approvalRequestedAt: utcTimestamp(),
|
|
151
149
|
mcpServerSlug: intr.mcpServerSlug,
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
policyEngineVersion: intr.policySource ? POLICY_ENGINE_VERSION : "",
|
|
150
|
+
message: intr.message,
|
|
151
|
+
...(args ? { args } : {}),
|
|
152
|
+
...(intr.policySource ? { provenance: intr.policySource } : {}),
|
|
156
153
|
});
|
|
157
|
-
const { argsPreview, args } = captureApprovalArtifacts({ toolCallId: intr.toolCallId, messages: aiMessages });
|
|
158
|
-
if (argsPreview) toolCall.argsPreview = argsPreview;
|
|
159
|
-
if (args) toolCall.args = args as typeof toolCall.args;
|
|
160
|
-
aiMsg.toolCalls.push(toolCall);
|
|
161
154
|
}
|
|
162
|
-
sink.
|
|
163
|
-
return true;
|
|
155
|
+
return sink.transcript.awaitingApproval;
|
|
164
156
|
}
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
* knows are reported through the sink exactly as the orchestrator reported
|
|
26
26
|
* them (the resolution labels are the runtime's).
|
|
27
27
|
*
|
|
28
|
-
* One root for everything
|
|
28
|
+
* One root for everything: the deepagents backend, the CAS
|
|
29
29
|
* observer, the gate's path normalization and the publisher are all rooted
|
|
30
30
|
* at `workspace.primaryDir` — the same tree the runtime locks, links and
|
|
31
31
|
* captures. For zero or one workspace entry this is byte-identical to the
|
|
32
32
|
* orchestrator's `workspaceBackend.rootDir`.
|
|
33
33
|
*
|
|
34
34
|
* Moved from `setup.ts` `performSetup` (the LangGraph half; the resolution
|
|
35
|
-
* half is the runtime's twelve phases)
|
|
35
|
+
* half is the runtime's twelve phases) in #1096; the step bodies are the
|
|
36
36
|
* orchestrator's, verbatim where nothing changed.
|
|
37
37
|
*/
|
|
38
38
|
|
|
@@ -81,7 +81,7 @@ import { modelHasNativeThinking, transformAndCompileSubagents } from "./subagent
|
|
|
81
81
|
* (`execute-cursor/turn-setup.ts` `CursorAdapterConfig` is the idiom): a
|
|
82
82
|
* whole `Config` satisfies it, a test constructs these fields and nothing
|
|
83
83
|
* else. Smaller than the orchestrator's reach — the synthesized attachments'
|
|
84
|
-
* endpoints it read are the runtime's now (
|
|
84
|
+
* endpoints it read are the runtime's now (since #1096).
|
|
85
85
|
*/
|
|
86
86
|
export type DeepAgentAdapterConfig = Pick<
|
|
87
87
|
Config,
|
|
@@ -147,8 +147,8 @@ export type DeepAgentGraphInput =
|
|
|
147
147
|
* spec named none — the one reader of `spec.executionConfig.modelName`, which
|
|
148
148
|
* the Cursor adapter reads too), or the registry's default for `"default"`.
|
|
149
149
|
* The same reading the runtime's attachment phase made for the vision budget,
|
|
150
|
-
* so the model that sees the images is the model that runs. (Until
|
|
151
|
-
* read the spec field beside the runtime's resolved copy
|
|
150
|
+
* so the model that sees the images is the model that runs. (Until #1096 this
|
|
151
|
+
* read the spec field beside the runtime's resolved copy.)
|
|
152
152
|
*/
|
|
153
153
|
export async function resolveModelName(input: TurnInput): Promise<string> {
|
|
154
154
|
return input.model.requested === "default" ? await getDefaultModel() : input.model.requested;
|
|
@@ -173,7 +173,7 @@ export async function openCheckpointer(input: TurnInput, sink: TurnSink, config:
|
|
|
173
173
|
|
|
174
174
|
/**
|
|
175
175
|
* The workspace as the engine sees it, rooted at the runtime's primary tree
|
|
176
|
-
* (
|
|
176
|
+
* (the one root). The platform dir the shared provision ensured rides along so
|
|
177
177
|
* the backend routes `.stigmer/…` reads to it.
|
|
178
178
|
*
|
|
179
179
|
* CAS capture (design docs 08/11/12): the single per-turn observer owns the
|
|
@@ -209,7 +209,7 @@ export function buildDeepAgentWorkspace(input: TurnInput): DeepAgentWorkspace {
|
|
|
209
209
|
* refuses an empty config, which is what the orchestrator's MCP gate
|
|
210
210
|
* (`mcp-gate.ts`) guarded against beside its channel-only reason; the
|
|
211
211
|
* runtime resolves unconditionally, so the one remaining question is
|
|
212
|
-
* "anything to connect?" (
|
|
212
|
+
* "anything to connect?" (since #1096).
|
|
213
213
|
*/
|
|
214
214
|
export async function connectTools(input: TurnInput, sink: TurnSink): Promise<DeepAgentTools> {
|
|
215
215
|
if (input.mcp.servers.length === 0) {
|
|
@@ -315,7 +315,7 @@ export function composeSystemPrompt(input: TurnInput, recalledMemories: Recalled
|
|
|
315
315
|
* stop on the invoke config and the budget middleware's ~80% advisory, so
|
|
316
316
|
* the warning and the enforcement can never disagree.
|
|
317
317
|
*
|
|
318
|
-
* Nothing in the middleware stack stops the run (
|
|
318
|
+
* Nothing in the middleware stack stops the run (since #1096):
|
|
319
319
|
* the runtime's abort is the platform's one stop, and its TERMINATED arm the
|
|
320
320
|
* one enforcement of `max_cost_usd`; the cost advisory warns the model at
|
|
321
321
|
* ~80% of the cap the way the budget middleware warns at ~80% of the
|