@stigmer/runner 3.40.0 → 3.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/execution-record-fixture.d.ts +2 -1
- package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
- package/dist/activities/call-agent.js +1 -1
- package/dist/activities/discover-mcp-server.d.ts +7 -1
- package/dist/activities/discover-mcp-server.js +13 -29
- package/dist/activities/discover-mcp-server.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +4 -2
- package/dist/activities/execute-cursor/__test-utils__/fold.js +3 -4
- package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +1 -0
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/approval-policy.d.ts +1 -29
- package/dist/activities/execute-cursor/approval-policy.js +11 -35
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/boundary-rows.js +4 -4
- package/dist/activities/execute-cursor/boundary-rows.js.map +1 -1
- package/dist/activities/execute-cursor/translator.d.ts +12 -17
- package/dist/activities/execute-cursor/translator.js +13 -30
- package/dist/activities/execute-cursor/translator.js.map +1 -1
- package/dist/activities/execute-cursor/turn-stream.js +4 -2
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +11 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -3
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
- package/dist/activities/execute-deep-agent/inline-publisher.d.ts +33 -2
- package/dist/activities/execute-deep-agent/inline-publisher.js +33 -7
- package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
- package/dist/activities/execute-deep-agent/platform-route.d.ts +48 -13
- package/dist/activities/execute-deep-agent/platform-route.js +87 -19
- package/dist/activities/execute-deep-agent/platform-route.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +70 -35
- package/dist/activities/execute-deep-agent/prompt-builder.js +70 -55
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +20 -3
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +26 -4
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/translator.d.ts +5 -4
- package/dist/activities/execute-deep-agent/translator.js +5 -4
- package/dist/activities/execute-deep-agent/translator.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-settle.js +6 -6
- package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +18 -13
- package/dist/activities/execute-deep-agent/turn-setup.js +42 -36
- package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-stream.d.ts +10 -6
- package/dist/activities/execute-deep-agent/turn-stream.js +6 -16
- package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn.d.ts +4 -1
- package/dist/activities/execute-deep-agent/turn.js +15 -6
- package/dist/activities/execute-deep-agent/turn.js.map +1 -1
- package/dist/activities/workflow-event-activities.js +2 -0
- package/dist/activities/workflow-event-activities.js.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/exit-backstop.d.ts +64 -0
- package/dist/exit-backstop.js +79 -0
- package/dist/exit-backstop.js.map +1 -0
- package/dist/harness/terminal-table.d.ts +12 -5
- package/dist/harness/terminal-table.js +13 -13
- package/dist/harness/terminal-table.js.map +1 -1
- package/dist/harness/transcript/builder.d.ts +21 -0
- package/dist/harness/transcript/builder.js +53 -31
- package/dist/harness/transcript/builder.js.map +1 -1
- package/dist/harness/transcript/events.d.ts +22 -26
- package/dist/harness/transcript/events.js +6 -5
- package/dist/harness/transcript/events.js.map +1 -1
- package/dist/harness/turn-context.d.ts +3 -1
- package/dist/harness/turn-context.js +5 -3
- package/dist/harness/turn-context.js.map +1 -1
- package/dist/main.js +10 -4
- package/dist/main.js.map +1 -1
- package/dist/middleware/cost-advisory.d.ts +6 -3
- package/dist/middleware/cost-advisory.js +6 -3
- package/dist/middleware/cost-advisory.js.map +1 -1
- package/dist/middleware/execution-budget.d.ts +22 -7
- package/dist/middleware/execution-budget.js +57 -35
- package/dist/middleware/execution-budget.js.map +1 -1
- package/dist/middleware/index.d.ts +10 -7
- package/dist/middleware/index.js +10 -7
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/types.d.ts +6 -1
- package/dist/runner-manager.js +3 -2
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.d.ts +25 -0
- package/dist/runner.js +41 -14
- package/dist/runner.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +23 -13
- package/dist/shared/approval-policy.js +47 -14
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/caller-identity.d.ts +4 -5
- package/dist/shared/caller-identity.js +4 -5
- package/dist/shared/caller-identity.js.map +1 -1
- package/dist/shared/channel-attachment.js +3 -2
- package/dist/shared/channel-attachment.js.map +1 -1
- package/dist/shared/connect-backfill.d.ts +2 -1
- package/dist/shared/connect-backfill.js +2 -2
- package/dist/shared/connect-backfill.js.map +1 -1
- package/dist/shared/mcp-resolver.d.ts +10 -1
- package/dist/shared/mcp-resolver.js +11 -2
- package/dist/shared/mcp-resolver.js.map +1 -1
- package/dist/shared/memory-attachment.js +3 -2
- package/dist/shared/memory-attachment.js.map +1 -1
- package/dist/shared/model-error.d.ts +25 -3
- package/dist/shared/model-error.js +78 -10
- package/dist/shared/model-error.js.map +1 -1
- package/dist/shared/platform-server-address.d.ts +71 -0
- package/dist/shared/platform-server-address.js +103 -0
- package/dist/shared/platform-server-address.js.map +1 -0
- package/dist/shared/prompt-sections.d.ts +6 -28
- package/dist/shared/prompt-sections.js +6 -35
- package/dist/shared/prompt-sections.js.map +1 -1
- package/dist/shared/skill-resolver.d.ts +2 -3
- package/dist/shared/skill-resolver.js +2 -3
- package/dist/shared/skill-resolver.js.map +1 -1
- package/dist/shared/synthesized-attachment.d.ts +0 -5
- package/dist/shared/synthesized-attachment.js +0 -12
- package/dist/shared/synthesized-attachment.js.map +1 -1
- package/dist/shared/tool-rounds.d.ts +51 -23
- package/dist/shared/tool-rounds.js +67 -24
- package/dist/shared/tool-rounds.js.map +1 -1
- package/dist/shared/workspace/platform-dir.d.ts +15 -0
- package/dist/shared/workspace/platform-dir.js +18 -1
- package/dist/shared/workspace/platform-dir.js.map +1 -1
- package/dist/shared/workspace/sources/git.js +13 -6
- package/dist/shared/workspace/sources/git.js.map +1 -1
- package/dist/shared/workspace/stigmer-link.d.ts +21 -14
- package/dist/shared/workspace/stigmer-link.js +91 -29
- package/dist/shared/workspace/stigmer-link.js.map +1 -1
- package/dist/tools/url-guard.d.ts +5 -1
- package/dist/tools/url-guard.js +9 -2
- package/dist/tools/url-guard.js.map +1 -1
- package/dist/worker.d.ts +11 -2
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/dist/workflow-engine/tasks/human-input.d.ts +16 -0
- package/dist/workflow-engine/tasks/human-input.js +79 -37
- package/dist/workflow-engine/tasks/human-input.js.map +1 -1
- package/dist/workflow-engine/types.d.ts +14 -4
- package/dist/workflow-engine/types.js.map +1 -1
- package/dist/workflows/call-agent-orchestrator.d.ts +13 -0
- package/dist/workflows/call-agent-orchestrator.js.map +1 -1
- package/dist/workflows/engine-core.d.ts +25 -0
- package/dist/workflows/engine-core.js.map +1 -1
- package/dist/workflows/execute-from-execution.d.ts +3 -0
- package/dist/workflows/execute-from-execution.js.map +1 -1
- package/dist/workflows/human-input-orchestrator.d.ts +9 -12
- package/dist/workflows/human-input-orchestrator.js +12 -44
- package/dist/workflows/human-input-orchestrator.js.map +1 -1
- package/package.json +5 -5
- package/src/__test-utils__/config-fixture.ts +1 -0
- package/src/__test-utils__/execution-record-fixture.ts +2 -1
- package/src/__test-utils__/harness-contract/runtime-contract.ts +5 -3
- package/src/__test-utils__/test-gate.ts +8 -0
- package/src/__tests__/exit-backstop.test.ts +91 -0
- package/src/__tests__/golden-e2e.test.ts +80 -62
- package/src/__tests__/history-encryption-e2e.test.ts +51 -27
- package/src/__tests__/runner.test.ts +60 -2
- package/src/activities/__tests__/classify-tool-approvals.test.ts +1 -0
- package/src/activities/__tests__/discover-mcp-server.hang.test.ts +5 -1
- package/src/activities/__tests__/discover-mcp-server.test.ts +90 -49
- package/src/activities/__tests__/workflow-event-activities.test.ts +28 -7
- package/src/activities/call-agent.ts +1 -1
- package/src/activities/discover-mcp-server.ts +27 -37
- package/src/activities/execute-cursor/__test-utils__/fold.ts +6 -4
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +1 -0
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +4 -29
- package/src/activities/execute-cursor/__tests__/hermetic/bypassed-tool-call.test.ts +120 -0
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +5 -5
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/file-review-capture.status.json +0 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/resolution-error.status.json +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +0 -3
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +0 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +0 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/stall.status.json +0 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +0 -3
- package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +9 -7
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +6 -1
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +8 -11
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +1 -3
- package/src/activities/execute-cursor/__tests__/translator.test.ts +68 -15
- package/src/activities/execute-cursor/approval-policy.ts +11 -36
- package/src/activities/execute-cursor/boundary-rows.ts +3 -3
- package/src/activities/execute-cursor/translator.ts +15 -32
- package/src/activities/execute-cursor/turn-stream.ts +4 -1
- package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +33 -2
- package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +1 -27
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +26 -30
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +1 -26
- package/src/activities/execute-deep-agent/__tests__/goldens/user-message.everything.md +36 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +4 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +1 -1
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +1 -1
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +1 -1
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +8 -73
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +1 -1
- package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +17 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +86 -26
- package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +9 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/thrown-turn-drains-publishes.test.ts +159 -0
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +84 -0
- package/src/activities/execute-deep-agent/__tests__/platform-route.test.ts +47 -10
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +127 -199
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +31 -26
- package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +34 -0
- package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +13 -5
- package/src/activities/execute-deep-agent/inline-publisher.ts +47 -7
- package/src/activities/execute-deep-agent/platform-route.ts +109 -20
- package/src/activities/execute-deep-agent/prompt-builder.ts +104 -92
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +27 -4
- package/src/activities/execute-deep-agent/translator.ts +5 -4
- package/src/activities/execute-deep-agent/turn-settle.ts +6 -6
- package/src/activities/execute-deep-agent/turn-setup.ts +43 -38
- package/src/activities/execute-deep-agent/turn-stream.ts +15 -22
- package/src/activities/execute-deep-agent/turn.ts +16 -7
- package/src/activities/workflow-event-activities.ts +2 -0
- package/src/config.ts +11 -0
- package/src/exit-backstop.ts +97 -0
- package/src/harness/README.md +5 -5
- package/src/harness/terminal-table.ts +13 -13
- package/src/harness/transcript/__tests__/builder.test.ts +93 -21
- package/src/harness/transcript/builder.ts +53 -30
- package/src/harness/transcript/events.ts +22 -27
- package/src/harness/turn-context.ts +5 -3
- package/src/main.ts +9 -5
- package/src/middleware/__tests__/execution-budget.test.ts +181 -103
- package/src/middleware/cost-advisory.ts +6 -3
- package/src/middleware/execution-budget.ts +60 -34
- package/src/middleware/index.ts +10 -7
- package/src/middleware/types.ts +6 -1
- package/src/runner-manager.ts +3 -2
- package/src/runner.ts +57 -15
- package/src/shared/__tests__/approval-policy.test.ts +41 -0
- package/src/shared/__tests__/artifact-storage.test.ts +1 -0
- package/src/shared/__tests__/connect-backfill.test.ts +15 -11
- package/src/shared/__tests__/mcp-resolver.test.ts +72 -10
- package/src/shared/__tests__/model-error.test.ts +71 -3
- package/src/shared/__tests__/platform-server-address.test.ts +122 -0
- package/src/shared/__tests__/prompt-sections.test.ts +2 -54
- package/src/shared/__tests__/tool-rounds.test.ts +64 -14
- package/src/shared/approval-policy.ts +57 -14
- package/src/shared/caller-identity.ts +4 -5
- package/src/shared/channel-attachment.ts +2 -2
- package/src/shared/connect-backfill.ts +5 -1
- package/src/shared/mcp-resolver.ts +11 -1
- package/src/shared/memory-attachment.ts +2 -2
- package/src/shared/model-error.ts +87 -9
- package/src/shared/platform-server-address.ts +123 -0
- package/src/shared/prompt-sections.ts +6 -55
- package/src/shared/skill-resolver.ts +2 -3
- package/src/shared/synthesized-attachment.ts +0 -12
- package/src/shared/tool-rounds.ts +70 -24
- package/src/shared/workspace/__tests__/git-source.test.ts +11 -5
- package/src/shared/workspace/__tests__/stigmer-link.test.ts +107 -10
- package/src/shared/workspace/platform-dir.ts +19 -1
- package/src/shared/workspace/sources/git.ts +14 -8
- package/src/shared/workspace/stigmer-link.ts +99 -29
- package/src/tools/__tests__/url-guard.test.ts +19 -1
- package/src/tools/url-guard.ts +9 -1
- package/src/worker.ts +12 -2
- package/src/workflow-engine/__tests__/golden-execution.test.ts +2 -1
- package/src/workflow-engine/__tests__/loader.test.ts +1 -1
- package/src/workflow-engine/__tests__/tasks/human-input.test.ts +133 -57
- package/src/workflow-engine/tasks/human-input.ts +92 -42
- package/src/workflow-engine/types.ts +16 -4
- package/src/workflows/call-agent-orchestrator.ts +7 -0
- package/src/workflows/engine-core.ts +18 -0
- package/src/workflows/execute-from-execution.ts +2 -1
- package/src/workflows/human-input-orchestrator.ts +15 -56
- package/dist/shared/skill-relevance.d.ts +0 -65
- package/dist/shared/skill-relevance.js +0 -175
- package/dist/shared/skill-relevance.js.map +0 -1
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +0 -146
- package/src/shared/__tests__/skill-relevance.test.ts +0 -292
- package/src/shared/skill-relevance.ts +0 -222
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ExecutionConfig.max_tool_rounds
|
|
2
|
+
* ExecutionConfig.max_tool_rounds: the round budget, its backstop, and the
|
|
3
|
+
* signal that the budget ended a turn.
|
|
3
4
|
*
|
|
4
5
|
* Implements the proto contract (agentexecution/v1/spec.proto):
|
|
5
|
-
* - 0 / unset = unlimited
|
|
6
|
-
*
|
|
6
|
+
* - 0 / unset = unlimited: no round limit and no recursionLimit, preserving
|
|
7
|
+
* the run-until-done + loop-detection posture.
|
|
7
8
|
* - When set, valid range is 10–1000 rounds; out-of-range values are
|
|
8
9
|
* clamped to the nearest bound with a warning log.
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
11
|
-
* node; ×6 is the contract's floor estimate.
|
|
10
|
+
* - A round is one model response that proposes one or more tool calls,
|
|
11
|
+
* followed by their execution; parallel calls are one round.
|
|
12
12
|
*
|
|
13
|
-
* The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* The budget is COUNTED, not estimated. `middleware/execution-budget.ts`
|
|
14
|
+
* counts rounds where the model is called and throws
|
|
15
|
+
* {@link ToolRoundLimitError} before round N+1's model call, so N rounds
|
|
16
|
+
* run on every middleware stack. The count and the "~80% of budget"
|
|
17
|
+
* advisory live in that one middleware, so they can never disagree. Until
|
|
18
|
+
* #1113 the budget was LangGraph's recursion limit at rounds × 6 super-steps,
|
|
19
|
+
* and because every middleware hook is its own graph node, how many rounds
|
|
20
|
+
* fitted moved whenever the stack did.
|
|
21
|
+
*
|
|
22
|
+
* LangGraph's recursion limit stays only as a backstop
|
|
23
|
+
* ({@link backstopRecursionLimit}): generous enough never to bind before the
|
|
24
|
+
* round count on any stack, it halts a graph that loops without calling the
|
|
25
|
+
* model. Either stop is the same outcome ({@link isToolCallBudgetStop}).
|
|
16
26
|
*
|
|
17
27
|
* The knob and its terminal copy live together (the `cost-guard.ts` shape):
|
|
18
28
|
* when the budget is exhausted the adapter ends its turn `tool_call_limit`
|
|
@@ -20,20 +30,27 @@
|
|
|
20
30
|
* below — the platform deliberately stopped the run, work is checkpointed,
|
|
21
31
|
* and the conversation continues on the next message.
|
|
22
32
|
*/
|
|
23
|
-
export declare const SUPER_STEPS_PER_ROUND = 6;
|
|
24
33
|
export declare const MIN_TOOL_ROUNDS = 10;
|
|
25
34
|
export declare const MAX_TOOL_ROUNDS = 1000;
|
|
26
35
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
36
|
+
* Super-steps per round the backstop allows: well above the graph nodes one
|
|
37
|
+
* round costs on any stack the runner builds (about five today), so the
|
|
38
|
+
* round count, never the backstop, is what a bounded run meets.
|
|
39
|
+
*/
|
|
40
|
+
export declare const SUPER_STEPS_BACKSTOP_PER_ROUND = 20;
|
|
41
|
+
/**
|
|
42
|
+
* The advisory-only round budget used when max_tool_rounds is unset: high
|
|
43
|
+
* enough to never fire on a healthy run. Deliberately NOT enforced — unset
|
|
44
|
+
* means unlimited per the proto contract.
|
|
30
45
|
*/
|
|
31
|
-
export declare const
|
|
46
|
+
export declare const UNBOUNDED_ADVISORY_TOOL_ROUNDS = 1000;
|
|
32
47
|
/**
|
|
33
|
-
* The
|
|
34
|
-
* unbounded (max_tool_rounds 0/unset — the
|
|
48
|
+
* The round budget for a turn, clamped to the valid range, or null when the
|
|
49
|
+
* execution is unbounded (max_tool_rounds 0/unset — the default posture).
|
|
35
50
|
*/
|
|
36
|
-
export declare function
|
|
51
|
+
export declare function resolveToolRoundLimit(maxToolRounds: number | undefined): number | null;
|
|
52
|
+
/** The recursionLimit backstop for a bounded turn's invoke config; see {@link SUPER_STEPS_BACKSTOP_PER_ROUND}. */
|
|
53
|
+
export declare function backstopRecursionLimit(toolRoundLimit: number): number;
|
|
37
54
|
/**
|
|
38
55
|
* Stable prefix of the tool-call-limit terminal error. This is a cross-repo
|
|
39
56
|
* contract: consumers that need to distinguish "ran out of tool-call budget"
|
|
@@ -53,10 +70,21 @@ export declare function formatToolCallLimitError(): string;
|
|
|
53
70
|
*/
|
|
54
71
|
export declare const TOOL_CALL_LIMIT_USER_COPY: string;
|
|
55
72
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
* The execution budget's stop: thrown by `middleware/execution-budget.ts` in
|
|
74
|
+
* place of round N+1's model call, so the graph ends on round N's tool
|
|
75
|
+
* results with no proposed call left unexecuted.
|
|
76
|
+
*/
|
|
77
|
+
export declare class ToolRoundLimitError extends Error {
|
|
78
|
+
readonly toolRoundLimit: number;
|
|
79
|
+
constructor(toolRoundLimit: number);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Whether an error thrown out of a LangGraph run is the tool-call budget
|
|
83
|
+
* ending the turn — the budget's own signal, not a failure: the adapter ends
|
|
84
|
+
* the turn `tool_call_limit`. Two producers, one outcome: the round count's
|
|
85
|
+
* {@link ToolRoundLimitError}, which reaches the turn wrapped in LangChain's
|
|
86
|
+
* `MiddlewareError` once per `wrapModelCall` layer (so the cause chain is
|
|
87
|
+
* walked, as `unwrapModelError` does for a model error), and the backstop's
|
|
88
|
+
* `GraphRecursionError`.
|
|
61
89
|
*/
|
|
62
|
-
export declare function
|
|
90
|
+
export declare function isToolCallBudgetStop(err: unknown): boolean;
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ExecutionConfig.max_tool_rounds
|
|
2
|
+
* ExecutionConfig.max_tool_rounds: the round budget, its backstop, and the
|
|
3
|
+
* signal that the budget ended a turn.
|
|
3
4
|
*
|
|
4
5
|
* Implements the proto contract (agentexecution/v1/spec.proto):
|
|
5
|
-
* - 0 / unset = unlimited
|
|
6
|
-
*
|
|
6
|
+
* - 0 / unset = unlimited: no round limit and no recursionLimit, preserving
|
|
7
|
+
* the run-until-done + loop-detection posture.
|
|
7
8
|
* - When set, valid range is 10–1000 rounds; out-of-range values are
|
|
8
9
|
* clamped to the nearest bound with a warning log.
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
11
|
-
* node; ×6 is the contract's floor estimate.
|
|
10
|
+
* - A round is one model response that proposes one or more tool calls,
|
|
11
|
+
* followed by their execution; parallel calls are one round.
|
|
12
12
|
*
|
|
13
|
-
* The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* The budget is COUNTED, not estimated. `middleware/execution-budget.ts`
|
|
14
|
+
* counts rounds where the model is called and throws
|
|
15
|
+
* {@link ToolRoundLimitError} before round N+1's model call, so N rounds
|
|
16
|
+
* run on every middleware stack. The count and the "~80% of budget"
|
|
17
|
+
* advisory live in that one middleware, so they can never disagree. Until
|
|
18
|
+
* #1113 the budget was LangGraph's recursion limit at rounds × 6 super-steps,
|
|
19
|
+
* and because every middleware hook is its own graph node, how many rounds
|
|
20
|
+
* fitted moved whenever the stack did.
|
|
21
|
+
*
|
|
22
|
+
* LangGraph's recursion limit stays only as a backstop
|
|
23
|
+
* ({@link backstopRecursionLimit}): generous enough never to bind before the
|
|
24
|
+
* round count on any stack, it halts a graph that loops without calling the
|
|
25
|
+
* model. Either stop is the same outcome ({@link isToolCallBudgetStop}).
|
|
16
26
|
*
|
|
17
27
|
* The knob and its terminal copy live together (the `cost-guard.ts` shape):
|
|
18
28
|
* when the budget is exhausted the adapter ends its turn `tool_call_limit`
|
|
@@ -20,24 +30,34 @@
|
|
|
20
30
|
* below — the platform deliberately stopped the run, work is checkpointed,
|
|
21
31
|
* and the conversation continues on the next message.
|
|
22
32
|
*/
|
|
23
|
-
|
|
33
|
+
import { unwrapModelError } from "./model-error.js";
|
|
24
34
|
export const MIN_TOOL_ROUNDS = 10;
|
|
25
35
|
export const MAX_TOOL_ROUNDS = 1000;
|
|
26
36
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
37
|
+
* Super-steps per round the backstop allows: well above the graph nodes one
|
|
38
|
+
* round costs on any stack the runner builds (about five today), so the
|
|
39
|
+
* round count, never the backstop, is what a bounded run meets.
|
|
40
|
+
*/
|
|
41
|
+
export const SUPER_STEPS_BACKSTOP_PER_ROUND = 20;
|
|
42
|
+
/**
|
|
43
|
+
* The advisory-only round budget used when max_tool_rounds is unset: high
|
|
44
|
+
* enough to never fire on a healthy run. Deliberately NOT enforced — unset
|
|
45
|
+
* means unlimited per the proto contract.
|
|
30
46
|
*/
|
|
31
|
-
export const
|
|
47
|
+
export const UNBOUNDED_ADVISORY_TOOL_ROUNDS = MAX_TOOL_ROUNDS;
|
|
32
48
|
/**
|
|
33
|
-
* The
|
|
34
|
-
* unbounded (max_tool_rounds 0/unset — the
|
|
49
|
+
* The round budget for a turn, clamped to the valid range, or null when the
|
|
50
|
+
* execution is unbounded (max_tool_rounds 0/unset — the default posture).
|
|
35
51
|
*/
|
|
36
|
-
export function
|
|
52
|
+
export function resolveToolRoundLimit(maxToolRounds) {
|
|
37
53
|
if (!maxToolRounds || maxToolRounds <= 0) {
|
|
38
54
|
return null;
|
|
39
55
|
}
|
|
40
|
-
return clampToolRounds(maxToolRounds)
|
|
56
|
+
return clampToolRounds(maxToolRounds);
|
|
57
|
+
}
|
|
58
|
+
/** The recursionLimit backstop for a bounded turn's invoke config; see {@link SUPER_STEPS_BACKSTOP_PER_ROUND}. */
|
|
59
|
+
export function backstopRecursionLimit(toolRoundLimit) {
|
|
60
|
+
return toolRoundLimit * SUPER_STEPS_BACKSTOP_PER_ROUND;
|
|
41
61
|
}
|
|
42
62
|
function clampToolRounds(requested) {
|
|
43
63
|
if (requested < MIN_TOOL_ROUNDS) {
|
|
@@ -75,13 +95,36 @@ export const TOOL_CALL_LIMIT_USER_COPY = "The agent reached the tool-call limit
|
|
|
75
95
|
"Work completed so far has been saved. " +
|
|
76
96
|
"Send another message to continue where the agent left off.";
|
|
77
97
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
|
|
82
|
-
|
|
98
|
+
* The execution budget's stop: thrown by `middleware/execution-budget.ts` in
|
|
99
|
+
* place of round N+1's model call, so the graph ends on round N's tool
|
|
100
|
+
* results with no proposed call left unexecuted.
|
|
101
|
+
*/
|
|
102
|
+
export class ToolRoundLimitError extends Error {
|
|
103
|
+
toolRoundLimit;
|
|
104
|
+
constructor(toolRoundLimit) {
|
|
105
|
+
super(`Tool-round limit reached: ${toolRoundLimit} rounds`);
|
|
106
|
+
this.toolRoundLimit = toolRoundLimit;
|
|
107
|
+
this.name = "ToolRoundLimitError";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Whether an error thrown out of a LangGraph run is the tool-call budget
|
|
112
|
+
* ending the turn — the budget's own signal, not a failure: the adapter ends
|
|
113
|
+
* the turn `tool_call_limit`. Two producers, one outcome: the round count's
|
|
114
|
+
* {@link ToolRoundLimitError}, which reaches the turn wrapped in LangChain's
|
|
115
|
+
* `MiddlewareError` once per `wrapModelCall` layer (so the cause chain is
|
|
116
|
+
* walked, as `unwrapModelError` does for a model error), and the backstop's
|
|
117
|
+
* `GraphRecursionError`.
|
|
118
|
+
*/
|
|
119
|
+
export function isToolCallBudgetStop(err) {
|
|
120
|
+
return unwrapModelError(err) instanceof ToolRoundLimitError || isRecursionLimitError(err);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* LangGraph exhausting the backstop recursion limit. Matched by class name and
|
|
124
|
+
* message because the error class is not exported on a stable path across
|
|
125
|
+
* `@langchain/langgraph` versions.
|
|
83
126
|
*/
|
|
84
|
-
|
|
127
|
+
function isRecursionLimitError(err) {
|
|
85
128
|
if (err instanceof Error) {
|
|
86
129
|
return err.constructor.name === "GraphRecursionError" ||
|
|
87
130
|
err.message.includes("GraphRecursionError") ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-rounds.js","sourceRoot":"","sources":["../../src/shared/tool-rounds.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tool-rounds.js","sourceRoot":"","sources":["../../src/shared/tool-rounds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,eAAe,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,aAAiC;IACrE,IAAI,CAAC,aAAa,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,aAAa,CAAC,CAAC;AACxC,CAAC;AAED,kHAAkH;AAClH,MAAM,UAAU,sBAAsB,CAAC,cAAsB;IAC3D,OAAO,cAAc,GAAG,8BAA8B,CAAC;AACzD,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB;IACxC,IAAI,SAAS,GAAG,eAAe,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CACV,iCAAiC,SAAS,yBAAyB;YACnE,IAAI,eAAe,IAAI,eAAe,kBAAkB,eAAe,EAAE,CAC1E,CAAC;QACF,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,SAAS,GAAG,eAAe,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CACV,iCAAiC,SAAS,yBAAyB;YACnE,IAAI,eAAe,IAAI,eAAe,kBAAkB,eAAe,EAAE,CAC1E,CAAC;QACF,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,mCAAmC,CAAC;AAEhF,6GAA6G;AAC7G,MAAM,UAAU,wBAAwB;IACtC,OAAO,GAAG,4BAA4B,sDAAsD,CAAC;AAC/F,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACpC,0DAA0D;IAC1D,wCAAwC;IACxC,4DAA4D,CAAC;AAE/D;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACvB;IAArB,YAAqB,cAAsB;QACzC,KAAK,CAAC,6BAA6B,cAAc,SAAS,CAAC,CAAC;QADzC,mBAAc,GAAd,cAAc,CAAQ;QAEzC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAY;IAC/C,OAAO,gBAAgB,CAAC,GAAG,CAAC,YAAY,mBAAmB,IAAI,qBAAqB,CAAC,GAAG,CAAC,CAAC;AAC5F,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,KAAK,qBAAqB;YACnD,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YAC3C,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* a real repo never leaves Stigmer files behind in it (see issue #173); only
|
|
11
11
|
* a minimal, transient `.cursor/hooks.json` referencing the absolute script
|
|
12
12
|
* path is written into the workspace itself.
|
|
13
|
+
* - `displaced/` — a real `.stigmer` entry found in the workspace when the
|
|
14
|
+
* platform link takes the name, kept rather than deleted (stigmer-link.ts).
|
|
13
15
|
*
|
|
14
16
|
* This module replaces the duplicated `getPlatformDir` helpers in
|
|
15
17
|
* execute-cursor/skill-resolver.ts and shared/attachment-resolver.ts.
|
|
@@ -70,6 +72,19 @@ export declare function ensureCheckpointDbPath(sessionId: string): Promise<strin
|
|
|
70
72
|
* safe to call multiple times for the same session.
|
|
71
73
|
*/
|
|
72
74
|
export declare function ensurePlatformDir(sessionId: string): Promise<string>;
|
|
75
|
+
/**
|
|
76
|
+
* Compute where a real `.stigmer` entry found in a workspace is moved when the
|
|
77
|
+
* platform link takes the name — `displaced/<stamp>` beside the session's
|
|
78
|
+
* `platform/` and `hitl/` trees (see stigmer-link.ts). Outside the workspace,
|
|
79
|
+
* so a real repo is never left holding it (issue #173) and a write-back never
|
|
80
|
+
* commits it; outside `platform/`, so the agent never reads it back as
|
|
81
|
+
* platform content.
|
|
82
|
+
*
|
|
83
|
+
* Takes the platform dir rather than a session id, unlike its siblings: the
|
|
84
|
+
* link step knows only the dir it links to, and the session dir is its parent.
|
|
85
|
+
* Pure function — performs no I/O.
|
|
86
|
+
*/
|
|
87
|
+
export declare function getDisplacedDir(platformDir: string, stamp: string): string;
|
|
73
88
|
/**
|
|
74
89
|
* Compute the HITL directory path for a session — the runner-owned home for the
|
|
75
90
|
* approval gate's hook script, approval-state file, and denial ledger.
|
|
@@ -10,11 +10,13 @@
|
|
|
10
10
|
* a real repo never leaves Stigmer files behind in it (see issue #173); only
|
|
11
11
|
* a minimal, transient `.cursor/hooks.json` referencing the absolute script
|
|
12
12
|
* path is written into the workspace itself.
|
|
13
|
+
* - `displaced/` — a real `.stigmer` entry found in the workspace when the
|
|
14
|
+
* platform link takes the name, kept rather than deleted (stigmer-link.ts).
|
|
13
15
|
*
|
|
14
16
|
* This module replaces the duplicated `getPlatformDir` helpers in
|
|
15
17
|
* execute-cursor/skill-resolver.ts and shared/attachment-resolver.ts.
|
|
16
18
|
*/
|
|
17
|
-
import { join } from "node:path";
|
|
19
|
+
import { dirname, join } from "node:path";
|
|
18
20
|
import { mkdir } from "node:fs/promises";
|
|
19
21
|
import { homedir } from "node:os";
|
|
20
22
|
import { createHash } from "node:crypto";
|
|
@@ -100,6 +102,21 @@ export async function ensurePlatformDir(sessionId) {
|
|
|
100
102
|
await mkdir(dir, { recursive: true });
|
|
101
103
|
return dir;
|
|
102
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Compute where a real `.stigmer` entry found in a workspace is moved when the
|
|
107
|
+
* platform link takes the name — `displaced/<stamp>` beside the session's
|
|
108
|
+
* `platform/` and `hitl/` trees (see stigmer-link.ts). Outside the workspace,
|
|
109
|
+
* so a real repo is never left holding it (issue #173) and a write-back never
|
|
110
|
+
* commits it; outside `platform/`, so the agent never reads it back as
|
|
111
|
+
* platform content.
|
|
112
|
+
*
|
|
113
|
+
* Takes the platform dir rather than a session id, unlike its siblings: the
|
|
114
|
+
* link step knows only the dir it links to, and the session dir is its parent.
|
|
115
|
+
* Pure function — performs no I/O.
|
|
116
|
+
*/
|
|
117
|
+
export function getDisplacedDir(platformDir, stamp) {
|
|
118
|
+
return join(dirname(platformDir), "displaced", stamp);
|
|
119
|
+
}
|
|
103
120
|
/**
|
|
104
121
|
* Compute the HITL directory path for a session — the runner-owned home for the
|
|
105
122
|
* approval gate's hook script, approval-state file, and denial ledger.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-dir.js","sourceRoot":"","sources":["../../../src/shared/workspace/platform-dir.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"platform-dir.js","sourceRoot":"","sources":["../../../src/shared/workspace/platform-dir.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,13 +50,22 @@ export async function provisionGit(options) {
|
|
|
50
50
|
rootDir: cloneDir,
|
|
51
51
|
sourceType: "git_repo",
|
|
52
52
|
consumedKeys,
|
|
53
|
-
workspaceDescription:
|
|
54
|
-
(metadata.branch ? ` (branch: ${metadata.branch})` : "") +
|
|
55
|
-
`.\nBase commit: ${metadata.baseCommit}`,
|
|
53
|
+
workspaceDescription: describeClone(url, metadata.branch),
|
|
56
54
|
gitMetadata: metadata,
|
|
57
55
|
entryName: "",
|
|
58
56
|
};
|
|
59
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* The model's description of a cloned workspace, the same on the turn that
|
|
60
|
+
* clones and on every turn that reuses the clone: the native system prompt
|
|
61
|
+
* carries it and must not change from one message to the next. So it names
|
|
62
|
+
* the repository and the branch, never the commit (write-back commits move
|
|
63
|
+
* `HEAD` on every approved turn) and never whether the clone was reused. The
|
|
64
|
+
* branch changes only when a branch really changes, and the text says so.
|
|
65
|
+
*/
|
|
66
|
+
function describeClone(url, branch) {
|
|
67
|
+
return `Your workspace is a git clone of ${url}` + (branch ? ` (branch: ${branch})` : "") + ".";
|
|
68
|
+
}
|
|
60
69
|
async function reuseExistingRepo(cloneDir, url, backend, envVars, configureCredentials, targetSubdir) {
|
|
61
70
|
let metadata = await extractGitMetadata(cloneDir, url, backend, targetSubdir);
|
|
62
71
|
const githubToken = envVars.GITHUB_TOKEN;
|
|
@@ -70,9 +79,7 @@ async function reuseExistingRepo(cloneDir, url, backend, envVars, configureCrede
|
|
|
70
79
|
rootDir: cloneDir,
|
|
71
80
|
sourceType: "git_repo",
|
|
72
81
|
consumedKeys: [],
|
|
73
|
-
workspaceDescription:
|
|
74
|
-
(metadata.branch ? ` (branch: ${metadata.branch})` : "") +
|
|
75
|
-
` (existing repo detected).\nBase commit: ${metadata.baseCommit}`,
|
|
82
|
+
workspaceDescription: describeClone(url, metadata.branch),
|
|
76
83
|
gitMetadata: metadata,
|
|
77
84
|
entryName: "",
|
|
78
85
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../../src/shared/workspace/sources/git.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,uBAAuB,GAIxB,MAAM,aAAa,CAAC;AAYrB,MAAM,WAAW,GAAG,YAAY,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC;IAEnG,MAAM,QAAQ,GAAG,YAAY;QAC3B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC;QACrC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAEpB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,MAAM,CACpC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CACnD,CAAC;IAEF,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,iBAAiB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,YAAY,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IACzC,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,IAAI,QAAQ,GAAG,GAAG,CAAC;IAEnB,IAAI,WAAW,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7C,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACzC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,SAAS,GAAG,WAAW;YAC3B,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC;YACxC,CAAC,CAAC,OAAO,CAAC;QACZ,MAAM,IAAI,uBAAuB,CAC/B,UAAU,EACV,qBAAqB,SAAS,EAAE,EAChC,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,CACnE,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IAE9E,IAAI,oBAAoB,IAAI,WAAW,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACrE,MAAM,UAAU,GAAG,MAAM,2BAA2B,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QAC1F,IAAI,UAAU,EAAE,CAAC;YACf,QAAQ,GAAG,EAAE,GAAG,QAAQ,EAAE,wBAAwB,EAAE,IAAI,EAAE,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,MAAM,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAE5C,OAAO;QACL,OAAO,EAAE,QAAQ;QACjB,UAAU,EAAE,UAAU;QACtB,YAAY;QACZ,oBAAoB,
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../../src/shared/workspace/sources/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
* `.stigmer/…` paths those agents are prompted with (skill locations,
|
|
12
12
|
* `.stigmer/inputs/…` attachments) actually resolve. The native harness's
|
|
13
13
|
* FILE tools are the exception: their virtual-rooted backend refuses a path
|
|
14
|
-
* whose real location leaves the workspace, so they
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* whose real location leaves the workspace, so they reach `.stigmer/` through
|
|
15
|
+
* a route instead (`activities/execute-deep-agent/platform-route.ts`),
|
|
16
|
+
* mounted on every turn and exposing the platform dir on exactly the turns
|
|
17
|
+
* this link exists ({@link stigmerSymlinkPointsAt}).
|
|
18
18
|
*
|
|
19
19
|
* Lifecycle contract (same for both harnesses):
|
|
20
20
|
* - Created per turn, under the workspace turn lock — the link is a
|
|
@@ -29,21 +29,28 @@
|
|
|
29
29
|
* - {@link ensureStigmerSymlink} is idempotent, so multiple populaters may
|
|
30
30
|
* run in any order within a turn.
|
|
31
31
|
*
|
|
32
|
-
* OWNERSHIP
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* `
|
|
38
|
-
*
|
|
39
|
-
*
|
|
32
|
+
* OWNERSHIP: the platform owns the `.stigmer` name inside a workspace, but
|
|
33
|
+
* never deletes what it did not make. A real (non-symlink) `.stigmer` entry
|
|
34
|
+
* found where the link goes — left by an older runner, or written by a shell
|
|
35
|
+
* command or a Cursor edit on a turn with no link, where nothing sits between
|
|
36
|
+
* those tools and the disk (#1123) — is MOVED out of the workspace to the
|
|
37
|
+
* session's `displaced/` dir (platform-dir.ts `getDisplacedDir`) and named in
|
|
38
|
+
* a warning; an empty directory is simply removed. Out of the workspace
|
|
39
|
+
* because a write-back commits everything the tree holds (`git add -A`) and
|
|
40
|
+
* git excludes only the exact `.stigmer` name. One case is refused outright:
|
|
41
|
+
* a `.stigmer` that is, or holds, the platform dir itself — a workspace
|
|
42
|
+
* rooted at the home directory, whose `.stigmer` is the Stigmer home (#1424).
|
|
43
|
+
* Turn-end removal is the conservative half: it only ever removes a SYMLINK.
|
|
40
44
|
*/
|
|
41
45
|
/** The workspace-visible name of the platform namespace. */
|
|
42
46
|
export declare const STIGMER_LOCAL_STATE_DIR = ".stigmer";
|
|
43
47
|
/**
|
|
44
48
|
* Ensure the workspace `.stigmer` symlink points to the platform dir.
|
|
45
|
-
* Idempotent: an existing correct link is kept
|
|
46
|
-
*
|
|
49
|
+
* Idempotent: an existing correct link is kept and a stale link is
|
|
50
|
+
* re-pointed. A real entry in the link's place is moved to the session's
|
|
51
|
+
* `displaced/` dir first (an empty directory is removed); a real `.stigmer`
|
|
52
|
+
* that holds the platform dir is refused with an error naming it, before
|
|
53
|
+
* anything is touched. See the module header, OWNERSHIP.
|
|
47
54
|
*/
|
|
48
55
|
export declare function ensureStigmerSymlink(workspaceDir: string, platformDir: string): Promise<void>;
|
|
49
56
|
/**
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
* `.stigmer/…` paths those agents are prompted with (skill locations,
|
|
12
12
|
* `.stigmer/inputs/…` attachments) actually resolve. The native harness's
|
|
13
13
|
* FILE tools are the exception: their virtual-rooted backend refuses a path
|
|
14
|
-
* whose real location leaves the workspace, so they
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* whose real location leaves the workspace, so they reach `.stigmer/` through
|
|
15
|
+
* a route instead (`activities/execute-deep-agent/platform-route.ts`),
|
|
16
|
+
* mounted on every turn and exposing the platform dir on exactly the turns
|
|
17
|
+
* this link exists ({@link stigmerSymlinkPointsAt}).
|
|
18
18
|
*
|
|
19
19
|
* Lifecycle contract (same for both harnesses):
|
|
20
20
|
* - Created per turn, under the workspace turn lock — the link is a
|
|
@@ -29,45 +29,107 @@
|
|
|
29
29
|
* - {@link ensureStigmerSymlink} is idempotent, so multiple populaters may
|
|
30
30
|
* run in any order within a turn.
|
|
31
31
|
*
|
|
32
|
-
* OWNERSHIP
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* `
|
|
38
|
-
*
|
|
39
|
-
*
|
|
32
|
+
* OWNERSHIP: the platform owns the `.stigmer` name inside a workspace, but
|
|
33
|
+
* never deletes what it did not make. A real (non-symlink) `.stigmer` entry
|
|
34
|
+
* found where the link goes — left by an older runner, or written by a shell
|
|
35
|
+
* command or a Cursor edit on a turn with no link, where nothing sits between
|
|
36
|
+
* those tools and the disk (#1123) — is MOVED out of the workspace to the
|
|
37
|
+
* session's `displaced/` dir (platform-dir.ts `getDisplacedDir`) and named in
|
|
38
|
+
* a warning; an empty directory is simply removed. Out of the workspace
|
|
39
|
+
* because a write-back commits everything the tree holds (`git add -A`) and
|
|
40
|
+
* git excludes only the exact `.stigmer` name. One case is refused outright:
|
|
41
|
+
* a `.stigmer` that is, or holds, the platform dir itself — a workspace
|
|
42
|
+
* rooted at the home directory, whose `.stigmer` is the Stigmer home (#1424).
|
|
43
|
+
* Turn-end removal is the conservative half: it only ever removes a SYMLINK.
|
|
40
44
|
*/
|
|
41
|
-
import {
|
|
42
|
-
import { join } from "node:path";
|
|
45
|
+
import { cp, lstat, mkdir, readdir, readlink, realpath, rename, rm, rmdir, symlink, unlink } from "node:fs/promises";
|
|
46
|
+
import { dirname, isAbsolute, join, relative, sep } from "node:path";
|
|
47
|
+
import { getDisplacedDir } from "./platform-dir.js";
|
|
43
48
|
/** The workspace-visible name of the platform namespace. */
|
|
44
49
|
export const STIGMER_LOCAL_STATE_DIR = ".stigmer";
|
|
45
50
|
/**
|
|
46
51
|
* Ensure the workspace `.stigmer` symlink points to the platform dir.
|
|
47
|
-
* Idempotent: an existing correct link is kept
|
|
48
|
-
*
|
|
52
|
+
* Idempotent: an existing correct link is kept and a stale link is
|
|
53
|
+
* re-pointed. A real entry in the link's place is moved to the session's
|
|
54
|
+
* `displaced/` dir first (an empty directory is removed); a real `.stigmer`
|
|
55
|
+
* that holds the platform dir is refused with an error naming it, before
|
|
56
|
+
* anything is touched. See the module header, OWNERSHIP.
|
|
49
57
|
*/
|
|
50
58
|
export async function ensureStigmerSymlink(workspaceDir, platformDir) {
|
|
51
59
|
const linkPath = join(workspaceDir, STIGMER_LOCAL_STATE_DIR);
|
|
60
|
+
let entry;
|
|
52
61
|
try {
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
entry = await lstat(linkPath);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
if (errnoCode(err) !== "ENOENT")
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
if (entry?.isSymbolicLink()) {
|
|
69
|
+
if ((await readlink(linkPath)) === platformDir)
|
|
55
70
|
return;
|
|
56
71
|
await unlink(linkPath);
|
|
57
72
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
73
|
+
else if (entry !== undefined) {
|
|
74
|
+
await displaceRealEntry(linkPath, platformDir, entry);
|
|
75
|
+
}
|
|
76
|
+
await symlink(platformDir, linkPath, "dir");
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Clear a real `.stigmer` entry out of the link's place without losing it:
|
|
80
|
+
* refuse the Stigmer home, remove an empty directory, move anything else.
|
|
81
|
+
*/
|
|
82
|
+
async function displaceRealEntry(linkPath, platformDir, entry) {
|
|
83
|
+
if (entry.isDirectory()) {
|
|
84
|
+
await refuseDirHoldingPlatform(linkPath, platformDir);
|
|
85
|
+
if ((await readdir(linkPath)).length === 0) {
|
|
86
|
+
await rmdir(linkPath);
|
|
87
|
+
return;
|
|
65
88
|
}
|
|
66
|
-
|
|
89
|
+
}
|
|
90
|
+
const destination = getDisplacedDir(platformDir, displacementStamp(new Date()));
|
|
91
|
+
await mkdir(dirname(destination), { recursive: true });
|
|
92
|
+
await moveEntry(linkPath, destination);
|
|
93
|
+
console.warn(`ensureStigmerSymlink: moved the real ${linkPath} out of the workspace to ${destination}; ` +
|
|
94
|
+
"the platform owns the .stigmer name, so the link to the session's platform dir takes its place");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Throw when the real `.stigmer` directory is, or contains, the platform dir:
|
|
98
|
+
* a workspace rooted at the home directory resolves `.stigmer` to the Stigmer
|
|
99
|
+
* home, where the platform dir, the CLI's config and every session live.
|
|
100
|
+
* Compared by real path, so a symlinked or `HOME`-overridden spelling of
|
|
101
|
+
* either side cannot slip past.
|
|
102
|
+
*/
|
|
103
|
+
async function refuseDirHoldingPlatform(linkPath, platformDir) {
|
|
104
|
+
const [realLink, realPlatform] = await Promise.all([realpath(linkPath), realpath(platformDir)]);
|
|
105
|
+
const fromLink = relative(realLink, realPlatform);
|
|
106
|
+
const outside = fromLink === ".." || fromLink.startsWith(`..${sep}`) || isAbsolute(fromLink);
|
|
107
|
+
if (!outside) {
|
|
108
|
+
throw new Error(`The workspace's ${linkPath} is the Stigmer home (it holds this session's platform dir, ${platformDir}); ` +
|
|
109
|
+
"use a project directory as the workspace, not the home directory");
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/** Rename, or copy then remove when the destination is on another filesystem (a cloud workspace volume and `$HOME` are). */
|
|
113
|
+
async function moveEntry(source, destination) {
|
|
114
|
+
try {
|
|
115
|
+
await rename(source, destination);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
if (errnoCode(err) !== "EXDEV")
|
|
67
119
|
throw err;
|
|
68
|
-
}
|
|
120
|
+
await cp(source, destination, { recursive: true, errorOnExist: true, force: false, verbatimSymlinks: true });
|
|
121
|
+
await rm(source, { recursive: true, force: true });
|
|
69
122
|
}
|
|
70
|
-
|
|
123
|
+
}
|
|
124
|
+
/** A compact UTC stamp with milliseconds (`20260929T101500123Z`): sortable, and free of the colons a path should not carry. */
|
|
125
|
+
function displacementStamp(now) {
|
|
126
|
+
return now.toISOString().replace(/[-:.]/g, "");
|
|
127
|
+
}
|
|
128
|
+
/** The errno code of a Node filesystem error, or `undefined` for anything else. */
|
|
129
|
+
function errnoCode(err) {
|
|
130
|
+
if (typeof err !== "object" || err === null || !("code" in err))
|
|
131
|
+
return undefined;
|
|
132
|
+
return typeof err.code === "string" ? err.code : undefined;
|
|
71
133
|
}
|
|
72
134
|
/**
|
|
73
135
|
* Whether the workspace's `.stigmer` is, right now, the link
|
|
@@ -102,7 +164,7 @@ export async function removeStigmerSymlink(workspaceDir) {
|
|
|
102
164
|
}
|
|
103
165
|
}
|
|
104
166
|
catch (err) {
|
|
105
|
-
if (err
|
|
167
|
+
if (errnoCode(err) !== "ENOENT") {
|
|
106
168
|
console.warn(`removeStigmerSymlink: failed to remove ${linkPath} (non-fatal): ` +
|
|
107
169
|
`${err instanceof Error ? err.message : err}`);
|
|
108
170
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stigmer-link.js","sourceRoot":"","sources":["../../../src/shared/workspace/stigmer-link.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"stigmer-link.js","sourceRoot":"","sources":["../../../src/shared/workspace/stigmer-link.ts"],"names":[],"mappings":"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"}
|