@caupulican/pi-adaptative 0.85.8 → 0.86.2
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 +42 -0
- package/dist/core/agent-paths.d.ts +6 -3
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +10 -3
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/agent-session.d.ts +5 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +19 -8
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +11 -5
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +34 -8
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/subagent-prompt.d.ts +3 -3
- package/dist/core/autonomy/subagent-prompt.js +9 -9
- package/dist/core/autonomy/subagent-prompt.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +10 -8
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +23 -13
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/bash-execution-controller.d.ts +4 -0
- package/dist/core/bash-execution-controller.d.ts.map +1 -1
- package/dist/core/bash-execution-controller.js +11 -4
- package/dist/core/bash-execution-controller.js.map +1 -1
- package/dist/core/bash-executor.d.ts +2 -0
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +2 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/capability-contract.d.ts +1 -1
- package/dist/core/capability-contract.d.ts.map +1 -1
- package/dist/core/capability-contract.js +0 -1
- package/dist/core/capability-contract.js.map +1 -1
- package/dist/core/default-tool-surface.d.ts +1 -0
- package/dist/core/default-tool-surface.d.ts.map +1 -1
- package/dist/core/default-tool-surface.js +3 -2
- package/dist/core/default-tool-surface.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +27 -8
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.js +191 -33
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-agent-control.d.ts +45 -6
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control.js +110 -13
- package/dist/core/delegation/worker-agent-control.js.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.js +177 -158
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.d.ts +23 -0
- package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -0
- package/dist/core/delegation/worker-authority-resolver.js +128 -0
- package/dist/core/delegation/worker-authority-resolver.js.map +1 -0
- package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -1
- package/dist/core/delegation/worker-conversation-store.js +1 -1
- package/dist/core/delegation/worker-conversation-store.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +7 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +260 -87
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-delegation-request.d.ts +25 -4
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js +90 -1
- package/dist/core/delegation/worker-delegation-request.js.map +1 -1
- package/dist/core/delegation/worker-execution-policy.d.ts +2 -0
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
- package/dist/core/delegation/worker-execution-policy.js +22 -12
- package/dist/core/delegation/worker-execution-policy.js.map +1 -1
- package/dist/core/delegation/worker-lifecycle.d.ts +1 -0
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
- package/dist/core/delegation/worker-lifecycle.js +4 -2
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts +0 -2
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.js +8 -35
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.js +1 -0
- package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-runner.d.ts +6 -1
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +20 -6
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts +47 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.js +210 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -0
- package/dist/core/memory/providers/file-store.d.ts +2 -0
- package/dist/core/memory/providers/file-store.d.ts.map +1 -1
- package/dist/core/memory/providers/file-store.js +22 -20
- package/dist/core/memory/providers/file-store.js.map +1 -1
- package/dist/core/models/runtime-process.d.ts.map +1 -1
- package/dist/core/models/runtime-process.js +5 -18
- package/dist/core/models/runtime-process.js.map +1 -1
- package/dist/core/orchestration/bounded-string-array.d.ts +11 -0
- package/dist/core/orchestration/bounded-string-array.d.ts.map +1 -0
- package/dist/core/orchestration/bounded-string-array.js +17 -0
- package/dist/core/orchestration/bounded-string-array.js.map +1 -0
- package/dist/core/orchestration/capability-gateway.d.ts +16 -0
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +38 -0
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +11 -3
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +0 -1
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/delegation-ledger.d.ts +1 -0
- package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
- package/dist/core/orchestration/delegation-ledger.js +3 -0
- package/dist/core/orchestration/delegation-ledger.js.map +1 -1
- package/dist/core/orchestration/event-store.d.ts +12 -10
- package/dist/core/orchestration/event-store.d.ts.map +1 -1
- package/dist/core/orchestration/event-store.js +94 -104
- package/dist/core/orchestration/event-store.js.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.d.ts +2 -2
- package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.js +4 -1
- package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
- package/dist/core/orchestration/policy-compiler.d.ts.map +1 -1
- package/dist/core/orchestration/policy-compiler.js +8 -9
- package/dist/core/orchestration/policy-compiler.js.map +1 -1
- package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
- package/dist/core/orchestration/profile-registry.js +4 -10
- package/dist/core/orchestration/profile-registry.js.map +1 -1
- package/dist/core/orchestration/task-runtime.d.ts +1 -0
- package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
- package/dist/core/orchestration/task-runtime.js +58 -3
- package/dist/core/orchestration/task-runtime.js.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.js +10 -17
- package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
- package/dist/core/risk-classifier.js +3 -3
- package/dist/core/risk-classifier.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +4 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +34 -15
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/secrets/bitwarden-credential-storage.d.ts +51 -0
- package/dist/core/secrets/bitwarden-credential-storage.d.ts.map +1 -0
- package/dist/core/secrets/bitwarden-credential-storage.js +345 -0
- package/dist/core/secrets/bitwarden-credential-storage.js.map +1 -0
- package/dist/core/secrets/credential-exposure-guard.d.ts +8 -4
- package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -1
- package/dist/core/secrets/credential-exposure-guard.js +30 -31
- package/dist/core/secrets/credential-exposure-guard.js.map +1 -1
- package/dist/core/secrets/credential-manager.d.ts +109 -0
- package/dist/core/secrets/credential-manager.d.ts.map +1 -0
- package/dist/core/secrets/credential-manager.js +384 -0
- package/dist/core/secrets/credential-manager.js.map +1 -0
- package/dist/core/secrets/credential-project.d.ts +4 -0
- package/dist/core/secrets/credential-project.d.ts.map +1 -0
- package/dist/core/secrets/credential-project.js +145 -0
- package/dist/core/secrets/credential-project.js.map +1 -0
- package/dist/core/secrets/secret-dotenv.d.ts +1 -1
- package/dist/core/secrets/secret-dotenv.js +1 -1
- package/dist/core/secrets/secret-dotenv.js.map +1 -1
- package/dist/core/settings-manager.d.ts +4 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +9 -5
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tool-capability-policy.js +2 -2
- package/dist/core/tool-capability-policy.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +29 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +179 -28
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/git-filter.d.ts +1 -0
- package/dist/core/tools/git-filter.d.ts.map +1 -1
- package/dist/core/tools/git-filter.js +1 -1
- package/dist/core/tools/git-filter.js.map +1 -1
- package/dist/core/tools/profile-writer.js +3 -3
- package/dist/core/tools/profile-writer.js.map +1 -1
- package/dist/core/tools/python.d.ts +2 -0
- package/dist/core/tools/python.d.ts.map +1 -1
- package/dist/core/tools/python.js +17 -12
- package/dist/core/tools/python.js.map +1 -1
- package/dist/core/tools/run-process.d.ts +2 -0
- package/dist/core/tools/run-process.d.ts.map +1 -1
- package/dist/core/tools/run-process.js +7 -3
- package/dist/core/tools/run-process.js.map +1 -1
- package/dist/core/tools/secret-store.d.ts +8 -18
- package/dist/core/tools/secret-store.d.ts.map +1 -1
- package/dist/core/tools/secret-store.js +83 -348
- package/dist/core/tools/secret-store.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +38 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +35 -14
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +26 -3
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/secret-menu-controller.d.ts +21 -0
- package/dist/modes/interactive/secret-menu-controller.d.ts.map +1 -0
- package/dist/modes/interactive/secret-menu-controller.js +276 -0
- package/dist/modes/interactive/secret-menu-controller.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +2 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +43 -48
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/zip-extractor.d.ts +8 -0
- package/dist/utils/zip-extractor.d.ts.map +1 -0
- package/dist/utils/zip-extractor.js +275 -0
- package/dist/utils/zip-extractor.js.map +1 -0
- package/docs/harness-architecture.md +34 -22
- package/docs/index.md +1 -1
- package/docs/resources.md +1 -1
- package/docs/settings.md +39 -103
- package/docs/usage.md +7 -5
- package/docs/worker-profiles.md +9 -7
- 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
- package/dist/core/secrets/secret-vault-format.d.ts +0 -112
- package/dist/core/secrets/secret-vault-format.d.ts.map +0 -1
- package/dist/core/secrets/secret-vault-format.js +0 -396
- package/dist/core/secrets/secret-vault-format.js.map +0 -1
- package/dist/core/secrets/secret-vault.d.ts +0 -72
- package/dist/core/secrets/secret-vault.d.ts.map +0 -1
- package/dist/core/secrets/secret-vault.js +0 -663
- package/dist/core/secrets/secret-vault.js.map +0 -1
|
@@ -3,6 +3,7 @@ import { getPrivateLaneDeniedPaths } from "../autonomy/lane-private-paths.js";
|
|
|
3
3
|
import { createLaneToolSurface } from "../autonomy/lane-tool-surface.js";
|
|
4
4
|
import { appendLaneRecordSnapshot } from "../autonomy/session-lane-record.js";
|
|
5
5
|
import { AUTONOMY_TELEMETRY_EVENT_TYPES } from "../autonomy/telemetry-events.js";
|
|
6
|
+
import { STABLE_SHELL_TOOL_NAME } from "../default-tool-surface.js";
|
|
6
7
|
import { deriveModelCapabilityProfile } from "../model-capability.js";
|
|
7
8
|
import { isLoopbackModelEndpoint } from "../models/model-endpoint.js";
|
|
8
9
|
import { providerUsageFromAttemptUsage } from "../orchestration/attempt-usage.js";
|
|
@@ -10,10 +11,15 @@ import { SessionTaskProfileStore } from "../orchestration/session-task-profile-s
|
|
|
10
11
|
import { TaskProfileWriter, } from "../orchestration/task-profile-writer.js";
|
|
11
12
|
import { createWorkerExecutionContract, verifierWorkerExecutionContract, } from "../orchestration/worker-execution-contract.js";
|
|
12
13
|
import { registerInFlightWork } from "../reload-blockers.js";
|
|
14
|
+
import { createDelegateToolDefinition } from "../tools/delegate.js";
|
|
15
|
+
import { disposePersistentShellSession } from "../tools/shell-session.js";
|
|
16
|
+
import { wrapToolDefinition } from "../tools/tool-definition-wrapper.js";
|
|
13
17
|
import { applyWorkerActions } from "./worker-actions.js";
|
|
14
18
|
import { WorkerAgentControlCoordinator } from "./worker-agent-control-coordinator.js";
|
|
15
19
|
import { createWorkerAttemptExecutor } from "./worker-attempt-executor.js";
|
|
20
|
+
import { resolveWorkerAuthority } from "./worker-authority-resolver.js";
|
|
16
21
|
import { WorkerConversationStore, } from "./worker-conversation-store.js";
|
|
22
|
+
import { parseWorkerDelegationAuthorityRequest } from "./worker-delegation-request.js";
|
|
17
23
|
import { WorkerDispatchScheduler } from "./worker-dispatch-scheduler.js";
|
|
18
24
|
import { buildWorkerExecutionPlan, compileWorkerExecutionGrant, narrowWorkerExecutionPlan, workerExecutionAuthorityFromPlan, } from "./worker-execution-policy.js";
|
|
19
25
|
import { createLocalWorkerProcessOwnerId } from "./worker-process-owner.js";
|
|
@@ -22,6 +28,7 @@ import { WorkerRecoveryCoordinator } from "./worker-recovery-coordinator.js";
|
|
|
22
28
|
import { selectWorkerResourcePointers } from "./worker-resource-catalog.js";
|
|
23
29
|
import { materializeWorkerResourceBundle } from "./worker-resource-materializer.js";
|
|
24
30
|
import { finalizeWorkerClaim } from "./worker-terminal-finalizer.js";
|
|
31
|
+
import { collectWorkerTreeBudgetSeeds, WorkerTreeBudgetCoordinator } from "./worker-tree-budget-coordinator.js";
|
|
25
32
|
import { WorkerWriteReservationCoordinator } from "./worker-write-reservation-coordinator.js";
|
|
26
33
|
export function isLocalExecutionModel(model) {
|
|
27
34
|
if (model.provider === "ollama" || model.provider === "transformers" || model.provider === "llama-cpp") {
|
|
@@ -54,8 +61,11 @@ export class WorkerDelegationController {
|
|
|
54
61
|
constructor(deps, notifications, lifecycle) {
|
|
55
62
|
this.workerAbort = new AbortController();
|
|
56
63
|
this.laneAbortControllers = new Map();
|
|
64
|
+
this.shellSessionKeys = new Set();
|
|
57
65
|
this.publishedTerminalAttemptIds = new Set();
|
|
66
|
+
this.yieldedCapacityAttemptIds = new Set();
|
|
58
67
|
this.conversations = new WorkerConversationStore();
|
|
68
|
+
this.treeBudgets = new WorkerTreeBudgetCoordinator();
|
|
59
69
|
this.inFlightLedgers = new Map();
|
|
60
70
|
this.deps = deps;
|
|
61
71
|
this.notifications = notifications;
|
|
@@ -106,6 +116,7 @@ export class WorkerDelegationController {
|
|
|
106
116
|
this.publishTerminalRecord(terminal);
|
|
107
117
|
return terminal;
|
|
108
118
|
},
|
|
119
|
+
yieldCapacity: (callerAgentId, targetAgentId) => this.yieldWorkerCapacity(callerAgentId, targetAgentId),
|
|
109
120
|
});
|
|
110
121
|
this.writeReservations = new WorkerWriteReservationCoordinator({
|
|
111
122
|
agentDir: this.deps.getAgentDir(),
|
|
@@ -226,6 +237,9 @@ export class WorkerDelegationController {
|
|
|
226
237
|
}
|
|
227
238
|
this.scheduler.cancelQueued();
|
|
228
239
|
this.writeReservations.dispose();
|
|
240
|
+
for (const shellSessionKey of this.shellSessionKeys)
|
|
241
|
+
disposePersistentShellSession(shellSessionKey);
|
|
242
|
+
this.shellSessionKeys.clear();
|
|
229
243
|
}
|
|
230
244
|
getWorkerLifecycle() {
|
|
231
245
|
return this.lifecycle;
|
|
@@ -240,7 +254,6 @@ export class WorkerDelegationController {
|
|
|
240
254
|
getResourceLoader: () => this.deps.getResourceLoader(),
|
|
241
255
|
getModelRegistry: () => this.deps.getModelRegistry(),
|
|
242
256
|
isModelExhausted: (model) => this.deps.isModelExhausted(model),
|
|
243
|
-
getActiveOrchestrationProfile: () => this.deps.getActiveOrchestrationProfile?.(),
|
|
244
257
|
getTaskProfileStore: () => this.getTaskProfileStore(),
|
|
245
258
|
onDiagnostic: (message) => this.safeWarn(message),
|
|
246
259
|
});
|
|
@@ -325,6 +338,23 @@ export class WorkerDelegationController {
|
|
|
325
338
|
? { ok: true, shipment: resolved.resolved }
|
|
326
339
|
: { ok: false, skipReason: `independent_verifier_unavailable:${resolved.reason}` };
|
|
327
340
|
}
|
|
341
|
+
hasExactRecursiveCycle(parentAgentId, instructions, profileId) {
|
|
342
|
+
const normalizedInstructions = instructions.trim();
|
|
343
|
+
const visited = new Set();
|
|
344
|
+
let current = this.lifecycle.getAgent(parentAgentId);
|
|
345
|
+
while (current) {
|
|
346
|
+
if (visited.has(current.agentId))
|
|
347
|
+
return true;
|
|
348
|
+
visited.add(current.agentId);
|
|
349
|
+
const attempt = this.lifecycle.getLatestAgentAttempt(current.agentId);
|
|
350
|
+
if (attempt?.dispatch.instructions.trim() === normalizedInstructions &&
|
|
351
|
+
attempt.dispatch.profileId === profileId) {
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
current = current.parentAgentId ? this.lifecycle.getAgent(current.parentAgentId) : undefined;
|
|
355
|
+
}
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
328
358
|
/** Single admission contract shared by enqueue, scheduler revalidation, and execution. */
|
|
329
359
|
resolveWorkerAdmission(request, pinnedContract) {
|
|
330
360
|
if (this.deps.isDisposed())
|
|
@@ -337,16 +367,64 @@ export class WorkerDelegationController {
|
|
|
337
367
|
const settings = this.deps.getSettingsManager().getWorkerDelegationSettings();
|
|
338
368
|
if (!settings.enabled)
|
|
339
369
|
return { ok: false, skipReason: "worker_delegation_disabled" };
|
|
370
|
+
const parentAgent = request.parentAgentId ? this.lifecycle.getAgent(request.parentAgentId) : undefined;
|
|
371
|
+
if (request.parentAgentId && !parentAgent) {
|
|
372
|
+
return { ok: false, skipReason: "orchestration_parent_agent_unknown" };
|
|
373
|
+
}
|
|
374
|
+
const parentAttempt = parentAgent ? this.lifecycle.getLatestAgentAttempt(parentAgent.agentId) : undefined;
|
|
375
|
+
const parentContract = parentAttempt?.dispatch.executionContract;
|
|
376
|
+
if (parentAgent && !parentContract) {
|
|
377
|
+
return { ok: false, skipReason: "orchestration_parent_authority_missing" };
|
|
378
|
+
}
|
|
340
379
|
if (pinnedContract && request.profileId && request.profileId !== pinnedContract.worker.profile.profileId) {
|
|
341
380
|
return { ok: false, skipReason: "orchestration_execution_contract_mismatch" };
|
|
342
381
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
382
|
+
let authority = request.authority;
|
|
383
|
+
if (!pinnedContract && authority) {
|
|
384
|
+
try {
|
|
385
|
+
authority = parseWorkerDelegationAuthorityRequest(authority);
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
return {
|
|
389
|
+
ok: false,
|
|
390
|
+
skipReason: `orchestration_authority_invalid:${error instanceof Error ? error.message : String(error)}`,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
let baseShipment;
|
|
395
|
+
if (pinnedContract) {
|
|
396
|
+
const pinned = this.getWorkerProfileResolver().resolveContract(pinnedContract.worker);
|
|
397
|
+
if (!pinned.ok)
|
|
398
|
+
return { ok: false, skipReason: pinned.reason };
|
|
399
|
+
baseShipment = pinned.resolved;
|
|
400
|
+
}
|
|
401
|
+
else if (!request.profileId && parentContract) {
|
|
402
|
+
const inherited = this.getWorkerProfileResolver().resolveContract(parentContract.worker);
|
|
403
|
+
if (!inherited.ok)
|
|
404
|
+
return { ok: false, skipReason: inherited.reason };
|
|
405
|
+
baseShipment = inherited.resolved;
|
|
406
|
+
}
|
|
407
|
+
else if (request.profileId || settings.orchestrationProfile) {
|
|
408
|
+
const configured = this.resolveWorkerShipment(request, settings);
|
|
409
|
+
if (!configured.ok)
|
|
410
|
+
return configured;
|
|
411
|
+
baseShipment = configured.shipment;
|
|
412
|
+
}
|
|
413
|
+
const adaptive = pinnedContract
|
|
414
|
+
? { ok: true, shipment: baseShipment }
|
|
415
|
+
: resolveWorkerAuthority({
|
|
416
|
+
authority,
|
|
417
|
+
...(baseShipment ? { base: baseShipment } : {}),
|
|
418
|
+
...(this.deps.getModel() ? { foregroundModel: this.deps.getModel() } : {}),
|
|
419
|
+
modelRegistry: this.deps.getModelRegistry(),
|
|
420
|
+
isModelExhausted: (model) => this.deps.isModelExhausted(model),
|
|
421
|
+
});
|
|
422
|
+
if (!adaptive.ok)
|
|
423
|
+
return { ok: false, skipReason: adaptive.reason };
|
|
424
|
+
const shipment = adaptive.shipment;
|
|
425
|
+
if (parentAgent && this.hasExactRecursiveCycle(parentAgent.agentId, instructions, shipment.profile.profileId)) {
|
|
426
|
+
return { ok: false, skipReason: "recursive_delegation_cycle" };
|
|
348
427
|
}
|
|
349
|
-
const shipment = "shipment" in resolved ? resolved.shipment : resolved.resolved;
|
|
350
428
|
if (request.verificationOfTaskId && shipment.profile.role !== "verifier") {
|
|
351
429
|
return { ok: false, skipReason: "verification_profile_role_mismatch" };
|
|
352
430
|
}
|
|
@@ -380,9 +458,10 @@ export class WorkerDelegationController {
|
|
|
380
458
|
: shipment.resourcePointers.map((pointer) => pointer.id));
|
|
381
459
|
if (!selectedResources.ok)
|
|
382
460
|
return { ok: false, skipReason: selectedResources.reason };
|
|
383
|
-
const currentExecutionPlan = this.buildWorkerExecutionPlan(shipment.profile, settings);
|
|
384
|
-
const
|
|
385
|
-
|
|
461
|
+
const currentExecutionPlan = this.buildWorkerExecutionPlan(shipment.profile, settings, adaptive.requestedReadPaths, adaptive.requestedWritePaths);
|
|
462
|
+
const inheritedAuthority = pinnedContract?.worker.authority ?? parentContract?.worker.authority;
|
|
463
|
+
const executionPlan = inheritedAuthority
|
|
464
|
+
? narrowWorkerExecutionPlan(inheritedAuthority, currentExecutionPlan)
|
|
386
465
|
: currentExecutionPlan;
|
|
387
466
|
const executionContract = pinnedContract ??
|
|
388
467
|
createWorkerExecutionContract({
|
|
@@ -428,10 +507,37 @@ export class WorkerDelegationController {
|
|
|
428
507
|
};
|
|
429
508
|
}
|
|
430
509
|
publishTerminalRecord(record) {
|
|
431
|
-
const
|
|
510
|
+
const attempt = this.lifecycle?.getActiveAttempt(record.laneId);
|
|
511
|
+
const attemptId = attempt?.attemptId;
|
|
432
512
|
if (attemptId && this.publishedTerminalAttemptIds.has(attemptId))
|
|
433
513
|
return;
|
|
434
|
-
|
|
514
|
+
const childAgentId = attempt?.agentId ?? attempt?.dispatch.logicalLaneId ?? record.laneId;
|
|
515
|
+
const parentAgentId = this.lifecycle.getAgent(childAgentId)?.parentAgentId ?? attempt?.dispatch.parentAgentId;
|
|
516
|
+
let handedOffToParent = false;
|
|
517
|
+
if (attemptId && parentAgentId) {
|
|
518
|
+
try {
|
|
519
|
+
this.agentControl.deliverWorkerTerminalHandoff({
|
|
520
|
+
parentAgentId,
|
|
521
|
+
childAgentId,
|
|
522
|
+
terminalAttemptId: attemptId,
|
|
523
|
+
record,
|
|
524
|
+
});
|
|
525
|
+
handedOffToParent = true;
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
this.safeWarn(`Worker terminal handoff for ${record.laneId} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
if (handedOffToParent) {
|
|
532
|
+
const notification = this.lifecycle.getTerminalNotification(record.laneId);
|
|
533
|
+
if (notification?.status === "pending") {
|
|
534
|
+
this.lifecycle.markNotificationsDelivered([notification.notificationId]);
|
|
535
|
+
}
|
|
536
|
+
this.notifications.statusChanged();
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
this.recordTerminal(record);
|
|
540
|
+
}
|
|
435
541
|
appendLaneRecordSnapshot(this.deps.getSessionManager(), record);
|
|
436
542
|
this.deps.emitAutonomyTelemetry({
|
|
437
543
|
type: AUTONOMY_TELEMETRY_EVENT_TYPES.workerTerminal,
|
|
@@ -444,6 +550,7 @@ export class WorkerDelegationController {
|
|
|
444
550
|
costUsd: record.costUsd ?? null,
|
|
445
551
|
},
|
|
446
552
|
});
|
|
553
|
+
this.agentControl.signalStateChanged();
|
|
447
554
|
if (attemptId)
|
|
448
555
|
this.publishedTerminalAttemptIds.add(attemptId);
|
|
449
556
|
}
|
|
@@ -459,18 +566,44 @@ export class WorkerDelegationController {
|
|
|
459
566
|
this.publishTerminalRecord(record);
|
|
460
567
|
return record;
|
|
461
568
|
}
|
|
462
|
-
hasWorkerCapacity(settings
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
569
|
+
hasWorkerCapacity(settings) {
|
|
570
|
+
const snapshot = this.getWorkerLifecycle().getTaskRuntimeSnapshot();
|
|
571
|
+
let yielded = 0;
|
|
572
|
+
for (const attemptId of [...this.yieldedCapacityAttemptIds]) {
|
|
573
|
+
const status = snapshot.attempts[attemptId]?.status;
|
|
574
|
+
if (status === "leased" || status === "running")
|
|
575
|
+
yielded += 1;
|
|
576
|
+
else
|
|
577
|
+
this.yieldedCapacityAttemptIds.delete(attemptId);
|
|
578
|
+
}
|
|
579
|
+
return Math.max(0, this.getWorkerLifecycle().getRunningCount() - yielded) < settings.maxConcurrent;
|
|
580
|
+
}
|
|
581
|
+
yieldWorkerCapacity(callerAgentId, targetAgentId) {
|
|
582
|
+
const caller = this.lifecycle.getAgent(callerAgentId);
|
|
583
|
+
const target = this.lifecycle.getAgent(targetAgentId);
|
|
584
|
+
if (!caller || !target || caller.rootAgentId !== target.rootAgentId)
|
|
585
|
+
return () => undefined;
|
|
586
|
+
const attempt = this.lifecycle.getLatestAgentAttempt(caller.agentId);
|
|
587
|
+
if (!attempt || (attempt.status !== "leased" && attempt.status !== "running"))
|
|
588
|
+
return () => undefined;
|
|
589
|
+
this.yieldedCapacityAttemptIds.add(attempt.attemptId);
|
|
590
|
+
this.scheduler.drain();
|
|
591
|
+
let released = false;
|
|
592
|
+
return () => {
|
|
593
|
+
if (released)
|
|
594
|
+
return;
|
|
595
|
+
released = true;
|
|
596
|
+
this.yieldedCapacityAttemptIds.delete(attempt.attemptId);
|
|
597
|
+
if (!this.deps.isDisposed())
|
|
598
|
+
this.scheduler.drain();
|
|
599
|
+
};
|
|
467
600
|
}
|
|
468
601
|
workerDispatchAdmission(request, record) {
|
|
469
602
|
const contract = this.getWorkerLifecycle().getActiveAttempt(record.laneId)?.dispatch.executionContract;
|
|
470
603
|
const admission = this.resolveWorkerAdmission(request, contract);
|
|
471
604
|
if (!admission.ok)
|
|
472
605
|
return { action: "cancel", reasonCode: admission.skipReason };
|
|
473
|
-
if (!this.hasWorkerCapacity(admission.settings
|
|
606
|
+
if (!this.hasWorkerCapacity(admission.settings))
|
|
474
607
|
return { action: "wait", reason: "capacity" };
|
|
475
608
|
const attempt = this.getWorkerLifecycle().getActiveAttempt(record.laneId);
|
|
476
609
|
if (!attempt)
|
|
@@ -480,7 +613,7 @@ export class WorkerDelegationController {
|
|
|
480
613
|
return { action: "cancel", reasonCode: reservation.reasonCode };
|
|
481
614
|
return reservation.kind === "granted" ? { action: "start" } : { action: "wait", reason: "write_reservation" };
|
|
482
615
|
}
|
|
483
|
-
buildWorkerExecutionPlan(profile, settings) {
|
|
616
|
+
buildWorkerExecutionPlan(profile, settings, requestedReadPaths, requestedWritePaths) {
|
|
484
617
|
return buildWorkerExecutionPlan({
|
|
485
618
|
profile,
|
|
486
619
|
settings,
|
|
@@ -488,6 +621,8 @@ export class WorkerDelegationController {
|
|
|
488
621
|
deniedPaths: getPrivateLaneDeniedPaths(this.deps.getCwd(), this.deps.getAgentDir()),
|
|
489
622
|
foregroundMaxCostUsd: this.deps.getCapabilityEnvelope()?.maxEstimatedUsd,
|
|
490
623
|
memoryEnabled: this.deps.getSettingsManager().getMemoryRetrievalSettings().enabled,
|
|
624
|
+
...(requestedReadPaths ? { requestedReadPaths } : {}),
|
|
625
|
+
...(requestedWritePaths ? { requestedWritePaths } : {}),
|
|
491
626
|
});
|
|
492
627
|
}
|
|
493
628
|
/** One durable preparation path for queued, immediate, and recovered execution. */
|
|
@@ -504,6 +639,7 @@ export class WorkerDelegationController {
|
|
|
504
639
|
const goal = this.deps.getGoalStateSnapshot();
|
|
505
640
|
const prepared = lifecycle.prepare({
|
|
506
641
|
instructions: admission.instructions,
|
|
642
|
+
...(request.parentAgentId ? { parentAgentId: request.parentAgentId } : {}),
|
|
507
643
|
executionContract: admission.executionContract,
|
|
508
644
|
requiredCapabilities: admission.executionPlan.requiredCapabilities,
|
|
509
645
|
...(request.verificationOfTaskId ? { verificationOfTaskId: request.verificationOfTaskId } : {}),
|
|
@@ -517,6 +653,57 @@ export class WorkerDelegationController {
|
|
|
517
653
|
});
|
|
518
654
|
return { executionPlan: admission.executionPlan, lifecycle, ...prepared };
|
|
519
655
|
}
|
|
656
|
+
ensurePreparedAgent(prepared, admission) {
|
|
657
|
+
if (!prepared.attempt)
|
|
658
|
+
throw new Error("Prepared worker attempt is missing.");
|
|
659
|
+
const immutableWorker = prepared.attempt.dispatch.executionContract?.worker;
|
|
660
|
+
if (!immutableWorker)
|
|
661
|
+
throw new Error("Prepared worker execution contract is missing.");
|
|
662
|
+
const agentId = prepared.attempt.agentId ?? prepared.attempt.dispatch.logicalLaneId ?? prepared.record.laneId;
|
|
663
|
+
const existing = prepared.lifecycle.getAgent(agentId);
|
|
664
|
+
if (existing) {
|
|
665
|
+
const conversation = this.conversations.open({
|
|
666
|
+
agentDir: this.deps.getAgentDir(),
|
|
667
|
+
resumeContext: existing.resumeContext,
|
|
668
|
+
expectedLogicalAgentId: existing.agentId,
|
|
669
|
+
});
|
|
670
|
+
const materialized = materializeWorkerResourceBundle(existing.resumeContext.contextPointers);
|
|
671
|
+
if (!materialized.ok)
|
|
672
|
+
throw new Error(`worker_resource_materialization_${materialized.code}`);
|
|
673
|
+
return {
|
|
674
|
+
conversation,
|
|
675
|
+
resources: materialized.pointers,
|
|
676
|
+
resourceSystemPrompt: materialized.systemPrompt,
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
const selected = selectWorkerResourcePointers(immutableWorker.resourcePointers, admission.resourcePointerIds);
|
|
680
|
+
if (!selected.ok)
|
|
681
|
+
throw new Error(selected.reason);
|
|
682
|
+
const materialized = materializeWorkerResourceBundle(selected.pointers);
|
|
683
|
+
if (!materialized.ok)
|
|
684
|
+
throw new Error(`worker_resource_materialization_${materialized.code}`);
|
|
685
|
+
const conversation = this.conversations.ensure({
|
|
686
|
+
agentDir: this.deps.getAgentDir(),
|
|
687
|
+
parentSessionId: this.deps.getSessionId(),
|
|
688
|
+
logicalAgentId: agentId,
|
|
689
|
+
cwd: this.deps.getCwd(),
|
|
690
|
+
orchestrationProfileId: immutableWorker.profile.profileId,
|
|
691
|
+
modelRef: `${immutableWorker.modelBinding.provider}/${immutableWorker.modelBinding.modelId}`,
|
|
692
|
+
resourceProfileNames: immutableWorker.profile.resourceProfileNames,
|
|
693
|
+
contextPointers: materialized.pointers,
|
|
694
|
+
});
|
|
695
|
+
prepared.lifecycle.ensureAgent({
|
|
696
|
+
agentId,
|
|
697
|
+
...(prepared.attempt.dispatch.parentAgentId ? { parentAgentId: prepared.attempt.dispatch.parentAgentId } : {}),
|
|
698
|
+
role: immutableWorker.profile.role,
|
|
699
|
+
resumeContext: conversation.getResumeContext(),
|
|
700
|
+
});
|
|
701
|
+
return {
|
|
702
|
+
conversation,
|
|
703
|
+
resources: materialized.pointers,
|
|
704
|
+
resourceSystemPrompt: materialized.systemPrompt,
|
|
705
|
+
};
|
|
706
|
+
}
|
|
520
707
|
start(request) {
|
|
521
708
|
return this.startInternal(request);
|
|
522
709
|
}
|
|
@@ -529,21 +716,24 @@ export class WorkerDelegationController {
|
|
|
529
716
|
const { settings, shipment } = admission;
|
|
530
717
|
const foreground = this.deps.getModel();
|
|
531
718
|
const contendsWithLocalForeground = foreground !== undefined && isLocalExecutionModel(foreground) && isLocalExecutionModel(shipment.model);
|
|
532
|
-
if (contendsWithLocalForeground || !this.hasWorkerCapacity(settings
|
|
719
|
+
if (contendsWithLocalForeground || !this.hasWorkerCapacity(settings)) {
|
|
533
720
|
// A mandatory verifier is the continuation of an already admitted implementation, not a
|
|
534
721
|
// new owner request. Reserve its queue admission so a burst of ordinary work cannot strand
|
|
535
722
|
// the subject behind `independent_verification_required` with no terminal handoff.
|
|
536
|
-
if (this.scheduler.queuedCount >= 8 && !request.verificationOfTaskId) {
|
|
537
|
-
return { started: false, skipReason: "worker_delegation_queue_full" };
|
|
538
|
-
}
|
|
539
723
|
let record;
|
|
540
724
|
try {
|
|
541
|
-
|
|
725
|
+
const prepared = this.prepareWorkerAttempt(request, admission);
|
|
726
|
+
record = prepared.record;
|
|
727
|
+
this.ensurePreparedAgent(prepared, admission);
|
|
542
728
|
}
|
|
543
729
|
catch (error) {
|
|
730
|
+
if (record)
|
|
731
|
+
this.cancelAndPublish(this.lifecycle, record.laneId, "worker_conversation_unavailable");
|
|
544
732
|
this.safeWarn(`Worker dispatch was not persisted: ${error instanceof Error ? error.message : String(error)}`);
|
|
545
733
|
return { started: false, skipReason: "orchestration_ledger_error" };
|
|
546
734
|
}
|
|
735
|
+
if (!record)
|
|
736
|
+
return { started: false, skipReason: "orchestration_attempt_missing" };
|
|
547
737
|
this.scheduler.enqueue(record, { ...request, profileId: shipment.profile.profileId }, false, request.verificationOfTaskId !== undefined);
|
|
548
738
|
this.notifications.statusChanged();
|
|
549
739
|
return { started: true, record };
|
|
@@ -575,7 +765,7 @@ export class WorkerDelegationController {
|
|
|
575
765
|
this.recovery.recover();
|
|
576
766
|
const { instructions, settings, verifierShipment } = admission;
|
|
577
767
|
const { model, modelBinding, profile: orchestrationProfile, soul } = admission.shipment;
|
|
578
|
-
if (!this.hasWorkerCapacity(settings
|
|
768
|
+
if (!this.hasWorkerCapacity(settings)) {
|
|
579
769
|
return { started: false, skipReason: "worker_delegation_already_running" };
|
|
580
770
|
}
|
|
581
771
|
const laneCapability = this.laneCapabilityProfile(model);
|
|
@@ -584,42 +774,31 @@ export class WorkerDelegationController {
|
|
|
584
774
|
const { executionPlan, lifecycle } = prepared;
|
|
585
775
|
if (!prepared.attempt)
|
|
586
776
|
return { started: false, skipReason: "orchestration_attempt_missing" };
|
|
777
|
+
let preparedAgent;
|
|
778
|
+
try {
|
|
779
|
+
preparedAgent = this.ensurePreparedAgent(prepared, admission);
|
|
780
|
+
}
|
|
781
|
+
catch (error) {
|
|
782
|
+
this.cancelAndPublish(lifecycle, prepared.record.laneId, "worker_conversation_unavailable");
|
|
783
|
+
this.safeWarn(`Worker conversation setup failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
784
|
+
return { started: false, skipReason: "worker_conversation_unavailable" };
|
|
785
|
+
}
|
|
587
786
|
const durableTask = lifecycle.getTask(prepared.record.laneId);
|
|
588
787
|
if (!durableTask)
|
|
589
788
|
return { started: false, skipReason: "orchestration_task_missing" };
|
|
590
789
|
const immutableWorker = prepared.attempt.dispatch.executionContract?.worker;
|
|
591
790
|
if (!immutableWorker)
|
|
592
791
|
return { started: false, skipReason: "orchestration_execution_contract_missing" };
|
|
593
|
-
const selectedResources = selectWorkerResourcePointers(immutableWorker.resourcePointers, prepared.attempt.dispatch.resourcePointerIds.length > 0
|
|
594
|
-
? prepared.attempt.dispatch.resourcePointerIds
|
|
595
|
-
: admission.resourcePointerIds);
|
|
596
|
-
if (!selectedResources.ok) {
|
|
597
|
-
this.cancelAndPublish(lifecycle, prepared.record.laneId, selectedResources.reason);
|
|
598
|
-
return { started: false, skipReason: selectedResources.reason };
|
|
599
|
-
}
|
|
600
792
|
let grant;
|
|
601
|
-
|
|
793
|
+
const workerResourceSystemPrompt = preparedAgent.resourceSystemPrompt;
|
|
602
794
|
if (prepared.attempt.grant) {
|
|
603
|
-
if (!this.recovery.durableGrantIsStillPermitted(prepared.attempt.grant, executionPlan,
|
|
795
|
+
if (!this.recovery.durableGrantIsStillPermitted(prepared.attempt.grant, executionPlan, preparedAgent.resources)) {
|
|
604
796
|
this.cancelAndPublish(lifecycle, prepared.record.laneId, "recovered_grant_revoked");
|
|
605
797
|
return { started: false, skipReason: "recovered_grant_revoked" };
|
|
606
798
|
}
|
|
607
799
|
grant = prepared.attempt.grant;
|
|
608
|
-
const materialized = materializeWorkerResourceBundle(grant.resources);
|
|
609
|
-
if (!materialized.ok) {
|
|
610
|
-
const reason = `worker_resource_materialization_${materialized.code}`;
|
|
611
|
-
this.cancelAndPublish(lifecycle, prepared.record.laneId, reason);
|
|
612
|
-
return { started: false, skipReason: reason };
|
|
613
|
-
}
|
|
614
|
-
workerResourceSystemPrompt = materialized.systemPrompt;
|
|
615
800
|
}
|
|
616
801
|
else {
|
|
617
|
-
const materialized = materializeWorkerResourceBundle(selectedResources.pointers);
|
|
618
|
-
if (!materialized.ok) {
|
|
619
|
-
const reason = `worker_resource_materialization_${materialized.code}`;
|
|
620
|
-
this.cancelAndPublish(lifecycle, prepared.record.laneId, reason);
|
|
621
|
-
return { started: false, skipReason: reason };
|
|
622
|
-
}
|
|
623
802
|
const compiled = compileWorkerExecutionGrant({
|
|
624
803
|
target: {
|
|
625
804
|
objectiveId: durableTask.task.objectiveId,
|
|
@@ -628,7 +807,7 @@ export class WorkerDelegationController {
|
|
|
628
807
|
},
|
|
629
808
|
profile: orchestrationProfile,
|
|
630
809
|
plan: executionPlan,
|
|
631
|
-
resources:
|
|
810
|
+
resources: preparedAgent.resources,
|
|
632
811
|
});
|
|
633
812
|
if (!compiled.ok) {
|
|
634
813
|
this.cancelAndPublish(lifecycle, prepared.record.laneId, compiled.reasonCodes.join(","));
|
|
@@ -636,7 +815,6 @@ export class WorkerDelegationController {
|
|
|
636
815
|
}
|
|
637
816
|
lifecycle.bindGrant(prepared.attempt.attemptId, compiled.grant);
|
|
638
817
|
grant = compiled.grant;
|
|
639
|
-
workerResourceSystemPrompt = materialized.systemPrompt;
|
|
640
818
|
}
|
|
641
819
|
const immutableProfile = immutableWorker.profile;
|
|
642
820
|
// Follow-up tasks deliberately receive unique task ids while retaining the original logical
|
|
@@ -647,44 +825,9 @@ export class WorkerDelegationController {
|
|
|
647
825
|
this.cancelAndPublish(lifecycle, prepared.record.laneId, "orchestration_agent_missing");
|
|
648
826
|
return { started: false, skipReason: "orchestration_agent_missing" };
|
|
649
827
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
// Recovery must trust only the registered resume context; reconstructing one here could
|
|
654
|
-
// silently redirect a logical worker to a different transcript or resource scope.
|
|
655
|
-
conversation = this.conversations.open({
|
|
656
|
-
agentDir: this.deps.getAgentDir(),
|
|
657
|
-
resumeContext: registeredAgent.resumeContext,
|
|
658
|
-
expectedLogicalAgentId: registeredAgent.agentId,
|
|
659
|
-
});
|
|
660
|
-
if (prepared.attempt.status === "suspended")
|
|
661
|
-
this.recovery.repairInterruptedToolResults(conversation);
|
|
662
|
-
}
|
|
663
|
-
else {
|
|
664
|
-
conversation = this.conversations.ensure({
|
|
665
|
-
agentDir: this.deps.getAgentDir(),
|
|
666
|
-
parentSessionId: this.deps.getSessionId(),
|
|
667
|
-
logicalAgentId: agentId,
|
|
668
|
-
cwd: this.deps.getCwd(),
|
|
669
|
-
orchestrationProfileId: immutableProfile.profileId,
|
|
670
|
-
modelRef: `${prepared.attempt.dispatch.executionContract.worker.modelBinding.provider}/${prepared.attempt.dispatch.executionContract.worker.modelBinding.modelId}`,
|
|
671
|
-
resourceProfileNames: immutableProfile.resourceProfileNames,
|
|
672
|
-
contextPointers: grant.resources,
|
|
673
|
-
});
|
|
674
|
-
lifecycle.ensureAgent({
|
|
675
|
-
agentId,
|
|
676
|
-
role: immutableProfile.role,
|
|
677
|
-
resumeContext: conversation.getResumeContext(),
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
catch (error) {
|
|
682
|
-
if (prepared.attempt.status !== "suspended") {
|
|
683
|
-
this.cancelAndPublish(lifecycle, prepared.record.laneId, "worker_conversation_unavailable");
|
|
684
|
-
}
|
|
685
|
-
this.safeWarn(`Worker conversation setup failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
686
|
-
return { started: false, skipReason: "worker_conversation_unavailable" };
|
|
687
|
-
}
|
|
828
|
+
const conversation = preparedAgent.conversation;
|
|
829
|
+
if (prepared.attempt.status === "suspended")
|
|
830
|
+
this.recovery.repairInterruptedToolResults(conversation);
|
|
688
831
|
const reservation = this.writeReservations.acquire(prepared.record.laneId, prepared.attempt, executionPlan);
|
|
689
832
|
if (reservation.kind === "denied") {
|
|
690
833
|
this.cancelAndPublish(lifecycle, prepared.record.laneId, reservation.reasonCode);
|
|
@@ -727,6 +870,31 @@ export class WorkerDelegationController {
|
|
|
727
870
|
onStarted?.(startedRecord);
|
|
728
871
|
const maxUsd = grant.budget.maxCostUsd;
|
|
729
872
|
const executionPolicy = orchestrationProfile.executionPolicy;
|
|
873
|
+
const recursiveDelegateTool = wrapToolDefinition(createDelegateToolDefinition({
|
|
874
|
+
startWorkerDelegation: (childRequest) => this.start({ ...childRequest, parentAgentId: agentId }),
|
|
875
|
+
runWorkerDelegation: (childRequest) => this.runOnce({ ...childRequest, parentAgentId: agentId }),
|
|
876
|
+
orchestrationProfiles: this.getProfileCatalog(),
|
|
877
|
+
workerAgentControl: this.agentControl,
|
|
878
|
+
callerAgentId: agentId,
|
|
879
|
+
}));
|
|
880
|
+
const agentBinding = lifecycle.getAgent(agentId);
|
|
881
|
+
if (!agentBinding) {
|
|
882
|
+
this.cancelAndPublish(lifecycle, prepared.record.laneId, "orchestration_agent_missing");
|
|
883
|
+
return { started: false, skipReason: "orchestration_agent_missing" };
|
|
884
|
+
}
|
|
885
|
+
const rootAttempt = lifecycle.getLatestAgentAttempt(agentBinding.rootAgentId);
|
|
886
|
+
const rootBudget = rootAttempt?.dispatch.executionContract?.worker.authority.budget ?? grant.budget;
|
|
887
|
+
const sharedBudget = this.treeBudgets.createPort({
|
|
888
|
+
rootAgentId: agentBinding.rootAgentId,
|
|
889
|
+
attemptId: durableHandle.attemptId,
|
|
890
|
+
budget: rootBudget,
|
|
891
|
+
seeds: collectWorkerTreeBudgetSeeds(lifecycle.getTaskRuntimeSnapshot(), agentBinding.rootAgentId),
|
|
892
|
+
initialUsage,
|
|
893
|
+
});
|
|
894
|
+
const shellGranted = executionPlan.toolManifests.some((manifest) => manifest.toolName === STABLE_SHELL_TOOL_NAME);
|
|
895
|
+
const shellSessionKey = shellGranted ? `worker:${this.deps.getSessionId()}:${agentId}` : undefined;
|
|
896
|
+
if (shellSessionKey)
|
|
897
|
+
this.shellSessionKeys.add(shellSessionKey);
|
|
730
898
|
const toolSurface = createLaneToolSurface({
|
|
731
899
|
cwd: this.deps.getCwd(),
|
|
732
900
|
readMemory: executionPlan.readMemory ? (query) => this.deps.readMemoryForLane(query) : undefined,
|
|
@@ -734,9 +902,12 @@ export class WorkerDelegationController {
|
|
|
734
902
|
writePaths: executionPlan.writePaths,
|
|
735
903
|
...(executionPlan.processEnabled && executionPolicy ? { executionPolicy } : {}),
|
|
736
904
|
processMaxWallClockMs: grant.budget.maxWallClockMs ?? 0,
|
|
905
|
+
...(shellSessionKey ? { shellSessionKey } : {}),
|
|
737
906
|
grant,
|
|
738
907
|
toolManifests: executionPlan.toolManifests,
|
|
908
|
+
additionalTools: [recursiveDelegateTool],
|
|
739
909
|
initialUsage,
|
|
910
|
+
sharedBudget,
|
|
740
911
|
});
|
|
741
912
|
const writeGranted = executionPlan.writeEnabled &&
|
|
742
913
|
toolSurface.gateway !== undefined &&
|
|
@@ -1010,6 +1181,8 @@ export class WorkerDelegationController {
|
|
|
1010
1181
|
}
|
|
1011
1182
|
this.agentControl.signalStateChanged();
|
|
1012
1183
|
deregisterInFlight();
|
|
1184
|
+
if (!this.deps.isDisposed())
|
|
1185
|
+
this.scheduler.drain(true);
|
|
1013
1186
|
}
|
|
1014
1187
|
}
|
|
1015
1188
|
/** Start every capacity-eligible queued worker at the owner session's foreground-idle boundary. */
|