@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
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { uniquifyFilename, allocateUniqueName } from "../attachment-naming.js";
|
|
6
|
+
import { injectAttachments } from "../../activities/execute-deep-agent/attachment-injector.js";
|
|
7
|
+
import { resolveAttachments } from "../../activities/execute-cursor/attachment-resolver.js";
|
|
8
|
+
import { getPlatformDir } from "../workspace/platform-dir.js";
|
|
9
|
+
import { makeInMemoryArtifactStorage } from "../../__test-utils__/fake-artifact-storage.js";
|
|
10
|
+
import type { WorkspaceBackend } from "../workspace/types.js";
|
|
11
|
+
|
|
12
|
+
describe("uniquifyFilename", () => {
|
|
13
|
+
// This table is the byte-for-byte twin of the React SDK suite
|
|
14
|
+
// (sdk/react/src/attachment/__tests__/attachment-utils.test.ts) — the two
|
|
15
|
+
// implementations are kept in sync by hand, so their pins must agree.
|
|
16
|
+
const cases: Array<{
|
|
17
|
+
scenario: string;
|
|
18
|
+
name: string;
|
|
19
|
+
taken: string[];
|
|
20
|
+
expected: string;
|
|
21
|
+
}> = [
|
|
22
|
+
{
|
|
23
|
+
scenario: "returns the name unchanged when nothing collides",
|
|
24
|
+
name: "report.pdf",
|
|
25
|
+
taken: [],
|
|
26
|
+
expected: "report.pdf",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
scenario: "suffixes -2 before the extension on first collision",
|
|
30
|
+
name: "report.pdf",
|
|
31
|
+
taken: ["report.pdf"],
|
|
32
|
+
expected: "report-2.pdf",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
scenario: "walks past already-taken suffixes",
|
|
36
|
+
name: "report.pdf",
|
|
37
|
+
taken: ["report.pdf", "report-2.pdf", "report-3.pdf"],
|
|
38
|
+
expected: "report-4.pdf",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
scenario: "handles names without an extension",
|
|
42
|
+
name: "Makefile",
|
|
43
|
+
taken: ["Makefile"],
|
|
44
|
+
expected: "Makefile-2",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
scenario: "treats a leading dot as a hidden-file prefix, not an extension",
|
|
48
|
+
name: ".env",
|
|
49
|
+
taken: [".env"],
|
|
50
|
+
expected: ".env-2",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
scenario: "only splits on the last dot of a multi-dot name",
|
|
54
|
+
name: "backup.tar.gz",
|
|
55
|
+
taken: ["backup.tar.gz"],
|
|
56
|
+
expected: "backup.tar-2.gz",
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
for (const { scenario, name, taken, expected } of cases) {
|
|
61
|
+
it(scenario, () => {
|
|
62
|
+
expect(uniquifyFilename(name, new Set(taken))).toBe(expected);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe("allocateUniqueName", () => {
|
|
68
|
+
it("claims the allocated name so sequential allocations see each other", () => {
|
|
69
|
+
const taken = new Set<string>();
|
|
70
|
+
|
|
71
|
+
expect(allocateUniqueName("data.csv", taken)).toEqual({ name: "data.csv" });
|
|
72
|
+
expect(allocateUniqueName("data.csv", taken)).toEqual({
|
|
73
|
+
name: "data-2.csv",
|
|
74
|
+
renamedFrom: "data.csv",
|
|
75
|
+
});
|
|
76
|
+
expect(allocateUniqueName("data.csv", taken)).toEqual({
|
|
77
|
+
name: "data-3.csv",
|
|
78
|
+
renamedFrom: "data.csv",
|
|
79
|
+
});
|
|
80
|
+
expect(taken).toEqual(new Set(["data.csv", "data-2.csv", "data-3.csv"]));
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("carries no renamedFrom when the name was free (nothing to disclose)", () => {
|
|
84
|
+
const allocated = allocateUniqueName("report.pdf", new Set());
|
|
85
|
+
expect(allocated.name).toBe("report.pdf");
|
|
86
|
+
expect("renamedFrom" in allocated && allocated.renamedFrom !== undefined).toBe(false);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("cross-harness naming parity", () => {
|
|
91
|
+
// Both harnesses must resolve the same attachment list to the same final
|
|
92
|
+
// basenames — one platform answer, not two accidental ones (issue #364).
|
|
93
|
+
let workspaceDir: string;
|
|
94
|
+
let sessionId: string;
|
|
95
|
+
let platformDir: string;
|
|
96
|
+
|
|
97
|
+
beforeEach(() => {
|
|
98
|
+
workspaceDir = mkdtempSync(join(tmpdir(), "naming-parity-ws-"));
|
|
99
|
+
sessionId = `parity-session-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
100
|
+
platformDir = getPlatformDir(sessionId);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
afterEach(() => {
|
|
104
|
+
rmSync(platformDir, { recursive: true, force: true });
|
|
105
|
+
rmSync(workspaceDir, { recursive: true, force: true });
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
function makeAttachment(filename: string, storageKey: string) {
|
|
109
|
+
return {
|
|
110
|
+
filename,
|
|
111
|
+
storageKey,
|
|
112
|
+
mountPath: "",
|
|
113
|
+
contentType: "text/plain",
|
|
114
|
+
extract: false,
|
|
115
|
+
localPath: "",
|
|
116
|
+
$typeName: "ai.stigmer.agentic.agentexecution.v1.Attachment" as const,
|
|
117
|
+
$unknown: undefined,
|
|
118
|
+
} as any;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
it("both harnesses produce identical final basenames for the same duplicate-heavy list", async () => {
|
|
122
|
+
const { storage } = makeInMemoryArtifactStorage();
|
|
123
|
+
await storage.upload("attachments/01A/data.csv", Buffer.from("a"), "text/plain");
|
|
124
|
+
await storage.upload("attachments/01B/data.csv", Buffer.from("b"), "text/plain");
|
|
125
|
+
await storage.upload("attachments/01C/Makefile", Buffer.from("c"), "text/plain");
|
|
126
|
+
await storage.upload("attachments/01D/Makefile", Buffer.from("d"), "text/plain");
|
|
127
|
+
const attachments = [
|
|
128
|
+
makeAttachment("data.csv", "attachments/01A/data.csv"),
|
|
129
|
+
makeAttachment("data.csv", "attachments/01B/data.csv"),
|
|
130
|
+
makeAttachment("Makefile", "attachments/01C/Makefile"),
|
|
131
|
+
makeAttachment("Makefile", "attachments/01D/Makefile"),
|
|
132
|
+
];
|
|
133
|
+
|
|
134
|
+
const backend = { writeFileBuffer: vi.fn() } as unknown as WorkspaceBackend;
|
|
135
|
+
const injected = await injectAttachments({
|
|
136
|
+
backend,
|
|
137
|
+
attachments,
|
|
138
|
+
storage,
|
|
139
|
+
isLocalMode: false,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const resolved = await resolveAttachments(attachments, {
|
|
143
|
+
sessionId,
|
|
144
|
+
primaryWorkspaceDir: workspaceDir,
|
|
145
|
+
mode: "cloud",
|
|
146
|
+
storage,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const injectedNames = injected.map((f) => f.filename);
|
|
150
|
+
const resolvedNames = resolved.map((r) => r.filename);
|
|
151
|
+
expect(injectedNames).toEqual(["data.csv", "data-2.csv", "Makefile", "Makefile-2"]);
|
|
152
|
+
expect(resolvedNames).toEqual(injectedNames);
|
|
153
|
+
expect(injected.map((f) => f.renamedFrom)).toEqual(
|
|
154
|
+
resolved.map((r) => r.renamedFrom),
|
|
155
|
+
);
|
|
156
|
+
// The resolver's files really land under the renamed paths.
|
|
157
|
+
expect(readFileSync(join(platformDir, "inputs", "data-2.csv"), "utf-8")).toBe("b");
|
|
158
|
+
});
|
|
159
|
+
});
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter test for the bedrock backend branch of buildChatModel — the
|
|
3
|
+
* complement of bedrock-seam.test.ts, mirroring vertex-adapter.test.ts.
|
|
4
|
+
*
|
|
5
|
+
* The seam test pins the REAL AnthropicBedrock client's wire behavior under
|
|
6
|
+
* a hand-built ChatAnthropic. This file pins OUR production wiring: a real
|
|
7
|
+
* `buildChatModel` and a real `ChatAnthropic` drive a mocked
|
|
8
|
+
* `@anthropic-ai/bedrock-sdk`, so LangChain's lazy `createClient` invocation
|
|
9
|
+
* path (client constructed on first request, once per cached client) is
|
|
10
|
+
* exercised exactly as production does it. Together the two files cover the
|
|
11
|
+
* whole chain without any test-only injection seam in production code.
|
|
12
|
+
*
|
|
13
|
+
* Pinned here:
|
|
14
|
+
* - the factory forwards LangChain's `maxRetries: 0` to the client (a
|
|
15
|
+
* factory that drops it nests SDK retries inside LangChain's own loop),
|
|
16
|
+
* - the factory forwards the request timeout (clientOptions.timeout ->
|
|
17
|
+
* factory options -> SDK constructor; how STIGMER_LLM_REQUEST_TIMEOUT_MS
|
|
18
|
+
* bounds this backend),
|
|
19
|
+
* - construction and invocation succeed with NO ANTHROPIC_API_KEY (Bedrock
|
|
20
|
+
* auth is AWS's, and ChatAnthropic waives the key when createClient is
|
|
21
|
+
* provided),
|
|
22
|
+
* - the translated `anthropic.…-v1:0` id (with the deployment's inference
|
|
23
|
+
* prefix and map overrides applied) crosses the wire while the returned
|
|
24
|
+
* apiModelId stays canonical (the canonical-id invariant),
|
|
25
|
+
* - the maxTokens landmine: Bedrock ids miss LangChain's per-model default
|
|
26
|
+
* table, so the adapter must inject the CANONICAL id's default,
|
|
27
|
+
* - usage_metadata survives the adapter (what billing reads).
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
31
|
+
import { HumanMessage, AIMessage } from "@langchain/core/messages";
|
|
32
|
+
|
|
33
|
+
const { bedrockCtorArgs, createRequests } = vi.hoisted(() => ({
|
|
34
|
+
bedrockCtorArgs: [] as Array<{ maxRetries?: number; timeout?: number }>,
|
|
35
|
+
createRequests: [] as Array<Record<string, unknown>>,
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
vi.mock("@anthropic-ai/bedrock-sdk", () => ({
|
|
39
|
+
AnthropicBedrock: class {
|
|
40
|
+
readonly maxRetries: number | undefined;
|
|
41
|
+
readonly messages = {
|
|
42
|
+
create: async (request: Record<string, unknown>) => {
|
|
43
|
+
createRequests.push(request);
|
|
44
|
+
return {
|
|
45
|
+
id: "msg_bedrock_adapter_01",
|
|
46
|
+
type: "message",
|
|
47
|
+
role: "assistant",
|
|
48
|
+
model: request.model,
|
|
49
|
+
content: [{ type: "text", text: "Namaste from Bedrock." }],
|
|
50
|
+
stop_reason: "end_turn",
|
|
51
|
+
stop_sequence: null,
|
|
52
|
+
usage: { input_tokens: 7, output_tokens: 5 },
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
constructor(opts: { maxRetries?: number; timeout?: number }) {
|
|
58
|
+
bedrockCtorArgs.push(opts);
|
|
59
|
+
this.maxRetries = opts.maxRetries;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
}));
|
|
63
|
+
|
|
64
|
+
import { ChatAnthropic } from "@langchain/anthropic";
|
|
65
|
+
|
|
66
|
+
import { buildChatModel } from "../model-client.js";
|
|
67
|
+
import { _resetRegistryCache } from "../model-registry.js";
|
|
68
|
+
|
|
69
|
+
describe("buildChatModel bedrock adapter", () => {
|
|
70
|
+
const savedEnv = { ...process.env };
|
|
71
|
+
|
|
72
|
+
beforeEach(() => {
|
|
73
|
+
_resetRegistryCache();
|
|
74
|
+
bedrockCtorArgs.length = 0;
|
|
75
|
+
createRequests.length = 0;
|
|
76
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
77
|
+
delete process.env.STIGMER_BEDROCK_MODEL_MAP;
|
|
78
|
+
delete process.env.STIGMER_BEDROCK_INFERENCE_PREFIX;
|
|
79
|
+
process.env.STIGMER_ANTHROPIC_BACKEND = "bedrock";
|
|
80
|
+
process.env.AWS_REGION = "ap-south-1";
|
|
81
|
+
// Registry offline → resolveToApiModelId passes the id through, keeping
|
|
82
|
+
// this test free of registry fixtures (that path has its own tests).
|
|
83
|
+
vi.spyOn(globalThis, "fetch").mockRejectedValue(new Error("registry offline"));
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
afterEach(() => {
|
|
87
|
+
_resetRegistryCache();
|
|
88
|
+
vi.restoreAllMocks();
|
|
89
|
+
process.env = { ...savedEnv };
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("drives the mocked client through the real createClient path with the invariants intact", async () => {
|
|
93
|
+
const { model, apiModelId } = await buildChatModel({
|
|
94
|
+
modelName: "claude-sonnet-4-5-20250929",
|
|
95
|
+
maxTokens: 1024,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Canonical id returned; the client is not constructed yet (lazy factory).
|
|
99
|
+
expect(apiModelId).toBe("claude-sonnet-4-5-20250929");
|
|
100
|
+
expect(bedrockCtorArgs).toHaveLength(0);
|
|
101
|
+
|
|
102
|
+
const result = await model.invoke([new HumanMessage("Weather in Chennai?")]);
|
|
103
|
+
|
|
104
|
+
// First request constructed exactly one (batch) client, with LangChain's
|
|
105
|
+
// maxRetries: 0 honored — LangChain owns retrying.
|
|
106
|
+
expect(bedrockCtorArgs).toHaveLength(1);
|
|
107
|
+
expect(bedrockCtorArgs[0].maxRetries).toBe(0);
|
|
108
|
+
|
|
109
|
+
// The wire carries the Bedrock-translated id; billing already got the
|
|
110
|
+
// canonical one above.
|
|
111
|
+
expect(createRequests).toHaveLength(1);
|
|
112
|
+
expect(createRequests[0].model).toBe("anthropic.claude-sonnet-4-5-20250929-v1:0");
|
|
113
|
+
expect(createRequests[0].max_tokens).toBe(1024);
|
|
114
|
+
|
|
115
|
+
// Response and usage flow back through LangChain untouched.
|
|
116
|
+
expect(result).toBeInstanceOf(AIMessage);
|
|
117
|
+
expect(result.text).toBe("Namaste from Bedrock.");
|
|
118
|
+
expect((result as AIMessage).usage_metadata).toMatchObject({
|
|
119
|
+
input_tokens: 7,
|
|
120
|
+
output_tokens: 5,
|
|
121
|
+
total_tokens: 12,
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("applies the deployment's inference prefix to the wire id, canonical id untouched", async () => {
|
|
126
|
+
process.env.STIGMER_BEDROCK_INFERENCE_PREFIX = "us";
|
|
127
|
+
|
|
128
|
+
const { model, apiModelId } = await buildChatModel({
|
|
129
|
+
modelName: "claude-sonnet-4-6",
|
|
130
|
+
maxTokens: 256,
|
|
131
|
+
});
|
|
132
|
+
await model.invoke([new HumanMessage("hi")]);
|
|
133
|
+
|
|
134
|
+
expect(apiModelId).toBe("claude-sonnet-4-6");
|
|
135
|
+
expect(createRequests.at(-1)?.model).toBe("us.anthropic.claude-sonnet-4-6-v1:0");
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("honors a model-map override over prefix and rule", async () => {
|
|
139
|
+
process.env.STIGMER_BEDROCK_MODEL_MAP =
|
|
140
|
+
"claude-sonnet-4-6=eu.anthropic.claude-sonnet-4-6-custom-v2:0";
|
|
141
|
+
process.env.STIGMER_BEDROCK_INFERENCE_PREFIX = "us";
|
|
142
|
+
|
|
143
|
+
const { model } = await buildChatModel({
|
|
144
|
+
modelName: "claude-sonnet-4-6",
|
|
145
|
+
maxTokens: 256,
|
|
146
|
+
});
|
|
147
|
+
await model.invoke([new HumanMessage("hi")]);
|
|
148
|
+
|
|
149
|
+
expect(createRequests.at(-1)?.model).toBe("eu.anthropic.claude-sonnet-4-6-custom-v2:0");
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("injects the CANONICAL id's default maxTokens when the caller omits it (the 4096 landmine)", async () => {
|
|
153
|
+
// LangChain's per-model default table prefix-matches the model string.
|
|
154
|
+
// `anthropic.…` ids match nothing and silently fall back to 4096 —
|
|
155
|
+
// setup.ts omits maxTokens, so every deep-agent call would be capped.
|
|
156
|
+
// The adapter must inject what the canonical id would have received on
|
|
157
|
+
// the public API or vertex, whatever that is at the installed LangChain
|
|
158
|
+
// version (16384 for 4.5/4.6-generation ids at 1.4.0).
|
|
159
|
+
const canonicalDefault = new ChatAnthropic({
|
|
160
|
+
model: "claude-sonnet-4-5-20250929",
|
|
161
|
+
apiKey: "probe",
|
|
162
|
+
}).maxTokens;
|
|
163
|
+
const bedrockFallback = new ChatAnthropic({
|
|
164
|
+
model: "anthropic.claude-sonnet-4-5-20250929-v1:0",
|
|
165
|
+
apiKey: "probe",
|
|
166
|
+
}).maxTokens;
|
|
167
|
+
// The landmine this guards against: if these ever agree, the injection
|
|
168
|
+
// is redundant (but still correct) — the pin below is what matters.
|
|
169
|
+
expect(bedrockFallback).not.toBe(canonicalDefault);
|
|
170
|
+
|
|
171
|
+
const { model } = await buildChatModel({ modelName: "claude-sonnet-4-5-20250929" });
|
|
172
|
+
await model.invoke([new HumanMessage("hi")]);
|
|
173
|
+
|
|
174
|
+
expect(createRequests.at(-1)?.max_tokens).toBe(canonicalDefault);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("forwards the request timeout to the SDK client (STIGMER_LLM_REQUEST_TIMEOUT_MS path)", async () => {
|
|
178
|
+
// The timeout rides clientOptions -> factory options -> SDK constructor.
|
|
179
|
+
// A factory that drops it silently unbounds the operator's timeout on
|
|
180
|
+
// this backend (the regression T06 repaired for the public path).
|
|
181
|
+
const { model } = await buildChatModel({
|
|
182
|
+
modelName: "claude-sonnet-4-6",
|
|
183
|
+
maxTokens: 256,
|
|
184
|
+
timeoutMs: 5000,
|
|
185
|
+
});
|
|
186
|
+
await model.invoke([new HumanMessage("hi")]);
|
|
187
|
+
|
|
188
|
+
expect(bedrockCtorArgs).toHaveLength(1);
|
|
189
|
+
expect(bedrockCtorArgs[0].timeout).toBe(5000);
|
|
190
|
+
expect(bedrockCtorArgs[0].maxRetries).toBe(0);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("constructs and invokes with no ANTHROPIC_API_KEY anywhere in the environment", async () => {
|
|
194
|
+
expect(process.env.ANTHROPIC_API_KEY).toBeUndefined();
|
|
195
|
+
|
|
196
|
+
const { model } = await buildChatModel({
|
|
197
|
+
modelName: "claude-sonnet-4-6",
|
|
198
|
+
maxTokens: 256,
|
|
199
|
+
});
|
|
200
|
+
const result = await model.invoke([new HumanMessage("hi")]);
|
|
201
|
+
|
|
202
|
+
expect(result).toBeInstanceOf(AIMessage);
|
|
203
|
+
expect(createRequests.at(-1)?.model).toBe("anthropic.claude-sonnet-4-6-v1:0");
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("fails at dispatch with the catalog message when AWS_REGION is missing", async () => {
|
|
207
|
+
delete process.env.AWS_REGION;
|
|
208
|
+
|
|
209
|
+
await expect(
|
|
210
|
+
buildChatModel({ modelName: "claude-sonnet-4-6", maxTokens: 256 }),
|
|
211
|
+
).rejects.toThrow(/AWS_REGION/);
|
|
212
|
+
});
|
|
213
|
+
});
|