@caupulican/pi-adaptative 0.86.3 → 0.86.6
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/CHANGELOG.md +44 -0
- package/dist/core/agent-paths.d.ts +13 -0
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +23 -0
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts +7 -0
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +12 -4
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +2 -0
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +6 -3
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/subagent-prompt.js +1 -1
- package/dist/core/autonomy/subagent-prompt.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +25 -2
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +67 -0
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/delegation/replay-safe-mailbox-bounds.d.ts +4 -0
- package/dist/core/delegation/replay-safe-mailbox-bounds.d.ts.map +1 -0
- package/dist/core/delegation/replay-safe-mailbox-bounds.js +20 -0
- package/dist/core/delegation/replay-safe-mailbox-bounds.js.map +1 -0
- package/dist/core/delegation/sanitized-context-fork.d.ts +25 -0
- package/dist/core/delegation/sanitized-context-fork.d.ts.map +1 -0
- package/dist/core/delegation/sanitized-context-fork.js +299 -0
- package/dist/core/delegation/sanitized-context-fork.js.map +1 -0
- package/dist/core/delegation/session-root-mailbox.d.ts +75 -0
- package/dist/core/delegation/session-root-mailbox.d.ts.map +1 -0
- package/dist/core/delegation/session-root-mailbox.js +627 -0
- package/dist/core/delegation/session-root-mailbox.js.map +1 -0
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +102 -9
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.js +1307 -125
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-agent-control.d.ts +183 -8
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control.js +778 -48
- package/dist/core/delegation/worker-agent-control.js.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.d.ts +9 -0
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.js +479 -214
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.d.ts +9 -0
- package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.js +21 -2
- package/dist/core/delegation/worker-authority-resolver.js.map +1 -1
- package/dist/core/delegation/worker-context-fork-store.d.ts +71 -0
- package/dist/core/delegation/worker-context-fork-store.d.ts.map +1 -0
- package/dist/core/delegation/worker-context-fork-store.js +437 -0
- package/dist/core/delegation/worker-context-fork-store.js.map +1 -0
- package/dist/core/delegation/worker-context-inheritance-policy.d.ts +18 -0
- package/dist/core/delegation/worker-context-inheritance-policy.d.ts.map +1 -0
- package/dist/core/delegation/worker-context-inheritance-policy.js +28 -0
- package/dist/core/delegation/worker-context-inheritance-policy.js.map +1 -0
- package/dist/core/delegation/worker-conversation-revision.d.ts +31 -0
- package/dist/core/delegation/worker-conversation-revision.d.ts.map +1 -0
- package/dist/core/delegation/worker-conversation-revision.js +203 -0
- package/dist/core/delegation/worker-conversation-revision.js.map +1 -0
- package/dist/core/delegation/worker-conversation-store.d.ts +130 -18
- package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -1
- package/dist/core/delegation/worker-conversation-store.js +1263 -79
- package/dist/core/delegation/worker-conversation-store.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +30 -2
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +675 -111
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-delegation-request.d.ts +2 -0
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts +20 -1
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.js +210 -37
- package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -1
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
- package/dist/core/delegation/worker-execution-policy.js +14 -2
- package/dist/core/delegation/worker-execution-policy.js.map +1 -1
- package/dist/core/delegation/worker-fleet-limits.d.ts +38 -0
- package/dist/core/delegation/worker-fleet-limits.d.ts.map +1 -0
- package/dist/core/delegation/worker-fleet-limits.js +113 -0
- package/dist/core/delegation/worker-fleet-limits.js.map +1 -0
- package/dist/core/delegation/worker-lane-projection.d.ts +1 -0
- package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -1
- package/dist/core/delegation/worker-lane-projection.js +6 -2
- package/dist/core/delegation/worker-lane-projection.js.map +1 -1
- package/dist/core/delegation/worker-lifecycle.d.ts +20 -3
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
- package/dist/core/delegation/worker-lifecycle.js +42 -18
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-notification-coordinator.d.ts +4 -0
- package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-notification-coordinator.js +45 -4
- package/dist/core/delegation/worker-notification-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-provider-turn-protocol.d.ts +50 -0
- package/dist/core/delegation/worker-provider-turn-protocol.d.ts.map +1 -0
- package/dist/core/delegation/worker-provider-turn-protocol.js +185 -0
- package/dist/core/delegation/worker-provider-turn-protocol.js.map +1 -0
- package/dist/core/delegation/worker-recovery-coordinator.d.ts +45 -4
- package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.js +223 -17
- package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-retry-policy.d.ts +36 -0
- package/dist/core/delegation/worker-retry-policy.d.ts.map +1 -0
- package/dist/core/delegation/worker-retry-policy.js +41 -0
- package/dist/core/delegation/worker-retry-policy.js.map +1 -0
- package/dist/core/delegation/worker-runner.d.ts +3 -1
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +4 -2
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-task-view.d.ts +43 -0
- package/dist/core/delegation/worker-task-view.d.ts.map +1 -0
- package/dist/core/delegation/worker-task-view.js +194 -0
- package/dist/core/delegation/worker-task-view.js.map +1 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts +55 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.js +179 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts +2 -2
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-tree-budget-coordinator.js +12 -46
- package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -1
- package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-controller.js +15 -0
- package/dist/core/goals/goal-continuation-controller.js.map +1 -1
- package/dist/core/goals/goal-state.d.ts +6 -0
- package/dist/core/goals/goal-state.d.ts.map +1 -1
- package/dist/core/goals/goal-state.js +1 -0
- package/dist/core/goals/goal-state.js.map +1 -1
- package/dist/core/goals/goal-tool-core.d.ts +1 -0
- package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
- package/dist/core/goals/goal-tool-core.js +25 -3
- package/dist/core/goals/goal-tool-core.js.map +1 -1
- package/dist/core/keybindings.d.ts +10 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/orchestration/attempt-ordering.d.ts +9 -0
- package/dist/core/orchestration/attempt-ordering.d.ts.map +1 -0
- package/dist/core/orchestration/attempt-ordering.js +29 -0
- package/dist/core/orchestration/attempt-ordering.js.map +1 -0
- package/dist/core/orchestration/capability-gateway.d.ts +19 -0
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +19 -2
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +43 -3
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +24 -0
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/delegation-ledger.d.ts +8 -3
- package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
- package/dist/core/orchestration/delegation-ledger.js +148 -55
- package/dist/core/orchestration/delegation-ledger.js.map +1 -1
- package/dist/core/orchestration/event-store.d.ts +6 -3
- package/dist/core/orchestration/event-store.d.ts.map +1 -1
- package/dist/core/orchestration/event-store.js +228 -30
- package/dist/core/orchestration/event-store.js.map +1 -1
- package/dist/core/orchestration/task-runtime-codecs.d.ts +31 -0
- package/dist/core/orchestration/task-runtime-codecs.d.ts.map +1 -0
- package/dist/core/orchestration/task-runtime-codecs.js +1471 -0
- package/dist/core/orchestration/task-runtime-codecs.js.map +1 -0
- package/dist/core/orchestration/task-runtime-projection.d.ts +30 -0
- package/dist/core/orchestration/task-runtime-projection.d.ts.map +1 -0
- package/dist/core/orchestration/task-runtime-projection.js +340 -0
- package/dist/core/orchestration/task-runtime-projection.js.map +1 -0
- package/dist/core/orchestration/task-runtime-reducer.d.ts +38 -0
- package/dist/core/orchestration/task-runtime-reducer.d.ts.map +1 -0
- package/dist/core/orchestration/task-runtime-reducer.js +1270 -0
- package/dist/core/orchestration/task-runtime-reducer.js.map +1 -0
- package/dist/core/orchestration/task-runtime-state.d.ts +142 -0
- package/dist/core/orchestration/task-runtime-state.d.ts.map +1 -0
- package/dist/core/orchestration/task-runtime-state.js +14 -0
- package/dist/core/orchestration/task-runtime-state.js.map +1 -0
- package/dist/core/orchestration/task-runtime.d.ts +44 -98
- package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
- package/dist/core/orchestration/task-runtime.js +357 -1113
- package/dist/core/orchestration/task-runtime.js.map +1 -1
- package/dist/core/orchestration/worker-context-fork-reference.d.ts +20 -0
- package/dist/core/orchestration/worker-context-fork-reference.d.ts.map +1 -0
- package/dist/core/orchestration/worker-context-fork-reference.js +53 -0
- package/dist/core/orchestration/worker-context-fork-reference.js.map +1 -0
- package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.js +4 -2
- package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
- package/dist/core/research/research-runner.d.ts +2 -0
- package/dist/core/research/research-runner.d.ts.map +1 -1
- package/dist/core/research/research-runner.js +1 -0
- package/dist/core/research/research-runner.js.map +1 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +8 -0
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/secrets/credential-project.d.ts.map +1 -1
- package/dist/core/secrets/credential-project.js +24 -2
- package/dist/core/secrets/credential-project.js.map +1 -1
- package/dist/core/security/secret-text.d.ts +3 -0
- package/dist/core/security/secret-text.d.ts.map +1 -1
- package/dist/core/security/secret-text.js +15 -0
- package/dist/core/security/secret-text.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +160 -8
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +33 -15
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +763 -115
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/goal.d.ts +1 -0
- package/dist/core/tools/goal.d.ts.map +1 -1
- package/dist/core/tools/goal.js +9 -1
- package/dist/core/tools/goal.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/activity-lane.d.ts +5 -0
- package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -1
- package/dist/modes/interactive/components/activity-lane.js +133 -49
- package/dist/modes/interactive/components/activity-lane.js.map +1 -1
- package/dist/modes/interactive/components/agents-overlay.d.ts +40 -0
- package/dist/modes/interactive/components/agents-overlay.d.ts.map +1 -0
- package/dist/modes/interactive/components/agents-overlay.js +153 -0
- package/dist/modes/interactive/components/agents-overlay.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +18 -13
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-event-controller.d.ts +1 -1
- package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-event-controller.js +6 -3
- package/dist/modes/interactive/interactive-event-controller.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +5 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +51 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/key-handlers.d.ts +1 -0
- package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
- package/dist/modes/interactive/key-handlers.js +1 -0
- package/dist/modes/interactive/key-handlers.js.map +1 -1
- package/docs/harness-architecture.md +61 -17
- package/docs/settings.md +17 -9
- package/docs/worker-profiles.md +6 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { attemptUsageFromGatewayUsage, EMPTY_ATTEMPT_USAGE, reconcileAttemptUsage, } from "../orchestration/attempt-usage.js";
|
|
2
|
+
import { budgetedTokens, } from "../orchestration/capability-gateway.js";
|
|
1
3
|
import { intersectRiskBudgets } from "../orchestration/risk-budget.js";
|
|
2
4
|
export class WorkerTreeBudgetExceededError extends Error {
|
|
3
5
|
constructor(field, subject) {
|
|
@@ -6,16 +8,6 @@ export class WorkerTreeBudgetExceededError extends Error {
|
|
|
6
8
|
this.field = field;
|
|
7
9
|
}
|
|
8
10
|
}
|
|
9
|
-
const EMPTY_ATTEMPT_USAGE = {
|
|
10
|
-
toolCalls: 0,
|
|
11
|
-
inputTokens: 0,
|
|
12
|
-
outputTokens: 0,
|
|
13
|
-
cacheReadTokens: 0,
|
|
14
|
-
cacheWriteTokens: 0,
|
|
15
|
-
totalTokens: 0,
|
|
16
|
-
costUsd: 0,
|
|
17
|
-
activeWallClockMs: 0,
|
|
18
|
-
};
|
|
19
11
|
/** Rebuild every durable tree attempt, including attempts with no usage checkpoint yet. */
|
|
20
12
|
export function collectWorkerTreeBudgetSeeds(snapshot, rootAgentId) {
|
|
21
13
|
const seeds = [];
|
|
@@ -31,32 +23,6 @@ export function collectWorkerTreeBudgetSeeds(snapshot, rootAgentId) {
|
|
|
31
23
|
}
|
|
32
24
|
return seeds;
|
|
33
25
|
}
|
|
34
|
-
function gatewayUsage(usage) {
|
|
35
|
-
return {
|
|
36
|
-
toolCalls: usage.toolCalls,
|
|
37
|
-
inputTokens: usage.inputTokens,
|
|
38
|
-
outputTokens: usage.outputTokens,
|
|
39
|
-
cacheReadTokens: usage.cacheReadTokens,
|
|
40
|
-
cacheWriteTokens: usage.cacheWriteTokens,
|
|
41
|
-
totalTokens: usage.totalTokens,
|
|
42
|
-
costUsd: usage.costUsd,
|
|
43
|
-
wallClockMs: usage.activeWallClockMs,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
function mergeUsage(current, incoming) {
|
|
47
|
-
if (!current)
|
|
48
|
-
return structuredClone(incoming);
|
|
49
|
-
return {
|
|
50
|
-
toolCalls: Math.max(current.toolCalls, incoming.toolCalls),
|
|
51
|
-
inputTokens: Math.max(current.inputTokens, incoming.inputTokens),
|
|
52
|
-
outputTokens: Math.max(current.outputTokens, incoming.outputTokens),
|
|
53
|
-
cacheReadTokens: Math.max(current.cacheReadTokens, incoming.cacheReadTokens),
|
|
54
|
-
cacheWriteTokens: Math.max(current.cacheWriteTokens, incoming.cacheWriteTokens),
|
|
55
|
-
totalTokens: Math.max(current.totalTokens, incoming.totalTokens),
|
|
56
|
-
costUsd: Math.max(current.costUsd, incoming.costUsd),
|
|
57
|
-
wallClockMs: Math.max(current.wallClockMs, incoming.wallClockMs),
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
26
|
function abortReason(signal) {
|
|
61
27
|
return signal.reason ?? new Error("Worker provider budget reservation was aborted.");
|
|
62
28
|
}
|
|
@@ -75,9 +41,9 @@ export class WorkerTreeBudgetCoordinator {
|
|
|
75
41
|
state.budget = intersectRiskBudgets(state.budget, args.budget);
|
|
76
42
|
}
|
|
77
43
|
for (const seed of args.seeds) {
|
|
78
|
-
state.attempts.set(seed.attemptId,
|
|
44
|
+
state.attempts.set(seed.attemptId, reconcileAttemptUsage(state.attempts.get(seed.attemptId) ?? EMPTY_ATTEMPT_USAGE, seed.usage));
|
|
79
45
|
}
|
|
80
|
-
state.attempts.set(args.attemptId,
|
|
46
|
+
state.attempts.set(args.attemptId, reconcileAttemptUsage(state.attempts.get(args.attemptId) ?? EMPTY_ATTEMPT_USAGE, args.initialUsage));
|
|
81
47
|
const tree = state;
|
|
82
48
|
return {
|
|
83
49
|
assertBudgetAvailable: (subject) => this.assertAvailable(tree, subject),
|
|
@@ -86,18 +52,18 @@ export class WorkerTreeBudgetCoordinator {
|
|
|
86
52
|
const maximum = tree.budget.maxTokens;
|
|
87
53
|
return maximum === undefined
|
|
88
54
|
? undefined
|
|
89
|
-
: Math.max(0, maximum - this.
|
|
55
|
+
: Math.max(0, maximum - this.budgetedTokens(tree) - this.reservedTokens(tree));
|
|
90
56
|
},
|
|
91
57
|
reserveProviderBudget: (requestedMaxTokens, subject, signal) => this.reserveProviderBudget(tree, args.attemptId, requestedMaxTokens, subject, signal),
|
|
92
58
|
};
|
|
93
59
|
}
|
|
94
60
|
recordAttemptUsage(state, attemptId, usage) {
|
|
95
61
|
const previous = state.attempts.get(attemptId);
|
|
96
|
-
const merged =
|
|
62
|
+
const merged = reconcileAttemptUsage(previous ?? EMPTY_ATTEMPT_USAGE, attemptUsageFromGatewayUsage(usage));
|
|
97
63
|
state.attempts.set(attemptId, merged);
|
|
98
64
|
const reservation = state.reservations.get(attemptId);
|
|
99
65
|
if (reservation && previous) {
|
|
100
|
-
reservation.maxTokens = Math.max(0, reservation.maxTokens - Math.max(0, merged
|
|
66
|
+
reservation.maxTokens = Math.max(0, reservation.maxTokens - Math.max(0, budgetedTokens(merged) - budgetedTokens(previous)));
|
|
101
67
|
}
|
|
102
68
|
}
|
|
103
69
|
reserveProviderBudget(state, attemptId, requestedMaxTokens, subject, signal) {
|
|
@@ -152,7 +118,7 @@ export class WorkerTreeBudgetCoordinator {
|
|
|
152
118
|
}
|
|
153
119
|
const availableTokens = state.budget.maxTokens === undefined
|
|
154
120
|
? waiter.requestedMaxTokens
|
|
155
|
-
: Math.max(0, state.budget.maxTokens - this.
|
|
121
|
+
: Math.max(0, state.budget.maxTokens - this.budgetedTokens(state) - this.reservedTokens(state));
|
|
156
122
|
if (availableTokens <= 0)
|
|
157
123
|
return;
|
|
158
124
|
const maxTokens = Math.min(waiter.requestedMaxTokens, availableTokens);
|
|
@@ -179,8 +145,8 @@ export class WorkerTreeBudgetCoordinator {
|
|
|
179
145
|
if (waiter.signal && waiter.onAbort)
|
|
180
146
|
waiter.signal.removeEventListener("abort", waiter.onAbort);
|
|
181
147
|
}
|
|
182
|
-
|
|
183
|
-
return [...state.attempts.values()].reduce((total, usage) => total + usage
|
|
148
|
+
budgetedTokens(state) {
|
|
149
|
+
return [...state.attempts.values()].reduce((total, usage) => total + budgetedTokens(usage), 0);
|
|
184
150
|
}
|
|
185
151
|
reservedTokens(state) {
|
|
186
152
|
return [...state.reservations.values()].reduce((total, reservation) => total + reservation.maxTokens, 0);
|
|
@@ -190,7 +156,7 @@ export class WorkerTreeBudgetCoordinator {
|
|
|
190
156
|
if (state.budget.maxAttempts !== undefined && usages.length > state.budget.maxAttempts) {
|
|
191
157
|
throw new WorkerTreeBudgetExceededError("maxAttempts", subject);
|
|
192
158
|
}
|
|
193
|
-
if (state.budget.maxTokens !== undefined && this.
|
|
159
|
+
if (state.budget.maxTokens !== undefined && this.budgetedTokens(state) >= state.budget.maxTokens) {
|
|
194
160
|
throw new WorkerTreeBudgetExceededError("maxTokens", subject);
|
|
195
161
|
}
|
|
196
162
|
if (state.budget.maxCostUsd !== undefined &&
|
|
@@ -202,7 +168,7 @@ export class WorkerTreeBudgetCoordinator {
|
|
|
202
168
|
throw new WorkerTreeBudgetExceededError("maxToolCalls", subject);
|
|
203
169
|
}
|
|
204
170
|
if (state.budget.maxWallClockMs !== undefined &&
|
|
205
|
-
usages.reduce((total, usage) => total + usage.
|
|
171
|
+
usages.reduce((total, usage) => total + usage.activeWallClockMs, 0) >= state.budget.maxWallClockMs) {
|
|
206
172
|
throw new WorkerTreeBudgetExceededError("maxWallClockMs", subject);
|
|
207
173
|
}
|
|
208
174
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-tree-budget-coordinator.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-tree-budget-coordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tGatewayUsageSnapshot,\n\tProviderBudgetReservation,\n\tSharedCapabilityBudget,\n} from \"../orchestration/capability-gateway.ts\";\nimport type { AttemptUsageSnapshot, RiskBudget } from \"../orchestration/contracts.ts\";\nimport { intersectRiskBudgets } from \"../orchestration/risk-budget.ts\";\n\nexport class WorkerTreeBudgetExceededError extends Error {\n\treadonly field: \"maxTokens\" | \"maxCostUsd\" | \"maxToolCalls\" | \"maxWallClockMs\" | \"maxAttempts\";\n\n\tconstructor(field: WorkerTreeBudgetExceededError[\"field\"], subject: string) {\n\t\tsuper(`Worker orchestration tree budget '${field}' is exhausted before ${subject}.`);\n\t\tthis.name = \"WorkerTreeBudgetExceededError\";\n\t\tthis.field = field;\n\t}\n}\n\ninterface TreeBudgetState {\n\tbudget: RiskBudget;\n\tattempts: Map<string, GatewayUsageSnapshot>;\n\treservations: Map<string, { maxTokens: number }>;\n\twaiters: ProviderBudgetWaiter[];\n}\n\ninterface ProviderBudgetWaiter {\n\tattemptId: string;\n\trequestedMaxTokens: number;\n\tsubject: string;\n\tsignal?: AbortSignal;\n\tresolve(reservation: ProviderBudgetReservation): void;\n\treject(error: unknown): void;\n\tonAbort?: () => void;\n}\n\nexport interface WorkerTreeBudgetSeed {\n\tattemptId: string;\n\tusage: AttemptUsageSnapshot;\n}\n\nexport interface WorkerTreeBudgetProjection {\n\tagents: Readonly<Record<string, { rootAgentId: string }>>;\n\tattempts: Readonly<\n\t\tRecord<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tattemptId: string;\n\t\t\t\tagentId?: string;\n\t\t\t\tdispatch: { logicalLaneId?: string };\n\t\t\t\tcheckpointIds: readonly string[];\n\t\t\t}\n\t\t>\n\t>;\n\tcheckpoints: Readonly<Record<string, { usage?: AttemptUsageSnapshot }>>;\n}\n\nconst EMPTY_ATTEMPT_USAGE: AttemptUsageSnapshot = {\n\ttoolCalls: 0,\n\tinputTokens: 0,\n\toutputTokens: 0,\n\tcacheReadTokens: 0,\n\tcacheWriteTokens: 0,\n\ttotalTokens: 0,\n\tcostUsd: 0,\n\tactiveWallClockMs: 0,\n};\n\n/** Rebuild every durable tree attempt, including attempts with no usage checkpoint yet. */\nexport function collectWorkerTreeBudgetSeeds(\n\tsnapshot: WorkerTreeBudgetProjection,\n\trootAgentId: string,\n): WorkerTreeBudgetSeed[] {\n\tconst seeds: WorkerTreeBudgetSeed[] = [];\n\tfor (const attempt of Object.values(snapshot.attempts)) {\n\t\tconst attemptAgentId = attempt.agentId ?? attempt.dispatch.logicalLaneId;\n\t\tif (!attemptAgentId || snapshot.agents[attemptAgentId]?.rootAgentId !== rootAgentId) continue;\n\t\tconst usage = [...attempt.checkpointIds]\n\t\t\t.reverse()\n\t\t\t.map((checkpointId) => snapshot.checkpoints[checkpointId]?.usage)\n\t\t\t.find((candidate): candidate is AttemptUsageSnapshot => candidate !== undefined);\n\t\tseeds.push({ attemptId: attempt.attemptId, usage: usage ?? EMPTY_ATTEMPT_USAGE });\n\t}\n\treturn seeds;\n}\n\nfunction gatewayUsage(usage: AttemptUsageSnapshot): GatewayUsageSnapshot {\n\treturn {\n\t\ttoolCalls: usage.toolCalls,\n\t\tinputTokens: usage.inputTokens,\n\t\toutputTokens: usage.outputTokens,\n\t\tcacheReadTokens: usage.cacheReadTokens,\n\t\tcacheWriteTokens: usage.cacheWriteTokens,\n\t\ttotalTokens: usage.totalTokens,\n\t\tcostUsd: usage.costUsd,\n\t\twallClockMs: usage.activeWallClockMs,\n\t};\n}\n\nfunction mergeUsage(current: GatewayUsageSnapshot | undefined, incoming: GatewayUsageSnapshot): GatewayUsageSnapshot {\n\tif (!current) return structuredClone(incoming);\n\treturn {\n\t\ttoolCalls: Math.max(current.toolCalls, incoming.toolCalls),\n\t\tinputTokens: Math.max(current.inputTokens, incoming.inputTokens),\n\t\toutputTokens: Math.max(current.outputTokens, incoming.outputTokens),\n\t\tcacheReadTokens: Math.max(current.cacheReadTokens, incoming.cacheReadTokens),\n\t\tcacheWriteTokens: Math.max(current.cacheWriteTokens, incoming.cacheWriteTokens),\n\t\ttotalTokens: Math.max(current.totalTokens, incoming.totalTokens),\n\t\tcostUsd: Math.max(current.costUsd, incoming.costUsd),\n\t\twallClockMs: Math.max(current.wallClockMs, incoming.wallClockMs),\n\t};\n}\n\nfunction abortReason(signal: AbortSignal): unknown {\n\treturn signal.reason ?? new Error(\"Worker provider budget reservation was aborted.\");\n}\n\n/** One in-memory aggregate reconstructed from durable checkpoints whenever a root is first used. */\nexport class WorkerTreeBudgetCoordinator {\n\tprivate readonly trees = new Map<string, TreeBudgetState>();\n\n\tcreatePort(args: {\n\t\trootAgentId: string;\n\t\tattemptId: string;\n\t\tbudget: RiskBudget;\n\t\tseeds: readonly WorkerTreeBudgetSeed[];\n\t\tinitialUsage: AttemptUsageSnapshot;\n\t}): SharedCapabilityBudget {\n\t\tlet state = this.trees.get(args.rootAgentId);\n\t\tif (!state) {\n\t\t\tstate = { budget: structuredClone(args.budget), attempts: new Map(), reservations: new Map(), waiters: [] };\n\t\t\tthis.trees.set(args.rootAgentId, state);\n\t\t} else {\n\t\t\tstate.budget = intersectRiskBudgets(state.budget, args.budget);\n\t\t}\n\t\tfor (const seed of args.seeds) {\n\t\t\tstate.attempts.set(seed.attemptId, mergeUsage(state.attempts.get(seed.attemptId), gatewayUsage(seed.usage)));\n\t\t}\n\t\tstate.attempts.set(\n\t\t\targs.attemptId,\n\t\t\tmergeUsage(state.attempts.get(args.attemptId), gatewayUsage(args.initialUsage)),\n\t\t);\n\t\tconst tree = state;\n\t\treturn {\n\t\t\tassertBudgetAvailable: (subject) => this.assertAvailable(tree, subject),\n\t\t\trecordAttemptUsage: (usage) => this.recordAttemptUsage(tree, args.attemptId, usage),\n\t\t\tremainingTokens: () => {\n\t\t\t\tconst maximum = tree.budget.maxTokens;\n\t\t\t\treturn maximum === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: Math.max(0, maximum - this.totalTokens(tree) - this.reservedTokens(tree));\n\t\t\t},\n\t\t\treserveProviderBudget: (requestedMaxTokens, subject, signal) =>\n\t\t\t\tthis.reserveProviderBudget(tree, args.attemptId, requestedMaxTokens, subject, signal),\n\t\t};\n\t}\n\n\tprivate recordAttemptUsage(state: TreeBudgetState, attemptId: string, usage: GatewayUsageSnapshot): void {\n\t\tconst previous = state.attempts.get(attemptId);\n\t\tconst merged = mergeUsage(previous, usage);\n\t\tstate.attempts.set(attemptId, merged);\n\t\tconst reservation = state.reservations.get(attemptId);\n\t\tif (reservation && previous) {\n\t\t\treservation.maxTokens = Math.max(\n\t\t\t\t0,\n\t\t\t\treservation.maxTokens - Math.max(0, merged.totalTokens - previous.totalTokens),\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate reserveProviderBudget(\n\t\tstate: TreeBudgetState,\n\t\tattemptId: string,\n\t\trequestedMaxTokens: number,\n\t\tsubject: string,\n\t\tsignal?: AbortSignal,\n\t): Promise<ProviderBudgetReservation> {\n\t\tif (!Number.isSafeInteger(requestedMaxTokens) || requestedMaxTokens <= 0) {\n\t\t\treturn Promise.reject(new Error(\"Worker provider token reservation must be a positive safe integer.\"));\n\t\t}\n\t\tif (signal?.aborted) return Promise.reject(abortReason(signal));\n\t\treturn new Promise<ProviderBudgetReservation>((resolve, reject) => {\n\t\t\tconst waiter: ProviderBudgetWaiter = {\n\t\t\t\tattemptId,\n\t\t\t\trequestedMaxTokens,\n\t\t\t\tsubject,\n\t\t\t\t...(signal ? { signal } : {}),\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t};\n\t\t\tif (signal) {\n\t\t\t\twaiter.onAbort = () => {\n\t\t\t\t\tconst index = state.waiters.indexOf(waiter);\n\t\t\t\t\tif (index < 0) return;\n\t\t\t\t\tstate.waiters.splice(index, 1);\n\t\t\t\t\treject(abortReason(signal));\n\t\t\t\t\tthis.drainWaiters(state);\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.onAbort, { once: true });\n\t\t\t}\n\t\t\tstate.waiters.push(waiter);\n\t\t\tthis.drainWaiters(state);\n\t\t});\n\t}\n\n\tprivate drainWaiters(state: TreeBudgetState): void {\n\t\twhile (state.waiters.length > 0) {\n\t\t\tconst waiter = state.waiters[0];\n\t\t\tif (!waiter) return;\n\t\t\ttry {\n\t\t\t\tthis.assertAvailable(state, waiter.subject);\n\t\t\t} catch (error) {\n\t\t\t\tstate.waiters.shift();\n\t\t\t\tthis.detachAbort(waiter);\n\t\t\t\twaiter.reject(error);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (state.reservations.has(waiter.attemptId)) return;\n\t\t\tif (\n\t\t\t\t(state.budget.maxCostUsd !== undefined || state.budget.maxWallClockMs !== undefined) &&\n\t\t\t\tstate.reservations.size > 0\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst availableTokens =\n\t\t\t\tstate.budget.maxTokens === undefined\n\t\t\t\t\t? waiter.requestedMaxTokens\n\t\t\t\t\t: Math.max(0, state.budget.maxTokens - this.totalTokens(state) - this.reservedTokens(state));\n\t\t\tif (availableTokens <= 0) return;\n\t\t\tconst maxTokens = Math.min(waiter.requestedMaxTokens, availableTokens);\n\t\t\tstate.waiters.shift();\n\t\t\tthis.detachAbort(waiter);\n\t\t\tconst reservationState = { maxTokens };\n\t\t\tstate.reservations.set(waiter.attemptId, reservationState);\n\t\t\tlet released = false;\n\t\t\twaiter.resolve({\n\t\t\t\tmaxTokens,\n\t\t\t\trelease: () => {\n\t\t\t\t\tif (released) return;\n\t\t\t\t\treleased = true;\n\t\t\t\t\tif (state.reservations.get(waiter.attemptId) === reservationState) {\n\t\t\t\t\t\tstate.reservations.delete(waiter.attemptId);\n\t\t\t\t\t}\n\t\t\t\t\tthis.drainWaiters(state);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate detachAbort(waiter: ProviderBudgetWaiter): void {\n\t\tif (waiter.signal && waiter.onAbort) waiter.signal.removeEventListener(\"abort\", waiter.onAbort);\n\t}\n\n\tprivate totalTokens(state: TreeBudgetState): number {\n\t\treturn [...state.attempts.values()].reduce((total, usage) => total + usage.totalTokens, 0);\n\t}\n\n\tprivate reservedTokens(state: TreeBudgetState): number {\n\t\treturn [...state.reservations.values()].reduce((total, reservation) => total + reservation.maxTokens, 0);\n\t}\n\n\tprivate assertAvailable(state: TreeBudgetState, subject: string): void {\n\t\tconst usages = [...state.attempts.values()];\n\t\tif (state.budget.maxAttempts !== undefined && usages.length > state.budget.maxAttempts) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxAttempts\", subject);\n\t\t}\n\t\tif (state.budget.maxTokens !== undefined && this.totalTokens(state) >= state.budget.maxTokens) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxTokens\", subject);\n\t\t}\n\t\tif (\n\t\t\tstate.budget.maxCostUsd !== undefined &&\n\t\t\tusages.reduce((total, usage) => total + usage.costUsd, 0) >= state.budget.maxCostUsd\n\t\t) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxCostUsd\", subject);\n\t\t}\n\t\tif (\n\t\t\tstate.budget.maxToolCalls !== undefined &&\n\t\t\tusages.reduce((total, usage) => total + usage.toolCalls, 0) >= state.budget.maxToolCalls\n\t\t) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxToolCalls\", subject);\n\t\t}\n\t\tif (\n\t\t\tstate.budget.maxWallClockMs !== undefined &&\n\t\t\tusages.reduce((total, usage) => total + usage.wallClockMs, 0) >= state.budget.maxWallClockMs\n\t\t) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxWallClockMs\", subject);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"worker-tree-budget-coordinator.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-tree-budget-coordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tattemptUsageFromGatewayUsage,\n\tEMPTY_ATTEMPT_USAGE,\n\treconcileAttemptUsage,\n} from \"../orchestration/attempt-usage.ts\";\nimport {\n\tbudgetedTokens,\n\ttype GatewayUsageSnapshot,\n\ttype ProviderBudgetReservation,\n\ttype SharedCapabilityBudget,\n} from \"../orchestration/capability-gateway.ts\";\nimport type { AttemptUsageSnapshot, RiskBudget } from \"../orchestration/contracts.ts\";\nimport { intersectRiskBudgets } from \"../orchestration/risk-budget.ts\";\n\nexport class WorkerTreeBudgetExceededError extends Error {\n\treadonly field: \"maxTokens\" | \"maxCostUsd\" | \"maxToolCalls\" | \"maxWallClockMs\" | \"maxAttempts\";\n\n\tconstructor(field: WorkerTreeBudgetExceededError[\"field\"], subject: string) {\n\t\tsuper(`Worker orchestration tree budget '${field}' is exhausted before ${subject}.`);\n\t\tthis.name = \"WorkerTreeBudgetExceededError\";\n\t\tthis.field = field;\n\t}\n}\n\ninterface TreeBudgetState {\n\tbudget: RiskBudget;\n\tattempts: Map<string, AttemptUsageSnapshot>;\n\treservations: Map<string, { maxTokens: number }>;\n\twaiters: ProviderBudgetWaiter[];\n}\n\ninterface ProviderBudgetWaiter {\n\tattemptId: string;\n\trequestedMaxTokens: number;\n\tsubject: string;\n\tsignal?: AbortSignal;\n\tresolve(reservation: ProviderBudgetReservation): void;\n\treject(error: unknown): void;\n\tonAbort?: () => void;\n}\n\nexport interface WorkerTreeBudgetSeed {\n\tattemptId: string;\n\tusage: AttemptUsageSnapshot;\n}\n\nexport interface WorkerTreeBudgetProjection {\n\tagents: Readonly<Record<string, { rootAgentId: string }>>;\n\tattempts: Readonly<\n\t\tRecord<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tattemptId: string;\n\t\t\t\tagentId?: string;\n\t\t\t\tdispatch: { logicalLaneId?: string };\n\t\t\t\tcheckpointIds: readonly string[];\n\t\t\t}\n\t\t>\n\t>;\n\tcheckpoints: Readonly<Record<string, { usage?: AttemptUsageSnapshot }>>;\n}\n\n/** Rebuild every durable tree attempt, including attempts with no usage checkpoint yet. */\nexport function collectWorkerTreeBudgetSeeds(\n\tsnapshot: WorkerTreeBudgetProjection,\n\trootAgentId: string,\n): WorkerTreeBudgetSeed[] {\n\tconst seeds: WorkerTreeBudgetSeed[] = [];\n\tfor (const attempt of Object.values(snapshot.attempts)) {\n\t\tconst attemptAgentId = attempt.agentId ?? attempt.dispatch.logicalLaneId;\n\t\tif (!attemptAgentId || snapshot.agents[attemptAgentId]?.rootAgentId !== rootAgentId) continue;\n\t\tconst usage = [...attempt.checkpointIds]\n\t\t\t.reverse()\n\t\t\t.map((checkpointId) => snapshot.checkpoints[checkpointId]?.usage)\n\t\t\t.find((candidate): candidate is AttemptUsageSnapshot => candidate !== undefined);\n\t\tseeds.push({ attemptId: attempt.attemptId, usage: usage ?? EMPTY_ATTEMPT_USAGE });\n\t}\n\treturn seeds;\n}\n\nfunction abortReason(signal: AbortSignal): unknown {\n\treturn signal.reason ?? new Error(\"Worker provider budget reservation was aborted.\");\n}\n\n/** One in-memory aggregate reconstructed from durable checkpoints whenever a root is first used. */\nexport class WorkerTreeBudgetCoordinator {\n\tprivate readonly trees = new Map<string, TreeBudgetState>();\n\n\tcreatePort(args: {\n\t\trootAgentId: string;\n\t\tattemptId: string;\n\t\tbudget: RiskBudget;\n\t\tseeds: readonly WorkerTreeBudgetSeed[];\n\t\tinitialUsage: AttemptUsageSnapshot;\n\t}): SharedCapabilityBudget {\n\t\tlet state = this.trees.get(args.rootAgentId);\n\t\tif (!state) {\n\t\t\tstate = { budget: structuredClone(args.budget), attempts: new Map(), reservations: new Map(), waiters: [] };\n\t\t\tthis.trees.set(args.rootAgentId, state);\n\t\t} else {\n\t\t\tstate.budget = intersectRiskBudgets(state.budget, args.budget);\n\t\t}\n\t\tfor (const seed of args.seeds) {\n\t\t\tstate.attempts.set(\n\t\t\t\tseed.attemptId,\n\t\t\t\treconcileAttemptUsage(state.attempts.get(seed.attemptId) ?? EMPTY_ATTEMPT_USAGE, seed.usage),\n\t\t\t);\n\t\t}\n\t\tstate.attempts.set(\n\t\t\targs.attemptId,\n\t\t\treconcileAttemptUsage(state.attempts.get(args.attemptId) ?? EMPTY_ATTEMPT_USAGE, args.initialUsage),\n\t\t);\n\t\tconst tree = state;\n\t\treturn {\n\t\t\tassertBudgetAvailable: (subject) => this.assertAvailable(tree, subject),\n\t\t\trecordAttemptUsage: (usage) => this.recordAttemptUsage(tree, args.attemptId, usage),\n\t\t\tremainingTokens: () => {\n\t\t\t\tconst maximum = tree.budget.maxTokens;\n\t\t\t\treturn maximum === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: Math.max(0, maximum - this.budgetedTokens(tree) - this.reservedTokens(tree));\n\t\t\t},\n\t\t\treserveProviderBudget: (requestedMaxTokens, subject, signal) =>\n\t\t\t\tthis.reserveProviderBudget(tree, args.attemptId, requestedMaxTokens, subject, signal),\n\t\t};\n\t}\n\n\tprivate recordAttemptUsage(state: TreeBudgetState, attemptId: string, usage: GatewayUsageSnapshot): void {\n\t\tconst previous = state.attempts.get(attemptId);\n\t\tconst merged = reconcileAttemptUsage(previous ?? EMPTY_ATTEMPT_USAGE, attemptUsageFromGatewayUsage(usage));\n\t\tstate.attempts.set(attemptId, merged);\n\t\tconst reservation = state.reservations.get(attemptId);\n\t\tif (reservation && previous) {\n\t\t\treservation.maxTokens = Math.max(\n\t\t\t\t0,\n\t\t\t\treservation.maxTokens - Math.max(0, budgetedTokens(merged) - budgetedTokens(previous)),\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate reserveProviderBudget(\n\t\tstate: TreeBudgetState,\n\t\tattemptId: string,\n\t\trequestedMaxTokens: number,\n\t\tsubject: string,\n\t\tsignal?: AbortSignal,\n\t): Promise<ProviderBudgetReservation> {\n\t\tif (!Number.isSafeInteger(requestedMaxTokens) || requestedMaxTokens <= 0) {\n\t\t\treturn Promise.reject(new Error(\"Worker provider token reservation must be a positive safe integer.\"));\n\t\t}\n\t\tif (signal?.aborted) return Promise.reject(abortReason(signal));\n\t\treturn new Promise<ProviderBudgetReservation>((resolve, reject) => {\n\t\t\tconst waiter: ProviderBudgetWaiter = {\n\t\t\t\tattemptId,\n\t\t\t\trequestedMaxTokens,\n\t\t\t\tsubject,\n\t\t\t\t...(signal ? { signal } : {}),\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t};\n\t\t\tif (signal) {\n\t\t\t\twaiter.onAbort = () => {\n\t\t\t\t\tconst index = state.waiters.indexOf(waiter);\n\t\t\t\t\tif (index < 0) return;\n\t\t\t\t\tstate.waiters.splice(index, 1);\n\t\t\t\t\treject(abortReason(signal));\n\t\t\t\t\tthis.drainWaiters(state);\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.onAbort, { once: true });\n\t\t\t}\n\t\t\tstate.waiters.push(waiter);\n\t\t\tthis.drainWaiters(state);\n\t\t});\n\t}\n\n\tprivate drainWaiters(state: TreeBudgetState): void {\n\t\twhile (state.waiters.length > 0) {\n\t\t\tconst waiter = state.waiters[0];\n\t\t\tif (!waiter) return;\n\t\t\ttry {\n\t\t\t\tthis.assertAvailable(state, waiter.subject);\n\t\t\t} catch (error) {\n\t\t\t\tstate.waiters.shift();\n\t\t\t\tthis.detachAbort(waiter);\n\t\t\t\twaiter.reject(error);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (state.reservations.has(waiter.attemptId)) return;\n\t\t\tif (\n\t\t\t\t(state.budget.maxCostUsd !== undefined || state.budget.maxWallClockMs !== undefined) &&\n\t\t\t\tstate.reservations.size > 0\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst availableTokens =\n\t\t\t\tstate.budget.maxTokens === undefined\n\t\t\t\t\t? waiter.requestedMaxTokens\n\t\t\t\t\t: Math.max(0, state.budget.maxTokens - this.budgetedTokens(state) - this.reservedTokens(state));\n\t\t\tif (availableTokens <= 0) return;\n\t\t\tconst maxTokens = Math.min(waiter.requestedMaxTokens, availableTokens);\n\t\t\tstate.waiters.shift();\n\t\t\tthis.detachAbort(waiter);\n\t\t\tconst reservationState = { maxTokens };\n\t\t\tstate.reservations.set(waiter.attemptId, reservationState);\n\t\t\tlet released = false;\n\t\t\twaiter.resolve({\n\t\t\t\tmaxTokens,\n\t\t\t\trelease: () => {\n\t\t\t\t\tif (released) return;\n\t\t\t\t\treleased = true;\n\t\t\t\t\tif (state.reservations.get(waiter.attemptId) === reservationState) {\n\t\t\t\t\t\tstate.reservations.delete(waiter.attemptId);\n\t\t\t\t\t}\n\t\t\t\t\tthis.drainWaiters(state);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate detachAbort(waiter: ProviderBudgetWaiter): void {\n\t\tif (waiter.signal && waiter.onAbort) waiter.signal.removeEventListener(\"abort\", waiter.onAbort);\n\t}\n\n\tprivate budgetedTokens(state: TreeBudgetState): number {\n\t\treturn [...state.attempts.values()].reduce((total, usage) => total + budgetedTokens(usage), 0);\n\t}\n\n\tprivate reservedTokens(state: TreeBudgetState): number {\n\t\treturn [...state.reservations.values()].reduce((total, reservation) => total + reservation.maxTokens, 0);\n\t}\n\n\tprivate assertAvailable(state: TreeBudgetState, subject: string): void {\n\t\tconst usages = [...state.attempts.values()];\n\t\tif (state.budget.maxAttempts !== undefined && usages.length > state.budget.maxAttempts) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxAttempts\", subject);\n\t\t}\n\t\tif (state.budget.maxTokens !== undefined && this.budgetedTokens(state) >= state.budget.maxTokens) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxTokens\", subject);\n\t\t}\n\t\tif (\n\t\t\tstate.budget.maxCostUsd !== undefined &&\n\t\t\tusages.reduce((total, usage) => total + usage.costUsd, 0) >= state.budget.maxCostUsd\n\t\t) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxCostUsd\", subject);\n\t\t}\n\t\tif (\n\t\t\tstate.budget.maxToolCalls !== undefined &&\n\t\t\tusages.reduce((total, usage) => total + usage.toolCalls, 0) >= state.budget.maxToolCalls\n\t\t) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxToolCalls\", subject);\n\t\t}\n\t\tif (\n\t\t\tstate.budget.maxWallClockMs !== undefined &&\n\t\t\tusages.reduce((total, usage) => total + usage.activeWallClockMs, 0) >= state.budget.maxWallClockMs\n\t\t) {\n\t\t\tthrow new WorkerTreeBudgetExceededError(\"maxWallClockMs\", subject);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-continuation-controller.d.ts","sourceRoot":"","sources":["../../../src/core/goals/goal-continuation-controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAC/F,MAAM,MAAM,0BAA0B,GACnC,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,oBAAoB,GACpB,qBAAqB,GACrB,gBAAgB,GAChB,qBAAqB,GACrB,0BAA0B,GAC1B,8BAA8B,GAC9B,8BAA8B,GAC9B,oBAAoB,GACpB,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,GACpB,oBAAoB,CAAC;AAExB,MAAM,WAAW,wBAAwB;IACxC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,UAAU,EAAE,0BAA0B,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,uBAAuB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,wBAAwB;IACxC,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,wBAAwB,CAAC;IACnC;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;OAUG;IACH,wBAAwB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/C;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC3C,GAAG,wBAAwB,
|
|
1
|
+
{"version":3,"file":"goal-continuation-controller.d.ts","sourceRoot":"","sources":["../../../src/core/goals/goal-continuation-controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAC/F,MAAM,MAAM,0BAA0B,GACnC,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,oBAAoB,GACpB,qBAAqB,GACrB,gBAAgB,GAChB,qBAAqB,GACrB,0BAA0B,GAC1B,8BAA8B,GAC9B,8BAA8B,GAC9B,oBAAoB,GACpB,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,GACpB,oBAAoB,CAAC;AAExB,MAAM,WAAW,wBAAwB;IACxC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,UAAU,EAAE,0BAA0B,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,uBAAuB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,wBAAwB;IACxC,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,wBAAwB,CAAC;IACnC;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;OAUG;IACH,wBAAwB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/C;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC3C,GAAG,wBAAwB,CAmP3B"}
|
|
@@ -54,6 +54,21 @@ export function evaluateGoalContinuation(args) {
|
|
|
54
54
|
message: "The goal is explicitly blocked.",
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
+
// Semantic Circuit Breaker: check if any requirement has been repeatedly blocked.
|
|
58
|
+
// If a requirement has failed verification / been blocked 3 or more times, the
|
|
59
|
+
// subagent loop is stuck. Forcefully retire the goal to prevent infinite orchestrator looping.
|
|
60
|
+
const MAX_REQUIREMENT_BLOCKS = 3;
|
|
61
|
+
for (const reqId of blockedRequirementIds) {
|
|
62
|
+
const blockCount = state.events.filter((e) => e.type === "block_requirement" && e.id === reqId).length;
|
|
63
|
+
if (blockCount >= MAX_REQUIREMENT_BLOCKS) {
|
|
64
|
+
return {
|
|
65
|
+
...baseDecision,
|
|
66
|
+
action: "stop",
|
|
67
|
+
reasonCode: "stall_limit_reached",
|
|
68
|
+
message: `Circuit Breaker: Requirement '${reqId}' has been blocked ${blockCount} times (e.g. repeated verification failures). The task is stuck in a loop and requires human intervention.`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
57
72
|
if (state.status === "usage_limited") {
|
|
58
73
|
return {
|
|
59
74
|
...baseDecision,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-continuation-controller.js","sourceRoot":"","sources":["../../../src/core/goals/goal-continuation-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { getUnprovenGoalRequirementIds } from \"./goal-acceptance.ts\";\nimport type { GoalState } from \"./goal-state.ts\";\n\nexport type GoalContinuationAction = \"continue\" | \"ask-user\" | \"finalize\" | \"stop\" | \"waiting\";\nexport type GoalContinuationReasonCode =\n\t| \"goal_active\"\n\t| \"goal_completed\"\n\t| \"goal_paused\"\n\t| \"goal_blocked\"\n\t| \"goal_usage_limited\"\n\t| \"goal_budget_limited\"\n\t| \"goal_cancelled\"\n\t| \"stall_limit_reached\"\n\t| \"goal_completion_required\"\n\t| \"acceptance_evidence_required\"\n\t| \"blocked_requirements_present\"\n\t| \"missing_goal_state\"\n\t| \"worker_in_flight\"\n\t| \"worker_wait_timeout\"\n\t| \"lane_sync_conflict\"\n\t| \"lane_sync_required\";\n\nexport interface GoalContinuationDecision {\n\taction: GoalContinuationAction;\n\treasonCode: GoalContinuationReasonCode;\n\tmessage: string;\n\tgoalId?: string;\n\tstallTurns?: number;\n\tmaxStallTurns?: number;\n\topenRequirementIds: readonly string[];\n\tblockedRequirementIds: readonly string[];\n\tsatisfiedRequirementIds: readonly string[];\n}\n\nexport interface GoalContinuationSettings {\n\tmaxStallTurns: number;\n}\n\nexport function evaluateGoalContinuation(args: {\n\tstate?: GoalState;\n\tsettings: GoalContinuationSettings;\n\t/**\n\t * LaneIds currently queued/running AND tagged with THIS goal's id (see `LaneRecord.goalId`).\n\t * When an open requirement is bound (`Requirement.boundLaneId`) to one of these lanes, the\n\t * goal is WAITING on that worker rather than stalled or ready for another pass: the loop must not\n\t * submit a hollow continuation prompt (which would waste a turn while no parent work can advance),\n\t * and the idle scheduler must not race a re-dispatch against the same open requirement. Optional\n\t * so every pre-existing (in-flight-unaware) caller keeps compiling and behaving unchanged.\n\t */\n\tinFlightGoalLaneIds?: ReadonlySet<string>;\n\t/**\n\t * Current time as an ISO string, paired with `maxWorkerWaitMs` to detect a bound in-flight\n\t * requirement that has hung past its deadline (see below). Optional so every pre-existing\n\t * caller that omits it keeps behaving byte-identically -- the goal waits indefinitely, exactly\n\t * as before this field existed.\n\t */\n\tnow?: string;\n\t/**\n\t * Maximum milliseconds a bound in-flight requirement (`Requirement.boundAt`) may wait before\n\t * this escalates to `action:\"ask-user\"`/`reasonCode:\"worker_wait_timeout\"` instead of\n\t * `\"waiting\"` -- a worker that is alive-but-hung past its deadline must not wait forever. Only\n\t * takes effect when BOTH `now` and this are supplied; escalation fires only once EVERY\n\t * bound-in-flight open requirement has individually passed `boundAt + maxWorkerWaitMs`, so a\n\t * goal with a mix of fresh and stale bindings keeps waiting on the fresh one.\n\t */\n\tmaxWorkerWaitMs?: number;\n\t/**\n\t * Bound lanes (`Requirement.boundLaneId` -- SAME id-space as `inFlightGoalLaneIds`, not the raw\n\t * worktree-sync `laneKey`) whose worktree-sync lane has a rebase stopped on conflicts\n\t * (`LaneFacts.rebaseInProgress`). The caller (`goal-runtime-snapshot.ts`) is responsible for\n\t * translating live per-worktree-lane status into this id-space by matching each status entry's\n\t * own `boundLaneId` against the requirement -- this function stays pure and never resolves a\n\t * worktree laneKey itself, exactly like `inFlightGoalLaneIds` never resolves a tmux job id.\n\t * Checked BEFORE the waiting branch (see `lane_sync_conflict` below): a stalled-but-conflicted\n\t * worker must get the resolve directive, not silently wait forever. Optional so every\n\t * pre-existing caller keeps compiling and behaving byte-identically when omitted or empty.\n\t */\n\tlaneSyncConflictLaneKeys?: ReadonlySet<string>;\n\t/**\n\t * Bound lanes (`Requirement.boundLaneId`, same id-space note as {@link laneSyncConflictLaneKeys})\n\t * whose worktree-sync lane is stale and must sync with current main before further work\n\t * (`sync_required`, i.e. NOT already covered by `laneSyncConflictLaneKeys` -- a lane with a\n\t * rebase in progress is reported as a conflict, never double-counted here). Checked BEFORE the\n\t * waiting branch, same precedence rationale as above. Optional so every pre-existing caller keeps\n\t * compiling and behaving byte-identically when omitted or empty.\n\t */\n\tsyncRequiredLaneKeys?: ReadonlySet<string>;\n}): GoalContinuationDecision {\n\tif (!args.state) {\n\t\treturn {\n\t\t\taction: \"ask-user\",\n\t\t\treasonCode: \"missing_goal_state\",\n\t\t\tmessage: \"No goal state is present.\",\n\t\t\topenRequirementIds: [],\n\t\t\tblockedRequirementIds: [],\n\t\t\tsatisfiedRequirementIds: [],\n\t\t};\n\t}\n\n\tconst state = args.state;\n\tconst openRequirementIds: string[] = [];\n\tconst blockedRequirementIds: string[] = [];\n\tconst satisfiedRequirementIds: string[] = [];\n\n\tfor (const req of state.requirements) {\n\t\tif (req.status === \"open\") openRequirementIds.push(req.id);\n\t\telse if (req.status === \"blocked\") blockedRequirementIds.push(req.id);\n\t\telse if (req.status === \"satisfied\") satisfiedRequirementIds.push(req.id);\n\t}\n\n\tconst baseDecision = {\n\t\tgoalId: state.goalId,\n\t\tstallTurns: state.stallTurns,\n\t\tmaxStallTurns: args.settings.maxStallTurns,\n\t\topenRequirementIds,\n\t\tblockedRequirementIds,\n\t\tsatisfiedRequirementIds,\n\t};\n\n\tif (state.status === \"completed\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"finalize\",\n\t\t\treasonCode: \"goal_completed\",\n\t\t\tmessage: \"The goal is marked as completed.\",\n\t\t};\n\t}\n\n\tif (state.status === \"paused\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"stop\",\n\t\t\treasonCode: \"goal_paused\",\n\t\t\tmessage: \"The goal is paused by the owner.\",\n\t\t};\n\t}\n\n\tif (state.status === \"blocked\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"ask-user\",\n\t\t\treasonCode: \"goal_blocked\",\n\t\t\tmessage: \"The goal is explicitly blocked.\",\n\t\t};\n\t}\n\n\tif (state.status === \"usage_limited\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"ask-user\",\n\t\t\treasonCode: \"goal_usage_limited\",\n\t\t\tmessage: \"The goal stopped after the active provider reached a usage limit.\",\n\t\t};\n\t}\n\n\tif (state.status === \"budget_limited\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"stop\",\n\t\t\treasonCode: \"goal_budget_limited\",\n\t\t\tmessage: \"The goal exhausted its configured budget.\",\n\t\t};\n\t}\n\n\tif (state.status === \"cancelled\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"stop\",\n\t\t\treasonCode: \"goal_cancelled\",\n\t\t\tmessage: \"The goal has been cancelled.\",\n\t\t};\n\t}\n\n\tif (openRequirementIds.length === 0) {\n\t\tif (blockedRequirementIds.length > 0) {\n\t\t\treturn {\n\t\t\t\t...baseDecision,\n\t\t\t\taction: \"ask-user\",\n\t\t\t\treasonCode: \"blocked_requirements_present\",\n\t\t\t\tmessage: \"All remaining legacy goal requirements are blocked.\",\n\t\t\t};\n\t\t}\n\t\tif (state.requirements.length === 0) {\n\t\t\treturn {\n\t\t\t\t...baseDecision,\n\t\t\t\taction: \"continue\",\n\t\t\t\treasonCode: \"goal_active\",\n\t\t\t\tmessage: \"The compact goal record is active.\",\n\t\t\t};\n\t\t}\n\t\tconst unprovenRequirementIds = getUnprovenGoalRequirementIds(state);\n\t\tif (unprovenRequirementIds.length > 0) {\n\t\t\treturn {\n\t\t\t\t...baseDecision,\n\t\t\t\taction: \"continue\",\n\t\t\t\treasonCode: \"acceptance_evidence_required\",\n\t\t\t\tmessage: `Requirement(s) ${unprovenRequirementIds.join(\", \")} still need trusted acceptance evidence.`,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"continue\",\n\t\t\treasonCode: \"goal_completion_required\",\n\t\t\tmessage: \"All requirements are proven. Mark the goal complete only after confirming no required work remains.\",\n\t\t};\n\t}\n\n\t// Worktree-sync directives take precedence over the \"waiting\" branch below: a worker whose bound\n\t// lane is conflicted or stale is NOT merely in-flight-and-quiet -- it needs an explicit directive\n\t// (resolve conflicts, or sync) delivered through the continuation prompt, and a stalled-but-stale\n\t// worker must never be left waiting indefinitely for a sync it was never told to run. Conflict is\n\t// checked first: a lane with a rebase already stopped on conflicts cannot usefully be told to\n\t// \"sync\" again (that lane's `sync_required` flag is never set while `rebaseInProgress` is true --\n\t// see `goal-runtime-snapshot.ts` -- so the two sets below are disjoint by construction, not by a\n\t// priority check here).\n\tconst laneSyncConflictLaneKeys = args.laneSyncConflictLaneKeys;\n\tconst conflictedRequirements = laneSyncConflictLaneKeys\n\t\t? state.requirements.filter(\n\t\t\t\t(requirement) =>\n\t\t\t\t\trequirement.status === \"open\" &&\n\t\t\t\t\trequirement.boundLaneId !== undefined &&\n\t\t\t\t\tlaneSyncConflictLaneKeys.has(requirement.boundLaneId),\n\t\t\t)\n\t\t: [];\n\tif (conflictedRequirements.length > 0) {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"continue\",\n\t\t\treasonCode: \"lane_sync_conflict\",\n\t\t\tmessage: `Requirement(s) ${conflictedRequirements.map((requirement) => requirement.id).join(\", \")} are bound to a worktree-sync lane with a rebase stopped on conflicts; resolve via worktree_sync action:\"continue\" (or \"abort_sync\") before this goal can progress further.`,\n\t\t};\n\t}\n\n\tconst syncRequiredLaneKeys = args.syncRequiredLaneKeys;\n\tconst syncRequiredRequirements = syncRequiredLaneKeys\n\t\t? state.requirements.filter(\n\t\t\t\t(requirement) =>\n\t\t\t\t\trequirement.status === \"open\" &&\n\t\t\t\t\trequirement.boundLaneId !== undefined &&\n\t\t\t\t\tsyncRequiredLaneKeys.has(requirement.boundLaneId),\n\t\t\t)\n\t\t: [];\n\tif (syncRequiredRequirements.length > 0) {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"continue\",\n\t\t\treasonCode: \"lane_sync_required\",\n\t\t\tmessage: `Requirement(s) ${syncRequiredRequirements.map((requirement) => requirement.id).join(\", \")} are bound to a worktree-sync lane that must rebase current main before further work; deliver worktree_sync action:\"sync\" to the bound worker, or run it directly for an idle lane.`,\n\t\t};\n\t}\n\n\t// A worker is dispatched (queued/running) against an open requirement this goal owns — wait\n\t// for it rather than submit a hollow pass or let the stall counter judge the goal unproductive.\n\t// Checked BEFORE the stall check so an in-flight worker always wins over an accumulated stall\n\t// count: the goal isn't stalled, it's actively being worked by something other than this loop.\n\tconst inFlightGoalLaneIds = args.inFlightGoalLaneIds;\n\tconst boundInFlightRequirements = inFlightGoalLaneIds\n\t\t? state.requirements.filter(\n\t\t\t\t(requirement) =>\n\t\t\t\t\trequirement.status === \"open\" &&\n\t\t\t\t\trequirement.boundLaneId !== undefined &&\n\t\t\t\t\tinFlightGoalLaneIds.has(requirement.boundLaneId),\n\t\t\t)\n\t\t: [];\n\n\tif (boundInFlightRequirements.length > 0) {\n\t\t// Never-hang backstop: a worker alive-but-hung past its deadline must escalate to the owner\n\t\t// instead of waiting forever. Only evaluated when the caller supplies BOTH a clock reading and\n\t\t// a deadline; escalates only once EVERY bound-in-flight requirement has individually timed out,\n\t\t// so one fresh binding keeps the goal legitimately waiting.\n\t\tif (args.now !== undefined && args.maxWorkerWaitMs !== undefined) {\n\t\t\tconst nowMs = Date.parse(args.now);\n\t\t\tconst maxWorkerWaitMs = args.maxWorkerWaitMs;\n\t\t\tconst allTimedOut =\n\t\t\t\tNumber.isFinite(nowMs) &&\n\t\t\t\tboundInFlightRequirements.every((requirement) => {\n\t\t\t\t\tif (requirement.boundAt === undefined) return false;\n\t\t\t\t\tconst boundAtMs = Date.parse(requirement.boundAt);\n\t\t\t\t\treturn Number.isFinite(boundAtMs) && boundAtMs + maxWorkerWaitMs <= nowMs;\n\t\t\t\t});\n\t\t\tif (allTimedOut) {\n\t\t\t\treturn {\n\t\t\t\t\t...baseDecision,\n\t\t\t\t\taction: \"ask-user\",\n\t\t\t\t\treasonCode: \"worker_wait_timeout\",\n\t\t\t\t\tmessage: `A dispatched worker has not completed within the maximum wait of ${maxWorkerWaitMs}ms; escalating to the owner instead of waiting indefinitely.`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"waiting\",\n\t\t\treasonCode: \"worker_in_flight\",\n\t\t\tmessage: \"A worker is dispatched against an open requirement; waiting for it to finish before continuing.\",\n\t\t};\n\t}\n\n\tif (args.settings.maxStallTurns > 0 && state.stallTurns >= args.settings.maxStallTurns) {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"ask-user\",\n\t\t\treasonCode: \"stall_limit_reached\",\n\t\t\tmessage: `The goal has reached the maximum stall limit of ${args.settings.maxStallTurns} turns.`,\n\t\t};\n\t}\n\n\treturn {\n\t\t...baseDecision,\n\t\taction: \"continue\",\n\t\treasonCode: \"goal_active\",\n\t\tmessage: \"The goal is active and making progress.\",\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"goal-continuation-controller.js","sourceRoot":"","sources":["../../../src/core/goals/goal-continuation-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { getUnprovenGoalRequirementIds } from \"./goal-acceptance.ts\";\nimport type { GoalState } from \"./goal-state.ts\";\n\nexport type GoalContinuationAction = \"continue\" | \"ask-user\" | \"finalize\" | \"stop\" | \"waiting\";\nexport type GoalContinuationReasonCode =\n\t| \"goal_active\"\n\t| \"goal_completed\"\n\t| \"goal_paused\"\n\t| \"goal_blocked\"\n\t| \"goal_usage_limited\"\n\t| \"goal_budget_limited\"\n\t| \"goal_cancelled\"\n\t| \"stall_limit_reached\"\n\t| \"goal_completion_required\"\n\t| \"acceptance_evidence_required\"\n\t| \"blocked_requirements_present\"\n\t| \"missing_goal_state\"\n\t| \"worker_in_flight\"\n\t| \"worker_wait_timeout\"\n\t| \"lane_sync_conflict\"\n\t| \"lane_sync_required\";\n\nexport interface GoalContinuationDecision {\n\taction: GoalContinuationAction;\n\treasonCode: GoalContinuationReasonCode;\n\tmessage: string;\n\tgoalId?: string;\n\tstallTurns?: number;\n\tmaxStallTurns?: number;\n\topenRequirementIds: readonly string[];\n\tblockedRequirementIds: readonly string[];\n\tsatisfiedRequirementIds: readonly string[];\n}\n\nexport interface GoalContinuationSettings {\n\tmaxStallTurns: number;\n}\n\nexport function evaluateGoalContinuation(args: {\n\tstate?: GoalState;\n\tsettings: GoalContinuationSettings;\n\t/**\n\t * LaneIds currently queued/running AND tagged with THIS goal's id (see `LaneRecord.goalId`).\n\t * When an open requirement is bound (`Requirement.boundLaneId`) to one of these lanes, the\n\t * goal is WAITING on that worker rather than stalled or ready for another pass: the loop must not\n\t * submit a hollow continuation prompt (which would waste a turn while no parent work can advance),\n\t * and the idle scheduler must not race a re-dispatch against the same open requirement. Optional\n\t * so every pre-existing (in-flight-unaware) caller keeps compiling and behaving unchanged.\n\t */\n\tinFlightGoalLaneIds?: ReadonlySet<string>;\n\t/**\n\t * Current time as an ISO string, paired with `maxWorkerWaitMs` to detect a bound in-flight\n\t * requirement that has hung past its deadline (see below). Optional so every pre-existing\n\t * caller that omits it keeps behaving byte-identically -- the goal waits indefinitely, exactly\n\t * as before this field existed.\n\t */\n\tnow?: string;\n\t/**\n\t * Maximum milliseconds a bound in-flight requirement (`Requirement.boundAt`) may wait before\n\t * this escalates to `action:\"ask-user\"`/`reasonCode:\"worker_wait_timeout\"` instead of\n\t * `\"waiting\"` -- a worker that is alive-but-hung past its deadline must not wait forever. Only\n\t * takes effect when BOTH `now` and this are supplied; escalation fires only once EVERY\n\t * bound-in-flight open requirement has individually passed `boundAt + maxWorkerWaitMs`, so a\n\t * goal with a mix of fresh and stale bindings keeps waiting on the fresh one.\n\t */\n\tmaxWorkerWaitMs?: number;\n\t/**\n\t * Bound lanes (`Requirement.boundLaneId` -- SAME id-space as `inFlightGoalLaneIds`, not the raw\n\t * worktree-sync `laneKey`) whose worktree-sync lane has a rebase stopped on conflicts\n\t * (`LaneFacts.rebaseInProgress`). The caller (`goal-runtime-snapshot.ts`) is responsible for\n\t * translating live per-worktree-lane status into this id-space by matching each status entry's\n\t * own `boundLaneId` against the requirement -- this function stays pure and never resolves a\n\t * worktree laneKey itself, exactly like `inFlightGoalLaneIds` never resolves a tmux job id.\n\t * Checked BEFORE the waiting branch (see `lane_sync_conflict` below): a stalled-but-conflicted\n\t * worker must get the resolve directive, not silently wait forever. Optional so every\n\t * pre-existing caller keeps compiling and behaving byte-identically when omitted or empty.\n\t */\n\tlaneSyncConflictLaneKeys?: ReadonlySet<string>;\n\t/**\n\t * Bound lanes (`Requirement.boundLaneId`, same id-space note as {@link laneSyncConflictLaneKeys})\n\t * whose worktree-sync lane is stale and must sync with current main before further work\n\t * (`sync_required`, i.e. NOT already covered by `laneSyncConflictLaneKeys` -- a lane with a\n\t * rebase in progress is reported as a conflict, never double-counted here). Checked BEFORE the\n\t * waiting branch, same precedence rationale as above. Optional so every pre-existing caller keeps\n\t * compiling and behaving byte-identically when omitted or empty.\n\t */\n\tsyncRequiredLaneKeys?: ReadonlySet<string>;\n}): GoalContinuationDecision {\n\tif (!args.state) {\n\t\treturn {\n\t\t\taction: \"ask-user\",\n\t\t\treasonCode: \"missing_goal_state\",\n\t\t\tmessage: \"No goal state is present.\",\n\t\t\topenRequirementIds: [],\n\t\t\tblockedRequirementIds: [],\n\t\t\tsatisfiedRequirementIds: [],\n\t\t};\n\t}\n\n\tconst state = args.state;\n\tconst openRequirementIds: string[] = [];\n\tconst blockedRequirementIds: string[] = [];\n\tconst satisfiedRequirementIds: string[] = [];\n\n\tfor (const req of state.requirements) {\n\t\tif (req.status === \"open\") openRequirementIds.push(req.id);\n\t\telse if (req.status === \"blocked\") blockedRequirementIds.push(req.id);\n\t\telse if (req.status === \"satisfied\") satisfiedRequirementIds.push(req.id);\n\t}\n\n\tconst baseDecision = {\n\t\tgoalId: state.goalId,\n\t\tstallTurns: state.stallTurns,\n\t\tmaxStallTurns: args.settings.maxStallTurns,\n\t\topenRequirementIds,\n\t\tblockedRequirementIds,\n\t\tsatisfiedRequirementIds,\n\t};\n\n\tif (state.status === \"completed\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"finalize\",\n\t\t\treasonCode: \"goal_completed\",\n\t\t\tmessage: \"The goal is marked as completed.\",\n\t\t};\n\t}\n\n\tif (state.status === \"paused\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"stop\",\n\t\t\treasonCode: \"goal_paused\",\n\t\t\tmessage: \"The goal is paused by the owner.\",\n\t\t};\n\t}\n\n\tif (state.status === \"blocked\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"ask-user\",\n\t\t\treasonCode: \"goal_blocked\",\n\t\t\tmessage: \"The goal is explicitly blocked.\",\n\t\t};\n\t}\n\n\t// Semantic Circuit Breaker: check if any requirement has been repeatedly blocked.\n\t// If a requirement has failed verification / been blocked 3 or more times, the\n\t// subagent loop is stuck. Forcefully retire the goal to prevent infinite orchestrator looping.\n\tconst MAX_REQUIREMENT_BLOCKS = 3;\n\tfor (const reqId of blockedRequirementIds) {\n\t\tconst blockCount = state.events.filter((e) => e.type === \"block_requirement\" && e.id === reqId).length;\n\n\t\tif (blockCount >= MAX_REQUIREMENT_BLOCKS) {\n\t\t\treturn {\n\t\t\t\t...baseDecision,\n\t\t\t\taction: \"stop\",\n\t\t\t\treasonCode: \"stall_limit_reached\",\n\t\t\t\tmessage: `Circuit Breaker: Requirement '${reqId}' has been blocked ${blockCount} times (e.g. repeated verification failures). The task is stuck in a loop and requires human intervention.`,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (state.status === \"usage_limited\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"ask-user\",\n\t\t\treasonCode: \"goal_usage_limited\",\n\t\t\tmessage: \"The goal stopped after the active provider reached a usage limit.\",\n\t\t};\n\t}\n\n\tif (state.status === \"budget_limited\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"stop\",\n\t\t\treasonCode: \"goal_budget_limited\",\n\t\t\tmessage: \"The goal exhausted its configured budget.\",\n\t\t};\n\t}\n\n\tif (state.status === \"cancelled\") {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"stop\",\n\t\t\treasonCode: \"goal_cancelled\",\n\t\t\tmessage: \"The goal has been cancelled.\",\n\t\t};\n\t}\n\n\tif (openRequirementIds.length === 0) {\n\t\tif (blockedRequirementIds.length > 0) {\n\t\t\treturn {\n\t\t\t\t...baseDecision,\n\t\t\t\taction: \"ask-user\",\n\t\t\t\treasonCode: \"blocked_requirements_present\",\n\t\t\t\tmessage: \"All remaining legacy goal requirements are blocked.\",\n\t\t\t};\n\t\t}\n\t\tif (state.requirements.length === 0) {\n\t\t\treturn {\n\t\t\t\t...baseDecision,\n\t\t\t\taction: \"continue\",\n\t\t\t\treasonCode: \"goal_active\",\n\t\t\t\tmessage: \"The compact goal record is active.\",\n\t\t\t};\n\t\t}\n\t\tconst unprovenRequirementIds = getUnprovenGoalRequirementIds(state);\n\t\tif (unprovenRequirementIds.length > 0) {\n\t\t\treturn {\n\t\t\t\t...baseDecision,\n\t\t\t\taction: \"continue\",\n\t\t\t\treasonCode: \"acceptance_evidence_required\",\n\t\t\t\tmessage: `Requirement(s) ${unprovenRequirementIds.join(\", \")} still need trusted acceptance evidence.`,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"continue\",\n\t\t\treasonCode: \"goal_completion_required\",\n\t\t\tmessage: \"All requirements are proven. Mark the goal complete only after confirming no required work remains.\",\n\t\t};\n\t}\n\n\t// Worktree-sync directives take precedence over the \"waiting\" branch below: a worker whose bound\n\t// lane is conflicted or stale is NOT merely in-flight-and-quiet -- it needs an explicit directive\n\t// (resolve conflicts, or sync) delivered through the continuation prompt, and a stalled-but-stale\n\t// worker must never be left waiting indefinitely for a sync it was never told to run. Conflict is\n\t// checked first: a lane with a rebase already stopped on conflicts cannot usefully be told to\n\t// \"sync\" again (that lane's `sync_required` flag is never set while `rebaseInProgress` is true --\n\t// see `goal-runtime-snapshot.ts` -- so the two sets below are disjoint by construction, not by a\n\t// priority check here).\n\tconst laneSyncConflictLaneKeys = args.laneSyncConflictLaneKeys;\n\tconst conflictedRequirements = laneSyncConflictLaneKeys\n\t\t? state.requirements.filter(\n\t\t\t\t(requirement) =>\n\t\t\t\t\trequirement.status === \"open\" &&\n\t\t\t\t\trequirement.boundLaneId !== undefined &&\n\t\t\t\t\tlaneSyncConflictLaneKeys.has(requirement.boundLaneId),\n\t\t\t)\n\t\t: [];\n\tif (conflictedRequirements.length > 0) {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"continue\",\n\t\t\treasonCode: \"lane_sync_conflict\",\n\t\t\tmessage: `Requirement(s) ${conflictedRequirements.map((requirement) => requirement.id).join(\", \")} are bound to a worktree-sync lane with a rebase stopped on conflicts; resolve via worktree_sync action:\"continue\" (or \"abort_sync\") before this goal can progress further.`,\n\t\t};\n\t}\n\n\tconst syncRequiredLaneKeys = args.syncRequiredLaneKeys;\n\tconst syncRequiredRequirements = syncRequiredLaneKeys\n\t\t? state.requirements.filter(\n\t\t\t\t(requirement) =>\n\t\t\t\t\trequirement.status === \"open\" &&\n\t\t\t\t\trequirement.boundLaneId !== undefined &&\n\t\t\t\t\tsyncRequiredLaneKeys.has(requirement.boundLaneId),\n\t\t\t)\n\t\t: [];\n\tif (syncRequiredRequirements.length > 0) {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"continue\",\n\t\t\treasonCode: \"lane_sync_required\",\n\t\t\tmessage: `Requirement(s) ${syncRequiredRequirements.map((requirement) => requirement.id).join(\", \")} are bound to a worktree-sync lane that must rebase current main before further work; deliver worktree_sync action:\"sync\" to the bound worker, or run it directly for an idle lane.`,\n\t\t};\n\t}\n\n\t// A worker is dispatched (queued/running) against an open requirement this goal owns — wait\n\t// for it rather than submit a hollow pass or let the stall counter judge the goal unproductive.\n\t// Checked BEFORE the stall check so an in-flight worker always wins over an accumulated stall\n\t// count: the goal isn't stalled, it's actively being worked by something other than this loop.\n\tconst inFlightGoalLaneIds = args.inFlightGoalLaneIds;\n\tconst boundInFlightRequirements = inFlightGoalLaneIds\n\t\t? state.requirements.filter(\n\t\t\t\t(requirement) =>\n\t\t\t\t\trequirement.status === \"open\" &&\n\t\t\t\t\trequirement.boundLaneId !== undefined &&\n\t\t\t\t\tinFlightGoalLaneIds.has(requirement.boundLaneId),\n\t\t\t)\n\t\t: [];\n\n\tif (boundInFlightRequirements.length > 0) {\n\t\t// Never-hang backstop: a worker alive-but-hung past its deadline must escalate to the owner\n\t\t// instead of waiting forever. Only evaluated when the caller supplies BOTH a clock reading and\n\t\t// a deadline; escalates only once EVERY bound-in-flight requirement has individually timed out,\n\t\t// so one fresh binding keeps the goal legitimately waiting.\n\t\tif (args.now !== undefined && args.maxWorkerWaitMs !== undefined) {\n\t\t\tconst nowMs = Date.parse(args.now);\n\t\t\tconst maxWorkerWaitMs = args.maxWorkerWaitMs;\n\t\t\tconst allTimedOut =\n\t\t\t\tNumber.isFinite(nowMs) &&\n\t\t\t\tboundInFlightRequirements.every((requirement) => {\n\t\t\t\t\tif (requirement.boundAt === undefined) return false;\n\t\t\t\t\tconst boundAtMs = Date.parse(requirement.boundAt);\n\t\t\t\t\treturn Number.isFinite(boundAtMs) && boundAtMs + maxWorkerWaitMs <= nowMs;\n\t\t\t\t});\n\t\t\tif (allTimedOut) {\n\t\t\t\treturn {\n\t\t\t\t\t...baseDecision,\n\t\t\t\t\taction: \"ask-user\",\n\t\t\t\t\treasonCode: \"worker_wait_timeout\",\n\t\t\t\t\tmessage: `A dispatched worker has not completed within the maximum wait of ${maxWorkerWaitMs}ms; escalating to the owner instead of waiting indefinitely.`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"waiting\",\n\t\t\treasonCode: \"worker_in_flight\",\n\t\t\tmessage: \"A worker is dispatched against an open requirement; waiting for it to finish before continuing.\",\n\t\t};\n\t}\n\n\tif (args.settings.maxStallTurns > 0 && state.stallTurns >= args.settings.maxStallTurns) {\n\t\treturn {\n\t\t\t...baseDecision,\n\t\t\taction: \"ask-user\",\n\t\t\treasonCode: \"stall_limit_reached\",\n\t\t\tmessage: `The goal has reached the maximum stall limit of ${args.settings.maxStallTurns} turns.`,\n\t\t};\n\t}\n\n\treturn {\n\t\t...baseDecision,\n\t\taction: \"continue\",\n\t\treasonCode: \"goal_active\",\n\t\tmessage: \"The goal is active and making progress.\",\n\t};\n}\n"]}
|
|
@@ -74,6 +74,11 @@ export interface Requirement {
|
|
|
74
74
|
* later populates `"worker"`-kind evidence and prompts an explicit `satisfy_requirement` pass.
|
|
75
75
|
*/
|
|
76
76
|
boundLaneId?: string;
|
|
77
|
+
/**
|
|
78
|
+
* IDs of other requirements that must be satisfied before this requirement can be worked on.
|
|
79
|
+
* Implementing this native graph tracking allows the orchestrator to automatically sequence subagent delegations.
|
|
80
|
+
*/
|
|
81
|
+
dependencies?: readonly string[];
|
|
77
82
|
/**
|
|
78
83
|
* ISO timestamp of the moment `boundLaneId` was most recently bound to a REAL lane -- the clock
|
|
79
84
|
* the never-hang wait-timeout (`evaluateGoalContinuation`'s `worker_wait_timeout` reasonCode)
|
|
@@ -106,6 +111,7 @@ export type GoalEvent = {
|
|
|
106
111
|
type: "add_requirement";
|
|
107
112
|
id: string;
|
|
108
113
|
text: string;
|
|
114
|
+
dependencies?: readonly string[];
|
|
109
115
|
now: string;
|
|
110
116
|
} | {
|
|
111
117
|
type: "satisfy_requirement";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-state.d.ts","sourceRoot":"","sources":["../../../src/core/goals/goal-state.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"goal-state.d.ts","sourceRoot":"","sources":["../../../src/core/goals/goal-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -239,6 +239,7 @@ export function applyGoalEvent(state, event) {
|
|
|
239
239
|
text: event.text,
|
|
240
240
|
status: "open",
|
|
241
241
|
evidenceIds: [],
|
|
242
|
+
dependencies: event.dependencies,
|
|
242
243
|
createdAt: existingIndex >= 0 ? newState.requirements[existingIndex].createdAt : event.now,
|
|
243
244
|
updatedAt: event.now,
|
|
244
245
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-state.js","sourceRoot":"","sources":["../../../src/core/goals/goal-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { isPlainRecord } from \"../util/value-guards.ts\";\n\nexport type GoalStatus =\n\t| \"active\"\n\t| \"paused\"\n\t| \"blocked\"\n\t| \"usage_limited\"\n\t| \"budget_limited\"\n\t| \"completed\"\n\t| \"cancelled\";\nexport type RequirementStatus = \"open\" | \"satisfied\" | \"blocked\";\nexport type GoalEvidenceKind = \"file\" | \"test\" | \"tool\" | \"user\" | \"finding\" | \"worker\";\n\nexport const MAX_GOAL_OBJECTIVE_LENGTH = 4_000;\nexport const MAX_GOAL_EVENT_HISTORY = 128;\n\n/** One shared lifecycle classification for tools, runtime, persistence, and UI. */\nexport function isGoalExecutionActive(status: GoalStatus): boolean {\n\treturn status === \"active\";\n}\n\nexport function isGoalResumableStatus(status: GoalStatus): boolean {\n\treturn status === \"paused\" || status === \"blocked\" || status === \"usage_limited\";\n}\n\nexport function isGoalTerminalStatus(status: GoalStatus): boolean {\n\treturn status === \"completed\" || status === \"cancelled\" || status === \"budget_limited\";\n}\n\nexport function isGoalUnfinishedStatus(status: GoalStatus): boolean {\n\treturn status !== \"completed\" && status !== \"cancelled\";\n}\n\nexport interface GoalState {\n\tgoalId: string;\n\tuserGoal: string;\n\tstatus: GoalStatus;\n\t/** Monotonic state revision used by compare-and-append persistence. Legacy snapshots start at 0. */\n\trevision?: number;\n\t/** Monotonic meaningful-progress revision used by the continuation stall gate. */\n\tprogressRevision?: number;\n\t/** Optional owner-requested token ceiling. Charged usage is uncached input plus output. */\n\ttokenBudget?: number;\n\t/** Exact usage attributed to submitted goal-continuation turns. */\n\ttokensUsed?: number;\n\trequirements: readonly Requirement[];\n\tevidence: readonly GoalEvidenceRef[];\n\tevents: readonly GoalEvent[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tlastProgressAt: string;\n\tstallTurns: number;\n\tblockedReason?: string;\n\t/**\n\t * Cumulative continuation turns submitted for this goal across EVERY `continueGoalLoop`\n\t * invocation for its lifetime (idle-driven auto-continues and manual continues alike) —\n\t * durable via goal-state persistence, so it survives process restarts and idle cycles.\n\t * Optional because snapshots persisted before this field existed carry no value; treat\n\t * `undefined` as `0` everywhere it is read.\n\t */\n\tcontinuationTurnsUsed?: number;\n\t/**\n\t * Observed cumulative ACTIVE wall-clock milliseconds spent running continuation passes for this goal —\n\t * the sum of each individual pass's own await duration, NOT wall-clock time elapsed between\n\t * passes or during idle gaps. Same backward-compat/undefined-as-0 note as `continuationTurnsUsed`.\n\t */\n\tcontinuationWallClockMs?: number;\n\t/**\n\t * Observed cumulative USD attributed to this goal's own continuation passes from assistant messages\n\t * appended within each pass's captured branch interval. Deliberately excludes worker/subagent spend,\n\t * which is reported separately. Same backward-compat note.\n\t */\n\tcontinuationSpendUsd?: number;\n\t/**\n\t * Observed cumulative USD attributed to WORKER/SUBAGENT spend for this goal's lanes (in-process worker\n\t * usage via `addSpawnedUsage`, out-of-process tmux-worker usage via the advisory\n\t * `reportSpawnedUsage` claim) — the counterpart this goal's OWN model spend excludes (see\n\t * {@link continuationSpendUsd}). Populated by the runtime that sums lane spend by goalId; this\n\t * field is only the durable slot. Same backward-compat/undefined-as-0 note as the other\n\t * continuation accounting fields. This is advisory telemetry, not an implicit execution limit.\n\t */\n\tcontinuationWorkerSpendUsd?: number;\n\t/** Durable acceptance override; avoids depending on an unbounded historical event scan. */\n\tacceptanceOverride?: boolean;\n}\n\nexport interface Requirement {\n\tid: string;\n\ttext: string;\n\tstatus: RequirementStatus;\n\tevidenceIds: readonly string[];\n\tblockedReason?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\t/**\n\t * LaneId of a worker dispatched against this requirement (set by the `dispatch_worker` event).\n\t * Recording a binding never satisfies the requirement by itself -- the worker's own completion\n\t * later populates `\"worker\"`-kind evidence and prompts an explicit `satisfy_requirement` pass.\n\t */\n\tboundLaneId?: string;\n\t/**\n\t * ISO timestamp of the moment `boundLaneId` was most recently bound to a REAL lane -- the clock\n\t * the never-hang wait-timeout (`evaluateGoalContinuation`'s `worker_wait_timeout` reasonCode)\n\t * reads to detect a worker that has hung past `maxWorkerWaitMs`. Stamped ONLY when a\n\t * `dispatch_worker` event carries a lane id; a declined dispatch (no lane) leaves this field\n\t * untouched, so no clock starts for a worker that never actually launched.\n\t */\n\tboundAt?: string;\n}\n\nexport interface GoalEvidenceRef {\n\tid: string;\n\tkind: GoalEvidenceKind;\n\tsummary: string;\n\turi?: string;\n\t/**\n\t * Whether `uri` was checked against session records (\"tool\" evidence, a toolCallId) or the\n\t * filesystem (\"file\" evidence, a path) at add_evidence time. `true`/`false` only when the\n\t * ref was checkable; `undefined` when the evidence kind carries no checkable ref (e.g.\n\t * \"user\"/\"finding\"/\"test\", or a \"tool\"/\"file\" entry with no `uri`).\n\t */\n\tverified?: boolean;\n\tcreatedAt: string;\n}\n\nexport type GoalEvent =\n\t| { type: \"edit_goal\"; userGoal: string; tokenBudget?: number; now: string }\n\t| { type: \"add_requirement\"; id: string; text: string; now: string }\n\t| { type: \"satisfy_requirement\"; id: string; evidenceIds: readonly string[]; now: string }\n\t| { type: \"block_requirement\"; id: string; blockedReason: string; now: string }\n\t| { type: \"reopen_requirement\"; id: string; now: string }\n\t| {\n\t\t\ttype: \"dispatch_worker\";\n\t\t\t/** Requirement id the worker is bound to. */\n\t\t\tid: string;\n\t\t\t/** Instructions the worker was (or will be) dispatched with. */\n\t\t\tinstructions: string;\n\t\t\t/**\n\t\t\t * LaneId returned by the tool-layer dispatch side effect. Undefined when that side effect\n\t\t\t * is unwired/stubbed -- the binding is then recorded with no lane target yet.\n\t\t\t */\n\t\t\tlaneId?: string;\n\t\t\tnow: string;\n\t }\n\t| {\n\t\t\ttype: \"add_evidence\";\n\t\t\tid: string;\n\t\t\tkind: GoalEvidenceKind;\n\t\t\tsummary: string;\n\t\t\turi?: string;\n\t\t\t/** See {@link GoalEvidenceRef.verified}; computed by the tool layer before the event is applied. */\n\t\t\tverified?: boolean;\n\t\t\tnow: string;\n\t }\n\t| { type: \"progress\"; now: string }\n\t| { type: \"no_progress\"; now: string }\n\t| {\n\t\t\ttype: \"record_continuation_budget\";\n\t\t\t/** Turns submitted in this pass (currently always 1 — the loop calls once per submitted pass). */\n\t\t\tturns: number;\n\t\t\t/** This pass's own active wall-clock duration, in milliseconds. */\n\t\t\twallClockMs: number;\n\t\t\t/** Exact uncached input + output tokens produced after this pass's session-entry cursor. */\n\t\t\ttokens: number;\n\t\t\t/** Exact model spend produced after this pass's session-entry cursor. */\n\t\t\tspendUsd: number;\n\t\t\tnow: string;\n\t }\n\t| { type: \"complete_goal\"; acceptanceOverride?: boolean; now: string }\n\t| { type: \"complete_goal_manually\"; now: string }\n\t| { type: \"block_goal\"; reason: string; now: string }\n\t| { type: \"pause_goal\"; now: string }\n\t| { type: \"resume_goal\"; now: string }\n\t| { type: \"system_stop_goal\"; status: \"blocked\" | \"usage_limited\" | \"budget_limited\"; reason: string; now: string }\n\t| { type: \"cancel_goal\"; now: string };\n\nfunction isStringArray(value: unknown): value is readonly string[] {\n\treturn Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction isGoalStatus(value: unknown): value is GoalStatus {\n\treturn (\n\t\tvalue === \"active\" ||\n\t\tvalue === \"paused\" ||\n\t\tvalue === \"blocked\" ||\n\t\tvalue === \"usage_limited\" ||\n\t\tvalue === \"budget_limited\" ||\n\t\tvalue === \"completed\" ||\n\t\tvalue === \"cancelled\"\n\t);\n}\n\nfunction isRequirementStatus(value: unknown): value is RequirementStatus {\n\treturn value === \"open\" || value === \"satisfied\" || value === \"blocked\";\n}\n\nfunction isGoalEvidenceKind(value: unknown): value is GoalEvidenceKind {\n\treturn (\n\t\tvalue === \"file\" ||\n\t\tvalue === \"test\" ||\n\t\tvalue === \"tool\" ||\n\t\tvalue === \"user\" ||\n\t\tvalue === \"finding\" ||\n\t\tvalue === \"worker\"\n\t);\n}\n\nfunction hasOptionalString(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || typeof record[key] === \"string\";\n}\n\nfunction hasOptionalBoolean(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || typeof record[key] === \"boolean\";\n}\n\nfunction hasOptionalFiniteNumber(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || (typeof record[key] === \"number\" && Number.isFinite(record[key]));\n}\n\nfunction isRequirement(value: unknown): value is Requirement {\n\tif (!isPlainRecord(value)) return false;\n\treturn (\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.text === \"string\" &&\n\t\tisRequirementStatus(value.status) &&\n\t\tisStringArray(value.evidenceIds) &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\ttypeof value.updatedAt === \"string\" &&\n\t\thasOptionalString(value, \"blockedReason\") &&\n\t\thasOptionalString(value, \"boundLaneId\") &&\n\t\thasOptionalString(value, \"boundAt\")\n\t);\n}\n\nfunction isGoalEvidenceRef(value: unknown): value is GoalEvidenceRef {\n\tif (!isPlainRecord(value)) return false;\n\treturn (\n\t\ttypeof value.id === \"string\" &&\n\t\tisGoalEvidenceKind(value.kind) &&\n\t\ttypeof value.summary === \"string\" &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\thasOptionalString(value, \"uri\") &&\n\t\thasOptionalBoolean(value, \"verified\")\n\t);\n}\n\nexport function isGoalEvent(value: unknown): value is GoalEvent {\n\tif (!isPlainRecord(value) || typeof value.type !== \"string\" || typeof value.now !== \"string\") return false;\n\tswitch (value.type) {\n\t\tcase \"edit_goal\":\n\t\t\treturn typeof value.userGoal === \"string\" && hasOptionalFiniteNumber(value, \"tokenBudget\");\n\t\tcase \"add_requirement\":\n\t\t\treturn typeof value.id === \"string\" && typeof value.text === \"string\";\n\t\tcase \"satisfy_requirement\":\n\t\t\treturn typeof value.id === \"string\" && isStringArray(value.evidenceIds);\n\t\tcase \"block_requirement\":\n\t\t\treturn typeof value.id === \"string\" && typeof value.blockedReason === \"string\";\n\t\tcase \"reopen_requirement\":\n\t\t\treturn typeof value.id === \"string\";\n\t\tcase \"dispatch_worker\":\n\t\t\treturn (\n\t\t\t\ttypeof value.id === \"string\" && typeof value.instructions === \"string\" && hasOptionalString(value, \"laneId\")\n\t\t\t);\n\t\tcase \"add_evidence\":\n\t\t\treturn (\n\t\t\t\ttypeof value.id === \"string\" &&\n\t\t\t\tisGoalEvidenceKind(value.kind) &&\n\t\t\t\ttypeof value.summary === \"string\" &&\n\t\t\t\thasOptionalString(value, \"uri\") &&\n\t\t\t\thasOptionalBoolean(value, \"verified\")\n\t\t\t);\n\t\tcase \"progress\":\n\t\tcase \"no_progress\":\n\t\t\treturn true;\n\t\tcase \"complete_goal\":\n\t\t\treturn hasOptionalBoolean(value, \"acceptanceOverride\");\n\t\tcase \"complete_goal_manually\":\n\t\tcase \"pause_goal\":\n\t\tcase \"resume_goal\":\n\t\tcase \"cancel_goal\":\n\t\t\treturn true;\n\t\tcase \"block_goal\":\n\t\t\treturn typeof value.reason === \"string\";\n\t\tcase \"system_stop_goal\":\n\t\t\treturn (\n\t\t\t\t(value.status === \"blocked\" || value.status === \"usage_limited\" || value.status === \"budget_limited\") &&\n\t\t\t\ttypeof value.reason === \"string\"\n\t\t\t);\n\t\tcase \"record_continuation_budget\":\n\t\t\treturn (\n\t\t\t\ttypeof value.turns === \"number\" &&\n\t\t\t\tNumber.isFinite(value.turns) &&\n\t\t\t\ttypeof value.wallClockMs === \"number\" &&\n\t\t\t\tNumber.isFinite(value.wallClockMs) &&\n\t\t\t\ttypeof value.tokens === \"number\" &&\n\t\t\t\tNumber.isFinite(value.tokens) &&\n\t\t\t\ttypeof value.spendUsd === \"number\" &&\n\t\t\t\tNumber.isFinite(value.spendUsd)\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nexport function isGoalState(value: unknown): value is GoalState {\n\tif (!isPlainRecord(value)) return false;\n\treturn (\n\t\ttypeof value.goalId === \"string\" &&\n\t\ttypeof value.userGoal === \"string\" &&\n\t\tisGoalStatus(value.status) &&\n\t\thasOptionalFiniteNumber(value, \"revision\") &&\n\t\thasOptionalFiniteNumber(value, \"progressRevision\") &&\n\t\thasOptionalFiniteNumber(value, \"tokenBudget\") &&\n\t\thasOptionalFiniteNumber(value, \"tokensUsed\") &&\n\t\tArray.isArray(value.requirements) &&\n\t\tvalue.requirements.every(isRequirement) &&\n\t\tArray.isArray(value.evidence) &&\n\t\tvalue.evidence.every(isGoalEvidenceRef) &&\n\t\tArray.isArray(value.events) &&\n\t\tvalue.events.every(isGoalEvent) &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\ttypeof value.updatedAt === \"string\" &&\n\t\ttypeof value.lastProgressAt === \"string\" &&\n\t\ttypeof value.stallTurns === \"number\" &&\n\t\tNumber.isFinite(value.stallTurns) &&\n\t\thasOptionalString(value, \"blockedReason\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationTurnsUsed\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationWallClockMs\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationSpendUsd\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationWorkerSpendUsd\") &&\n\t\thasOptionalBoolean(value, \"acceptanceOverride\")\n\t);\n}\n\nfunction cloneRequirement(requirement: Requirement): Requirement {\n\treturn {\n\t\t...requirement,\n\t\tevidenceIds: [...requirement.evidenceIds],\n\t};\n}\n\nfunction cloneGoalEvidenceRef(evidence: GoalEvidenceRef): GoalEvidenceRef {\n\treturn { ...evidence };\n}\n\nfunction cloneGoalEvent(event: GoalEvent): GoalEvent {\n\tif (event.type === \"satisfy_requirement\") {\n\t\treturn { ...event, evidenceIds: [...event.evidenceIds] };\n\t}\n\treturn { ...event };\n}\n\nexport function cloneGoalEventForStorage(event: GoalEvent): GoalEvent {\n\treturn cloneGoalEvent(event);\n}\n\nfunction cloneGoalState(state: GoalState): GoalState {\n\treturn {\n\t\t...state,\n\t\trequirements: state.requirements.map(cloneRequirement),\n\t\tevidence: state.evidence.map(cloneGoalEvidenceRef),\n\t\tevents: state.events.map(cloneGoalEvent),\n\t};\n}\n\nexport function cloneGoalStateForStorage(state: GoalState): GoalState {\n\treturn cloneGoalState(state);\n}\n\nexport function createGoalState(args: {\n\tgoalId: string;\n\tuserGoal: string;\n\tnow: string;\n\ttokenBudget?: number;\n}): GoalState {\n\treturn {\n\t\tgoalId: args.goalId,\n\t\tuserGoal: args.userGoal,\n\t\tstatus: \"active\",\n\t\trevision: 0,\n\t\tprogressRevision: 0,\n\t\ttokensUsed: 0,\n\t\t...(args.tokenBudget !== undefined ? { tokenBudget: args.tokenBudget } : {}),\n\t\trequirements: [],\n\t\tevidence: [],\n\t\tevents: [],\n\t\tcreatedAt: args.now,\n\t\tupdatedAt: args.now,\n\t\tlastProgressAt: args.now,\n\t\tstallTurns: 0,\n\t\tcontinuationTurnsUsed: 0,\n\t\tcontinuationWallClockMs: 0,\n\t\tcontinuationSpendUsd: 0,\n\t\tcontinuationWorkerSpendUsd: 0,\n\t};\n}\n\nfunction updateRequirement(state: GoalState, id: string, update: (requirement: Requirement) => Requirement): void {\n\tconst index = state.requirements.findIndex((requirement) => requirement.id === id);\n\tif (index < 0) return;\n\tconst requirements = [...state.requirements];\n\trequirements[index] = update(requirements[index]);\n\tstate.requirements = requirements;\n}\n\nexport function applyGoalEvent(state: GoalState, event: GoalEvent): GoalState {\n\tconst newState: GoalState = {\n\t\t...state,\n\t\trevision: (state.revision ?? 0) + 1,\n\t\trequirements: state.requirements.map(cloneRequirement),\n\t\tevidence: state.evidence.map(cloneGoalEvidenceRef),\n\t\tevents: [...state.events.map(cloneGoalEvent), cloneGoalEvent(event)].slice(-MAX_GOAL_EVENT_HISTORY),\n\t\tupdatedAt: event.now,\n\t};\n\n\tswitch (event.type) {\n\t\tcase \"edit_goal\": {\n\t\t\tnewState.userGoal = event.userGoal;\n\t\t\tif (event.tokenBudget !== undefined) newState.tokenBudget = event.tokenBudget;\n\t\t\tif (state.status === \"completed\") newState.status = \"active\";\n\t\t\tif (\n\t\t\t\tstate.status === \"budget_limited\" &&\n\t\t\t\tevent.tokenBudget !== undefined &&\n\t\t\t\tevent.tokenBudget > (state.tokensUsed ?? 0)\n\t\t\t) {\n\t\t\t\tnewState.status = \"active\";\n\t\t\t}\n\t\t\tif (newState.status === \"active\") newState.blockedReason = undefined;\n\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"add_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tconst newRequirement: Requirement = {\n\t\t\t\tid: event.id,\n\t\t\t\ttext: event.text,\n\t\t\t\tstatus: \"open\",\n\t\t\t\tevidenceIds: [],\n\t\t\t\tcreatedAt: existingIndex >= 0 ? newState.requirements[existingIndex].createdAt : event.now,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t};\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = newRequirement;\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t} else {\n\t\t\t\tnewState.requirements = [...newState.requirements, newRequirement];\n\t\t\t}\n\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"satisfy_requirement\": {\n\t\t\tupdateRequirement(newState, event.id, (requirement) => ({\n\t\t\t\t...requirement,\n\t\t\t\tstatus: \"satisfied\",\n\t\t\t\tevidenceIds: [...event.evidenceIds],\n\t\t\t\tupdatedAt: event.now,\n\t\t\t\tblockedReason: undefined,\n\t\t\t}));\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"block_requirement\": {\n\t\t\tupdateRequirement(newState, event.id, (requirement) => ({\n\t\t\t\t...requirement,\n\t\t\t\tstatus: \"blocked\",\n\t\t\t\tblockedReason: event.blockedReason,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t}));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"reopen_requirement\": {\n\t\t\tupdateRequirement(newState, event.id, (requirement) => ({\n\t\t\t\t...requirement,\n\t\t\t\tstatus: \"open\",\n\t\t\t\tblockedReason: undefined,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t}));\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"dispatch_worker\": {\n\t\t\t// Records the requirement<->lane binding ONLY -- never satisfies the requirement and never\n\t\t\t// touches lastProgressAt/stallTurns. The worker's own completion later populates \"worker\"\n\t\t\t// evidence and prompts an explicit satisfy_requirement pass through the existing gate.\n\t\t\tupdateRequirement(newState, event.id, (requirement) => ({\n\t\t\t\t...requirement,\n\t\t\t\tboundLaneId: event.laneId,\n\t\t\t\t// Start (or keep) the wait-timeout clock ONLY when this dispatch actually bound a real\n\t\t\t\t// lane -- a declined dispatch (no laneId) preserves whatever boundAt was already there.\n\t\t\t\tboundAt: event.laneId ? event.now : requirement.boundAt,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t}));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"add_evidence\": {\n\t\t\tconst existingIndex = newState.evidence.findIndex((evidence) => evidence.id === event.id);\n\t\t\tconst newEvidence: GoalEvidenceRef = {\n\t\t\t\tid: event.id,\n\t\t\t\tkind: event.kind,\n\t\t\t\tsummary: event.summary,\n\t\t\t\turi: event.uri,\n\t\t\t\tverified: event.verified,\n\t\t\t\tcreatedAt: existingIndex >= 0 ? newState.evidence[existingIndex].createdAt : event.now,\n\t\t\t};\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst updatedEvidence = [...newState.evidence];\n\t\t\t\tupdatedEvidence[existingIndex] = newEvidence;\n\t\t\t\tnewState.evidence = updatedEvidence;\n\t\t\t} else {\n\t\t\t\tnewState.evidence = [...newState.evidence, newEvidence];\n\t\t\t}\n\t\t\tif (event.kind === \"user\" || event.verified === true) {\n\t\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"progress\": {\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"no_progress\": {\n\t\t\tnewState.stallTurns = state.stallTurns + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"record_continuation_budget\": {\n\t\t\tnewState.continuationTurnsUsed = (state.continuationTurnsUsed ?? 0) + event.turns;\n\t\t\tnewState.continuationWallClockMs = (state.continuationWallClockMs ?? 0) + event.wallClockMs;\n\t\t\tnewState.continuationSpendUsd = (state.continuationSpendUsd ?? 0) + Math.max(0, event.spendUsd);\n\t\t\tnewState.tokensUsed = (state.tokensUsed ?? 0) + Math.max(0, event.tokens);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"complete_goal\": {\n\t\t\tconst hasUnsatisfied = newState.requirements.some((requirement) => requirement.status !== \"satisfied\");\n\t\t\tif (!hasUnsatisfied) {\n\t\t\t\tnewState.status = \"completed\";\n\t\t\t\tnewState.blockedReason = undefined;\n\t\t\t\tnewState.acceptanceOverride = event.acceptanceOverride;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"complete_goal_manually\": {\n\t\t\tnewState.status = \"completed\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tnewState.acceptanceOverride = true;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"block_goal\": {\n\t\t\tnewState.status = \"blocked\";\n\t\t\tnewState.blockedReason = event.reason;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"pause_goal\": {\n\t\t\tnewState.status = \"paused\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"resume_goal\": {\n\t\t\tnewState.status = \"active\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"system_stop_goal\": {\n\t\t\tnewState.status = event.status;\n\t\t\tnewState.blockedReason = event.reason;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"cancel_goal\": {\n\t\t\tnewState.status = \"cancelled\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn newState;\n}\n\nexport function shouldContinueGoalLoop(args: { state: GoalState; maxStallTurns: number; now: string }): boolean {\n\tif (!isGoalExecutionActive(args.state.status)) {\n\t\treturn false;\n\t}\n\tif (args.state.stallTurns >= args.maxStallTurns) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nexport function serializeGoalState(state: GoalState): string {\n\treturn JSON.stringify(cloneGoalState(state), null, 2);\n}\n\nexport function parseGoalState(text: string): GoalState | undefined {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(text);\n\t\tif (!isGoalState(parsed)) return undefined;\n\t\treturn cloneGoalState(parsed);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"goal-state.js","sourceRoot":"","sources":["../../../src/core/goals/goal-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { isPlainRecord } from \"../util/value-guards.ts\";\n\nexport type GoalStatus =\n\t| \"active\"\n\t| \"paused\"\n\t| \"blocked\"\n\t| \"usage_limited\"\n\t| \"budget_limited\"\n\t| \"completed\"\n\t| \"cancelled\";\nexport type RequirementStatus = \"open\" | \"satisfied\" | \"blocked\";\nexport type GoalEvidenceKind = \"file\" | \"test\" | \"tool\" | \"user\" | \"finding\" | \"worker\";\n\nexport const MAX_GOAL_OBJECTIVE_LENGTH = 4_000;\nexport const MAX_GOAL_EVENT_HISTORY = 128;\n\n/** One shared lifecycle classification for tools, runtime, persistence, and UI. */\nexport function isGoalExecutionActive(status: GoalStatus): boolean {\n\treturn status === \"active\";\n}\n\nexport function isGoalResumableStatus(status: GoalStatus): boolean {\n\treturn status === \"paused\" || status === \"blocked\" || status === \"usage_limited\";\n}\n\nexport function isGoalTerminalStatus(status: GoalStatus): boolean {\n\treturn status === \"completed\" || status === \"cancelled\" || status === \"budget_limited\";\n}\n\nexport function isGoalUnfinishedStatus(status: GoalStatus): boolean {\n\treturn status !== \"completed\" && status !== \"cancelled\";\n}\n\nexport interface GoalState {\n\tgoalId: string;\n\tuserGoal: string;\n\tstatus: GoalStatus;\n\t/** Monotonic state revision used by compare-and-append persistence. Legacy snapshots start at 0. */\n\trevision?: number;\n\t/** Monotonic meaningful-progress revision used by the continuation stall gate. */\n\tprogressRevision?: number;\n\t/** Optional owner-requested token ceiling. Charged usage is uncached input plus output. */\n\ttokenBudget?: number;\n\t/** Exact usage attributed to submitted goal-continuation turns. */\n\ttokensUsed?: number;\n\trequirements: readonly Requirement[];\n\tevidence: readonly GoalEvidenceRef[];\n\tevents: readonly GoalEvent[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tlastProgressAt: string;\n\tstallTurns: number;\n\tblockedReason?: string;\n\t/**\n\t * Cumulative continuation turns submitted for this goal across EVERY `continueGoalLoop`\n\t * invocation for its lifetime (idle-driven auto-continues and manual continues alike) —\n\t * durable via goal-state persistence, so it survives process restarts and idle cycles.\n\t * Optional because snapshots persisted before this field existed carry no value; treat\n\t * `undefined` as `0` everywhere it is read.\n\t */\n\tcontinuationTurnsUsed?: number;\n\t/**\n\t * Observed cumulative ACTIVE wall-clock milliseconds spent running continuation passes for this goal —\n\t * the sum of each individual pass's own await duration, NOT wall-clock time elapsed between\n\t * passes or during idle gaps. Same backward-compat/undefined-as-0 note as `continuationTurnsUsed`.\n\t */\n\tcontinuationWallClockMs?: number;\n\t/**\n\t * Observed cumulative USD attributed to this goal's own continuation passes from assistant messages\n\t * appended within each pass's captured branch interval. Deliberately excludes worker/subagent spend,\n\t * which is reported separately. Same backward-compat note.\n\t */\n\tcontinuationSpendUsd?: number;\n\t/**\n\t * Observed cumulative USD attributed to WORKER/SUBAGENT spend for this goal's lanes (in-process worker\n\t * usage via `addSpawnedUsage`, out-of-process tmux-worker usage via the advisory\n\t * `reportSpawnedUsage` claim) — the counterpart this goal's OWN model spend excludes (see\n\t * {@link continuationSpendUsd}). Populated by the runtime that sums lane spend by goalId; this\n\t * field is only the durable slot. Same backward-compat/undefined-as-0 note as the other\n\t * continuation accounting fields. This is advisory telemetry, not an implicit execution limit.\n\t */\n\tcontinuationWorkerSpendUsd?: number;\n\t/** Durable acceptance override; avoids depending on an unbounded historical event scan. */\n\tacceptanceOverride?: boolean;\n}\n\nexport interface Requirement {\n\tid: string;\n\ttext: string;\n\tstatus: RequirementStatus;\n\tevidenceIds: readonly string[];\n\tblockedReason?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\t/**\n\t * LaneId of a worker dispatched against this requirement (set by the `dispatch_worker` event).\n\t * Recording a binding never satisfies the requirement by itself -- the worker's own completion\n\t * later populates `\"worker\"`-kind evidence and prompts an explicit `satisfy_requirement` pass.\n\t */\n\tboundLaneId?: string;\n\t/**\n\t * IDs of other requirements that must be satisfied before this requirement can be worked on.\n\t * Implementing this native graph tracking allows the orchestrator to automatically sequence subagent delegations.\n\t */\n\tdependencies?: readonly string[];\n\t/**\n\t * ISO timestamp of the moment `boundLaneId` was most recently bound to a REAL lane -- the clock\n\t * the never-hang wait-timeout (`evaluateGoalContinuation`'s `worker_wait_timeout` reasonCode)\n\t * reads to detect a worker that has hung past `maxWorkerWaitMs`. Stamped ONLY when a\n\t * `dispatch_worker` event carries a lane id; a declined dispatch (no lane) leaves this field\n\t * untouched, so no clock starts for a worker that never actually launched.\n\t */\n\tboundAt?: string;\n}\n\nexport interface GoalEvidenceRef {\n\tid: string;\n\tkind: GoalEvidenceKind;\n\tsummary: string;\n\turi?: string;\n\t/**\n\t * Whether `uri` was checked against session records (\"tool\" evidence, a toolCallId) or the\n\t * filesystem (\"file\" evidence, a path) at add_evidence time. `true`/`false` only when the\n\t * ref was checkable; `undefined` when the evidence kind carries no checkable ref (e.g.\n\t * \"user\"/\"finding\"/\"test\", or a \"tool\"/\"file\" entry with no `uri`).\n\t */\n\tverified?: boolean;\n\tcreatedAt: string;\n}\n\nexport type GoalEvent =\n\t| { type: \"edit_goal\"; userGoal: string; tokenBudget?: number; now: string }\n\t| { type: \"add_requirement\"; id: string; text: string; dependencies?: readonly string[]; now: string }\n\t| { type: \"satisfy_requirement\"; id: string; evidenceIds: readonly string[]; now: string }\n\t| { type: \"block_requirement\"; id: string; blockedReason: string; now: string }\n\t| { type: \"reopen_requirement\"; id: string; now: string }\n\t| {\n\t\t\ttype: \"dispatch_worker\";\n\t\t\t/** Requirement id the worker is bound to. */\n\t\t\tid: string;\n\t\t\t/** Instructions the worker was (or will be) dispatched with. */\n\t\t\tinstructions: string;\n\t\t\t/**\n\t\t\t * LaneId returned by the tool-layer dispatch side effect. Undefined when that side effect\n\t\t\t * is unwired/stubbed -- the binding is then recorded with no lane target yet.\n\t\t\t */\n\t\t\tlaneId?: string;\n\t\t\tnow: string;\n\t }\n\t| {\n\t\t\ttype: \"add_evidence\";\n\t\t\tid: string;\n\t\t\tkind: GoalEvidenceKind;\n\t\t\tsummary: string;\n\t\t\turi?: string;\n\t\t\t/** See {@link GoalEvidenceRef.verified}; computed by the tool layer before the event is applied. */\n\t\t\tverified?: boolean;\n\t\t\tnow: string;\n\t }\n\t| { type: \"progress\"; now: string }\n\t| { type: \"no_progress\"; now: string }\n\t| {\n\t\t\ttype: \"record_continuation_budget\";\n\t\t\t/** Turns submitted in this pass (currently always 1 — the loop calls once per submitted pass). */\n\t\t\tturns: number;\n\t\t\t/** This pass's own active wall-clock duration, in milliseconds. */\n\t\t\twallClockMs: number;\n\t\t\t/** Exact uncached input + output tokens produced after this pass's session-entry cursor. */\n\t\t\ttokens: number;\n\t\t\t/** Exact model spend produced after this pass's session-entry cursor. */\n\t\t\tspendUsd: number;\n\t\t\tnow: string;\n\t }\n\t| { type: \"complete_goal\"; acceptanceOverride?: boolean; now: string }\n\t| { type: \"complete_goal_manually\"; now: string }\n\t| { type: \"block_goal\"; reason: string; now: string }\n\t| { type: \"pause_goal\"; now: string }\n\t| { type: \"resume_goal\"; now: string }\n\t| { type: \"system_stop_goal\"; status: \"blocked\" | \"usage_limited\" | \"budget_limited\"; reason: string; now: string }\n\t| { type: \"cancel_goal\"; now: string };\n\nfunction isStringArray(value: unknown): value is readonly string[] {\n\treturn Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction isGoalStatus(value: unknown): value is GoalStatus {\n\treturn (\n\t\tvalue === \"active\" ||\n\t\tvalue === \"paused\" ||\n\t\tvalue === \"blocked\" ||\n\t\tvalue === \"usage_limited\" ||\n\t\tvalue === \"budget_limited\" ||\n\t\tvalue === \"completed\" ||\n\t\tvalue === \"cancelled\"\n\t);\n}\n\nfunction isRequirementStatus(value: unknown): value is RequirementStatus {\n\treturn value === \"open\" || value === \"satisfied\" || value === \"blocked\";\n}\n\nfunction isGoalEvidenceKind(value: unknown): value is GoalEvidenceKind {\n\treturn (\n\t\tvalue === \"file\" ||\n\t\tvalue === \"test\" ||\n\t\tvalue === \"tool\" ||\n\t\tvalue === \"user\" ||\n\t\tvalue === \"finding\" ||\n\t\tvalue === \"worker\"\n\t);\n}\n\nfunction hasOptionalString(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || typeof record[key] === \"string\";\n}\n\nfunction hasOptionalBoolean(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || typeof record[key] === \"boolean\";\n}\n\nfunction hasOptionalFiniteNumber(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || (typeof record[key] === \"number\" && Number.isFinite(record[key]));\n}\n\nfunction isRequirement(value: unknown): value is Requirement {\n\tif (!isPlainRecord(value)) return false;\n\treturn (\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.text === \"string\" &&\n\t\tisRequirementStatus(value.status) &&\n\t\tisStringArray(value.evidenceIds) &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\ttypeof value.updatedAt === \"string\" &&\n\t\thasOptionalString(value, \"blockedReason\") &&\n\t\thasOptionalString(value, \"boundLaneId\") &&\n\t\thasOptionalString(value, \"boundAt\")\n\t);\n}\n\nfunction isGoalEvidenceRef(value: unknown): value is GoalEvidenceRef {\n\tif (!isPlainRecord(value)) return false;\n\treturn (\n\t\ttypeof value.id === \"string\" &&\n\t\tisGoalEvidenceKind(value.kind) &&\n\t\ttypeof value.summary === \"string\" &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\thasOptionalString(value, \"uri\") &&\n\t\thasOptionalBoolean(value, \"verified\")\n\t);\n}\n\nexport function isGoalEvent(value: unknown): value is GoalEvent {\n\tif (!isPlainRecord(value) || typeof value.type !== \"string\" || typeof value.now !== \"string\") return false;\n\tswitch (value.type) {\n\t\tcase \"edit_goal\":\n\t\t\treturn typeof value.userGoal === \"string\" && hasOptionalFiniteNumber(value, \"tokenBudget\");\n\t\tcase \"add_requirement\":\n\t\t\treturn typeof value.id === \"string\" && typeof value.text === \"string\";\n\t\tcase \"satisfy_requirement\":\n\t\t\treturn typeof value.id === \"string\" && isStringArray(value.evidenceIds);\n\t\tcase \"block_requirement\":\n\t\t\treturn typeof value.id === \"string\" && typeof value.blockedReason === \"string\";\n\t\tcase \"reopen_requirement\":\n\t\t\treturn typeof value.id === \"string\";\n\t\tcase \"dispatch_worker\":\n\t\t\treturn (\n\t\t\t\ttypeof value.id === \"string\" && typeof value.instructions === \"string\" && hasOptionalString(value, \"laneId\")\n\t\t\t);\n\t\tcase \"add_evidence\":\n\t\t\treturn (\n\t\t\t\ttypeof value.id === \"string\" &&\n\t\t\t\tisGoalEvidenceKind(value.kind) &&\n\t\t\t\ttypeof value.summary === \"string\" &&\n\t\t\t\thasOptionalString(value, \"uri\") &&\n\t\t\t\thasOptionalBoolean(value, \"verified\")\n\t\t\t);\n\t\tcase \"progress\":\n\t\tcase \"no_progress\":\n\t\t\treturn true;\n\t\tcase \"complete_goal\":\n\t\t\treturn hasOptionalBoolean(value, \"acceptanceOverride\");\n\t\tcase \"complete_goal_manually\":\n\t\tcase \"pause_goal\":\n\t\tcase \"resume_goal\":\n\t\tcase \"cancel_goal\":\n\t\t\treturn true;\n\t\tcase \"block_goal\":\n\t\t\treturn typeof value.reason === \"string\";\n\t\tcase \"system_stop_goal\":\n\t\t\treturn (\n\t\t\t\t(value.status === \"blocked\" || value.status === \"usage_limited\" || value.status === \"budget_limited\") &&\n\t\t\t\ttypeof value.reason === \"string\"\n\t\t\t);\n\t\tcase \"record_continuation_budget\":\n\t\t\treturn (\n\t\t\t\ttypeof value.turns === \"number\" &&\n\t\t\t\tNumber.isFinite(value.turns) &&\n\t\t\t\ttypeof value.wallClockMs === \"number\" &&\n\t\t\t\tNumber.isFinite(value.wallClockMs) &&\n\t\t\t\ttypeof value.tokens === \"number\" &&\n\t\t\t\tNumber.isFinite(value.tokens) &&\n\t\t\t\ttypeof value.spendUsd === \"number\" &&\n\t\t\t\tNumber.isFinite(value.spendUsd)\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nexport function isGoalState(value: unknown): value is GoalState {\n\tif (!isPlainRecord(value)) return false;\n\treturn (\n\t\ttypeof value.goalId === \"string\" &&\n\t\ttypeof value.userGoal === \"string\" &&\n\t\tisGoalStatus(value.status) &&\n\t\thasOptionalFiniteNumber(value, \"revision\") &&\n\t\thasOptionalFiniteNumber(value, \"progressRevision\") &&\n\t\thasOptionalFiniteNumber(value, \"tokenBudget\") &&\n\t\thasOptionalFiniteNumber(value, \"tokensUsed\") &&\n\t\tArray.isArray(value.requirements) &&\n\t\tvalue.requirements.every(isRequirement) &&\n\t\tArray.isArray(value.evidence) &&\n\t\tvalue.evidence.every(isGoalEvidenceRef) &&\n\t\tArray.isArray(value.events) &&\n\t\tvalue.events.every(isGoalEvent) &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\ttypeof value.updatedAt === \"string\" &&\n\t\ttypeof value.lastProgressAt === \"string\" &&\n\t\ttypeof value.stallTurns === \"number\" &&\n\t\tNumber.isFinite(value.stallTurns) &&\n\t\thasOptionalString(value, \"blockedReason\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationTurnsUsed\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationWallClockMs\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationSpendUsd\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationWorkerSpendUsd\") &&\n\t\thasOptionalBoolean(value, \"acceptanceOverride\")\n\t);\n}\n\nfunction cloneRequirement(requirement: Requirement): Requirement {\n\treturn {\n\t\t...requirement,\n\t\tevidenceIds: [...requirement.evidenceIds],\n\t};\n}\n\nfunction cloneGoalEvidenceRef(evidence: GoalEvidenceRef): GoalEvidenceRef {\n\treturn { ...evidence };\n}\n\nfunction cloneGoalEvent(event: GoalEvent): GoalEvent {\n\tif (event.type === \"satisfy_requirement\") {\n\t\treturn { ...event, evidenceIds: [...event.evidenceIds] };\n\t}\n\treturn { ...event };\n}\n\nexport function cloneGoalEventForStorage(event: GoalEvent): GoalEvent {\n\treturn cloneGoalEvent(event);\n}\n\nfunction cloneGoalState(state: GoalState): GoalState {\n\treturn {\n\t\t...state,\n\t\trequirements: state.requirements.map(cloneRequirement),\n\t\tevidence: state.evidence.map(cloneGoalEvidenceRef),\n\t\tevents: state.events.map(cloneGoalEvent),\n\t};\n}\n\nexport function cloneGoalStateForStorage(state: GoalState): GoalState {\n\treturn cloneGoalState(state);\n}\n\nexport function createGoalState(args: {\n\tgoalId: string;\n\tuserGoal: string;\n\tnow: string;\n\ttokenBudget?: number;\n}): GoalState {\n\treturn {\n\t\tgoalId: args.goalId,\n\t\tuserGoal: args.userGoal,\n\t\tstatus: \"active\",\n\t\trevision: 0,\n\t\tprogressRevision: 0,\n\t\ttokensUsed: 0,\n\t\t...(args.tokenBudget !== undefined ? { tokenBudget: args.tokenBudget } : {}),\n\t\trequirements: [],\n\t\tevidence: [],\n\t\tevents: [],\n\t\tcreatedAt: args.now,\n\t\tupdatedAt: args.now,\n\t\tlastProgressAt: args.now,\n\t\tstallTurns: 0,\n\t\tcontinuationTurnsUsed: 0,\n\t\tcontinuationWallClockMs: 0,\n\t\tcontinuationSpendUsd: 0,\n\t\tcontinuationWorkerSpendUsd: 0,\n\t};\n}\n\nfunction updateRequirement(state: GoalState, id: string, update: (requirement: Requirement) => Requirement): void {\n\tconst index = state.requirements.findIndex((requirement) => requirement.id === id);\n\tif (index < 0) return;\n\tconst requirements = [...state.requirements];\n\trequirements[index] = update(requirements[index]);\n\tstate.requirements = requirements;\n}\n\nexport function applyGoalEvent(state: GoalState, event: GoalEvent): GoalState {\n\tconst newState: GoalState = {\n\t\t...state,\n\t\trevision: (state.revision ?? 0) + 1,\n\t\trequirements: state.requirements.map(cloneRequirement),\n\t\tevidence: state.evidence.map(cloneGoalEvidenceRef),\n\t\tevents: [...state.events.map(cloneGoalEvent), cloneGoalEvent(event)].slice(-MAX_GOAL_EVENT_HISTORY),\n\t\tupdatedAt: event.now,\n\t};\n\n\tswitch (event.type) {\n\t\tcase \"edit_goal\": {\n\t\t\tnewState.userGoal = event.userGoal;\n\t\t\tif (event.tokenBudget !== undefined) newState.tokenBudget = event.tokenBudget;\n\t\t\tif (state.status === \"completed\") newState.status = \"active\";\n\t\t\tif (\n\t\t\t\tstate.status === \"budget_limited\" &&\n\t\t\t\tevent.tokenBudget !== undefined &&\n\t\t\t\tevent.tokenBudget > (state.tokensUsed ?? 0)\n\t\t\t) {\n\t\t\t\tnewState.status = \"active\";\n\t\t\t}\n\t\t\tif (newState.status === \"active\") newState.blockedReason = undefined;\n\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"add_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tconst newRequirement: Requirement = {\n\t\t\t\tid: event.id,\n\t\t\t\ttext: event.text,\n\t\t\t\tstatus: \"open\",\n\t\t\t\tevidenceIds: [],\n\t\t\t\tdependencies: event.dependencies,\n\t\t\t\tcreatedAt: existingIndex >= 0 ? newState.requirements[existingIndex].createdAt : event.now,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t};\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = newRequirement;\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t} else {\n\t\t\t\tnewState.requirements = [...newState.requirements, newRequirement];\n\t\t\t}\n\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"satisfy_requirement\": {\n\t\t\tupdateRequirement(newState, event.id, (requirement) => ({\n\t\t\t\t...requirement,\n\t\t\t\tstatus: \"satisfied\",\n\t\t\t\tevidenceIds: [...event.evidenceIds],\n\t\t\t\tupdatedAt: event.now,\n\t\t\t\tblockedReason: undefined,\n\t\t\t}));\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"block_requirement\": {\n\t\t\tupdateRequirement(newState, event.id, (requirement) => ({\n\t\t\t\t...requirement,\n\t\t\t\tstatus: \"blocked\",\n\t\t\t\tblockedReason: event.blockedReason,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t}));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"reopen_requirement\": {\n\t\t\tupdateRequirement(newState, event.id, (requirement) => ({\n\t\t\t\t...requirement,\n\t\t\t\tstatus: \"open\",\n\t\t\t\tblockedReason: undefined,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t}));\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"dispatch_worker\": {\n\t\t\t// Records the requirement<->lane binding ONLY -- never satisfies the requirement and never\n\t\t\t// touches lastProgressAt/stallTurns. The worker's own completion later populates \"worker\"\n\t\t\t// evidence and prompts an explicit satisfy_requirement pass through the existing gate.\n\t\t\tupdateRequirement(newState, event.id, (requirement) => ({\n\t\t\t\t...requirement,\n\t\t\t\tboundLaneId: event.laneId,\n\t\t\t\t// Start (or keep) the wait-timeout clock ONLY when this dispatch actually bound a real\n\t\t\t\t// lane -- a declined dispatch (no laneId) preserves whatever boundAt was already there.\n\t\t\t\tboundAt: event.laneId ? event.now : requirement.boundAt,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t}));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"add_evidence\": {\n\t\t\tconst existingIndex = newState.evidence.findIndex((evidence) => evidence.id === event.id);\n\t\t\tconst newEvidence: GoalEvidenceRef = {\n\t\t\t\tid: event.id,\n\t\t\t\tkind: event.kind,\n\t\t\t\tsummary: event.summary,\n\t\t\t\turi: event.uri,\n\t\t\t\tverified: event.verified,\n\t\t\t\tcreatedAt: existingIndex >= 0 ? newState.evidence[existingIndex].createdAt : event.now,\n\t\t\t};\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst updatedEvidence = [...newState.evidence];\n\t\t\t\tupdatedEvidence[existingIndex] = newEvidence;\n\t\t\t\tnewState.evidence = updatedEvidence;\n\t\t\t} else {\n\t\t\t\tnewState.evidence = [...newState.evidence, newEvidence];\n\t\t\t}\n\t\t\tif (event.kind === \"user\" || event.verified === true) {\n\t\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"progress\": {\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tnewState.progressRevision = (state.progressRevision ?? 0) + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"no_progress\": {\n\t\t\tnewState.stallTurns = state.stallTurns + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"record_continuation_budget\": {\n\t\t\tnewState.continuationTurnsUsed = (state.continuationTurnsUsed ?? 0) + event.turns;\n\t\t\tnewState.continuationWallClockMs = (state.continuationWallClockMs ?? 0) + event.wallClockMs;\n\t\t\tnewState.continuationSpendUsd = (state.continuationSpendUsd ?? 0) + Math.max(0, event.spendUsd);\n\t\t\tnewState.tokensUsed = (state.tokensUsed ?? 0) + Math.max(0, event.tokens);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"complete_goal\": {\n\t\t\tconst hasUnsatisfied = newState.requirements.some((requirement) => requirement.status !== \"satisfied\");\n\t\t\tif (!hasUnsatisfied) {\n\t\t\t\tnewState.status = \"completed\";\n\t\t\t\tnewState.blockedReason = undefined;\n\t\t\t\tnewState.acceptanceOverride = event.acceptanceOverride;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"complete_goal_manually\": {\n\t\t\tnewState.status = \"completed\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tnewState.acceptanceOverride = true;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"block_goal\": {\n\t\t\tnewState.status = \"blocked\";\n\t\t\tnewState.blockedReason = event.reason;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"pause_goal\": {\n\t\t\tnewState.status = \"paused\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"resume_goal\": {\n\t\t\tnewState.status = \"active\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"system_stop_goal\": {\n\t\t\tnewState.status = event.status;\n\t\t\tnewState.blockedReason = event.reason;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"cancel_goal\": {\n\t\t\tnewState.status = \"cancelled\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn newState;\n}\n\nexport function shouldContinueGoalLoop(args: { state: GoalState; maxStallTurns: number; now: string }): boolean {\n\tif (!isGoalExecutionActive(args.state.status)) {\n\t\treturn false;\n\t}\n\tif (args.state.stallTurns >= args.maxStallTurns) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nexport function serializeGoalState(state: GoalState): string {\n\treturn JSON.stringify(cloneGoalState(state), null, 2);\n}\n\nexport function parseGoalState(text: string): GoalState | undefined {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(text);\n\t\tif (!isGoalState(parsed)) return undefined;\n\t\treturn cloneGoalState(parsed);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
|