@stigmer/runner 3.0.9-dev.20260616060535 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/approval-contract/types.d.ts +174 -0
- package/dist/__test-utils__/approval-contract/types.js +24 -0
- package/dist/__test-utils__/approval-contract/types.js.map +1 -0
- package/dist/activities/call-agent-status.d.ts +19 -1
- package/dist/activities/call-agent-status.js +64 -5
- package/dist/activities/call-agent-status.js.map +1 -1
- package/dist/activities/call-llm.js +19 -53
- package/dist/activities/call-llm.js.map +1 -1
- package/dist/activities/classify-tool-approvals.d.ts +24 -0
- package/dist/activities/classify-tool-approvals.js +69 -17
- package/dist/activities/classify-tool-approvals.js.map +1 -1
- package/dist/activities/discover-mcp-server.d.ts +7 -0
- package/dist/activities/discover-mcp-server.js +11 -1
- package/dist/activities/discover-mcp-server.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +140 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +130 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.d.ts +18 -0
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +123 -0
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -0
- package/dist/activities/execute-cursor/approval-policy.d.ts +17 -61
- package/dist/activities/execute-cursor/approval-policy.js +8 -120
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +219 -9
- package/dist/activities/execute-cursor/approval-state.js +233 -17
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/capture-flow.d.ts +127 -0
- package/dist/activities/execute-cursor/capture-flow.js +234 -0
- package/dist/activities/execute-cursor/capture-flow.js.map +1 -0
- package/dist/activities/execute-cursor/cas-observations.d.ts +96 -0
- package/dist/activities/execute-cursor/cas-observations.js +184 -0
- package/dist/activities/execute-cursor/cas-observations.js.map +1 -0
- package/dist/activities/execute-cursor/command-provenance.d.ts +62 -0
- package/dist/activities/execute-cursor/command-provenance.js +128 -0
- package/dist/activities/execute-cursor/command-provenance.js.map +1 -0
- package/dist/activities/execute-cursor/exact-apply.d.ts +110 -0
- package/dist/activities/execute-cursor/exact-apply.js +204 -0
- package/dist/activities/execute-cursor/exact-apply.js.map +1 -0
- package/dist/activities/execute-cursor/hook-script.d.ts +53 -24
- package/dist/activities/execute-cursor/hook-script.js +310 -47
- package/dist/activities/execute-cursor/hook-script.js.map +1 -1
- package/dist/activities/execute-cursor/index.d.ts +8 -1
- package/dist/activities/execute-cursor/index.js +500 -64
- package/dist/activities/execute-cursor/index.js.map +1 -1
- package/dist/activities/execute-cursor/message-translator.d.ts +258 -11
- package/dist/activities/execute-cursor/message-translator.js +836 -90
- package/dist/activities/execute-cursor/message-translator.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +20 -23
- package/dist/activities/execute-cursor/prompt-builder.js +74 -15
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/workspace-setup.d.ts +17 -0
- package/dist/activities/execute-cursor/workspace-setup.js +212 -33
- package/dist/activities/execute-cursor/workspace-setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.d.ts +19 -0
- package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.js +143 -0
- package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +88 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +81 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -0
- package/dist/activities/execute-deep-agent/approval-file-change.d.ts +47 -0
- package/dist/activities/execute-deep-agent/approval-file-change.js +68 -0
- package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -0
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +8 -1
- package/dist/activities/execute-deep-agent/attachment-injector.js +7 -7
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +1 -1
- package/dist/activities/execute-deep-agent/cas-capture-backend.d.ts +42 -0
- package/dist/activities/execute-deep-agent/cas-capture-backend.js +47 -0
- package/dist/activities/execute-deep-agent/cas-capture-backend.js.map +1 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +79 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js +112 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -0
- package/dist/activities/execute-deep-agent/hitl.d.ts +10 -0
- package/dist/activities/execute-deep-agent/hitl.js +5 -1
- package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
- package/dist/activities/execute-deep-agent/index.d.ts +2 -1
- package/dist/activities/execute-deep-agent/index.js +370 -56
- package/dist/activities/execute-deep-agent/index.js.map +1 -1
- package/dist/activities/execute-deep-agent/inline-publisher.d.ts +7 -1
- package/dist/activities/execute-deep-agent/inline-publisher.js +23 -2
- package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +53 -2
- package/dist/activities/execute-deep-agent/setup.js +149 -92
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +36 -0
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +56 -0
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +1 -0
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +34 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.js +26 -25
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
- package/dist/activities/execute-deep-agent/status-builder.d.ts +11 -5
- package/dist/activities/execute-deep-agent/status-builder.js +6 -2
- package/dist/activities/execute-deep-agent/status-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +2 -19
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming.js +3 -15
- package/dist/activities/execute-deep-agent/streaming.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -7
- package/dist/activities/execute-deep-agent/subagent-transformer.js +23 -7
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +30 -3
- package/dist/activities/execute-deep-agent/subagent-wiring.js +29 -3
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.js +6 -2
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
- package/dist/claimcheck/payload-codec.js +9 -5
- package/dist/claimcheck/payload-codec.js.map +1 -1
- package/dist/client/stigmer-client.d.ts +2 -0
- package/dist/client/stigmer-client.js +2 -0
- package/dist/client/stigmer-client.js.map +1 -1
- package/dist/middleware/approval-gate.d.ts +85 -4
- package/dist/middleware/approval-gate.js +165 -38
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/middleware/types.d.ts +2 -5
- package/dist/shared/activity-input.d.ts +43 -0
- package/dist/shared/activity-input.js +17 -0
- package/dist/shared/activity-input.js.map +1 -0
- package/dist/shared/approval-canonicalize.d.ts +19 -0
- package/dist/shared/approval-canonicalize.js +119 -0
- package/dist/shared/approval-canonicalize.js.map +1 -0
- package/dist/shared/approval-fingerprint.d.ts +106 -0
- package/dist/shared/approval-fingerprint.js +113 -0
- package/dist/shared/approval-fingerprint.js.map +1 -0
- package/dist/shared/approval-policy.d.ts +182 -12
- package/dist/shared/approval-policy.js +213 -27
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/args-preview.d.ts +52 -0
- package/dist/shared/args-preview.js +93 -0
- package/dist/shared/args-preview.js.map +1 -0
- package/dist/shared/artifact-storage.d.ts +19 -1
- package/dist/shared/artifact-storage.js +48 -11
- package/dist/shared/artifact-storage.js.map +1 -1
- package/dist/shared/file-change.d.ts +44 -0
- package/dist/shared/file-change.js +57 -0
- package/dist/shared/file-change.js.map +1 -0
- package/dist/shared/file-tools.d.ts +107 -0
- package/dist/shared/file-tools.js +168 -0
- package/dist/shared/file-tools.js.map +1 -0
- package/dist/shared/filereview/capture.d.ts +202 -0
- package/dist/shared/filereview/capture.js +498 -0
- package/dist/shared/filereview/capture.js.map +1 -0
- package/dist/shared/filereview/cas-substrate.d.ts +190 -0
- package/dist/shared/filereview/cas-substrate.js +284 -0
- package/dist/shared/filereview/cas-substrate.js.map +1 -0
- package/dist/shared/filereview/digest.d.ts +40 -0
- package/dist/shared/filereview/digest.js +66 -0
- package/dist/shared/filereview/digest.js.map +1 -0
- package/dist/shared/filereview/events.d.ts +170 -0
- package/dist/shared/filereview/events.js +298 -0
- package/dist/shared/filereview/events.js.map +1 -0
- package/dist/shared/filereview/git-substrate.d.ts +175 -0
- package/dist/shared/filereview/git-substrate.js +439 -0
- package/dist/shared/filereview/git-substrate.js.map +1 -0
- package/dist/shared/filereview/index.d.ts +11 -0
- package/dist/shared/filereview/index.js +12 -0
- package/dist/shared/filereview/index.js.map +1 -0
- package/dist/shared/filereview/secret-paths.d.ts +63 -0
- package/dist/shared/filereview/secret-paths.js +105 -0
- package/dist/shared/filereview/secret-paths.js.map +1 -0
- package/dist/shared/fingerprint-secret.d.ts +26 -0
- package/dist/shared/fingerprint-secret.js +47 -0
- package/dist/shared/fingerprint-secret.js.map +1 -0
- package/dist/shared/model-client.d.ts +51 -0
- package/dist/shared/model-client.js +77 -0
- package/dist/shared/model-client.js.map +1 -0
- package/dist/shared/plan-artifact.js +0 -2
- package/dist/shared/plan-artifact.js.map +1 -1
- package/dist/shared/status-offload.d.ts +83 -9
- package/dist/shared/status-offload.js +399 -79
- package/dist/shared/status-offload.js.map +1 -1
- package/dist/shared/status.js +14 -1
- package/dist/shared/status.js.map +1 -1
- package/dist/shared/tool-kind.d.ts +19 -0
- package/dist/shared/tool-kind.js +13 -0
- package/dist/shared/tool-kind.js.map +1 -1
- package/dist/shared/tool-row.d.ts +88 -0
- package/dist/shared/tool-row.js +127 -0
- package/dist/shared/tool-row.js.map +1 -0
- package/dist/shared/workspace/platform-dir.d.ts +25 -0
- package/dist/shared/workspace/platform-dir.js +38 -2
- package/dist/shared/workspace/platform-dir.js.map +1 -1
- package/dist/workflows/call-agent-orchestrator.js +56 -7
- package/dist/workflows/call-agent-orchestrator.js.map +1 -1
- package/dist/workflows/connect-mcp-server.d.ts +50 -0
- package/dist/workflows/connect-mcp-server.js +136 -15
- package/dist/workflows/connect-mcp-server.js.map +1 -1
- package/dist/workflows/types.d.ts +8 -0
- package/package.json +2 -2
- package/src/__test-utils__/approval-contract/contract.ts +224 -0
- package/src/__test-utils__/approval-contract/types.ts +179 -0
- package/src/__test-utils__/fake-artifact-storage.ts +72 -0
- package/src/__tests__/approval-gateway-contract.test.ts +29 -0
- package/src/__tests__/claimcheck-codec.test.ts +16 -53
- package/src/__tests__/golden-e2e.test.ts +2 -0
- package/src/__tests__/runner-token-coordinator.test.ts +3 -3
- package/src/activities/__tests__/call-agent-status.test.ts +135 -0
- package/src/activities/__tests__/call-llm.test.ts +1 -1
- package/src/activities/__tests__/classify-tool-approvals.test.ts +208 -1
- package/src/activities/__tests__/discover-mcp-server.test.ts +30 -0
- package/src/activities/__tests__/workflow-event-activities.test.ts +2 -1
- package/src/activities/call-agent-status.ts +74 -4
- package/src/activities/call-llm.ts +18 -63
- package/src/activities/classify-tool-approvals.ts +101 -19
- package/src/activities/discover-mcp-server.ts +29 -1
- package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +216 -0
- package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +148 -0
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +41 -9
- package/src/activities/execute-cursor/__tests__/approval-state.test.ts +292 -0
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +68 -1
- package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +1005 -0
- package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +187 -0
- package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +97 -0
- package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +240 -0
- package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +203 -0
- package/src/activities/execute-cursor/__tests__/exact-apply.test.ts +375 -0
- package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +1294 -24
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +446 -0
- package/src/activities/execute-cursor/__tests__/hook-script.test.ts +384 -110
- package/src/activities/execute-cursor/__tests__/message-translator.test.ts +171 -25
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +189 -0
- package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +44 -23
- package/src/activities/execute-cursor/__tests__/workspace-setup.test.ts +190 -10
- package/src/activities/execute-cursor/approval-policy.ts +28 -159
- package/src/activities/execute-cursor/approval-state.ts +366 -18
- package/src/activities/execute-cursor/capture-flow.ts +323 -0
- package/src/activities/execute-cursor/cas-observations.ts +204 -0
- package/src/activities/execute-cursor/command-provenance.ts +168 -0
- package/src/activities/execute-cursor/exact-apply.ts +253 -0
- package/src/activities/execute-cursor/hook-script.ts +317 -51
- package/src/activities/execute-cursor/index.ts +575 -67
- package/src/activities/execute-cursor/message-translator.ts +963 -89
- package/src/activities/execute-cursor/prompt-builder.ts +80 -14
- package/src/activities/execute-cursor/workspace-setup.ts +257 -42
- package/src/activities/execute-deep-agent/__test-utils__/gateway-substrate.ts +180 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +134 -0
- package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +84 -0
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +11 -24
- package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +64 -0
- package/src/activities/execute-deep-agent/__tests__/cas-capture-observer.test.ts +163 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +8 -5
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +342 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +2 -5
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +31 -13
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +349 -0
- package/src/activities/execute-deep-agent/__tests__/stamp-flowed-rows.test.ts +119 -0
- package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +12 -11
- package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +9 -9
- package/src/activities/execute-deep-agent/__tests__/subagent-approval-propagation.test.ts +160 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +213 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +3 -6
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +84 -1
- package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +4 -1
- package/src/activities/execute-deep-agent/approval-file-change.ts +80 -0
- package/src/activities/execute-deep-agent/attachment-injector.ts +20 -11
- package/src/activities/execute-deep-agent/cas-capture-backend.ts +66 -0
- package/src/activities/execute-deep-agent/cas-capture-observer.ts +125 -0
- package/src/activities/execute-deep-agent/hitl.ts +15 -1
- package/src/activities/execute-deep-agent/index.ts +434 -64
- package/src/activities/execute-deep-agent/inline-publisher.ts +27 -4
- package/src/activities/execute-deep-agent/setup.ts +223 -125
- package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +64 -0
- package/src/activities/execute-deep-agent/status-builder-shared.ts +62 -23
- package/src/activities/execute-deep-agent/status-builder.ts +19 -7
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +2 -16
- package/src/activities/execute-deep-agent/streaming.ts +3 -13
- package/src/activities/execute-deep-agent/subagent-transformer.ts +53 -13
- package/src/activities/execute-deep-agent/subagent-wiring.ts +50 -3
- package/src/activities/execute-deep-agent/v3-status-builder.ts +8 -2
- package/src/claimcheck/payload-codec.ts +8 -8
- package/src/client/stigmer-client.ts +9 -1
- package/src/middleware/__tests__/approval-gate.test.ts +488 -4
- package/src/middleware/approval-gate.ts +247 -38
- package/src/middleware/types.ts +5 -5
- package/src/shared/__tests__/activity-input.test.ts +78 -0
- package/src/shared/__tests__/approval-canonicalize.test.ts +106 -0
- package/src/shared/__tests__/approval-fingerprint.test.ts +115 -0
- package/src/shared/__tests__/approval-policy.test.ts +274 -40
- package/src/shared/__tests__/args-preview.test.ts +78 -0
- package/src/shared/__tests__/artifact-storage-extended.test.ts +62 -10
- package/src/shared/__tests__/artifact-storage.test.ts +123 -11
- package/src/shared/__tests__/file-change.test.ts +85 -0
- package/src/shared/__tests__/file-tools.test.ts +90 -0
- package/src/shared/__tests__/fingerprint-secret.test.ts +51 -0
- package/src/shared/__tests__/lease-scope-corpus.test.ts +56 -0
- package/src/shared/__tests__/model-client.test.ts +162 -0
- package/src/shared/__tests__/plan-artifact.test.ts +11 -26
- package/src/shared/__tests__/policy-source-corpus.test.ts +58 -0
- package/src/shared/__tests__/status-offload.test.ts +573 -16
- package/src/shared/__tests__/status.test.ts +4 -5
- package/src/shared/__tests__/tool-kind.test.ts +24 -1
- package/src/shared/__tests__/tool-row.test.ts +221 -0
- package/src/shared/activity-input.ts +57 -0
- package/src/shared/approval-canonicalize.ts +159 -0
- package/src/shared/approval-fingerprint.ts +148 -0
- package/src/shared/approval-policy.ts +303 -27
- package/src/shared/args-preview.ts +98 -0
- package/src/shared/artifact-storage.ts +62 -11
- package/src/shared/checkpointer/__tests__/http-saver.test.ts +1 -2
- package/src/shared/file-change.ts +64 -0
- package/src/shared/file-tools.ts +169 -0
- package/src/shared/filereview/__tests__/capture.test.ts +856 -0
- package/src/shared/filereview/__tests__/cas-substrate.test.ts +404 -0
- package/src/shared/filereview/__tests__/digest.test.ts +100 -0
- package/src/shared/filereview/__tests__/events.test.ts +245 -0
- package/src/shared/filereview/__tests__/git-substrate.test.ts +362 -0
- package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +286 -0
- package/src/shared/filereview/__tests__/secret-paths.test.ts +121 -0
- package/src/shared/filereview/capture.ts +727 -0
- package/src/shared/filereview/cas-substrate.ts +401 -0
- package/src/shared/filereview/digest.ts +83 -0
- package/src/shared/filereview/events.ts +449 -0
- package/src/shared/filereview/git-substrate.ts +555 -0
- package/src/shared/filereview/index.ts +60 -0
- package/src/shared/filereview/secret-paths.ts +121 -0
- package/src/shared/fingerprint-secret.ts +53 -0
- package/src/shared/model-client.ts +122 -0
- package/src/shared/plan-artifact.ts +0 -2
- package/src/shared/status-offload.ts +433 -77
- package/src/shared/status.ts +13 -0
- package/src/shared/tool-kind.ts +33 -0
- package/src/shared/tool-row.ts +135 -0
- package/src/shared/workspace/platform-dir.ts +41 -2
- package/src/workflow-engine/__tests__/golden-execution.test.ts +35 -18
- package/src/workflow-engine/__tests__/tasks/try.test.ts +1 -1
- package/src/workflows/__tests__/connect-mcp-server.test.ts +304 -29
- package/src/workflows/call-agent-orchestrator.ts +53 -6
- package/src/workflows/connect-mcp-server.ts +179 -24
- package/src/workflows/types.ts +8 -0
|
@@ -18,8 +18,15 @@
|
|
|
18
18
|
|
|
19
19
|
import { proxyActivities, log } from "@temporalio/workflow";
|
|
20
20
|
|
|
21
|
-
import type {
|
|
22
|
-
|
|
21
|
+
import type {
|
|
22
|
+
createDiscoverMcpServerActivities,
|
|
23
|
+
DiscoveredToolResult,
|
|
24
|
+
ToolApprovalDict,
|
|
25
|
+
} from "../activities/discover-mcp-server.js";
|
|
26
|
+
import type {
|
|
27
|
+
createClassifyToolApprovalsActivities,
|
|
28
|
+
ToolApprovalResult,
|
|
29
|
+
} from "../activities/classify-tool-approvals.js";
|
|
23
30
|
|
|
24
31
|
import type {
|
|
25
32
|
ConnectMcpServerWorkflowInput,
|
|
@@ -48,6 +55,135 @@ function classifyWithTimeout(numTools: number) {
|
|
|
48
55
|
});
|
|
49
56
|
}
|
|
50
57
|
|
|
58
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
59
|
+
// Incremental classification planner (pure, deterministic, sandbox-safe)
|
|
60
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Canonical, order-stable signature of a single tool's definition.
|
|
64
|
+
*
|
|
65
|
+
* Mirrors the shape `toolsFingerprint` hashes (name + description + input_schema)
|
|
66
|
+
* so "unchanged" here means the same thing it means for the whole-server
|
|
67
|
+
* fingerprint. Uses only JSON — no `node:crypto` — so it is safe to call from
|
|
68
|
+
* inside the Temporal deterministic V8 isolate.
|
|
69
|
+
*/
|
|
70
|
+
function toolSignature(tool: DiscoveredToolResult): string {
|
|
71
|
+
return JSON.stringify({
|
|
72
|
+
name: tool.name,
|
|
73
|
+
description: tool.description,
|
|
74
|
+
input_schema: tool.inputSchema ?? null,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Partition the freshly discovered tools into those that must be classified and
|
|
80
|
+
* the prior approval decisions that can be carried forward verbatim.
|
|
81
|
+
*
|
|
82
|
+
* Reuse is **content-addressed**: a prior decision is kept only when a tool's
|
|
83
|
+
* name AND full definition are byte-identical to the previous connect. This is
|
|
84
|
+
* deliberately stricter than reusing by name alone — a tool can keep its name
|
|
85
|
+
* while its schema changes from benign to destructive, and such a tool MUST be
|
|
86
|
+
* re-evaluated rather than left with a stale "auto-approve". Tools that are
|
|
87
|
+
* unchanged are never re-classified (stable, deterministic, no LLM cost; no
|
|
88
|
+
* flapping for borderline tools), and a tool present last time but gone now is
|
|
89
|
+
* simply absent from both outputs (dropped).
|
|
90
|
+
*
|
|
91
|
+
* The previous approval list is a presence-set of *gated* tools (a tool in
|
|
92
|
+
* `previousToolApprovals` requires approval; a known tool absent from it was
|
|
93
|
+
* auto-approved). So a reused tool emits a carried-forward entry only when it
|
|
94
|
+
* was gated; reused auto-approved tools emit nothing, which correctly keeps them
|
|
95
|
+
* un-gated. `ClassifyToolApprovals` likewise returns only gated entries, so the
|
|
96
|
+
* union `[...carriedForward, ...classified]` is the complete gated set.
|
|
97
|
+
*
|
|
98
|
+
* Pure and free of Temporal APIs so it can be exhaustively unit-tested and is
|
|
99
|
+
* safe to evaluate inside the workflow sandbox.
|
|
100
|
+
*/
|
|
101
|
+
export function planIncrementalClassification(
|
|
102
|
+
previousTools: DiscoveredToolResult[],
|
|
103
|
+
previousToolApprovals: ToolApprovalDict[],
|
|
104
|
+
currentTools: DiscoveredToolResult[],
|
|
105
|
+
): { toolsToClassify: DiscoveredToolResult[]; carriedForward: ToolApprovalResult[] } {
|
|
106
|
+
const prevSigByName = new Map<string, string>();
|
|
107
|
+
for (const tool of previousTools) {
|
|
108
|
+
prevSigByName.set(tool.name, toolSignature(tool));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const prevGatedByName = new Map<string, ToolApprovalDict>();
|
|
112
|
+
for (const approval of previousToolApprovals) {
|
|
113
|
+
prevGatedByName.set(approval.toolName, approval);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const toolsToClassify: DiscoveredToolResult[] = [];
|
|
117
|
+
const carriedForward: ToolApprovalResult[] = [];
|
|
118
|
+
|
|
119
|
+
for (const tool of currentTools) {
|
|
120
|
+
const prevSig = prevSigByName.get(tool.name);
|
|
121
|
+
const unchanged = prevSig !== undefined && prevSig === toolSignature(tool);
|
|
122
|
+
|
|
123
|
+
if (!unchanged) {
|
|
124
|
+
toolsToClassify.push(tool);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const gated = prevGatedByName.get(tool.name);
|
|
129
|
+
if (gated) {
|
|
130
|
+
carriedForward.push({
|
|
131
|
+
tool_name: gated.toolName,
|
|
132
|
+
requires_approval: true,
|
|
133
|
+
message: gated.message,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// An unchanged tool that was not gated stays auto-approved — emit nothing.
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return { toolsToClassify, carriedForward };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
143
|
+
// destructiveHint fail-closed tightener (pure, deterministic, sandbox-safe)
|
|
144
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Force-gate any tool whose live MCP annotation declares `destructiveHint:true`
|
|
148
|
+
* but that the classifier (or carry-forward) left un-gated.
|
|
149
|
+
*
|
|
150
|
+
* This is the ONLY way annotations influence policy, and it is deliberately
|
|
151
|
+
* one-directional. The MCP spec warns that clients must never make tool-use
|
|
152
|
+
* decisions on annotations from untrusted servers; trusting a server's
|
|
153
|
+
* "I am destructive" claim only ever ADDS an approval prompt (the safe
|
|
154
|
+
* direction), so it cannot be abused. The inverse — trusting `readOnlyHint` to
|
|
155
|
+
* AUTO-APPROVE — is exactly the unsafe direction the spec forbids, so a spoofed
|
|
156
|
+
* `readOnlyHint:true` on a destructive tool must never relax it. Read-only
|
|
157
|
+
* auto-approval authority lives solely with the trusted LLM classifier.
|
|
158
|
+
*
|
|
159
|
+
* Recomputed from live discovery on every connect, so it has zero coupling to
|
|
160
|
+
* `toolSignature`/incremental reuse and needs no persistence. Pure JS so it is
|
|
161
|
+
* safe to evaluate inside the Temporal deterministic isolate.
|
|
162
|
+
*/
|
|
163
|
+
export function applyDestructiveHintTightener(
|
|
164
|
+
gated: ToolApprovalResult[],
|
|
165
|
+
currentTools: DiscoveredToolResult[],
|
|
166
|
+
): { tightened: ToolApprovalResult[]; addedCount: number } {
|
|
167
|
+
const gatedNames = new Set(gated.map((g) => g.tool_name));
|
|
168
|
+
const tightened = [...gated];
|
|
169
|
+
let addedCount = 0;
|
|
170
|
+
|
|
171
|
+
for (const tool of currentTools) {
|
|
172
|
+
if (tool.annotations?.destructiveHint === true && !gatedNames.has(tool.name)) {
|
|
173
|
+
tightened.push({
|
|
174
|
+
tool_name: tool.name,
|
|
175
|
+
requires_approval: true,
|
|
176
|
+
message: `Execute ${tool.name}`,
|
|
177
|
+
from_destructive_hint: true,
|
|
178
|
+
});
|
|
179
|
+
gatedNames.add(tool.name);
|
|
180
|
+
addedCount++;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return { tightened, addedCount };
|
|
185
|
+
}
|
|
186
|
+
|
|
51
187
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
52
188
|
// ConnectMcpServerWorkflow — primary connect flow
|
|
53
189
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -61,32 +197,32 @@ export async function connectMcpServer(
|
|
|
61
197
|
invokerIdentityAccountId: input.invoker_identity_account_id ?? null,
|
|
62
198
|
});
|
|
63
199
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
200
|
+
// Content-addressed incremental classification: reuse prior decisions for
|
|
201
|
+
// tools whose definition is unchanged, and classify only the new or changed
|
|
202
|
+
// ones. Keeps decisions stable/deterministic across reconnects and avoids
|
|
203
|
+
// redundant LLM calls, while still re-evaluating a tool whose schema changed.
|
|
204
|
+
const { toolsToClassify, carriedForward } = planIncrementalClassification(
|
|
205
|
+
discovery.previousTools,
|
|
206
|
+
discovery.previousToolApprovals,
|
|
207
|
+
discovery.tools,
|
|
208
|
+
);
|
|
68
209
|
|
|
69
|
-
let toolApprovals:
|
|
70
|
-
tool_name: string;
|
|
71
|
-
requires_approval: boolean;
|
|
72
|
-
message: string;
|
|
73
|
-
}>;
|
|
210
|
+
let toolApprovals: ToolApprovalResult[];
|
|
74
211
|
|
|
75
|
-
if (
|
|
212
|
+
if (toolsToClassify.length === 0) {
|
|
76
213
|
log.info(
|
|
77
|
-
`Tools unchanged for '${input.mcp_server_id}' ` +
|
|
78
|
-
|
|
79
|
-
`reusing ${discovery.previousToolApprovals.length} previous approval(s)`,
|
|
214
|
+
`Tools unchanged for '${input.mcp_server_id}' — reusing ` +
|
|
215
|
+
`${carriedForward.length} previous approval(s), no classification needed`,
|
|
80
216
|
);
|
|
81
|
-
|
|
82
|
-
toolApprovals = discovery.previousToolApprovals.map((a) => ({
|
|
83
|
-
tool_name: a.toolName,
|
|
84
|
-
requires_approval: a.requiresApproval,
|
|
85
|
-
message: a.message,
|
|
86
|
-
}));
|
|
217
|
+
toolApprovals = carriedForward;
|
|
87
218
|
} else {
|
|
219
|
+
log.info(
|
|
220
|
+
`Classifying ${toolsToClassify.length} new/changed tool(s) for ` +
|
|
221
|
+
`'${input.mcp_server_id}', reusing ${carriedForward.length} prior decision(s)`,
|
|
222
|
+
);
|
|
223
|
+
|
|
88
224
|
const classifyInput = {
|
|
89
|
-
tools:
|
|
225
|
+
tools: toolsToClassify.map((t) => ({
|
|
90
226
|
name: t.name,
|
|
91
227
|
description: t.description,
|
|
92
228
|
input_schema: t.inputSchema ?? null,
|
|
@@ -96,9 +232,28 @@ export async function connectMcpServer(
|
|
|
96
232
|
mcpServerId: input.mcp_server_id,
|
|
97
233
|
};
|
|
98
234
|
|
|
99
|
-
const classify = classifyWithTimeout(
|
|
100
|
-
|
|
235
|
+
const classify = classifyWithTimeout(toolsToClassify.length);
|
|
236
|
+
const classified = await classify.ClassifyToolApprovals(classifyInput);
|
|
237
|
+
toolApprovals = [...carriedForward, ...classified];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Fail-closed tightener over the FULL live tool set: a tool the server's own
|
|
241
|
+
// annotation marks destructiveHint=true is force-gated if it slipped through
|
|
242
|
+
// un-gated. Runs on live discovery (not the reused/classified subset), so it
|
|
243
|
+
// also re-asserts gating for carried-forward tools whose server later flips a
|
|
244
|
+
// tool to destructive. We never trust readOnlyHint to relax — see the
|
|
245
|
+
// tightener's contract for the MCP untrusted-hints rationale.
|
|
246
|
+
const { tightened, addedCount } = applyDestructiveHintTightener(
|
|
247
|
+
toolApprovals,
|
|
248
|
+
discovery.tools,
|
|
249
|
+
);
|
|
250
|
+
if (addedCount > 0) {
|
|
251
|
+
log.info(
|
|
252
|
+
`Force-gated ${addedCount} tool(s) via destructiveHint annotation for ` +
|
|
253
|
+
`'${input.mcp_server_id}'`,
|
|
254
|
+
);
|
|
101
255
|
}
|
|
256
|
+
toolApprovals = tightened;
|
|
102
257
|
|
|
103
258
|
return {
|
|
104
259
|
tools: discovery.tools.map((t) => ({
|
package/src/workflows/types.ts
CHANGED
|
@@ -49,6 +49,14 @@ export interface WireToolApproval {
|
|
|
49
49
|
tool_name: string;
|
|
50
50
|
requires_approval: boolean;
|
|
51
51
|
message: string;
|
|
52
|
+
/**
|
|
53
|
+
* True when the connect-time destructiveHint tightener force-gated this tool
|
|
54
|
+
* (see applyDestructiveHintTightener). Persisted to
|
|
55
|
+
* ToolApprovalPolicy.from_destructive_hint so the runner attributes the gate to
|
|
56
|
+
* the annotation rather than the classifier. Omitted on classifier/pinned
|
|
57
|
+
* entries.
|
|
58
|
+
*/
|
|
59
|
+
from_destructive_hint?: boolean;
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
// ─────────────────────────────────────────────────────────────────────────────
|