@caupulican/pi-adaptative 0.86.3 → 0.86.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/core/agent-paths.d.ts +13 -0
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +23 -0
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts +7 -0
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +12 -4
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +2 -0
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +6 -3
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/subagent-prompt.js +1 -1
- package/dist/core/autonomy/subagent-prompt.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +25 -2
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +67 -0
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/delegation/replay-safe-mailbox-bounds.d.ts +4 -0
- package/dist/core/delegation/replay-safe-mailbox-bounds.d.ts.map +1 -0
- package/dist/core/delegation/replay-safe-mailbox-bounds.js +20 -0
- package/dist/core/delegation/replay-safe-mailbox-bounds.js.map +1 -0
- package/dist/core/delegation/sanitized-context-fork.d.ts +25 -0
- package/dist/core/delegation/sanitized-context-fork.d.ts.map +1 -0
- package/dist/core/delegation/sanitized-context-fork.js +299 -0
- package/dist/core/delegation/sanitized-context-fork.js.map +1 -0
- package/dist/core/delegation/session-root-mailbox.d.ts +75 -0
- package/dist/core/delegation/session-root-mailbox.d.ts.map +1 -0
- package/dist/core/delegation/session-root-mailbox.js +627 -0
- package/dist/core/delegation/session-root-mailbox.js.map +1 -0
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +102 -9
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.js +1307 -125
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-agent-control.d.ts +183 -8
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control.js +778 -48
- package/dist/core/delegation/worker-agent-control.js.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.d.ts +9 -0
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.js +479 -214
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.d.ts +9 -0
- package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.js +21 -2
- package/dist/core/delegation/worker-authority-resolver.js.map +1 -1
- package/dist/core/delegation/worker-context-fork-store.d.ts +71 -0
- package/dist/core/delegation/worker-context-fork-store.d.ts.map +1 -0
- package/dist/core/delegation/worker-context-fork-store.js +437 -0
- package/dist/core/delegation/worker-context-fork-store.js.map +1 -0
- package/dist/core/delegation/worker-context-inheritance-policy.d.ts +18 -0
- package/dist/core/delegation/worker-context-inheritance-policy.d.ts.map +1 -0
- package/dist/core/delegation/worker-context-inheritance-policy.js +28 -0
- package/dist/core/delegation/worker-context-inheritance-policy.js.map +1 -0
- package/dist/core/delegation/worker-conversation-revision.d.ts +31 -0
- package/dist/core/delegation/worker-conversation-revision.d.ts.map +1 -0
- package/dist/core/delegation/worker-conversation-revision.js +203 -0
- package/dist/core/delegation/worker-conversation-revision.js.map +1 -0
- package/dist/core/delegation/worker-conversation-store.d.ts +130 -18
- package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -1
- package/dist/core/delegation/worker-conversation-store.js +1263 -79
- package/dist/core/delegation/worker-conversation-store.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +29 -2
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +625 -111
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-delegation-request.d.ts +2 -0
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts +20 -1
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.js +210 -37
- package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -1
- package/dist/core/delegation/worker-fleet-limits.d.ts +38 -0
- package/dist/core/delegation/worker-fleet-limits.d.ts.map +1 -0
- package/dist/core/delegation/worker-fleet-limits.js +113 -0
- package/dist/core/delegation/worker-fleet-limits.js.map +1 -0
- package/dist/core/delegation/worker-lane-projection.d.ts +1 -0
- package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -1
- package/dist/core/delegation/worker-lane-projection.js +6 -2
- package/dist/core/delegation/worker-lane-projection.js.map +1 -1
- package/dist/core/delegation/worker-lifecycle.d.ts +20 -3
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
- package/dist/core/delegation/worker-lifecycle.js +42 -18
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-notification-coordinator.d.ts +4 -0
- package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-notification-coordinator.js +45 -4
- package/dist/core/delegation/worker-notification-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-provider-turn-protocol.d.ts +50 -0
- package/dist/core/delegation/worker-provider-turn-protocol.d.ts.map +1 -0
- package/dist/core/delegation/worker-provider-turn-protocol.js +185 -0
- package/dist/core/delegation/worker-provider-turn-protocol.js.map +1 -0
- package/dist/core/delegation/worker-recovery-coordinator.d.ts +45 -4
- package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.js +223 -17
- package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-retry-policy.d.ts +36 -0
- package/dist/core/delegation/worker-retry-policy.d.ts.map +1 -0
- package/dist/core/delegation/worker-retry-policy.js +41 -0
- package/dist/core/delegation/worker-retry-policy.js.map +1 -0
- package/dist/core/delegation/worker-runner.d.ts +3 -1
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +4 -2
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-task-view.d.ts +43 -0
- package/dist/core/delegation/worker-task-view.d.ts.map +1 -0
- package/dist/core/delegation/worker-task-view.js +194 -0
- package/dist/core/delegation/worker-task-view.js.map +1 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts +55 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.js +179 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts +2 -2
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-tree-budget-coordinator.js +12 -46
- package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -1
- package/dist/core/keybindings.d.ts +10 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/orchestration/attempt-ordering.d.ts +9 -0
- package/dist/core/orchestration/attempt-ordering.d.ts.map +1 -0
- package/dist/core/orchestration/attempt-ordering.js +29 -0
- package/dist/core/orchestration/attempt-ordering.js.map +1 -0
- package/dist/core/orchestration/capability-gateway.d.ts +19 -0
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +19 -2
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +43 -3
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +24 -0
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/delegation-ledger.d.ts +8 -3
- package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
- package/dist/core/orchestration/delegation-ledger.js +148 -55
- package/dist/core/orchestration/delegation-ledger.js.map +1 -1
- package/dist/core/orchestration/event-store.d.ts +6 -3
- package/dist/core/orchestration/event-store.d.ts.map +1 -1
- package/dist/core/orchestration/event-store.js +228 -30
- package/dist/core/orchestration/event-store.js.map +1 -1
- package/dist/core/orchestration/task-runtime-codecs.d.ts +31 -0
- package/dist/core/orchestration/task-runtime-codecs.d.ts.map +1 -0
- package/dist/core/orchestration/task-runtime-codecs.js +1471 -0
- package/dist/core/orchestration/task-runtime-codecs.js.map +1 -0
- package/dist/core/orchestration/task-runtime-projection.d.ts +30 -0
- package/dist/core/orchestration/task-runtime-projection.d.ts.map +1 -0
- package/dist/core/orchestration/task-runtime-projection.js +340 -0
- package/dist/core/orchestration/task-runtime-projection.js.map +1 -0
- package/dist/core/orchestration/task-runtime-reducer.d.ts +38 -0
- package/dist/core/orchestration/task-runtime-reducer.d.ts.map +1 -0
- package/dist/core/orchestration/task-runtime-reducer.js +1270 -0
- package/dist/core/orchestration/task-runtime-reducer.js.map +1 -0
- package/dist/core/orchestration/task-runtime-state.d.ts +142 -0
- package/dist/core/orchestration/task-runtime-state.d.ts.map +1 -0
- package/dist/core/orchestration/task-runtime-state.js +14 -0
- package/dist/core/orchestration/task-runtime-state.js.map +1 -0
- package/dist/core/orchestration/task-runtime.d.ts +44 -98
- package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
- package/dist/core/orchestration/task-runtime.js +357 -1113
- package/dist/core/orchestration/task-runtime.js.map +1 -1
- package/dist/core/orchestration/worker-context-fork-reference.d.ts +20 -0
- package/dist/core/orchestration/worker-context-fork-reference.d.ts.map +1 -0
- package/dist/core/orchestration/worker-context-fork-reference.js +53 -0
- package/dist/core/orchestration/worker-context-fork-reference.js.map +1 -0
- package/dist/core/research/research-runner.d.ts +2 -0
- package/dist/core/research/research-runner.d.ts.map +1 -1
- package/dist/core/research/research-runner.js +1 -0
- package/dist/core/research/research-runner.js.map +1 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +8 -0
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/secrets/credential-project.d.ts.map +1 -1
- package/dist/core/secrets/credential-project.js +24 -2
- package/dist/core/secrets/credential-project.js.map +1 -1
- package/dist/core/security/secret-text.d.ts +3 -0
- package/dist/core/security/secret-text.d.ts.map +1 -1
- package/dist/core/security/secret-text.js +15 -0
- package/dist/core/security/secret-text.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +160 -8
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +31 -4
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +749 -103
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/activity-lane.d.ts +5 -0
- package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -1
- package/dist/modes/interactive/components/activity-lane.js +133 -49
- package/dist/modes/interactive/components/activity-lane.js.map +1 -1
- package/dist/modes/interactive/components/agents-overlay.d.ts +40 -0
- package/dist/modes/interactive/components/agents-overlay.d.ts.map +1 -0
- package/dist/modes/interactive/components/agents-overlay.js +153 -0
- package/dist/modes/interactive/components/agents-overlay.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +18 -13
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-event-controller.d.ts +1 -1
- package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-event-controller.js +6 -3
- package/dist/modes/interactive/interactive-event-controller.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +5 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +51 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/key-handlers.d.ts +1 -0
- package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
- package/dist/modes/interactive/key-handlers.js +1 -0
- package/dist/modes/interactive/key-handlers.js.map +1 -1
- package/docs/harness-architecture.md +61 -17
- package/docs/settings.md +17 -9
- package/docs/worker-profiles.md +6 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { latestAgentAttemptByDurableOrder } from "../orchestration/attempt-ordering.js";
|
|
2
|
+
import { MAX_ORCHESTRATION_AGENT_BINDINGS } from "../orchestration/contracts.js";
|
|
3
|
+
export const DEFAULT_WORKER_FLEET_LIMITS = Object.freeze({
|
|
4
|
+
maxDepth: 8,
|
|
5
|
+
maxAgentsPerSession: MAX_ORCHESTRATION_AGENT_BINDINGS,
|
|
6
|
+
maxChildrenPerAgent: 64,
|
|
7
|
+
maxQueuedDispatches: 256,
|
|
8
|
+
});
|
|
9
|
+
/** Subjects whose admitted verifier identity has not yet been materialized. */
|
|
10
|
+
export function pendingVerifierSubjectTaskIds(snapshot) {
|
|
11
|
+
const agents = snapshot.agents ?? {};
|
|
12
|
+
const tasks = snapshot.tasks ?? {};
|
|
13
|
+
const attempts = snapshot.attempts ?? {};
|
|
14
|
+
const pending = new Set();
|
|
15
|
+
for (const taskId in tasks) {
|
|
16
|
+
if (!Object.hasOwn(tasks, taskId))
|
|
17
|
+
continue;
|
|
18
|
+
const subject = tasks[taskId];
|
|
19
|
+
if (!subject || subject.verification)
|
|
20
|
+
continue;
|
|
21
|
+
let attempt;
|
|
22
|
+
for (let index = subject.attemptIds.length - 1; index >= 0; index -= 1) {
|
|
23
|
+
attempt = attempts[subject.attemptIds[index]];
|
|
24
|
+
if (attempt)
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
if (!attempt?.dispatch.executionContract?.verifier)
|
|
28
|
+
continue;
|
|
29
|
+
if (attempt.status === "queued" ||
|
|
30
|
+
attempt.status === "leased" ||
|
|
31
|
+
attempt.status === "running" ||
|
|
32
|
+
attempt.status === "suspended" ||
|
|
33
|
+
attempt.result?.nextAction === "independent_verification_required") {
|
|
34
|
+
pending.add(subject.task.taskId);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (pending.size === 0)
|
|
38
|
+
return pending;
|
|
39
|
+
for (const taskId in tasks) {
|
|
40
|
+
if (!Object.hasOwn(tasks, taskId))
|
|
41
|
+
continue;
|
|
42
|
+
const verifierTask = tasks[taskId];
|
|
43
|
+
const verificationOfTaskId = verifierTask?.task.verificationOfTaskId;
|
|
44
|
+
if (!verifierTask || !verificationOfTaskId || !pending.has(verificationOfTaskId))
|
|
45
|
+
continue;
|
|
46
|
+
let verifierAttempt;
|
|
47
|
+
for (let index = verifierTask.attemptIds.length - 1; index >= 0; index -= 1) {
|
|
48
|
+
verifierAttempt = attempts[verifierTask.attemptIds[index]];
|
|
49
|
+
if (verifierAttempt)
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
const verifierAgentId = verifierAttempt?.agentId ?? verifierAttempt?.dispatch.logicalLaneId ?? verifierTask.task.taskId;
|
|
53
|
+
if (agents[verifierAgentId])
|
|
54
|
+
pending.delete(verificationOfTaskId);
|
|
55
|
+
if (pending.size === 0)
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
return pending;
|
|
59
|
+
}
|
|
60
|
+
/** Reserve durable identity slots without applying parent depth or direct-child limits. */
|
|
61
|
+
function evaluateWorkerIdentityHeadroom(agents, requiredAgentSlots, limits = DEFAULT_WORKER_FLEET_LIMITS) {
|
|
62
|
+
if (!Number.isSafeInteger(requiredAgentSlots) || requiredAgentSlots < 0) {
|
|
63
|
+
throw new TypeError("requiredAgentSlots must be a non-negative safe integer.");
|
|
64
|
+
}
|
|
65
|
+
return requiredAgentSlots > limits.maxAgentsPerSession - Object.keys(agents).length
|
|
66
|
+
? { ok: false, reasonCode: "worker_agent_session_limit_reached" }
|
|
67
|
+
: { ok: true };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A persistent-agent turn consumes no implementation identity, but its retained immutable contract
|
|
71
|
+
* can still require a fresh verifier. Protect both that verifier and every earlier reservation.
|
|
72
|
+
*/
|
|
73
|
+
export function evaluateReusableWorkerTaskAdmission(snapshot, agentId, limits = DEFAULT_WORKER_FLEET_LIMITS) {
|
|
74
|
+
const latestAttempt = latestAgentAttemptByDurableOrder(snapshot, agentId);
|
|
75
|
+
const requiredAgentSlots = pendingVerifierSubjectTaskIds(snapshot).size + (latestAttempt?.dispatch.executionContract?.verifier ? 1 : 0);
|
|
76
|
+
return evaluateWorkerIdentityHeadroom(snapshot.agents, requiredAgentSlots, limits);
|
|
77
|
+
}
|
|
78
|
+
/** Evaluate a new durable identity before a task, conversation, or scheduler entry is created. */
|
|
79
|
+
export function evaluateNewWorkerAdmission(agents, parentAgentId, limits = DEFAULT_WORKER_FLEET_LIMITS, requiredAgentSlots = 1) {
|
|
80
|
+
if (!Number.isSafeInteger(requiredAgentSlots) || requiredAgentSlots < 1) {
|
|
81
|
+
throw new TypeError("requiredAgentSlots must be a positive safe integer.");
|
|
82
|
+
}
|
|
83
|
+
const headroom = evaluateWorkerIdentityHeadroom(agents, requiredAgentSlots, limits);
|
|
84
|
+
if (!headroom.ok)
|
|
85
|
+
return headroom;
|
|
86
|
+
if (!parentAgentId)
|
|
87
|
+
return { ok: true, depth: 0 };
|
|
88
|
+
const parent = agents[parentAgentId];
|
|
89
|
+
if (!parent)
|
|
90
|
+
return { ok: false, reasonCode: "worker_agent_parent_unknown" };
|
|
91
|
+
if (parent.status === "retired")
|
|
92
|
+
return { ok: false, reasonCode: "worker_agent_parent_retired" };
|
|
93
|
+
const depth = parent.depth + 1;
|
|
94
|
+
if (depth > limits.maxDepth)
|
|
95
|
+
return { ok: false, reasonCode: "worker_agent_depth_limit_reached" };
|
|
96
|
+
let directChildren = 0;
|
|
97
|
+
for (const agent of Object.values(agents)) {
|
|
98
|
+
if (agent.parentAgentId === parent.agentId)
|
|
99
|
+
directChildren += 1;
|
|
100
|
+
}
|
|
101
|
+
if (directChildren >= limits.maxChildrenPerAgent) {
|
|
102
|
+
return { ok: false, reasonCode: "worker_agent_child_limit_reached" };
|
|
103
|
+
}
|
|
104
|
+
return { ok: true, depth };
|
|
105
|
+
}
|
|
106
|
+
/** Keep one queue slot reserved for an already-admitted mandatory verifier. */
|
|
107
|
+
export function workerQueueHasCapacity(queuedCount, priority, limits = DEFAULT_WORKER_FLEET_LIMITS) {
|
|
108
|
+
if (!Number.isSafeInteger(queuedCount) || queuedCount < 0)
|
|
109
|
+
return false;
|
|
110
|
+
const ceiling = priority ? limits.maxQueuedDispatches : limits.maxQueuedDispatches - 1;
|
|
111
|
+
return queuedCount < ceiling;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=worker-fleet-limits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-fleet-limits.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-fleet-limits.ts"],"names":[],"mappings":"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","sourcesContent":["import { latestAgentAttemptByDurableOrder } from \"../orchestration/attempt-ordering.ts\";\nimport { type AgentBindingContract, MAX_ORCHESTRATION_AGENT_BINDINGS } from \"../orchestration/contracts.ts\";\nimport type { AttemptRuntimeState, TaskRuntimeProjection } from \"../orchestration/task-runtime.ts\";\n\n/**\n * Process-independent safety ceilings for one durable session fleet. These limits bound persisted\n * identity growth and scheduler fan-out; model/provider budgets remain separately authoritative.\n */\nexport interface WorkerFleetLimits {\n\tmaxDepth: number;\n\tmaxAgentsPerSession: number;\n\tmaxChildrenPerAgent: number;\n\tmaxQueuedDispatches: number;\n}\n\nexport const DEFAULT_WORKER_FLEET_LIMITS: Readonly<WorkerFleetLimits> = Object.freeze({\n\tmaxDepth: 8,\n\tmaxAgentsPerSession: MAX_ORCHESTRATION_AGENT_BINDINGS,\n\tmaxChildrenPerAgent: 64,\n\tmaxQueuedDispatches: 256,\n});\n\nexport type NewWorkerAdmission =\n\t| { ok: true; depth: number }\n\t| {\n\t\t\tok: false;\n\t\t\treasonCode:\n\t\t\t\t| \"worker_agent_parent_unknown\"\n\t\t\t\t| \"worker_agent_parent_retired\"\n\t\t\t\t| \"worker_agent_depth_limit_reached\"\n\t\t\t\t| \"worker_agent_child_limit_reached\"\n\t\t\t\t| \"worker_agent_session_limit_reached\";\n\t };\n\nexport type WorkerIdentityHeadroomAdmission =\n\t| { ok: true }\n\t| { ok: false; reasonCode: \"worker_agent_session_limit_reached\" };\n\n/** Subjects whose admitted verifier identity has not yet been materialized. */\nexport function pendingVerifierSubjectTaskIds(\n\tsnapshot: Pick<TaskRuntimeProjection, \"agents\" | \"tasks\" | \"attempts\">,\n): Set<string> {\n\tconst agents = snapshot.agents ?? {};\n\tconst tasks = snapshot.tasks ?? {};\n\tconst attempts = snapshot.attempts ?? {};\n\tconst pending = new Set<string>();\n\tfor (const taskId in tasks) {\n\t\tif (!Object.hasOwn(tasks, taskId)) continue;\n\t\tconst subject = tasks[taskId];\n\t\tif (!subject || subject.verification) continue;\n\t\tlet attempt: AttemptRuntimeState | undefined;\n\t\tfor (let index = subject.attemptIds.length - 1; index >= 0; index -= 1) {\n\t\t\tattempt = attempts[subject.attemptIds[index]!];\n\t\t\tif (attempt) break;\n\t\t}\n\t\tif (!attempt?.dispatch.executionContract?.verifier) continue;\n\t\tif (\n\t\t\tattempt.status === \"queued\" ||\n\t\t\tattempt.status === \"leased\" ||\n\t\t\tattempt.status === \"running\" ||\n\t\t\tattempt.status === \"suspended\" ||\n\t\t\tattempt.result?.nextAction === \"independent_verification_required\"\n\t\t) {\n\t\t\tpending.add(subject.task.taskId);\n\t\t}\n\t}\n\tif (pending.size === 0) return pending;\n\tfor (const taskId in tasks) {\n\t\tif (!Object.hasOwn(tasks, taskId)) continue;\n\t\tconst verifierTask = tasks[taskId];\n\t\tconst verificationOfTaskId = verifierTask?.task.verificationOfTaskId;\n\t\tif (!verifierTask || !verificationOfTaskId || !pending.has(verificationOfTaskId)) continue;\n\t\tlet verifierAttempt: AttemptRuntimeState | undefined;\n\t\tfor (let index = verifierTask.attemptIds.length - 1; index >= 0; index -= 1) {\n\t\t\tverifierAttempt = attempts[verifierTask.attemptIds[index]!];\n\t\t\tif (verifierAttempt) break;\n\t\t}\n\t\tconst verifierAgentId =\n\t\t\tverifierAttempt?.agentId ?? verifierAttempt?.dispatch.logicalLaneId ?? verifierTask.task.taskId;\n\t\tif (agents[verifierAgentId]) pending.delete(verificationOfTaskId);\n\t\tif (pending.size === 0) break;\n\t}\n\treturn pending;\n}\n\n/** Reserve durable identity slots without applying parent depth or direct-child limits. */\nfunction evaluateWorkerIdentityHeadroom(\n\tagents: Readonly<Record<string, AgentBindingContract>>,\n\trequiredAgentSlots: number,\n\tlimits: Readonly<WorkerFleetLimits> = DEFAULT_WORKER_FLEET_LIMITS,\n): WorkerIdentityHeadroomAdmission {\n\tif (!Number.isSafeInteger(requiredAgentSlots) || requiredAgentSlots < 0) {\n\t\tthrow new TypeError(\"requiredAgentSlots must be a non-negative safe integer.\");\n\t}\n\treturn requiredAgentSlots > limits.maxAgentsPerSession - Object.keys(agents).length\n\t\t? { ok: false, reasonCode: \"worker_agent_session_limit_reached\" }\n\t\t: { ok: true };\n}\n\n/**\n * A persistent-agent turn consumes no implementation identity, but its retained immutable contract\n * can still require a fresh verifier. Protect both that verifier and every earlier reservation.\n */\nexport function evaluateReusableWorkerTaskAdmission(\n\tsnapshot: Pick<TaskRuntimeProjection, \"agents\" | \"tasks\" | \"attempts\">,\n\tagentId: string,\n\tlimits: Readonly<WorkerFleetLimits> = DEFAULT_WORKER_FLEET_LIMITS,\n): WorkerIdentityHeadroomAdmission {\n\tconst latestAttempt = latestAgentAttemptByDurableOrder(snapshot, agentId);\n\tconst requiredAgentSlots =\n\t\tpendingVerifierSubjectTaskIds(snapshot).size + (latestAttempt?.dispatch.executionContract?.verifier ? 1 : 0);\n\treturn evaluateWorkerIdentityHeadroom(snapshot.agents, requiredAgentSlots, limits);\n}\n\n/** Evaluate a new durable identity before a task, conversation, or scheduler entry is created. */\nexport function evaluateNewWorkerAdmission(\n\tagents: Readonly<Record<string, AgentBindingContract>>,\n\tparentAgentId?: string,\n\tlimits: Readonly<WorkerFleetLimits> = DEFAULT_WORKER_FLEET_LIMITS,\n\trequiredAgentSlots = 1,\n): NewWorkerAdmission {\n\tif (!Number.isSafeInteger(requiredAgentSlots) || requiredAgentSlots < 1) {\n\t\tthrow new TypeError(\"requiredAgentSlots must be a positive safe integer.\");\n\t}\n\tconst headroom = evaluateWorkerIdentityHeadroom(agents, requiredAgentSlots, limits);\n\tif (!headroom.ok) return headroom;\n\tif (!parentAgentId) return { ok: true, depth: 0 };\n\tconst parent = agents[parentAgentId];\n\tif (!parent) return { ok: false, reasonCode: \"worker_agent_parent_unknown\" };\n\tif (parent.status === \"retired\") return { ok: false, reasonCode: \"worker_agent_parent_retired\" };\n\tconst depth = parent.depth + 1;\n\tif (depth > limits.maxDepth) return { ok: false, reasonCode: \"worker_agent_depth_limit_reached\" };\n\tlet directChildren = 0;\n\tfor (const agent of Object.values(agents)) {\n\t\tif (agent.parentAgentId === parent.agentId) directChildren += 1;\n\t}\n\tif (directChildren >= limits.maxChildrenPerAgent) {\n\t\treturn { ok: false, reasonCode: \"worker_agent_child_limit_reached\" };\n\t}\n\treturn { ok: true, depth };\n}\n\n/** Keep one queue slot reserved for an already-admitted mandatory verifier. */\nexport function workerQueueHasCapacity(\n\tqueuedCount: number,\n\tpriority: boolean,\n\tlimits: Readonly<WorkerFleetLimits> = DEFAULT_WORKER_FLEET_LIMITS,\n): boolean {\n\tif (!Number.isSafeInteger(queuedCount) || queuedCount < 0) return false;\n\tconst ceiling = priority ? limits.maxQueuedDispatches : limits.maxQueuedDispatches - 1;\n\treturn queuedCount < ceiling;\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { LaneRecord } from "../autonomy/lane-tracker.ts";
|
|
2
2
|
import type { AttemptRuntimeState, TaskRuntimeProjection } from "../orchestration/task-runtime.ts";
|
|
3
3
|
export declare const ACTIVE_WORKER_ATTEMPT_STATUSES: ReadonlySet<string>;
|
|
4
|
+
export declare const NONTERMINAL_WORKER_ATTEMPT_STATUSES: ReadonlySet<string>;
|
|
4
5
|
export declare function isManagedWorkerAttempt(attempt: AttemptRuntimeState): boolean;
|
|
5
6
|
export declare function selectedWorkerAttempt(snapshot: TaskRuntimeProjection, taskId: string): AttemptRuntimeState | undefined;
|
|
6
7
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-lane-projection.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-lane-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAsB,MAAM,6BAA6B,CAAC;AAClF,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAGnG,eAAO,MAAM,8BAA8B,EAAE,WAAW,CAAC,MAAM,CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"worker-lane-projection.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-lane-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAsB,MAAM,6BAA6B,CAAC;AAClF,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAGnG,eAAO,MAAM,8BAA8B,EAAE,WAAW,CAAC,MAAM,CAA4C,CAAC;AAC5G,eAAO,MAAM,mCAAmC,EAAE,WAAW,CAAC,MAAM,CAGlE,CAAC;AAEH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAE5E;AAWD,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,qBAAqB,EAC/B,MAAM,EAAE,MAAM,GACZ,mBAAmB,GAAG,SAAS,CAQjC;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CA2C/G;AAED,oEAAoE;AACpE,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,qBAAqB,GAAG,UAAU,EAAE,CAkB7F;AAED,wBAAgB,4BAA4B,CAC3C,QAAQ,EAAE,qBAAqB,EAC/B,aAAa,EAAE,MAAM,GACnB,mBAAmB,GAAG,SAAS,CAQjC"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { deriveWorkerTaskLabel } from "./worker-task-label.js";
|
|
2
2
|
export const ACTIVE_WORKER_ATTEMPT_STATUSES = new Set(["queued", "leased", "running"]);
|
|
3
|
+
export const NONTERMINAL_WORKER_ATTEMPT_STATUSES = new Set([
|
|
4
|
+
...ACTIVE_WORKER_ATTEMPT_STATUSES,
|
|
5
|
+
"suspended",
|
|
6
|
+
]);
|
|
3
7
|
export function isManagedWorkerAttempt(attempt) {
|
|
4
8
|
return attempt.dispatch.executionKind === "managed-process";
|
|
5
9
|
}
|
|
@@ -20,7 +24,7 @@ export function selectedWorkerAttempt(snapshot, taskId) {
|
|
|
20
24
|
if (!task)
|
|
21
25
|
return undefined;
|
|
22
26
|
const attempts = task.attemptIds.map((attemptId) => snapshot.attempts[attemptId]).filter(Boolean);
|
|
23
|
-
return ([...attempts].reverse().find((attempt) => attempt &&
|
|
27
|
+
return ([...attempts].reverse().find((attempt) => attempt && NONTERMINAL_WORKER_ATTEMPT_STATUSES.has(attempt.status)) ??
|
|
24
28
|
attempts.at(-1));
|
|
25
29
|
}
|
|
26
30
|
/**
|
|
@@ -43,7 +47,7 @@ export function projectWorkerLaneRecord(snapshot, taskId) {
|
|
|
43
47
|
: "failed"
|
|
44
48
|
: attempt.status === "queued"
|
|
45
49
|
? "queued"
|
|
46
|
-
: attempt.status === "leased" || attempt.status === "running"
|
|
50
|
+
: attempt.status === "leased" || attempt.status === "running" || attempt.status === "suspended"
|
|
47
51
|
? "running"
|
|
48
52
|
: terminalStatus(attempt);
|
|
49
53
|
const reasonCode = task.verification?.reasonCode ?? attempt.result?.reasonCode ?? attempt.reasonCode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-lane-projection.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-lane-projection.ts"],"names":[],"mappings":"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","sourcesContent":["import type { LaneRecord, LaneTerminalStatus } from \"../autonomy/lane-tracker.ts\";\nimport type { AttemptRuntimeState, TaskRuntimeProjection } from \"../orchestration/task-runtime.ts\";\nimport { deriveWorkerTaskLabel } from \"./worker-task-label.ts\";\n\nexport const ACTIVE_WORKER_ATTEMPT_STATUSES: ReadonlySet<string> = new Set([\"queued\", \"leased\", \"running\"]);\n\nexport function isManagedWorkerAttempt(attempt: AttemptRuntimeState): boolean {\n\treturn attempt.dispatch.executionKind === \"managed-process\";\n}\n\nfunction terminalStatus(attempt: AttemptRuntimeState): LaneTerminalStatus {\n\tif (attempt.status === \"completed\") return \"succeeded\";\n\tif (attempt.status === \"cancelled\") return \"canceled\";\n\tconst reasonCode = attempt.result?.reasonCode ?? attempt.reasonCode ?? \"\";\n\tif (reasonCode.includes(\"budget\")) return \"budget_exhausted\";\n\tif (reasonCode.includes(\"timeout\")) return \"timeout\";\n\treturn \"failed\";\n}\n\nexport function selectedWorkerAttempt(\n\tsnapshot: TaskRuntimeProjection,\n\ttaskId: string,\n): AttemptRuntimeState | undefined {\n\tconst task = snapshot.tasks[taskId];\n\tif (!task) return undefined;\n\tconst attempts = task.attemptIds.map((attemptId) => snapshot.attempts[attemptId]).filter(Boolean);\n\treturn (\n\t\t[...attempts].reverse().find((attempt) => attempt && ACTIVE_WORKER_ATTEMPT_STATUSES.has(attempt.status)) ??\n\t\tattempts.at(-1)\n\t);\n}\n\n/**\n * One-way compatibility projection from durable orchestration state. A LaneRecord is never read\n * back to decide lifecycle, retry, verification, or notification transitions.\n */\nexport function projectWorkerLaneRecord(snapshot: TaskRuntimeProjection, taskId: string): LaneRecord | undefined {\n\tconst task = snapshot.tasks[taskId];\n\tconst attempt = selectedWorkerAttempt(snapshot, taskId);\n\tif (!task || !attempt) return undefined;\n\tconst managed = isManagedWorkerAttempt(attempt);\n\tconst objective = snapshot.objectives[task.task.objectiveId];\n\tconst awaitingVerification =\n\t\tattempt.result?.nextAction === \"independent_verification_required\" && task.verification === undefined;\n\tconst status = awaitingVerification\n\t\t? \"running\"\n\t\t: task.verification\n\t\t\t? task.verification.verdict === \"accepted\"\n\t\t\t\t? \"succeeded\"\n\t\t\t\t: \"failed\"\n\t\t\t: attempt.status === \"queued\"\n\t\t\t\t? \"queued\"\n\t\t\t\t: attempt.status === \"leased\" || attempt.status === \"running\"\n\t\t\t\t\t? \"running\"\n\t\t\t\t\t: terminalStatus(attempt);\n\tconst reasonCode = task.verification?.reasonCode ?? attempt.result?.reasonCode ?? attempt.reasonCode;\n\tconst genericTitle = `Delegated ${task.task.role} work`;\n\tconst label = deriveWorkerTaskLabel(\n\t\ttask.task.title === genericTitle ? task.task.description : task.task.title,\n\t\tgenericTitle,\n\t);\n\tconst goalId = objective?.objective.objectiveId.startsWith(\"goal:\")\n\t\t? objective.objective.objectiveId.slice(\"goal:\".length)\n\t\t: undefined;\n\treturn {\n\t\tlaneId: managed ? (attempt.dispatch.logicalLaneId ?? taskId) : taskId,\n\t\ttype: managed ? \"tmux-worker\" : \"worker\",\n\t\tstatus,\n\t\tlabel,\n\t\tprofileId: attempt.dispatch.profileId,\n\t\t...(reasonCode ? { reasonCode } : {}),\n\t\t...(attempt.status !== \"queued\" ? { startedAt: attempt.createdAt } : {}),\n\t\t...(status === \"queued\" || status === \"running\"\n\t\t\t? {}\n\t\t\t: { completedAt: task.verification?.completedAt ?? attempt.updatedAt }),\n\t\t...(attempt.result?.usage.costUsd !== undefined ? { costUsd: attempt.result.usage.costUsd } : {}),\n\t\t...(goalId ? { goalId } : {}),\n\t\t...(attempt.dispatch.worktreeLaneKey ? { worktreeLaneKey: attempt.dispatch.worktreeLaneKey } : {}),\n\t};\n}\n\n/** Latest durable turn for each externally managed logical lane. */\nexport function projectManagedWorkerLaneRecords(snapshot: TaskRuntimeProjection): LaneRecord[] {\n\tconst latest = new Map<string, { sequence: number; createdAt: string; record: LaneRecord }>();\n\tfor (const taskId of Object.keys(snapshot.tasks)) {\n\t\tconst attempt = selectedWorkerAttempt(snapshot, taskId);\n\t\tif (!attempt || !isManagedWorkerAttempt(attempt)) continue;\n\t\tconst record = projectWorkerLaneRecord(snapshot, taskId);\n\t\tif (!record) continue;\n\t\tconst sequence = attempt.dispatch.dispatchSequence ?? 1;\n\t\tconst current = latest.get(record.laneId);\n\t\tif (\n\t\t\t!current ||\n\t\t\tsequence > current.sequence ||\n\t\t\t(sequence === current.sequence && attempt.createdAt.localeCompare(current.createdAt) > 0)\n\t\t) {\n\t\t\tlatest.set(record.laneId, { sequence, createdAt: attempt.createdAt, record });\n\t\t}\n\t}\n\treturn [...latest.values()].map((entry) => entry.record);\n}\n\nexport function selectedManagedWorkerAttempt(\n\tsnapshot: TaskRuntimeProjection,\n\tlogicalLaneId: string,\n): AttemptRuntimeState | undefined {\n\treturn Object.values(snapshot.attempts)\n\t\t.filter((attempt) => isManagedWorkerAttempt(attempt) && attempt.dispatch.logicalLaneId === logicalLaneId)\n\t\t.sort((left, right) => {\n\t\t\tconst sequence = (left.dispatch.dispatchSequence ?? 1) - (right.dispatch.dispatchSequence ?? 1);\n\t\t\treturn sequence !== 0 ? sequence : left.createdAt.localeCompare(right.createdAt);\n\t\t})\n\t\t.at(-1);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"worker-lane-projection.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-lane-projection.ts"],"names":[],"mappings":"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","sourcesContent":["import type { LaneRecord, LaneTerminalStatus } from \"../autonomy/lane-tracker.ts\";\nimport type { AttemptRuntimeState, TaskRuntimeProjection } from \"../orchestration/task-runtime.ts\";\nimport { deriveWorkerTaskLabel } from \"./worker-task-label.ts\";\n\nexport const ACTIVE_WORKER_ATTEMPT_STATUSES: ReadonlySet<string> = new Set([\"queued\", \"leased\", \"running\"]);\nexport const NONTERMINAL_WORKER_ATTEMPT_STATUSES: ReadonlySet<string> = new Set([\n\t...ACTIVE_WORKER_ATTEMPT_STATUSES,\n\t\"suspended\",\n]);\n\nexport function isManagedWorkerAttempt(attempt: AttemptRuntimeState): boolean {\n\treturn attempt.dispatch.executionKind === \"managed-process\";\n}\n\nfunction terminalStatus(attempt: AttemptRuntimeState): LaneTerminalStatus {\n\tif (attempt.status === \"completed\") return \"succeeded\";\n\tif (attempt.status === \"cancelled\") return \"canceled\";\n\tconst reasonCode = attempt.result?.reasonCode ?? attempt.reasonCode ?? \"\";\n\tif (reasonCode.includes(\"budget\")) return \"budget_exhausted\";\n\tif (reasonCode.includes(\"timeout\")) return \"timeout\";\n\treturn \"failed\";\n}\n\nexport function selectedWorkerAttempt(\n\tsnapshot: TaskRuntimeProjection,\n\ttaskId: string,\n): AttemptRuntimeState | undefined {\n\tconst task = snapshot.tasks[taskId];\n\tif (!task) return undefined;\n\tconst attempts = task.attemptIds.map((attemptId) => snapshot.attempts[attemptId]).filter(Boolean);\n\treturn (\n\t\t[...attempts].reverse().find((attempt) => attempt && NONTERMINAL_WORKER_ATTEMPT_STATUSES.has(attempt.status)) ??\n\t\tattempts.at(-1)\n\t);\n}\n\n/**\n * One-way compatibility projection from durable orchestration state. A LaneRecord is never read\n * back to decide lifecycle, retry, verification, or notification transitions.\n */\nexport function projectWorkerLaneRecord(snapshot: TaskRuntimeProjection, taskId: string): LaneRecord | undefined {\n\tconst task = snapshot.tasks[taskId];\n\tconst attempt = selectedWorkerAttempt(snapshot, taskId);\n\tif (!task || !attempt) return undefined;\n\tconst managed = isManagedWorkerAttempt(attempt);\n\tconst objective = snapshot.objectives[task.task.objectiveId];\n\tconst awaitingVerification =\n\t\tattempt.result?.nextAction === \"independent_verification_required\" && task.verification === undefined;\n\tconst status = awaitingVerification\n\t\t? \"running\"\n\t\t: task.verification\n\t\t\t? task.verification.verdict === \"accepted\"\n\t\t\t\t? \"succeeded\"\n\t\t\t\t: \"failed\"\n\t\t\t: attempt.status === \"queued\"\n\t\t\t\t? \"queued\"\n\t\t\t\t: attempt.status === \"leased\" || attempt.status === \"running\" || attempt.status === \"suspended\"\n\t\t\t\t\t? \"running\"\n\t\t\t\t\t: terminalStatus(attempt);\n\tconst reasonCode = task.verification?.reasonCode ?? attempt.result?.reasonCode ?? attempt.reasonCode;\n\tconst genericTitle = `Delegated ${task.task.role} work`;\n\tconst label = deriveWorkerTaskLabel(\n\t\ttask.task.title === genericTitle ? task.task.description : task.task.title,\n\t\tgenericTitle,\n\t);\n\tconst goalId = objective?.objective.objectiveId.startsWith(\"goal:\")\n\t\t? objective.objective.objectiveId.slice(\"goal:\".length)\n\t\t: undefined;\n\treturn {\n\t\tlaneId: managed ? (attempt.dispatch.logicalLaneId ?? taskId) : taskId,\n\t\ttype: managed ? \"tmux-worker\" : \"worker\",\n\t\tstatus,\n\t\tlabel,\n\t\tprofileId: attempt.dispatch.profileId,\n\t\t...(reasonCode ? { reasonCode } : {}),\n\t\t...(attempt.status !== \"queued\" ? { startedAt: attempt.createdAt } : {}),\n\t\t...(status === \"queued\" || status === \"running\"\n\t\t\t? {}\n\t\t\t: { completedAt: task.verification?.completedAt ?? attempt.updatedAt }),\n\t\t...(attempt.result?.usage.costUsd !== undefined ? { costUsd: attempt.result.usage.costUsd } : {}),\n\t\t...(goalId ? { goalId } : {}),\n\t\t...(attempt.dispatch.worktreeLaneKey ? { worktreeLaneKey: attempt.dispatch.worktreeLaneKey } : {}),\n\t};\n}\n\n/** Latest durable turn for each externally managed logical lane. */\nexport function projectManagedWorkerLaneRecords(snapshot: TaskRuntimeProjection): LaneRecord[] {\n\tconst latest = new Map<string, { sequence: number; createdAt: string; record: LaneRecord }>();\n\tfor (const taskId of Object.keys(snapshot.tasks)) {\n\t\tconst attempt = selectedWorkerAttempt(snapshot, taskId);\n\t\tif (!attempt || !isManagedWorkerAttempt(attempt)) continue;\n\t\tconst record = projectWorkerLaneRecord(snapshot, taskId);\n\t\tif (!record) continue;\n\t\tconst sequence = attempt.dispatch.dispatchSequence ?? 1;\n\t\tconst current = latest.get(record.laneId);\n\t\tif (\n\t\t\t!current ||\n\t\t\tsequence > current.sequence ||\n\t\t\t(sequence === current.sequence && attempt.createdAt.localeCompare(current.createdAt) > 0)\n\t\t) {\n\t\t\tlatest.set(record.laneId, { sequence, createdAt: attempt.createdAt, record });\n\t\t}\n\t}\n\treturn [...latest.values()].map((entry) => entry.record);\n}\n\nexport function selectedManagedWorkerAttempt(\n\tsnapshot: TaskRuntimeProjection,\n\tlogicalLaneId: string,\n): AttemptRuntimeState | undefined {\n\treturn Object.values(snapshot.attempts)\n\t\t.filter((attempt) => isManagedWorkerAttempt(attempt) && attempt.dispatch.logicalLaneId === logicalLaneId)\n\t\t.sort((left, right) => {\n\t\t\tconst sequence = (left.dispatch.dispatchSequence ?? 1) - (right.dispatch.dispatchSequence ?? 1);\n\t\t\treturn sequence !== 0 ? sequence : left.createdAt.localeCompare(right.createdAt);\n\t\t})\n\t\t.at(-1);\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { LaneRecord } from "../autonomy/lane-tracker.ts";
|
|
2
2
|
import type { GoalState } from "../goals/goal-state.ts";
|
|
3
|
-
import type { AgentBindingContract, AgentResumeContext, AttemptUsageSnapshot, ExecutionGrant, WorkerExecutionContract, WorkerResultContract, WorkerRole } from "../orchestration/contracts.ts";
|
|
3
|
+
import type { AgentBindingContract, AgentResumeContext, AttemptRetryState, AttemptUsageSnapshot, ExecutionGrant, WorkerExecutionContract, WorkerResultContract, WorkerRole } from "../orchestration/contracts.ts";
|
|
4
4
|
import { DelegationOrchestrationLedger, type PrepareDelegationInput, type PrepareManagedDelegationInput, type StartedDelegationAttempt } from "../orchestration/delegation-ledger.ts";
|
|
5
|
-
import type { AttemptRuntimeState, TaskRuntimeProjection } from "../orchestration/task-runtime.ts";
|
|
5
|
+
import type { AttemptDispatchReadiness, AttemptRuntimeState, TaskRuntimeProjection } from "../orchestration/task-runtime.ts";
|
|
6
6
|
export type PendingVerificationRecovery = {
|
|
7
7
|
action: "dispatch";
|
|
8
8
|
subjectTaskId: string;
|
|
@@ -30,15 +30,20 @@ export declare class WorkerLifecycle {
|
|
|
30
30
|
agentDir: string;
|
|
31
31
|
sessionId: string;
|
|
32
32
|
isProcessAlive?: (pid: number) => boolean;
|
|
33
|
+
now?: () => number;
|
|
33
34
|
});
|
|
34
35
|
prepare(input: Omit<PrepareDelegationInput, "laneId">, laneId?: string): {
|
|
35
36
|
record: LaneRecord;
|
|
36
37
|
attempt: AttemptRuntimeState;
|
|
37
38
|
};
|
|
39
|
+
/** Return the next generated lane id without reserving it or changing lifecycle state. */
|
|
40
|
+
getNextAvailableLaneIdCandidate(): string;
|
|
38
41
|
/** Queue the next distinct task/attempt for an idle logical agent. */
|
|
39
42
|
prepareAgentTurn(input: {
|
|
40
43
|
agentId: string;
|
|
41
44
|
instructions: string;
|
|
45
|
+
controlMessageId?: string;
|
|
46
|
+
dependsOnTaskIds?: readonly string[];
|
|
42
47
|
}): {
|
|
43
48
|
record: LaneRecord;
|
|
44
49
|
attempt: AttemptRuntimeState;
|
|
@@ -49,6 +54,8 @@ export declare class WorkerLifecycle {
|
|
|
49
54
|
role: WorkerRole;
|
|
50
55
|
resumeContext: AgentResumeContext;
|
|
51
56
|
}): AgentBindingContract;
|
|
57
|
+
/** Retire one idle logical worker while retaining its durable binding and transcript identity. */
|
|
58
|
+
retireAgent(agentId: string): AgentBindingContract;
|
|
52
59
|
prepareManaged(input: PrepareManagedDelegationInput & {
|
|
53
60
|
leaseTtlMs: number;
|
|
54
61
|
compileGrant(target: {
|
|
@@ -86,9 +93,17 @@ export declare class WorkerLifecycle {
|
|
|
86
93
|
leaseId: string;
|
|
87
94
|
fencingToken: number;
|
|
88
95
|
reasonCode: string;
|
|
96
|
+
retry?: AttemptRetryState;
|
|
89
97
|
}): void;
|
|
90
98
|
resumeAgent(laneId: string, agentId: string, leaseTtlMs: number, ownerId?: string): StartedDelegationAttempt;
|
|
91
|
-
suspendAgent(laneId: string, agentId: string, ownerId: string, reasonCode?: string): void;
|
|
99
|
+
suspendAgent(laneId: string, agentId: string, ownerId: string, reasonCode?: string, retry?: AttemptRetryState): void;
|
|
100
|
+
scheduleAgentRetry(args: {
|
|
101
|
+
laneId: string;
|
|
102
|
+
agentId: string;
|
|
103
|
+
ownerId: string;
|
|
104
|
+
reasonCode: string;
|
|
105
|
+
retry: AttemptRetryState;
|
|
106
|
+
}): AttemptRuntimeState;
|
|
92
107
|
bindGrant(attemptId: string, grant: ExecutionGrant): void;
|
|
93
108
|
finish(result: WorkerResultContract, options?: {
|
|
94
109
|
notify?: boolean;
|
|
@@ -112,6 +127,8 @@ export declare class WorkerLifecycle {
|
|
|
112
127
|
getAgent(agentId: string): AgentBindingContract | undefined;
|
|
113
128
|
getLatestAgentAttempt(agentId: string): AttemptRuntimeState | undefined;
|
|
114
129
|
getTaskRuntimeSnapshot(): TaskRuntimeProjection;
|
|
130
|
+
/** Read-only dispatch gate for an already persisted queued worker attempt. */
|
|
131
|
+
getAttemptDispatchReadiness(attemptId: string): AttemptDispatchReadiness;
|
|
115
132
|
getRecords(): LaneRecord[];
|
|
116
133
|
getManagedRecords(): LaneRecord[];
|
|
117
134
|
getAllRecords(): LaneRecord[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"worker-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { sameAgentResumeIdentity } from "../orchestration/agent-resume.js";
|
|
2
|
+
import { latestAgentAttemptByDurableOrder } from "../orchestration/attempt-ordering.js";
|
|
2
3
|
import { DelegationOrchestrationLedger, } from "../orchestration/delegation-ledger.js";
|
|
3
4
|
import { verifierWorkerExecutionContract } from "../orchestration/worker-execution-contract.js";
|
|
4
|
-
import { ACTIVE_WORKER_ATTEMPT_STATUSES, isManagedWorkerAttempt, projectManagedWorkerLaneRecords, projectWorkerLaneRecord, selectedManagedWorkerAttempt, selectedWorkerAttempt, } from "./worker-lane-projection.js";
|
|
5
|
+
import { ACTIVE_WORKER_ATTEMPT_STATUSES, isManagedWorkerAttempt, NONTERMINAL_WORKER_ATTEMPT_STATUSES, projectManagedWorkerLaneRecords, projectWorkerLaneRecord, selectedManagedWorkerAttempt, selectedWorkerAttempt, } from "./worker-lane-projection.js";
|
|
5
6
|
import { isLocalProcessAlive, isLocalWorkerProcessOwnerProvenDead } from "./worker-process-owner.js";
|
|
6
7
|
/**
|
|
7
8
|
* Sole owner of in-process worker lifecycle state. LaneRecord is a compatibility/UI projection;
|
|
@@ -20,18 +21,26 @@ export class WorkerLifecycle {
|
|
|
20
21
|
}
|
|
21
22
|
prepare(input, laneId) {
|
|
22
23
|
let selectedLaneId = laneId;
|
|
24
|
+
const generatedLaneId = !selectedLaneId;
|
|
23
25
|
if (!selectedLaneId) {
|
|
24
|
-
|
|
25
|
-
while (snapshot.tasks[`worker-${this.nextLaneNumber}`])
|
|
26
|
-
this.nextLaneNumber += 1;
|
|
27
|
-
selectedLaneId = `worker-${this.nextLaneNumber++}`;
|
|
26
|
+
selectedLaneId = this.getNextAvailableLaneIdCandidate();
|
|
28
27
|
}
|
|
29
28
|
const attempt = this.ledger.prepare({ ...input, laneId: selectedLaneId });
|
|
29
|
+
if (generatedLaneId)
|
|
30
|
+
this.nextLaneNumber = Number(selectedLaneId.slice("worker-".length)) + 1;
|
|
30
31
|
const record = this.getRecord(selectedLaneId);
|
|
31
32
|
if (!record)
|
|
32
33
|
throw new Error(`Durable worker '${selectedLaneId}' was not projected after enqueue.`);
|
|
33
34
|
return { record, attempt };
|
|
34
35
|
}
|
|
36
|
+
/** Return the next generated lane id without reserving it or changing lifecycle state. */
|
|
37
|
+
getNextAvailableLaneIdCandidate() {
|
|
38
|
+
const snapshot = this.ledger.runtime.getSnapshot();
|
|
39
|
+
let candidateNumber = this.nextLaneNumber;
|
|
40
|
+
while (snapshot.tasks[`worker-${candidateNumber}`])
|
|
41
|
+
candidateNumber += 1;
|
|
42
|
+
return `worker-${candidateNumber}`;
|
|
43
|
+
}
|
|
35
44
|
/** Queue the next distinct task/attempt for an idle logical agent. */
|
|
36
45
|
prepareAgentTurn(input) {
|
|
37
46
|
const attempt = this.ledger.prepareAgentTurn(input);
|
|
@@ -52,6 +61,10 @@ export class WorkerLifecycle {
|
|
|
52
61
|
}
|
|
53
62
|
return existing;
|
|
54
63
|
}
|
|
64
|
+
/** Retire one idle logical worker while retaining its durable binding and transcript identity. */
|
|
65
|
+
retireAgent(agentId) {
|
|
66
|
+
return this.ledger.runtime.retireAgent(agentId);
|
|
67
|
+
}
|
|
55
68
|
prepareManaged(input) {
|
|
56
69
|
const before = selectedManagedWorkerAttempt(this.ledger.runtime.getSnapshot(), input.laneId);
|
|
57
70
|
if (before?.dispatch.dispatchSequence === input.dispatchSequence) {
|
|
@@ -173,17 +186,19 @@ export class WorkerLifecycle {
|
|
|
173
186
|
leaseId: args.leaseId,
|
|
174
187
|
fencingToken: args.fencingToken,
|
|
175
188
|
reasonCode: args.reasonCode,
|
|
189
|
+
...(args.retry ? { retry: args.retry } : {}),
|
|
176
190
|
});
|
|
177
191
|
}
|
|
178
192
|
resumeAgent(laneId, agentId, leaseTtlMs, ownerId = agentId) {
|
|
179
193
|
const attempt = this.getActiveAttempt(laneId);
|
|
180
194
|
if (!attempt)
|
|
181
195
|
throw new Error(`Durable worker '${laneId}' has no resumable attempt.`);
|
|
182
|
-
this.ledger.runtime.
|
|
196
|
+
this.ledger.runtime.assertAttemptReadyForResume(attempt.attemptId);
|
|
197
|
+
this.ledger.runtime.requestAgentResume(agentId, attempt.attemptId);
|
|
183
198
|
const lease = this.ledger.runtime.resumeAttempt(attempt.attemptId, agentId, leaseTtlMs, ownerId);
|
|
184
199
|
return this.startedHandle(this.ledger.runtime.startAttempt(attempt.attemptId, lease.leaseId, lease.fencingToken));
|
|
185
200
|
}
|
|
186
|
-
suspendAgent(laneId, agentId, ownerId, reasonCode = "agent_interrupted") {
|
|
201
|
+
suspendAgent(laneId, agentId, ownerId, reasonCode = "agent_interrupted", retry) {
|
|
187
202
|
const attempt = this.getActiveAttempt(laneId);
|
|
188
203
|
if (!attempt || attempt.agentId !== agentId || !attempt.lease) {
|
|
189
204
|
throw new Error(`Logical worker '${agentId}' has no live attempt for interruption.`);
|
|
@@ -194,8 +209,16 @@ export class WorkerLifecycle {
|
|
|
194
209
|
leaseId: attempt.lease.leaseId,
|
|
195
210
|
fencingToken: attempt.lease.fencingToken,
|
|
196
211
|
reasonCode,
|
|
212
|
+
...(retry ? { retry } : {}),
|
|
197
213
|
});
|
|
198
214
|
}
|
|
215
|
+
scheduleAgentRetry(args) {
|
|
216
|
+
this.suspendAgent(args.laneId, args.agentId, args.ownerId, args.reasonCode, args.retry);
|
|
217
|
+
const attempt = this.getActiveAttempt(args.laneId);
|
|
218
|
+
if (!attempt)
|
|
219
|
+
throw new Error(`Durable worker '${args.laneId}' disappeared after retry suspension.`);
|
|
220
|
+
return attempt;
|
|
221
|
+
}
|
|
199
222
|
bindGrant(attemptId, grant) {
|
|
200
223
|
this.ledger.runtime.bindAttemptGrant(attemptId, grant);
|
|
201
224
|
}
|
|
@@ -260,7 +283,6 @@ export class WorkerLifecycle {
|
|
|
260
283
|
return [];
|
|
261
284
|
const verifier = Object.values(snapshot.tasks)
|
|
262
285
|
.filter((candidate) => candidate.task.verificationOfTaskId === subject.task.taskId)
|
|
263
|
-
.sort((left, right) => left.task.createdAt.localeCompare(right.task.createdAt))
|
|
264
286
|
.at(-1);
|
|
265
287
|
if (!verifier) {
|
|
266
288
|
const verifierExecutionContract = implementationAttempt.dispatch.executionContract
|
|
@@ -278,13 +300,14 @@ export class WorkerLifecycle {
|
|
|
278
300
|
];
|
|
279
301
|
}
|
|
280
302
|
const verifierAttempt = selectedWorkerAttempt(snapshot, verifier.task.taskId);
|
|
281
|
-
if (!verifierAttempt ||
|
|
303
|
+
if (!verifierAttempt || NONTERMINAL_WORKER_ATTEMPT_STATUSES.has(verifierAttempt.status))
|
|
282
304
|
return [];
|
|
283
|
-
const review = verifierAttempt.result?.evidence.find((evidence) => evidence.
|
|
305
|
+
const review = verifierAttempt.result?.evidence.find((evidence) => evidence.trusted &&
|
|
306
|
+
evidence.kind === "review" &&
|
|
307
|
+
evidence.metadata?.subjectTaskId === subject.task.taskId &&
|
|
308
|
+
(evidence.metadata.verdict === "accepted" || evidence.metadata.verdict === "rejected"));
|
|
284
309
|
const verdictValue = review?.metadata?.verdict;
|
|
285
|
-
const verdict =
|
|
286
|
-
? verdictValue
|
|
287
|
-
: "inconclusive";
|
|
310
|
+
const verdict = verdictValue === "accepted" || verdictValue === "rejected" ? verdictValue : "inconclusive";
|
|
288
311
|
const reasonCodesValue = review?.metadata?.reasonCodes;
|
|
289
312
|
const reasonCodes = Array.isArray(reasonCodesValue)
|
|
290
313
|
? reasonCodesValue.filter((reasonCode) => typeof reasonCode === "string")
|
|
@@ -312,14 +335,15 @@ export class WorkerLifecycle {
|
|
|
312
335
|
return this.ledger.runtime.getSnapshot().agents[agentId];
|
|
313
336
|
}
|
|
314
337
|
getLatestAgentAttempt(agentId) {
|
|
315
|
-
return
|
|
316
|
-
.filter((attempt) => attempt.agentId === agentId || attempt.dispatch.logicalLaneId === agentId)
|
|
317
|
-
.sort((left, right) => left.createdAt.localeCompare(right.createdAt))
|
|
318
|
-
.at(-1);
|
|
338
|
+
return latestAgentAttemptByDurableOrder(this.ledger.runtime.getSnapshot(), agentId);
|
|
319
339
|
}
|
|
320
340
|
getTaskRuntimeSnapshot() {
|
|
321
341
|
return this.ledger.runtime.getSnapshot();
|
|
322
342
|
}
|
|
343
|
+
/** Read-only dispatch gate for an already persisted queued worker attempt. */
|
|
344
|
+
getAttemptDispatchReadiness(attemptId) {
|
|
345
|
+
return this.ledger.runtime.getAttemptDispatchReadiness(attemptId);
|
|
346
|
+
}
|
|
323
347
|
getRecords() {
|
|
324
348
|
const snapshot = this.ledger.runtime.getSnapshot();
|
|
325
349
|
return Object.keys(snapshot.tasks).flatMap((taskId) => {
|
|
@@ -407,7 +431,7 @@ export class WorkerLifecycle {
|
|
|
407
431
|
}
|
|
408
432
|
enqueueTerminalNotification(record) {
|
|
409
433
|
const attempt = this.getActiveAttempt(record.laneId) ?? this.getManagedAttempt(record.laneId);
|
|
410
|
-
if (!attempt ||
|
|
434
|
+
if (!attempt || NONTERMINAL_WORKER_ATTEMPT_STATUSES.has(attempt.status))
|
|
411
435
|
return;
|
|
412
436
|
const snapshot = this.ledger.runtime.getSnapshot();
|
|
413
437
|
const task = snapshot.tasks[attempt.taskId];
|