@stigmer/runner 3.12.3 → 3.12.5
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/activities/call-http.js +12 -0
- package/dist/activities/call-http.js.map +1 -1
- package/dist/activities/call-llm.d.ts +18 -0
- package/dist/activities/call-llm.js +56 -2
- package/dist/activities/call-llm.js.map +1 -1
- package/dist/activities/execute-cursor/agent-session-cache.d.ts +72 -0
- package/dist/activities/execute-cursor/agent-session-cache.js +186 -0
- package/dist/activities/execute-cursor/agent-session-cache.js.map +1 -0
- package/dist/activities/execute-cursor/cursor-mcp-config.d.ts +45 -0
- package/dist/activities/execute-cursor/cursor-mcp-config.js +76 -0
- package/dist/activities/execute-cursor/cursor-mcp-config.js.map +1 -0
- package/dist/activities/execute-cursor/index.d.ts +10 -1
- package/dist/activities/execute-cursor/index.js +108 -57
- package/dist/activities/execute-cursor/index.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +13 -2
- package/dist/activities/execute-cursor/prompt-builder.js +11 -0
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/service-tier.d.ts +5 -15
- package/dist/activities/execute-cursor/service-tier.js +5 -21
- package/dist/activities/execute-cursor/service-tier.js.map +1 -1
- package/dist/activities/execute-cursor/session-lifecycle.d.ts +1 -1
- package/dist/activities/execute-cursor/skill-resolver.d.ts +2 -21
- package/dist/activities/execute-cursor/skill-resolver.js +5 -108
- package/dist/activities/execute-cursor/skill-resolver.js.map +1 -1
- package/dist/activities/execute-deep-agent/approval-file-change.d.ts +9 -0
- package/dist/activities/execute-deep-agent/approval-file-change.js +2 -1
- package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -1
- package/dist/activities/execute-deep-agent/cas-capture-backend.d.ts +18 -1
- package/dist/activities/execute-deep-agent/cas-capture-backend.js +20 -3
- package/dist/activities/execute-deep-agent/cas-capture-backend.js.map +1 -1
- package/dist/activities/execute-deep-agent/index.js +57 -5
- package/dist/activities/execute-deep-agent/index.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +9 -0
- package/dist/activities/execute-deep-agent/prompt-builder.js +10 -0
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.js +31 -16
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/shell-env.d.ts +8 -5
- package/dist/activities/execute-deep-agent/shell-env.js +10 -7
- package/dist/activities/execute-deep-agent/shell-env.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.js +17 -11
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +3 -3
- package/dist/config.js +10 -5
- package/dist/config.js.map +1 -1
- package/dist/encryption/config.js +7 -2
- package/dist/encryption/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/main.js +12 -6
- package/dist/main.js.map +1 -1
- package/dist/middleware/path-normalization.d.ts +49 -49
- package/dist/middleware/path-normalization.js +73 -84
- package/dist/middleware/path-normalization.js.map +1 -1
- package/dist/middleware/types.d.ts +3 -3
- package/dist/payload-codecs.js +2 -1
- package/dist/payload-codecs.js.map +1 -1
- package/dist/runner-manager.d.ts +1 -1
- package/dist/runner-manager.js +42 -22
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.js +30 -6
- package/dist/runner.js.map +1 -1
- package/dist/shared/args-preview.d.ts +8 -0
- package/dist/shared/args-preview.js +14 -3
- package/dist/shared/args-preview.js.map +1 -1
- package/dist/shared/artifact-storage.d.ts +11 -1
- package/dist/shared/artifact-storage.js +10 -1
- package/dist/shared/artifact-storage.js.map +1 -1
- package/dist/shared/declared-preferences.d.ts +47 -0
- package/dist/shared/declared-preferences.js +64 -0
- package/dist/shared/declared-preferences.js.map +1 -0
- package/dist/shared/fingerprint-secret.d.ts +3 -2
- package/dist/shared/fingerprint-secret.js +5 -3
- package/dist/shared/fingerprint-secret.js.map +1 -1
- package/dist/shared/llm-backend.js +8 -1
- package/dist/shared/llm-backend.js.map +1 -1
- package/dist/shared/mcp-enabled-tools.d.ts +2 -3
- package/dist/shared/mcp-enabled-tools.js +2 -3
- package/dist/shared/mcp-enabled-tools.js.map +1 -1
- package/dist/shared/mcp-resolver.d.ts +20 -15
- package/dist/shared/mcp-resolver.js +11 -12
- package/dist/shared/mcp-resolver.js.map +1 -1
- package/dist/shared/model-client.d.ts +15 -0
- package/dist/shared/model-client.js +57 -13
- package/dist/shared/model-client.js.map +1 -1
- package/dist/shared/placeholder-resolver.d.ts +9 -2
- package/dist/shared/placeholder-resolver.js +9 -2
- package/dist/shared/placeholder-resolver.js.map +1 -1
- package/dist/shared/plan-mode-permissions.d.ts +26 -46
- package/dist/shared/plan-mode-permissions.js +27 -55
- package/dist/shared/plan-mode-permissions.js.map +1 -1
- package/dist/shared/registry-endpoint.d.ts +5 -0
- package/dist/shared/registry-endpoint.js +7 -1
- package/dist/shared/registry-endpoint.js.map +1 -1
- package/dist/shared/runner-credential-keys.d.ts +26 -1
- package/dist/shared/runner-credential-keys.js +34 -1
- package/dist/shared/runner-credential-keys.js.map +1 -1
- package/dist/shared/runner-credential-store.d.ts +77 -0
- package/dist/shared/runner-credential-store.js +111 -0
- package/dist/shared/runner-credential-store.js.map +1 -0
- package/dist/shared/service-tier.d.ts +55 -0
- package/dist/shared/service-tier.js +67 -0
- package/dist/shared/service-tier.js.map +1 -0
- package/dist/shared/skill-mount.d.ts +89 -0
- package/dist/shared/skill-mount.js +142 -0
- package/dist/shared/skill-mount.js.map +1 -0
- package/dist/shared/skill-writer.d.ts +28 -26
- package/dist/shared/skill-writer.js +79 -102
- package/dist/shared/skill-writer.js.map +1 -1
- package/dist/shared/worker-shutdown.d.ts +67 -0
- package/dist/shared/worker-shutdown.js +79 -0
- package/dist/shared/worker-shutdown.js.map +1 -0
- package/dist/shared/workspace/types.d.ts +3 -2
- package/dist/shared/zip-extract.d.ts +10 -3
- package/dist/shared/zip-extract.js +10 -3
- package/dist/shared/zip-extract.js.map +1 -1
- package/dist/workflow-engine/loader.js +38 -1
- package/dist/workflow-engine/loader.js.map +1 -1
- package/dist/workflow-engine/tasks/call-function.d.ts +14 -0
- package/dist/workflow-engine/tasks/call-function.js +49 -5
- package/dist/workflow-engine/tasks/call-function.js.map +1 -1
- package/dist/workflow-engine/tasks/human-input.js +23 -2
- package/dist/workflow-engine/tasks/human-input.js.map +1 -1
- package/dist/workflow-engine/types.d.ts +6 -0
- package/dist/workflow-engine/types.js.map +1 -1
- package/dist/workflows/engine-core.js +36 -8
- package/dist/workflows/engine-core.js.map +1 -1
- package/package.json +15 -11
- package/src/activities/__tests__/call-http.test.ts +36 -0
- package/src/activities/__tests__/call-llm.test.ts +77 -0
- package/src/activities/call-http.ts +17 -0
- package/src/activities/call-llm.ts +78 -2
- package/src/activities/execute-cursor/__tests__/agent-session-cache.test.ts +220 -0
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +50 -0
- package/src/activities/execute-cursor/__tests__/cursor-mcp-config.test.ts +111 -0
- package/src/activities/execute-cursor/__tests__/service-tier.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/skill-resolver.test.ts +3 -94
- package/src/activities/execute-cursor/agent-session-cache.ts +229 -0
- package/src/activities/execute-cursor/cursor-mcp-config.ts +107 -0
- package/src/activities/execute-cursor/index.ts +129 -55
- package/src/activities/execute-cursor/prompt-builder.ts +29 -2
- package/src/activities/execute-cursor/service-tier.ts +5 -29
- package/src/activities/execute-cursor/session-lifecycle.ts +1 -1
- package/src/activities/execute-cursor/skill-resolver.ts +10 -137
- package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +15 -0
- package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +75 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +1 -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__/index.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +42 -29
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +52 -0
- 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 +11 -8
- package/src/activities/execute-deep-agent/approval-file-change.ts +11 -1
- package/src/activities/execute-deep-agent/cas-capture-backend.ts +20 -3
- package/src/activities/execute-deep-agent/index.ts +57 -5
- package/src/activities/execute-deep-agent/prompt-builder.ts +22 -0
- package/src/activities/execute-deep-agent/setup.ts +36 -19
- package/src/activities/execute-deep-agent/shell-env.ts +10 -7
- package/src/activities/execute-deep-agent/subagent-transformer.ts +19 -12
- package/src/activities/execute-deep-agent/subagent-wiring.ts +3 -3
- package/src/config.ts +10 -5
- package/src/encryption/config.ts +8 -2
- package/src/index.ts +1 -1
- package/src/main.ts +16 -6
- package/src/middleware/__tests__/path-normalization.test.ts +32 -32
- package/src/middleware/path-normalization.ts +78 -90
- package/src/middleware/types.ts +3 -3
- package/src/payload-codecs.ts +2 -1
- package/src/runner-manager.ts +55 -22
- package/src/runner.ts +39 -6
- package/src/shared/__tests__/artifact-storage.test.ts +28 -0
- package/src/shared/__tests__/bedrock-seam.test.ts +5 -5
- package/src/shared/__tests__/declared-preferences.test.ts +109 -0
- package/src/shared/__tests__/foundry-seam.test.ts +5 -5
- package/src/shared/__tests__/model-client.test.ts +99 -0
- package/src/shared/__tests__/plan-mode-permissions.test.ts +15 -44
- package/src/shared/__tests__/runner-credential-store.test.ts +155 -0
- package/src/shared/__tests__/skill-mount.test.ts +238 -0
- package/src/shared/__tests__/skill-writer.test.ts +151 -128
- package/src/shared/__tests__/vertex-adapter.test.ts +30 -3
- package/src/shared/__tests__/vertex-seam.test.ts +5 -5
- package/src/shared/__tests__/worker-shutdown.test.ts +101 -0
- package/src/shared/__tests__/zip-extract.test.ts +46 -11
- package/src/shared/args-preview.ts +17 -3
- package/src/shared/artifact-storage.ts +20 -1
- package/src/shared/declared-preferences.ts +84 -0
- package/src/shared/fingerprint-secret.ts +5 -3
- package/src/shared/llm-backend.ts +7 -1
- package/src/shared/mcp-enabled-tools.ts +2 -3
- package/src/shared/mcp-resolver.ts +20 -20
- package/src/shared/model-client.ts +76 -13
- package/src/shared/placeholder-resolver.ts +9 -2
- package/src/shared/plan-mode-permissions.ts +27 -58
- package/src/shared/registry-endpoint.ts +9 -1
- package/src/shared/runner-credential-keys.ts +36 -1
- package/src/shared/runner-credential-store.ts +115 -0
- package/src/shared/service-tier.ts +78 -0
- package/src/shared/skill-mount.ts +179 -0
- package/src/shared/skill-writer.ts +96 -130
- package/src/shared/worker-shutdown.ts +99 -0
- package/src/shared/workspace/types.ts +3 -2
- package/src/shared/zip-extract.ts +14 -7
- package/src/workflow-engine/__tests__/golden-execution.test.ts +20 -1
- package/src/workflow-engine/__tests__/loader.test.ts +51 -0
- package/src/workflow-engine/__tests__/tasks/call-function.test.ts +105 -0
- package/src/workflow-engine/__tests__/tasks/human-input.test.ts +117 -0
- package/src/workflow-engine/loader.ts +46 -1
- package/src/workflow-engine/tasks/call-function.ts +74 -13
- package/src/workflow-engine/tasks/human-input.ts +33 -5
- package/src/workflow-engine/types.ts +6 -0
- package/src/workflows/engine-core.ts +39 -8
- package/dist/activities/execute-cursor/connect-backfill.d.ts +0 -19
- package/dist/activities/execute-cursor/connect-backfill.js +0 -27
- package/dist/activities/execute-cursor/connect-backfill.js.map +0 -1
- package/dist/activities/execute-cursor/mcp-resolver.d.ts +0 -120
- package/dist/activities/execute-cursor/mcp-resolver.js +0 -194
- package/dist/activities/execute-cursor/mcp-resolver.js.map +0 -1
- package/dist/activities/execute-cursor/placeholder-resolver.d.ts +0 -34
- package/dist/activities/execute-cursor/placeholder-resolver.js +0 -82
- package/dist/activities/execute-cursor/placeholder-resolver.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/mcp-resolver.test.ts +0 -125
- package/src/activities/execute-cursor/connect-backfill.ts +0 -52
- package/src/activities/execute-cursor/mcp-resolver.ts +0 -324
- package/src/activities/execute-cursor/placeholder-resolver.ts +0 -109
|
@@ -2,26 +2,25 @@
|
|
|
2
2
|
* The Plan-mode filesystem permission rules — the enforcement twin of
|
|
3
3
|
* `plan-mode-prompt.ts` (which carries the instruction half of the contract).
|
|
4
4
|
*
|
|
5
|
-
* Plan mode is
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
5
|
+
* Plan mode's policy is: reads anywhere in the workspace, writes nowhere.
|
|
6
|
+
* Only the write half needs a RULE. The read boundary that issue #528 built
|
|
7
|
+
* out of rules (workspace read-allow + read-deny, glob-escaped real root) is
|
|
8
|
+
* now STRUCTURAL: every native-harness backend is virtual-rooted
|
|
9
|
+
* (`virtualMode: true` — see cas-capture-backend.ts, issue #754), so every
|
|
10
|
+
* path a tool can express resolves inside the workspace root and traversal
|
|
11
|
+
* is rejected at resolution. A rule cannot widen that, and no workspace-root
|
|
12
|
+
* glob is needed to narrow it — which also retires the whole
|
|
13
|
+
* special-characters-in-the-root hazard (`escapeGlobLiteral` and its
|
|
14
|
+
* end-to-end matcher suite) that the real-path rules carried.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
* path (
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* both; do not "harden" this into one.
|
|
16
|
+
* Paths in these rules are VIRTUAL: "/" is the workspace root, matched by
|
|
17
|
+
* micromatch against the raw tool-call path (dot:true) after the
|
|
18
|
+
* path-normalization middleware has canonicalized it (relative → "/"-rooted;
|
|
19
|
+
* see middleware/path-normalization.ts). The legitimate platform-dir reads
|
|
20
|
+
* (skills, attachments, the approved plan) keep working exactly as before:
|
|
21
|
+
* they are addressed through the `{workspace}/.stigmer` symlink
|
|
22
|
+
* (shared/workspace/stigmer-link.ts), an in-root path string in either
|
|
23
|
+
* dialect.
|
|
25
24
|
*
|
|
26
25
|
* Applied in execute-deep-agent/setup.ts to the parent graph AND threaded
|
|
27
26
|
* into every compiled sub-agent graph: deepagents' parent-permission
|
|
@@ -30,50 +29,23 @@
|
|
|
30
29
|
* (issue #255). Kept as its own side-effect-free module so tests can pin the
|
|
31
30
|
* production rules without dragging in setup.ts's import graph.
|
|
32
31
|
*
|
|
33
|
-
* Rules travel with a companion: every graph that carries them also installs
|
|
34
|
-
* the path-normalization middleware (middleware/path-normalization.ts,
|
|
35
|
-
* issues #429/#528), because deepagents' rule validation refuses
|
|
36
|
-
* workspace-relative paths outright and its `ls`/`glob`/`grep` schema default
|
|
37
|
-
* of "/" would deny the bare first listing. Both are derived from the same
|
|
38
|
-
* expression at each composition site so they cannot drift apart.
|
|
39
|
-
*
|
|
40
32
|
* Invariant: never combine these rules with a shell-capable (sandbox)
|
|
41
33
|
* backend — deepagents rejects that pairing at graph construction (see the
|
|
42
34
|
* cas-capture-backend.ts header). Plan mode guarantees it by construction:
|
|
43
35
|
* it is the mode that clears `shellEnv`, and `shellEnv` is the single switch
|
|
44
36
|
* for shell capability on both the parent and sub-agent backends.
|
|
45
37
|
*/
|
|
46
|
-
import { resolve } from "node:path";
|
|
47
|
-
/**
|
|
48
|
-
* Backslash-escape every character micromatch/picomatch treats as glob
|
|
49
|
-
* syntax, so the result matches the input literally. micromatch exports no
|
|
50
|
-
* escape API of its own, and this is correctness, not caution: an unescaped
|
|
51
|
-
* `(` in a desktop project path would make the workspace read-allow rule
|
|
52
|
-
* silently never match — bricking every plan-mode read for that workspace.
|
|
53
|
-
* Semantics are pinned end-to-end through deepagents' own matcher by the
|
|
54
|
-
* special-character workspace suite in plan-mode-path-normalization.test.ts.
|
|
55
|
-
*/
|
|
56
|
-
export function escapeGlobLiteral(literal) {
|
|
57
|
-
return literal.replace(/[\\*?()[\]{}!+@]/g, "\\$&");
|
|
58
|
-
}
|
|
59
38
|
/**
|
|
60
|
-
* Build the plan-mode rule set
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
39
|
+
* Build the plan-mode rule set. One rule IS the policy: writes denied
|
|
40
|
+
* everywhere ("/**" is every virtual path; deepagents evaluates
|
|
41
|
+
* first-match-wins with a permissive default, so reads stay allowed —
|
|
42
|
+
* workspace-confined structurally, not by rule).
|
|
64
43
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* paths (collapsed slashes, no trailing separator) before matching — a
|
|
69
|
-
* trailing slash in the pattern would silently match nothing.
|
|
44
|
+
* Deliberately parameterless: the pre-#754 signature took the workspace root
|
|
45
|
+
* to build a real-path read fence; resurrecting a root-derived rule would
|
|
46
|
+
* silently mismatch the virtual dialect the enforcement now sees.
|
|
70
47
|
*/
|
|
71
|
-
export function buildPlanModePermissions(
|
|
72
|
-
|
|
73
|
-
return [
|
|
74
|
-
{ operations: ["read"], paths: [`${escapeGlobLiteral(canonicalRoot)}/**`] },
|
|
75
|
-
{ operations: ["read"], paths: ["/**"], mode: "deny" },
|
|
76
|
-
{ operations: ["write"], paths: ["/**"], mode: "deny" },
|
|
77
|
-
];
|
|
48
|
+
export function buildPlanModePermissions() {
|
|
49
|
+
return [{ operations: ["write"], paths: ["/**"], mode: "deny" }];
|
|
78
50
|
}
|
|
79
51
|
//# sourceMappingURL=plan-mode-permissions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan-mode-permissions.js","sourceRoot":"","sources":["../../src/shared/plan-mode-permissions.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plan-mode-permissions.js","sourceRoot":"","sources":["../../src/shared/plan-mode-permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAIH;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -46,6 +46,11 @@ export declare function resolveRegistryBaseUrl(env?: NodeJS.ProcessEnv): string;
|
|
|
46
46
|
/**
|
|
47
47
|
* Build request headers for registry fetches: bearer auth when a token is
|
|
48
48
|
* present (cloud requires it; the local server ignores it).
|
|
49
|
+
*
|
|
50
|
+
* The default env is the credential-store view, not bare `process.env`:
|
|
51
|
+
* both token names are captured out of the environment at boot (#508), and
|
|
52
|
+
* the store also carries rotated tokens (manager updateToken / static
|
|
53
|
+
* renewal) that never touch env at all.
|
|
49
54
|
*/
|
|
50
55
|
export declare function buildRegistryHeaders(env?: NodeJS.ProcessEnv): Record<string, string>;
|
|
51
56
|
/** Full URL of the model registry endpoint for the resolved control plane. */
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* API would only mask misconfiguration (and breaks offline/local use).
|
|
20
20
|
*/
|
|
21
21
|
import { normalizeEndpoint } from "../config.js";
|
|
22
|
+
import { runnerSecretsEnvView } from "./runner-credential-store.js";
|
|
22
23
|
/** Default local stigmer-server origin — mirrors config.ts's local-mode default. */
|
|
23
24
|
const DEFAULT_LOCAL_BACKEND = "http://localhost:7234";
|
|
24
25
|
/**
|
|
@@ -62,8 +63,13 @@ export function resolveRegistryBaseUrl(env = process.env) {
|
|
|
62
63
|
/**
|
|
63
64
|
* Build request headers for registry fetches: bearer auth when a token is
|
|
64
65
|
* present (cloud requires it; the local server ignores it).
|
|
66
|
+
*
|
|
67
|
+
* The default env is the credential-store view, not bare `process.env`:
|
|
68
|
+
* both token names are captured out of the environment at boot (#508), and
|
|
69
|
+
* the store also carries rotated tokens (manager updateToken / static
|
|
70
|
+
* renewal) that never touch env at all.
|
|
65
71
|
*/
|
|
66
|
-
export function buildRegistryHeaders(env =
|
|
72
|
+
export function buildRegistryHeaders(env = runnerSecretsEnvView()) {
|
|
67
73
|
const token = env.STIGMER_TOKEN ?? env.STIGMER_AUTH_TOKEN;
|
|
68
74
|
return token ? { Authorization: `Bearer ${token}` } : {};
|
|
69
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry-endpoint.js","sourceRoot":"","sources":["../../src/shared/registry-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"registry-endpoint.js","sourceRoot":"","sources":["../../src/shared/registry-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,oFAAoF;AACpF,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAEtD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAqB;IACrD,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EAAE,GAAG;IAChB,aAAa,EAAE,CAAC;IAChB,UAAU,EAAE,CAAC;IACb,gBAAgB,EAAE,MAAM;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACzE,MAAM,QAAQ,GAAG,GAAG,CAAC,qBAAqB,CAAC;IAC3C,IAAI,QAAQ;QAAE,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAEjD,MAAM,aAAa,GAAG,GAAG,CAAC,sBAAsB,CAAC;IACjD,IAAI,aAAa;QAAE,OAAO,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAE3D,OAAO,iBAAiB,CAAC,GAAG,CAAC,wBAAwB,IAAI,qBAAqB,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAyB,oBAAoB,EAAE;IAE/C,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,kBAAkB,CAAC;IAC1D,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3D,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,uBAAuB,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC1E,OAAO,GAAG,sBAAsB,CAAC,GAAG,CAAC,0BAA0B,CAAC;AAClE,CAAC"}
|
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
* their sanctioned delivery channel, and denying them here would break it.
|
|
11
11
|
*
|
|
12
12
|
* Consumers:
|
|
13
|
-
* -
|
|
13
|
+
* - runner-credential-store.ts: captures every name listed in this module
|
|
14
|
+
* out of `process.env` at boot (issue #508 — the Cursor SDK's local agent
|
|
15
|
+
* runtime runs in-process and its shell tool spawns from the runner's own
|
|
16
|
+
* env, so credentials must not LIVE there; see that module for custody
|
|
17
|
+
* rules).
|
|
18
|
+
* - shell-env.ts: SHELL_ENV_DENYLIST for the native harness `execute` tool
|
|
19
|
+
* (defense-in-depth behind the boot scrub).
|
|
14
20
|
* - mcp-manager.test.ts: leak-tripwire canaries for MCP stdio subprocesses
|
|
15
21
|
* (that path passes NO runner env by construction; the test plants these
|
|
16
22
|
* names to prove none leak through).
|
|
@@ -22,3 +28,22 @@
|
|
|
22
28
|
* credential files off disk regardless (owner ruling on #385).
|
|
23
29
|
*/
|
|
24
30
|
export declare const RUNNER_CREDENTIAL_ENV_KEYS: readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* Env var names of the runner's non-credential secrets — material that is
|
|
33
|
+
* not an outbound-call credential (so it does not belong in
|
|
34
|
+
* {@link RUNNER_CREDENTIAL_ENV_KEYS}, whose inclusion rule is pinned above)
|
|
35
|
+
* but is every bit as sensitive in an agent-readable environment
|
|
36
|
+
* (owner ruling on #508: same boot scrub, separate constant so the #385
|
|
37
|
+
* rule keeps its meaning).
|
|
38
|
+
*
|
|
39
|
+
* The `*_KEY_ID` companions are deliberately absent: key identifiers are
|
|
40
|
+
* rotation bookkeeping, not secrets.
|
|
41
|
+
*/
|
|
42
|
+
export declare const RUNNER_ENCRYPTION_ENV_KEYS: readonly string[];
|
|
43
|
+
/**
|
|
44
|
+
* Every env name whose VALUE the credential store takes custody of at boot:
|
|
45
|
+
* the #385 credential set plus the #508 encryption-key set. This is the
|
|
46
|
+
* scrub list — after `captureRunnerSecrets()`, none of these names remain
|
|
47
|
+
* in `process.env`.
|
|
48
|
+
*/
|
|
49
|
+
export declare const RUNNER_SECRET_ENV_KEYS: readonly string[];
|
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
* their sanctioned delivery channel, and denying them here would break it.
|
|
11
11
|
*
|
|
12
12
|
* Consumers:
|
|
13
|
-
* -
|
|
13
|
+
* - runner-credential-store.ts: captures every name listed in this module
|
|
14
|
+
* out of `process.env` at boot (issue #508 — the Cursor SDK's local agent
|
|
15
|
+
* runtime runs in-process and its shell tool spawns from the runner's own
|
|
16
|
+
* env, so credentials must not LIVE there; see that module for custody
|
|
17
|
+
* rules).
|
|
18
|
+
* - shell-env.ts: SHELL_ENV_DENYLIST for the native harness `execute` tool
|
|
19
|
+
* (defense-in-depth behind the boot scrub).
|
|
14
20
|
* - mcp-manager.test.ts: leak-tripwire canaries for MCP stdio subprocesses
|
|
15
21
|
* (that path passes NO runner env by construction; the test plants these
|
|
16
22
|
* names to prove none leak through).
|
|
@@ -44,4 +50,31 @@ export const RUNNER_CREDENTIAL_ENV_KEYS = [
|
|
|
44
50
|
// (llm-backend.ts documents it as a supported auth path).
|
|
45
51
|
"AWS_BEARER_TOKEN_BEDROCK",
|
|
46
52
|
];
|
|
53
|
+
/**
|
|
54
|
+
* Env var names of the runner's non-credential secrets — material that is
|
|
55
|
+
* not an outbound-call credential (so it does not belong in
|
|
56
|
+
* {@link RUNNER_CREDENTIAL_ENV_KEYS}, whose inclusion rule is pinned above)
|
|
57
|
+
* but is every bit as sensitive in an agent-readable environment
|
|
58
|
+
* (owner ruling on #508: same boot scrub, separate constant so the #385
|
|
59
|
+
* rule keeps its meaning).
|
|
60
|
+
*
|
|
61
|
+
* The `*_KEY_ID` companions are deliberately absent: key identifiers are
|
|
62
|
+
* rotation bookkeeping, not secrets.
|
|
63
|
+
*/
|
|
64
|
+
export const RUNNER_ENCRYPTION_ENV_KEYS = [
|
|
65
|
+
// Temporal payload-encryption keys (encryption/config.ts). An agent that
|
|
66
|
+
// reads these could decrypt the runner's Temporal history payloads.
|
|
67
|
+
"STIGMER_PAYLOAD_ENCRYPTION_KEY",
|
|
68
|
+
"STIGMER_PAYLOAD_ENCRYPTION_SECONDARY_KEY",
|
|
69
|
+
];
|
|
70
|
+
/**
|
|
71
|
+
* Every env name whose VALUE the credential store takes custody of at boot:
|
|
72
|
+
* the #385 credential set plus the #508 encryption-key set. This is the
|
|
73
|
+
* scrub list — after `captureRunnerSecrets()`, none of these names remain
|
|
74
|
+
* in `process.env`.
|
|
75
|
+
*/
|
|
76
|
+
export const RUNNER_SECRET_ENV_KEYS = [
|
|
77
|
+
...RUNNER_CREDENTIAL_ENV_KEYS,
|
|
78
|
+
...RUNNER_ENCRYPTION_ENV_KEYS,
|
|
79
|
+
];
|
|
47
80
|
//# sourceMappingURL=runner-credential-keys.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-credential-keys.js","sourceRoot":"","sources":["../../src/shared/runner-credential-keys.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"runner-credential-keys.js","sourceRoot":"","sources":["../../src/shared/runner-credential-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAsB;IAC3D,wEAAwE;IACxE,iDAAiD;IACjD,4BAA4B;IAC5B,+DAA+D;IAC/D,sEAAsE;IACtE,eAAe;IACf,gEAAgE;IAChE,iDAAiD;IACjD,oBAAoB;IACpB,wEAAwE;IACxE,iCAAiC;IACjC,gBAAgB;IAChB,sEAAsE;IACtE,mBAAmB;IACnB,mEAAmE;IACnE,gBAAgB;IAChB,kDAAkD;IAClD,2BAA2B;IAC3B,iEAAiE;IACjE,0DAA0D;IAC1D,0BAA0B;CAC3B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAsB;IAC3D,yEAAyE;IACzE,oEAAoE;IACpE,gCAAgC;IAChC,0CAA0C;CAC3C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsB;IACvD,GAAG,0BAA0B;IAC7B,GAAG,0BAA0B;CAC9B,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custody point for the runner's own secrets — the VALUES companion to
|
|
3
|
+
* runner-credential-keys.ts's names (issue #508).
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: the Cursor SDK's local agent runtime ships inside
|
|
6
|
+
* `@cursor/sdk` and runs IN-PROCESS in the runner. Its shell tool spawns
|
|
7
|
+
* bash with `{...process.env, ...}` and its git layer does the same, so
|
|
8
|
+
* anything living in the runner's `process.env` is readable by every shell
|
|
9
|
+
* command the agent runs — and the SDK exposes no env option for local
|
|
10
|
+
* agents to scrub at the spawn boundary. Denylists on runner-owned spawn
|
|
11
|
+
* sites (shell-env.ts) cannot reach those vendor spawns. The only fix that
|
|
12
|
+
* covers every spawn surface, present and future, is for secrets not to
|
|
13
|
+
* LIVE in `process.env` at all: this module captures them at boot and is
|
|
14
|
+
* the sole holder afterwards.
|
|
15
|
+
*
|
|
16
|
+
* Custody rules:
|
|
17
|
+
*
|
|
18
|
+
* 1. `captureRunnerSecrets()` runs at every boot door (both public runner
|
|
19
|
+
* factories, plus main() for symmetry) — it MOVES every
|
|
20
|
+
* {@link RUNNER_SECRET_ENV_KEYS} value out of `process.env` into a
|
|
21
|
+
* module-private map. Idempotent; first call wins.
|
|
22
|
+
* 2. Reads go through {@link getRunnerSecret}: captured value first, live
|
|
23
|
+
* `process.env` as fallback. The fallback keeps the store honest rather
|
|
24
|
+
* than frozen — production sets these vars only at process start (the
|
|
25
|
+
* capture window), so the fallback is a dead path there, but tests and
|
|
26
|
+
* unusual embedders that plant a value later see it behave exactly like
|
|
27
|
+
* the env read it replaced.
|
|
28
|
+
* 3. Rotation writes go through {@link setRunnerSecret} (the
|
|
29
|
+
* runner-manager/static-renewal token channel that previously wrote
|
|
30
|
+
* `process.env.STIGMER_TOKEN` in lockstep with its tokenRef).
|
|
31
|
+
* 4. {@link runnerSecretsEnvView} adapts the store to the codebase's
|
|
32
|
+
* `env: NodeJS.ProcessEnv` injection seams (llm-backend,
|
|
33
|
+
* registry-endpoint). The view re-merges secrets over `process.env` —
|
|
34
|
+
* it exists for in-process CONFIG READS ONLY and must never be handed
|
|
35
|
+
* to a child process env or any spawn options.
|
|
36
|
+
*
|
|
37
|
+
* Embedder note: `@stigmer/runner` is a public library, and capture runs
|
|
38
|
+
* inside the factories, so embedding the runner scrubs the HOST process's
|
|
39
|
+
* env of runner secrets at boot. That is the point — agent shells run in
|
|
40
|
+
* the embedder's process — and host code that still needs a value reads it
|
|
41
|
+
* through this module.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* Move every {@link RUNNER_SECRET_ENV_KEYS} value out of `process.env` into
|
|
45
|
+
* the store. Idempotent — only the first call captures, so a late caller
|
|
46
|
+
* cannot re-freeze values that rotation has since replaced.
|
|
47
|
+
*/
|
|
48
|
+
export declare function captureRunnerSecrets(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Read a runner secret: captured value first, live `process.env` fallback
|
|
51
|
+
* (see custody rule 2). Returns `undefined` when the secret is absent —
|
|
52
|
+
* callers own their missing-secret reaction, exactly as with the env reads
|
|
53
|
+
* this replaces.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getRunnerSecret(name: string): string | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Write (or with `null`, clear) a runner secret — the rotation channel.
|
|
58
|
+
* Ensures capture has run first so a rotated value can never sit in
|
|
59
|
+
* `process.env` because a writer beat the boot capture.
|
|
60
|
+
*/
|
|
61
|
+
export declare function setRunnerSecret(name: string, value: string | null): void;
|
|
62
|
+
/**
|
|
63
|
+
* `process.env` with the captured secrets merged back over it — an adapter
|
|
64
|
+
* for the `env: NodeJS.ProcessEnv` injection seams so their defaults stay
|
|
65
|
+
* secret-aware after the boot scrub.
|
|
66
|
+
*
|
|
67
|
+
* IN-PROCESS CONFIG READS ONLY: never pass this to a spawn/exec env, a
|
|
68
|
+
* worker thread, or anything else that leaves the process — doing so would
|
|
69
|
+
* reopen exactly the leak the store closes.
|
|
70
|
+
*/
|
|
71
|
+
export declare function runnerSecretsEnvView(): NodeJS.ProcessEnv;
|
|
72
|
+
/**
|
|
73
|
+
* Test-only: forget everything captured and re-arm capture. Unit tests that
|
|
74
|
+
* plant secret env vars and boot pieces of the runner need each test to see
|
|
75
|
+
* its own values.
|
|
76
|
+
*/
|
|
77
|
+
export declare function resetRunnerSecretsForTests(): void;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custody point for the runner's own secrets — the VALUES companion to
|
|
3
|
+
* runner-credential-keys.ts's names (issue #508).
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: the Cursor SDK's local agent runtime ships inside
|
|
6
|
+
* `@cursor/sdk` and runs IN-PROCESS in the runner. Its shell tool spawns
|
|
7
|
+
* bash with `{...process.env, ...}` and its git layer does the same, so
|
|
8
|
+
* anything living in the runner's `process.env` is readable by every shell
|
|
9
|
+
* command the agent runs — and the SDK exposes no env option for local
|
|
10
|
+
* agents to scrub at the spawn boundary. Denylists on runner-owned spawn
|
|
11
|
+
* sites (shell-env.ts) cannot reach those vendor spawns. The only fix that
|
|
12
|
+
* covers every spawn surface, present and future, is for secrets not to
|
|
13
|
+
* LIVE in `process.env` at all: this module captures them at boot and is
|
|
14
|
+
* the sole holder afterwards.
|
|
15
|
+
*
|
|
16
|
+
* Custody rules:
|
|
17
|
+
*
|
|
18
|
+
* 1. `captureRunnerSecrets()` runs at every boot door (both public runner
|
|
19
|
+
* factories, plus main() for symmetry) — it MOVES every
|
|
20
|
+
* {@link RUNNER_SECRET_ENV_KEYS} value out of `process.env` into a
|
|
21
|
+
* module-private map. Idempotent; first call wins.
|
|
22
|
+
* 2. Reads go through {@link getRunnerSecret}: captured value first, live
|
|
23
|
+
* `process.env` as fallback. The fallback keeps the store honest rather
|
|
24
|
+
* than frozen — production sets these vars only at process start (the
|
|
25
|
+
* capture window), so the fallback is a dead path there, but tests and
|
|
26
|
+
* unusual embedders that plant a value later see it behave exactly like
|
|
27
|
+
* the env read it replaced.
|
|
28
|
+
* 3. Rotation writes go through {@link setRunnerSecret} (the
|
|
29
|
+
* runner-manager/static-renewal token channel that previously wrote
|
|
30
|
+
* `process.env.STIGMER_TOKEN` in lockstep with its tokenRef).
|
|
31
|
+
* 4. {@link runnerSecretsEnvView} adapts the store to the codebase's
|
|
32
|
+
* `env: NodeJS.ProcessEnv` injection seams (llm-backend,
|
|
33
|
+
* registry-endpoint). The view re-merges secrets over `process.env` —
|
|
34
|
+
* it exists for in-process CONFIG READS ONLY and must never be handed
|
|
35
|
+
* to a child process env or any spawn options.
|
|
36
|
+
*
|
|
37
|
+
* Embedder note: `@stigmer/runner` is a public library, and capture runs
|
|
38
|
+
* inside the factories, so embedding the runner scrubs the HOST process's
|
|
39
|
+
* env of runner secrets at boot. That is the point — agent shells run in
|
|
40
|
+
* the embedder's process — and host code that still needs a value reads it
|
|
41
|
+
* through this module.
|
|
42
|
+
*/
|
|
43
|
+
import { RUNNER_SECRET_ENV_KEYS } from "./runner-credential-keys.js";
|
|
44
|
+
const captured = new Map();
|
|
45
|
+
let captureRan = false;
|
|
46
|
+
/**
|
|
47
|
+
* Move every {@link RUNNER_SECRET_ENV_KEYS} value out of `process.env` into
|
|
48
|
+
* the store. Idempotent — only the first call captures, so a late caller
|
|
49
|
+
* cannot re-freeze values that rotation has since replaced.
|
|
50
|
+
*/
|
|
51
|
+
export function captureRunnerSecrets() {
|
|
52
|
+
if (captureRan)
|
|
53
|
+
return;
|
|
54
|
+
captureRan = true;
|
|
55
|
+
for (const name of RUNNER_SECRET_ENV_KEYS) {
|
|
56
|
+
const value = process.env[name];
|
|
57
|
+
if (value !== undefined) {
|
|
58
|
+
captured.set(name, value);
|
|
59
|
+
delete process.env[name];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Read a runner secret: captured value first, live `process.env` fallback
|
|
65
|
+
* (see custody rule 2). Returns `undefined` when the secret is absent —
|
|
66
|
+
* callers own their missing-secret reaction, exactly as with the env reads
|
|
67
|
+
* this replaces.
|
|
68
|
+
*/
|
|
69
|
+
export function getRunnerSecret(name) {
|
|
70
|
+
return captured.get(name) ?? process.env[name];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Write (or with `null`, clear) a runner secret — the rotation channel.
|
|
74
|
+
* Ensures capture has run first so a rotated value can never sit in
|
|
75
|
+
* `process.env` because a writer beat the boot capture.
|
|
76
|
+
*/
|
|
77
|
+
export function setRunnerSecret(name, value) {
|
|
78
|
+
captureRunnerSecrets();
|
|
79
|
+
if (value === null) {
|
|
80
|
+
captured.delete(name);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
captured.set(name, value);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* `process.env` with the captured secrets merged back over it — an adapter
|
|
88
|
+
* for the `env: NodeJS.ProcessEnv` injection seams so their defaults stay
|
|
89
|
+
* secret-aware after the boot scrub.
|
|
90
|
+
*
|
|
91
|
+
* IN-PROCESS CONFIG READS ONLY: never pass this to a spawn/exec env, a
|
|
92
|
+
* worker thread, or anything else that leaves the process — doing so would
|
|
93
|
+
* reopen exactly the leak the store closes.
|
|
94
|
+
*/
|
|
95
|
+
export function runnerSecretsEnvView() {
|
|
96
|
+
const view = { ...process.env };
|
|
97
|
+
for (const [name, value] of captured) {
|
|
98
|
+
view[name] = value;
|
|
99
|
+
}
|
|
100
|
+
return view;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Test-only: forget everything captured and re-arm capture. Unit tests that
|
|
104
|
+
* plant secret env vars and boot pieces of the runner need each test to see
|
|
105
|
+
* its own values.
|
|
106
|
+
*/
|
|
107
|
+
export function resetRunnerSecretsForTests() {
|
|
108
|
+
captured.clear();
|
|
109
|
+
captureRan = false;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=runner-credential-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-credential-store.js","sourceRoot":"","sources":["../../src/shared/runner-credential-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;AAC3C,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,IAAI,UAAU;QAAE,OAAO;IACvB,UAAU,GAAG,IAAI,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,sBAAsB,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,KAAoB;IAChE,oBAAoB,EAAE,CAAC;IACvB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,IAAI,GAAsB,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACrB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B;IACxC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACjB,UAAU,GAAG,KAAK,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness-neutral service-tier semantics (stigmer/stigmer#357, extended to
|
|
3
|
+
* the native harness by #361).
|
|
4
|
+
*
|
|
5
|
+
* The platform contract: an execution's price-bearing tier is ALWAYS
|
|
6
|
+
* explicit by the time a provider request leaves the runner. UNSPECIFIED
|
|
7
|
+
* resolves to STANDARD here and ONLY here — every upstream layer preserves
|
|
8
|
+
* the caller's raw enum so "user chose standard" stays distinguishable
|
|
9
|
+
* from "platform default" all the way to the ledger.
|
|
10
|
+
*
|
|
11
|
+
* Each harness owns its translation of the EFFECTIVE tier into provider
|
|
12
|
+
* wire terms:
|
|
13
|
+
* - Cursor: explicit `ModelSelection.params` pinning the price-bearing
|
|
14
|
+
* variant booleans (`execute-cursor/service-tier.ts`).
|
|
15
|
+
* - Native: the provider's own request parameter, mapped in
|
|
16
|
+
* `model-client.ts` (`toOpenAiServiceTier` / `toAnthropicServiceTier`
|
|
17
|
+
* below) so no construction site can invent a third mapping.
|
|
18
|
+
*/
|
|
19
|
+
import { ServiceTier } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
20
|
+
/**
|
|
21
|
+
* The effective tier after platform-default resolution: never UNSPECIFIED.
|
|
22
|
+
*/
|
|
23
|
+
export type EffectiveServiceTier = ServiceTier.STANDARD | ServiceTier.FAST;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the configured tier to its effective value. The single place in
|
|
26
|
+
* the platform where UNSPECIFIED becomes STANDARD.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveEffectiveServiceTier(configured: ServiceTier | undefined): EffectiveServiceTier;
|
|
29
|
+
/** Human-readable tier label for logs and error messages. */
|
|
30
|
+
export declare function serviceTierLabel(tier: ServiceTier): string;
|
|
31
|
+
/**
|
|
32
|
+
* OpenAI's `service_tier` request parameter for the effective tier.
|
|
33
|
+
*
|
|
34
|
+
* STANDARD maps to "default", NOT "auto": "auto" lets the ACCOUNT's
|
|
35
|
+
* project settings pick the processing tier — the exact
|
|
36
|
+
* account-default-decides-the-price hole #357 closed on the Cursor
|
|
37
|
+
* harness. FAST maps to "priority" (pay-as-you-go priority processing);
|
|
38
|
+
* create-time validation makes FAST unreachable until a registry entry
|
|
39
|
+
* prices it, so today's traffic always sends "default". "flex" (cheaper,
|
|
40
|
+
* slower) is a possible future tier, deliberately unmapped.
|
|
41
|
+
*/
|
|
42
|
+
export declare function toOpenAiServiceTier(tier: EffectiveServiceTier): "default" | "priority";
|
|
43
|
+
/**
|
|
44
|
+
* Anthropic's `service_tier` request parameter for the effective tier.
|
|
45
|
+
*
|
|
46
|
+
* STANDARD maps to "standard_only": never consume priority-tier capacity,
|
|
47
|
+
* so the bill is the public standard rate regardless of what the account
|
|
48
|
+
* has purchased. FAST maps to "auto" — Anthropic's priority tier is
|
|
49
|
+
* PURCHASED capacity, and "auto" means "use it when available"; the
|
|
50
|
+
* response's `usage.service_tier` reports what actually served, which is
|
|
51
|
+
* what billing reconciles against. FAST is unreachable until a registry
|
|
52
|
+
* entry prices it (and the platform buys priority capacity — the #361
|
|
53
|
+
* half-2 hold).
|
|
54
|
+
*/
|
|
55
|
+
export declare function toAnthropicServiceTier(tier: EffectiveServiceTier): "auto" | "standard_only";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness-neutral service-tier semantics (stigmer/stigmer#357, extended to
|
|
3
|
+
* the native harness by #361).
|
|
4
|
+
*
|
|
5
|
+
* The platform contract: an execution's price-bearing tier is ALWAYS
|
|
6
|
+
* explicit by the time a provider request leaves the runner. UNSPECIFIED
|
|
7
|
+
* resolves to STANDARD here and ONLY here — every upstream layer preserves
|
|
8
|
+
* the caller's raw enum so "user chose standard" stays distinguishable
|
|
9
|
+
* from "platform default" all the way to the ledger.
|
|
10
|
+
*
|
|
11
|
+
* Each harness owns its translation of the EFFECTIVE tier into provider
|
|
12
|
+
* wire terms:
|
|
13
|
+
* - Cursor: explicit `ModelSelection.params` pinning the price-bearing
|
|
14
|
+
* variant booleans (`execute-cursor/service-tier.ts`).
|
|
15
|
+
* - Native: the provider's own request parameter, mapped in
|
|
16
|
+
* `model-client.ts` (`toOpenAiServiceTier` / `toAnthropicServiceTier`
|
|
17
|
+
* below) so no construction site can invent a third mapping.
|
|
18
|
+
*/
|
|
19
|
+
import { ServiceTier } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the configured tier to its effective value. The single place in
|
|
22
|
+
* the platform where UNSPECIFIED becomes STANDARD.
|
|
23
|
+
*/
|
|
24
|
+
export function resolveEffectiveServiceTier(configured) {
|
|
25
|
+
return configured === ServiceTier.FAST ? ServiceTier.FAST : ServiceTier.STANDARD;
|
|
26
|
+
}
|
|
27
|
+
/** Human-readable tier label for logs and error messages. */
|
|
28
|
+
export function serviceTierLabel(tier) {
|
|
29
|
+
switch (tier) {
|
|
30
|
+
case ServiceTier.FAST:
|
|
31
|
+
return "fast";
|
|
32
|
+
case ServiceTier.STANDARD:
|
|
33
|
+
return "standard";
|
|
34
|
+
default:
|
|
35
|
+
return "unspecified";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* OpenAI's `service_tier` request parameter for the effective tier.
|
|
40
|
+
*
|
|
41
|
+
* STANDARD maps to "default", NOT "auto": "auto" lets the ACCOUNT's
|
|
42
|
+
* project settings pick the processing tier — the exact
|
|
43
|
+
* account-default-decides-the-price hole #357 closed on the Cursor
|
|
44
|
+
* harness. FAST maps to "priority" (pay-as-you-go priority processing);
|
|
45
|
+
* create-time validation makes FAST unreachable until a registry entry
|
|
46
|
+
* prices it, so today's traffic always sends "default". "flex" (cheaper,
|
|
47
|
+
* slower) is a possible future tier, deliberately unmapped.
|
|
48
|
+
*/
|
|
49
|
+
export function toOpenAiServiceTier(tier) {
|
|
50
|
+
return tier === ServiceTier.FAST ? "priority" : "default";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Anthropic's `service_tier` request parameter for the effective tier.
|
|
54
|
+
*
|
|
55
|
+
* STANDARD maps to "standard_only": never consume priority-tier capacity,
|
|
56
|
+
* so the bill is the public standard rate regardless of what the account
|
|
57
|
+
* has purchased. FAST maps to "auto" — Anthropic's priority tier is
|
|
58
|
+
* PURCHASED capacity, and "auto" means "use it when available"; the
|
|
59
|
+
* response's `usage.service_tier` reports what actually served, which is
|
|
60
|
+
* what billing reconciles against. FAST is unreachable until a registry
|
|
61
|
+
* entry prices it (and the platform buys priority capacity — the #361
|
|
62
|
+
* half-2 hold).
|
|
63
|
+
*/
|
|
64
|
+
export function toAnthropicServiceTier(tier) {
|
|
65
|
+
return tier === ServiceTier.FAST ? "auto" : "standard_only";
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=service-tier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-tier.js","sourceRoot":"","sources":["../../src/shared/service-tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,8DAA8D,CAAC;AAO3F;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CACzC,UAAmC;IAEnC,OAAO,UAAU,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC;AACnF,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW,CAAC,IAAI;YACnB,OAAO,MAAM,CAAC;QAChB,KAAK,WAAW,CAAC,QAAQ;YACvB,OAAO,UAAU,CAAC;QACpB;YACE,OAAO,aAAa,CAAC;IACzB,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA0B;IAC5D,OAAO,IAAI,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAA0B;IAC/D,OAAO,IAAI,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC;AAC9D,CAAC"}
|