@stigmer/runner 3.14.0 → 3.15.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/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 +268 -0
- package/dist/__test-utils__/hermetic-activity.js +385 -0
- package/dist/__test-utils__/hermetic-activity.js.map +1 -0
- package/dist/__test-utils__/mock-client.d.ts +13 -0
- package/dist/__test-utils__/mock-client.js +45 -0
- package/dist/__test-utils__/mock-client.js.map +1 -0
- 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 +148 -0
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +257 -0
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +183 -0
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +262 -0
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.d.ts +138 -0
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js +191 -0
- package/dist/activities/execute-cursor/__test-utils__/scripted-sdk.js.map +1 -0
- 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 +87 -0
- package/dist/harness/capabilities.js +37 -0
- package/dist/harness/capabilities.js.map +1 -0
- 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 +106 -0
- package/dist/harness/registry.js +168 -0
- package/dist/harness/registry.js.map +1 -0
- 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 +448 -0
- package/dist/harness/types.js +64 -0
- package/dist/harness/types.js.map +1 -0
- 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 +325 -0
- package/src/__test-utils__/config-fixture.ts +63 -0
- 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 +581 -0
- package/src/__test-utils__/harness-contract/recording-sink.ts +107 -0
- package/src/__test-utils__/harness-contract/runtime-contract.ts +666 -0
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +349 -0
- package/src/__test-utils__/harness-contract/types.ts +176 -0
- package/src/__test-utils__/hermetic-activity.ts +502 -0
- package/src/__test-utils__/model-registry-fixture.ts +72 -0
- package/src/__test-utils__/module-specifiers.ts +82 -0
- package/src/__test-utils__/proto-helpers.ts +25 -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 +27 -0
- 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 +342 -0
- package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +368 -0
- package/src/activities/execute-cursor/__test-utils__/scripted-sdk.ts +254 -0
- 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 +228 -0
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +180 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/cost-cap.status.json +53 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/deny-and-retry.turn1.status.json +55 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/deny-and-retry.turn2.status.json +77 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/file-review-capture.status.json +126 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/pause.status.json +40 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/plain-turn.status.json +48 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/platform-stop.status.json +56 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/recovery-fresh-agent.status.json +53 -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/tool-call.status.json +68 -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 +42 -0
- 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 +205 -0
- package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +171 -0
- package/src/activities/execute-cursor/__tests__/hermetic/recovery-fresh-agent.test.ts +156 -0
- 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 +137 -0
- 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 +168 -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 +92 -0
- package/src/harness/persist-chokepoint.ts +112 -0
- package/src/harness/registry.ts +197 -0
- 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 +473 -0
- 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
package/dist/.build-fingerprint
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"hash":"
|
|
1
|
+
{"hash":"2ac96be487c6ce2c","builtAt":"2026-09-13T09:42:32.154Z","fileCount":325}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The four resources of one execution, wired by id into the chain the turn
|
|
3
|
+
* runtime resolves (`execution.spec.sessionId` → `session.spec.
|
|
4
|
+
* agentInstanceId` → `agentInstance.spec.agentId` → the agent), as an
|
|
5
|
+
* `ExecutionRecord` the hermetic client answers from.
|
|
6
|
+
*
|
|
7
|
+
* Harness-agnostic: the record is the control plane's, and the runtime's
|
|
8
|
+
* phases read it the same way whatever engine runs the turn. A harness's
|
|
9
|
+
* driver supplies its own fixture ids and model (`execute-cursor/__test-
|
|
10
|
+
* utils__/hermetic-cursor.ts` `cursorExecutionRecord`); the runtime's own
|
|
11
|
+
* tests use the defaults. Ids are fixed so goldens are readable and
|
|
12
|
+
* byte-stable.
|
|
13
|
+
*/
|
|
14
|
+
import type { WorkspaceEntry } from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
|
|
15
|
+
import { ExecutionRecord, type ExecutionRecordInput } from "./hermetic-activity.js";
|
|
16
|
+
/** The ids a record's four resources carry. */
|
|
17
|
+
export interface ExecutionRecordIds {
|
|
18
|
+
readonly org: string;
|
|
19
|
+
readonly executionId: string;
|
|
20
|
+
readonly sessionId: string;
|
|
21
|
+
readonly agentInstanceId: string;
|
|
22
|
+
readonly agentId: string;
|
|
23
|
+
readonly agentName: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const DEFAULT_RECORD_IDS: ExecutionRecordIds;
|
|
26
|
+
export interface ExecutionRecordOptions {
|
|
27
|
+
/** The user's message for this execution. */
|
|
28
|
+
readonly message: string;
|
|
29
|
+
/** The agent's instructions (system prompt body). */
|
|
30
|
+
readonly instructions?: string;
|
|
31
|
+
/** Session workspace entries (a `local_path` entry turns on capture mode). */
|
|
32
|
+
readonly workspaceEntries?: WorkspaceEntry[];
|
|
33
|
+
/** The requested model; the pinned fixture model when omitted. */
|
|
34
|
+
readonly modelName?: string;
|
|
35
|
+
readonly autoApproveAll?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* `ExecutionConfig.max_cost_usd`: the per-message cost budget the runtime
|
|
38
|
+
* enforces as a hard stop (cost-guard.ts). Omitted or 0 = no cap, the
|
|
39
|
+
* proto's default. Priced against the registry fixture's round numbers, so
|
|
40
|
+
* a scenario can state its overrun exactly (600 000 input tokens = $0.60).
|
|
41
|
+
*/
|
|
42
|
+
readonly maxCostUsd?: number;
|
|
43
|
+
/** The control plane's STOP lever; see `ExecutionRecordInput.controlSignal`. */
|
|
44
|
+
readonly controlSignal?: ExecutionRecordInput["controlSignal"];
|
|
45
|
+
readonly ids?: ExecutionRecordIds;
|
|
46
|
+
}
|
|
47
|
+
export declare function executionRecordFixture(options: ExecutionRecordOptions): ExecutionRecord;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The four resources of one execution, wired by id into the chain the turn
|
|
3
|
+
* runtime resolves (`execution.spec.sessionId` → `session.spec.
|
|
4
|
+
* agentInstanceId` → `agentInstance.spec.agentId` → the agent), as an
|
|
5
|
+
* `ExecutionRecord` the hermetic client answers from.
|
|
6
|
+
*
|
|
7
|
+
* Harness-agnostic: the record is the control plane's, and the runtime's
|
|
8
|
+
* phases read it the same way whatever engine runs the turn. A harness's
|
|
9
|
+
* driver supplies its own fixture ids and model (`execute-cursor/__test-
|
|
10
|
+
* utils__/hermetic-cursor.ts` `cursorExecutionRecord`); the runtime's own
|
|
11
|
+
* tests use the defaults. Ids are fixed so goldens are readable and
|
|
12
|
+
* byte-stable.
|
|
13
|
+
*/
|
|
14
|
+
import { create } from "@bufbuild/protobuf";
|
|
15
|
+
import { AgentExecutionSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
16
|
+
import { AgentExecutionSpecSchema, ExecutionConfigSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
|
|
17
|
+
import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
|
|
18
|
+
import { SessionSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/spec_pb";
|
|
19
|
+
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
20
|
+
import { AgentSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb";
|
|
21
|
+
import { AgentInstanceSchema } from "@stigmer/protos/ai/stigmer/agentic/agentinstance/v1/api_pb";
|
|
22
|
+
import { AgentInstanceSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/agentinstance/v1/spec_pb";
|
|
23
|
+
import { ApiResourceMetadataSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/metadata_pb";
|
|
24
|
+
import { ExecutionRecord } from "./hermetic-activity.js";
|
|
25
|
+
import { FIXTURE_MODEL } from "./model-registry-fixture.js";
|
|
26
|
+
export const DEFAULT_RECORD_IDS = {
|
|
27
|
+
org: "hermetic-org",
|
|
28
|
+
executionId: "aex_hermetic_0001",
|
|
29
|
+
sessionId: "ses_hermetic_0001",
|
|
30
|
+
agentInstanceId: "ain_hermetic_0001",
|
|
31
|
+
agentId: "agt_hermetic_0001",
|
|
32
|
+
agentName: "hermetic-agent",
|
|
33
|
+
};
|
|
34
|
+
export function executionRecordFixture(options) {
|
|
35
|
+
const ids = options.ids ?? DEFAULT_RECORD_IDS;
|
|
36
|
+
const execution = create(AgentExecutionSchema, {
|
|
37
|
+
metadata: create(ApiResourceMetadataSchema, { id: ids.executionId, org: ids.org, name: ids.executionId }),
|
|
38
|
+
spec: create(AgentExecutionSpecSchema, {
|
|
39
|
+
sessionId: ids.sessionId,
|
|
40
|
+
message: options.message,
|
|
41
|
+
autoApproveAll: options.autoApproveAll ?? false,
|
|
42
|
+
executionConfig: create(ExecutionConfigSchema, {
|
|
43
|
+
modelName: options.modelName ?? FIXTURE_MODEL,
|
|
44
|
+
maxCostUsd: options.maxCostUsd ?? 0,
|
|
45
|
+
}),
|
|
46
|
+
}),
|
|
47
|
+
});
|
|
48
|
+
const session = create(SessionSchema, {
|
|
49
|
+
metadata: create(ApiResourceMetadataSchema, { id: ids.sessionId, org: ids.org, name: ids.sessionId }),
|
|
50
|
+
spec: create(SessionSpecSchema, {
|
|
51
|
+
agentInstanceId: ids.agentInstanceId,
|
|
52
|
+
workspaceEntries: options.workspaceEntries ?? [],
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
const agentInstance = create(AgentInstanceSchema, {
|
|
56
|
+
metadata: create(ApiResourceMetadataSchema, { id: ids.agentInstanceId, org: ids.org, name: ids.agentInstanceId }),
|
|
57
|
+
spec: create(AgentInstanceSpecSchema, { agentId: ids.agentId }),
|
|
58
|
+
});
|
|
59
|
+
const agent = create(AgentSchema, {
|
|
60
|
+
metadata: create(ApiResourceMetadataSchema, { id: ids.agentId, org: ids.org, name: ids.agentName }),
|
|
61
|
+
spec: create(AgentSpecSchema, {
|
|
62
|
+
description: "Hermetic fixture agent",
|
|
63
|
+
instructions: options.instructions ?? "You are the hermetic fixture agent. Answer briefly.",
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
return new ExecutionRecord({ execution, session, agentInstance, agent, controlSignal: options.controlSignal });
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=execution-record-fixture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-record-fixture.js","sourceRoot":"","sources":["../../src/__test-utils__/execution-record-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAuB,MAAM,6DAA6D,CAAC;AACxH,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,8DAA8D,CAAC;AAC/H,OAAO,EAAE,aAAa,EAAgB,MAAM,sDAAsD,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,uDAAuD,CAAC;AAE1F,OAAO,EAAE,WAAW,EAAc,MAAM,oDAAoD,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAE,MAAM,qDAAqD,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAsB,MAAM,4DAA4D,CAAC;AACrH,OAAO,EAAE,uBAAuB,EAAE,MAAM,6DAA6D,CAAC;AACtG,OAAO,EAAE,yBAAyB,EAAE,MAAM,4DAA4D,CAAC;AAEvG,OAAO,EAAE,eAAe,EAA6B,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAY5D,MAAM,CAAC,MAAM,kBAAkB,GAAuB;IACpD,GAAG,EAAE,cAAc;IACnB,WAAW,EAAE,mBAAmB;IAChC,SAAS,EAAE,mBAAmB;IAC9B,eAAe,EAAE,mBAAmB;IACpC,OAAO,EAAE,mBAAmB;IAC5B,SAAS,EAAE,gBAAgB;CAC5B,CAAC;AAwBF,MAAM,UAAU,sBAAsB,CAAC,OAA+B;IACpE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,kBAAkB,CAAC;IAC9C,MAAM,SAAS,GAAmB,MAAM,CAAC,oBAAoB,EAAE;QAC7D,QAAQ,EAAE,MAAM,CAAC,yBAAyB,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC;QACzG,IAAI,EAAE,MAAM,CAAC,wBAAwB,EAAE;YACrC,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,KAAK;YAC/C,eAAe,EAAE,MAAM,CAAC,qBAAqB,EAAE;gBAC7C,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,aAAa;gBAC7C,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;aACpC,CAAC;SACH,CAAC;KACH,CAAC,CAAC;IACH,MAAM,OAAO,GAAY,MAAM,CAAC,aAAa,EAAE;QAC7C,QAAQ,EAAE,MAAM,CAAC,yBAAyB,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;QACrG,IAAI,EAAE,MAAM,CAAC,iBAAiB,EAAE;YAC9B,eAAe,EAAE,GAAG,CAAC,eAAe;YACpC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,EAAE;SACjD,CAAC;KACH,CAAC,CAAC;IACH,MAAM,aAAa,GAAkB,MAAM,CAAC,mBAAmB,EAAE;QAC/D,QAAQ,EAAE,MAAM,CAAC,yBAAyB,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,eAAe,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC;QACjH,IAAI,EAAE,MAAM,CAAC,uBAAuB,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;KAChE,CAAC,CAAC;IACH,MAAM,KAAK,GAAU,MAAM,CAAC,WAAW,EAAE;QACvC,QAAQ,EAAE,MAAM,CAAC,yBAAyB,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;QACnG,IAAI,EAAE,MAAM,CAAC,eAAe,EAAE;YAC5B,WAAW,EAAE,wBAAwB;YACrC,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,qDAAqD;SAC5F,CAAC;KACH,CAAC,CAAC;IACH,OAAO,IAAI,eAAe,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;AACjH,CAAC"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The test-facing seam of the harness contract kit.
|
|
3
|
+
*
|
|
4
|
+
* `HarnessAdapter.runTurn(input, sink)` gives a test no way to make the
|
|
5
|
+
* engine DO anything: propose a gated action, emit usage, hang, fail. The
|
|
6
|
+
* approval-contract kit met the same problem with `GatewaySubstrate` — a
|
|
7
|
+
* small interface each real substrate adapts so one invariant catalog can
|
|
8
|
+
* drive all of them. This is that seam for harnesses: a
|
|
9
|
+
* {@link HarnessContractSubject} owns the ENGINE (what the next turn will
|
|
10
|
+
* do), and the kit owns everything the runtime would own (the sink, the
|
|
11
|
+
* `TurnInput`, the state id threading, the reinvocation).
|
|
12
|
+
*
|
|
13
|
+
* The scenario vocabulary is deliberately small and engine-neutral: it says
|
|
14
|
+
* what the kit needs to PROVOKE, never how an engine behaves. The scripted
|
|
15
|
+
* fake consumes it directly; a real harness's subject translates it onto that
|
|
16
|
+
* harness's own double (the Cursor subject onto the scripted `@cursor/sdk`
|
|
17
|
+
* agent of `execute-cursor/__test-utils__/`). One vocabulary, not one per
|
|
18
|
+
* engine, so the kit cannot drift from what the fake can do.
|
|
19
|
+
*
|
|
20
|
+
* Gated actions reuse `ProposedAction` from `approval-contract/types.ts`, the
|
|
21
|
+
* taxonomy-free action every enforcement substrate already translates, so the
|
|
22
|
+
* two kits speak of the same logical side effect and neither restates the
|
|
23
|
+
* HITL taxonomy.
|
|
24
|
+
*/
|
|
25
|
+
import type { ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
26
|
+
import type { Config } from "../../config.js";
|
|
27
|
+
import type { HarnessName } from "../../harness/registry.js";
|
|
28
|
+
import type { FailureSurface, HarnessAdapter, UsageDelta } from "../../harness/types.js";
|
|
29
|
+
import type { ProposedAction } from "../approval-contract/types.js";
|
|
30
|
+
import type { TurnInputFixtureOverrides } from "../turn-input-fixture.js";
|
|
31
|
+
/**
|
|
32
|
+
* One thing the engine does during a turn. A turn plays its steps in order
|
|
33
|
+
* and ends `completed` when none is left, unless a step ends it first.
|
|
34
|
+
*
|
|
35
|
+
* - `say`: the engine emits assistant text (a transcript row).
|
|
36
|
+
* - `propose`: the engine reaches a gated side effect identified by
|
|
37
|
+
* `toolCallId`. Undecided → the turn ends `awaiting_approval` and later
|
|
38
|
+
* steps do not run; APPROVE → the effect runs once and the turn continues;
|
|
39
|
+
* REJECT / SKIP → the effect never runs and the turn continues. WHICH
|
|
40
|
+
* kinds a harness gates is the harness's policy and the workspace's
|
|
41
|
+
* posture: a `shell` is gated by every harness in every posture; a `write`
|
|
42
|
+
* is gated only outside apply-then-review capture (a git tree, or artifact
|
|
43
|
+
* storage), so an arm that must gate on every subject proposes a `shell`.
|
|
44
|
+
* - `read`: the engine performs an UNGATED read of `path` — a tool-call row
|
|
45
|
+
* that runs at once, never pauses, and is the discrete event every harness
|
|
46
|
+
* flushes a persist on (the lever an arm pulls when it needs the control
|
|
47
|
+
* plane to answer a mid-turn persist).
|
|
48
|
+
* - `usage`: the engine reports one turn's token counts.
|
|
49
|
+
* - `hang`: the engine makes no further progress until told to stop. The
|
|
50
|
+
* step that the stop-signal invariants and the runtime's stall watchdog
|
|
51
|
+
* are built around; it must be parked on the signal, never on a timer.
|
|
52
|
+
* - `fail`: the engine fails with a message the adapter can name; the turn
|
|
53
|
+
* ends `failed` on the given surface (`engine` unless the scenario says
|
|
54
|
+
* otherwise — the runtime's three failure copies are its own invariant).
|
|
55
|
+
* - `cancelled`: the engine ends its own run cancelled with nothing to
|
|
56
|
+
* wait for (an SDK-side cancel); the turn ends `cancelled`.
|
|
57
|
+
*/
|
|
58
|
+
export type ScenarioStep = {
|
|
59
|
+
readonly kind: "say";
|
|
60
|
+
readonly text: string;
|
|
61
|
+
} | {
|
|
62
|
+
readonly kind: "propose";
|
|
63
|
+
readonly toolCallId: string;
|
|
64
|
+
readonly action: ProposedAction;
|
|
65
|
+
} | {
|
|
66
|
+
readonly kind: "read";
|
|
67
|
+
readonly toolCallId: string;
|
|
68
|
+
readonly path: string;
|
|
69
|
+
} | {
|
|
70
|
+
readonly kind: "usage";
|
|
71
|
+
readonly delta: UsageDelta;
|
|
72
|
+
} | {
|
|
73
|
+
readonly kind: "hang";
|
|
74
|
+
} | {
|
|
75
|
+
readonly kind: "fail";
|
|
76
|
+
readonly message: string;
|
|
77
|
+
readonly surface: FailureSurface;
|
|
78
|
+
} | {
|
|
79
|
+
readonly kind: "cancelled";
|
|
80
|
+
};
|
|
81
|
+
/** One turn's worth of engine behaviour. */
|
|
82
|
+
export type TurnScenario = readonly ScenarioStep[];
|
|
83
|
+
/** Step builders — the vocabulary a kit invariant reads as. */
|
|
84
|
+
export declare const scenario: {
|
|
85
|
+
readonly say: (text: string) => ScenarioStep;
|
|
86
|
+
readonly propose: (toolCallId: string, action: ProposedAction) => ScenarioStep;
|
|
87
|
+
readonly read: (toolCallId: string, path: string) => ScenarioStep;
|
|
88
|
+
readonly usage: (delta: UsageDelta) => ScenarioStep;
|
|
89
|
+
readonly hang: () => ScenarioStep;
|
|
90
|
+
readonly fail: (message: string, surface?: FailureSurface) => ScenarioStep;
|
|
91
|
+
readonly cancelled: () => ScenarioStep;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* What the engine can know about the turn it is about to play, handed to the
|
|
95
|
+
* subject with every {@link HarnessContractSubject.arrange}: which execution
|
|
96
|
+
* and session it serves (a real engine is per session — its handle is parked
|
|
97
|
+
* under the session, its workspace and hook state live under the session —
|
|
98
|
+
* so a subject arranges THAT session's engine, never "the next turn"), and
|
|
99
|
+
* the approval decisions the prompt will carry (the runtime's
|
|
100
|
+
* `approvalDecisionsOf` over the persisted status — the one reader both
|
|
101
|
+
* drivers call). A subject whose engine cannot re-run a settled action, or
|
|
102
|
+
* whose model is told not to perform a skipped one, reads its decision here
|
|
103
|
+
* instead of parsing the prompt for it.
|
|
104
|
+
*/
|
|
105
|
+
export interface EngineView {
|
|
106
|
+
readonly executionId: string;
|
|
107
|
+
readonly sessionId: string;
|
|
108
|
+
readonly approvalDecisions: ReadonlyMap<string, ApprovalAction>;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* What a subject may say about the record its engine is handed, laid UNDER
|
|
112
|
+
* the driver's own facts: the five it threads (`executionId`, `threadId`,
|
|
113
|
+
* `turnSeq`, `sessionId`, `approvalDecisions`) and the persisted status it
|
|
114
|
+
* seeds are the kit's bookkeeping and never a subject's to state.
|
|
115
|
+
*/
|
|
116
|
+
export type SubjectInputOverrides = Omit<TurnInputFixtureOverrides, "executionId" | "threadId" | "turnSeq" | "sessionId" | "approvalDecisions" | "persistedStatus">;
|
|
117
|
+
/**
|
|
118
|
+
* One adapter under test, with the engine controls the kit needs. Adapters
|
|
119
|
+
* translate scenarios into their own double's drives and report what the
|
|
120
|
+
* double observed; they never reimplement contract behaviour.
|
|
121
|
+
*
|
|
122
|
+
* The kit owns the adapter's lifetime: it boots the adapter before the first
|
|
123
|
+
* turn and shuts it down after the last (the registry boots every adapter
|
|
124
|
+
* before the worker polls, and a real adapter refuses a turn before boot).
|
|
125
|
+
* The exported assertion functions therefore REQUIRE a booted adapter.
|
|
126
|
+
*/
|
|
127
|
+
export interface HarnessContractSubject {
|
|
128
|
+
/** Stable name, used in suite titles and every assertion message. */
|
|
129
|
+
readonly name: string;
|
|
130
|
+
/** The registry row this adapter fills; the runtime half selects the activity by it. */
|
|
131
|
+
readonly harness: HarnessName;
|
|
132
|
+
/** The adapter under test — the real implementation of the contract. */
|
|
133
|
+
readonly adapter: HarnessAdapter;
|
|
134
|
+
/** What `adapter.boot` needs. The subject knows its adapter's fields; the kit does not. */
|
|
135
|
+
readonly config: Config;
|
|
136
|
+
/**
|
|
137
|
+
* Arrange the engine so that the NEXT `runTurn` for `view.sessionId` plays
|
|
138
|
+
* `turn` — REPLACING whatever was arranged for that session and not yet
|
|
139
|
+
* played (a turn interrupted before its engine ran leaves no stale script
|
|
140
|
+
* behind). Called by the kit before every `runTurn`, including a
|
|
141
|
+
* reinvocation (the engine re-reaches the same gated call on resume, so the
|
|
142
|
+
* same proposal is arranged again).
|
|
143
|
+
*/
|
|
144
|
+
arrange(turn: TurnScenario, view: EngineView): void;
|
|
145
|
+
/**
|
|
146
|
+
* What this engine needs the record to say beyond the driver's facts (the
|
|
147
|
+
* model the adapter validates, the workspace its gate installs into). A
|
|
148
|
+
* subject whose engine reads nothing of the record omits it.
|
|
149
|
+
*/
|
|
150
|
+
inputOverrides?(view: EngineView): SubjectInputOverrides;
|
|
151
|
+
/**
|
|
152
|
+
* Resolves the next time a turn parks on a `hang` step — the moment the
|
|
153
|
+
* kit stops a turn from the outside, and the moment the runtime half
|
|
154
|
+
* delivers a cancellation, a drain or the clock tick that trips the stall
|
|
155
|
+
* watchdog. A real engine reaches its hang only after real setup (file
|
|
156
|
+
* writes, catalog fetches); a stop delivered any earlier would land in that
|
|
157
|
+
* setup and prove nothing about the hang. Never a timer.
|
|
158
|
+
*/
|
|
159
|
+
whenHanging(): Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* How many times the side effect behind `toolCallId` actually ran, as the
|
|
162
|
+
* subject's double observed it. The safety-critical observable; zero for an
|
|
163
|
+
* id the engine never reached.
|
|
164
|
+
*/
|
|
165
|
+
executionCount(toolCallId: string): number;
|
|
166
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The test-facing seam of the harness contract kit.
|
|
3
|
+
*
|
|
4
|
+
* `HarnessAdapter.runTurn(input, sink)` gives a test no way to make the
|
|
5
|
+
* engine DO anything: propose a gated action, emit usage, hang, fail. The
|
|
6
|
+
* approval-contract kit met the same problem with `GatewaySubstrate` — a
|
|
7
|
+
* small interface each real substrate adapts so one invariant catalog can
|
|
8
|
+
* drive all of them. This is that seam for harnesses: a
|
|
9
|
+
* {@link HarnessContractSubject} owns the ENGINE (what the next turn will
|
|
10
|
+
* do), and the kit owns everything the runtime would own (the sink, the
|
|
11
|
+
* `TurnInput`, the state id threading, the reinvocation).
|
|
12
|
+
*
|
|
13
|
+
* The scenario vocabulary is deliberately small and engine-neutral: it says
|
|
14
|
+
* what the kit needs to PROVOKE, never how an engine behaves. The scripted
|
|
15
|
+
* fake consumes it directly; a real harness's subject translates it onto that
|
|
16
|
+
* harness's own double (the Cursor subject onto the scripted `@cursor/sdk`
|
|
17
|
+
* agent of `execute-cursor/__test-utils__/`). One vocabulary, not one per
|
|
18
|
+
* engine, so the kit cannot drift from what the fake can do.
|
|
19
|
+
*
|
|
20
|
+
* Gated actions reuse `ProposedAction` from `approval-contract/types.ts`, the
|
|
21
|
+
* taxonomy-free action every enforcement substrate already translates, so the
|
|
22
|
+
* two kits speak of the same logical side effect and neither restates the
|
|
23
|
+
* HITL taxonomy.
|
|
24
|
+
*/
|
|
25
|
+
/** Step builders — the vocabulary a kit invariant reads as. */
|
|
26
|
+
export const scenario = {
|
|
27
|
+
say(text) {
|
|
28
|
+
return { kind: "say", text };
|
|
29
|
+
},
|
|
30
|
+
propose(toolCallId, action) {
|
|
31
|
+
return { kind: "propose", toolCallId, action };
|
|
32
|
+
},
|
|
33
|
+
read(toolCallId, path) {
|
|
34
|
+
return { kind: "read", toolCallId, path };
|
|
35
|
+
},
|
|
36
|
+
usage(delta) {
|
|
37
|
+
return { kind: "usage", delta };
|
|
38
|
+
},
|
|
39
|
+
hang() {
|
|
40
|
+
return { kind: "hang" };
|
|
41
|
+
},
|
|
42
|
+
fail(message, surface = "engine") {
|
|
43
|
+
return { kind: "fail", message, surface };
|
|
44
|
+
},
|
|
45
|
+
cancelled() {
|
|
46
|
+
return { kind: "cancelled" };
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/__test-utils__/harness-contract/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAiDH,+DAA+D;AAC/D,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,GAAG,CAAC,IAAY;QACd,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC/B,CAAC;IACD,OAAO,CAAC,UAAkB,EAAE,MAAsB;QAChD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,CAAC,UAAkB,EAAE,IAAY;QACnC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAC5C,CAAC;IACD,KAAK,CAAC,KAAiB;QACrB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAClC,CAAC;IACD,IAAI;QACF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,OAAe,EAAE,UAA0B,QAAQ;QACtD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;IACD,SAAS;QACP,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC/B,CAAC;CACO,CAAC"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hermetic activity driver — run a REAL runner activity end to end with no
|
|
3
|
+
* network, no credentials, and no live Temporal worker, and read back every
|
|
4
|
+
* status it persisted.
|
|
5
|
+
*
|
|
6
|
+
* Why this exists: the runner's activities (`ExecuteCursor`, `ExecuteDeepAgent`)
|
|
7
|
+
* are the wire contract the control plane's workflow keys on — the phases they
|
|
8
|
+
* persist, the copy they write, whether they RETURN a slim status or THROW
|
|
9
|
+
* `CancelledFailure`. Refactoring them safely needs goldens recorded through the
|
|
10
|
+
* activity whole, not through its modules one at a time. The native harness
|
|
11
|
+
* tests already run their activity hermetically by mocking three modules at the
|
|
12
|
+
* boundary (`execute-deep-agent/__tests__/{index,hitl-*,sequential-gate-resume}.test.ts`);
|
|
13
|
+
* this module is that convention made reusable, harness-agnostic, and driven by
|
|
14
|
+
* the framework's own activity environment instead of a hand-written stand-in.
|
|
15
|
+
*
|
|
16
|
+
* What is generic here and what is not: everything an activity touches that is
|
|
17
|
+
* NOT the vendor SDK — the Temporal `Context`, the control-plane client, the
|
|
18
|
+
* runner-owned `~/.stigmer` tree, artifact storage, the model registry, the
|
|
19
|
+
* clock, the worker-shutdown signal — is set up here. The vendor SDK double
|
|
20
|
+
* belongs to the harness (`activities/execute-cursor/__test-utils__/scripted-*.ts`),
|
|
21
|
+
* the same split as `approval-contract/` (runner-wide kit) + each harness's
|
|
22
|
+
* `gateway-substrate.ts`.
|
|
23
|
+
*
|
|
24
|
+
* Three substitutions, and why each is shaped the way it is:
|
|
25
|
+
*
|
|
26
|
+
* 1. `Context.current()` — `MockActivityEnvironment` from `@temporalio/testing`,
|
|
27
|
+
* ONE PER INVOCATION. It gives the activity a real `Context` (real
|
|
28
|
+
* `cancellationSignal`, real `heartbeat()` surfaced as events, real
|
|
29
|
+
* `CancelledFailure` on throw). The native tests' stand-in mints a fresh
|
|
30
|
+
* `AbortController` on every `Context.current()` call and so cannot drive a
|
|
31
|
+
* pause; production hands each attempt one `Context`, and so does this. The
|
|
32
|
+
* environment's documented caveat — once cancelled it stays cancelled — is
|
|
33
|
+
* why it is per invocation and never shared.
|
|
34
|
+
*
|
|
35
|
+
* 2. `StigmerClient` — the test file mocks the module (`vi.mock` is hoisted and
|
|
36
|
+
* must live in the test file; see {@link hermeticStigmerClientModule}) and
|
|
37
|
+
* the constructor hands back whatever client {@link bindHermeticClient} bound
|
|
38
|
+
* for the current run. The client is `mockStigmerClient` over an
|
|
39
|
+
* {@link ExecutionRecord}: `updateStatus` writes back into the record the way
|
|
40
|
+
* the server would, so a REINVOCATION (`threadId` set) reads the transcript
|
|
41
|
+
* the first invocation persisted — the resume path runs on real data, not on
|
|
42
|
+
* a hand-built status.
|
|
43
|
+
*
|
|
44
|
+
* 3. The environment — a temp `HOME` (the runner-owned `~/.stigmer` tree,
|
|
45
|
+
* `platform-dir.ts` reads `process.env.HOME`), a temp workspace root, local
|
|
46
|
+
* artifact storage in a temp dir, and the HITL fingerprint secret pinned by
|
|
47
|
+
* env var (`fingerprint-secret.ts` falls back to `randomBytes` — the ONE
|
|
48
|
+
* source of randomness on the activity path — and memoizes on first call, so
|
|
49
|
+
* the pin must precede the first invocation in the process).
|
|
50
|
+
*
|
|
51
|
+
* Determinism: the clock is faked for `Date` ONLY (`vi.useFakeTimers({ toFake:
|
|
52
|
+
* ["Date"] })`) and TICKS — the harness double advances it a fixed quantum per
|
|
53
|
+
* script step through {@link ScriptedClock}. Frozen time would make
|
|
54
|
+
* `delta-enricher.ts`'s persist debounce (`Date.now() - lastPersistTime`) never
|
|
55
|
+
* elapse and silently skip the mid-stream persist path production always runs;
|
|
56
|
+
* a ticking clock runs the same path and lands on the same instants every run.
|
|
57
|
+
* Timers stay real so the periodic heartbeat and the stall watchdog behave.
|
|
58
|
+
*
|
|
59
|
+
* Not in scope: this module never edits a production module and never
|
|
60
|
+
* normalizes output. If a golden is not byte-stable, the volatile source is
|
|
61
|
+
* controlled at its origin or the surprise is escalated — never redacted here.
|
|
62
|
+
*/
|
|
63
|
+
import { CancelledFailure } from "@temporalio/activity";
|
|
64
|
+
import { type AgentExecution, type AgentExecutionStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
65
|
+
import { ApprovalAction, ExecutionControlSignal, ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
66
|
+
import type { ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
67
|
+
import { type Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
|
|
68
|
+
import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
69
|
+
import type { AgentInstance } from "@stigmer/protos/ai/stigmer/agentic/agentinstance/v1/api_pb";
|
|
70
|
+
import type { StigmerClient } from "../client/stigmer-client.js";
|
|
71
|
+
/**
|
|
72
|
+
* The four resources the activity's blueprint chain reads
|
|
73
|
+
* (`execution.spec.sessionId -> session.spec.agentInstanceId ->
|
|
74
|
+
* agentInstance.spec.agentId -> agent`) plus the status the server would hold.
|
|
75
|
+
*/
|
|
76
|
+
export interface ExecutionRecordInput {
|
|
77
|
+
readonly execution: AgentExecution;
|
|
78
|
+
readonly session: Session;
|
|
79
|
+
readonly agentInstance: AgentInstance;
|
|
80
|
+
readonly agent: Agent;
|
|
81
|
+
/**
|
|
82
|
+
* What `UpdateStatus` answers for each FULL status write — the platform's
|
|
83
|
+
* STOP lever (`ExecutionControlSignal`), decided by the control plane per
|
|
84
|
+
* write and read by the harness stream loop on its mid-stream persist.
|
|
85
|
+
* Evaluated AFTER the write lands, on the snapshot just persisted, so a
|
|
86
|
+
* policy can key on the transcript ("stop once the first assistant message
|
|
87
|
+
* is in"). Defaults to UNSPECIFIED: keep going.
|
|
88
|
+
*/
|
|
89
|
+
readonly controlSignal?: (status: AgentExecutionStatus) => ExecutionControlSignal;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* An in-memory stand-in for the server's execution row, with the TWO merge
|
|
93
|
+
* rules and the ONE control lever the activity depends on, and no others:
|
|
94
|
+
*
|
|
95
|
+
* - A status whose phase is UNSPECIFIED is a setup-progress report
|
|
96
|
+
* (`reportSetupProgress`): the server keeps `setup_progress` and leaves the
|
|
97
|
+
* phase and transcript alone. Modelled as: record the label, change nothing else.
|
|
98
|
+
* - Any other status replaces the held status wholesale (the runner is the
|
|
99
|
+
* writer of the transcript; the server's own field-ownership merge — approval
|
|
100
|
+
* fields it owns — is exercised by the test SETTING `approvalAction` on the
|
|
101
|
+
* record between invocations, exactly as `SubmitApproval` would).
|
|
102
|
+
* - Every `UpdateStatus` answers a control signal ({@link ExecutionRecordInput.controlSignal});
|
|
103
|
+
* the server's STOP is the one instruction that travels back to the runner
|
|
104
|
+
* on this channel, and it is a server decision, so it is modelled here and
|
|
105
|
+
* not by the test hand-writing the client.
|
|
106
|
+
*
|
|
107
|
+
* Every persisted status is also kept in order (`persisted`) so a test can
|
|
108
|
+
* assert the phase sequence the activity wrote, independent of the final state.
|
|
109
|
+
*/
|
|
110
|
+
export declare class ExecutionRecord {
|
|
111
|
+
readonly execution: AgentExecution;
|
|
112
|
+
readonly session: Session;
|
|
113
|
+
readonly agentInstance: AgentInstance;
|
|
114
|
+
readonly agent: Agent;
|
|
115
|
+
private readonly controlSignal;
|
|
116
|
+
/** Every `updateStatus` payload, in order, snapshotted at write time. */
|
|
117
|
+
readonly persisted: AgentExecutionStatus[];
|
|
118
|
+
/** Setup-progress labels reported before the stream started, in order. */
|
|
119
|
+
readonly setupProgress: string[];
|
|
120
|
+
/**
|
|
121
|
+
* Every `updateSession` payload, in order (the `harness_state_id` write-back),
|
|
122
|
+
* snapshotted at write time: the activity re-binds the SAME session object on
|
|
123
|
+
* a fresh-agent recovery, so a live reference would show the second id twice.
|
|
124
|
+
*/
|
|
125
|
+
readonly sessionUpdates: Session[];
|
|
126
|
+
constructor(input: ExecutionRecordInput);
|
|
127
|
+
get executionId(): string;
|
|
128
|
+
/** The status the server would currently hold (what `getExecution` returns). */
|
|
129
|
+
get status(): AgentExecutionStatus | undefined;
|
|
130
|
+
/** The last FULL status written (phase set), or undefined if none yet. */
|
|
131
|
+
get lastFullStatus(): AgentExecutionStatus | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* The ORDERED, DISTINCT phases the activity persisted — the deterministic
|
|
134
|
+
* shape of the persist cadence. The COUNT of persists depends on the
|
|
135
|
+
* debounce timer and is deliberately not exposed as an assertion surface.
|
|
136
|
+
*/
|
|
137
|
+
get persistedPhases(): ExecutionPhase[];
|
|
138
|
+
/** Every tool call on the held transcript (top-level messages), in order. */
|
|
139
|
+
toolCalls(): ToolCall[];
|
|
140
|
+
/** The tool calls currently paused for a decision. */
|
|
141
|
+
waitingToolCalls(): ToolCall[];
|
|
142
|
+
/**
|
|
143
|
+
* What the server's `SubmitApproval` does to the row: record the decision on
|
|
144
|
+
* the tool call the runner wrote. The runner owns `status`; the server owns
|
|
145
|
+
* `approval_action` (field ownership, 005 mandate 2) — so this is the ONE
|
|
146
|
+
* place a test writes it, and the status stays WAITING_APPROVAL until the
|
|
147
|
+
* resumed turn runs the tool, exactly as in production.
|
|
148
|
+
*/
|
|
149
|
+
decideWaitingToolCalls(action: ApprovalAction, decidedAt: string): number;
|
|
150
|
+
/**
|
|
151
|
+
* Apply one `UpdateStatus` write and answer the control signal the server
|
|
152
|
+
* would. A setup-progress report never carries a signal (the runner ignores
|
|
153
|
+
* the response there; the server has nothing to say about a label).
|
|
154
|
+
*/
|
|
155
|
+
applyStatusUpdate(status: AgentExecutionStatus): ExecutionControlSignal;
|
|
156
|
+
/**
|
|
157
|
+
* The control-plane client the activity sees: every read answers from this
|
|
158
|
+
* record; every write lands in it. Reads the activity makes for optional
|
|
159
|
+
* facets (execution context, channels, skills) answer the everyday shape —
|
|
160
|
+
* NOT_FOUND for the execution context (an execution with no env vars), no
|
|
161
|
+
* channels, no scoped token (the OSS/local posture) — so a scenario opts INTO
|
|
162
|
+
* a facet by overriding.
|
|
163
|
+
*/
|
|
164
|
+
client(overrides?: Partial<StigmerClient>): StigmerClient;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Bind the client the mocked `StigmerClient` constructor hands out for the
|
|
168
|
+
* current run. Called by the harness driver immediately before invoking the
|
|
169
|
+
* activity factory (`createCursorActivities(config)` constructs its client
|
|
170
|
+
* inside the factory, so the bind must precede the factory call).
|
|
171
|
+
*/
|
|
172
|
+
export declare function bindHermeticClient(client: StigmerClient): void;
|
|
173
|
+
/**
|
|
174
|
+
* The factory a test passes to `vi.mock(".../client/stigmer-client.js", ...)`.
|
|
175
|
+
* `vi.mock` is hoisted and must appear in the test file itself; the factory can
|
|
176
|
+
* `await import()` this module. Usage:
|
|
177
|
+
*
|
|
178
|
+
* ```ts
|
|
179
|
+
* vi.mock("../../../../client/stigmer-client.js", async () =>
|
|
180
|
+
* (await import("../../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule(),
|
|
181
|
+
* );
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
export declare function hermeticStigmerClientModule(): {
|
|
185
|
+
StigmerClient: new () => StigmerClient;
|
|
186
|
+
};
|
|
187
|
+
export interface HermeticEnvironment {
|
|
188
|
+
/** The temp `HOME` (the runner's `~/.stigmer` lands under it). */
|
|
189
|
+
readonly home: string;
|
|
190
|
+
/** The temp workspace root (`config.workspaceRootDir`). */
|
|
191
|
+
readonly workspaceRootDir: string;
|
|
192
|
+
/** The temp local artifact store (`LOCAL_ARTIFACT_PATH`). */
|
|
193
|
+
readonly artifactPath: string;
|
|
194
|
+
/** Restore every env var and remove the temp tree. Idempotent. */
|
|
195
|
+
dispose(): void;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Create the temp tree and pin the env vars. Call once per test FILE (in
|
|
199
|
+
* `beforeAll`) — the fingerprint secret is memoized per process on first use,
|
|
200
|
+
* and vitest isolates files in forks, so per-file is the natural unit.
|
|
201
|
+
*/
|
|
202
|
+
export declare function createHermeticEnvironment(): HermeticEnvironment;
|
|
203
|
+
/**
|
|
204
|
+
* A deterministic, TICKING `Date`. Only `Date` is faked; timers stay real (the
|
|
205
|
+
* periodic heartbeat, the stall watchdog, `withTimeout` all need them). The
|
|
206
|
+
* harness double calls {@link ScriptedClock.tick} once per script step, so
|
|
207
|
+
* every `Date.now()`-based decision on the activity path (status timestamps,
|
|
208
|
+
* the enricher's persist debounce, cache TTLs) sees the same instants run after
|
|
209
|
+
* run and runs the same branches production runs.
|
|
210
|
+
*/
|
|
211
|
+
export declare class ScriptedClock {
|
|
212
|
+
/** A fixed epoch: 2026-01-01T00:00:00.000Z. Chosen for readability in goldens. */
|
|
213
|
+
static readonly EPOCH_MS: number;
|
|
214
|
+
/** One second per step — well under any stall or cache horizon. */
|
|
215
|
+
static readonly STEP_MS = 1000;
|
|
216
|
+
private nowMs;
|
|
217
|
+
install(): void;
|
|
218
|
+
tick(ms?: number): void;
|
|
219
|
+
/** Back to the epoch — for a second scenario in the same file. */
|
|
220
|
+
reset(): void;
|
|
221
|
+
uninstall(): void;
|
|
222
|
+
}
|
|
223
|
+
/** How an activity invocation ended: the return value or the error it threw. */
|
|
224
|
+
export type ActivityOutcome = {
|
|
225
|
+
readonly kind: "returned";
|
|
226
|
+
readonly value: unknown;
|
|
227
|
+
} | {
|
|
228
|
+
readonly kind: "threw";
|
|
229
|
+
readonly error: unknown;
|
|
230
|
+
};
|
|
231
|
+
export interface ActivityInvocation {
|
|
232
|
+
readonly outcome: ActivityOutcome;
|
|
233
|
+
/** Heartbeat details the activity reported, in order. */
|
|
234
|
+
readonly heartbeats: unknown[];
|
|
235
|
+
/** The `taskQueue` the invocation ran on (the shutdown signal is keyed by it). */
|
|
236
|
+
readonly taskQueue: string;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Handles a scenario uses to interrupt the invocation FROM A SCRIPT STEP —
|
|
240
|
+
* never from a timer. `cancel()` aborts the activity's `cancellationSignal`
|
|
241
|
+
* (a user pause, as the workflow delivers it). `signalWorkerShutdown()` aborts
|
|
242
|
+
* the queue's shutdown signal first, which the activity reads to tell a worker
|
|
243
|
+
* drain from a user pause (`classifyTurnInterruption`).
|
|
244
|
+
*/
|
|
245
|
+
export interface InvocationControls {
|
|
246
|
+
cancel(): void;
|
|
247
|
+
signalWorkerShutdown(): void;
|
|
248
|
+
}
|
|
249
|
+
export interface RunActivityOptions {
|
|
250
|
+
readonly taskQueue?: string;
|
|
251
|
+
/**
|
|
252
|
+
* Receives the invocation's controls before the activity starts, so a
|
|
253
|
+
* scenario can hand them to the harness double's `effect` steps.
|
|
254
|
+
*/
|
|
255
|
+
readonly onControls?: (controls: InvocationControls) => void;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Run one activity function under a fresh `MockActivityEnvironment` and
|
|
259
|
+
* capture how it ended. `CancelledFailure` is caught like any other throw and
|
|
260
|
+
* reported as `{ kind: "threw" }` — the throw-vs-return table is the thing
|
|
261
|
+
* under test, so the driver never interprets it.
|
|
262
|
+
*/
|
|
263
|
+
export declare function runActivityHermetically<A extends unknown[]>(activity: (...args: A) => Promise<unknown>, args: A, options?: RunActivityOptions): Promise<ActivityInvocation>;
|
|
264
|
+
/** True when the outcome is a thrown Temporal `CancelledFailure`. */
|
|
265
|
+
export declare function threwCancelledFailure(outcome: ActivityOutcome): outcome is {
|
|
266
|
+
kind: "threw";
|
|
267
|
+
error: CancelledFailure;
|
|
268
|
+
};
|