@stigmer/runner 3.10.0 → 3.11.1-dev.20260812192248
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/dist/.build-fingerprint +1 -1
- package/dist/activities/call-llm.js +9 -10
- package/dist/activities/call-llm.js.map +1 -1
- package/dist/activities/classify-tool-approvals.d.ts +2 -1
- package/dist/activities/classify-tool-approvals.js +28 -2
- package/dist/activities/classify-tool-approvals.js.map +1 -1
- package/dist/activities/discover-mcp-server.d.ts +39 -0
- package/dist/activities/discover-mcp-server.js +165 -28
- package/dist/activities/discover-mcp-server.js.map +1 -1
- package/dist/activities/emit-event.d.ts +14 -2
- package/dist/activities/emit-event.js +52 -17
- package/dist/activities/emit-event.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +8 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +1 -1
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +28 -2
- package/dist/activities/execute-cursor/approval-state.js +7 -1
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/attachment-resolver.d.ts +14 -0
- package/dist/activities/execute-cursor/attachment-resolver.js +18 -4
- package/dist/activities/execute-cursor/attachment-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/blueprint-resolver.d.ts +1 -9
- package/dist/activities/execute-cursor/blueprint-resolver.js +6 -22
- package/dist/activities/execute-cursor/blueprint-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/env-resolver.js +3 -1
- package/dist/activities/execute-cursor/env-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/error-classifier.d.ts +59 -3
- package/dist/activities/execute-cursor/error-classifier.js +115 -6
- package/dist/activities/execute-cursor/error-classifier.js.map +1 -1
- package/dist/activities/execute-cursor/extract-structured-output.d.ts +29 -0
- package/dist/activities/execute-cursor/extract-structured-output.js +58 -0
- package/dist/activities/execute-cursor/extract-structured-output.js.map +1 -0
- package/dist/activities/execute-cursor/hook-script.d.ts +14 -3
- package/dist/activities/execute-cursor/hook-script.js +72 -10
- package/dist/activities/execute-cursor/hook-script.js.map +1 -1
- package/dist/activities/execute-cursor/index.d.ts +51 -11
- package/dist/activities/execute-cursor/index.js +177 -93
- package/dist/activities/execute-cursor/index.js.map +1 -1
- package/dist/activities/execute-cursor/mcp-resolver.d.ts +24 -1
- package/dist/activities/execute-cursor/mcp-resolver.js +5 -2
- package/dist/activities/execute-cursor/mcp-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/model-pricing-data.d.ts +2 -0
- package/dist/activities/execute-cursor/model-pricing-data.js +13 -3
- package/dist/activities/execute-cursor/model-pricing-data.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +51 -4
- package/dist/activities/execute-cursor/prompt-builder.js +49 -7
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/turn-recovery.d.ts +52 -0
- package/dist/activities/execute-cursor/turn-recovery.js +193 -0
- package/dist/activities/execute-cursor/turn-recovery.js.map +1 -0
- package/dist/activities/execute-cursor/turn-stream.js +4 -1
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +18 -1
- package/dist/activities/execute-deep-agent/attachment-injector.js +68 -23
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +1 -1
- package/dist/activities/execute-deep-agent/environment.js +3 -1
- package/dist/activities/execute-deep-agent/environment.js.map +1 -1
- package/dist/activities/execute-deep-agent/index.js +15 -0
- package/dist/activities/execute-deep-agent/index.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +7 -7
- package/dist/activities/execute-deep-agent/prompt-builder.js +8 -2
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +10 -0
- package/dist/activities/execute-deep-agent/setup.js +65 -24
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/shell-env.d.ts +5 -1
- package/dist/activities/execute-deep-agent/shell-env.js +7 -9
- package/dist/activities/execute-deep-agent/shell-env.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +18 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.js +15 -2
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +27 -6
- package/dist/activities/execute-deep-agent/subagent-wiring.js +26 -5
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/hydrate-workflow-execution.js +8 -3
- package/dist/activities/hydrate-workflow-execution.js.map +1 -1
- package/dist/activities/run-command.d.ts +5 -2
- package/dist/activities/run-command.js +22 -10
- package/dist/activities/run-command.js.map +1 -1
- package/dist/activities/run-env.d.ts +40 -0
- package/dist/activities/run-env.js +66 -0
- package/dist/activities/run-env.js.map +1 -0
- package/dist/activities/workflow-event-activities.d.ts +28 -10
- package/dist/activities/workflow-event-activities.js +87 -58
- package/dist/activities/workflow-event-activities.js.map +1 -1
- package/dist/bootstrap.js +5 -0
- package/dist/bootstrap.js.map +1 -1
- package/dist/claimcheck/payload-codec.js +21 -1
- package/dist/claimcheck/payload-codec.js.map +1 -1
- package/dist/client/stigmer-client.d.ts +83 -21
- package/dist/client/stigmer-client.js +106 -29
- package/dist/client/stigmer-client.js.map +1 -1
- package/dist/encryption/config.d.ts +64 -0
- package/dist/encryption/config.js +108 -0
- package/dist/encryption/config.js.map +1 -0
- package/dist/encryption/index.d.ts +3 -0
- package/dist/encryption/index.js +3 -0
- package/dist/encryption/index.js.map +1 -0
- package/dist/encryption/payload-codec.d.ts +41 -0
- package/dist/encryption/payload-codec.js +130 -0
- package/dist/encryption/payload-codec.js.map +1 -0
- package/dist/middleware/index.d.ts +3 -0
- package/dist/middleware/index.js +7 -0
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/path-normalization.d.ts +57 -0
- package/dist/middleware/path-normalization.js +109 -0
- package/dist/middleware/path-normalization.js.map +1 -0
- package/dist/middleware/types.d.ts +8 -0
- package/dist/payload-codecs.d.ts +17 -0
- package/dist/payload-codecs.js +42 -0
- package/dist/payload-codecs.js.map +1 -0
- package/dist/preflight.d.ts +31 -0
- package/dist/preflight.js +43 -0
- package/dist/preflight.js.map +1 -1
- package/dist/runner-manager.js +21 -17
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.js +11 -18
- package/dist/runner.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +9 -3
- package/dist/shared/approval-policy.js +15 -6
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/artifact-storage.d.ts +23 -1
- package/dist/shared/artifact-storage.js +51 -10
- package/dist/shared/artifact-storage.js.map +1 -1
- package/dist/shared/attachment-naming.d.ts +53 -0
- package/dist/shared/attachment-naming.js +59 -0
- package/dist/shared/attachment-naming.js.map +1 -0
- package/dist/shared/caller-identity.d.ts +23 -2
- package/dist/shared/caller-identity.js +36 -5
- package/dist/shared/caller-identity.js.map +1 -1
- package/dist/shared/channel-attachment.js +1 -0
- package/dist/shared/channel-attachment.js.map +1 -1
- package/dist/shared/checkpointer/http-saver.d.ts +26 -1
- package/dist/shared/checkpointer/http-saver.js +54 -8
- package/dist/shared/checkpointer/http-saver.js.map +1 -1
- package/dist/shared/conversation-attachment.js +1 -0
- package/dist/shared/conversation-attachment.js.map +1 -1
- package/dist/shared/conversation-catchup.d.ts +9 -2
- package/dist/shared/conversation-catchup.js +39 -6
- package/dist/shared/conversation-catchup.js.map +1 -1
- package/dist/shared/datastore-attachment.d.ts +50 -7
- package/dist/shared/datastore-attachment.js +93 -11
- package/dist/shared/datastore-attachment.js.map +1 -1
- package/dist/shared/grpc-retry.d.ts +5 -1
- package/dist/shared/grpc-retry.js +5 -1
- package/dist/shared/grpc-retry.js.map +1 -1
- package/dist/shared/http-retry.d.ts +85 -0
- package/dist/shared/http-retry.js +101 -0
- package/dist/shared/http-retry.js.map +1 -0
- package/dist/shared/llm-backend.d.ts +275 -0
- package/dist/shared/llm-backend.js +425 -0
- package/dist/shared/llm-backend.js.map +1 -0
- package/dist/shared/llm-proxy.d.ts +8 -0
- package/dist/shared/llm-proxy.js +15 -0
- package/dist/shared/llm-proxy.js.map +1 -1
- package/dist/shared/mcp-enabled-tools.d.ts +57 -0
- package/dist/shared/mcp-enabled-tools.js +86 -0
- package/dist/shared/mcp-enabled-tools.js.map +1 -0
- package/dist/shared/mcp-manager.d.ts +11 -5
- package/dist/shared/mcp-manager.js +47 -8
- package/dist/shared/mcp-manager.js.map +1 -1
- package/dist/shared/mcp-resolver.d.ts +39 -2
- package/dist/shared/mcp-resolver.js +38 -2
- package/dist/shared/mcp-resolver.js.map +1 -1
- package/dist/shared/mcp-schema-sanitizer.d.ts +70 -0
- package/dist/shared/mcp-schema-sanitizer.js +197 -0
- package/dist/shared/mcp-schema-sanitizer.js.map +1 -0
- package/dist/shared/model-client.d.ts +18 -5
- package/dist/shared/model-client.js +149 -18
- package/dist/shared/model-client.js.map +1 -1
- package/dist/shared/model-error.js +198 -5
- package/dist/shared/model-error.js.map +1 -1
- package/dist/shared/model-pricing-data.d.ts +2 -0
- package/dist/shared/model-pricing-data.js +13 -3
- package/dist/shared/model-pricing-data.js.map +1 -1
- package/dist/shared/model-registry.js +3 -2
- package/dist/shared/model-registry.js.map +1 -1
- package/dist/shared/plan-mode-permissions.d.ts +33 -0
- package/dist/shared/plan-mode-permissions.js +35 -0
- package/dist/shared/plan-mode-permissions.js.map +1 -0
- package/dist/shared/registry-endpoint.d.ts +20 -0
- package/dist/shared/registry-endpoint.js +25 -0
- package/dist/shared/registry-endpoint.js.map +1 -1
- package/dist/shared/runner-credential-keys.d.ts +24 -0
- package/dist/shared/runner-credential-keys.js +47 -0
- package/dist/shared/runner-credential-keys.js.map +1 -0
- package/dist/worker.d.ts +2 -1
- package/dist/worker.js +2 -4
- package/dist/worker.js.map +1 -1
- package/dist/workflow-engine/resolve.d.ts +19 -1
- package/dist/workflow-engine/resolve.js +37 -2
- package/dist/workflow-engine/resolve.js.map +1 -1
- package/dist/workflow-engine/types.d.ts +18 -0
- package/dist/workflow-engine/types.js.map +1 -1
- package/dist/workflows/call-agent-orchestrator.d.ts +9 -0
- package/dist/workflows/call-agent-orchestrator.js +1 -0
- package/dist/workflows/call-agent-orchestrator.js.map +1 -1
- package/dist/workflows/connect-mcp-server.js +9 -0
- package/dist/workflows/connect-mcp-server.js.map +1 -1
- package/dist/workflows/engine-core.js +23 -2
- package/dist/workflows/engine-core.js.map +1 -1
- package/dist/workflows/execute-from-execution.d.ts +1 -1
- package/dist/workflows/execute-from-execution.js +11 -1
- package/dist/workflows/execute-from-execution.js.map +1 -1
- package/dist/workflows/types.d.ts +8 -0
- package/package.json +9 -4
- package/src/__test-utils__/__tests__/vitest-global-setup.test.ts +37 -0
- package/src/__test-utils__/vitest-global-setup.ts +50 -0
- package/src/__tests__/bootstrap.test.ts +43 -0
- package/src/__tests__/claimcheck-codec.test.ts +36 -0
- package/src/__tests__/encryption-codec.test.ts +287 -0
- package/src/__tests__/fixtures/encrypted-payload-fixture.json +15 -0
- package/src/__tests__/history-encryption-e2e.test.ts +243 -0
- package/src/__tests__/preflight.test.ts +65 -2
- package/src/activities/__tests__/call-llm.test.ts +75 -0
- package/src/activities/__tests__/classify-tool-approvals.test.ts +117 -1
- package/src/activities/__tests__/discover-mcp-server.hang.test.ts +103 -0
- package/src/activities/__tests__/discover-mcp-server.test.ts +242 -1
- package/src/activities/__tests__/error-classifier.test.ts +94 -2
- package/src/activities/__tests__/run-command.test.ts +221 -0
- package/src/activities/__tests__/workflow-event-activities.test.ts +107 -8
- package/src/activities/call-llm.ts +9 -16
- package/src/activities/classify-tool-approvals.ts +34 -4
- package/src/activities/discover-mcp-server.ts +203 -31
- package/src/activities/emit-event.ts +65 -21
- package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +9 -0
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +14 -0
- package/src/activities/execute-cursor/__tests__/attachment-resolver.test.ts +53 -0
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +151 -16
- package/src/activities/execute-cursor/__tests__/error-classifier-extraction.test.ts +208 -0
- package/src/activities/execute-cursor/__tests__/extract-structured-output.test.ts +120 -0
- package/src/activities/execute-cursor/__tests__/hook-script.test.ts +93 -0
- package/src/activities/execute-cursor/__tests__/mcp-resolver.test.ts +125 -0
- package/src/activities/execute-cursor/__tests__/model-pricing.test.ts +62 -1
- package/src/activities/execute-cursor/__tests__/prompt-builder-delegation.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/turn-recovery.test.ts +160 -0
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +13 -0
- package/src/activities/execute-cursor/approval-state.ts +30 -1
- package/src/activities/execute-cursor/attachment-resolver.ts +31 -3
- package/src/activities/execute-cursor/blueprint-resolver.ts +7 -27
- package/src/activities/execute-cursor/env-resolver.ts +3 -1
- package/src/activities/execute-cursor/error-classifier.ts +131 -7
- package/src/activities/execute-cursor/extract-structured-output.ts +72 -0
- package/src/activities/execute-cursor/hook-script.ts +74 -10
- package/src/activities/execute-cursor/index.ts +209 -109
- package/src/activities/execute-cursor/mcp-resolver.ts +36 -2
- package/src/activities/execute-cursor/model-pricing-data.ts +22 -3
- package/src/activities/execute-cursor/prompt-builder.ts +85 -9
- package/src/activities/execute-cursor/turn-recovery.ts +208 -0
- package/src/activities/execute-cursor/turn-stream.ts +5 -2
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +110 -8
- package/src/activities/execute-deep-agent/__tests__/datastore-degradation.test.ts +104 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +2 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +174 -0
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +34 -5
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/shell-env.test.ts +24 -10
- package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +178 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +12 -7
- package/src/activities/execute-deep-agent/attachment-injector.ts +94 -30
- package/src/activities/execute-deep-agent/environment.ts +3 -1
- package/src/activities/execute-deep-agent/index.ts +20 -0
- package/src/activities/execute-deep-agent/prompt-builder.ts +20 -10
- package/src/activities/execute-deep-agent/setup.ts +85 -29
- package/src/activities/execute-deep-agent/shell-env.ts +8 -9
- package/src/activities/execute-deep-agent/subagent-transformer.ts +30 -2
- package/src/activities/execute-deep-agent/subagent-wiring.ts +39 -6
- package/src/activities/hydrate-workflow-execution.ts +8 -3
- package/src/activities/run-command.ts +25 -12
- package/src/activities/run-env.ts +79 -0
- package/src/activities/workflow-event-activities.ts +96 -69
- package/src/bootstrap.ts +5 -0
- package/src/claimcheck/payload-codec.ts +33 -1
- package/src/client/__tests__/stigmer-client.test.ts +110 -11
- package/src/client/stigmer-client.ts +150 -37
- package/src/encryption/config.ts +155 -0
- package/src/encryption/index.ts +3 -0
- package/src/encryption/payload-codec.ts +152 -0
- package/src/middleware/__tests__/path-normalization.test.ts +140 -0
- package/src/middleware/index.ts +8 -0
- package/src/middleware/path-normalization.ts +125 -0
- package/src/middleware/types.ts +11 -0
- package/src/payload-codecs.ts +62 -0
- package/src/preflight.ts +45 -0
- package/src/runner-manager.ts +26 -26
- package/src/runner.ts +12 -27
- package/src/shared/__tests__/approval-policy.test.ts +82 -39
- package/src/shared/__tests__/artifact-storage.test.ts +145 -2
- package/src/shared/__tests__/attachment-naming.test.ts +159 -0
- package/src/shared/__tests__/bedrock-adapter.test.ts +213 -0
- package/src/shared/__tests__/bedrock-seam.test.ts +390 -0
- package/src/shared/__tests__/caller-identity.test.ts +25 -0
- package/src/shared/__tests__/channel-attachment.test.ts +1 -1
- package/src/shared/__tests__/connect-backfill.test.ts +1 -0
- package/src/shared/__tests__/conversation-attachment.test.ts +1 -1
- package/src/shared/__tests__/conversation-catchup.test.ts +24 -0
- package/src/shared/__tests__/datastore-attachment.test.ts +129 -1
- package/src/shared/__tests__/foundry-adapter.test.ts +276 -0
- package/src/shared/__tests__/foundry-seam.test.ts +482 -0
- package/src/shared/__tests__/http-retry.test.ts +68 -0
- package/src/shared/__tests__/llm-backend.test.ts +616 -0
- package/src/shared/__tests__/mcp-enabled-tools.test.ts +86 -0
- package/src/shared/__tests__/mcp-manager.test.ts +137 -15
- package/src/shared/__tests__/mcp-resolver.test.ts +146 -3
- package/src/shared/__tests__/mcp-schema-sanitizer.test.ts +267 -0
- package/src/shared/__tests__/model-client.test.ts +200 -0
- package/src/shared/__tests__/model-error.test.ts +289 -1
- package/src/shared/__tests__/model-pricing.test.ts +62 -2
- package/src/shared/__tests__/model-registry.test.ts +22 -0
- package/src/shared/__tests__/synthesized-attachment.test.ts +1 -0
- package/src/shared/__tests__/vertex-adapter.test.ts +169 -0
- package/src/shared/__tests__/vertex-seam.test.ts +295 -0
- package/src/shared/approval-policy.ts +14 -7
- package/src/shared/artifact-storage.ts +75 -10
- package/src/shared/attachment-naming.ts +78 -0
- package/src/shared/caller-identity.ts +40 -5
- package/src/shared/channel-attachment.ts +1 -0
- package/src/shared/checkpointer/__tests__/http-saver.test.ts +196 -1
- package/src/shared/checkpointer/http-saver.ts +71 -8
- package/src/shared/conversation-attachment.ts +1 -0
- package/src/shared/conversation-catchup.ts +39 -6
- package/src/shared/datastore-attachment.ts +106 -11
- package/src/shared/grpc-retry.ts +5 -1
- package/src/shared/http-retry.ts +139 -0
- package/src/shared/llm-backend.ts +544 -0
- package/src/shared/llm-proxy.ts +15 -0
- package/src/shared/mcp-enabled-tools.ts +105 -0
- package/src/shared/mcp-manager.ts +56 -8
- package/src/shared/mcp-resolver.ts +73 -2
- package/src/shared/mcp-schema-sanitizer.ts +224 -0
- package/src/shared/model-client.ts +179 -19
- package/src/shared/model-error.ts +222 -4
- package/src/shared/model-pricing-data.ts +22 -3
- package/src/shared/model-registry.ts +7 -2
- package/src/shared/plan-mode-permissions.ts +37 -0
- package/src/shared/registry-endpoint.ts +27 -0
- package/src/shared/runner-credential-keys.ts +46 -0
- package/src/worker.ts +4 -5
- package/src/workflow-engine/__tests__/tasks/emit-event.test.ts +127 -49
- package/src/workflow-engine/resolve.ts +48 -2
- package/src/workflow-engine/types.ts +18 -0
- package/src/workflows/__tests__/connect-mcp-server.test.ts +25 -0
- package/src/workflows/__tests__/execute-serverless-workflow.test.ts +68 -2
- package/src/workflows/call-agent-orchestrator.ts +10 -0
- package/src/workflows/connect-mcp-server.ts +9 -0
- package/src/workflows/engine-core.ts +23 -2
- package/src/workflows/execute-from-execution.ts +12 -2
- package/src/workflows/types.ts +8 -0
- package/dist/activities/execute-cursor/mcp-config.d.ts +0 -30
- package/dist/activities/execute-cursor/mcp-config.js +0 -39
- package/dist/activities/execute-cursor/mcp-config.js.map +0 -1
- package/src/activities/execute-cursor/mcp-config.ts +0 -66
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
import { InteractionMode, ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
29
29
|
import type { Config } from "../../config.js";
|
|
30
|
-
import type { AgentResolution } from "./session-lifecycle.js";
|
|
30
|
+
import type { AgentResolution, AgentResolutionReason } from "./session-lifecycle.js";
|
|
31
31
|
import { type ExecuteActivityInput } from "../../shared/activity-input.js";
|
|
32
32
|
/**
|
|
33
33
|
* Creates the activity functions bound to the runner config.
|
|
@@ -52,7 +52,11 @@ export interface BuildPromptInput {
|
|
|
52
52
|
subAgents: import("@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb").SubAgent[];
|
|
53
53
|
workspaceDirs: string[];
|
|
54
54
|
workspaceFileRefs: string[];
|
|
55
|
-
|
|
55
|
+
/**
|
|
56
|
+
* This turn's resolved attachments for the `<input_files>` section —
|
|
57
|
+
* final paths plus duplicate-rename disclosure (attachment-resolver.ts).
|
|
58
|
+
*/
|
|
59
|
+
attachments: import("./prompt-builder.js").AttachmentPromptEntry[];
|
|
56
60
|
/**
|
|
57
61
|
* Vision facts for the input-files section (T04): which attachments the
|
|
58
62
|
* model sees inline and which degraded to path-only. PER-TURN like the
|
|
@@ -103,6 +107,15 @@ export interface BuildPromptInput {
|
|
|
103
107
|
* usually blank.
|
|
104
108
|
*/
|
|
105
109
|
conversationCatchup?: string;
|
|
110
|
+
/**
|
|
111
|
+
* The turn's recorded transcript rendered as digest lines
|
|
112
|
+
* (turn-recovery.ts), composed from `status.messages` at the call site.
|
|
113
|
+
* Consumed ONLY by the HITL-recovery shape — a fresh agent that replaced
|
|
114
|
+
* a lost one mid-HITL needs the story of the work it no longer remembers
|
|
115
|
+
* (issue #366); every other shape either has native context or no prior
|
|
116
|
+
* work to tell.
|
|
117
|
+
*/
|
|
118
|
+
turnRecoveryDigest?: string;
|
|
106
119
|
}
|
|
107
120
|
/**
|
|
108
121
|
* Select and build the appropriate prompt based on resolution reason and
|
|
@@ -113,20 +126,47 @@ export interface BuildPromptInput {
|
|
|
113
126
|
* volume, or cloud server-side state) — there is no separate continuation
|
|
114
127
|
* store. The prompt therefore depends only on how the agent was resolved:
|
|
115
128
|
*
|
|
116
|
-
* 1. HITL reinvocation -> buildReinvocationPrompt (approval decisions
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* 2.
|
|
120
|
-
*
|
|
129
|
+
* 1. HITL reinvocation, -> buildReinvocationPrompt (approval decisions
|
|
130
|
+
* resumed agent only; the resumed agent's native context
|
|
131
|
+
* carries the prior conversation)
|
|
132
|
+
* 2. HITL reinvocation, -> buildHitlRecoveryPrompt (full context +
|
|
133
|
+
* fresh agent after the turn's recorded transcript + decisions;
|
|
134
|
+
* resume failure the replacement agent's conversation is
|
|
135
|
+
* empty, and both fresh-agent crossings —
|
|
136
|
+
* resolution-time resume failure and mid-send
|
|
137
|
+
* poisoned-handle recovery — land here by
|
|
138
|
+
* keying on the reason, issue #366)
|
|
139
|
+
* 3. resumed_successfully -> raw userMessage (native context carries it)
|
|
140
|
+
* 4. first execution / fresh -> buildEnhancedPrompt (full instructions +
|
|
121
141
|
* agent after resume failure skills; no prior conversation to inherit)
|
|
122
142
|
*/
|
|
123
143
|
/**
|
|
124
144
|
* Whether this activity invocation is a HITL re-invocation — the turn resumes
|
|
125
145
|
* an agent purely to convey approval decisions, carrying NO user message.
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* vision payload
|
|
129
|
-
*
|
|
146
|
+
* Discriminates the two surfaces that depend on the agent already holding
|
|
147
|
+
* this turn's content natively — the prompt shape (below) and the primary
|
|
148
|
+
* send's vision payload — but never alone: both pair it with
|
|
149
|
+
* `resolution.reason`, because a FRESH agent mid-HITL holds nothing and
|
|
150
|
+
* needs the full re-delivery (issue #366).
|
|
130
151
|
*/
|
|
131
152
|
export declare function isHitlReinvocation(approvalDecisions: Map<string, ApprovalAction> | undefined): approvalDecisions is Map<string, ApprovalAction>;
|
|
153
|
+
/**
|
|
154
|
+
* Whether the PRIMARY send delivers the turn's vision payload. The invariant
|
|
155
|
+
* is "images accompany the user's turn message, wherever the conversation
|
|
156
|
+
* does not already hold them" — so the only send that skips them is a HITL
|
|
157
|
+
* re-invocation of a successfully RESUMED agent, whose native conversation
|
|
158
|
+
* carries the images from the original send. A fresh agent mid-HITL
|
|
159
|
+
* (resolution-time resume failure — issue #366's vision corollary) holds
|
|
160
|
+
* nothing and needs the re-delivery. The mid-send recovery retries always
|
|
161
|
+
* run on a fresh agent, so their send sites carry the payload
|
|
162
|
+
* unconditionally rather than consulting this.
|
|
163
|
+
*/
|
|
164
|
+
export declare function primarySendCarriesImages(approvalDecisions: Map<string, ApprovalAction> | undefined, reason: AgentResolutionReason): boolean;
|
|
165
|
+
/**
|
|
166
|
+
* Append the structured-output contract to a prompt when the execution
|
|
167
|
+
* requests one. A per-turn directive (the buildFromPlan rule): it must ride
|
|
168
|
+
* every prompt this turn sends — the primary send AND the poisoned-handle
|
|
169
|
+
* recovery rebuild, which previously lost it (issue #366 ride-along).
|
|
170
|
+
*/
|
|
171
|
+
export declare function appendStructuredOutputDirective(basePrompt: string, schema: Record<string, unknown> | undefined): string;
|
|
132
172
|
export declare function buildPrompt(input: BuildPromptInput): string;
|
|
@@ -62,6 +62,7 @@ import { readChannelConversationId, synthesizeConversationAttachment, } from "..
|
|
|
62
62
|
import { injectSynthesizedAttachment } from "../../shared/synthesized-attachment.js";
|
|
63
63
|
import { mergeApprovalPolicies } from "./approval-policy.js";
|
|
64
64
|
import { deriveActiveLeases, isUnattendedApprovalMode } from "../../shared/approval-policy.js";
|
|
65
|
+
import { enabledToolsBySlug } from "../../shared/mcp-enabled-tools.js";
|
|
65
66
|
import { backfillMcpServersIfNeeded } from "./connect-backfill.js";
|
|
66
67
|
import { resolveExecutionEnv } from "./env-resolver.js";
|
|
67
68
|
import { resolveBlueprint } from "./blueprint-resolver.js";
|
|
@@ -69,7 +70,8 @@ import { buildCursorSubAgentDefinitions } from "./subagent-config.js";
|
|
|
69
70
|
import { resolveSkills } from "./skill-resolver.js";
|
|
70
71
|
import { removeStigmerSymlink } from "../../shared/workspace/stigmer-link.js";
|
|
71
72
|
import { resolveAttachments } from "./attachment-resolver.js";
|
|
72
|
-
import { buildEnhancedPrompt, buildReinvocationPrompt, formatConversationCatchupSection, formatInputFiles, formatInteractionModePrefix, formatImplementPlanSection } from "./prompt-builder.js";
|
|
73
|
+
import { buildEnhancedPrompt, buildHitlRecoveryPrompt, buildReinvocationPrompt, formatConversationCatchupSection, formatInputFiles, formatInteractionModePrefix, formatImplementPlanSection } from "./prompt-builder.js";
|
|
74
|
+
import { composeTurnRecoveryDigest } from "./turn-recovery.js";
|
|
73
75
|
import { installHitlGate, removeHitlGate } from "./workspace-setup.js";
|
|
74
76
|
import { ensureHitlDir } from "../../shared/workspace/platform-dir.js";
|
|
75
77
|
import { acquireWorkspaceLock, WorkspaceLockCancelledError, WorkspaceLockTimeoutError, } from "../../shared/workspace/workspace-lock.js";
|
|
@@ -96,7 +98,7 @@ import { StreamingUsageSummarySchema } from "@stigmer/protos/ai/stigmer/agentic/
|
|
|
96
98
|
import { activityStarted, activityFinished } from "../../idle-watchdog.js";
|
|
97
99
|
import { normalizeActivityInput } from "../../shared/activity-input.js";
|
|
98
100
|
import { getCapturedRejection, clearCapturedRejection } from "./rejection-capture.js";
|
|
99
|
-
import { synthesizeError, formatClassifiedError, shouldRetryWithFreshAgent } from "./error-classifier.js";
|
|
101
|
+
import { synthesizeError, formatClassifiedError, shouldRetryWithFreshAgent, extractRunErrorSources } from "./error-classifier.js";
|
|
100
102
|
import { createAgent, createCloudAgent } from "./session-lifecycle.js";
|
|
101
103
|
import { setMaxListeners } from "node:events";
|
|
102
104
|
import { startHeartbeat } from "../../shared/heartbeat.js";
|
|
@@ -536,8 +538,20 @@ turnSeq) {
|
|
|
536
538
|
// the messaging reach; undefined lets a cloud sandbox runner's
|
|
537
539
|
// ambient session-scoped token or OSS's no-auth apply). The
|
|
538
540
|
// attachment header falls back to the ambient credential where no
|
|
539
|
-
// exchange happens.
|
|
540
|
-
|
|
541
|
+
// exchange happens. Unlike the env read (which hard-fails on a broken
|
|
542
|
+
// exchange — secrets are load-bearing there), this exchange is
|
|
543
|
+
// opportunistic: every consumer below degrades to an empty answer by
|
|
544
|
+
// contract, and the server refuses the ambient fallback safely, so a
|
|
545
|
+
// failed exchange must not kill the run.
|
|
546
|
+
let exchangedRunnerToken;
|
|
547
|
+
try {
|
|
548
|
+
exchangedRunnerToken =
|
|
549
|
+
await client.acquireScopedRunnerToken({ agentExecutionId: executionId });
|
|
550
|
+
}
|
|
551
|
+
catch (err) {
|
|
552
|
+
console.warn("[execute-cursor] Scoped-token exchange failed for attachment/discovery " +
|
|
553
|
+
`reads; degrading to the ambient credential: ${err instanceof Error ? err.message : err}`);
|
|
554
|
+
}
|
|
541
555
|
const attachmentCredential = exchangedRunnerToken
|
|
542
556
|
?? config.stigmerTokenRef?.current
|
|
543
557
|
?? config.stigmerToken;
|
|
@@ -612,9 +626,10 @@ turnSeq) {
|
|
|
612
626
|
// them as auto-approved); the global bypass empties the map entirely.
|
|
613
627
|
const leases = deriveActiveLeases(execution);
|
|
614
628
|
const globalBypass = leases.global;
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
629
|
+
// Layer-3 overrides ride each resolved server from its merged usage —
|
|
630
|
+
// see ResolvedMcpServer.toolApprovalOverrides (issue #349) — so there
|
|
631
|
+
// is no separate override input to pass here.
|
|
632
|
+
const mergedPolicies = mergeApprovalPolicies(mcpResolution.resolvedServers, leases);
|
|
618
633
|
heartbeat();
|
|
619
634
|
// Phase 4c: Validate MCP server env health (diagnostic, non-blocking)
|
|
620
635
|
const mcpWarnings = validateMcpServerEnv(mcpResolution.resolvedServers, blueprint.mergedMcpServerUsages, envVars);
|
|
@@ -650,7 +665,10 @@ turnSeq) {
|
|
|
650
665
|
storage: artifactStorage,
|
|
651
666
|
visionBudget,
|
|
652
667
|
});
|
|
653
|
-
const
|
|
668
|
+
const attachmentEntries = attachmentResults.map((a) => ({
|
|
669
|
+
path: a.relativePath,
|
|
670
|
+
...(a.renamedFrom !== undefined ? { renamedFrom: a.renamedFrom } : {}),
|
|
671
|
+
}));
|
|
654
672
|
// Vision facts, derived once from the single resolution result: the
|
|
655
673
|
// images the model will see inline (in attachment order) and the ones
|
|
656
674
|
// that degraded to path-only, disclosed in the prompt.
|
|
@@ -751,7 +769,12 @@ turnSeq) {
|
|
|
751
769
|
// approval denials with the non-pausing "unattended" kind, so the
|
|
752
770
|
// first-denial stop never fires and the turn boundary settles the denied
|
|
753
771
|
// calls as SKIPPED instead of pausing a turn nobody can approve.
|
|
754
|
-
const approvalState = buildApprovalState(mergedPolicies, globalBypass, leases.categories, approvalGrants, captureMode, captureIgnored, gitWorkspace, isUnattendedApprovalMode(execution)
|
|
772
|
+
const approvalState = buildApprovalState(mergedPolicies, globalBypass, leases.categories, approvalGrants, captureMode, captureIgnored, gitWorkspace, isUnattendedApprovalMode(execution),
|
|
773
|
+
// The enabled_tools capability manifest (issue #350): restricted
|
|
774
|
+
// servers' allow-lists, enforced by the hook's "disabled" arm ahead of
|
|
775
|
+
// every approval bypass. The Cursor SDK config cannot hide a server's
|
|
776
|
+
// tools, so this deny-at-call is the harness's enforcement.
|
|
777
|
+
enabledToolsBySlug(mcpResolution.resolvedServers));
|
|
755
778
|
const hitlGate = await installHitlGate({
|
|
756
779
|
workspaceRoot: primaryWorkspaceDir,
|
|
757
780
|
hitlDir,
|
|
@@ -944,7 +967,7 @@ turnSeq) {
|
|
|
944
967
|
subAgents: blueprint.subAgents,
|
|
945
968
|
workspaceDirs: blueprint.workspaceDirs,
|
|
946
969
|
workspaceFileRefs: spec.workspaceFileRefs ?? [],
|
|
947
|
-
|
|
970
|
+
attachments: attachmentEntries,
|
|
948
971
|
vision: visionPromptInfo,
|
|
949
972
|
pendingApprovals: adjudicatedApprovals,
|
|
950
973
|
appliedToolCallIds,
|
|
@@ -954,25 +977,36 @@ turnSeq) {
|
|
|
954
977
|
senderIdentity: readSenderIdentity(blueprint.sessionSpec.metadata),
|
|
955
978
|
sessionContext: readSessionContext(blueprint.sessionSpec.metadata),
|
|
956
979
|
conversationCatchup: readConversationCatchup(spec.conversationCatchup),
|
|
980
|
+
// The turn's recorded transcript, seeded from the persisted execution
|
|
981
|
+
// on a reinvocation (Phase 3). Consumed only by the HITL-recovery
|
|
982
|
+
// shape — reached from HERE when the stored handle failed to resume
|
|
983
|
+
// at resolution time (issue #366 crossing 2).
|
|
984
|
+
turnRecoveryDigest: isReinvocation
|
|
985
|
+
? composeTurnRecoveryDigest(status.messages)
|
|
986
|
+
: undefined,
|
|
957
987
|
});
|
|
958
|
-
// Phase 10a: Inject structured output instruction for Cursor
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
988
|
+
// Phase 10a: Inject the structured output instruction for the Cursor
|
|
989
|
+
// harness. A per-turn directive, so like buildFromPlan it must ride every
|
|
990
|
+
// prompt this turn sends — the primary AND the poisoned-handle recovery
|
|
991
|
+
// rebuild (the transport retry re-sends effectivePrompt and inherits it).
|
|
992
|
+
const withStructuredOutputDirective = (basePrompt) => appendStructuredOutputDirective(basePrompt, structuredOutputSchema);
|
|
993
|
+
const effectivePrompt = withStructuredOutputDirective(prompt);
|
|
964
994
|
// Phase 10a1: The turn's vision payload. The invariant is "images
|
|
965
|
-
// accompany the user's turn message
|
|
966
|
-
//
|
|
967
|
-
//
|
|
968
|
-
//
|
|
969
|
-
//
|
|
970
|
-
//
|
|
971
|
-
//
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
const
|
|
995
|
+
// accompany the user's turn message, wherever the conversation does not
|
|
996
|
+
// already hold them" (primarySendCarriesImages): the ONLY send that
|
|
997
|
+
// skips them is a HITL re-invocation of a successfully RESUMED agent,
|
|
998
|
+
// whose native conversation carries the images from the original send.
|
|
999
|
+
// Every send that starts an empty conversation re-delivers them — the
|
|
1000
|
+
// ordinary first/fresh-agent primary send, the HITL primary send after a
|
|
1001
|
+
// resolution-time resume failure, and both mid-send recovery retries
|
|
1002
|
+
// (which always run on a fresh agent, so their sites pass turnImages
|
|
1003
|
+
// unconditionally). Attachments re-resolve on every invocation
|
|
1004
|
+
// (Phase 5b), so the bytes are in hand even on a re-invocation.
|
|
1005
|
+
const turnImages = toCursorImages(visionImages);
|
|
1006
|
+
const primarySendImages = primarySendCarriesImages(approvalDecisions, resolution.reason)
|
|
1007
|
+
? turnImages
|
|
1008
|
+
: [];
|
|
1009
|
+
const toSendMessage = (sendPrompt, images) => images.length > 0 ? { text: sendPrompt, images } : sendPrompt;
|
|
976
1010
|
// Phase 10a2: Log Stigmer preamble size for context trimming diagnostics
|
|
977
1011
|
const promptChars = effectivePrompt.length;
|
|
978
1012
|
const promptEstimatedTokens = Math.ceil(promptChars / 4);
|
|
@@ -1073,7 +1107,7 @@ turnSeq) {
|
|
|
1073
1107
|
// The stall watchdog is armed inside consumeCursorTurnStream (it needs the
|
|
1074
1108
|
// run to cancel), stored on turnState.stallWatchdog so this shared onDelta can
|
|
1075
1109
|
// reset it and the activity's finally can stop it as a backstop.
|
|
1076
|
-
const run = await resolution.agent.send(toSendMessage(effectivePrompt), {
|
|
1110
|
+
const run = await resolution.agent.send(toSendMessage(effectivePrompt, primarySendImages), {
|
|
1077
1111
|
onDelta: (event) => {
|
|
1078
1112
|
if (!turnFirstEventEmitted) {
|
|
1079
1113
|
turnFirstEventEmitted = true;
|
|
@@ -1390,10 +1424,11 @@ turnSeq) {
|
|
|
1390
1424
|
// poisoned-handle path leaked the fresh agent — it closed the stale one.)
|
|
1391
1425
|
resolution = { ...resolution, agent: freshAgent, agentId: freshAgent.agentId, isNew: true };
|
|
1392
1426
|
turnState.streamErrorMessage = undefined;
|
|
1393
|
-
// The retry carries the turn's
|
|
1394
|
-
//
|
|
1395
|
-
// silently lose the user's photo on
|
|
1396
|
-
|
|
1427
|
+
// The retry always carries the turn's full image payload — never the
|
|
1428
|
+
// primary send's HITL-trimmed set: the fresh agent's conversation is
|
|
1429
|
+
// empty, so skipping them here would silently lose the user's photo on
|
|
1430
|
+
// a recovered turn (issue #366's vision corollary).
|
|
1431
|
+
const retryRun = await freshAgent.send(toSendMessage(retryPrompt, turnImages), {
|
|
1397
1432
|
onDelta: makeCursorTurnOnDelta(onDeltaDeps),
|
|
1398
1433
|
});
|
|
1399
1434
|
await consumeCursorTurnStream(retryRun, streamDeps);
|
|
@@ -1450,12 +1485,10 @@ turnSeq) {
|
|
|
1450
1485
|
status.phase = ExecutionPhase.EXECUTION_COMPLETED;
|
|
1451
1486
|
break;
|
|
1452
1487
|
case "error": {
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
?? resultAny.reason;
|
|
1458
|
-
const sdkErrorStr = sdkError ? String(sdkError) : undefined;
|
|
1488
|
+
// Shape-aware extraction, NOT String(): the result's error fields are
|
|
1489
|
+
// structured at runtime often enough that a bare coercion showed users
|
|
1490
|
+
// "[object Object]" and shadowed every fallback source below (oss#299).
|
|
1491
|
+
const runErrorSources = extractRunErrorSources(result);
|
|
1459
1492
|
// The SDK frequently resolves run.wait() to a bare { status: "error" }
|
|
1460
1493
|
// while the real reason (e.g. the original grpc-status 12 routing
|
|
1461
1494
|
// failure) lives on the failing conversation turn. Capture it here so
|
|
@@ -1465,7 +1498,8 @@ turnSeq) {
|
|
|
1465
1498
|
if (capturedRejection)
|
|
1466
1499
|
clearCapturedRejection(executionId);
|
|
1467
1500
|
const classified = synthesizeError({
|
|
1468
|
-
|
|
1501
|
+
sdkError: runErrorSources.sdkError,
|
|
1502
|
+
sdkResultFields: runErrorSources.sdkResultFields,
|
|
1469
1503
|
streamErrorMessage: turnState.streamErrorMessage,
|
|
1470
1504
|
capturedRejection,
|
|
1471
1505
|
conversationErrorText,
|
|
@@ -1508,9 +1542,13 @@ turnSeq) {
|
|
|
1508
1542
|
subAgents: blueprint.subAgents,
|
|
1509
1543
|
workspaceDirs: blueprint.workspaceDirs,
|
|
1510
1544
|
workspaceFileRefs: spec.workspaceFileRefs ?? [],
|
|
1511
|
-
|
|
1545
|
+
attachments: attachmentEntries,
|
|
1512
1546
|
vision: visionPromptInfo,
|
|
1513
1547
|
pendingApprovals: adjudicatedApprovals,
|
|
1548
|
+
// Without the applied set, the HITL-recovery prompt would tell
|
|
1549
|
+
// the fresh agent to carry out writes the runner already
|
|
1550
|
+
// exact-applied (the primary call at Phase 10 passes it too).
|
|
1551
|
+
appliedToolCallIds,
|
|
1514
1552
|
interactionMode,
|
|
1515
1553
|
// buildFromPlan was silently dropped here until T03 Sitting 3 —
|
|
1516
1554
|
// a build turn that hit handle recovery lost its directive. The
|
|
@@ -1521,6 +1559,10 @@ turnSeq) {
|
|
|
1521
1559
|
senderIdentity: readSenderIdentity(blueprint.sessionSpec.metadata),
|
|
1522
1560
|
sessionContext: readSessionContext(blueprint.sessionSpec.metadata),
|
|
1523
1561
|
conversationCatchup: readConversationCatchup(spec.conversationCatchup),
|
|
1562
|
+
// Composed fresh (not reused from Phase 10): the failed primary
|
|
1563
|
+
// stream may have appended partial work onto status.messages,
|
|
1564
|
+
// and the replacement agent should know about that too.
|
|
1565
|
+
turnRecoveryDigest: composeTurnRecoveryDigest(status.messages),
|
|
1524
1566
|
});
|
|
1525
1567
|
console.log(`ExecuteCursor retry with fresh agent: execution=${executionId}, ` +
|
|
1526
1568
|
`newAgentId=${freshAgent.agentId}`);
|
|
@@ -1533,7 +1575,11 @@ turnSeq) {
|
|
|
1533
1575
|
catch (updateErr) {
|
|
1534
1576
|
console.warn("Failed to update session with fresh agentId (non-fatal):", updateErr);
|
|
1535
1577
|
}
|
|
1536
|
-
|
|
1578
|
+
// Same per-turn directive rule as buildFromPlan above: a
|
|
1579
|
+
// structured-output turn keeps its output contract on the rebuilt
|
|
1580
|
+
// prompt (the transport retry re-sends effectivePrompt and
|
|
1581
|
+
// inherits it without help).
|
|
1582
|
+
const outcome = await runRecoveryStream(freshAgent, withStructuredOutputDirective(freshPrompt));
|
|
1537
1583
|
if (!outcome.proceeded) {
|
|
1538
1584
|
if (outcome.terminal.kind === "return")
|
|
1539
1585
|
return slimStatus(status);
|
|
@@ -1564,8 +1610,14 @@ turnSeq) {
|
|
|
1564
1610
|
if (retryRejection)
|
|
1565
1611
|
clearCapturedRejection(executionId);
|
|
1566
1612
|
const retryConversationErrorText = await introspectConversation(retryRun, executionId);
|
|
1613
|
+
// Same shape-aware extraction as the primary error arm — the retry
|
|
1614
|
+
// previously String()-coerced result.result alone, so a structured
|
|
1615
|
+
// retry failure both read "[object Object]" and ignored the
|
|
1616
|
+
// error/message/reason fields the primary arm consults.
|
|
1617
|
+
const retryErrorSources = extractRunErrorSources(retryResult);
|
|
1567
1618
|
const retryClassified = synthesizeError({
|
|
1568
|
-
|
|
1619
|
+
sdkError: retryErrorSources.sdkError,
|
|
1620
|
+
sdkResultFields: retryErrorSources.sdkResultFields,
|
|
1569
1621
|
streamErrorMessage: turnState.streamErrorMessage,
|
|
1570
1622
|
capturedRejection: retryRejection,
|
|
1571
1623
|
conversationErrorText: retryConversationErrorText,
|
|
@@ -1661,6 +1713,7 @@ turnSeq) {
|
|
|
1661
1713
|
console.log(`ExecuteCursor text extraction failed, trying LLM extraction: execution=${executionId}, ` +
|
|
1662
1714
|
`finalTextLength=${finalText.length}`);
|
|
1663
1715
|
try {
|
|
1716
|
+
const { extractStructuredOutput } = await import("./extract-structured-output.js");
|
|
1664
1717
|
structuredOutput = await extractStructuredOutput(finalText, structuredOutputSchema, config, requestedModel);
|
|
1665
1718
|
if (structuredOutput !== undefined) {
|
|
1666
1719
|
console.log(`ExecuteCursor structured output extracted (LLM): execution=${executionId}`);
|
|
@@ -1949,40 +2002,6 @@ function seedCursorTranscriptFromExecution(status, execution) {
|
|
|
1949
2002
|
}
|
|
1950
2003
|
return persisted.subAgentExecutions.map((sub) => clone(SubAgentExecutionSchema, sub));
|
|
1951
2004
|
}
|
|
1952
|
-
// ---------------------------------------------------------------------------
|
|
1953
|
-
// Structured Output Extraction (Cursor Harness Tier 2)
|
|
1954
|
-
// ---------------------------------------------------------------------------
|
|
1955
|
-
/**
|
|
1956
|
-
* Extract structured data from an agent's free-text response using an
|
|
1957
|
-
* economy-tier LLM with withStructuredOutput (function-calling).
|
|
1958
|
-
* Guarantees schema-conformant JSON output via the API's tool-use mechanism.
|
|
1959
|
-
*
|
|
1960
|
-
* Construction (registry-id resolution, provider inference, proxy wiring) is
|
|
1961
|
-
* delegated to the shared buildChatModel so the economy model's registry id is
|
|
1962
|
-
* always resolved to a provider API id before the call.
|
|
1963
|
-
*/
|
|
1964
|
-
async function extractStructuredOutput(agentResponse, schema, config, primaryModel) {
|
|
1965
|
-
const { getEconomyModel } = await import("../../shared/model-registry.js");
|
|
1966
|
-
const { buildChatModel } = await import("../../shared/model-client.js");
|
|
1967
|
-
const extractionModel = await getEconomyModel(primaryModel);
|
|
1968
|
-
const proxyEndpoint = config.proxyEndpoint ?? config.stigmerBackendEndpoint;
|
|
1969
|
-
const { model: llm } = await buildChatModel({
|
|
1970
|
-
modelName: extractionModel,
|
|
1971
|
-
proxyEndpoint,
|
|
1972
|
-
stigmerToken: config.stigmerToken ?? undefined,
|
|
1973
|
-
maxTokens: 4096,
|
|
1974
|
-
});
|
|
1975
|
-
const zodSchema = jsonSchemaToZod(schema);
|
|
1976
|
-
const structured = llm.withStructuredOutput(zodSchema);
|
|
1977
|
-
const result = await structured.invoke([
|
|
1978
|
-
{ role: "system", content: "Extract the structured data from the agent's response. Return only the data that matches the schema." },
|
|
1979
|
-
{ role: "user", content: agentResponse },
|
|
1980
|
-
]);
|
|
1981
|
-
return result ?? null;
|
|
1982
|
-
}
|
|
1983
|
-
// Re-export for use within this module; shared implementation eliminates
|
|
1984
|
-
// the three duplicate converters that previously drifted independently.
|
|
1985
|
-
import { jsonSchemaToZod } from "../../shared/json-schema-to-zod.js";
|
|
1986
2005
|
/**
|
|
1987
2006
|
* Select and build the appropriate prompt based on resolution reason and
|
|
1988
2007
|
* HITL state.
|
|
@@ -1992,30 +2011,95 @@ import { jsonSchemaToZod } from "../../shared/json-schema-to-zod.js";
|
|
|
1992
2011
|
* volume, or cloud server-side state) — there is no separate continuation
|
|
1993
2012
|
* store. The prompt therefore depends only on how the agent was resolved:
|
|
1994
2013
|
*
|
|
1995
|
-
* 1. HITL reinvocation -> buildReinvocationPrompt (approval decisions
|
|
1996
|
-
*
|
|
1997
|
-
*
|
|
1998
|
-
* 2.
|
|
1999
|
-
*
|
|
2014
|
+
* 1. HITL reinvocation, -> buildReinvocationPrompt (approval decisions
|
|
2015
|
+
* resumed agent only; the resumed agent's native context
|
|
2016
|
+
* carries the prior conversation)
|
|
2017
|
+
* 2. HITL reinvocation, -> buildHitlRecoveryPrompt (full context +
|
|
2018
|
+
* fresh agent after the turn's recorded transcript + decisions;
|
|
2019
|
+
* resume failure the replacement agent's conversation is
|
|
2020
|
+
* empty, and both fresh-agent crossings —
|
|
2021
|
+
* resolution-time resume failure and mid-send
|
|
2022
|
+
* poisoned-handle recovery — land here by
|
|
2023
|
+
* keying on the reason, issue #366)
|
|
2024
|
+
* 3. resumed_successfully -> raw userMessage (native context carries it)
|
|
2025
|
+
* 4. first execution / fresh -> buildEnhancedPrompt (full instructions +
|
|
2000
2026
|
* agent after resume failure skills; no prior conversation to inherit)
|
|
2001
2027
|
*/
|
|
2002
2028
|
/**
|
|
2003
2029
|
* Whether this activity invocation is a HITL re-invocation — the turn resumes
|
|
2004
2030
|
* an agent purely to convey approval decisions, carrying NO user message.
|
|
2005
|
-
*
|
|
2006
|
-
*
|
|
2007
|
-
* vision payload
|
|
2008
|
-
*
|
|
2031
|
+
* Discriminates the two surfaces that depend on the agent already holding
|
|
2032
|
+
* this turn's content natively — the prompt shape (below) and the primary
|
|
2033
|
+
* send's vision payload — but never alone: both pair it with
|
|
2034
|
+
* `resolution.reason`, because a FRESH agent mid-HITL holds nothing and
|
|
2035
|
+
* needs the full re-delivery (issue #366).
|
|
2009
2036
|
*/
|
|
2010
2037
|
export function isHitlReinvocation(approvalDecisions) {
|
|
2011
2038
|
return approvalDecisions !== undefined && approvalDecisions.size > 0;
|
|
2012
2039
|
}
|
|
2040
|
+
/**
|
|
2041
|
+
* Whether the PRIMARY send delivers the turn's vision payload. The invariant
|
|
2042
|
+
* is "images accompany the user's turn message, wherever the conversation
|
|
2043
|
+
* does not already hold them" — so the only send that skips them is a HITL
|
|
2044
|
+
* re-invocation of a successfully RESUMED agent, whose native conversation
|
|
2045
|
+
* carries the images from the original send. A fresh agent mid-HITL
|
|
2046
|
+
* (resolution-time resume failure — issue #366's vision corollary) holds
|
|
2047
|
+
* nothing and needs the re-delivery. The mid-send recovery retries always
|
|
2048
|
+
* run on a fresh agent, so their send sites carry the payload
|
|
2049
|
+
* unconditionally rather than consulting this.
|
|
2050
|
+
*/
|
|
2051
|
+
export function primarySendCarriesImages(approvalDecisions, reason) {
|
|
2052
|
+
return !(isHitlReinvocation(approvalDecisions) && reason === "resumed_successfully");
|
|
2053
|
+
}
|
|
2054
|
+
/**
|
|
2055
|
+
* Append the structured-output contract to a prompt when the execution
|
|
2056
|
+
* requests one. A per-turn directive (the buildFromPlan rule): it must ride
|
|
2057
|
+
* every prompt this turn sends — the primary send AND the poisoned-handle
|
|
2058
|
+
* recovery rebuild, which previously lost it (issue #366 ride-along).
|
|
2059
|
+
*/
|
|
2060
|
+
export function appendStructuredOutputDirective(basePrompt, schema) {
|
|
2061
|
+
if (!schema)
|
|
2062
|
+
return basePrompt;
|
|
2063
|
+
const schemaStr = JSON.stringify(schema, null, 2);
|
|
2064
|
+
return basePrompt + `\n\n---\nCRITICAL OUTPUT REQUIREMENT:\nYour final response MUST be a single valid JSON object (no markdown, no commentary, no code fences) that matches this schema:\n${schemaStr}\n\nRespond with ONLY the JSON object. Nothing else.`;
|
|
2065
|
+
}
|
|
2013
2066
|
export function buildPrompt(input) {
|
|
2014
|
-
const { resolution, approvalDecisions, instructions, userMessage, skills, subAgents, workspaceDirs, workspaceFileRefs,
|
|
2015
|
-
// HITL reinvocation: the
|
|
2016
|
-
//
|
|
2017
|
-
//
|
|
2067
|
+
const { resolution, approvalDecisions, instructions, userMessage, skills, subAgents, workspaceDirs, workspaceFileRefs, attachments, interactionMode, buildFromPlan, conversationCatchup, } = input;
|
|
2068
|
+
// HITL reinvocation: the decisions-only prompt is correct ONLY while the
|
|
2069
|
+
// agent's native context still carries the prior conversation — which only
|
|
2070
|
+
// resumed_successfully guarantees. Any other reason means a fresh agent
|
|
2071
|
+
// mid-HITL (in practice created_after_resume_failure: the stored handle
|
|
2072
|
+
// failed to resume, or a poisoned handle was replaced mid-send), which
|
|
2073
|
+
// gets the full recovery shape instead — enhanced context + the turn's
|
|
2074
|
+
// recorded transcript + the same decisions — because the bare decisions on
|
|
2075
|
+
// an empty conversation strand the agent with instructions and no story,
|
|
2076
|
+
// and the session inherits that amnesia permanently (issue #366).
|
|
2018
2077
|
if (isHitlReinvocation(approvalDecisions)) {
|
|
2078
|
+
if (resolution.reason !== "resumed_successfully") {
|
|
2079
|
+
return buildHitlRecoveryPrompt({
|
|
2080
|
+
instructions,
|
|
2081
|
+
userMessage,
|
|
2082
|
+
skills,
|
|
2083
|
+
datastoreUsages: input.datastoreUsages ?? [],
|
|
2084
|
+
channelMessaging: input.channelMessaging ?? [],
|
|
2085
|
+
subAgents,
|
|
2086
|
+
workspaceDirs,
|
|
2087
|
+
workspaceFileRefs,
|
|
2088
|
+
attachments,
|
|
2089
|
+
vision: input.vision,
|
|
2090
|
+
interactionMode,
|
|
2091
|
+
buildFromPlan,
|
|
2092
|
+
contextBridge: input.contextBridge,
|
|
2093
|
+
senderIdentity: input.senderIdentity,
|
|
2094
|
+
sessionContext: input.sessionContext,
|
|
2095
|
+
conversationCatchup,
|
|
2096
|
+
}, {
|
|
2097
|
+
turnDigest: input.turnRecoveryDigest,
|
|
2098
|
+
pendingApprovals: input.pendingApprovals,
|
|
2099
|
+
approvalDecisions,
|
|
2100
|
+
appliedToolCallIds: input.appliedToolCallIds,
|
|
2101
|
+
});
|
|
2102
|
+
}
|
|
2019
2103
|
return buildReinvocationPrompt(input.pendingApprovals, approvalDecisions, input.appliedToolCallIds);
|
|
2020
2104
|
}
|
|
2021
2105
|
// A successfully resumed agent carries its own conversation context via the
|
|
@@ -2035,9 +2119,9 @@ export function buildPrompt(input) {
|
|
|
2035
2119
|
if (resolution.reason === "resumed_successfully") {
|
|
2036
2120
|
const prefixes = [
|
|
2037
2121
|
formatInteractionModePrefix(interactionMode),
|
|
2038
|
-
formatImplementPlanSection(buildFromPlan,
|
|
2039
|
-
|
|
2040
|
-
? formatInputFiles(
|
|
2122
|
+
formatImplementPlanSection(buildFromPlan, attachments),
|
|
2123
|
+
attachments.length > 0
|
|
2124
|
+
? formatInputFiles(attachments, input.vision)
|
|
2041
2125
|
: undefined,
|
|
2042
2126
|
conversationCatchup !== undefined
|
|
2043
2127
|
? formatConversationCatchupSection(conversationCatchup)
|
|
@@ -2059,7 +2143,7 @@ export function buildPrompt(input) {
|
|
|
2059
2143
|
subAgents,
|
|
2060
2144
|
workspaceDirs,
|
|
2061
2145
|
workspaceFileRefs,
|
|
2062
|
-
|
|
2146
|
+
attachments,
|
|
2063
2147
|
vision: input.vision,
|
|
2064
2148
|
interactionMode,
|
|
2065
2149
|
buildFromPlan,
|