@stigmer/runner 3.9.0 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -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 +32 -0
- package/dist/activities/discover-mcp-server.js +162 -27
- package/dist/activities/discover-mcp-server.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 +25 -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 +40 -3
- package/dist/activities/execute-cursor/error-classifier.js +81 -3
- 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 +5 -1
- package/dist/activities/execute-cursor/index.js +59 -58
- 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/prompt-builder.d.ts +18 -4
- package/dist/activities/execute-cursor/prompt-builder.js +12 -7
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- 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 -26
- package/dist/activities/execute-deep-agent/setup.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 +8 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +11 -4
- package/dist/activities/execute-deep-agent/subagent-wiring.js +13 -4
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/hydrate-workflow-execution.js +3 -1
- package/dist/activities/hydrate-workflow-execution.js.map +1 -1
- 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/claimcheck/payload-codec.js +21 -1
- package/dist/claimcheck/payload-codec.js.map +1 -1
- package/dist/client/stigmer-client.d.ts +9 -4
- package/dist/client/stigmer-client.js +28 -15
- package/dist/client/stigmer-client.js.map +1 -1
- package/dist/encryption/config.d.ts +32 -0
- package/dist/encryption/config.js +68 -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/payload-codecs.d.ts +16 -0
- package/dist/payload-codecs.js +38 -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 +5 -15
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.js +5 -16
- 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/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/attachment-vision.d.ts +43 -2
- package/dist/shared/attachment-vision.js +72 -6
- package/dist/shared/attachment-vision.js.map +1 -1
- 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 +42 -1
- package/dist/shared/checkpointer/http-saver.js +96 -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/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/http-retry.d.ts +43 -0
- package/dist/shared/http-retry.js +50 -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 +17 -2
- package/dist/shared/mcp-manager.js +37 -25
- 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/model-client.d.ts +12 -5
- package/dist/shared/model-client.js +138 -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-registry.d.ts +20 -2
- package/dist/shared/model-registry.js +37 -2
- package/dist/shared/model-registry.js.map +1 -1
- package/dist/shared/plan-mode-permissions.d.ts +26 -0
- package/dist/shared/plan-mode-permissions.js +28 -0
- package/dist/shared/plan-mode-permissions.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/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 +7 -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/package.json +8 -2
- package/src/__tests__/claimcheck-codec.test.ts +36 -0
- package/src/__tests__/encryption-codec.test.ts +234 -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 +50 -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 +203 -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 +190 -32
- 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 +92 -0
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +40 -14
- 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__/prompt-builder-delegation.test.ts +1 -1
- 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 +38 -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 +91 -4
- 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 +63 -72
- package/src/activities/execute-cursor/mcp-resolver.ts +36 -2
- package/src/activities/execute-cursor/prompt-builder.ts +34 -9
- package/src/activities/execute-cursor/turn-stream.ts +5 -2
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +132 -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__/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__/subagent-plan-mode-permissions.test.ts +173 -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 +86 -31
- package/src/activities/execute-deep-agent/subagent-transformer.ts +23 -1
- package/src/activities/execute-deep-agent/subagent-wiring.ts +14 -4
- package/src/activities/hydrate-workflow-execution.ts +3 -1
- package/src/activities/workflow-event-activities.ts +96 -69
- package/src/claimcheck/payload-codec.ts +33 -1
- package/src/client/__tests__/stigmer-client.test.ts +8 -8
- package/src/client/stigmer-client.ts +32 -18
- package/src/encryption/config.ts +91 -0
- package/src/encryption/index.ts +3 -0
- package/src/encryption/payload-codec.ts +152 -0
- package/src/payload-codecs.ts +56 -0
- package/src/preflight.ts +45 -0
- package/src/runner-manager.ts +6 -24
- package/src/runner.ts +6 -25
- package/src/shared/__tests__/approval-policy.test.ts +82 -39
- package/src/shared/__tests__/attachment-naming.test.ts +159 -0
- package/src/shared/__tests__/attachment-vision.test.ts +97 -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__/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 +67 -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 +170 -2
- package/src/shared/__tests__/mcp-resolver.test.ts +146 -3
- package/src/shared/__tests__/model-client.test.ts +154 -0
- package/src/shared/__tests__/model-error.test.ts +289 -1
- package/src/shared/__tests__/model-registry.test.ts +71 -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/attachment-naming.ts +78 -0
- package/src/shared/attachment-vision.ts +92 -9
- 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 +117 -9
- package/src/shared/conversation-attachment.ts +1 -0
- package/src/shared/datastore-attachment.ts +106 -11
- package/src/shared/http-retry.ts +50 -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 +43 -26
- package/src/shared/mcp-resolver.ts +73 -2
- package/src/shared/model-client.ts +161 -19
- package/src/shared/model-error.ts +222 -4
- package/src/shared/model-registry.ts +50 -2
- package/src/shared/plan-mode-permissions.ts +30 -0
- package/src/worker.ts +4 -5
- package/src/workflow-engine/types.ts +18 -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 +7 -0
- package/src/workflows/engine-core.ts +23 -2
- package/src/workflows/execute-from-execution.ts +12 -2
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
} from "../../shared/workspace/stigmer-link.js";
|
|
33
33
|
import type { ToolOutputOffloadContext } from "../../shared/status-offload.js";
|
|
34
34
|
import { publishPlanArtifact } from "../../shared/plan-artifact.js";
|
|
35
|
+
import { formatDatastoreDegradationNotice } from "../../shared/datastore-attachment.js";
|
|
35
36
|
import { classifyTool } from "../../shared/tool-kind.js";
|
|
36
37
|
import {
|
|
37
38
|
POLICY_ENGINE_VERSION,
|
|
@@ -151,6 +152,25 @@ export function createDeepAgentActivities(config: Config) {
|
|
|
151
152
|
const initialStatus = shouldSeedFromPersistedTranscript(setup.execution)
|
|
152
153
|
? seedStatusFromExecution(setup.execution)
|
|
153
154
|
: create(AgentExecutionStatusSchema, {});
|
|
155
|
+
|
|
156
|
+
// Datastore degradation disclosure, operator half (issue #325): the
|
|
157
|
+
// prompt already tells the agent to disclose the outage; this makes
|
|
158
|
+
// it visible on the execution record without reading a transcript.
|
|
159
|
+
// Appended to initialStatus BEFORE streaming (not via a status
|
|
160
|
+
// builder): both the v2 and v3 stream paths construct their own
|
|
161
|
+
// builder around this same proto and only ever append messages, so
|
|
162
|
+
// this row survives whichever path runs and rides every persist.
|
|
163
|
+
if (setup.datastoreToolsMissing.length > 0) {
|
|
164
|
+
initialStatus.messages.push(create(AgentMessageSchema, {
|
|
165
|
+
type: MessageType.MESSAGE_SYSTEM,
|
|
166
|
+
content: formatDatastoreDegradationNotice(
|
|
167
|
+
setup.agent.spec?.datastoreUsages?.length ?? 0,
|
|
168
|
+
setup.datastoreToolsMissing,
|
|
169
|
+
),
|
|
170
|
+
timestamp: utcTimestamp(),
|
|
171
|
+
}));
|
|
172
|
+
}
|
|
173
|
+
|
|
154
174
|
const statusBuilder = new StatusBuilder(executionId, initialStatus);
|
|
155
175
|
|
|
156
176
|
statusBuilder.setApprovalProvider({
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
buildImplementPlanDirective,
|
|
27
27
|
findApprovedPlanPath,
|
|
28
28
|
} from "../../shared/implement-plan-prompt.js";
|
|
29
|
+
import type { InjectedFile } from "./attachment-injector.js";
|
|
29
30
|
|
|
30
31
|
const RESPONSE_RULES = `
|
|
31
32
|
|
|
@@ -99,8 +100,11 @@ export interface PromptBuilderInput {
|
|
|
99
100
|
containerRoot: string;
|
|
100
101
|
skillsPromptSection: string;
|
|
101
102
|
/**
|
|
102
|
-
* The
|
|
103
|
-
* formatDatastoresSection)
|
|
103
|
+
* The datastores section (shared/datastore-attachment.ts
|
|
104
|
+
* formatDatastoresSection): `<available_datastores>` when the connected
|
|
105
|
+
* record-tool roster is complete, `<unavailable_datastores>` when setup's
|
|
106
|
+
* reconciliation found record tools missing (issue #325). Empty when the
|
|
107
|
+
* agent uses no datastores.
|
|
104
108
|
*/
|
|
105
109
|
datastoresPromptSection?: string;
|
|
106
110
|
/**
|
|
@@ -162,11 +166,10 @@ export interface PromptBuilderInput {
|
|
|
162
166
|
sessionContext?: string;
|
|
163
167
|
}
|
|
164
168
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
169
|
+
// The prompt renders the injector's own result type — a local structural twin
|
|
170
|
+
// once lived here and silently dropped the size field (`size` vs `sizeBytes`),
|
|
171
|
+
// so the "(N bytes)" annotation never rendered. One type, one truth.
|
|
172
|
+
export type { InjectedFile } from "./attachment-injector.js";
|
|
170
173
|
|
|
171
174
|
/**
|
|
172
175
|
* Which images ride the user message inline (in send order) and which
|
|
@@ -396,7 +399,7 @@ function buildReferencedFilesSection(
|
|
|
396
399
|
}
|
|
397
400
|
|
|
398
401
|
function buildInjectedFilesSection(
|
|
399
|
-
files: InjectedFile[],
|
|
402
|
+
files: readonly InjectedFile[],
|
|
400
403
|
vision?: VisionPromptInfo,
|
|
401
404
|
): string {
|
|
402
405
|
let section = "\n\n## Input Files\n\n";
|
|
@@ -410,8 +413,15 @@ function buildInjectedFilesSection(
|
|
|
410
413
|
"Do NOT modify or delete these files.\n\n";
|
|
411
414
|
|
|
412
415
|
for (const f of files) {
|
|
413
|
-
const sizeInfo =
|
|
414
|
-
|
|
416
|
+
const sizeInfo = ` (${f.sizeBytes} bytes)`;
|
|
417
|
+
// A duplicate-renamed file (attachment-naming.ts) discloses its original
|
|
418
|
+
// name so the agent can connect "the two report.pdfs" in the user's
|
|
419
|
+
// message to distinct files on disk.
|
|
420
|
+
const renameInfo =
|
|
421
|
+
f.renamedFrom !== undefined
|
|
422
|
+
? ` (renamed from duplicate '${f.renamedFrom}')`
|
|
423
|
+
: "";
|
|
424
|
+
section += `- \`${f.path}\`${sizeInfo}${renameInfo}\n`;
|
|
415
425
|
}
|
|
416
426
|
|
|
417
427
|
// The vision lines (shared wording, attachment-vision.ts) tell the model
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* the streaming phase needs.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { createDeepAgent
|
|
11
|
+
import { createDeepAgent } from "deepagents";
|
|
12
12
|
import { InteractionMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
13
13
|
import type { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
14
14
|
import { z } from "zod";
|
|
@@ -33,11 +33,13 @@ import {
|
|
|
33
33
|
} from "../../shared/caller-identity.js";
|
|
34
34
|
import { readSessionContext } from "../../shared/session-context.js";
|
|
35
35
|
import { connectMcpServers, type McpConnectionResult } from "../../shared/mcp-manager.js";
|
|
36
|
-
import { resolveMcpServers } from "../../shared/mcp-resolver.js";
|
|
36
|
+
import { mergeMcpServerUsages, resolveMcpServers } from "../../shared/mcp-resolver.js";
|
|
37
37
|
import { resolveMcpTransportPosture } from "../../shared/mcp-transport-guard.js";
|
|
38
38
|
import { backfillMcpServersIfNeeded } from "../../shared/connect-backfill.js";
|
|
39
39
|
import {
|
|
40
|
+
DATASTORE_ATTACHMENT_SLUG,
|
|
40
41
|
formatDatastoresSection,
|
|
42
|
+
missingRecordTools,
|
|
41
43
|
synthesizeDatastoreAttachment,
|
|
42
44
|
} from "../../shared/datastore-attachment.js";
|
|
43
45
|
import {
|
|
@@ -56,6 +58,7 @@ import { LocalWorkspaceBackend } from "../../shared/workspace/local-backend.js";
|
|
|
56
58
|
import type { WorkspaceBackend, ProvisionResult } from "../../shared/workspace/types.js";
|
|
57
59
|
import { createCasCaptureBackend } from "./cas-capture-backend.js";
|
|
58
60
|
import { buildShellEnv } from "./shell-env.js";
|
|
61
|
+
import { PLAN_MODE_PERMISSIONS } from "../../shared/plan-mode-permissions.js";
|
|
59
62
|
import { CasCaptureObserver } from "./cas-capture-observer.js";
|
|
60
63
|
import { isGitWorkTree, isPathCapturable } from "../../shared/filereview/git-substrate.js";
|
|
61
64
|
import { deriveCaptureMode } from "../../shared/filereview/capture.js";
|
|
@@ -73,7 +76,7 @@ import type { ApprovalGateConfig } from "../../middleware/approval-gate.js";
|
|
|
73
76
|
import { deriveExecutionFingerprintKey } from "../../shared/approval-fingerprint.js";
|
|
74
77
|
import { getRunnerHitlMasterSecret } from "../../shared/fingerprint-secret.js";
|
|
75
78
|
import { getModelPricing, ensureLoaded as ensurePricingLoaded } from "../../shared/model-pricing.js";
|
|
76
|
-
import { getDefaultModel } from "../../shared/model-registry.js";
|
|
79
|
+
import { getDefaultModel, getModelVisionCapability } from "../../shared/model-registry.js";
|
|
77
80
|
import { buildChatModel } from "../../shared/model-client.js";
|
|
78
81
|
import {
|
|
79
82
|
loadArtifactStorageConfig,
|
|
@@ -126,6 +129,16 @@ export interface SetupResult {
|
|
|
126
129
|
readonly session: Session;
|
|
127
130
|
readonly workspaceBackend: WorkspaceBackend;
|
|
128
131
|
readonly mcpConnection: McpConnectionResult | null;
|
|
132
|
+
/**
|
|
133
|
+
* Record tools declared via datastore_usages but absent from the connected
|
|
134
|
+
* stigmer-records roster this turn (issue #325). Empty = healthy (also when
|
|
135
|
+
* the agent uses no datastores). Non-empty selects the degraded prompt
|
|
136
|
+
* section in Step 8, and the activity surfaces it to operators as a
|
|
137
|
+
* MESSAGE_SYSTEM row — the vision-facts pattern: setup computes the honest
|
|
138
|
+
* struct, the caller discloses. Recomputed every turn, so a healed outage
|
|
139
|
+
* stops disclosing on the next turn.
|
|
140
|
+
*/
|
|
141
|
+
readonly datastoreToolsMissing: readonly string[];
|
|
129
142
|
readonly mergedEnvVars: Record<string, string>;
|
|
130
143
|
readonly secretKeys: ReadonlySet<string>;
|
|
131
144
|
readonly modelName: string;
|
|
@@ -348,20 +361,36 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
348
361
|
: async () => true,
|
|
349
362
|
});
|
|
350
363
|
|
|
351
|
-
// Step 7: Resolve and connect MCP servers
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
364
|
+
// Step 7: Resolve and connect MCP servers. Session-wins-per-slug merge
|
|
365
|
+
// (the Cursor harness's blueprint semantics, shared so a duplicate slug
|
|
366
|
+
// resolves identically in both harnesses — one usage per server, whose
|
|
367
|
+
// enabled_tools is the one the connect-time filter honors).
|
|
368
|
+
const mcpServerUsages = mergeMcpServerUsages(
|
|
369
|
+
agent.spec!.mcpServerUsages || [],
|
|
370
|
+
session.spec!.mcpServerUsages || [],
|
|
371
|
+
);
|
|
356
372
|
const datastoreUsages = agent.spec!.datastoreUsages || [];
|
|
357
373
|
|
|
358
374
|
// The synthesized attachments' credential story (DD-006 D4): the
|
|
359
375
|
// exchanged token authenticates the discovery reads per-call (the
|
|
360
376
|
// messaging reach refuses a desktop runner's ambient embedded_runner
|
|
361
377
|
// credential; undefined lets the ambient credential apply). The
|
|
362
|
-
// attachment header falls back to the ambient credential.
|
|
363
|
-
|
|
364
|
-
|
|
378
|
+
// attachment header falls back to the ambient credential. Unlike the
|
|
379
|
+
// env read (which hard-fails on a broken exchange — secrets are
|
|
380
|
+
// load-bearing there), this exchange is opportunistic: every consumer
|
|
381
|
+
// below degrades to an empty answer by contract, and the server
|
|
382
|
+
// refuses the ambient fallback safely, so a failed exchange must not
|
|
383
|
+
// kill the run.
|
|
384
|
+
let exchangedRunnerToken: string | undefined;
|
|
385
|
+
try {
|
|
386
|
+
exchangedRunnerToken =
|
|
387
|
+
await client.acquireScopedRunnerToken({ agentExecutionId: executionId });
|
|
388
|
+
} catch (err) {
|
|
389
|
+
console.warn(
|
|
390
|
+
"[execute-deep-agent] Scoped-token exchange failed for attachment/discovery " +
|
|
391
|
+
`reads; degrading to the ambient credential: ${err instanceof Error ? err.message : err}`,
|
|
392
|
+
);
|
|
393
|
+
}
|
|
365
394
|
const attachmentCredential = exchangedRunnerToken
|
|
366
395
|
?? config.stigmerTokenRef?.current
|
|
367
396
|
?? config.stigmerToken;
|
|
@@ -516,9 +545,16 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
516
545
|
|
|
517
546
|
// Step 7c: Inject attachments. The vision budget rides along so image
|
|
518
547
|
// attachments are selected for inline delivery while their bytes are
|
|
519
|
-
// already in hand (attachment-vision.ts owns all policy).
|
|
548
|
+
// already in hand (attachment-vision.ts owns all policy). The budget
|
|
549
|
+
// also carries the root model's registry vision capability — the root
|
|
550
|
+
// model is the only one that ever receives inline image blocks
|
|
551
|
+
// (sub-agents get a fresh task description, summarization reuses this
|
|
552
|
+
// same model instance) — so a model flagged `vision: false` degrades
|
|
553
|
+
// images honestly instead of shipping a payload its provider rejects.
|
|
520
554
|
const attachments = execution.spec!.attachments || [];
|
|
521
|
-
const visionBudget = new VisionBudget(DEEP_AGENT_VISION_PROFILE
|
|
555
|
+
const visionBudget = new VisionBudget(DEEP_AGENT_VISION_PROFILE, {
|
|
556
|
+
modelVision: await getModelVisionCapability(modelName),
|
|
557
|
+
});
|
|
522
558
|
const injectedFiles = await injectAttachments({
|
|
523
559
|
backend: workspaceBackend,
|
|
524
560
|
attachments,
|
|
@@ -549,6 +585,28 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
549
585
|
}
|
|
550
586
|
timing.mark("inject_attachments");
|
|
551
587
|
|
|
588
|
+
// Reconcile the declared datastores against the record tools actually
|
|
589
|
+
// connected (issue #325): the records roster always serves all five
|
|
590
|
+
// tools, so any absence means the store is degraded, and the prompt
|
|
591
|
+
// must say so instead of promising tools the agent does not have. The
|
|
592
|
+
// connected roster is post-connect truth — when usages exist, MCP
|
|
593
|
+
// connect always ran above (a thrown connect already failed the run).
|
|
594
|
+
const datastoreToolsMissing = datastoreUsages.length > 0 && mcpConnection
|
|
595
|
+
? missingRecordTools(
|
|
596
|
+
(mcpConnection.serverToolMap[DATASTORE_ATTACHMENT_SLUG] ?? [])
|
|
597
|
+
.map((t) => t.name),
|
|
598
|
+
)
|
|
599
|
+
: [];
|
|
600
|
+
if (datastoreToolsMissing.length > 0) {
|
|
601
|
+
console.warn(
|
|
602
|
+
`[setup] Datastore record tools degraded: declared ` +
|
|
603
|
+
`${datastoreUsages.length} datastore usage(s) but the ` +
|
|
604
|
+
`'${DATASTORE_ATTACHMENT_SLUG}' roster is missing ` +
|
|
605
|
+
`[${datastoreToolsMissing.join(", ")}] — the prompt discloses the ` +
|
|
606
|
+
`outage instead of the available-datastores section.`,
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
|
|
552
610
|
// Step 8: Build enhanced system prompt
|
|
553
611
|
const systemPrompt = buildEnhancedSystemPrompt({
|
|
554
612
|
instructions,
|
|
@@ -556,7 +614,7 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
556
614
|
containerRoot: workspaceBackend.rootDir,
|
|
557
615
|
skillsPromptSection,
|
|
558
616
|
datastoresPromptSection: datastoreUsages.length > 0
|
|
559
|
-
? formatDatastoresSection(datastoreUsages)
|
|
617
|
+
? formatDatastoresSection(datastoreUsages, datastoreToolsMissing)
|
|
560
618
|
: undefined,
|
|
561
619
|
// "" (nothing sendable) threads as undefined: the tool alone still
|
|
562
620
|
// serves text sends inside a 24-hour window (DD-006 D6).
|
|
@@ -577,8 +635,11 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
577
635
|
// Step 9: Construct the LLM model. Resolution to the provider API id
|
|
578
636
|
// happens inside buildChatModel; modelName stays the registry id for
|
|
579
637
|
// pricing, the native-thinking heuristic, and sub-agent inheritance.
|
|
580
|
-
|
|
581
|
-
|
|
638
|
+
// Operator input: only a positive integer means "bound the request" —
|
|
639
|
+
// unset, non-numeric, zero, and negative all normalize to no bound.
|
|
640
|
+
const parsedTimeoutMs =
|
|
641
|
+
Number.parseInt(process.env.STIGMER_LLM_REQUEST_TIMEOUT_MS ?? "", 10);
|
|
642
|
+
const requestTimeoutMs = parsedTimeoutMs > 0 ? parsedTimeoutMs : undefined;
|
|
582
643
|
const { model } = await buildChatModel({
|
|
583
644
|
modelName,
|
|
584
645
|
proxyEndpoint: config.proxyEndpoint ?? undefined,
|
|
@@ -614,12 +675,11 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
614
675
|
// gate. Both flow into sub-agents via the shared config below.
|
|
615
676
|
const leases = deriveActiveLeases(execution);
|
|
616
677
|
const globalBypass = leases.global;
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
)
|
|
678
|
+
// Layer-3 overrides ride each resolved server from its (session-wins
|
|
679
|
+
// merged) usage — see ResolvedMcpServer.toolApprovalOverrides (issue
|
|
680
|
+
// #349) — so there is no separate override input to pass here.
|
|
620
681
|
const approvalPolicies = mergeApprovalPolicies(
|
|
621
682
|
resolvedMcpServers?.resolvedServers ?? [],
|
|
622
|
-
agentOverrides,
|
|
623
683
|
leases,
|
|
624
684
|
);
|
|
625
685
|
|
|
@@ -760,6 +820,10 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
760
820
|
// Presence of shellEnv is the shell-capability switch for sub-agent
|
|
761
821
|
// backends too (undefined in plan mode; see buildShellEnv above).
|
|
762
822
|
shellEnv,
|
|
823
|
+
// Plan mode's deny-all-writes rule, mirrored onto every sub-agent graph
|
|
824
|
+
// (issue #255) — pre-built CompiledSubAgents never inherit the parent's
|
|
825
|
+
// permissions, so read-only-by-construction must be baked in here.
|
|
826
|
+
...(isPlanMode ? { permissions: PLAN_MODE_PERMISSIONS } : {}),
|
|
763
827
|
});
|
|
764
828
|
timing.mark("compile_subagents");
|
|
765
829
|
}
|
|
@@ -773,16 +837,6 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
773
837
|
responseFormat = jsonSchemaToZod(outputSchema as unknown as Record<string, unknown>);
|
|
774
838
|
}
|
|
775
839
|
|
|
776
|
-
// Plan mode is read-only. Deny every filesystem write operation at the tool
|
|
777
|
-
// level so write_file/edit_file/etc. cannot mutate the workspace — enforcing
|
|
778
|
-
// the InteractionMode.PLAN contract by construction, not by prompt. Rules are
|
|
779
|
-
// first-match-wins with a permissive default, so a single deny-all-writes
|
|
780
|
-
// rule is sufficient. (The Cursor harness enforces plan mode via its prompt
|
|
781
|
-
// prefix; the native harness enforces it here.)
|
|
782
|
-
const planModePermissions: FilesystemPermission[] = [
|
|
783
|
-
{ operations: ["write"], paths: ["/**"], mode: "deny" },
|
|
784
|
-
];
|
|
785
|
-
|
|
786
840
|
// File capture point. Apply-then-review is universal (Slice 2b), so the
|
|
787
841
|
// CAS-observing backend: git-tracked edits flow to disk (the turn-boundary
|
|
788
842
|
// git diff is authoritative), and the shared CAS observer records the pre-turn
|
|
@@ -803,7 +857,7 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
803
857
|
middleware: middleware as any,
|
|
804
858
|
subagents: compiledSubagents ?? undefined,
|
|
805
859
|
...(responseFormat ? { responseFormat } : {}),
|
|
806
|
-
...(isPlanMode ? { permissions:
|
|
860
|
+
...(isPlanMode ? { permissions: PLAN_MODE_PERMISSIONS } : {}),
|
|
807
861
|
} as Parameters<typeof createDeepAgent>[0]);
|
|
808
862
|
|
|
809
863
|
// Step 11: Prepare invocation input and config. The conversation catchup
|
|
@@ -874,6 +928,7 @@ export async function performSetup(deps: SetupDependencies): Promise<SetupResult
|
|
|
874
928
|
session,
|
|
875
929
|
workspaceBackend,
|
|
876
930
|
mcpConnection,
|
|
931
|
+
datastoreToolsMissing,
|
|
877
932
|
mergedEnvVars: envResult.mergedEnvVars,
|
|
878
933
|
secretKeys: envResult.secretKeys,
|
|
879
934
|
modelName,
|
|
@@ -15,12 +15,15 @@
|
|
|
15
15
|
* no approval gate — see deepagents-profiles.ts for the suppression half)
|
|
16
16
|
* - Sub-agent backends are shell-capable outside plan mode (issue #248), mirroring
|
|
17
17
|
* the parent's backend selection in setup.ts
|
|
18
|
+
* - Sub-agent graphs carry the parent's filesystem permissions explicitly
|
|
19
|
+
* (issue #255): pre-built CompiledSubAgents never inherit them, so plan
|
|
20
|
+
* mode's deny-all-writes rule is baked into each graph at compile time
|
|
18
21
|
* - Invalid configurations are logged and skipped (graceful degradation)
|
|
19
22
|
* - Empty subagent list returns null (no subagents configured)
|
|
20
23
|
*/
|
|
21
24
|
|
|
22
25
|
import { createDeepAgent, FilesystemBackend, LocalShellBackend, DEFAULT_GENERAL_PURPOSE_DESCRIPTION, DEFAULT_SUBAGENT_PROMPT } from "deepagents";
|
|
23
|
-
import type { CompiledSubAgent } from "deepagents";
|
|
26
|
+
import type { CompiledSubAgent, FilesystemPermission } from "deepagents";
|
|
24
27
|
import type { StructuredTool } from "@langchain/core/tools";
|
|
25
28
|
import type { RunnableConfig } from "@langchain/core/runnables";
|
|
26
29
|
import type { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
@@ -180,6 +183,18 @@ export interface SubagentTransformOptions {
|
|
|
180
183
|
* backends, exactly like the parent's backend selection.
|
|
181
184
|
*/
|
|
182
185
|
readonly shellEnv?: Record<string, string>;
|
|
186
|
+
/**
|
|
187
|
+
* Filesystem permission rules baked into each compiled sub-agent graph,
|
|
188
|
+
* inherited from the parent's rules in setup.ts (plan mode's deny-all-writes
|
|
189
|
+
* today). Required because deepagents' parent-permission inheritance covers
|
|
190
|
+
* only spec-style sub-agents — pre-built CompiledSubAgents bypass it, so
|
|
191
|
+
* without this a plan-mode sub-agent could still write (issue #255).
|
|
192
|
+
*
|
|
193
|
+
* Must not be combined with `shellEnv`: deepagents rejects permissions on an
|
|
194
|
+
* execution-capable backend (see the cas-capture-backend.ts header). Plan
|
|
195
|
+
* mode guarantees that by construction — it is the mode that clears shellEnv.
|
|
196
|
+
*/
|
|
197
|
+
readonly permissions?: FilesystemPermission[];
|
|
183
198
|
}
|
|
184
199
|
|
|
185
200
|
// =========================================================================
|
|
@@ -525,6 +540,8 @@ export async function compileSubagents(
|
|
|
525
540
|
readonly modelFactory?: (modelName: string) => Promise<BaseChatModel>;
|
|
526
541
|
/** Shell env for `execute`; see {@link SubagentTransformOptions.shellEnv}. */
|
|
527
542
|
readonly shellEnv?: Record<string, string>;
|
|
543
|
+
/** Per-graph filesystem rules; see {@link SubagentTransformOptions.permissions}. */
|
|
544
|
+
readonly permissions?: FilesystemPermission[];
|
|
528
545
|
},
|
|
529
546
|
): Promise<CompiledSubAgent[]> {
|
|
530
547
|
if (transformed.length === 0) return [];
|
|
@@ -560,6 +577,9 @@ export async function compileSubagents(
|
|
|
560
577
|
tools: spec.tools.length > 0 ? spec.tools : undefined,
|
|
561
578
|
middleware: middleware as unknown[],
|
|
562
579
|
backend,
|
|
580
|
+
// Enforced inside this graph's own filesystem tools — and inherited by
|
|
581
|
+
// any spec-style sub-agent deepagents auto-injects one level deeper.
|
|
582
|
+
...(opts.permissions ? { permissions: opts.permissions } : {}),
|
|
563
583
|
} as Parameters<typeof createDeepAgent>[0]);
|
|
564
584
|
|
|
565
585
|
const gatedRunnable = gate.wrapRunnable(
|
|
@@ -623,6 +643,7 @@ export async function transformAndCompileSubagents(
|
|
|
623
643
|
costCap,
|
|
624
644
|
modelFactory,
|
|
625
645
|
shellEnv,
|
|
646
|
+
permissions,
|
|
626
647
|
} = options;
|
|
627
648
|
|
|
628
649
|
if (subAgents.length === 0 && !workspaceBackend.rootDir) {
|
|
@@ -743,6 +764,7 @@ export async function transformAndCompileSubagents(
|
|
|
743
764
|
casObserver,
|
|
744
765
|
modelFactory,
|
|
745
766
|
shellEnv,
|
|
767
|
+
permissions,
|
|
746
768
|
});
|
|
747
769
|
|
|
748
770
|
if (compiled.length === 0) {
|
|
@@ -9,11 +9,16 @@
|
|
|
9
9
|
* bypassed) — installed only when the parent itself is gated
|
|
10
10
|
* (`approvalGate` present; absent under auto-approve-all)
|
|
11
11
|
* - Shared cost cap view (parent's budget, no reset on sub-agent start)
|
|
12
|
+
* - Error hints (issue #255): a thrown tool error becomes a recoverable
|
|
13
|
+
* ToolMessage exactly as on the parent. Without it, any tool throw — a
|
|
14
|
+
* plan-mode permission denial, an MCP hiccup — propagated out of the
|
|
15
|
+
* sub-agent graph and killed the whole delegated task, losing all its
|
|
16
|
+
* accumulated work, where the parent's identical error is one failed
|
|
17
|
+
* tool round the model adapts to.
|
|
12
18
|
*
|
|
13
19
|
* The sub-agent middleware stack does NOT include:
|
|
14
20
|
* - Graceful stop (parent handles STOP signal propagation)
|
|
15
21
|
* - OTel spans (parent's OTel context propagates automatically)
|
|
16
|
-
* - Error hints (applied at tool level, not sub-agent level)
|
|
17
22
|
*
|
|
18
23
|
* Approval-gate note: the gate is what *creates* the LangGraph `interrupt()`.
|
|
19
24
|
* A sub-agent's interrupt does surface at the parent checkpoint and resumes
|
|
@@ -31,6 +36,7 @@ import {
|
|
|
31
36
|
createApprovalGateMiddleware,
|
|
32
37
|
type ApprovalGateConfig,
|
|
33
38
|
} from "../../middleware/approval-gate.js";
|
|
39
|
+
import { createErrorHintsMiddleware } from "../../middleware/error-hints.js";
|
|
34
40
|
|
|
35
41
|
const SUB_AGENT_ADVISORY_INTERVAL = 30;
|
|
36
42
|
const SUB_AGENT_MAX_ADVISORIES = 4;
|
|
@@ -60,9 +66,11 @@ export interface SubAgentMiddlewareOptions {
|
|
|
60
66
|
*
|
|
61
67
|
* Returns an ordered array mirroring the parent composition:
|
|
62
68
|
* loop detection → execution budget (periodic) → tool truncation →
|
|
63
|
-
* [approval gate] → cost cap view. The gate sits before the
|
|
64
|
-
* approval pause happens before budget accounting,
|
|
65
|
-
*
|
|
69
|
+
* [approval gate] → cost cap view → error hints. The gate sits before the
|
|
70
|
+
* cost-cap view so an approval pause happens before budget accounting, and
|
|
71
|
+
* error hints come after the gate — both matching the parent order
|
|
72
|
+
* (…→ truncation → graceful-stop → approval gate → cost cap → error hints …),
|
|
73
|
+
* which keeps the gate's HITL interrupt outside the hints' try/catch.
|
|
66
74
|
*/
|
|
67
75
|
export function buildSubAgentMiddleware(
|
|
68
76
|
options: SubAgentMiddlewareOptions = {},
|
|
@@ -99,5 +107,7 @@ export function buildSubAgentMiddleware(
|
|
|
99
107
|
stack.push(options.costCap.forSubAgent());
|
|
100
108
|
}
|
|
101
109
|
|
|
110
|
+
stack.push(createErrorHintsMiddleware());
|
|
111
|
+
|
|
102
112
|
return stack;
|
|
103
113
|
}
|
|
@@ -267,7 +267,9 @@ async function fetchAndFlattenEnv(
|
|
|
267
267
|
): Promise<Record<string, unknown>> {
|
|
268
268
|
// A desktop runner exchanges its bootstrap credential for a token scoped to
|
|
269
269
|
// this workflow execution, so cloud's decrypt gate binds the read (#156).
|
|
270
|
-
// No-op for cloud sandbox and OSS runners.
|
|
270
|
+
// No-op for cloud sandbox and OSS runners. A failed exchange throws and
|
|
271
|
+
// fails the activity: the bootstrap credential no longer decrypts
|
|
272
|
+
// (stigmer-cloud#218), so proceeding would hydrate redacted placeholders.
|
|
271
273
|
const scopedToken = await client.acquireScopedRunnerToken({
|
|
272
274
|
workflowExecutionId: executionId,
|
|
273
275
|
});
|