@caupulican/pi-adaptative 0.90.7 → 0.90.12
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 +56 -0
- package/dist/bundled-resources/skills/tool-call-repair/SKILL.md +5 -4
- package/dist/bundled-resources/skills/tool-call-repair/references/failure-grammar.md +6 -3
- package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +1 -0
- package/dist/core/agent-session-contracts.d.ts +2 -0
- package/dist/core/agent-session-contracts.d.ts.map +1 -1
- package/dist/core/agent-session-contracts.js.map +1 -1
- package/dist/core/agent-session.d.ts +8 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +84 -197
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts +7 -1
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +8 -2
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/contracts.d.ts +1 -1
- package/dist/core/autonomy/contracts.d.ts.map +1 -1
- package/dist/core/autonomy/contracts.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +14 -0
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +32 -0
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/billing-failover-controller.js +1 -1
- package/dist/core/billing-failover-controller.js.map +1 -1
- package/dist/core/context/current-work-memory.d.ts +1 -1
- package/dist/core/context/current-work-memory.d.ts.map +1 -1
- package/dist/core/context/current-work-memory.js +2 -1
- package/dist/core/context/current-work-memory.js.map +1 -1
- package/dist/core/context/long-term-memory-trigger.d.ts +1 -1
- package/dist/core/context/long-term-memory-trigger.d.ts.map +1 -1
- package/dist/core/context/long-term-memory-trigger.js +2 -1
- package/dist/core/context/long-term-memory-trigger.js.map +1 -1
- package/dist/core/delegation/managed-lane-controller.js +2 -2
- package/dist/core/delegation/managed-lane-controller.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +13 -0
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.js +71 -8
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.js +13 -8
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
- package/dist/core/delegation/worker-claim.d.ts.map +1 -1
- package/dist/core/delegation/worker-claim.js +14 -1
- package/dist/core/delegation/worker-claim.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +3 -2
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +95 -42
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-fleet-limits.d.ts.map +1 -1
- package/dist/core/delegation/worker-fleet-limits.js +5 -1
- package/dist/core/delegation/worker-fleet-limits.js.map +1 -1
- package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -1
- package/dist/core/delegation/worker-lane-projection.js +7 -4
- package/dist/core/delegation/worker-lane-projection.js.map +1 -1
- package/dist/core/delegation/worker-lifecycle.d.ts +8 -0
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-notification-coordinator.d.ts +21 -0
- package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-notification-coordinator.js +65 -2
- package/dist/core/delegation/worker-notification-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-runner.d.ts +7 -0
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +24 -7
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-system-prompt.d.ts +54 -0
- package/dist/core/delegation/worker-system-prompt.d.ts.map +1 -0
- package/dist/core/delegation/worker-system-prompt.js +85 -0
- package/dist/core/delegation/worker-system-prompt.js.map +1 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-tree-budget-coordinator.js +4 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +4 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-write-reservation-coordinator.js +28 -1
- package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -1
- package/dist/core/durable-custom-message-turn-controller.d.ts.map +1 -1
- package/dist/core/durable-custom-message-turn-controller.js +14 -3
- package/dist/core/durable-custom-message-turn-controller.js.map +1 -1
- package/dist/core/extension-binding-controller.d.ts +107 -0
- package/dist/core/extension-binding-controller.d.ts.map +1 -0
- package/dist/core/extension-binding-controller.js +224 -0
- package/dist/core/extension-binding-controller.js.map +1 -0
- package/dist/core/extensions/extension-session-scope.d.ts +17 -0
- package/dist/core/extensions/extension-session-scope.d.ts.map +1 -0
- package/dist/core/extensions/extension-session-scope.js +135 -0
- package/dist/core/extensions/extension-session-scope.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -0
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -0
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +2 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +10 -4
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/foreground-terminal-handoff-controller.d.ts +9 -0
- package/dist/core/foreground-terminal-handoff-controller.d.ts.map +1 -1
- package/dist/core/foreground-terminal-handoff-controller.js +35 -9
- package/dist/core/foreground-terminal-handoff-controller.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts.map +1 -1
- package/dist/core/goal-loop-controller.js +10 -1
- package/dist/core/goal-loop-controller.js.map +1 -1
- package/dist/core/goals/compact-goal-context.d.ts +1 -1
- package/dist/core/goals/compact-goal-context.d.ts.map +1 -1
- package/dist/core/goals/compact-goal-context.js +2 -1
- package/dist/core/goals/compact-goal-context.js.map +1 -1
- package/dist/core/goals/goal-execution-errors.d.ts +18 -0
- package/dist/core/goals/goal-execution-errors.d.ts.map +1 -0
- package/dist/core/goals/goal-execution-errors.js +21 -0
- package/dist/core/goals/goal-execution-errors.js.map +1 -0
- package/dist/core/goals/goal-lifecycle.d.ts.map +1 -1
- package/dist/core/goals/goal-lifecycle.js +3 -3
- package/dist/core/goals/goal-lifecycle.js.map +1 -1
- package/dist/core/goals/goal-session-controller.d.ts +11 -0
- package/dist/core/goals/goal-session-controller.d.ts.map +1 -1
- package/dist/core/goals/goal-session-controller.js +74 -14
- package/dist/core/goals/goal-session-controller.js.map +1 -1
- package/dist/core/goals/goal-state.js +1 -1
- package/dist/core/goals/goal-state.js.map +1 -1
- package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
- package/dist/core/goals/goal-tool-core.js +2 -2
- package/dist/core/goals/goal-tool-core.js.map +1 -1
- package/dist/core/goals/natural-language-goal.d.ts +18 -0
- package/dist/core/goals/natural-language-goal.d.ts.map +1 -1
- package/dist/core/goals/natural-language-goal.js +99 -16
- package/dist/core/goals/natural-language-goal.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +10 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +3 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/orchestration/capability-gateway.d.ts +1 -1
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +4 -4
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/event-store.d.ts +8 -0
- package/dist/core/orchestration/event-store.d.ts.map +1 -1
- package/dist/core/orchestration/event-store.js +9 -7
- package/dist/core/orchestration/event-store.js.map +1 -1
- package/dist/core/orchestration/task-runtime-reducer.js +1 -1
- package/dist/core/orchestration/task-runtime-reducer.js.map +1 -1
- package/dist/core/orchestration/worker-model-pins.d.ts +7 -0
- package/dist/core/orchestration/worker-model-pins.d.ts.map +1 -1
- package/dist/core/orchestration/worker-model-pins.js +17 -1
- package/dist/core/orchestration/worker-model-pins.js.map +1 -1
- package/dist/core/provider-request-runtime-controller.d.ts +9 -0
- package/dist/core/provider-request-runtime-controller.d.ts.map +1 -1
- package/dist/core/provider-request-runtime-controller.js +17 -3
- package/dist/core/provider-request-runtime-controller.js.map +1 -1
- package/dist/core/provider-tool-text.d.ts +15 -1
- package/dist/core/provider-tool-text.d.ts.map +1 -1
- package/dist/core/provider-tool-text.js +42 -10
- package/dist/core/provider-tool-text.js.map +1 -1
- package/dist/core/research/research-lane-controller.d.ts +1 -1
- package/dist/core/research/research-lane-controller.d.ts.map +1 -1
- package/dist/core/research/research-lane-controller.js +2 -1
- package/dist/core/research/research-lane-controller.js.map +1 -1
- package/dist/core/resource-loader.d.ts +3 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +8 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +8 -0
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +6 -0
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/session-supervision-runtime.d.ts.map +1 -1
- package/dist/core/session-supervision-runtime.js +2 -1
- package/dist/core/session-supervision-runtime.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +7 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tasks/task-state.d.ts +1 -1
- package/dist/core/tasks/task-state.d.ts.map +1 -1
- package/dist/core/tasks/task-state.js +4 -2
- package/dist/core/tasks/task-state.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +13 -0
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +20 -18
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/util/atomic-file.d.ts +7 -0
- package/dist/core/util/atomic-file.d.ts.map +1 -1
- package/dist/core/util/atomic-file.js +8 -6
- package/dist/core/util/atomic-file.js.map +1 -1
- package/dist/core/util/faultable-fs.d.ts +30 -0
- package/dist/core/util/faultable-fs.d.ts.map +1 -0
- package/dist/core/util/faultable-fs.js +30 -0
- package/dist/core/util/faultable-fs.js.map +1 -0
- package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
- package/dist/modes/interactive/auth-dialogs-controller.js +1 -0
- package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
- package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -1
- package/dist/modes/interactive/components/activity-lane.js +4 -3
- package/dist/modes/interactive/components/activity-lane.js.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +2 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +3 -2
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/report-commands.js +1 -1
- package/dist/modes/interactive/report-commands.js.map +1 -1
- package/dist/modes/interactive/session-flow-commands.d.ts +1 -1
- package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
- package/dist/modes/interactive/session-flow-commands.js +3 -2
- package/dist/modes/interactive/session-flow-commands.js.map +1 -1
- package/docs/extensions.md +1 -0
- package/docs/providers.md +3 -0
- package/docs/settings.md +4 -2
- package/docs/tool-repair.md +1 -0
- 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 +9 -4
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { composeSubagentSystemPrompt } from "../autonomy/subagent-prompt.js";
|
|
2
|
+
import { ModelAdaptationStore, } from "../models/adaptation-store.js";
|
|
3
|
+
/** Formats provider and model ID into standard modelRef key. */
|
|
4
|
+
export function formatWorkerModelRef(provider, modelId) {
|
|
5
|
+
return `${provider}/${modelId}`;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Dynamically loads model-specific adaptation rules and tool-recovery observations
|
|
9
|
+
* from the session's ModelAdaptationStore based on provider and model ID.
|
|
10
|
+
*/
|
|
11
|
+
export function loadWorkerModelGuidance(options) {
|
|
12
|
+
const modelRef = formatWorkerModelRef(options.provider, options.modelId);
|
|
13
|
+
const store = ModelAdaptationStore.forAgentDir(options.agentDir, { readOnly: true });
|
|
14
|
+
const profile = store.get(modelRef);
|
|
15
|
+
return {
|
|
16
|
+
rules: profile.rules,
|
|
17
|
+
toolProbeStatus: profile.toolProbe?.status,
|
|
18
|
+
toolProbeGrade: profile.toolProbe?.nativeGrade,
|
|
19
|
+
toolProbeDiagnostic: profile.toolProbe?.diagnostic,
|
|
20
|
+
protocolStatus: profile.protocol?.status ?? (profile.protocol ? "calibrated" : undefined),
|
|
21
|
+
protocolVariant: profile.protocol?.status !== "failed" ? profile.protocol?.variant : undefined,
|
|
22
|
+
teachStats: profile.teachStats,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Formats model adaptation rules and tool-recovery observations into prompt blocks.
|
|
27
|
+
*/
|
|
28
|
+
export function formatWorkerModelGuidancePrompt(guidance) {
|
|
29
|
+
const blocks = [];
|
|
30
|
+
if (guidance.rules.length > 0) {
|
|
31
|
+
const ruleLines = guidance.rules.map((rule) => `- ${rule.text}`);
|
|
32
|
+
blocks.push(`MODEL TOOL SHAPE RULES\n${ruleLines.join("\n")}`);
|
|
33
|
+
}
|
|
34
|
+
const observationLines = [];
|
|
35
|
+
if (guidance.toolProbeStatus) {
|
|
36
|
+
const gradeInfo = guidance.toolProbeGrade ? ` (grade: ${guidance.toolProbeGrade})` : "";
|
|
37
|
+
observationLines.push(`- Tool probe verdict: ${guidance.toolProbeStatus}${gradeInfo}`);
|
|
38
|
+
}
|
|
39
|
+
if (guidance.toolProbeDiagnostic) {
|
|
40
|
+
observationLines.push(`- Tool probe diagnostic: ${guidance.toolProbeDiagnostic}`);
|
|
41
|
+
}
|
|
42
|
+
if (guidance.protocolStatus) {
|
|
43
|
+
const variantInfo = guidance.protocolVariant ? ` (${guidance.protocolVariant})` : "";
|
|
44
|
+
observationLines.push(`- Text protocol status: ${guidance.protocolStatus}${variantInfo}`);
|
|
45
|
+
}
|
|
46
|
+
const activeTeachModes = Object.entries(guidance.teachStats ?? {}).filter(([_, stats]) => stats.taught > 0);
|
|
47
|
+
if (activeTeachModes.length > 0) {
|
|
48
|
+
for (const [mode, stats] of activeTeachModes) {
|
|
49
|
+
observationLines.push(`- Calibrated repair mode ${mode}: taught=${stats.taught}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (observationLines.length > 0) {
|
|
53
|
+
blocks.push(`MODEL TOOL-RECOVERY OBSERVATIONS\n${observationLines.join("\n")}`);
|
|
54
|
+
}
|
|
55
|
+
return blocks.length > 0 ? blocks.join("\n\n") : undefined;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Builds worker system prompt with level-0 subagent core, situational soul,
|
|
59
|
+
* role prompt, resource system prompt, and dynamically appended model adaptation guidance.
|
|
60
|
+
*/
|
|
61
|
+
export function buildWorkerSystemPrompt(options) {
|
|
62
|
+
const provider = options.model?.provider ?? options.provider;
|
|
63
|
+
const modelId = options.model?.id ?? options.modelId;
|
|
64
|
+
let modelGuidancePrompt;
|
|
65
|
+
if (options.agentDir && provider && modelId) {
|
|
66
|
+
try {
|
|
67
|
+
const guidance = loadWorkerModelGuidance({
|
|
68
|
+
agentDir: options.agentDir,
|
|
69
|
+
provider,
|
|
70
|
+
modelId,
|
|
71
|
+
});
|
|
72
|
+
modelGuidancePrompt = formatWorkerModelGuidancePrompt(guidance);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
modelGuidancePrompt = undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const rolePromptParts = [options.rolePrompt, options.workerResourceSystemPrompt, modelGuidancePrompt].filter((part) => Boolean(part && part.trim().length > 0));
|
|
79
|
+
return composeSubagentSystemPrompt({
|
|
80
|
+
soul: options.soul,
|
|
81
|
+
rolePrompt: rolePromptParts.join("\n\n"),
|
|
82
|
+
override: options.override,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=worker-system-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-system-prompt.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Model } from \"@caupulican/pi-ai\";\nimport { composeSubagentSystemPrompt } from \"../autonomy/subagent-prompt.ts\";\nimport {\n\ttype ModelAdaptationProfile,\n\ttype ModelAdaptationRule,\n\tModelAdaptationStore,\n} from \"../models/adaptation-store.ts\";\n\nexport interface WorkerModelGuidance {\n\trules: ModelAdaptationRule[];\n\ttoolProbeStatus?: string;\n\ttoolProbeGrade?: string;\n\ttoolProbeDiagnostic?: string;\n\tprotocolStatus?: string;\n\tprotocolVariant?: string;\n\tteachStats?: Record<string, { taught: number; recurrenceBefore: number; recurrenceAfter: number }>;\n}\n\nexport interface BuildWorkerSystemPromptOptions {\n\t/** Situational soul / identity snippet from shipped profile. */\n\tsoul?: string;\n\t/** Worker role prompt or execution plan prompt. */\n\trolePrompt: string;\n\t/** Materialized worker resource system prompt (skills/tools). */\n\tworkerResourceSystemPrompt?: string;\n\t/** Override for all layers above Level-0 subagent core. */\n\toverride?: string;\n\t/** Session agent directory to resolve ModelAdaptationStore. */\n\tagentDir?: string;\n\t/** Provider string (e.g. \"anthropic\", \"openai\"). */\n\tprovider?: string;\n\t/** Model ID string (e.g. \"claude-3-5-sonnet-20241022\"). */\n\tmodelId?: string;\n\t/** Target model instance if available. */\n\tmodel?: Model<any>;\n}\n\n/** Formats provider and model ID into standard modelRef key. */\nexport function formatWorkerModelRef(provider: string, modelId: string): string {\n\treturn `${provider}/${modelId}`;\n}\n\n/**\n * Dynamically loads model-specific adaptation rules and tool-recovery observations\n * from the session's ModelAdaptationStore based on provider and model ID.\n */\nexport function loadWorkerModelGuidance(options: {\n\tagentDir: string;\n\tprovider: string;\n\tmodelId: string;\n}): WorkerModelGuidance {\n\tconst modelRef = formatWorkerModelRef(options.provider, options.modelId);\n\tconst store = ModelAdaptationStore.forAgentDir(options.agentDir, { readOnly: true });\n\tconst profile: ModelAdaptationProfile = store.get(modelRef);\n\n\treturn {\n\t\trules: profile.rules,\n\t\ttoolProbeStatus: profile.toolProbe?.status,\n\t\ttoolProbeGrade: profile.toolProbe?.nativeGrade,\n\t\ttoolProbeDiagnostic: profile.toolProbe?.diagnostic,\n\t\tprotocolStatus: profile.protocol?.status ?? (profile.protocol ? \"calibrated\" : undefined),\n\t\tprotocolVariant: profile.protocol?.status !== \"failed\" ? profile.protocol?.variant : undefined,\n\t\tteachStats: profile.teachStats,\n\t};\n}\n\n/**\n * Formats model adaptation rules and tool-recovery observations into prompt blocks.\n */\nexport function formatWorkerModelGuidancePrompt(guidance: WorkerModelGuidance): string | undefined {\n\tconst blocks: string[] = [];\n\n\tif (guidance.rules.length > 0) {\n\t\tconst ruleLines = guidance.rules.map((rule) => `- ${rule.text}`);\n\t\tblocks.push(`MODEL TOOL SHAPE RULES\\n${ruleLines.join(\"\\n\")}`);\n\t}\n\n\tconst observationLines: string[] = [];\n\tif (guidance.toolProbeStatus) {\n\t\tconst gradeInfo = guidance.toolProbeGrade ? ` (grade: ${guidance.toolProbeGrade})` : \"\";\n\t\tobservationLines.push(`- Tool probe verdict: ${guidance.toolProbeStatus}${gradeInfo}`);\n\t}\n\tif (guidance.toolProbeDiagnostic) {\n\t\tobservationLines.push(`- Tool probe diagnostic: ${guidance.toolProbeDiagnostic}`);\n\t}\n\tif (guidance.protocolStatus) {\n\t\tconst variantInfo = guidance.protocolVariant ? ` (${guidance.protocolVariant})` : \"\";\n\t\tobservationLines.push(`- Text protocol status: ${guidance.protocolStatus}${variantInfo}`);\n\t}\n\n\tconst activeTeachModes = Object.entries(guidance.teachStats ?? {}).filter(([_, stats]) => stats.taught > 0);\n\tif (activeTeachModes.length > 0) {\n\t\tfor (const [mode, stats] of activeTeachModes) {\n\t\t\tobservationLines.push(`- Calibrated repair mode ${mode}: taught=${stats.taught}`);\n\t\t}\n\t}\n\n\tif (observationLines.length > 0) {\n\t\tblocks.push(`MODEL TOOL-RECOVERY OBSERVATIONS\\n${observationLines.join(\"\\n\")}`);\n\t}\n\n\treturn blocks.length > 0 ? blocks.join(\"\\n\\n\") : undefined;\n}\n\n/**\n * Builds worker system prompt with level-0 subagent core, situational soul,\n * role prompt, resource system prompt, and dynamically appended model adaptation guidance.\n */\nexport function buildWorkerSystemPrompt(options: BuildWorkerSystemPromptOptions): string {\n\tconst provider = options.model?.provider ?? options.provider;\n\tconst modelId = options.model?.id ?? options.modelId;\n\n\tlet modelGuidancePrompt: string | undefined;\n\tif (options.agentDir && provider && modelId) {\n\t\ttry {\n\t\t\tconst guidance = loadWorkerModelGuidance({\n\t\t\t\tagentDir: options.agentDir,\n\t\t\t\tprovider,\n\t\t\t\tmodelId,\n\t\t\t});\n\t\t\tmodelGuidancePrompt = formatWorkerModelGuidancePrompt(guidance);\n\t\t} catch {\n\t\t\tmodelGuidancePrompt = undefined;\n\t\t}\n\t}\n\n\tconst rolePromptParts = [options.rolePrompt, options.workerResourceSystemPrompt, modelGuidancePrompt].filter(\n\t\t(part): part is string => Boolean(part && part.trim().length > 0),\n\t);\n\n\treturn composeSubagentSystemPrompt({\n\t\tsoul: options.soul,\n\t\trolePrompt: rolePromptParts.join(\"\\n\\n\"),\n\t\toverride: options.override,\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-tree-budget-coordinator.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-tree-budget-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAMlF,OAAO,EAIN,KAAK,sBAAsB,EAC3B,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGtF,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAUnH,qBAAa,6BAA8B,SAAQ,6BAA6B;IAC/E,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IAEtC,YAAY,KAAK,EAAE,6BAA6B,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAQzE;CACD;AAmBD,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,oBAAoB,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IAC1C,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC1D,QAAQ,EAAE,QAAQ,CACjB,MAAM,CACL,MAAM,EACN;QACC,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE;YAAE,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACrC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;KACjC,CACD,CACD,CAAC;IACF,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,oBAAoB,CAAA;KAAE,CAAC,CAAC,CAAC;CACxE;AAED,2FAA2F;AAC3F,wBAAgB,4BAA4B,CAC3C,QAAQ,EAAE,0BAA0B,EACpC,WAAW,EAAE,MAAM,GACjB,oBAAoB,EAAE,CAYxB;AAMD,oGAAoG;AACpG,qBAAa,2BAA2B;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;IAE5D,UAAU,CAAC,IAAI,EAAE;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,UAAU,CAAC;QACnB,KAAK,EAAE,SAAS,oBAAoB,EAAE,CAAC;QACvC,YAAY,EAAE,oBAAoB,CAAC;KACnC,GAAG,sBAAsB,CA+BzB;IAED,OAAO,CAAC,kBAAkB;
|
|
1
|
+
{"version":3,"file":"worker-tree-budget-coordinator.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-tree-budget-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAMlF,OAAO,EAIN,KAAK,sBAAsB,EAC3B,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGtF,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAUnH,qBAAa,6BAA8B,SAAQ,6BAA6B;IAC/E,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IAEtC,YAAY,KAAK,EAAE,6BAA6B,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAQzE;CACD;AAmBD,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,oBAAoB,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IAC1C,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC1D,QAAQ,EAAE,QAAQ,CACjB,MAAM,CACL,MAAM,EACN;QACC,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE;YAAE,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACrC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;KACjC,CACD,CACD,CAAC;IACF,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,oBAAoB,CAAA;KAAE,CAAC,CAAC,CAAC;CACxE;AAED,2FAA2F;AAC3F,wBAAgB,4BAA4B,CAC3C,QAAQ,EAAE,0BAA0B,EACpC,WAAW,EAAE,MAAM,GACjB,oBAAoB,EAAE,CAYxB;AAMD,oGAAoG;AACpG,qBAAa,2BAA2B;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;IAE5D,UAAU,CAAC,IAAI,EAAE;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,UAAU,CAAC;QACnB,KAAK,EAAE,SAAS,oBAAoB,EAAE,CAAC;QACvC,YAAY,EAAE,oBAAoB,CAAC;KACnC,GAAG,sBAAsB,CA+BzB;IAED,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,qBAAqB;IAmC7B,OAAO,CAAC,YAAY;IA4CpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,eAAe;CA2BvB"}
|
|
@@ -73,6 +73,10 @@ export class WorkerTreeBudgetCoordinator {
|
|
|
73
73
|
if (reservation && previous) {
|
|
74
74
|
reservation.maxTokens = Math.max(0, reservation.maxTokens - Math.max(0, budgetedTokens(merged) - budgetedTokens(previous)));
|
|
75
75
|
}
|
|
76
|
+
// Shrinking a reservation to match actual (rather than speculatively requested) usage frees
|
|
77
|
+
// tree token headroom the same way release() does — waiters parked on an earlier
|
|
78
|
+
// availableTokens<=0 check must see it too, or they stay parked despite available budget.
|
|
79
|
+
this.drainWaiters(state);
|
|
76
80
|
}
|
|
77
81
|
reserveProviderBudget(state, attemptId, requestedMaxTokens, subject, signal) {
|
|
78
82
|
if (!Number.isSafeInteger(requestedMaxTokens) || requestedMaxTokens <= 0) {
|
|
@@ -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 { BoundedCompletionFailureError } from \"../autonomy/bounded-completion.ts\";\nimport {\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 type WorkerTreeBudgetField = \"maxTokens\" | \"maxCostUsd\" | \"maxToolCalls\" | \"maxWallClockMs\" | \"maxAttempts\";\n\nconst WORKER_TREE_BUDGET_REASON_CODES: Readonly<Record<WorkerTreeBudgetField, string>> = {\n\tmaxTokens: \"worker_tree_token_budget_exhausted\",\n\tmaxCostUsd: \"worker_tree_cost_budget_exhausted\",\n\tmaxToolCalls: \"worker_tree_tool_call_budget_exhausted\",\n\tmaxWallClockMs: \"worker_tree_wall_clock_budget_exhausted\",\n\tmaxAttempts: \"worker_tree_attempt_budget_exhausted\",\n};\n\nexport class WorkerTreeBudgetExceededError extends BoundedCompletionFailureError {\n\treadonly field: WorkerTreeBudgetField;\n\n\tconstructor(field: WorkerTreeBudgetExceededError[\"field\"], subject: string) {\n\t\tsuper(\n\t\t\t\"budget_exhausted\",\n\t\t\tWORKER_TREE_BUDGET_REASON_CODES[field],\n\t\t\t`Worker orchestration tree budget '${field}' is exhausted before ${subject}.`,\n\t\t);\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
|
+
{"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 { BoundedCompletionFailureError } from \"../autonomy/bounded-completion.ts\";\nimport {\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 type WorkerTreeBudgetField = \"maxTokens\" | \"maxCostUsd\" | \"maxToolCalls\" | \"maxWallClockMs\" | \"maxAttempts\";\n\nconst WORKER_TREE_BUDGET_REASON_CODES: Readonly<Record<WorkerTreeBudgetField, string>> = {\n\tmaxTokens: \"worker_tree_token_budget_exhausted\",\n\tmaxCostUsd: \"worker_tree_cost_budget_exhausted\",\n\tmaxToolCalls: \"worker_tree_tool_call_budget_exhausted\",\n\tmaxWallClockMs: \"worker_tree_wall_clock_budget_exhausted\",\n\tmaxAttempts: \"worker_tree_attempt_budget_exhausted\",\n};\n\nexport class WorkerTreeBudgetExceededError extends BoundedCompletionFailureError {\n\treadonly field: WorkerTreeBudgetField;\n\n\tconstructor(field: WorkerTreeBudgetExceededError[\"field\"], subject: string) {\n\t\tsuper(\n\t\t\t\"budget_exhausted\",\n\t\t\tWORKER_TREE_BUDGET_REASON_CODES[field],\n\t\t\t`Worker orchestration tree budget '${field}' is exhausted before ${subject}.`,\n\t\t);\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\t// Shrinking a reservation to match actual (rather than speculatively requested) usage frees\n\t\t// tree token headroom the same way release() does — waiters parked on an earlier\n\t\t// availableTokens<=0 check must see it too, or they stay parked despite available budget.\n\t\tthis.drainWaiters(state);\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"]}
|
|
@@ -31,11 +31,14 @@ export declare class WorkerWriteReservationCoordinator {
|
|
|
31
31
|
private readonly store;
|
|
32
32
|
private readonly leases;
|
|
33
33
|
private readonly blockedByLocalLaneIds;
|
|
34
|
+
private readonly availabilityListeners;
|
|
34
35
|
private watchDispose;
|
|
35
36
|
constructor(options: WorkerWriteReservationCoordinatorOptions);
|
|
36
37
|
acquire(laneId: string, attempt: Pick<AttemptRuntimeState, "attemptId" | "lease">, plan: Pick<WorkerExecutionPlan, "writeEnabled" | "writePaths">): WorkerWriteReservationAdmission;
|
|
37
38
|
hasFenceMismatch(laneId: string, attemptId: string, fencingToken: number): boolean;
|
|
38
39
|
isBlockedBy(targetLaneId: string, blockerLaneId: string): boolean;
|
|
40
|
+
/** Event-driven wakeup when a write reservation is released; same signal that drains the queue. */
|
|
41
|
+
subscribeAvailability(listener: () => void): () => void;
|
|
39
42
|
/** Release one exact live caller lane while its model turn is blocked inside a worker wait. */
|
|
40
43
|
yieldForWait(laneId: string, expectedAttemptId: string, expectedFencingToken: number): WorkerWriteReservationWaitYield | undefined;
|
|
41
44
|
/** Reacquire the exact yielded attempt fence before its model turn may resume. */
|
|
@@ -47,6 +50,7 @@ export declare class WorkerWriteReservationCoordinator {
|
|
|
47
50
|
private acquireLease;
|
|
48
51
|
private recordLocalBlockers;
|
|
49
52
|
private forgetLease;
|
|
53
|
+
private emitAvailability;
|
|
50
54
|
private ensureWatch;
|
|
51
55
|
}
|
|
52
56
|
//# sourceMappingURL=worker-write-reservation-coordinator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-write-reservation-coordinator.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-write-reservation-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,EACN,KAAK,2BAA2B,EAGhC,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,+BAA+B,GACxC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,iCAAiC,GAAG,+BAA+B,CAAA;CAAE,CAAC;AAEvG,MAAM,WAAW,+BAA+B;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,2BAA2B,CAAC;CACnC;AAED,MAAM,WAAW,wCAAwC;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,IAAI,MAAM,CAAC;IACjB,kBAAkB,IAAI,MAAM,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,IAAI,IAAI,CAAC;IAC3B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AAED;;;GAGG;AACH,qBAAa,iCAAiC;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IACnE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;IACzE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAkC;IACxE,OAAO,CAAC,YAAY,CAA2B;IAE/C,YAAY,OAAO,EAAE,wCAAwC,EAG5D;IAED,OAAO,CACN,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,GAAG,OAAO,CAAC,EACzD,IAAI,EAAE,IAAI,CAAC,mBAAmB,EAAE,cAAc,GAAG,YAAY,CAAC,GAC5D,+BAA+B,CA0BjC;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAGjF;IAED,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAEhE;IAED,+FAA+F;IAC/F,YAAY,CACX,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,MAAM,EACzB,oBAAoB,EAAE,MAAM,GAC1B,+BAA+B,GAAG,SAAS,CAe7C;IAED,kFAAkF;IAClF,gBAAgB,CAAC,OAAO,EAAE,+BAA+B,GAAG,+BAA+B,CAkC1F;IAED,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAiBvF;IAED,kBAAkB,IAAI,IAAI,CAqBzB;IAED,OAAO,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"worker-write-reservation-coordinator.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-write-reservation-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,EACN,KAAK,2BAA2B,EAGhC,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,+BAA+B,GACxC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,iCAAiC,GAAG,+BAA+B,CAAA;CAAE,CAAC;AAEvG,MAAM,WAAW,+BAA+B;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,2BAA2B,CAAC;CACnC;AAED,MAAM,WAAW,wCAAwC;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,IAAI,MAAM,CAAC;IACjB,kBAAkB,IAAI,MAAM,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,IAAI,IAAI,CAAC;IAC3B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AAED;;;GAGG;AACH,qBAAa,iCAAiC;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IACnE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;IACzE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAkC;IACxE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAyB;IAC/D,OAAO,CAAC,YAAY,CAA2B;IAE/C,YAAY,OAAO,EAAE,wCAAwC,EAG5D;IAED,OAAO,CACN,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,GAAG,OAAO,CAAC,EACzD,IAAI,EAAE,IAAI,CAAC,mBAAmB,EAAE,cAAc,GAAG,YAAY,CAAC,GAC5D,+BAA+B,CA0BjC;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAGjF;IAED,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAEhE;IAED,mGAAmG;IACnG,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAMtD;IAED,+FAA+F;IAC/F,YAAY,CACX,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,MAAM,EACzB,oBAAoB,EAAE,MAAM,GAC1B,+BAA+B,GAAG,SAAS,CAe7C;IAED,kFAAkF;IAClF,gBAAgB,CAAC,OAAO,EAAE,+BAA+B,GAAG,+BAA+B,CAkC1F;IAED,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAiBvF;IAED,kBAAkB,IAAI,IAAI,CAqBzB;IAED,OAAO,IAAI,IAAI,CAUd;IAED,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,YAAY;IAmCpB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,WAAW;CAInB"}
|
|
@@ -8,6 +8,7 @@ export class WorkerWriteReservationCoordinator {
|
|
|
8
8
|
constructor(options) {
|
|
9
9
|
this.leases = new Map();
|
|
10
10
|
this.blockedByLocalLaneIds = new Map();
|
|
11
|
+
this.availabilityListeners = new Set();
|
|
11
12
|
this.options = options;
|
|
12
13
|
this.store = new WorkerWriteReservationStore({ agentDir: options.agentDir });
|
|
13
14
|
}
|
|
@@ -40,6 +41,14 @@ export class WorkerWriteReservationCoordinator {
|
|
|
40
41
|
isBlockedBy(targetLaneId, blockerLaneId) {
|
|
41
42
|
return this.blockedByLocalLaneIds.get(targetLaneId)?.has(blockerLaneId) === true;
|
|
42
43
|
}
|
|
44
|
+
/** Event-driven wakeup when a write reservation is released; same signal that drains the queue. */
|
|
45
|
+
subscribeAvailability(listener) {
|
|
46
|
+
this.availabilityListeners.add(listener);
|
|
47
|
+
this.ensureWatch();
|
|
48
|
+
return () => {
|
|
49
|
+
this.availabilityListeners.delete(listener);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
43
52
|
/** Release one exact live caller lane while its model turn is blocked inside a worker wait. */
|
|
44
53
|
yieldForWait(laneId, expectedAttemptId, expectedFencingToken) {
|
|
45
54
|
const held = this.leases.get(laneId);
|
|
@@ -127,6 +136,13 @@ export class WorkerWriteReservationCoordinator {
|
|
|
127
136
|
dispose() {
|
|
128
137
|
this.watchDispose?.();
|
|
129
138
|
this.watchDispose = undefined;
|
|
139
|
+
this.availabilityListeners.clear();
|
|
140
|
+
// Release every held lease through the same path release() uses (best-effort store release,
|
|
141
|
+
// warn on failure, forgetLease bookkeeping) — dispose() previously dropped this coordinator's
|
|
142
|
+
// in-memory map of them without ever releasing the underlying durable reservations, leaking
|
|
143
|
+
// them until an unrelated recoverProvenStale() pass eventually proved the owner dead.
|
|
144
|
+
for (const laneId of [...this.leases.keys()])
|
|
145
|
+
this.release(laneId);
|
|
130
146
|
this.blockedByLocalLaneIds.clear();
|
|
131
147
|
}
|
|
132
148
|
workspace() {
|
|
@@ -183,10 +199,21 @@ export class WorkerWriteReservationCoordinator {
|
|
|
183
199
|
this.blockedByLocalLaneIds.delete(targetLaneId);
|
|
184
200
|
}
|
|
185
201
|
}
|
|
202
|
+
emitAvailability() {
|
|
203
|
+
this.options.drainQueuedWorkers();
|
|
204
|
+
for (const listener of this.availabilityListeners) {
|
|
205
|
+
try {
|
|
206
|
+
listener();
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// Waiters re-enter restore; a throwing observer cannot consume the release event.
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
186
213
|
ensureWatch() {
|
|
187
214
|
if (this.watchDispose)
|
|
188
215
|
return;
|
|
189
|
-
this.watchDispose = this.store.watchAvailability(this.workspace(), () => this.
|
|
216
|
+
this.watchDispose = this.store.watchAvailability(this.workspace(), () => this.emitAvailability());
|
|
190
217
|
}
|
|
191
218
|
}
|
|
192
219
|
//# sourceMappingURL=worker-write-reservation-coordinator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-write-reservation-coordinator.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-write-reservation-coordinator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAGN,2BAA2B,GAC3B,MAAM,+BAA+B,CAAC;AAsBvC;;;GAGG;AACH,MAAM,OAAO,iCAAiC;IAO7C,YAAY,OAAiD;QAJ5C,WAAM,GAAG,IAAI,GAAG,EAAuC,CAAC;QACxD,0BAAqB,GAAG,IAAI,GAAG,EAAuB,CAAC;QAIvE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,IAAI,2BAA2B,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,CACN,MAAc,EACd,OAAyD,EACzD,IAA8D;QAE9D,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC5B,CAAC;QACD,MAAM,YAAY,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,YAAY,KAAK,YAAY,EAAE,CAAC;YACjG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CACvB,MAAM,EACN;YACC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE;YAClD,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,YAAY;YACZ,MAAM,EAAE,OAAO;YACf,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;YAC3B,WAAW,EAAE,IAAI,CAAC,UAAU;SAC5B,EACD,iCAAiC,EACjC,IAAI,CACJ,CAAC;IACH,CAAC;IAED,gBAAgB,CAAC,MAAc,EAAE,SAAiB,EAAE,YAAoB;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,YAAY,CAAC,CAAC;IACtG,CAAC;IAED,WAAW,CAAC,YAAoB,EAAE,aAAqB;QACtD,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC;IAClF,CAAC;IAED,+FAA+F;IAC/F,YAAY,CACX,MAAc,EACd,iBAAyB,EACzB,oBAA4B;QAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,IAAI,IAAI,CAAC,SAAS,KAAK,iBAAiB,IAAI,IAAI,CAAC,YAAY,KAAK,oBAAoB,EAAE,CAAC;YACxF,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;QACjG,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,QAAQ,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/B,OAAO;YACN,MAAM;YACN,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE;SACtD,CAAC;IACH,CAAC;IAED,kFAAkF;IAClF,gBAAgB,CAAC,OAAwC;QACxD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;QAClC,IACC,KAAK,CAAC,MAAM,KAAK,MAAM;YACvB,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE;YAC3D,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,EACrC,CAAC;YACF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,+BAA+B,EAAE,CAAC;QACxE,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,OAAO,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC,YAAY,KAAK,KAAK,CAAC,YAAY;gBAC1F,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE;gBACrB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,+BAA+B,EAAE,CAAC;QACpE,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CACvB,MAAM,EACN;YACC,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,MAAM,EAAE,OAAO;YACf,SAAS,EAAE;gBACV,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrF;YACD,WAAW,EAAE,KAAK,CAAC,WAAW;SAC9B,EACD,yCAAyC,EACzC,KAAK,CACL,CAAC;IACH,CAAC;IAED,OAAO,CAAC,MAAc,EAAE,iBAA0B,EAAE,oBAA6B;QAChF,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO;QACR,CAAC;QACD,IAAI,iBAAiB,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,iBAAiB;YAAE,OAAO;QACpF,IAAI,oBAAoB,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,oBAAoB;YAAE,OAAO;QAC7F,IAAI,CAAC;YACJ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,IAAI,CAChB,8CAA8C,MAAM,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACjH,CAAC;QACH,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;IAED,kBAAkB;QACjB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACrF,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACtD,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,KAAK,EACJ,+BAA+B,CAC9B,OAAO,CAAC,KAAK,CAAC,OAAO,EACrB,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,mBAAmB,CAClD,KAAK,MAAM;gBACX,CAAC,CAAE,UAAoB;gBACvB,CAAC,CAAE,SAAmB;SACxB,CAAC,CAAC,CAAC;QACJ,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC9F,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO;gBAAE,SAAS;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACnD,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBACnE,IAAI,CAAC,OAAO,CAAC,IAAI,CAChB,kCAAkC,OAAO,CAAC,aAAa,sBAAsB,QAAQ,CAAC,IAAI,IAAI,CAC9F,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO;QACN,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;IACpC,CAAC;IAEO,SAAS;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC;IACpD,CAAC;IAEO,YAAY,CACnB,MAAc,EACd,OAAsC,EACtC,aAAqB,EACrB,oBAA6B;QAE7B,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,yBAAyB,CAAC,CAAC;gBACnE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACnB,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC1C,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACtC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,aAAa,KAAK,OAAO,EAAE,CAAC,CAAC;YAClD,OAAO;gBACN,IAAI,EAAE,QAAQ;gBACd,UAAU,EACT,oBAAoB,IAAI,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC;oBACpE,CAAC,CAAC,iCAAiC;oBACnC,CAAC,CAAC,+BAA+B;aACnC,CAAC;QACH,CAAC;IACF,CAAC;IAEO,mBAAmB,CAAC,MAAc,EAAE,yBAAwD;QACnG,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;QAChE,MAAM,aAAa,GAAG,IAAI,GAAG,CAC5B,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;aACd,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;aAC9D,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CACzC,CAAC;QACF,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC;YAAE,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;;YAC7E,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAEO,WAAW,CAAC,MAAc,EAAE,IAAiC;QACpE,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI;YAAE,OAAO;QAC7C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,KAAK,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YACzE,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,cAAc,CAAC,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAChF,CAAC;IACF,CAAC;IAEO,WAAW;QAClB,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC7G,CAAC;CACD","sourcesContent":["import type { AttemptRuntimeState } from \"../orchestration/task-runtime.ts\";\nimport type { WorkerExecutionPlan } from \"./worker-execution-policy.ts\";\nimport { isLocalProcessAlive, localWorkerProcessOwnerLiveness } from \"./worker-process-owner.ts\";\nimport {\n\ttype WorkerWriteReservationLease,\n\ttype WorkerWriteReservationRequest,\n\tWorkerWriteReservationStore,\n} from \"./worker-write-reservation.ts\";\n\nexport type WorkerWriteReservationAdmission =\n\t| { kind: \"granted\" }\n\t| { kind: \"blocked\" }\n\t| { kind: \"denied\"; reasonCode: \"write_reservation_scope_invalid\" | \"write_reservation_unavailable\" };\n\nexport interface WorkerWriteReservationWaitYield {\n\tlaneId: string;\n\tlease: WorkerWriteReservationLease;\n}\n\nexport interface WorkerWriteReservationCoordinatorOptions {\n\tagentDir: string;\n\tgetCwd(): string;\n\tgetParentSessionId(): string;\n\townerId: string;\n\tdrainQueuedWorkers(): void;\n\twarn(message: string): void;\n\tisProcessAlive?(pid: number): boolean;\n}\n\n/**\n * Owns one controller process's write-reservation lifecycle: admission, exact-fence release,\n * event-driven queue wakeup, and fail-closed recovery of positively dead owners.\n */\nexport class WorkerWriteReservationCoordinator {\n\tprivate readonly options: WorkerWriteReservationCoordinatorOptions;\n\tprivate readonly store: WorkerWriteReservationStore;\n\tprivate readonly leases = new Map<string, WorkerWriteReservationLease>();\n\tprivate readonly blockedByLocalLaneIds = new Map<string, Set<string>>();\n\tprivate watchDispose: (() => void) | undefined;\n\n\tconstructor(options: WorkerWriteReservationCoordinatorOptions) {\n\t\tthis.options = options;\n\t\tthis.store = new WorkerWriteReservationStore({ agentDir: options.agentDir });\n\t}\n\n\tacquire(\n\t\tlaneId: string,\n\t\tattempt: Pick<AttemptRuntimeState, \"attemptId\" | \"lease\">,\n\t\tplan: Pick<WorkerExecutionPlan, \"writeEnabled\" | \"writePaths\">,\n\t): WorkerWriteReservationAdmission {\n\t\tif (!plan.writeEnabled || plan.writePaths.length === 0) {\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\treturn { kind: \"granted\" };\n\t\t}\n\t\tconst fencingToken = (attempt.lease?.fencingToken ?? 0) + 1;\n\t\tconst current = this.leases.get(laneId);\n\t\tif (current && current.attemptId === attempt.attemptId && current.fencingToken === fencingToken) {\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\treturn { kind: \"granted\" };\n\t\t}\n\t\treturn this.acquireLease(\n\t\t\tlaneId,\n\t\t\t{\n\t\t\t\tparentSessionId: this.options.getParentSessionId(),\n\t\t\t\townerId: this.options.ownerId,\n\t\t\t\ttaskId: laneId,\n\t\t\t\tattemptId: attempt.attemptId,\n\t\t\t\tfencingToken,\n\t\t\t\taccess: \"write\",\n\t\t\t\tworkspace: this.workspace(),\n\t\t\t\twriteScopes: plan.writePaths,\n\t\t\t},\n\t\t\t\"Worker write reservation denied\",\n\t\t\ttrue,\n\t\t);\n\t}\n\n\thasFenceMismatch(laneId: string, attemptId: string, fencingToken: number): boolean {\n\t\tconst lease = this.leases.get(laneId);\n\t\treturn lease !== undefined && (lease.attemptId !== attemptId || lease.fencingToken !== fencingToken);\n\t}\n\n\tisBlockedBy(targetLaneId: string, blockerLaneId: string): boolean {\n\t\treturn this.blockedByLocalLaneIds.get(targetLaneId)?.has(blockerLaneId) === true;\n\t}\n\n\t/** Release one exact live caller lane while its model turn is blocked inside a worker wait. */\n\tyieldForWait(\n\t\tlaneId: string,\n\t\texpectedAttemptId: string,\n\t\texpectedFencingToken: number,\n\t): WorkerWriteReservationWaitYield | undefined {\n\t\tconst held = this.leases.get(laneId);\n\t\tif (!held) return undefined;\n\t\tif (held.attemptId !== expectedAttemptId || held.fencingToken !== expectedFencingToken) {\n\t\t\tthrow new Error(\"Worker wait cannot yield a write reservation owned by another attempt fence.\");\n\t\t}\n\t\tconst released = this.store.release(held);\n\t\tif (released.kind === \"stale_fence\") {\n\t\t\tthrow new Error(\"Worker wait write reservation yield encountered a stale attempt fence.\");\n\t\t}\n\t\tthis.forgetLease(laneId, held);\n\t\treturn {\n\t\t\tlaneId,\n\t\t\tlease: { ...held, writeScopes: [...held.writeScopes] },\n\t\t};\n\t}\n\n\t/** Reacquire the exact yielded attempt fence before its model turn may resume. */\n\trestoreAfterWait(yielded: WorkerWriteReservationWaitYield): WorkerWriteReservationAdmission {\n\t\tconst { laneId, lease } = yielded;\n\t\tif (\n\t\t\tlease.taskId !== laneId ||\n\t\t\tlease.parentSessionId !== this.options.getParentSessionId() ||\n\t\t\tlease.ownerId !== this.options.ownerId\n\t\t) {\n\t\t\treturn { kind: \"denied\", reasonCode: \"write_reservation_unavailable\" };\n\t\t}\n\t\tconst current = this.leases.get(laneId);\n\t\tif (current) {\n\t\t\treturn current.attemptId === lease.attemptId && current.fencingToken === lease.fencingToken\n\t\t\t\t? { kind: \"granted\" }\n\t\t\t\t: { kind: \"denied\", reasonCode: \"write_reservation_unavailable\" };\n\t\t}\n\t\treturn this.acquireLease(\n\t\t\tlaneId,\n\t\t\t{\n\t\t\t\tparentSessionId: lease.parentSessionId,\n\t\t\t\townerId: lease.ownerId,\n\t\t\t\ttaskId: lease.taskId,\n\t\t\t\tattemptId: lease.attemptId,\n\t\t\t\tfencingToken: lease.fencingToken,\n\t\t\t\taccess: \"write\",\n\t\t\t\tworkspace: {\n\t\t\t\t\trepositoryRoot: lease.repositoryRoot,\n\t\t\t\t\texecutionRoot: lease.executionRoot,\n\t\t\t\t\t...(lease.isolatedWorktreeId ? { isolatedWorktreeId: lease.isolatedWorktreeId } : {}),\n\t\t\t\t},\n\t\t\t\twriteScopes: lease.writeScopes,\n\t\t\t},\n\t\t\t\"Worker write reservation restore denied\",\n\t\t\tfalse,\n\t\t);\n\t}\n\n\trelease(laneId: string, expectedAttemptId?: string, expectedFencingToken?: number): void {\n\t\tconst held = this.leases.get(laneId);\n\t\tif (!held) {\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\treturn;\n\t\t}\n\t\tif (expectedAttemptId !== undefined && held.attemptId !== expectedAttemptId) return;\n\t\tif (expectedFencingToken !== undefined && held.fencingToken !== expectedFencingToken) return;\n\t\ttry {\n\t\t\tthis.store.release(held);\n\t\t} catch (error) {\n\t\t\tthis.options.warn(\n\t\t\t\t`Failed to release worker write reservation ${laneId}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t} finally {\n\t\t\tthis.forgetLease(laneId, held);\n\t\t}\n\t}\n\n\trecoverProvenStale(): void {\n\t\tconst discovered = this.store.recover({ workspace: this.workspace(), evidence: [] });\n\t\tconst evidence = discovered.outcomes.map((outcome) => ({\n\t\t\treservationId: outcome.reservationId,\n\t\t\tstate:\n\t\t\t\tlocalWorkerProcessOwnerLiveness(\n\t\t\t\t\toutcome.lease.ownerId,\n\t\t\t\t\tthis.options.isProcessAlive ?? isLocalProcessAlive,\n\t\t\t\t) === \"dead\"\n\t\t\t\t\t? (\"not_live\" as const)\n\t\t\t\t\t: (\"unknown\" as const),\n\t\t}));\n\t\tfor (const outcome of this.store.recover({ workspace: this.workspace(), evidence }).outcomes) {\n\t\t\tif (outcome.kind !== \"stale\") continue;\n\t\t\tconst released = this.store.release(outcome.lease);\n\t\t\tif (released.kind !== \"released\" && released.kind !== \"not_found\") {\n\t\t\t\tthis.options.warn(\n\t\t\t\t\t`Stale worker write reservation ${outcome.reservationId} was not released (${released.kind}).`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tthis.watchDispose?.();\n\t\tthis.watchDispose = undefined;\n\t\tthis.blockedByLocalLaneIds.clear();\n\t}\n\n\tprivate workspace() {\n\t\tconst cwd = this.options.getCwd();\n\t\treturn { repositoryRoot: cwd, executionRoot: cwd };\n\t}\n\n\tprivate acquireLease(\n\t\tlaneId: string,\n\t\trequest: WorkerWriteReservationRequest,\n\t\twarningPrefix: string,\n\t\tclassifyScopeFailure: boolean,\n\t): WorkerWriteReservationAdmission {\n\t\ttry {\n\t\t\tconst result = this.store.acquire(request);\n\t\t\tif (result.kind === \"blocked\") {\n\t\t\t\tthis.recordLocalBlockers(laneId, result.conflictingReservationIds);\n\t\t\t\tthis.ensureWatch();\n\t\t\t\treturn { kind: \"blocked\" };\n\t\t\t}\n\t\t\tif (!result.lease) {\n\t\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\t\tthis.ensureWatch();\n\t\t\t\treturn { kind: \"blocked\" };\n\t\t\t}\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\tthis.leases.set(laneId, result.lease);\n\t\t\treturn { kind: \"granted\" };\n\t\t} catch (error) {\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthis.options.warn(`${warningPrefix}: ${message}`);\n\t\t\treturn {\n\t\t\t\tkind: \"denied\",\n\t\t\t\treasonCode:\n\t\t\t\t\tclassifyScopeFailure && message.includes(\"within the execution root\")\n\t\t\t\t\t\t? \"write_reservation_scope_invalid\"\n\t\t\t\t\t\t: \"write_reservation_unavailable\",\n\t\t\t};\n\t\t}\n\t}\n\n\tprivate recordLocalBlockers(laneId: string, conflictingReservationIds: readonly string[] | undefined): void {\n\t\tconst conflictingIds = new Set(conflictingReservationIds ?? []);\n\t\tconst localBlockers = new Set(\n\t\t\t[...this.leases]\n\t\t\t\t.filter(([, lease]) => conflictingIds.has(lease.reservationId))\n\t\t\t\t.map(([blockedLaneId]) => blockedLaneId),\n\t\t);\n\t\tif (localBlockers.size > 0) this.blockedByLocalLaneIds.set(laneId, localBlockers);\n\t\telse this.blockedByLocalLaneIds.delete(laneId);\n\t}\n\n\tprivate forgetLease(laneId: string, held: WorkerWriteReservationLease): void {\n\t\tif (this.leases.get(laneId) !== held) return;\n\t\tthis.leases.delete(laneId);\n\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\tfor (const [targetLaneId, blockerLaneIds] of this.blockedByLocalLaneIds) {\n\t\t\tblockerLaneIds.delete(laneId);\n\t\t\tif (blockerLaneIds.size === 0) this.blockedByLocalLaneIds.delete(targetLaneId);\n\t\t}\n\t}\n\n\tprivate ensureWatch(): void {\n\t\tif (this.watchDispose) return;\n\t\tthis.watchDispose = this.store.watchAvailability(this.workspace(), () => this.options.drainQueuedWorkers());\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"worker-write-reservation-coordinator.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-write-reservation-coordinator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAGN,2BAA2B,GAC3B,MAAM,+BAA+B,CAAC;AAsBvC;;;GAGG;AACH,MAAM,OAAO,iCAAiC;IAQ7C,YAAY,OAAiD;QAL5C,WAAM,GAAG,IAAI,GAAG,EAAuC,CAAC;QACxD,0BAAqB,GAAG,IAAI,GAAG,EAAuB,CAAC;QACvD,0BAAqB,GAAG,IAAI,GAAG,EAAc,CAAC;QAI9D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,IAAI,2BAA2B,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,CACN,MAAc,EACd,OAAyD,EACzD,IAA8D;QAE9D,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC5B,CAAC;QACD,MAAM,YAAY,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,YAAY,KAAK,YAAY,EAAE,CAAC;YACjG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CACvB,MAAM,EACN;YACC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE;YAClD,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,YAAY;YACZ,MAAM,EAAE,OAAO;YACf,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;YAC3B,WAAW,EAAE,IAAI,CAAC,UAAU;SAC5B,EACD,iCAAiC,EACjC,IAAI,CACJ,CAAC;IACH,CAAC;IAED,gBAAgB,CAAC,MAAc,EAAE,SAAiB,EAAE,YAAoB;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,YAAY,CAAC,CAAC;IACtG,CAAC;IAED,WAAW,CAAC,YAAoB,EAAE,aAAqB;QACtD,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC;IAClF,CAAC;IAED,mGAAmG;IACnG,qBAAqB,CAAC,QAAoB;QACzC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,OAAO,GAAG,EAAE;YACX,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC,CAAC;IACH,CAAC;IAED,+FAA+F;IAC/F,YAAY,CACX,MAAc,EACd,iBAAyB,EACzB,oBAA4B;QAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,IAAI,IAAI,CAAC,SAAS,KAAK,iBAAiB,IAAI,IAAI,CAAC,YAAY,KAAK,oBAAoB,EAAE,CAAC;YACxF,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;QACjG,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,QAAQ,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/B,OAAO;YACN,MAAM;YACN,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE;SACtD,CAAC;IACH,CAAC;IAED,kFAAkF;IAClF,gBAAgB,CAAC,OAAwC;QACxD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;QAClC,IACC,KAAK,CAAC,MAAM,KAAK,MAAM;YACvB,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE;YAC3D,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,EACrC,CAAC;YACF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,+BAA+B,EAAE,CAAC;QACxE,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,OAAO,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC,YAAY,KAAK,KAAK,CAAC,YAAY;gBAC1F,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE;gBACrB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,+BAA+B,EAAE,CAAC;QACpE,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CACvB,MAAM,EACN;YACC,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,MAAM,EAAE,OAAO;YACf,SAAS,EAAE;gBACV,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrF;YACD,WAAW,EAAE,KAAK,CAAC,WAAW;SAC9B,EACD,yCAAyC,EACzC,KAAK,CACL,CAAC;IACH,CAAC;IAED,OAAO,CAAC,MAAc,EAAE,iBAA0B,EAAE,oBAA6B;QAChF,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO;QACR,CAAC;QACD,IAAI,iBAAiB,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,iBAAiB;YAAE,OAAO;QACpF,IAAI,oBAAoB,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,oBAAoB;YAAE,OAAO;QAC7F,IAAI,CAAC;YACJ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,IAAI,CAChB,8CAA8C,MAAM,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACjH,CAAC;QACH,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;IAED,kBAAkB;QACjB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACrF,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACtD,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,KAAK,EACJ,+BAA+B,CAC9B,OAAO,CAAC,KAAK,CAAC,OAAO,EACrB,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,mBAAmB,CAClD,KAAK,MAAM;gBACX,CAAC,CAAE,UAAoB;gBACvB,CAAC,CAAE,SAAmB;SACxB,CAAC,CAAC,CAAC;QACJ,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC9F,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO;gBAAE,SAAS;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACnD,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBACnE,IAAI,CAAC,OAAO,CAAC,IAAI,CAChB,kCAAkC,OAAO,CAAC,aAAa,sBAAsB,QAAQ,CAAC,IAAI,IAAI,CAC9F,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO;QACN,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;QACnC,4FAA4F;QAC5F,8FAA8F;QAC9F,4FAA4F;QAC5F,sFAAsF;QACtF,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACnE,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;IACpC,CAAC;IAEO,SAAS;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC;IACpD,CAAC;IAEO,YAAY,CACnB,MAAc,EACd,OAAsC,EACtC,aAAqB,EACrB,oBAA6B;QAE7B,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,yBAAyB,CAAC,CAAC;gBACnE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACnB,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC1C,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACtC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,aAAa,KAAK,OAAO,EAAE,CAAC,CAAC;YAClD,OAAO;gBACN,IAAI,EAAE,QAAQ;gBACd,UAAU,EACT,oBAAoB,IAAI,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC;oBACpE,CAAC,CAAC,iCAAiC;oBACnC,CAAC,CAAC,+BAA+B;aACnC,CAAC;QACH,CAAC;IACF,CAAC;IAEO,mBAAmB,CAAC,MAAc,EAAE,yBAAwD;QACnG,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;QAChE,MAAM,aAAa,GAAG,IAAI,GAAG,CAC5B,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;aACd,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;aAC9D,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CACzC,CAAC;QACF,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC;YAAE,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;;YAC7E,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAEO,WAAW,CAAC,MAAc,EAAE,IAAiC;QACpE,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI;YAAE,OAAO;QAC7C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,KAAK,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YACzE,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,cAAc,CAAC,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAChF,CAAC;IACF,CAAC;IAEO,gBAAgB;QACvB,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAClC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YACnD,IAAI,CAAC;gBACJ,QAAQ,EAAE,CAAC;YACZ,CAAC;YAAC,MAAM,CAAC;gBACR,kFAAkF;YACnF,CAAC;QACF,CAAC;IACF,CAAC;IAEO,WAAW;QAClB,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACnG,CAAC;CACD","sourcesContent":["import type { AttemptRuntimeState } from \"../orchestration/task-runtime.ts\";\nimport type { WorkerExecutionPlan } from \"./worker-execution-policy.ts\";\nimport { isLocalProcessAlive, localWorkerProcessOwnerLiveness } from \"./worker-process-owner.ts\";\nimport {\n\ttype WorkerWriteReservationLease,\n\ttype WorkerWriteReservationRequest,\n\tWorkerWriteReservationStore,\n} from \"./worker-write-reservation.ts\";\n\nexport type WorkerWriteReservationAdmission =\n\t| { kind: \"granted\" }\n\t| { kind: \"blocked\" }\n\t| { kind: \"denied\"; reasonCode: \"write_reservation_scope_invalid\" | \"write_reservation_unavailable\" };\n\nexport interface WorkerWriteReservationWaitYield {\n\tlaneId: string;\n\tlease: WorkerWriteReservationLease;\n}\n\nexport interface WorkerWriteReservationCoordinatorOptions {\n\tagentDir: string;\n\tgetCwd(): string;\n\tgetParentSessionId(): string;\n\townerId: string;\n\tdrainQueuedWorkers(): void;\n\twarn(message: string): void;\n\tisProcessAlive?(pid: number): boolean;\n}\n\n/**\n * Owns one controller process's write-reservation lifecycle: admission, exact-fence release,\n * event-driven queue wakeup, and fail-closed recovery of positively dead owners.\n */\nexport class WorkerWriteReservationCoordinator {\n\tprivate readonly options: WorkerWriteReservationCoordinatorOptions;\n\tprivate readonly store: WorkerWriteReservationStore;\n\tprivate readonly leases = new Map<string, WorkerWriteReservationLease>();\n\tprivate readonly blockedByLocalLaneIds = new Map<string, Set<string>>();\n\tprivate readonly availabilityListeners = new Set<() => void>();\n\tprivate watchDispose: (() => void) | undefined;\n\n\tconstructor(options: WorkerWriteReservationCoordinatorOptions) {\n\t\tthis.options = options;\n\t\tthis.store = new WorkerWriteReservationStore({ agentDir: options.agentDir });\n\t}\n\n\tacquire(\n\t\tlaneId: string,\n\t\tattempt: Pick<AttemptRuntimeState, \"attemptId\" | \"lease\">,\n\t\tplan: Pick<WorkerExecutionPlan, \"writeEnabled\" | \"writePaths\">,\n\t): WorkerWriteReservationAdmission {\n\t\tif (!plan.writeEnabled || plan.writePaths.length === 0) {\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\treturn { kind: \"granted\" };\n\t\t}\n\t\tconst fencingToken = (attempt.lease?.fencingToken ?? 0) + 1;\n\t\tconst current = this.leases.get(laneId);\n\t\tif (current && current.attemptId === attempt.attemptId && current.fencingToken === fencingToken) {\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\treturn { kind: \"granted\" };\n\t\t}\n\t\treturn this.acquireLease(\n\t\t\tlaneId,\n\t\t\t{\n\t\t\t\tparentSessionId: this.options.getParentSessionId(),\n\t\t\t\townerId: this.options.ownerId,\n\t\t\t\ttaskId: laneId,\n\t\t\t\tattemptId: attempt.attemptId,\n\t\t\t\tfencingToken,\n\t\t\t\taccess: \"write\",\n\t\t\t\tworkspace: this.workspace(),\n\t\t\t\twriteScopes: plan.writePaths,\n\t\t\t},\n\t\t\t\"Worker write reservation denied\",\n\t\t\ttrue,\n\t\t);\n\t}\n\n\thasFenceMismatch(laneId: string, attemptId: string, fencingToken: number): boolean {\n\t\tconst lease = this.leases.get(laneId);\n\t\treturn lease !== undefined && (lease.attemptId !== attemptId || lease.fencingToken !== fencingToken);\n\t}\n\n\tisBlockedBy(targetLaneId: string, blockerLaneId: string): boolean {\n\t\treturn this.blockedByLocalLaneIds.get(targetLaneId)?.has(blockerLaneId) === true;\n\t}\n\n\t/** Event-driven wakeup when a write reservation is released; same signal that drains the queue. */\n\tsubscribeAvailability(listener: () => void): () => void {\n\t\tthis.availabilityListeners.add(listener);\n\t\tthis.ensureWatch();\n\t\treturn () => {\n\t\t\tthis.availabilityListeners.delete(listener);\n\t\t};\n\t}\n\n\t/** Release one exact live caller lane while its model turn is blocked inside a worker wait. */\n\tyieldForWait(\n\t\tlaneId: string,\n\t\texpectedAttemptId: string,\n\t\texpectedFencingToken: number,\n\t): WorkerWriteReservationWaitYield | undefined {\n\t\tconst held = this.leases.get(laneId);\n\t\tif (!held) return undefined;\n\t\tif (held.attemptId !== expectedAttemptId || held.fencingToken !== expectedFencingToken) {\n\t\t\tthrow new Error(\"Worker wait cannot yield a write reservation owned by another attempt fence.\");\n\t\t}\n\t\tconst released = this.store.release(held);\n\t\tif (released.kind === \"stale_fence\") {\n\t\t\tthrow new Error(\"Worker wait write reservation yield encountered a stale attempt fence.\");\n\t\t}\n\t\tthis.forgetLease(laneId, held);\n\t\treturn {\n\t\t\tlaneId,\n\t\t\tlease: { ...held, writeScopes: [...held.writeScopes] },\n\t\t};\n\t}\n\n\t/** Reacquire the exact yielded attempt fence before its model turn may resume. */\n\trestoreAfterWait(yielded: WorkerWriteReservationWaitYield): WorkerWriteReservationAdmission {\n\t\tconst { laneId, lease } = yielded;\n\t\tif (\n\t\t\tlease.taskId !== laneId ||\n\t\t\tlease.parentSessionId !== this.options.getParentSessionId() ||\n\t\t\tlease.ownerId !== this.options.ownerId\n\t\t) {\n\t\t\treturn { kind: \"denied\", reasonCode: \"write_reservation_unavailable\" };\n\t\t}\n\t\tconst current = this.leases.get(laneId);\n\t\tif (current) {\n\t\t\treturn current.attemptId === lease.attemptId && current.fencingToken === lease.fencingToken\n\t\t\t\t? { kind: \"granted\" }\n\t\t\t\t: { kind: \"denied\", reasonCode: \"write_reservation_unavailable\" };\n\t\t}\n\t\treturn this.acquireLease(\n\t\t\tlaneId,\n\t\t\t{\n\t\t\t\tparentSessionId: lease.parentSessionId,\n\t\t\t\townerId: lease.ownerId,\n\t\t\t\ttaskId: lease.taskId,\n\t\t\t\tattemptId: lease.attemptId,\n\t\t\t\tfencingToken: lease.fencingToken,\n\t\t\t\taccess: \"write\",\n\t\t\t\tworkspace: {\n\t\t\t\t\trepositoryRoot: lease.repositoryRoot,\n\t\t\t\t\texecutionRoot: lease.executionRoot,\n\t\t\t\t\t...(lease.isolatedWorktreeId ? { isolatedWorktreeId: lease.isolatedWorktreeId } : {}),\n\t\t\t\t},\n\t\t\t\twriteScopes: lease.writeScopes,\n\t\t\t},\n\t\t\t\"Worker write reservation restore denied\",\n\t\t\tfalse,\n\t\t);\n\t}\n\n\trelease(laneId: string, expectedAttemptId?: string, expectedFencingToken?: number): void {\n\t\tconst held = this.leases.get(laneId);\n\t\tif (!held) {\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\treturn;\n\t\t}\n\t\tif (expectedAttemptId !== undefined && held.attemptId !== expectedAttemptId) return;\n\t\tif (expectedFencingToken !== undefined && held.fencingToken !== expectedFencingToken) return;\n\t\ttry {\n\t\t\tthis.store.release(held);\n\t\t} catch (error) {\n\t\t\tthis.options.warn(\n\t\t\t\t`Failed to release worker write reservation ${laneId}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t} finally {\n\t\t\tthis.forgetLease(laneId, held);\n\t\t}\n\t}\n\n\trecoverProvenStale(): void {\n\t\tconst discovered = this.store.recover({ workspace: this.workspace(), evidence: [] });\n\t\tconst evidence = discovered.outcomes.map((outcome) => ({\n\t\t\treservationId: outcome.reservationId,\n\t\t\tstate:\n\t\t\t\tlocalWorkerProcessOwnerLiveness(\n\t\t\t\t\toutcome.lease.ownerId,\n\t\t\t\t\tthis.options.isProcessAlive ?? isLocalProcessAlive,\n\t\t\t\t) === \"dead\"\n\t\t\t\t\t? (\"not_live\" as const)\n\t\t\t\t\t: (\"unknown\" as const),\n\t\t}));\n\t\tfor (const outcome of this.store.recover({ workspace: this.workspace(), evidence }).outcomes) {\n\t\t\tif (outcome.kind !== \"stale\") continue;\n\t\t\tconst released = this.store.release(outcome.lease);\n\t\t\tif (released.kind !== \"released\" && released.kind !== \"not_found\") {\n\t\t\t\tthis.options.warn(\n\t\t\t\t\t`Stale worker write reservation ${outcome.reservationId} was not released (${released.kind}).`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tthis.watchDispose?.();\n\t\tthis.watchDispose = undefined;\n\t\tthis.availabilityListeners.clear();\n\t\t// Release every held lease through the same path release() uses (best-effort store release,\n\t\t// warn on failure, forgetLease bookkeeping) — dispose() previously dropped this coordinator's\n\t\t// in-memory map of them without ever releasing the underlying durable reservations, leaking\n\t\t// them until an unrelated recoverProvenStale() pass eventually proved the owner dead.\n\t\tfor (const laneId of [...this.leases.keys()]) this.release(laneId);\n\t\tthis.blockedByLocalLaneIds.clear();\n\t}\n\n\tprivate workspace() {\n\t\tconst cwd = this.options.getCwd();\n\t\treturn { repositoryRoot: cwd, executionRoot: cwd };\n\t}\n\n\tprivate acquireLease(\n\t\tlaneId: string,\n\t\trequest: WorkerWriteReservationRequest,\n\t\twarningPrefix: string,\n\t\tclassifyScopeFailure: boolean,\n\t): WorkerWriteReservationAdmission {\n\t\ttry {\n\t\t\tconst result = this.store.acquire(request);\n\t\t\tif (result.kind === \"blocked\") {\n\t\t\t\tthis.recordLocalBlockers(laneId, result.conflictingReservationIds);\n\t\t\t\tthis.ensureWatch();\n\t\t\t\treturn { kind: \"blocked\" };\n\t\t\t}\n\t\t\tif (!result.lease) {\n\t\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\t\tthis.ensureWatch();\n\t\t\t\treturn { kind: \"blocked\" };\n\t\t\t}\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\tthis.leases.set(laneId, result.lease);\n\t\t\treturn { kind: \"granted\" };\n\t\t} catch (error) {\n\t\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthis.options.warn(`${warningPrefix}: ${message}`);\n\t\t\treturn {\n\t\t\t\tkind: \"denied\",\n\t\t\t\treasonCode:\n\t\t\t\t\tclassifyScopeFailure && message.includes(\"within the execution root\")\n\t\t\t\t\t\t? \"write_reservation_scope_invalid\"\n\t\t\t\t\t\t: \"write_reservation_unavailable\",\n\t\t\t};\n\t\t}\n\t}\n\n\tprivate recordLocalBlockers(laneId: string, conflictingReservationIds: readonly string[] | undefined): void {\n\t\tconst conflictingIds = new Set(conflictingReservationIds ?? []);\n\t\tconst localBlockers = new Set(\n\t\t\t[...this.leases]\n\t\t\t\t.filter(([, lease]) => conflictingIds.has(lease.reservationId))\n\t\t\t\t.map(([blockedLaneId]) => blockedLaneId),\n\t\t);\n\t\tif (localBlockers.size > 0) this.blockedByLocalLaneIds.set(laneId, localBlockers);\n\t\telse this.blockedByLocalLaneIds.delete(laneId);\n\t}\n\n\tprivate forgetLease(laneId: string, held: WorkerWriteReservationLease): void {\n\t\tif (this.leases.get(laneId) !== held) return;\n\t\tthis.leases.delete(laneId);\n\t\tthis.blockedByLocalLaneIds.delete(laneId);\n\t\tfor (const [targetLaneId, blockerLaneIds] of this.blockedByLocalLaneIds) {\n\t\t\tblockerLaneIds.delete(laneId);\n\t\t\tif (blockerLaneIds.size === 0) this.blockedByLocalLaneIds.delete(targetLaneId);\n\t\t}\n\t}\n\n\tprivate emitAvailability(): void {\n\t\tthis.options.drainQueuedWorkers();\n\t\tfor (const listener of this.availabilityListeners) {\n\t\t\ttry {\n\t\t\t\tlistener();\n\t\t\t} catch {\n\t\t\t\t// Waiters re-enter restore; a throwing observer cannot consume the release event.\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate ensureWatch(): void {\n\t\tif (this.watchDispose) return;\n\t\tthis.watchDispose = this.store.watchAvailability(this.workspace(), () => this.emitAvailability());\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durable-custom-message-turn-controller.d.ts","sourceRoot":"","sources":["../../src/core/durable-custom-message-turn-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AACnH,OAAO,KAAK,EAAsB,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAEpG,UAAU,sCAAsC;IAC/C,UAAU,EAAE,4BAA4B,CAAC;IACzC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,gBAAgB,GAAG,cAAc,CAAC,CAAC;CACtE;AAED;;;;GAIG;AACH,qBAAa,kCAAkC;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwF;IAEhH,YAAY,IAAI,EAAE,sCAAsC,EAEvD;IAED,wFAAwF;IACxF,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,OAAO,CAMtD;IAEK,KAAK,CAAC,CAAC,EACZ,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC,EACjF,eAAe,EAAE,yBAAyB,EAC1C,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"durable-custom-message-turn-controller.d.ts","sourceRoot":"","sources":["../../src/core/durable-custom-message-turn-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AACnH,OAAO,KAAK,EAAsB,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAEpG,UAAU,sCAAsC;IAC/C,UAAU,EAAE,4BAA4B,CAAC;IACzC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,gBAAgB,GAAG,cAAc,CAAC,CAAC;CACtE;AAED;;;;GAIG;AACH,qBAAa,kCAAkC;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwF;IAEhH,YAAY,IAAI,EAAE,sCAAsC,EAEvD;IAED,wFAAwF;IACxF,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,OAAO,CAMtD;IAEK,KAAK,CAAC,CAAC,EACZ,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC,EACjF,eAAe,EAAE,yBAAyB,EAC1C,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC,CAgDxC;CACD"}
|
|
@@ -41,9 +41,20 @@ export class DurableCustomMessageTurnController {
|
|
|
41
41
|
this.pending.delete(appMessage);
|
|
42
42
|
throw error;
|
|
43
43
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
let completion;
|
|
45
|
+
try {
|
|
46
|
+
completion = this.deps.foreground
|
|
47
|
+
.runAgentPrompt(appMessage, submissionLease)
|
|
48
|
+
.finally(() => this.deps.goals.endExecution(goalExecutionLease));
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
// runAgentPrompt is expected to report failure through its returned promise, but if it
|
|
52
|
+
// throws SYNCHRONOUSLY instead, the .finally() above never attaches and the goal
|
|
53
|
+
// execution lease acquired above leaks forever. Every exit path must release it.
|
|
54
|
+
this.deps.goals.endExecution(goalExecutionLease);
|
|
55
|
+
this.pending.delete(appMessage);
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
47
58
|
void completion.then(() => {
|
|
48
59
|
if (!this.pending.delete(appMessage))
|
|
49
60
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durable-custom-message-turn-controller.js","sourceRoot":"","sources":["../../src/core/durable-custom-message-turn-controller.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,MAAM,OAAO,kCAAkC;IAI9C,YAAY,IAA4C;QAFvC,YAAO,GAAG,IAAI,GAAG,EAA6E,CAAC;QAG/G,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,wFAAwF;IACxF,aAAa,CAAC,OAA+B;QAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7B,UAAU,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,KAAK,CACV,OAAiF,EACjF,eAA0C,EAC1C,MAAe;QAEf,MAAM,UAAU,GAAG;YAClB,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACM,CAAC;QAC7B,IAAI,eAA4B,CAAC;QACjC,IAAI,cAAyC,CAAC;QAC9C,MAAM,eAAe,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7D,eAAe,GAAG,OAAO,CAAC;YAC1B,cAAc,GAAG,MAAM,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;QACnF,IAAI,kBAAkD,CAAC;QACvD,IAAI,CAAC;YACJ,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAChC,MAAM,KAAK,CAAC;QACb,CAAC;QACD,
|
|
1
|
+
{"version":3,"file":"durable-custom-message-turn-controller.js","sourceRoot":"","sources":["../../src/core/durable-custom-message-turn-controller.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,MAAM,OAAO,kCAAkC;IAI9C,YAAY,IAA4C;QAFvC,YAAO,GAAG,IAAI,GAAG,EAA6E,CAAC;QAG/G,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,wFAAwF;IACxF,aAAa,CAAC,OAA+B;QAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7B,UAAU,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,KAAK,CACV,OAAiF,EACjF,eAA0C,EAC1C,MAAe;QAEf,MAAM,UAAU,GAAG;YAClB,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACM,CAAC;QAC7B,IAAI,eAA4B,CAAC;QACjC,IAAI,cAAyC,CAAC;QAC9C,MAAM,eAAe,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7D,eAAe,GAAG,OAAO,CAAC;YAC1B,cAAc,GAAG,MAAM,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;QACnF,IAAI,kBAAkD,CAAC;QACvD,IAAI,CAAC;YACJ,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAChC,MAAM,KAAK,CAAC;QACb,CAAC;QACD,IAAI,UAAyB,CAAC;QAC9B,IAAI,CAAC;YACJ,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU;iBAC/B,cAAc,CAAC,UAAU,EAAE,eAAe,CAAC;iBAC3C,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,uFAAuF;YACvF,iFAAiF;YACjF,iFAAiF;YACjF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;YACjD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAChC,MAAM,KAAK,CAAC;QACb,CAAC;QACD,KAAK,UAAU,CAAC,IAAI,CACnB,GAAG,EAAE;YACJ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;gBAAE,OAAO;YAC7C,cAAc,CAAC,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC,CAAC;QACvF,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;YAClB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;gBAAE,OAAO;YAC7C,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC,CACD,CAAC;QACF,MAAM,eAAe,CAAC;QACtB,OAAO,EAAE,UAAU,EAAE,CAAC;IACvB,CAAC;CACD","sourcesContent":["import type { CustomMessage } from \"@caupulican/pi-agent-core\";\nimport type { ForegroundRecoveryController, ForegroundSubmissionLease } from \"./foreground-recovery-controller.ts\";\nimport type { GoalExecutionLease, GoalSessionController } from \"./goals/goal-session-controller.ts\";\n\ninterface DurableCustomMessageTurnControllerDeps {\n\tforeground: ForegroundRecoveryController;\n\tgoals: Pick<GoalSessionController, \"beginExecution\" | \"endExecution\">;\n}\n\n/**\n * Starts an internal custom-message turn and separates durable input acceptance from full model-run\n * completion. Notification outboxes may acknowledge after `start` resolves, while the foreground\n * owner retains its lease until the returned completion settles.\n */\nexport class DurableCustomMessageTurnController {\n\tprivate readonly deps: DurableCustomMessageTurnControllerDeps;\n\tprivate readonly pending = new Map<CustomMessage<unknown>, { resolve(): void; reject(error: unknown): void }>();\n\n\tconstructor(deps: DurableCustomMessageTurnControllerDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\t/** Accept only the exact custom-message object after SessionManager append succeeds. */\n\tnotePersisted(message: CustomMessage<unknown>): boolean {\n\t\tconst acceptance = this.pending.get(message);\n\t\tif (!acceptance) return false;\n\t\tthis.pending.delete(message);\n\t\tacceptance.resolve();\n\t\treturn true;\n\t}\n\n\tasync start<T>(\n\t\tmessage: Pick<CustomMessage<T>, \"customType\" | \"content\" | \"display\" | \"details\">,\n\t\tsubmissionLease: ForegroundSubmissionLease,\n\t\tgoalId?: string,\n\t): Promise<{ completion: Promise<void> }> {\n\t\tconst appMessage = {\n\t\t\trole: \"custom\" as const,\n\t\t\tcustomType: message.customType,\n\t\t\tcontent: message.content,\n\t\t\tdisplay: message.display,\n\t\t\tdetails: message.details,\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies CustomMessage<T>;\n\t\tlet resolveAccepted!: () => void;\n\t\tlet rejectAccepted!: (error: unknown) => void;\n\t\tconst acceptedPromise = new Promise<void>((resolve, reject) => {\n\t\t\tresolveAccepted = resolve;\n\t\t\trejectAccepted = reject;\n\t\t});\n\t\tthis.pending.set(appMessage, { resolve: resolveAccepted, reject: rejectAccepted });\n\t\tlet goalExecutionLease: GoalExecutionLease | undefined;\n\t\ttry {\n\t\t\tgoalExecutionLease = this.deps.goals.beginExecution(goalId);\n\t\t} catch (error) {\n\t\t\tthis.pending.delete(appMessage);\n\t\t\tthrow error;\n\t\t}\n\t\tlet completion: Promise<void>;\n\t\ttry {\n\t\t\tcompletion = this.deps.foreground\n\t\t\t\t.runAgentPrompt(appMessage, submissionLease)\n\t\t\t\t.finally(() => this.deps.goals.endExecution(goalExecutionLease));\n\t\t} catch (error) {\n\t\t\t// runAgentPrompt is expected to report failure through its returned promise, but if it\n\t\t\t// throws SYNCHRONOUSLY instead, the .finally() above never attaches and the goal\n\t\t\t// execution lease acquired above leaks forever. Every exit path must release it.\n\t\t\tthis.deps.goals.endExecution(goalExecutionLease);\n\t\t\tthis.pending.delete(appMessage);\n\t\t\tthrow error;\n\t\t}\n\t\tvoid completion.then(\n\t\t\t() => {\n\t\t\t\tif (!this.pending.delete(appMessage)) return;\n\t\t\t\trejectAccepted(new Error(\"Custom-message turn ended before its input was persisted\"));\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tif (!this.pending.delete(appMessage)) return;\n\t\t\t\trejectAccepted(error);\n\t\t\t},\n\t\t);\n\t\tawait acceptedPromise;\n\t\treturn { completion };\n\t}\n}\n"]}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension runtime binding: the boundary between {@link AgentSession} and the {@link
|
|
3
|
+
* ExtensionRunner} it hosts. Owns the public `bindExtensions()` entry point (stores the
|
|
4
|
+
* host-supplied UI/mode/callback bindings, applies them to the runner, fires the session-start
|
|
5
|
+
* event, discovers extension-contributed resources, and initializes memory), the resource
|
|
6
|
+
* discovery pass that turns extension-reported skill/prompt/theme paths into labeled {@link
|
|
7
|
+
* ResourceExtensionPaths}, and `bindExtensionCore` — the ~30-method translation of the session's
|
|
8
|
+
* own public surface (send message, set model, compact, abort, reload, …) into the `ExtensionActions`
|
|
9
|
+
* / `ExtensionContextActions` shape `ExtensionRunner.bindCore` expects.
|
|
10
|
+
*
|
|
11
|
+
* Extracted verbatim from agent-session.ts (god-file decomposition). All logic here is pure code
|
|
12
|
+
* motion — no behavior changes. State that other collaborators (RuntimeBuilder, LocalRuntimeController,
|
|
13
|
+
* HumanInputController) also read (`_extensionUIContext`, `_extensionMode`, `_extensionCommandContextActions`,
|
|
14
|
+
* `_extensionShutdownHandler`, `_extensionErrorListener`) stays host-owned and is reached through the
|
|
15
|
+
* same get/set deps accessors those collaborators already use; `_extensionAbortHandler` and the
|
|
16
|
+
* error-unsubscribe callback are touched only within this binding boundary, so they are owned here.
|
|
17
|
+
*
|
|
18
|
+
* Host-binding boundary note (see runtime-builder.ts): `bindExtensionCore` exposes session identity
|
|
19
|
+
* to the extension runner, not tool-registry build logic, which is why it lives in its own dedicated
|
|
20
|
+
* module rather than inside RuntimeBuilder; RuntimeBuilder still invokes it (and `applyExtensionBindings`
|
|
21
|
+
* / `extendResourcesFromExtensions`) through {@link RuntimeBuilderDeps}, one level further delegated.
|
|
22
|
+
*/
|
|
23
|
+
import type { Agent, ThinkingLevel } from "@caupulican/pi-agent-core";
|
|
24
|
+
import type { CustomMessage } from "@caupulican/pi-agent-core/messages";
|
|
25
|
+
import type { SessionManager } from "@caupulican/pi-agent-core/node";
|
|
26
|
+
import type { Api, ImageContent, Model, TextContent, Usage } from "@caupulican/pi-ai";
|
|
27
|
+
import type { ExtensionBindings } from "./agent-session-contracts.ts";
|
|
28
|
+
import type { MemoryProvider as ContextMemoryProvider } from "./context/memory-provider-contract.ts";
|
|
29
|
+
import type { CompactOptions, ContextUsage, ExtensionCommandContextActions, ExtensionContext, ExtensionErrorListener, ExtensionRunner, ExtensionUIContext, SessionStartEvent, ShutdownHandler, ToolInfo } from "./extensions/index.ts";
|
|
30
|
+
import type { ManagedLaneEvent } from "./extensions/types.ts";
|
|
31
|
+
import type { MemoryProvider } from "./memory/memory-provider.ts";
|
|
32
|
+
import type { ModelRegistry } from "./model-registry.ts";
|
|
33
|
+
import type { PromptTemplate } from "./prompt-templates.ts";
|
|
34
|
+
import type { ResourceLoader } from "./resource-loader.ts";
|
|
35
|
+
import type { SettingsManager } from "./settings-manager.ts";
|
|
36
|
+
export interface ExtensionBindingControllerDeps {
|
|
37
|
+
getAgent(): Agent;
|
|
38
|
+
getExtensionRunner(): ExtensionRunner;
|
|
39
|
+
getSessionStartEvent(): SessionStartEvent;
|
|
40
|
+
getCwd(): string;
|
|
41
|
+
getResourceLoader(): ResourceLoader;
|
|
42
|
+
getSessionManager(): SessionManager;
|
|
43
|
+
getSettingsManager(): SettingsManager;
|
|
44
|
+
getModelRegistry(): ModelRegistry;
|
|
45
|
+
getModel(): Model<Api> | undefined;
|
|
46
|
+
getActiveToolNames(): string[];
|
|
47
|
+
getAllTools(): ToolInfo[];
|
|
48
|
+
setActiveToolsByName(toolNames: string[]): void;
|
|
49
|
+
refreshToolRegistry(): void;
|
|
50
|
+
rebuildSystemPrompt(toolNames: string[]): string;
|
|
51
|
+
setBaseSystemPrompt(prompt: string): void;
|
|
52
|
+
getPromptTemplates(): ReadonlyArray<PromptTemplate>;
|
|
53
|
+
getThinkingLevel(): ThinkingLevel;
|
|
54
|
+
setThinkingLevel(level: ThinkingLevel): void;
|
|
55
|
+
setModel(model: Model<Api>): Promise<void>;
|
|
56
|
+
sendCustomMessage(message: Pick<CustomMessage, "customType" | "content" | "display" | "details">, options?: {
|
|
57
|
+
triggerTurn?: boolean;
|
|
58
|
+
deliverAs?: "steer" | "followUp" | "nextTurn";
|
|
59
|
+
}): Promise<void>;
|
|
60
|
+
sendUserMessage(content: string | (TextContent | ImageContent)[], options?: {
|
|
61
|
+
deliverAs?: "steer" | "followUp";
|
|
62
|
+
processSlashCommands?: boolean;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
setSessionName(name: string): void;
|
|
65
|
+
registerMemoryProvider(provider: MemoryProvider): void;
|
|
66
|
+
registerContextMemoryProvider(provider: ContextMemoryProvider): void;
|
|
67
|
+
addSpawnedUsage(usage: Usage, opts?: {
|
|
68
|
+
label?: string;
|
|
69
|
+
sourceSessionId?: string;
|
|
70
|
+
reportId?: string;
|
|
71
|
+
}): string | undefined;
|
|
72
|
+
recordManagedLane(event: ManagedLaneEvent): void;
|
|
73
|
+
isForegroundBusy(): boolean;
|
|
74
|
+
getPendingMessageCount(): number;
|
|
75
|
+
isStreaming(): boolean;
|
|
76
|
+
isCompacting(): boolean;
|
|
77
|
+
getContextUsage(): ContextUsage | undefined;
|
|
78
|
+
compactForExtension(options?: CompactOptions): void;
|
|
79
|
+
reload(): Promise<void>;
|
|
80
|
+
abort(): Promise<void>;
|
|
81
|
+
getSystemPrompt(): string;
|
|
82
|
+
getExtensionCommandContextActions(): ExtensionCommandContextActions | undefined;
|
|
83
|
+
refreshCurrentModelFromRegistry(): void;
|
|
84
|
+
initializeMemory(): Promise<void>;
|
|
85
|
+
getExtensionUIContext(): ExtensionUIContext | undefined;
|
|
86
|
+
setExtensionUIContext(uiContext: ExtensionUIContext | undefined): void;
|
|
87
|
+
getExtensionMode(): ExtensionContext["mode"];
|
|
88
|
+
setExtensionMode(mode: ExtensionContext["mode"]): void;
|
|
89
|
+
setExtensionCommandContextActions(actions: ExtensionCommandContextActions | undefined): void;
|
|
90
|
+
getExtensionShutdownHandler(): ShutdownHandler | undefined;
|
|
91
|
+
setExtensionShutdownHandler(handler: ShutdownHandler | undefined): void;
|
|
92
|
+
getExtensionErrorListener(): ExtensionErrorListener | undefined;
|
|
93
|
+
setExtensionErrorListener(listener: ExtensionErrorListener | undefined): void;
|
|
94
|
+
}
|
|
95
|
+
export declare class ExtensionBindingController {
|
|
96
|
+
private readonly deps;
|
|
97
|
+
private extensionAbortHandler?;
|
|
98
|
+
private extensionErrorUnsubscriber?;
|
|
99
|
+
constructor(deps: ExtensionBindingControllerDeps);
|
|
100
|
+
bindExtensions(bindings: ExtensionBindings): Promise<void>;
|
|
101
|
+
extendResourcesFromExtensions(reason: "startup" | "reload"): Promise<void>;
|
|
102
|
+
private buildExtensionResourcePaths;
|
|
103
|
+
private getExtensionSourceLabel;
|
|
104
|
+
applyExtensionBindings(runner: ExtensionRunner): void;
|
|
105
|
+
bindExtensionCore(runner: ExtensionRunner): void;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=extension-binding-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-binding-controller.d.ts","sourceRoot":"","sources":["../../src/core/extension-binding-controller.ts"],"names":[],"mappings":"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"}
|