@stigmer/runner 3.14.1 → 3.15.1
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/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/execution-record-fixture.d.ts +47 -0
- package/dist/__test-utils__/execution-record-fixture.js +68 -0
- package/dist/__test-utils__/execution-record-fixture.js.map +1 -0
- package/dist/__test-utils__/harness-contract/types.d.ts +166 -0
- package/dist/__test-utils__/harness-contract/types.js +49 -0
- package/dist/__test-utils__/harness-contract/types.js.map +1 -0
- package/dist/__test-utils__/hermetic-activity.d.ts +28 -5
- package/dist/__test-utils__/hermetic-activity.js +23 -7
- package/dist/__test-utils__/hermetic-activity.js.map +1 -1
- package/dist/__test-utils__/mock-workspace.d.ts +15 -0
- package/dist/__test-utils__/mock-workspace.js +21 -0
- package/dist/__test-utils__/mock-workspace.js.map +1 -0
- package/dist/__test-utils__/model-registry-fixture.d.ts +56 -0
- package/dist/__test-utils__/model-registry-fixture.js +66 -0
- package/dist/__test-utils__/model-registry-fixture.js.map +1 -0
- package/dist/__test-utils__/turn-input-fixture.d.ts +60 -0
- package/dist/__test-utils__/turn-input-fixture.js +118 -0
- package/dist/__test-utils__/turn-input-fixture.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.d.ts +107 -0
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +344 -0
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +20 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +58 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +2 -32
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +38 -62
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +47 -121
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +17 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +27 -4
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.d.ts +52 -11
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js +66 -7
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +55 -0
- package/dist/activities/execute-cursor/adapter.js +119 -0
- package/dist/activities/execute-cursor/adapter.js.map +1 -0
- package/dist/activities/execute-cursor/approval-state.d.ts +2 -2
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/capture-flow.d.ts +15 -30
- package/dist/activities/execute-cursor/capture-flow.js +17 -26
- package/dist/activities/execute-cursor/capture-flow.js.map +1 -1
- package/dist/activities/execute-cursor/cursor-capabilities.d.ts +23 -0
- package/dist/activities/execute-cursor/cursor-capabilities.js +33 -0
- package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -0
- package/dist/activities/execute-cursor/cursor-mcp-config.d.ts +2 -2
- package/dist/activities/execute-cursor/cursor-mcp-config.js.map +1 -1
- package/dist/activities/execute-cursor/fetch-interceptor.d.ts +15 -25
- package/dist/activities/execute-cursor/fetch-interceptor.js +39 -33
- package/dist/activities/execute-cursor/fetch-interceptor.js.map +1 -1
- package/dist/activities/execute-cursor/http2-interceptor.d.ts +21 -17
- package/dist/activities/execute-cursor/http2-interceptor.js +38 -31
- package/dist/activities/execute-cursor/http2-interceptor.js.map +1 -1
- package/dist/activities/execute-cursor/message-translator.d.ts +28 -19
- package/dist/activities/execute-cursor/message-translator.js +76 -27
- package/dist/activities/execute-cursor/message-translator.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +180 -11
- package/dist/activities/execute-cursor/prompt-builder.js +171 -0
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/rejection-capture.d.ts +3 -6
- package/dist/activities/execute-cursor/rejection-capture.js +5 -7
- package/dist/activities/execute-cursor/rejection-capture.js.map +1 -1
- package/dist/activities/execute-cursor/session-lifecycle.d.ts +1 -4
- package/dist/activities/execute-cursor/session-lifecycle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-boundary.d.ts +1 -1
- package/dist/activities/execute-cursor/turn-settle.d.ts +49 -0
- package/dist/activities/execute-cursor/turn-settle.js +507 -0
- package/dist/activities/execute-cursor/turn-settle.js.map +1 -0
- package/dist/activities/execute-cursor/turn-setup.d.ts +173 -0
- package/dist/activities/execute-cursor/turn-setup.js +496 -0
- package/dist/activities/execute-cursor/turn-setup.js.map +1 -0
- package/dist/activities/execute-cursor/turn-stream.d.ts +41 -71
- package/dist/activities/execute-cursor/turn-stream.js +70 -135
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-cursor/turn.d.ts +43 -0
- package/dist/activities/execute-cursor/turn.js +222 -0
- package/dist/activities/execute-cursor/turn.js.map +1 -0
- package/dist/activities/execute-cursor/usage-pricing.d.ts +38 -0
- package/dist/activities/execute-cursor/usage-pricing.js +50 -0
- package/dist/activities/execute-cursor/usage-pricing.js.map +1 -0
- package/dist/activities/execute-deep-agent/approval-file-change.d.ts +1 -1
- package/dist/activities/execute-deep-agent/approval-file-change.js +1 -1
- package/dist/activities/execute-deep-agent/environment.js +1 -1
- package/dist/activities/execute-deep-agent/environment.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.js +3 -2
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/activities/hydrate-workflow-execution.js +1 -1
- package/dist/activities/hydrate-workflow-execution.js.map +1 -1
- package/dist/config.d.ts +15 -0
- package/dist/config.js.map +1 -1
- package/dist/harness/capabilities.d.ts +16 -0
- package/dist/harness/capabilities.js +1 -0
- package/dist/harness/capabilities.js.map +1 -1
- package/dist/harness/persist-chokepoint.d.ts +74 -0
- package/dist/harness/persist-chokepoint.js +88 -0
- package/dist/harness/persist-chokepoint.js.map +1 -0
- package/dist/harness/registry.d.ts +44 -5
- package/dist/harness/registry.js +61 -5
- package/dist/harness/registry.js.map +1 -1
- package/dist/harness/run-turn.d.ts +53 -0
- package/dist/harness/run-turn.js +528 -0
- package/dist/harness/run-turn.js.map +1 -0
- package/dist/harness/stop-controller.d.ts +50 -0
- package/dist/harness/stop-controller.js +62 -0
- package/dist/harness/stop-controller.js.map +1 -0
- package/dist/harness/terminal-table.d.ts +141 -0
- package/dist/harness/terminal-table.js +239 -0
- package/dist/harness/terminal-table.js.map +1 -0
- package/dist/harness/turn-context.d.ts +523 -0
- package/dist/harness/turn-context.js +739 -0
- package/dist/harness/turn-context.js.map +1 -0
- package/dist/harness/types.d.ts +232 -52
- package/dist/harness/types.js +17 -8
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage-accumulator.d.ts +68 -0
- package/dist/harness/usage-accumulator.js +101 -0
- package/dist/harness/usage-accumulator.js.map +1 -0
- package/dist/harness-adapters.d.ts +27 -0
- package/dist/harness-adapters.js +28 -0
- package/dist/harness-adapters.js.map +1 -0
- package/dist/main.js.map +1 -1
- package/dist/runner-manager.js +64 -48
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.d.ts +5 -4
- package/dist/runner.js +65 -64
- package/dist/runner.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +1 -1
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/{activities/execute-cursor → shared}/attachment-resolver.d.ts +2 -2
- package/dist/{activities/execute-cursor → shared}/attachment-resolver.js +5 -5
- package/dist/shared/attachment-resolver.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/blueprint-resolver.d.ts +7 -5
- package/dist/{activities/execute-cursor → shared}/blueprint-resolver.js +3 -63
- package/dist/shared/blueprint-resolver.js.map +1 -0
- package/dist/shared/channel-attachment.d.ts +1 -1
- package/dist/shared/channel-attachment.js.map +1 -1
- package/dist/{activities/execute-cursor → shared}/cost-guard.d.ts +5 -1
- package/dist/{activities/execute-cursor → shared}/cost-guard.js +5 -1
- package/dist/shared/cost-guard.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/env-resolver.d.ts +1 -1
- package/dist/shared/env-resolver.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/exact-apply.d.ts +1 -1
- package/dist/{activities/execute-cursor → shared}/exact-apply.js +6 -6
- package/dist/shared/exact-apply.js.map +1 -0
- package/dist/shared/execution-context.d.ts +35 -0
- package/dist/shared/execution-context.js +38 -0
- package/dist/shared/execution-context.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/extract-structured-output.d.ts +5 -2
- package/dist/{activities/execute-cursor → shared}/extract-structured-output.js +9 -6
- package/dist/shared/extract-structured-output.js.map +1 -0
- package/dist/shared/filereview/capture.d.ts +1 -1
- package/dist/shared/filereview/capture.js +1 -1
- package/dist/shared/heartbeat.d.ts +13 -11
- package/dist/shared/heartbeat.js +14 -29
- package/dist/shared/heartbeat.js.map +1 -1
- package/dist/{activities/execute-cursor → shared}/persist-decision.d.ts +5 -2
- package/dist/{activities/execute-cursor → shared}/persist-decision.js +4 -1
- package/dist/shared/persist-decision.js.map +1 -0
- package/dist/{activities/execute-cursor → shared}/skill-resolver.d.ts +16 -3
- package/dist/{activities/execute-cursor → shared}/skill-resolver.js +12 -4
- package/dist/shared/skill-resolver.js.map +1 -0
- package/dist/shared/subagent-rows.d.ts +21 -0
- package/dist/shared/subagent-rows.js +34 -0
- package/dist/shared/subagent-rows.js.map +1 -0
- package/dist/shared/worker-shutdown.d.ts +43 -16
- package/dist/shared/worker-shutdown.js +28 -13
- package/dist/shared/worker-shutdown.js.map +1 -1
- package/dist/shared/workspace/platform-dir.d.ts +1 -1
- package/dist/shared/workspace/platform-dir.js +1 -1
- package/dist/shared/workspace/session-provision.d.ts +54 -0
- package/dist/{activities/execute-cursor/workspace-provision.js → shared/workspace/session-provision.js} +15 -12
- package/dist/shared/workspace/session-provision.js.map +1 -0
- package/package.json +4 -4
- package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +110 -14
- package/src/__test-utils__/execution-record-fixture.ts +104 -0
- package/src/__test-utils__/harness-boot-order-child.ts +58 -0
- package/src/__test-utils__/harness-contract/contract.ts +128 -83
- package/src/__test-utils__/harness-contract/recording-sink.ts +15 -4
- package/src/__test-utils__/harness-contract/runtime-contract.ts +666 -0
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +92 -32
- package/src/__test-utils__/harness-contract/types.ts +85 -9
- package/src/__test-utils__/hermetic-activity.ts +33 -8
- package/src/__test-utils__/model-registry-fixture.ts +72 -0
- package/src/__test-utils__/module-specifiers.ts +82 -0
- package/src/__test-utils__/turn-input-fixture.ts +155 -0
- package/src/__tests__/harness-boot-order.test.ts +77 -0
- package/src/__tests__/harness-contract.test.ts +7 -5
- package/src/__tests__/runner-manager.test.ts +18 -0
- package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +102 -0
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +396 -0
- package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +66 -0
- package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +2 -43
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +65 -145
- package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +30 -4
- package/src/activities/execute-cursor/__test-utils__/scripted-sdk.ts +96 -8
- package/src/activities/execute-cursor/__tests__/adapter-is-temporal-free.test.ts +45 -0
- package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +90 -0
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +7 -8
- package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +28 -1
- package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +64 -6
- 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/cost-cap.status.json +53 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/pause.status.json +1 -6
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/platform-stop.status.json +56 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/recovery-transport-timeout.status.json +48 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/run-cancelled.status.json +36 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/run-error-non-retryable.status.json +37 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +38 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/stall.status.json +59 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +79 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/worker-shutdown.status.json +2 -7
- package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +170 -0
- package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +22 -18
- package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/recovery-fresh-agent.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +286 -0
- package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +332 -0
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +193 -0
- package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +185 -0
- package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +151 -0
- package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +65 -35
- package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -40
- package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +171 -0
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +118 -243
- package/src/activities/execute-cursor/__tests__/usage-pricing.test.ts +84 -0
- package/src/activities/execute-cursor/adapter.ts +138 -0
- package/src/activities/execute-cursor/approval-state.ts +2 -2
- package/src/activities/execute-cursor/capture-flow.ts +18 -41
- package/src/activities/execute-cursor/cursor-capabilities.ts +35 -0
- package/src/activities/execute-cursor/cursor-mcp-config.ts +2 -2
- package/src/activities/execute-cursor/fetch-interceptor.ts +48 -45
- package/src/activities/execute-cursor/http2-interceptor.ts +47 -34
- package/src/activities/execute-cursor/message-translator.ts +90 -45
- package/src/activities/execute-cursor/prompt-builder.ts +327 -12
- package/src/activities/execute-cursor/rejection-capture.ts +5 -12
- package/src/activities/execute-cursor/session-lifecycle.ts +1 -5
- package/src/activities/execute-cursor/turn-boundary.ts +1 -1
- package/src/activities/execute-cursor/turn-settle.ts +601 -0
- package/src/activities/execute-cursor/turn-setup.ts +645 -0
- package/src/activities/execute-cursor/turn-stream.ts +84 -210
- package/src/activities/execute-cursor/turn.ts +240 -0
- package/src/activities/execute-cursor/usage-pricing.ts +67 -0
- package/src/activities/execute-deep-agent/approval-file-change.ts +1 -1
- package/src/activities/execute-deep-agent/environment.ts +1 -1
- package/src/activities/execute-deep-agent/setup.ts +3 -2
- package/src/activities/hydrate-workflow-execution.ts +1 -1
- package/src/config.ts +13 -0
- package/src/harness/__tests__/import-direction.test.ts +168 -0
- package/src/harness/__tests__/persist-chokepoint.test.ts +146 -0
- package/src/harness/__tests__/registry.test.ts +1 -0
- package/src/harness/__tests__/run-turn.test.ts +165 -0
- package/src/harness/__tests__/stop-controller.test.ts +49 -0
- package/src/harness/__tests__/turn-context.test.ts +178 -0
- package/src/harness/__tests__/usage-accumulator.test.ts +83 -0
- package/src/harness/capabilities.ts +17 -0
- package/src/harness/persist-chokepoint.ts +112 -0
- package/src/harness/registry.ts +79 -5
- package/src/harness/run-turn.ts +618 -0
- package/src/harness/stop-controller.ts +83 -0
- package/src/harness/terminal-table.ts +276 -0
- package/src/harness/turn-context.ts +1028 -0
- package/src/harness/types.ts +248 -53
- package/src/harness/usage-accumulator.ts +122 -0
- package/src/harness-adapters.ts +30 -0
- package/src/main.ts +1 -1
- package/src/runner-manager.ts +68 -61
- package/src/runner.ts +67 -78
- package/src/shared/__tests__/attachment-naming.test.ts +1 -1
- package/src/{activities/execute-cursor → shared}/__tests__/attachment-resolver.test.ts +6 -4
- package/src/{activities/execute-cursor → shared}/__tests__/cost-guard.test.ts +2 -1
- package/src/{activities/execute-cursor → shared}/__tests__/exact-apply.test.ts +3 -3
- package/src/{activities/execute-cursor → shared}/__tests__/extract-structured-output.test.ts +8 -8
- package/src/{activities/execute-cursor → shared}/__tests__/persist-decision.test.ts +4 -2
- package/src/{activities/execute-cursor → shared}/__tests__/skill-resolver.test.ts +1 -1
- package/src/shared/__tests__/subagent-rows.test.ts +34 -0
- package/src/shared/__tests__/worker-shutdown.test.ts +44 -39
- package/src/shared/approval-policy.ts +1 -1
- package/src/{activities/execute-cursor → shared}/attachment-resolver.ts +6 -6
- package/src/{activities/execute-cursor → shared}/blueprint-resolver.ts +7 -78
- package/src/shared/channel-attachment.ts +1 -1
- package/src/{activities/execute-cursor → shared}/cost-guard.ts +5 -1
- package/src/{activities/execute-cursor → shared}/env-resolver.ts +1 -1
- package/src/{activities/execute-cursor → shared}/exact-apply.ts +7 -7
- package/src/shared/execution-context.ts +45 -0
- package/src/{activities/execute-cursor → shared}/extract-structured-output.ts +10 -7
- package/src/shared/filereview/capture.ts +1 -1
- package/src/shared/heartbeat.ts +13 -33
- package/src/{activities/execute-cursor → shared}/persist-decision.ts +5 -2
- package/src/{activities/execute-cursor → shared}/skill-resolver.ts +20 -6
- package/src/shared/subagent-rows.ts +39 -0
- package/src/shared/worker-shutdown.ts +55 -25
- package/src/{activities/execute-cursor/__tests__/workspace-provision.test.ts → shared/workspace/__tests__/session-provision.test.ts} +25 -28
- package/src/shared/workspace/platform-dir.ts +1 -1
- package/src/{activities/execute-cursor/workspace-provision.ts → shared/workspace/session-provision.ts} +29 -16
- package/dist/activities/execute-cursor/attachment-resolver.js.map +0 -1
- package/dist/activities/execute-cursor/blueprint-resolver.js.map +0 -1
- package/dist/activities/execute-cursor/cost-guard.js.map +0 -1
- package/dist/activities/execute-cursor/env-resolver.js.map +0 -1
- package/dist/activities/execute-cursor/exact-apply.js.map +0 -1
- package/dist/activities/execute-cursor/extract-structured-output.js.map +0 -1
- package/dist/activities/execute-cursor/index.d.ts +0 -209
- package/dist/activities/execute-cursor/index.js +0 -2345
- package/dist/activities/execute-cursor/index.js.map +0 -1
- package/dist/activities/execute-cursor/persist-decision.js.map +0 -1
- package/dist/activities/execute-cursor/skill-resolver.js.map +0 -1
- package/dist/activities/execute-cursor/usage-accumulator.d.ts +0 -89
- package/dist/activities/execute-cursor/usage-accumulator.js +0 -121
- package/dist/activities/execute-cursor/usage-accumulator.js.map +0 -1
- package/dist/activities/execute-cursor/workspace-provision.d.ts +0 -42
- package/dist/activities/execute-cursor/workspace-provision.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/usage-accumulator.test.ts +0 -164
- package/src/activities/execute-cursor/index.ts +0 -2876
- package/src/activities/execute-cursor/usage-accumulator.ts +0 -169
- /package/dist/{activities/execute-cursor → shared}/env-resolver.js +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model registry document a hermetic activity run reads, and the `fetch`
|
|
3
|
+
* stub that serves it and refuses everything else.
|
|
4
|
+
*
|
|
5
|
+
* The activity's only HTTP fetch is the model registry (`shared/model-
|
|
6
|
+
* registry.ts` for vision capability; the Cursor harness's `model-pricing-
|
|
7
|
+
* data.ts` for pricing). Both fail SOFT to defaults with a 60 s failure
|
|
8
|
+
* cache, which would make a golden depend on DEFAULT_PRICING and log a
|
|
9
|
+
* warning on every run, so a hermetic run stubs `fetch` to answer one
|
|
10
|
+
* registry document — and to THROW for any other URL, so a new network
|
|
11
|
+
* dependency on the activity path fails the run instead of leaking.
|
|
12
|
+
*
|
|
13
|
+
* One entry, `composer-2.5`, priced at round numbers so a golden's
|
|
14
|
+
* `estimatedCostUsd` is legible (600 000 input tokens = $0.60). The entry is
|
|
15
|
+
* a Cursor-harness model because that is what the registry lists; the
|
|
16
|
+
* document itself is the control plane's, read by every harness's runtime.
|
|
17
|
+
* `parsePricingTable` wants `harness: "cursor"` + `pricing`; `parseRegistry`
|
|
18
|
+
* wants `id` + `provider` and reads `capabilities.vision`.
|
|
19
|
+
*/
|
|
20
|
+
/** The pinned model of every hermetic run; in the registry document AND in the Cursor double's catalog. */
|
|
21
|
+
export declare const FIXTURE_MODEL = "composer-2.5";
|
|
22
|
+
export declare const REGISTRY_DOCUMENT: {
|
|
23
|
+
readonly models: readonly [{
|
|
24
|
+
readonly id: "composer-2.5";
|
|
25
|
+
readonly displayName: "Composer 2.5 (hermetic fixture)";
|
|
26
|
+
readonly provider: "cursor";
|
|
27
|
+
readonly harness: "cursor";
|
|
28
|
+
readonly costTier: "standard";
|
|
29
|
+
readonly featured: true;
|
|
30
|
+
readonly capabilities: {
|
|
31
|
+
readonly vision: true;
|
|
32
|
+
};
|
|
33
|
+
readonly pricing: {
|
|
34
|
+
readonly inputPricePerMillion: 1;
|
|
35
|
+
readonly outputPricePerMillion: 4;
|
|
36
|
+
readonly cacheWritePricePerMillion: 1;
|
|
37
|
+
readonly cacheReadPricePerMillion: 0.1;
|
|
38
|
+
};
|
|
39
|
+
readonly pricingVariants: {
|
|
40
|
+
readonly fast: {
|
|
41
|
+
readonly inputPricePerMillion: 3;
|
|
42
|
+
readonly outputPricePerMillion: 12;
|
|
43
|
+
readonly cacheWritePricePerMillion: 3;
|
|
44
|
+
readonly cacheReadPricePerMillion: 0.3;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}];
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Stub `fetch` to answer the registry document and refuse everything else.
|
|
51
|
+
* Returns the URLs fetched, for the "no other network" assertion.
|
|
52
|
+
*/
|
|
53
|
+
export declare function stubRegistryFetch(): {
|
|
54
|
+
readonly urls: string[];
|
|
55
|
+
restore(): void;
|
|
56
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model registry document a hermetic activity run reads, and the `fetch`
|
|
3
|
+
* stub that serves it and refuses everything else.
|
|
4
|
+
*
|
|
5
|
+
* The activity's only HTTP fetch is the model registry (`shared/model-
|
|
6
|
+
* registry.ts` for vision capability; the Cursor harness's `model-pricing-
|
|
7
|
+
* data.ts` for pricing). Both fail SOFT to defaults with a 60 s failure
|
|
8
|
+
* cache, which would make a golden depend on DEFAULT_PRICING and log a
|
|
9
|
+
* warning on every run, so a hermetic run stubs `fetch` to answer one
|
|
10
|
+
* registry document — and to THROW for any other URL, so a new network
|
|
11
|
+
* dependency on the activity path fails the run instead of leaking.
|
|
12
|
+
*
|
|
13
|
+
* One entry, `composer-2.5`, priced at round numbers so a golden's
|
|
14
|
+
* `estimatedCostUsd` is legible (600 000 input tokens = $0.60). The entry is
|
|
15
|
+
* a Cursor-harness model because that is what the registry lists; the
|
|
16
|
+
* document itself is the control plane's, read by every harness's runtime.
|
|
17
|
+
* `parsePricingTable` wants `harness: "cursor"` + `pricing`; `parseRegistry`
|
|
18
|
+
* wants `id` + `provider` and reads `capabilities.vision`.
|
|
19
|
+
*/
|
|
20
|
+
import { vi } from "vitest";
|
|
21
|
+
/** The pinned model of every hermetic run; in the registry document AND in the Cursor double's catalog. */
|
|
22
|
+
export const FIXTURE_MODEL = "composer-2.5";
|
|
23
|
+
export const REGISTRY_DOCUMENT = {
|
|
24
|
+
models: [
|
|
25
|
+
{
|
|
26
|
+
id: FIXTURE_MODEL,
|
|
27
|
+
displayName: "Composer 2.5 (hermetic fixture)",
|
|
28
|
+
provider: "cursor",
|
|
29
|
+
harness: "cursor",
|
|
30
|
+
costTier: "standard",
|
|
31
|
+
featured: true,
|
|
32
|
+
capabilities: { vision: true },
|
|
33
|
+
pricing: {
|
|
34
|
+
inputPricePerMillion: 1.0,
|
|
35
|
+
outputPricePerMillion: 4.0,
|
|
36
|
+
cacheWritePricePerMillion: 1.0,
|
|
37
|
+
cacheReadPricePerMillion: 0.1,
|
|
38
|
+
},
|
|
39
|
+
pricingVariants: {
|
|
40
|
+
fast: {
|
|
41
|
+
inputPricePerMillion: 3.0,
|
|
42
|
+
outputPricePerMillion: 12.0,
|
|
43
|
+
cacheWritePricePerMillion: 3.0,
|
|
44
|
+
cacheReadPricePerMillion: 0.3,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Stub `fetch` to answer the registry document and refuse everything else.
|
|
52
|
+
* Returns the URLs fetched, for the "no other network" assertion.
|
|
53
|
+
*/
|
|
54
|
+
export function stubRegistryFetch() {
|
|
55
|
+
const urls = [];
|
|
56
|
+
vi.stubGlobal("fetch", vi.fn(async (input) => {
|
|
57
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
58
|
+
urls.push(url);
|
|
59
|
+
if (!url.includes("/model-registry")) {
|
|
60
|
+
throw new Error(`hermetic run attempted a non-registry network call: ${url}`);
|
|
61
|
+
}
|
|
62
|
+
return { ok: true, status: 200, json: async () => REGISTRY_DOCUMENT };
|
|
63
|
+
}));
|
|
64
|
+
return { urls, restore: () => vi.unstubAllGlobals() };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=model-registry-fixture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-registry-fixture.js","sourceRoot":"","sources":["../../src/__test-utils__/model-registry-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B,2GAA2G;AAC3G,MAAM,CAAC,MAAM,aAAa,GAAG,cAAc,CAAC;AAE5C,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE;QACN;YACE,EAAE,EAAE,aAAa;YACjB,WAAW,EAAE,iCAAiC;YAC9C,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,QAAQ;YACjB,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;YAC9B,OAAO,EAAE;gBACP,oBAAoB,EAAE,GAAG;gBACzB,qBAAqB,EAAE,GAAG;gBAC1B,yBAAyB,EAAE,GAAG;gBAC9B,wBAAwB,EAAE,GAAG;aAC9B;YACD,eAAe,EAAE;gBACf,IAAI,EAAE;oBACJ,oBAAoB,EAAE,GAAG;oBACzB,qBAAqB,EAAE,IAAI;oBAC3B,yBAAyB,EAAE,GAAG;oBAC9B,wBAAwB,EAAE,GAAG;iBAC9B;aACF;SACF;KACF;CACO,CAAC;AAEX;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,EAAE,CAAC,UAAU,CACX,OAAO,EACP,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,KAA6B,EAAE,EAAE;QAC5C,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;QACpG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,uDAAuD,GAAG,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,iBAAiB,EAAyB,CAAC;IAC/F,CAAC,CAAC,CACH,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,gBAAgB,EAAE,EAAE,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A whole `TurnInput` for tests that stand in for the runtime.
|
|
3
|
+
*
|
|
4
|
+
* The contract's input is the runtime's entire resolved record (`harness/
|
|
5
|
+
* types.ts`): the execution and session protos, the blueprint, the
|
|
6
|
+
* environment, the workspace, the tool surface, the attachments, the model
|
|
7
|
+
* preferences, the standing context. A test that drives an adapter WITHOUT
|
|
8
|
+
* the runtime — the harness contract kit's `ExecutionDriver`, a unit test of
|
|
9
|
+
* one adapter step — needs a record that type-checks and is inert: empty
|
|
10
|
+
* protos, an empty tool surface, a workspace under the OS temp dir, a memory
|
|
11
|
+
* selection that answers nothing. Everything here is the neutral value;
|
|
12
|
+
* `overrides` deep-merges one level (a test states the fields it is about
|
|
13
|
+
* and nothing else), the way `testConfig()` does for `Config`.
|
|
14
|
+
*
|
|
15
|
+
* Nothing here is Cursor's or native's: the vision profile, the file-review
|
|
16
|
+
* identity and the state id source are the ADAPTER's capabilities, not
|
|
17
|
+
* input facts, so they do not appear.
|
|
18
|
+
*/
|
|
19
|
+
import { type AgentExecution, type AgentExecutionStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
20
|
+
import { type Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
|
|
21
|
+
import type { TurnInput } from "../harness/types.js";
|
|
22
|
+
import type { ResolvedBlueprint } from "../shared/blueprint-resolver.js";
|
|
23
|
+
/** The ids a fixture record carries when a test does not name its own. */
|
|
24
|
+
export declare const TURN_INPUT_FIXTURE_IDS: {
|
|
25
|
+
readonly executionId: "aex_fixture_0001";
|
|
26
|
+
readonly sessionId: "ses_fixture_0001";
|
|
27
|
+
readonly agentId: "agt_fixture_0001";
|
|
28
|
+
readonly org: "fixture-org";
|
|
29
|
+
};
|
|
30
|
+
export interface TurnInputFixtureOverrides extends Partial<Omit<TurnInput, "execution" | "session" | "blueprint">> {
|
|
31
|
+
readonly execution?: AgentExecution;
|
|
32
|
+
readonly session?: Session;
|
|
33
|
+
readonly blueprint?: Partial<ResolvedBlueprint>;
|
|
34
|
+
/**
|
|
35
|
+
* The user's message on the default execution's spec (ignored when a whole
|
|
36
|
+
* `execution` is given). Empty by default: the neutral record asks nothing.
|
|
37
|
+
*/
|
|
38
|
+
readonly message?: string;
|
|
39
|
+
/**
|
|
40
|
+
* The status the default execution carries — what the control plane
|
|
41
|
+
* persisted at the end of the previous invocation, on a reinvocation. The
|
|
42
|
+
* runtime seeds the turn's in-progress status from a clone of it
|
|
43
|
+
* (`seedTranscriptFromExecution`) and an adapter may read the record's own
|
|
44
|
+
* copy for its facts, so a test standing in for the runtime hands both.
|
|
45
|
+
*/
|
|
46
|
+
readonly persistedStatus?: AgentExecutionStatus;
|
|
47
|
+
/**
|
|
48
|
+
* Where the default workspace lives (ignored when a whole `workspace` is
|
|
49
|
+
* given). A test that only needs "my workspace is here" — because its
|
|
50
|
+
* engine writes into it — states the directory and nothing else of the
|
|
51
|
+
* provision record.
|
|
52
|
+
*/
|
|
53
|
+
readonly workspaceDir?: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The neutral record, with `overrides` laid over it one level deep. The
|
|
57
|
+
* `session` and `blueprint.session` are the SAME object, as the runtime
|
|
58
|
+
* guarantees (`bindHarnessState` writes it).
|
|
59
|
+
*/
|
|
60
|
+
export declare function turnInputFixture(overrides?: TurnInputFixtureOverrides): TurnInput;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A whole `TurnInput` for tests that stand in for the runtime.
|
|
3
|
+
*
|
|
4
|
+
* The contract's input is the runtime's entire resolved record (`harness/
|
|
5
|
+
* types.ts`): the execution and session protos, the blueprint, the
|
|
6
|
+
* environment, the workspace, the tool surface, the attachments, the model
|
|
7
|
+
* preferences, the standing context. A test that drives an adapter WITHOUT
|
|
8
|
+
* the runtime — the harness contract kit's `ExecutionDriver`, a unit test of
|
|
9
|
+
* one adapter step — needs a record that type-checks and is inert: empty
|
|
10
|
+
* protos, an empty tool surface, a workspace under the OS temp dir, a memory
|
|
11
|
+
* selection that answers nothing. Everything here is the neutral value;
|
|
12
|
+
* `overrides` deep-merges one level (a test states the fields it is about
|
|
13
|
+
* and nothing else), the way `testConfig()` does for `Config`.
|
|
14
|
+
*
|
|
15
|
+
* Nothing here is Cursor's or native's: the vision profile, the file-review
|
|
16
|
+
* identity and the state id source are the ADAPTER's capabilities, not
|
|
17
|
+
* input facts, so they do not appear.
|
|
18
|
+
*/
|
|
19
|
+
import { create } from "@bufbuild/protobuf";
|
|
20
|
+
import { tmpdir } from "node:os";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { AgentExecutionSchema, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
23
|
+
import { AgentExecutionSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
|
|
24
|
+
import { ServiceTier, ThinkingMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
25
|
+
import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
|
|
26
|
+
import { SessionSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/spec_pb";
|
|
27
|
+
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
28
|
+
import { AgentSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb";
|
|
29
|
+
import { ApiResourceMetadataSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/metadata_pb";
|
|
30
|
+
import { mockWorkspaceBackend } from "./mock-workspace.js";
|
|
31
|
+
/** The ids a fixture record carries when a test does not name its own. */
|
|
32
|
+
export const TURN_INPUT_FIXTURE_IDS = {
|
|
33
|
+
executionId: "aex_fixture_0001",
|
|
34
|
+
sessionId: "ses_fixture_0001",
|
|
35
|
+
agentId: "agt_fixture_0001",
|
|
36
|
+
org: "fixture-org",
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The neutral record, with `overrides` laid over it one level deep. The
|
|
40
|
+
* `session` and `blueprint.session` are the SAME object, as the runtime
|
|
41
|
+
* guarantees (`bindHarnessState` writes it).
|
|
42
|
+
*/
|
|
43
|
+
export function turnInputFixture(overrides = {}) {
|
|
44
|
+
const executionId = overrides.executionId ?? TURN_INPUT_FIXTURE_IDS.executionId;
|
|
45
|
+
const sessionId = overrides.sessionId ?? TURN_INPUT_FIXTURE_IDS.sessionId;
|
|
46
|
+
const session = overrides.session ??
|
|
47
|
+
create(SessionSchema, {
|
|
48
|
+
metadata: create(ApiResourceMetadataSchema, { id: sessionId, org: TURN_INPUT_FIXTURE_IDS.org, name: sessionId }),
|
|
49
|
+
spec: create(SessionSpecSchema, {}),
|
|
50
|
+
});
|
|
51
|
+
const execution = overrides.execution ??
|
|
52
|
+
create(AgentExecutionSchema, {
|
|
53
|
+
metadata: create(ApiResourceMetadataSchema, { id: executionId, org: TURN_INPUT_FIXTURE_IDS.org, name: executionId }),
|
|
54
|
+
spec: create(AgentExecutionSpecSchema, { sessionId, message: overrides.message ?? "" }),
|
|
55
|
+
status: overrides.persistedStatus,
|
|
56
|
+
});
|
|
57
|
+
const agent = create(AgentSchema, {
|
|
58
|
+
metadata: create(ApiResourceMetadataSchema, {
|
|
59
|
+
id: TURN_INPUT_FIXTURE_IDS.agentId,
|
|
60
|
+
org: TURN_INPUT_FIXTURE_IDS.org,
|
|
61
|
+
name: "fixture-agent",
|
|
62
|
+
}),
|
|
63
|
+
spec: create(AgentSpecSchema, { instructions: "You are the fixture agent." }),
|
|
64
|
+
});
|
|
65
|
+
const workspaceDir = overrides.workspaceDir ?? join(tmpdir(), "stigmer-runner-turn-input-fixture");
|
|
66
|
+
const blueprint = {
|
|
67
|
+
agent,
|
|
68
|
+
agentSpec: agent.spec,
|
|
69
|
+
session,
|
|
70
|
+
sessionSpec: session.spec,
|
|
71
|
+
instructions: agent.spec.instructions,
|
|
72
|
+
subAgents: [],
|
|
73
|
+
mergedMcpServerUsages: [],
|
|
74
|
+
mergedSkillRefs: [],
|
|
75
|
+
cloudRepos: [],
|
|
76
|
+
...overrides.blueprint,
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
executionId,
|
|
80
|
+
threadId: overrides.threadId ?? "",
|
|
81
|
+
turnSeq: overrides.turnSeq ?? 0,
|
|
82
|
+
sessionId,
|
|
83
|
+
approvalDecisions: overrides.approvalDecisions ?? new Map(),
|
|
84
|
+
execution,
|
|
85
|
+
session,
|
|
86
|
+
blueprint,
|
|
87
|
+
environment: overrides.environment ?? { envVars: {}, secretKeys: new Set() },
|
|
88
|
+
workspace: overrides.workspace ?? {
|
|
89
|
+
dirs: [workspaceDir],
|
|
90
|
+
primaryDir: workspaceDir,
|
|
91
|
+
gitWorkspace: false,
|
|
92
|
+
captureMode: false,
|
|
93
|
+
changeSetId: `${executionId}:${overrides.turnSeq ?? 0}`,
|
|
94
|
+
provision: { workspaceDirs: [workspaceDir], provisionResults: [], workspaceBackend: mockWorkspaceBackend() },
|
|
95
|
+
},
|
|
96
|
+
mcp: overrides.mcp ?? {
|
|
97
|
+
servers: [],
|
|
98
|
+
channelMessaging: [],
|
|
99
|
+
leases: { global: false, categories: new Set(), servers: new Set() },
|
|
100
|
+
policies: new Map(),
|
|
101
|
+
},
|
|
102
|
+
skills: overrides.skills ?? [],
|
|
103
|
+
attachments: overrides.attachments ?? { results: [], visionImages: [], visionNotViewable: [] },
|
|
104
|
+
appliedToolCallIds: overrides.appliedToolCallIds ?? new Set(),
|
|
105
|
+
model: overrides.model ?? { requested: "default", serviceTier: ServiceTier.STANDARD, thinkingMode: ThinkingMode.DISABLED },
|
|
106
|
+
structuredOutputSchema: overrides.structuredOutputSchema,
|
|
107
|
+
standing: overrides.standing ?? {
|
|
108
|
+
contextBridge: undefined,
|
|
109
|
+
senderIdentity: undefined,
|
|
110
|
+
sessionContext: undefined,
|
|
111
|
+
declaredPreferences: undefined,
|
|
112
|
+
conversationCatchup: undefined,
|
|
113
|
+
selectRecalledMemories: async () => undefined,
|
|
114
|
+
},
|
|
115
|
+
artifactStorage: overrides.artifactStorage,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=turn-input-fixture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-input-fixture.js","sourceRoot":"","sources":["../../src/__test-utils__/turn-input-fixture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Cursor harness as a `HarnessContractSubject` — the REAL `createCursorAdapter()`
|
|
3
|
+
* driven through the harness contract kit, with the kit's engine-neutral
|
|
4
|
+
* scenario vocabulary translated onto S0's scripted `@cursor/sdk` double.
|
|
5
|
+
*
|
|
6
|
+
* The sibling of `gateway-substrate.ts` (the Cursor side of the approval
|
|
7
|
+
* contract kit): the kit owns the invariants and the runtime stand-in, this
|
|
8
|
+
* module owns the ENGINE — what the next turn of a session's agent will do —
|
|
9
|
+
* and reports what the double observed. The adapter under test is the
|
|
10
|
+
* production one, untouched; it imports no `@temporalio/*` (the fence test
|
|
11
|
+
* pins that), which is what lets the kit run it outside any activity
|
|
12
|
+
* context.
|
|
13
|
+
*
|
|
14
|
+
* ── The engine is per session ───────────────────────────────────────────────
|
|
15
|
+
* One scripted agent per session, minted when the kit first arranges a turn
|
|
16
|
+
* for it and handed out by the double's `Agent.create` for THAT session (keyed
|
|
17
|
+
* by the SDK's `platform.workspaceRef`, computed the way the adapter computes
|
|
18
|
+
* it), then parked by the real session cache across turns exactly as in a live
|
|
19
|
+
* worker. Arranging a turn REPLACES the agent's next script, so a turn the
|
|
20
|
+
* adapter interrupts before its `send()` leaves no stale script for the
|
|
21
|
+
* session's next turn. Every session also gets the workspace directory the
|
|
22
|
+
* runtime's provisioner would give it (`<workspaceRootDir>/sessions/<id>`), so
|
|
23
|
+
* both halves of the kit gate in the same directory shape; the hook's
|
|
24
|
+
* active-turn pointer is per workspace, so concurrent sessions cannot repoint
|
|
25
|
+
* each other's hook.
|
|
26
|
+
*
|
|
27
|
+
* ── The translation, one rule per word ──────────────────────────────────────
|
|
28
|
+
* - `say(text)` → an `assistant` event. A first send opens with the
|
|
29
|
+
* `system/init` event; a resumed send does not (the
|
|
30
|
+
* `deny-and-retry` turn-2 script is the precedent).
|
|
31
|
+
* - `propose(id, a)` → the STREAM tool call (`edit` / `shell` / `delete`, the
|
|
32
|
+
* kits' shared translation in `cursor-hook-harness.ts`),
|
|
33
|
+
* an `effect` that runs the REAL preToolUse hook the
|
|
34
|
+
* adapter installed against the session's workspace,
|
|
35
|
+
* and the call's completion event. `executionCount(id)`
|
|
36
|
+
* is the hook's `allow` answers for `id` — the SDK
|
|
37
|
+
* executes a tool iff the hook allows it, so this is the
|
|
38
|
+
* safety-critical observable. WHETHER the call is
|
|
39
|
+
* emitted is decided from the kit's view and this
|
|
40
|
+
* subject's own memory, as the model and the SDK would
|
|
41
|
+
* decide it (see {@link CursorContractSubject.proposeSteps}).
|
|
42
|
+
* - `read(id, path)` → the `read` tool call, the REAL hook (which allows it —
|
|
43
|
+
* a read is never gated) and the completion; counted as
|
|
44
|
+
* run. The discrete event the adapter's loop flushes a
|
|
45
|
+
* persist on.
|
|
46
|
+
* - `usage(delta)` → a `turn-ended` delta; the adapter prices it.
|
|
47
|
+
* - `hang` → an `effect` parked on the run's own `cancelled`
|
|
48
|
+
* status, which the adapter's stop-signal listener
|
|
49
|
+
* (`turn-stream.ts` `cancelOnStop`) produces. Never a
|
|
50
|
+
* timer. Resolves `whenHanging`.
|
|
51
|
+
* - `fail(msg, s)` → `engine`: the run ends `{ status: "error" }` and
|
|
52
|
+
* `run.wait()` carries the message; `internal`: an
|
|
53
|
+
* `effect` throws mid-stream (the adapter's catch
|
|
54
|
+
* classifies it). `actionable` is refused as a test bug:
|
|
55
|
+
* only the unattributed-hook-block path produces that
|
|
56
|
+
* surface, and the kit's invariants do not ask for it.
|
|
57
|
+
* - `cancelled` → an `effect` calling `run.cancel()` from the SDK side
|
|
58
|
+
* (the `run-cancelled` golden's shape).
|
|
59
|
+
* Every script that does not end in `fail`, `cancelled` or `hang` closes with
|
|
60
|
+
* `finished({ result: <last say> })` so `run.wait()` has an answer.
|
|
61
|
+
*
|
|
62
|
+
* ── Two modelling decisions (S2 M4, Q-M4-4) ─────────────────────────────────
|
|
63
|
+
* A `propose` for an id this subject has already seen the hook ALLOW emits
|
|
64
|
+
* nothing: the real SDK does not re-run a completed tool on resume — the parked
|
|
65
|
+
* agent's conversation already holds the tool's result. A `propose` whose id
|
|
66
|
+
* carries a SKIP or REJECT decision emits nothing either: the resume prompt
|
|
67
|
+
* tells the model the user declined the action and an obedient model moves
|
|
68
|
+
* on. Both are what "the engine re-reaches the same call" and "the turn
|
|
69
|
+
* continues" MEAN for a deny-and-retry harness; neither hides anything from
|
|
70
|
+
* the safety observable, because a fresh identical command from a
|
|
71
|
+
* disobedient model IS a new gated act and Cursor re-gates it — the subject
|
|
72
|
+
* file proves that with {@link CursorContractSubject.forceReissue}.
|
|
73
|
+
*
|
|
74
|
+
* The completion event a `propose` emits is scripted from the answer the hook
|
|
75
|
+
* is EXPECTED to give (deny for an undecided proposal, allow for an approved
|
|
76
|
+
* re-issue); the hook's actual answer is recorded at effect time and any
|
|
77
|
+
* disagreement is kept in {@link CursorContractSubject.hookDisagreements} for
|
|
78
|
+
* the subject file to assert empty — a hook that allows an undecided action
|
|
79
|
+
* would show up there AND in `executionCount`, never be papered over.
|
|
80
|
+
*/
|
|
81
|
+
import type { HarnessAdapter } from "../../../harness/types.js";
|
|
82
|
+
import type { HarnessContractSubject } from "../../../__test-utils__/harness-contract/types.js";
|
|
83
|
+
import type { HermeticEnvironment } from "../../../__test-utils__/hermetic-activity.js";
|
|
84
|
+
import { ScriptedCursorAgent } from "./scripted-agent.js";
|
|
85
|
+
import { ScriptedCursorSdk } from "./scripted-sdk.js";
|
|
86
|
+
export interface CursorContractSubject extends HarnessContractSubject {
|
|
87
|
+
readonly adapter: HarnessAdapter;
|
|
88
|
+
/** The SDK double the adapter is talking to, for the subject file's own observations. */
|
|
89
|
+
readonly sdk: ScriptedCursorSdk;
|
|
90
|
+
/** The scripted agent minted for a session, once the kit has arranged a turn for it. */
|
|
91
|
+
agentFor(sessionId: string): ScriptedCursorAgent | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* Make the NEXT `propose` of `toolCallId` emit its call whatever the
|
|
94
|
+
* decision or the memory says — the disobedient model, for the observation
|
|
95
|
+
* the kit's vocabulary cannot express.
|
|
96
|
+
*/
|
|
97
|
+
forceReissue(toolCallId: string): void;
|
|
98
|
+
/** Every proposal at which the hook answered other than the script expected; the subject file asserts it stays empty. */
|
|
99
|
+
readonly hookDisagreements: readonly string[];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Build the subject over one hermetic environment (the temp `HOME` the gate's
|
|
103
|
+
* per-session HITL artifacts land under, the temp workspace root). The
|
|
104
|
+
* environment is the caller's to create before and dispose after; the SDK
|
|
105
|
+
* double is bound for the module here, so a file holds one subject.
|
|
106
|
+
*/
|
|
107
|
+
export declare function createCursorContractSubject(env: HermeticEnvironment): CursorContractSubject;
|