@stigmer/runner 3.14.1 → 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 +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
package/src/runner-manager.ts
CHANGED
|
@@ -234,9 +234,9 @@ export async function createStigmerRunnerManager(
|
|
|
234
234
|
// `tokenRef` holds the control-plane token (the host's durable credential,
|
|
235
235
|
// e.g. the desktop's Auth0 token) and is shared with activity clients via
|
|
236
236
|
// config.stigmerTokenRef. The proxy credential (x-stigmer-auth) is managed
|
|
237
|
-
// separately by a RunnerTokenCoordinator (created after the
|
|
238
|
-
//
|
|
239
|
-
//
|
|
237
|
+
// separately by a RunnerTokenCoordinator (created after the harnesses boot)
|
|
238
|
+
// — see that module for the two-writer rationale and the staleness history
|
|
239
|
+
// it guards.
|
|
240
240
|
const tokenRef = { current: options.stigmerToken ?? null };
|
|
241
241
|
// `runnerTokenRef` mirrors the coordinator's proxy credential for gRPC use:
|
|
242
242
|
// the minted runner token (token_type=embedded_runner) once adopted, tracking
|
|
@@ -251,48 +251,33 @@ export async function createStigmerRunnerManager(
|
|
|
251
251
|
|
|
252
252
|
assertLlmBackendsPreflight(baseConfig.proxyEndpoint);
|
|
253
253
|
|
|
254
|
-
//
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
// that facade if it runs first,
|
|
259
|
-
//
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
//
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
// HTTP/2 interceptor for Connect RPC auth + execution ID injection (BiDi billing)
|
|
272
|
-
const { installHttp2Interceptor, updateHttp2InterceptorToken, assertHttp2ConnectPatched } = await import(
|
|
273
|
-
"./activities/execute-cursor/http2-interceptor.js"
|
|
274
|
-
);
|
|
275
|
-
installHttp2Interceptor({
|
|
276
|
-
proxyEndpoint: baseConfig.proxyEndpoint ?? undefined,
|
|
277
|
-
stigmerToken: baseConfig.stigmerToken ?? undefined,
|
|
278
|
-
});
|
|
279
|
-
// Fail loudly at boot if a load-order regression left the node:http2 ESM
|
|
280
|
-
// facade unpatched (otherwise BiDi streams would silently 401). No-op when
|
|
281
|
-
// the interceptor is unconfigured (no proxy/token).
|
|
282
|
-
await assertHttp2ConnectPatched();
|
|
283
|
-
markBoot("interceptors_installed");
|
|
254
|
+
// Boot the harnesses BEFORE resolving Temporal coordinates. Coordinate
|
|
255
|
+
// discovery dials the control plane through connect-node, which snapshots
|
|
256
|
+
// the node:http2 ESM facade on first import; the Cursor adapter's boot
|
|
257
|
+
// installs the proxy interceptors (the HTTP/2 one patches http2.connect,
|
|
258
|
+
// which only reaches that facade if it runs first), proves the patch landed,
|
|
259
|
+
// and only then loads its SDK. The interceptors read the proxy credential
|
|
260
|
+
// per request from `runnerTokenRef` (Config.proxyTokenRef, bound by
|
|
261
|
+
// mapManagerOptionsToConfig): the control-plane token until a runner token
|
|
262
|
+
// is minted, the minted token after, exactly the lockstep the coordinator
|
|
263
|
+
// below maintains in that ref. Nothing a boot reads depends on the
|
|
264
|
+
// coordinates, so `baseConfig` carries none yet. The two modules imported
|
|
265
|
+
// here are connect-free by construction (`harness-adapters.ts`,
|
|
266
|
+
// `harness/registry.ts`; `__tests__/harness-boot-order.test.ts`).
|
|
267
|
+
const [{ HARNESS_ADAPTERS }, { adaptersOf, bootHarnesses, releaseHarnessSession, shutdownHarnesses }] =
|
|
268
|
+
await Promise.all([import("./harness-adapters.js"), import("./harness/registry.js")]);
|
|
269
|
+
await bootHarnesses(adaptersOf(HARNESS_ADAPTERS), baseConfig);
|
|
270
|
+
markBoot("harnesses_booted");
|
|
284
271
|
|
|
285
272
|
// The token coordinator owns the proxy credential (x-stigmer-auth) and its
|
|
286
|
-
// refresh lifecycle. It writes
|
|
287
|
-
//
|
|
273
|
+
// refresh lifecycle. It writes ONE sink, `runnerTokenRef`, which is read per
|
|
274
|
+
// request by both the interceptors (as Config.proxyTokenRef) and the gRPC
|
|
275
|
+
// client (as Config.stigmerRunnerTokenRef), so mint and refresh reach every
|
|
276
|
+
// reader in one write. It re-mints using the always-fresh control-plane
|
|
288
277
|
// token in `tokenRef` — never the (possibly expired) minted token itself, so
|
|
289
278
|
// a slept-past-TTL runner recovers without a restart.
|
|
290
279
|
const tokenCoordinator = createRunnerTokenCoordinator({
|
|
291
280
|
applyProxyToken: (token) => {
|
|
292
|
-
updateInterceptorToken(token);
|
|
293
|
-
updateHttp2InterceptorToken(token);
|
|
294
|
-
// Third sink: keeps the ExecutionContext-read credential in lockstep with
|
|
295
|
-
// the proxy credential across mint and refresh (see runnerTokenRef above).
|
|
296
281
|
runnerTokenRef.current = token;
|
|
297
282
|
},
|
|
298
283
|
reMint: () =>
|
|
@@ -302,7 +287,7 @@ export async function createStigmerRunnerManager(
|
|
|
302
287
|
}),
|
|
303
288
|
});
|
|
304
289
|
|
|
305
|
-
// Resolve the runner bootstrap after the
|
|
290
|
+
// Resolve the runner bootstrap after the harnesses have booted (discovery
|
|
306
291
|
// dials the control plane through connect-node). An explicit address wins;
|
|
307
292
|
// otherwise a token triggers control-plane discovery; otherwise localhost.
|
|
308
293
|
// Must happen before createAllActivities so the activities' Config carries
|
|
@@ -341,11 +326,6 @@ export async function createStigmerRunnerManager(
|
|
|
341
326
|
);
|
|
342
327
|
}
|
|
343
328
|
|
|
344
|
-
const { setExecutionContextRef } = await import(
|
|
345
|
-
"./activities/execute-cursor/rejection-capture.js"
|
|
346
|
-
);
|
|
347
|
-
setExecutionContextRef(getExecutionContext());
|
|
348
|
-
|
|
349
329
|
const activities = await createAllActivities(config);
|
|
350
330
|
markBoot("activities_imported");
|
|
351
331
|
// Surface the resolved artifact store at boot (see runner.ts for rationale):
|
|
@@ -538,13 +518,19 @@ export async function createStigmerRunnerManager(
|
|
|
538
518
|
await removeManaged(
|
|
539
519
|
sessions, sessionId, SESSION_QUEUE_PREFIX + sessionId, "session",
|
|
540
520
|
);
|
|
541
|
-
// The session is done on this host —
|
|
542
|
-
// the
|
|
543
|
-
// than
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
521
|
+
// The session is done on this host — every harness releases what it
|
|
522
|
+
// parked for it (the Cursor harness: the agent, and the executor + MCP
|
|
523
|
+
// subprocesses its lease pins) now rather than after the idle TTL
|
|
524
|
+
// (#215). Logged, never thrown: the session's worker is already gone,
|
|
525
|
+
// and failing this IPC command would tell the desktop a removal that
|
|
526
|
+
// did happen did not.
|
|
527
|
+
try {
|
|
528
|
+
await releaseHarnessSession(adaptersOf(HARNESS_ADAPTERS), sessionId);
|
|
529
|
+
} catch (err) {
|
|
530
|
+
console.error(
|
|
531
|
+
`[runner-manager] Harness release for session ${sessionId} failed (continuing): ${err instanceof Error ? err.message : String(err)}`,
|
|
532
|
+
);
|
|
533
|
+
}
|
|
548
534
|
},
|
|
549
535
|
|
|
550
536
|
activeSessions(): string[] {
|
|
@@ -659,12 +645,18 @@ export async function createStigmerRunnerManager(
|
|
|
659
645
|
}
|
|
660
646
|
|
|
661
647
|
await Promise.all(shutdownPromises);
|
|
662
|
-
// Workers are drained —
|
|
663
|
-
//
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
648
|
+
// Workers are drained — every harness releases what it still holds
|
|
649
|
+
// (the Cursor harness: its parked session agents, whose executor leases
|
|
650
|
+
// dispose and whose stdio MCP subprocesses die with them, #215). Logged,
|
|
651
|
+
// never thrown: the drain has already happened, and a teardown failure
|
|
652
|
+
// must not mask a clean stop.
|
|
653
|
+
try {
|
|
654
|
+
await shutdownHarnesses(adaptersOf(HARNESS_ADAPTERS));
|
|
655
|
+
} catch (err) {
|
|
656
|
+
console.error(
|
|
657
|
+
`[runner-manager] Harness shutdown failed after the workers drained (continuing): ${err instanceof Error ? err.message : String(err)}`,
|
|
658
|
+
);
|
|
659
|
+
}
|
|
668
660
|
sessions.clear();
|
|
669
661
|
workflowExecutions.clear();
|
|
670
662
|
poolControl = null;
|
|
@@ -711,6 +703,11 @@ export function mapManagerOptionsToConfig(
|
|
|
711
703
|
mcpBridgeEndpoint: process.env.STIGMER_MCP_BRIDGE_ENDPOINT ?? null,
|
|
712
704
|
stigmerTokenRef: tokenRef,
|
|
713
705
|
stigmerRunnerTokenRef: runnerTokenRef,
|
|
706
|
+
// The manager's proxy credential is the minted runner token once adopted
|
|
707
|
+
// (the control-plane token in lockstep before that), so it is this ref and
|
|
708
|
+
// not `tokenRef`: binding `tokenRef` would keep sending the desktop's own
|
|
709
|
+
// Auth0 token as x-stigmer-auth after the mint (Q-S2-7).
|
|
710
|
+
proxyTokenRef: runnerTokenRef,
|
|
714
711
|
cursorApiKey: proxyActive
|
|
715
712
|
? (options.cursorApiKey ?? "proxy-managed")
|
|
716
713
|
: (options.cursorApiKey ?? ""),
|
|
@@ -736,9 +733,18 @@ export function mapManagerOptionsToConfig(
|
|
|
736
733
|
};
|
|
737
734
|
}
|
|
738
735
|
|
|
736
|
+
/**
|
|
737
|
+
* Dynamically import all activity factories and merge into a single map,
|
|
738
|
+
* after the harnesses have booted: several of these modules transitively load
|
|
739
|
+
* `@connectrpc/connect-node` and LangChain, and the Cursor adapter's boot must
|
|
740
|
+
* have patched `node:http2` before connect-node is first imported (see
|
|
741
|
+
* createStigmerRunnerManager). The harness rows and the registry were imported
|
|
742
|
+
* by the factory for the boot; the imports here hit the module cache.
|
|
743
|
+
*/
|
|
739
744
|
async function createAllActivities(config: Config): Promise<WorkerActivities> {
|
|
740
745
|
const [
|
|
741
|
-
{
|
|
746
|
+
{ HARNESS_ADAPTERS },
|
|
747
|
+
{ createHarnessActivities },
|
|
742
748
|
{ createDeepAgentActivities },
|
|
743
749
|
{ createEnsureThreadActivities },
|
|
744
750
|
{ createGenerateSessionSubjectActivities },
|
|
@@ -757,7 +763,8 @@ async function createAllActivities(config: Config): Promise<WorkerActivities> {
|
|
|
757
763
|
{ createPromoteTaskOutputActivities },
|
|
758
764
|
{ createAttachSessionActivities },
|
|
759
765
|
] = await Promise.all([
|
|
760
|
-
import("./
|
|
766
|
+
import("./harness-adapters.js"),
|
|
767
|
+
import("./harness/registry.js"),
|
|
761
768
|
import("./activities/execute-deep-agent/index.js"),
|
|
762
769
|
import("./activities/ensure-thread.js"),
|
|
763
770
|
import("./activities/generate-session-subject.js"),
|
|
@@ -778,7 +785,7 @@ async function createAllActivities(config: Config): Promise<WorkerActivities> {
|
|
|
778
785
|
]);
|
|
779
786
|
|
|
780
787
|
return {
|
|
781
|
-
...
|
|
788
|
+
...(await createHarnessActivities(HARNESS_ADAPTERS, config)),
|
|
782
789
|
...createDeepAgentActivities(config),
|
|
783
790
|
...createEnsureThreadActivities(),
|
|
784
791
|
...createGenerateSessionSubjectActivities(config),
|
package/src/runner.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Public factory for the unified Stigmer runner.
|
|
3
3
|
*
|
|
4
|
-
* Encapsulates the full boot sequence:
|
|
5
|
-
*
|
|
4
|
+
* Encapsulates the full boot sequence: harness boot (the Cursor adapter
|
|
5
|
+
* installs its proxy interceptors there), bootstrap resolution, dynamic
|
|
6
|
+
* activity imports, Temporal worker creation. Consumers call
|
|
6
7
|
* {@link createStigmerRunner} with typed options and get back a handle
|
|
7
8
|
* to start/shutdown the worker.
|
|
8
9
|
*
|
|
@@ -125,13 +126,14 @@ export interface StigmerRunner {
|
|
|
125
126
|
/**
|
|
126
127
|
* Wire up self-renewal for a static cloud sandbox's control-plane credential
|
|
127
128
|
* (see sandbox-token-renewal.ts for the model). The applied token reaches
|
|
128
|
-
* every consumer: activity gRPC clients read
|
|
129
|
-
* per-call sites (call-llm, registry-endpoint
|
|
130
|
-
* the runner credential store (which replaced
|
|
131
|
-
* channel, #508), artifact storage resolves
|
|
132
|
-
*
|
|
129
|
+
* every consumer through the ONE ref: activity gRPC clients read
|
|
130
|
+
* {@code tokenRef} per request, per-call sites (call-llm, registry-endpoint
|
|
131
|
+
* headers) resolve it through the runner credential store (which replaced
|
|
132
|
+
* the process.env.STIGMER_TOKEN channel, #508), artifact storage resolves
|
|
133
|
+
* the ref per call, and the two Cursor SDK interceptors read the same ref per
|
|
134
|
+
* request as {@code Config.proxyTokenRef} — a static runner has no
|
|
133
135
|
* {@code RunnerTokenCoordinator} minting a separate proxy credential, so its
|
|
134
|
-
* x-stigmer-auth IS this token.
|
|
136
|
+
* x-stigmer-auth IS this token and one write here rotates it everywhere.
|
|
135
137
|
*/
|
|
136
138
|
async function startStaticSandboxTokenRenewal(
|
|
137
139
|
config: Config,
|
|
@@ -148,12 +150,6 @@ async function startStaticSandboxTokenRenewal(
|
|
|
148
150
|
}
|
|
149
151
|
|
|
150
152
|
const { StigmerClient } = await import("./client/stigmer-client.js");
|
|
151
|
-
const { updateInterceptorToken } = await import(
|
|
152
|
-
"./activities/execute-cursor/fetch-interceptor.js"
|
|
153
|
-
);
|
|
154
|
-
const { updateHttp2InterceptorToken } = await import(
|
|
155
|
-
"./activities/execute-cursor/http2-interceptor.js"
|
|
156
|
-
);
|
|
157
153
|
const client = new StigmerClient({
|
|
158
154
|
endpoint: config.stigmerBackendEndpoint,
|
|
159
155
|
token: null,
|
|
@@ -169,8 +165,6 @@ async function startStaticSandboxTokenRenewal(
|
|
|
169
165
|
// Store write replaced the process.env.STIGMER_TOKEN write (#508) —
|
|
170
166
|
// same per-call readers (call-llm, registry headers), no env exposure.
|
|
171
167
|
setRunnerSecret("STIGMER_TOKEN", token);
|
|
172
|
-
updateInterceptorToken(token);
|
|
173
|
-
updateHttp2InterceptorToken(token);
|
|
174
168
|
},
|
|
175
169
|
});
|
|
176
170
|
}
|
|
@@ -178,8 +172,8 @@ async function startStaticSandboxTokenRenewal(
|
|
|
178
172
|
/**
|
|
179
173
|
* Create a Stigmer runner ready to poll a Temporal task queue.
|
|
180
174
|
*
|
|
181
|
-
* Handles all internal setup:
|
|
182
|
-
*
|
|
175
|
+
* Handles all internal setup: harness boot, activity registration, and
|
|
176
|
+
* Temporal worker creation. Returns a handle with
|
|
183
177
|
* `start()` and `shutdown()` methods.
|
|
184
178
|
*
|
|
185
179
|
* @example
|
|
@@ -216,42 +210,40 @@ export async function createStigmerRunner(
|
|
|
216
210
|
|
|
217
211
|
assertLlmBackendsPreflight(baseConfig.proxyEndpoint);
|
|
218
212
|
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
//
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
//
|
|
228
|
-
|
|
229
|
-
const { installFetchInterceptor, getExecutionContext } = await import(
|
|
230
|
-
"./activities/execute-cursor/fetch-interceptor.js"
|
|
231
|
-
);
|
|
232
|
-
installFetchInterceptor({
|
|
233
|
-
proxyEndpoint: baseConfig.proxyEndpoint ?? undefined,
|
|
234
|
-
stigmerToken: baseConfig.stigmerToken ?? undefined,
|
|
235
|
-
});
|
|
213
|
+
// The control-plane credential lives in a shared mutable ref (as in manager
|
|
214
|
+
// mode) so the sandbox-token renewal below can rotate it in-process:
|
|
215
|
+
// activity clients read the ref per request instead of pinning the boot
|
|
216
|
+
// token for the pod's whole life. It is ALSO this root's proxy credential
|
|
217
|
+
// (Config.proxyTokenRef): a static host provides the proxy token itself and
|
|
218
|
+
// mints no separate one, so the interceptors read this same ref per request.
|
|
219
|
+
const tokenRef = { current: baseConfig.stigmerToken };
|
|
220
|
+
// The runner-class credential the bootstrap below may mint (see there); the
|
|
221
|
+
// ref exists from here so the boot config can carry it.
|
|
222
|
+
const runnerTokenRef: { current: string | null } = { current: null };
|
|
236
223
|
|
|
237
|
-
//
|
|
238
|
-
//
|
|
239
|
-
// the
|
|
240
|
-
//
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
224
|
+
// Boot the harnesses BEFORE resolving Temporal coordinates. Coordinate
|
|
225
|
+
// discovery dials the control plane through connect-node, which snapshots
|
|
226
|
+
// the node:http2 ESM facade on first import; the Cursor adapter's boot
|
|
227
|
+
// installs the proxy interceptors (the HTTP/2 one patches http2.connect,
|
|
228
|
+
// which only reaches that facade if it runs first), proves the patch landed,
|
|
229
|
+
// and only then loads its SDK. Nothing a boot reads depends on the
|
|
230
|
+
// coordinates, so `bootConfig` carries none yet. The two modules imported
|
|
231
|
+
// here are connect-free by construction (`harness-adapters.ts`,
|
|
232
|
+
// `harness/registry.ts`; `__tests__/harness-boot-order.test.ts`).
|
|
233
|
+
const bootConfig: Config = {
|
|
234
|
+
...baseConfig,
|
|
235
|
+
stigmerTokenRef: tokenRef,
|
|
236
|
+
stigmerRunnerTokenRef: runnerTokenRef,
|
|
237
|
+
proxyTokenRef: tokenRef,
|
|
238
|
+
};
|
|
239
|
+
const [{ HARNESS_ADAPTERS }, { adaptersOf, bootHarnesses, shutdownHarnesses }] = await Promise.all([
|
|
240
|
+
import("./harness-adapters.js"),
|
|
241
|
+
import("./harness/registry.js"),
|
|
242
|
+
]);
|
|
243
|
+
await bootHarnesses(adaptersOf(HARNESS_ADAPTERS), bootConfig);
|
|
244
|
+
markBoot("harnesses_booted");
|
|
253
245
|
|
|
254
|
-
// Resolve Temporal coordinates after the
|
|
246
|
+
// Resolve Temporal coordinates after the harnesses have booted (discovery
|
|
255
247
|
// dials the control plane through connect-node). Explicit address wins;
|
|
256
248
|
// otherwise a token triggers control-plane discovery; otherwise localhost.
|
|
257
249
|
// Only the worker connection consumes these coordinates — no activity dials
|
|
@@ -263,11 +255,6 @@ export async function createStigmerRunner(
|
|
|
263
255
|
token: options.stigmerToken,
|
|
264
256
|
stigmerEndpoint: baseConfig.stigmerBackendEndpoint,
|
|
265
257
|
});
|
|
266
|
-
// The control-plane credential lives in a shared mutable ref (as in manager
|
|
267
|
-
// mode) so the sandbox-token renewal below can rotate it in-process:
|
|
268
|
-
// activity clients read the ref per request instead of pinning the boot
|
|
269
|
-
// token for the pod's whole life.
|
|
270
|
-
const tokenRef = { current: baseConfig.stigmerToken };
|
|
271
258
|
|
|
272
259
|
// Adopt the bootstrap-minted embedded_runner credential for gRPC runner-class
|
|
273
260
|
// calls (stigmer-cloud#507). The static path historically discarded it ("the
|
|
@@ -282,7 +269,6 @@ export async function createStigmerRunner(
|
|
|
282
269
|
// Servers that mint nothing (explicit-address boots, tokenless OSS, cloud
|
|
283
270
|
// sandboxes with baked credentials) leave the ref null — byte-identical
|
|
284
271
|
// behavior to before.
|
|
285
|
-
const runnerTokenRef: { current: string | null } = { current: null };
|
|
286
272
|
const runnerTokenCoordinator = createRunnerTokenCoordinator({
|
|
287
273
|
applyProxyToken: (token) => {
|
|
288
274
|
runnerTokenRef.current = token;
|
|
@@ -301,11 +287,9 @@ export async function createStigmerRunner(
|
|
|
301
287
|
}
|
|
302
288
|
|
|
303
289
|
const config: Config = {
|
|
304
|
-
...
|
|
290
|
+
...bootConfig,
|
|
305
291
|
temporalAddress: coordinates.temporalAddress,
|
|
306
292
|
temporalNamespace: coordinates.temporalNamespace,
|
|
307
|
-
stigmerTokenRef: tokenRef,
|
|
308
|
-
stigmerRunnerTokenRef: runnerTokenRef,
|
|
309
293
|
};
|
|
310
294
|
markBoot("bootstrap_resolved");
|
|
311
295
|
|
|
@@ -314,11 +298,6 @@ export async function createStigmerRunner(
|
|
|
314
298
|
// renewal point is scheduled even if the pod boots with a part-used token.
|
|
315
299
|
const tokenRenewal = await startStaticSandboxTokenRenewal(config, tokenRef);
|
|
316
300
|
|
|
317
|
-
const { setExecutionContextRef } = await import(
|
|
318
|
-
"./activities/execute-cursor/rejection-capture.js"
|
|
319
|
-
);
|
|
320
|
-
setExecutionContextRef(getExecutionContext());
|
|
321
|
-
|
|
322
301
|
const activities = await createAllActivities(config);
|
|
323
302
|
markBoot("activities_imported");
|
|
324
303
|
|
|
@@ -382,12 +361,18 @@ export async function createStigmerRunner(
|
|
|
382
361
|
emitRunnerBootTiming({ task_queue: config.taskQueue, mode: config.mode });
|
|
383
362
|
await worker.run();
|
|
384
363
|
console.log("Worker stopped");
|
|
385
|
-
// The worker has drained —
|
|
386
|
-
//
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
364
|
+
// The worker has drained — every harness releases what it still holds
|
|
365
|
+
// (the Cursor harness: its parked session agents, whose executor leases
|
|
366
|
+
// dispose with the process, #215). Logged, never thrown: the drain has
|
|
367
|
+
// already happened and the process is exiting, so a teardown failure
|
|
368
|
+
// must not mask a clean stop.
|
|
369
|
+
try {
|
|
370
|
+
await shutdownHarnesses(adaptersOf(HARNESS_ADAPTERS));
|
|
371
|
+
} catch (err) {
|
|
372
|
+
console.error(
|
|
373
|
+
`[runner] Harness shutdown failed after the worker drained (continuing): ${err instanceof Error ? err.message : String(err)}`,
|
|
374
|
+
);
|
|
375
|
+
}
|
|
391
376
|
},
|
|
392
377
|
shutdown() {
|
|
393
378
|
tokenRenewal?.stop();
|
|
@@ -467,13 +452,16 @@ export function mapOptionsToConfig(options: StigmerRunnerOptions): Config {
|
|
|
467
452
|
/**
|
|
468
453
|
* Dynamically import all activity factories and merge into a single map.
|
|
469
454
|
*
|
|
470
|
-
* Dynamic imports
|
|
471
|
-
*
|
|
472
|
-
*
|
|
455
|
+
* Dynamic imports, after the harnesses have booted: several of these modules
|
|
456
|
+
* transitively load `@connectrpc/connect-node` and LangChain, and the Cursor
|
|
457
|
+
* adapter's boot must have patched `node:http2` before connect-node is first
|
|
458
|
+
* imported (see createStigmerRunner). The harness rows and the registry were
|
|
459
|
+
* imported by the factory for the boot; the imports here hit the module cache.
|
|
473
460
|
*/
|
|
474
461
|
async function createAllActivities(config: Config): Promise<WorkerActivities> {
|
|
475
462
|
const [
|
|
476
|
-
{
|
|
463
|
+
{ HARNESS_ADAPTERS },
|
|
464
|
+
{ createHarnessActivities },
|
|
477
465
|
{ createDeepAgentActivities },
|
|
478
466
|
{ createEnsureThreadActivities },
|
|
479
467
|
{ createGenerateSessionSubjectActivities },
|
|
@@ -492,7 +480,8 @@ async function createAllActivities(config: Config): Promise<WorkerActivities> {
|
|
|
492
480
|
{ createPromoteTaskOutputActivities },
|
|
493
481
|
{ createAttachSessionActivities },
|
|
494
482
|
] = await Promise.all([
|
|
495
|
-
import("./
|
|
483
|
+
import("./harness-adapters.js"),
|
|
484
|
+
import("./harness/registry.js"),
|
|
496
485
|
import("./activities/execute-deep-agent/index.js"),
|
|
497
486
|
import("./activities/ensure-thread.js"),
|
|
498
487
|
import("./activities/generate-session-subject.js"),
|
|
@@ -513,7 +502,7 @@ async function createAllActivities(config: Config): Promise<WorkerActivities> {
|
|
|
513
502
|
]);
|
|
514
503
|
|
|
515
504
|
return {
|
|
516
|
-
...
|
|
505
|
+
...(await createHarnessActivities(HARNESS_ADAPTERS, config)),
|
|
517
506
|
...createDeepAgentActivities(config),
|
|
518
507
|
...createEnsureThreadActivities(),
|
|
519
508
|
...createGenerateSessionSubjectActivities(config),
|
|
@@ -4,7 +4,7 @@ import { join } from "node:path";
|
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { uniquifyFilename, allocateUniqueName } from "../attachment-naming.js";
|
|
6
6
|
import { injectAttachments } from "../../activities/execute-deep-agent/attachment-injector.js";
|
|
7
|
-
import { resolveAttachments } from "
|
|
7
|
+
import { resolveAttachments } from "../attachment-resolver.js";
|
|
8
8
|
import { getPlatformDir } from "../workspace/platform-dir.js";
|
|
9
9
|
import { makeInMemoryArtifactStorage } from "../../__test-utils__/fake-artifact-storage.js";
|
|
10
10
|
import type { WorkspaceBackend } from "../workspace/types.js";
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tests for the Cursor
|
|
2
|
+
* Tests for the attachment resolver, which the Cursor activity calls today
|
|
3
|
+
* and the turn runtime takes over in S2 M3 (S3 retires the native twin,
|
|
4
|
+
* execute-deep-agent/attachment-injector.ts).
|
|
3
5
|
*
|
|
4
6
|
* The load-bearing behaviors: storage-key attachments materialize under the
|
|
5
7
|
* platform inputs dir (the universal path — every server-created attachment
|
|
@@ -14,9 +16,9 @@ import { mkdtempSync, writeFileSync, readFileSync, rmSync, lstatSync, readlinkSy
|
|
|
14
16
|
import { join } from "node:path";
|
|
15
17
|
import { tmpdir } from "node:os";
|
|
16
18
|
import { resolveAttachments, AttachmentResolutionError } from "../attachment-resolver.js";
|
|
17
|
-
import { getPlatformDir } from "
|
|
18
|
-
import { makeInMemoryArtifactStorage } from "
|
|
19
|
-
import { CURSOR_VISION_PROFILE, VisionBudget } from "
|
|
19
|
+
import { getPlatformDir } from "../workspace/platform-dir.js";
|
|
20
|
+
import { makeInMemoryArtifactStorage } from "../../__test-utils__/fake-artifact-storage.js";
|
|
21
|
+
import { CURSOR_VISION_PROFILE, VisionBudget } from "../attachment-vision.js";
|
|
20
22
|
|
|
21
23
|
function makeAttachment(overrides: Partial<{
|
|
22
24
|
filename: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Unit tests for the
|
|
2
|
+
* Unit tests for the max_cost_usd hard-stop guard (cost-guard.ts), which the
|
|
3
|
+
* Cursor activity calls today and the turn runtime takes over in S2 M3.
|
|
3
4
|
*
|
|
4
5
|
* The guard is the cursor-side analog of the native cost-cap middleware
|
|
5
6
|
* (middleware/cost-cap.ts): same proto semantics (0/unset = no cap), same
|
|
@@ -45,9 +45,9 @@ import {
|
|
|
45
45
|
excludeAppliedFromGrants,
|
|
46
46
|
resolveApprovedWholeFileContent,
|
|
47
47
|
} from "../exact-apply.js";
|
|
48
|
-
import { ELISION_MARKER } from "
|
|
49
|
-
import { mockWorkspaceBackend } from "
|
|
50
|
-
import type { WorkspaceBackend } from "
|
|
48
|
+
import { ELISION_MARKER } from "../status-offload.js";
|
|
49
|
+
import { mockWorkspaceBackend } from "../../__test-utils__/mock-workspace.js";
|
|
50
|
+
import type { WorkspaceBackend } from "../workspace/types.js";
|
|
51
51
|
|
|
52
52
|
const ROOT = "/root";
|
|
53
53
|
|
package/src/{activities/execute-cursor → shared}/__tests__/extract-structured-output.test.ts
RENAMED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import type { Config } from "
|
|
2
|
+
import type { Config } from "../../config.js";
|
|
3
3
|
|
|
4
|
-
vi.mock("
|
|
4
|
+
vi.mock("../model-registry.js", () => ({
|
|
5
5
|
getEconomyModel: vi.fn().mockResolvedValue("gpt-4o-mini"),
|
|
6
6
|
}));
|
|
7
7
|
|
|
8
8
|
const mockInvoke = vi.fn();
|
|
9
9
|
const mockWithStructuredOutput = vi.fn().mockReturnValue({ invoke: mockInvoke });
|
|
10
10
|
|
|
11
|
-
vi.mock("
|
|
11
|
+
vi.mock("../model-client.js", () => ({
|
|
12
12
|
buildChatModel: vi.fn().mockResolvedValue({
|
|
13
13
|
model: { withStructuredOutput: (...args: unknown[]) => mockWithStructuredOutput(...args) },
|
|
14
14
|
provider: "openai",
|
|
@@ -46,7 +46,7 @@ describe("extractStructuredOutput", () => {
|
|
|
46
46
|
|
|
47
47
|
it("direct mode with a key builds a direct-mode model (no endpoint threaded)", async () => {
|
|
48
48
|
vi.stubEnv("OPENAI_API_KEY", "sk-direct");
|
|
49
|
-
const { buildChatModel } = await import("
|
|
49
|
+
const { buildChatModel } = await import("../model-client.js");
|
|
50
50
|
const { extractStructuredOutput } = await import("../extract-structured-output.js");
|
|
51
51
|
mockInvoke.mockResolvedValueOnce({ answer: "42" });
|
|
52
52
|
|
|
@@ -61,7 +61,7 @@ describe("extractStructuredOutput", () => {
|
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
it("throws the credential message before any construction when no path exists", async () => {
|
|
64
|
-
const { buildChatModel } = await import("
|
|
64
|
+
const { buildChatModel } = await import("../model-client.js");
|
|
65
65
|
const { extractStructuredOutput } = await import("../extract-structured-output.js");
|
|
66
66
|
|
|
67
67
|
await expect(
|
|
@@ -72,7 +72,7 @@ describe("extractStructuredOutput", () => {
|
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
it("proxy mode threads the proxy endpoint and token, consulting no keys", async () => {
|
|
75
|
-
const { buildChatModel } = await import("
|
|
75
|
+
const { buildChatModel } = await import("../model-client.js");
|
|
76
76
|
const { extractStructuredOutput } = await import("../extract-structured-output.js");
|
|
77
77
|
mockInvoke.mockResolvedValueOnce({ answer: "ok" });
|
|
78
78
|
|
|
@@ -95,9 +95,9 @@ describe("extractStructuredOutput", () => {
|
|
|
95
95
|
// The registry-empty fallback returns the primary model verbatim; when
|
|
96
96
|
// its provider can't be inferred the pre-check must not guess — the
|
|
97
97
|
// construction path owns the precise message.
|
|
98
|
-
const { getEconomyModel } = await import("
|
|
98
|
+
const { getEconomyModel } = await import("../model-registry.js");
|
|
99
99
|
vi.mocked(getEconomyModel).mockResolvedValueOnce("mystery-model");
|
|
100
|
-
const { buildChatModel } = await import("
|
|
100
|
+
const { buildChatModel } = await import("../model-client.js");
|
|
101
101
|
const { extractStructuredOutput } = await import("../extract-structured-output.js");
|
|
102
102
|
mockInvoke.mockResolvedValueOnce({ answer: "ok" });
|
|
103
103
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Unit tests for the
|
|
2
|
+
* Unit tests for the streaming persist decision (issue #179), the shared
|
|
3
|
+
* cadence rule the Cursor stream loop calls today and the turn runtime
|
|
4
|
+
* takes over in S2 M3.
|
|
3
5
|
*
|
|
4
6
|
* Validates the converged cadence: discrete force-flush signals persist
|
|
5
7
|
* immediately, while high-frequency token deltas ride the shared
|
|
@@ -11,7 +13,7 @@ import { describe, it, expect } from "vitest";
|
|
|
11
13
|
import {
|
|
12
14
|
StreamingUpdateScheduler,
|
|
13
15
|
type StreamingConfig,
|
|
14
|
-
} from "
|
|
16
|
+
} from "../streaming-scheduler.js";
|
|
15
17
|
import { shouldPersistStreamingStatus } from "../persist-decision.js";
|
|
16
18
|
|
|
17
19
|
const CONFIG: StreamingConfig = {
|
|
@@ -75,7 +75,7 @@ describe("resolveSkills — artifact extraction", () => {
|
|
|
75
75
|
|
|
76
76
|
// We need to clean up the platform dir after the test; capture it
|
|
77
77
|
// via the getPlatformDir import so we know the actual path.
|
|
78
|
-
const { getPlatformDir } = await import("
|
|
78
|
+
const { getPlatformDir } = await import("../workspace/platform-dir.js");
|
|
79
79
|
const platformDir = getPlatformDir(sessionId);
|
|
80
80
|
|
|
81
81
|
const client = {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { create } from "@bufbuild/protobuf";
|
|
3
|
+
import { SubAgentExecutionSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/subagent_pb";
|
|
4
|
+
import { SubAgentStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
5
|
+
|
|
6
|
+
import { cancelInProgressSubAgentProtos } from "../subagent-rows.js";
|
|
7
|
+
|
|
8
|
+
describe("cancelInProgressSubAgentProtos", () => {
|
|
9
|
+
it("cancels IN_PROGRESS/PENDING protos in place and reports whether anything changed", () => {
|
|
10
|
+
const running = create(SubAgentExecutionSchema, { id: "a", status: SubAgentStatus.SUB_AGENT_IN_PROGRESS });
|
|
11
|
+
const pending = create(SubAgentExecutionSchema, { id: "b", status: SubAgentStatus.SUB_AGENT_PENDING });
|
|
12
|
+
const completed = create(SubAgentExecutionSchema, {
|
|
13
|
+
id: "c",
|
|
14
|
+
status: SubAgentStatus.SUB_AGENT_COMPLETED,
|
|
15
|
+
completedAt: "2026-01-01T00:00:00Z",
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const changed = cancelInProgressSubAgentProtos([running, pending, completed]);
|
|
19
|
+
|
|
20
|
+
expect(changed).toBe(true);
|
|
21
|
+
expect(running.status).toBe(SubAgentStatus.SUB_AGENT_CANCELLED);
|
|
22
|
+
expect(running.completedAt).not.toBe("");
|
|
23
|
+
expect(pending.status).toBe(SubAgentStatus.SUB_AGENT_CANCELLED);
|
|
24
|
+
// Terminal sub-agents are untouched.
|
|
25
|
+
expect(completed.status).toBe(SubAgentStatus.SUB_AGENT_COMPLETED);
|
|
26
|
+
expect(completed.completedAt).toBe("2026-01-01T00:00:00Z");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("returns false when there is nothing to cancel", () => {
|
|
30
|
+
const completed = create(SubAgentExecutionSchema, { id: "c", status: SubAgentStatus.SUB_AGENT_COMPLETED });
|
|
31
|
+
expect(cancelInProgressSubAgentProtos([completed])).toBe(false);
|
|
32
|
+
expect(cancelInProgressSubAgentProtos([])).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
});
|