@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
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* halves in its own hermetic file, where the mocks its double needs can be
|
|
14
14
|
* hoisted: the Cursor adapter does so in
|
|
15
15
|
* `activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts`
|
|
16
|
-
* (
|
|
16
|
+
* (since #1070), and the fake's runtime-side half runs in
|
|
17
17
|
* `harness/__tests__/run-turn.test.ts`.
|
|
18
18
|
*/
|
|
19
19
|
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The run credential end to end through a real Temporal
|
|
3
|
+
* (`TestWorkflowEnvironment`, the golden E2E's harness): a credential on the
|
|
4
|
+
* `execute-from-execution` workflow input reaches EVERY activity the run
|
|
5
|
+
* schedules — the remote hydrate and the engine's local activities alike —
|
|
6
|
+
* as the activity's current run credential, and a credential-less input
|
|
7
|
+
* reaches none of them. This is the property the whole carrier exists for
|
|
8
|
+
* (`shared/run-credential.ts`): no activity of a member's run ever runs as
|
|
9
|
+
* the operator, and no activity of a credential-less run changes.
|
|
10
|
+
*
|
|
11
|
+
* Both ends are registered exactly as the worker roots register them: the
|
|
12
|
+
* activity interceptor on the worker, the workflow interceptor module in the
|
|
13
|
+
* bundle. Skipped, like the golden E2E, when a local Temporal cannot boot.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
17
|
+
import { readFileSync } from "node:fs";
|
|
18
|
+
import { join, dirname } from "node:path";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
|
|
21
|
+
import { loadWorkflowFromYaml } from "../workflow-engine/loader.js";
|
|
22
|
+
import { evaluateExpressionBatch } from "../workflow-engine/expression.js";
|
|
23
|
+
import type { ExecuteFromExecutionInput } from "../workflows/execute-from-execution.js";
|
|
24
|
+
import { EXECUTE_FROM_EXECUTION_WORKFLOW_TYPE } from "../workflows/execute-from-execution.js";
|
|
25
|
+
import { runCredentialActivityInterceptor } from "../interceptors/run-credential-activity.js";
|
|
26
|
+
import { currentRunCredential } from "../shared/run-credential-store.js";
|
|
27
|
+
|
|
28
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
29
|
+
const WORKFLOWS_PATH = join(__dirname, "../workflows/index.ts");
|
|
30
|
+
const RUN_CREDENTIAL_WORKFLOW_INTERCEPTOR = join(
|
|
31
|
+
__dirname,
|
|
32
|
+
"../workflows/interceptors/run-credential.ts",
|
|
33
|
+
);
|
|
34
|
+
const GOLDEN_MODEL = readFileSync(
|
|
35
|
+
join(__dirname, "../../test/golden/01-operation-basic.yaml"),
|
|
36
|
+
"utf-8",
|
|
37
|
+
);
|
|
38
|
+
const TASK_QUEUE = "run-credential-e2e-test";
|
|
39
|
+
|
|
40
|
+
type TestWorkflowEnvironment =
|
|
41
|
+
import("@temporalio/testing").TestWorkflowEnvironment;
|
|
42
|
+
type Worker = import("@temporalio/worker").Worker;
|
|
43
|
+
|
|
44
|
+
let env: TestWorkflowEnvironment | null = null;
|
|
45
|
+
let worker: Worker | null = null;
|
|
46
|
+
let workerRunPromise: Promise<void> | null = null;
|
|
47
|
+
let envReady = false;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* What each activity saw as its run credential, in the order they ran, with
|
|
51
|
+
* the execution it was working on (the hydrate's input object; the engine's
|
|
52
|
+
* positional first argument).
|
|
53
|
+
*/
|
|
54
|
+
const observed: Array<{
|
|
55
|
+
activity: string;
|
|
56
|
+
executionId: string;
|
|
57
|
+
credential: string | undefined;
|
|
58
|
+
}> = [];
|
|
59
|
+
|
|
60
|
+
function observing<T extends (...args: never[]) => unknown>(
|
|
61
|
+
activity: string,
|
|
62
|
+
body: T,
|
|
63
|
+
): T {
|
|
64
|
+
return ((...args: never[]) => {
|
|
65
|
+
const first: unknown = args[0];
|
|
66
|
+
const executionId =
|
|
67
|
+
typeof first === "string"
|
|
68
|
+
? first
|
|
69
|
+
: typeof first === "object" && first !== null && "execution_id" in first
|
|
70
|
+
? String((first as { execution_id: unknown }).execution_id)
|
|
71
|
+
: "";
|
|
72
|
+
observed.push({
|
|
73
|
+
activity,
|
|
74
|
+
executionId,
|
|
75
|
+
credential: currentRunCredential(),
|
|
76
|
+
});
|
|
77
|
+
return body(...args);
|
|
78
|
+
}) as T;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function createObservingActivities() {
|
|
82
|
+
return {
|
|
83
|
+
HydrateWorkflowExecution: observing(
|
|
84
|
+
"HydrateWorkflowExecution",
|
|
85
|
+
async (input: ExecuteFromExecutionInput) => ({
|
|
86
|
+
model: loadWorkflowFromYaml(GOLDEN_MODEL),
|
|
87
|
+
workflow_input: null,
|
|
88
|
+
env: {},
|
|
89
|
+
metadata: { execution_id: input.execution_id },
|
|
90
|
+
}),
|
|
91
|
+
),
|
|
92
|
+
ResetEventSequence: observing(
|
|
93
|
+
"ResetEventSequence",
|
|
94
|
+
async (): Promise<number> => 0,
|
|
95
|
+
),
|
|
96
|
+
LoadRecoveryContext: observing(
|
|
97
|
+
"LoadRecoveryContext",
|
|
98
|
+
async (): Promise<unknown[]> => [],
|
|
99
|
+
),
|
|
100
|
+
EmitWorkflowEvents: observing(
|
|
101
|
+
"EmitWorkflowEvents",
|
|
102
|
+
async (): Promise<void> => {},
|
|
103
|
+
),
|
|
104
|
+
PromoteTaskOutput: observing(
|
|
105
|
+
"PromoteTaskOutput",
|
|
106
|
+
async (): Promise<void> => {},
|
|
107
|
+
),
|
|
108
|
+
EvaluateExpressions: observing(
|
|
109
|
+
"EvaluateExpressions",
|
|
110
|
+
async (
|
|
111
|
+
expressions: Record<string, string>,
|
|
112
|
+
input: unknown,
|
|
113
|
+
stateVars: Record<string, unknown>,
|
|
114
|
+
) => evaluateExpressionBatch(expressions, input, stateVars),
|
|
115
|
+
),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function runOnce(credential: string | undefined): Promise<string> {
|
|
120
|
+
if (!env) throw new Error("TestWorkflowEnvironment not initialized");
|
|
121
|
+
const executionId = `wex_e2e_${Math.random().toString(36).slice(2)}`;
|
|
122
|
+
const input: ExecuteFromExecutionInput = {
|
|
123
|
+
execution_id: executionId,
|
|
124
|
+
workflow_instance_id: "wfi_1",
|
|
125
|
+
workflow_id: "wf_1",
|
|
126
|
+
org_id: "org_1",
|
|
127
|
+
...(credential !== undefined
|
|
128
|
+
? { execution_context_token: credential }
|
|
129
|
+
: {}),
|
|
130
|
+
};
|
|
131
|
+
await env.client.workflow.execute(EXECUTE_FROM_EXECUTION_WORKFLOW_TYPE, {
|
|
132
|
+
taskQueue: TASK_QUEUE,
|
|
133
|
+
workflowId: `run-credential-e2e-${executionId}`,
|
|
134
|
+
args: [input],
|
|
135
|
+
workflowExecutionTimeout: "30s",
|
|
136
|
+
});
|
|
137
|
+
return executionId;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
describe("run credential E2E — Temporal TestWorkflowEnvironment", () => {
|
|
141
|
+
beforeAll(async () => {
|
|
142
|
+
try {
|
|
143
|
+
const { TestWorkflowEnvironment: TWE } =
|
|
144
|
+
await import("@temporalio/testing");
|
|
145
|
+
const { Worker: W } = await import("@temporalio/worker");
|
|
146
|
+
|
|
147
|
+
env = await TWE.createLocal();
|
|
148
|
+
worker = await W.create({
|
|
149
|
+
connection: env.nativeConnection,
|
|
150
|
+
taskQueue: TASK_QUEUE,
|
|
151
|
+
workflowsPath: WORKFLOWS_PATH,
|
|
152
|
+
activities: createObservingActivities(),
|
|
153
|
+
interceptors: {
|
|
154
|
+
activity: [runCredentialActivityInterceptor],
|
|
155
|
+
workflowModules: [RUN_CREDENTIAL_WORKFLOW_INTERCEPTOR],
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
workerRunPromise = worker.run();
|
|
159
|
+
await runOnce(undefined);
|
|
160
|
+
observed.length = 0;
|
|
161
|
+
envReady = true;
|
|
162
|
+
} catch (err: unknown) {
|
|
163
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
164
|
+
console.warn(
|
|
165
|
+
`Temporal E2E smoke test failed (tests will be skipped): ${msg}`,
|
|
166
|
+
);
|
|
167
|
+
envReady = false;
|
|
168
|
+
}
|
|
169
|
+
}, 90_000);
|
|
170
|
+
|
|
171
|
+
afterAll(async () => {
|
|
172
|
+
if (worker) {
|
|
173
|
+
worker.shutdown();
|
|
174
|
+
await workerRunPromise;
|
|
175
|
+
}
|
|
176
|
+
await env?.teardown();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("every activity of a run whose input carries a credential runs with that credential current", async (testCtx) => {
|
|
180
|
+
if (!envReady) return testCtx.skip();
|
|
181
|
+
observed.length = 0;
|
|
182
|
+
|
|
183
|
+
await runOnce("run-cred-e2e");
|
|
184
|
+
|
|
185
|
+
const activities = new Set(observed.map((o) => o.activity));
|
|
186
|
+
expect(activities).toContain("HydrateWorkflowExecution");
|
|
187
|
+
expect(activities).toContain("ResetEventSequence");
|
|
188
|
+
expect(activities).toContain("EmitWorkflowEvents");
|
|
189
|
+
expect(observed.length).toBeGreaterThan(3);
|
|
190
|
+
expect(
|
|
191
|
+
observed.every((o) => o.credential === "run-cred-e2e"),
|
|
192
|
+
JSON.stringify(observed),
|
|
193
|
+
).toBe(true);
|
|
194
|
+
}, 60_000);
|
|
195
|
+
|
|
196
|
+
it("no activity of a credential-less run sees a credential — an older server's dispatch is unchanged", async (testCtx) => {
|
|
197
|
+
if (!envReady) return testCtx.skip();
|
|
198
|
+
observed.length = 0;
|
|
199
|
+
|
|
200
|
+
await runOnce(undefined);
|
|
201
|
+
|
|
202
|
+
expect(observed.length).toBeGreaterThan(3);
|
|
203
|
+
expect(
|
|
204
|
+
observed.every((o) => o.credential === undefined),
|
|
205
|
+
JSON.stringify(observed),
|
|
206
|
+
).toBe(true);
|
|
207
|
+
}, 60_000);
|
|
208
|
+
|
|
209
|
+
it("two runs in flight at once each see their own credential", async (testCtx) => {
|
|
210
|
+
if (!envReady) return testCtx.skip();
|
|
211
|
+
observed.length = 0;
|
|
212
|
+
|
|
213
|
+
const [one, two] = await Promise.all([
|
|
214
|
+
runOnce("run-cred-one"),
|
|
215
|
+
runOnce("run-cred-two"),
|
|
216
|
+
]);
|
|
217
|
+
const expected = new Map([
|
|
218
|
+
[one, "run-cred-one"],
|
|
219
|
+
[two, "run-cred-two"],
|
|
220
|
+
]);
|
|
221
|
+
|
|
222
|
+
const identified = observed.filter((o) => o.executionId !== "");
|
|
223
|
+
expect(identified.length).toBeGreaterThan(6);
|
|
224
|
+
expect(new Set(identified.map((o) => o.executionId))).toEqual(
|
|
225
|
+
new Set([one, two]),
|
|
226
|
+
);
|
|
227
|
+
for (const o of identified) {
|
|
228
|
+
expect(o.credential, `${o.activity} on ${o.executionId}`).toBe(
|
|
229
|
+
expected.get(o.executionId),
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}, 60_000);
|
|
233
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pins that every place a worker is composed registers BOTH ends of the run
|
|
3
|
+
* credential (`shared/run-credential.ts`): the activity inbound interceptor
|
|
4
|
+
* in the two roots that create workers, and the workflow interceptor module
|
|
5
|
+
* in the two runtime-bundling roots and the pre-built bundle script.
|
|
6
|
+
*
|
|
7
|
+
* Why a fence and not a comment: a root that forgot the activity end would
|
|
8
|
+
* present the operator's API key on every member's run — the failure this
|
|
9
|
+
* whole design exists to end — and on the desktop (the manager root) it
|
|
10
|
+
* would be invisible, because a person's own runner works for that person
|
|
11
|
+
* either way. The roots are read off the TypeScript syntax tree
|
|
12
|
+
* (`__test-utils__/module-specifiers.ts`) for the imports and off the source
|
|
13
|
+
* for the one call each import must make; the build script is JavaScript
|
|
14
|
+
* and is read as text.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { describe, expect, it } from "vitest";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
moduleSpecifiers,
|
|
22
|
+
readSource,
|
|
23
|
+
} from "../__test-utils__/module-specifiers.js";
|
|
24
|
+
|
|
25
|
+
const SRC_ROOT = fileURLToPath(new URL("../", import.meta.url));
|
|
26
|
+
const RUNNER_ROOT = fileURLToPath(new URL("../../", import.meta.url));
|
|
27
|
+
|
|
28
|
+
const ACTIVITY_END = "./interceptors/run-credential-activity.js";
|
|
29
|
+
const WORKFLOW_END_RESOLVER = "runCredentialWorkflowInterceptorModule";
|
|
30
|
+
|
|
31
|
+
function root(file: string): {
|
|
32
|
+
file: string;
|
|
33
|
+
source: string;
|
|
34
|
+
specifiers: string[];
|
|
35
|
+
} {
|
|
36
|
+
const path = `${SRC_ROOT}${file}`;
|
|
37
|
+
const source = readSource(path);
|
|
38
|
+
return { file, source, specifiers: moduleSpecifiers(path, source) };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe("run-credential registration", () => {
|
|
42
|
+
for (const file of ["worker.ts", "runner-manager.ts"]) {
|
|
43
|
+
it(`${file} registers the activity end and resolves the workflow end`, () => {
|
|
44
|
+
const { specifiers, source } = root(file);
|
|
45
|
+
expect(
|
|
46
|
+
specifiers,
|
|
47
|
+
`${file} must import the activity interceptor`,
|
|
48
|
+
).toContain(ACTIVITY_END);
|
|
49
|
+
expect(
|
|
50
|
+
source,
|
|
51
|
+
`${file} must place runCredentialActivityInterceptor in its activity interceptors`,
|
|
52
|
+
).toMatch(
|
|
53
|
+
/ActivityInterceptorsFactory\[\]\s*=\s*\[runCredentialActivityInterceptor\]/,
|
|
54
|
+
);
|
|
55
|
+
expect(
|
|
56
|
+
source,
|
|
57
|
+
`${file} must resolve the workflow interceptor module`,
|
|
58
|
+
).toContain(`${WORKFLOW_END_RESOLVER}()`);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
it("scripts/bundle-slim.mjs bakes the workflow end into the pre-built bundle", () => {
|
|
63
|
+
const source = readSource(`${RUNNER_ROOT}scripts/bundle-slim.mjs`);
|
|
64
|
+
expect(source).toMatch(
|
|
65
|
+
new RegExp(
|
|
66
|
+
`workflowInterceptorModules:\\s*\\[\\s*${WORKFLOW_END_RESOLVER}\\(\\)`,
|
|
67
|
+
),
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("the workflow end is a sandbox module: it imports nothing from Node", () => {
|
|
72
|
+
const path = `${SRC_ROOT}workflows/interceptors/run-credential.ts`;
|
|
73
|
+
const nodeImports = moduleSpecifiers(path, readSource(path)).filter((s) =>
|
|
74
|
+
s.startsWith("node:"),
|
|
75
|
+
);
|
|
76
|
+
expect(nodeImports).toEqual([]);
|
|
77
|
+
const wirePath = `${SRC_ROOT}shared/run-credential.ts`;
|
|
78
|
+
expect(moduleSpecifiers(wirePath, readSource(wirePath))).toEqual([]);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -33,7 +33,7 @@ describe("mapManagerOptionsToConfig", () => {
|
|
|
33
33
|
expect(config.checkpointerType).toBe("http");
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
it("binds the proxy credential to the runner-token ref, never the control-plane ref
|
|
36
|
+
it("binds the proxy credential to the runner-token ref, never the control-plane ref", () => {
|
|
37
37
|
const tokenRef = { current: "control-plane-token" };
|
|
38
38
|
const runnerTokenRef = { current: "control-plane-token" };
|
|
39
39
|
const config = mapManagerOptionsToConfig(
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GenerateSessionSubject activity's wire contract: one argument in one of
|
|
3
|
+
* two shapes — the positional execution id every server has sent, and the
|
|
4
|
+
* typed object a server sends when the dispatch carries the run credential.
|
|
5
|
+
* Both reach the same core with the same execution id; the credential is the
|
|
6
|
+
* activity boundary's business, not this activity's (the header explains).
|
|
7
|
+
*
|
|
8
|
+
* The client is the hermetic module seam (`__test-utils__/hermetic-activity.ts`)
|
|
9
|
+
* because the factory constructs its own `StigmerClient`; the LLM seam is
|
|
10
|
+
* module-mocked to return a fixed title.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { describe, expect, it, vi } from "vitest";
|
|
14
|
+
import type { StigmerClient } from "../../client/stigmer-client.js";
|
|
15
|
+
import { bindHermeticClient } from "../../__test-utils__/hermetic-activity.js";
|
|
16
|
+
import { mockStigmerClient } from "../../__test-utils__/mock-client.js";
|
|
17
|
+
|
|
18
|
+
vi.mock("../../client/stigmer-client.js", async () =>
|
|
19
|
+
(
|
|
20
|
+
await import("../../__test-utils__/hermetic-activity.js")
|
|
21
|
+
).hermeticStigmerClientModule(),
|
|
22
|
+
);
|
|
23
|
+
vi.mock("../../shared/model-registry.js", () => ({
|
|
24
|
+
getSummarizationModel: vi.fn(async (primary: string) => primary),
|
|
25
|
+
}));
|
|
26
|
+
vi.mock("../../shared/model-client.js", () => ({
|
|
27
|
+
buildChatModel: vi.fn(async () => ({
|
|
28
|
+
model: { invoke: vi.fn(async () => ({ content: "Indexing Basics" })) },
|
|
29
|
+
})),
|
|
30
|
+
}));
|
|
31
|
+
vi.mock("../../shared/llm-backend.js", () => ({
|
|
32
|
+
checkDirectCredentials: vi.fn(() => null),
|
|
33
|
+
}));
|
|
34
|
+
vi.mock("../../shared/llm-proxy.js", () => ({
|
|
35
|
+
tryInferProvider: vi.fn(() => "anthropic"),
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
import {
|
|
39
|
+
AUTO_CREATED_SUBJECT,
|
|
40
|
+
createGenerateSessionSubjectActivities,
|
|
41
|
+
} from "../generate-session-subject.js";
|
|
42
|
+
import type { Config } from "../../config.js";
|
|
43
|
+
|
|
44
|
+
const EXECUTION_ID = "aex_wire_1";
|
|
45
|
+
|
|
46
|
+
function clientReadingExecution(): {
|
|
47
|
+
client: StigmerClient;
|
|
48
|
+
reads: string[];
|
|
49
|
+
titled: string[];
|
|
50
|
+
} {
|
|
51
|
+
const reads: string[] = [];
|
|
52
|
+
const titled: string[] = [];
|
|
53
|
+
const client = mockStigmerClient({
|
|
54
|
+
getExecution: vi.fn(async (executionId: string) => {
|
|
55
|
+
reads.push(executionId);
|
|
56
|
+
return {
|
|
57
|
+
spec: {
|
|
58
|
+
sessionId: "ses_1",
|
|
59
|
+
agentId: "agt_1",
|
|
60
|
+
message: "How do indexes work?",
|
|
61
|
+
},
|
|
62
|
+
} as never;
|
|
63
|
+
}),
|
|
64
|
+
getSession: vi.fn(
|
|
65
|
+
async () =>
|
|
66
|
+
({
|
|
67
|
+
spec: { subject: AUTO_CREATED_SUBJECT, agentInstanceId: "" },
|
|
68
|
+
}) as never,
|
|
69
|
+
),
|
|
70
|
+
getAgent: vi.fn(
|
|
71
|
+
async () =>
|
|
72
|
+
({ metadata: { name: "a" }, spec: { description: "" } }) as never,
|
|
73
|
+
),
|
|
74
|
+
updateSessionSubject: vi.fn(async (_sessionId: string, subject: string) => {
|
|
75
|
+
titled.push(subject);
|
|
76
|
+
return {} as never;
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
return { client, reads, titled };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function activityUnderTest() {
|
|
83
|
+
const { client, reads, titled } = clientReadingExecution();
|
|
84
|
+
bindHermeticClient(client);
|
|
85
|
+
const config = {
|
|
86
|
+
stigmerBackendEndpoint: "http://localhost:0",
|
|
87
|
+
stigmerToken: null,
|
|
88
|
+
proxyEndpoint: null,
|
|
89
|
+
primaryModel: "claude-sonnet-4.5",
|
|
90
|
+
} as unknown as Config;
|
|
91
|
+
const { GenerateSessionSubject } =
|
|
92
|
+
createGenerateSessionSubjectActivities(config);
|
|
93
|
+
return { GenerateSessionSubject, reads, titled };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
describe("GenerateSessionSubject wire shapes", () => {
|
|
97
|
+
it("accepts the positional execution id — every earlier server's shape", async () => {
|
|
98
|
+
const { GenerateSessionSubject, reads, titled } = activityUnderTest();
|
|
99
|
+
await GenerateSessionSubject(EXECUTION_ID);
|
|
100
|
+
expect(reads).toEqual([EXECUTION_ID]);
|
|
101
|
+
expect(titled).toEqual(["Indexing Basics"]);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("accepts the typed object carrying the run credential and reads the same execution", async () => {
|
|
105
|
+
const { GenerateSessionSubject, reads, titled } = activityUnderTest();
|
|
106
|
+
await GenerateSessionSubject({
|
|
107
|
+
execution_id: EXECUTION_ID,
|
|
108
|
+
execution_context_token: "run-cred",
|
|
109
|
+
});
|
|
110
|
+
expect(reads).toEqual([EXECUTION_ID]);
|
|
111
|
+
expect(titled).toEqual(["Indexing Basics"]);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("accepts the typed object without a credential", async () => {
|
|
115
|
+
const { GenerateSessionSubject, reads } = activityUnderTest();
|
|
116
|
+
await GenerateSessionSubject({ execution_id: EXECUTION_ID });
|
|
117
|
+
expect(reads).toEqual([EXECUTION_ID]);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The scripted `@cursor/sdk` double's own arms — the surface the harness
|
|
3
|
-
* contract kit's Cursor subject drives, added
|
|
3
|
+
* contract kit's Cursor subject drives, added in #1070 beside the golden
|
|
4
4
|
* scenarios' declared-up-front surface (which the seventeen goldens prove).
|
|
5
5
|
*
|
|
6
6
|
* - `arrangeNextTurn` writes the slot the NEXT `send()` consumes, replaces a
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The Cursor harness as a `HarnessContractSubject` — the REAL `createCursorAdapter()`
|
|
3
3
|
* driven through the harness contract kit, with the kit's engine-neutral
|
|
4
|
-
* scenario vocabulary translated onto
|
|
4
|
+
* scenario vocabulary translated onto the scripted `@cursor/sdk` double (#1048).
|
|
5
5
|
*
|
|
6
6
|
* The sibling of `gateway-substrate.ts` (the Cursor side of the approval
|
|
7
7
|
* contract kit): the kit owns the invariants and the runtime stand-in, this
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
* Every script that does not end in `fail`, `cancelled` or `hang` closes with
|
|
60
60
|
* `finished({ result: <last say> })` so `run.wait()` has an answer.
|
|
61
61
|
*
|
|
62
|
-
* ── Two modelling decisions (
|
|
62
|
+
* ── Two modelling decisions (#1070) ─────────────────────────────────────────
|
|
63
63
|
* A `propose` for an id this subject has already seen the hook ALLOW emits
|
|
64
64
|
* nothing: the real SDK does not re-run a completed tool on resume — the parked
|
|
65
65
|
* agent's conversation already holds the tool's result. A `propose` whose id
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive Cursor SDK events through the REAL pair the harness runs in production
|
|
3
|
+
* — `CursorTranslator` into `TranscriptBuilder` over an `AgentExecutionStatus`
|
|
4
|
+
* — and hand back what they built. The unit-test seam that replaced
|
|
5
|
+
* `new <accumulator>(messages, options)` in #1097 (the accumulator folded
|
|
6
|
+
* rows itself; now the translator emits events and the shared builder folds
|
|
7
|
+
* them), so the arms that read a row's shape after a sequence of SDK events
|
|
8
|
+
* keep their shape while the module under them changed.
|
|
9
|
+
*
|
|
10
|
+
* The same shape as the native translator's local `feedAll` in
|
|
11
|
+
* `execute-deep-agent/__tests__/translator-through-builder.test.ts`, shared
|
|
12
|
+
* here because seven Cursor test files read through it.
|
|
13
|
+
*
|
|
14
|
+
* Deltas follow the loop's discipline (`turn-stream.ts`): `observeDelta`
|
|
15
|
+
* queues, and the queue is drained into the builder after the NEXT stream
|
|
16
|
+
* event — or at {@link CursorFold.drain} for a caller that wants them applied
|
|
17
|
+
* now, the settle's own last drain before `finalize()`.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { create } from "@bufbuild/protobuf";
|
|
21
|
+
import type { InteractionUpdate, SDKMessage } from "@cursor/sdk";
|
|
22
|
+
import { AgentExecutionStatusSchema, type AgentExecutionStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
23
|
+
import type { AgentMessage, ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
24
|
+
import { TranscriptBuilder } from "../../../harness/transcript/builder.js";
|
|
25
|
+
import { CursorTranslator, type CursorTranslatorOptions } from "../translator.js";
|
|
26
|
+
|
|
27
|
+
export interface CursorFoldOptions {
|
|
28
|
+
/** The status to build into; a fresh empty one when omitted. Its `messages` are the translator's seed. */
|
|
29
|
+
readonly status?: AgentExecutionStatus;
|
|
30
|
+
/**
|
|
31
|
+
* An existing `messages` array to build into BY REFERENCE (a test that
|
|
32
|
+
* hand-built its seeded rows and keeps asserting on the same objects). Wins
|
|
33
|
+
* over `status`'s own array.
|
|
34
|
+
*/
|
|
35
|
+
readonly messages?: AgentMessage[];
|
|
36
|
+
readonly policies?: CursorTranslatorOptions["policies"];
|
|
37
|
+
readonly leases?: CursorTranslatorOptions["leases"];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export class CursorFold {
|
|
41
|
+
readonly status: AgentExecutionStatus;
|
|
42
|
+
readonly translator: CursorTranslator;
|
|
43
|
+
readonly builder: TranscriptBuilder;
|
|
44
|
+
|
|
45
|
+
constructor(options: CursorFoldOptions = {}) {
|
|
46
|
+
this.status = options.status ?? create(AgentExecutionStatusSchema, {});
|
|
47
|
+
if (options.messages) this.status.messages = options.messages;
|
|
48
|
+
this.translator = new CursorTranslator({
|
|
49
|
+
policies: options.policies ?? new Map(),
|
|
50
|
+
leases: options.leases ?? { global: false, categories: new Set() },
|
|
51
|
+
seeded: this.status.messages,
|
|
52
|
+
});
|
|
53
|
+
this.builder = new TranscriptBuilder("exec-fold", this.status);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** One stream event, translated and folded, then the deltas queued so far — the loop's order. */
|
|
57
|
+
event(event: SDKMessage): this {
|
|
58
|
+
for (const e of this.translator.translate(event)) this.builder.apply(e);
|
|
59
|
+
this.drain();
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
events(...events: SDKMessage[]): this {
|
|
64
|
+
for (const e of events) this.event(e);
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** One delta, queued — applied at the next {@link event} or {@link drain}. */
|
|
69
|
+
delta(update: InteractionUpdate): this {
|
|
70
|
+
this.translator.observeDelta(update);
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
drain(): this {
|
|
75
|
+
for (const e of this.translator.drainDeltas()) this.builder.apply(e);
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
finalize(): this {
|
|
80
|
+
this.drain();
|
|
81
|
+
this.builder.finalize();
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get messages(): AgentMessage[] {
|
|
86
|
+
return this.status.messages;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Every root row, in transcript order. */
|
|
90
|
+
rows(): ToolCall[] {
|
|
91
|
+
return this.status.messages.flatMap((m) => m.toolCalls);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
row(callId: string): ToolCall {
|
|
95
|
+
const found = this.rows().find((tc) => tc.id === callId);
|
|
96
|
+
if (!found) throw new Error(`CursorFold: no row ${callId}`);
|
|
97
|
+
return found;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Fold a sequence of stream events into a fresh transcript; the common one-liner. */
|
|
102
|
+
export function foldCursorEvents(events: readonly SDKMessage[], options: CursorFoldOptions = {}): CursorFold {
|
|
103
|
+
return new CursorFold(options).events(...events);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* A builder over an existing `messages` array, kept BY REFERENCE (the status
|
|
108
|
+
* is given the array itself, never a copy), so a boundary test that built its
|
|
109
|
+
* rows by hand can hand them to `reconcileDeniedToolCalls` and keep asserting
|
|
110
|
+
* on the same objects.
|
|
111
|
+
*/
|
|
112
|
+
export function builderOver(messages: AgentMessage[], executionId = "exec-boundary"): TranscriptBuilder {
|
|
113
|
+
const status = create(AgentExecutionStatusSchema, {});
|
|
114
|
+
status.messages = messages;
|
|
115
|
+
return new TranscriptBuilder(executionId, status);
|
|
116
|
+
}
|
|
@@ -80,7 +80,7 @@ export function createCursorSubstrate(): GatewaySubstrate {
|
|
|
80
80
|
enforcesExactContent: true,
|
|
81
81
|
appliesRunLifetimeLease: true,
|
|
82
82
|
// The Cursor hook's deny decision does not carry approval_policy_source;
|
|
83
|
-
// provenance is projected at
|
|
83
|
+
// provenance is projected at translation time (the Cursor translator)
|
|
84
84
|
// and asserted by the corpus + resolveApprovalProvenance suites instead.
|
|
85
85
|
surfacesGatePolicySource: false,
|
|
86
86
|
},
|