@caupulican/pi-adaptative 0.90.2 → 0.90.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 +41 -0
- package/dist/core/agent-session-contracts.d.ts +2 -0
- package/dist/core/agent-session-contracts.d.ts.map +1 -1
- package/dist/core/agent-session-contracts.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts +10 -1
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +24 -2
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/lane-tracker.d.ts +6 -1
- package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tracker.js +17 -1
- package/dist/core/autonomy/lane-tracker.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +1 -3
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/compaction-controller.d.ts.map +1 -1
- package/dist/core/compaction-controller.js +0 -1
- package/dist/core/compaction-controller.js.map +1 -1
- package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -1
- package/dist/core/delegation/managed-lane-controller.js +5 -1
- package/dist/core/delegation/managed-lane-controller.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +8 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.js +94 -36
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-agent-control.d.ts +1 -0
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
- 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 +7 -2
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.d.ts +2 -0
- package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.js +49 -6
- package/dist/core/delegation/worker-authority-resolver.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +8 -5
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +158 -40
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-fleet-limits.d.ts +9 -2
- package/dist/core/delegation/worker-fleet-limits.d.ts.map +1 -1
- package/dist/core/delegation/worker-fleet-limits.js +39 -3
- package/dist/core/delegation/worker-fleet-limits.js.map +1 -1
- package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -1
- package/dist/core/delegation/worker-lane-projection.js +10 -0
- package/dist/core/delegation/worker-lane-projection.js.map +1 -1
- package/dist/core/delegation/worker-lease-heartbeat.d.ts +16 -0
- package/dist/core/delegation/worker-lease-heartbeat.d.ts.map +1 -0
- package/dist/core/delegation/worker-lease-heartbeat.js +37 -0
- package/dist/core/delegation/worker-lease-heartbeat.js.map +1 -0
- 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 +6 -0
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-notification-coordinator.js +2 -1
- package/dist/core/delegation/worker-notification-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts +28 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.js +38 -9
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
- package/dist/core/delegation/worker-runner.js +2 -2
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts +1 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-terminal-handoff-coordinator.js +1 -0
- package/dist/core/delegation/worker-terminal-handoff-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts +4 -2
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-tree-budget-coordinator.js +10 -2
- package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +14 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-write-reservation-coordinator.js +121 -33
- package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -1
- package/dist/core/foreground-terminal-handoff-controller.d.ts +5 -0
- package/dist/core/foreground-terminal-handoff-controller.d.ts.map +1 -1
- package/dist/core/foreground-terminal-handoff-controller.js +28 -12
- package/dist/core/foreground-terminal-handoff-controller.js.map +1 -1
- package/dist/core/orchestration/capability-gateway.d.ts +2 -1
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +9 -2
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +16 -1
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +5 -0
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
- package/dist/core/orchestration/profile-registry.js +38 -1
- package/dist/core/orchestration/profile-registry.js.map +1 -1
- package/dist/core/orchestration/risk-budget.d.ts +10 -0
- package/dist/core/orchestration/risk-budget.d.ts.map +1 -1
- package/dist/core/orchestration/risk-budget.js +14 -0
- package/dist/core/orchestration/risk-budget.js.map +1 -1
- package/dist/core/orchestration/task-runtime-reducer.d.ts +1 -0
- package/dist/core/orchestration/task-runtime-reducer.d.ts.map +1 -1
- package/dist/core/orchestration/task-runtime-reducer.js +34 -0
- package/dist/core/orchestration/task-runtime-reducer.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 +24 -1
- package/dist/core/orchestration/task-runtime.js.map +1 -1
- package/dist/core/orchestration/worker-model-pins.d.ts +28 -0
- package/dist/core/orchestration/worker-model-pins.d.ts.map +1 -0
- package/dist/core/orchestration/worker-model-pins.js +141 -0
- package/dist/core/orchestration/worker-model-pins.js.map +1 -0
- package/dist/core/provider-prompt-contracts.d.ts.map +1 -1
- package/dist/core/provider-prompt-contracts.js +2 -1
- package/dist/core/provider-prompt-contracts.js.map +1 -1
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +8 -1
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +1 -0
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -3
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +26 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/bash.d.ts +3 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +13 -2
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/delegate-status.d.ts +3 -0
- package/dist/core/tools/delegate-status.d.ts.map +1 -1
- package/dist/core/tools/delegate-status.js +26 -1
- package/dist/core/tools/delegate-status.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +15 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +234 -68
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +14 -1
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-failure-recovery.d.ts +3 -0
- package/dist/core/tools/file-failure-recovery.d.ts.map +1 -1
- package/dist/core/tools/file-failure-recovery.js +11 -0
- package/dist/core/tools/file-failure-recovery.js.map +1 -1
- package/dist/core/tools/orchestration-panel.d.ts +1 -1
- package/dist/core/tools/orchestration-panel.d.ts.map +1 -1
- package/dist/core/tools/orchestration-panel.js +1 -0
- package/dist/core/tools/orchestration-panel.js.map +1 -1
- package/dist/core/tools/profile-writer.d.ts.map +1 -1
- package/dist/core/tools/profile-writer.js +2 -8
- package/dist/core/tools/profile-writer.js.map +1 -1
- package/dist/core/tools/search-command-guard.d.ts.map +1 -1
- package/dist/core/tools/search-command-guard.js +10 -3
- package/dist/core/tools/search-command-guard.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +10 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/modes/interactive/components/activity-lane.d.ts +1 -1
- package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -1
- package/dist/modes/interactive/components/activity-lane.js +11 -2
- package/dist/modes/interactive/components/activity-lane.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +1 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/utils/shell.d.ts +2 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +3 -1
- package/dist/utils/shell.js.map +1 -1
- package/docs/harness-architecture.md +6 -3
- package/docs/settings.md +39 -6
- package/docs/tool-repair.md +1 -1
- package/docs/worker-profiles.md +2 -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
|
@@ -14,6 +14,7 @@ import { MAX_ORCHESTRATION_DISPATCH_INSTRUCTIONS_LENGTH, } from "../orchestratio
|
|
|
14
14
|
import { SessionTaskProfileStore } from "../orchestration/session-task-profile-store.js";
|
|
15
15
|
import { TaskProfileWriter, } from "../orchestration/task-profile-writer.js";
|
|
16
16
|
import { createWorkerExecutionContract, verifierWorkerExecutionContract, } from "../orchestration/worker-execution-contract.js";
|
|
17
|
+
import { resolveWorkerModelPin } from "../orchestration/worker-model-pins.js";
|
|
17
18
|
import { registerInFlightWork } from "../reload-blockers.js";
|
|
18
19
|
import { createDelegateToolDefinition } from "../tools/delegate.js";
|
|
19
20
|
import { disposePersistentShellSession } from "../tools/shell-session.js";
|
|
@@ -29,16 +30,17 @@ import { WorkerConversationStore, } from "./worker-conversation-store.js";
|
|
|
29
30
|
import { parseWorkerDelegationAuthorityRequest } from "./worker-delegation-request.js";
|
|
30
31
|
import { WorkerDispatchScheduler } from "./worker-dispatch-scheduler.js";
|
|
31
32
|
import { buildWorkerExecutionPlan, compileWorkerExecutionGrant, narrowWorkerExecutionPlan, workerExecutionAuthorityFromPlan, } from "./worker-execution-policy.js";
|
|
32
|
-
import { DEFAULT_WORKER_FLEET_LIMITS, evaluateNewWorkerAdmission, pendingVerifierSubjectTaskIds, } from "./worker-fleet-limits.js";
|
|
33
|
+
import { DEFAULT_WORKER_FLEET_LIMITS, evaluateNewWorkerAdmission, intersectWorkerDelegationLimits, pendingVerifierSubjectTaskIds, resolveWorkerFleetLimits, } from "./worker-fleet-limits.js";
|
|
34
|
+
import { WorkerLeaseHeartbeat } from "./worker-lease-heartbeat.js";
|
|
33
35
|
import { createLocalWorkerProcessOwnerId } from "./worker-process-owner.js";
|
|
34
|
-
import { WorkerProfileResolver } from "./worker-profile-resolver.js";
|
|
36
|
+
import { WorkerProfileResolver, } from "./worker-profile-resolver.js";
|
|
35
37
|
import { WorkerRecoveryCoordinator } from "./worker-recovery-coordinator.js";
|
|
36
38
|
import { selectWorkerResourcePointers } from "./worker-resource-catalog.js";
|
|
37
39
|
import { materializeWorkerResourceBundle } from "./worker-resource-materializer.js";
|
|
38
40
|
import { finalizeWorkerClaim } from "./worker-terminal-finalizer.js";
|
|
39
41
|
import { WorkerTerminalHandoffCoordinator, } from "./worker-terminal-handoff-coordinator.js";
|
|
40
42
|
import { collectWorkerTreeBudgetSeeds, WorkerTreeBudgetCoordinator } from "./worker-tree-budget-coordinator.js";
|
|
41
|
-
import { WorkerWriteReservationCoordinator } from "./worker-write-reservation-coordinator.js";
|
|
43
|
+
import { WorkerWriteReservationCoordinator, } from "./worker-write-reservation-coordinator.js";
|
|
42
44
|
export function isLocalExecutionModel(model) {
|
|
43
45
|
if (model.provider === "ollama" || model.provider === "transformers" || model.provider === "llama-cpp") {
|
|
44
46
|
return true;
|
|
@@ -82,6 +84,7 @@ export class WorkerDelegationController {
|
|
|
82
84
|
this.shellSessionKeys = new Set();
|
|
83
85
|
this.publishedTerminalAttemptIds = new Set();
|
|
84
86
|
this.yieldedCapacityAttemptIds = new Map();
|
|
87
|
+
this.yieldedWriteReservations = new Map();
|
|
85
88
|
this.conversations = new WorkerConversationStore();
|
|
86
89
|
this.treeBudgets = new WorkerTreeBudgetCoordinator();
|
|
87
90
|
this.inFlightLedgers = new Map();
|
|
@@ -150,7 +153,8 @@ export class WorkerDelegationController {
|
|
|
150
153
|
? this.workerProjectionHeadroomSkipReason(contract)
|
|
151
154
|
: "orchestration_execution_contract_missing";
|
|
152
155
|
},
|
|
153
|
-
|
|
156
|
+
waitBlockedByCaller: (callerAgentId, targetAgentIds) => this.waitTargetsBlockedByCaller(callerAgentId, targetAgentIds),
|
|
157
|
+
yieldCallerForWait: (callerAgentId) => this.yieldWorkerForWait(callerAgentId),
|
|
154
158
|
warn: (message) => this.safeWarn(message),
|
|
155
159
|
});
|
|
156
160
|
this.terminalHandoffs = new WorkerTerminalHandoffCoordinator({
|
|
@@ -166,8 +170,10 @@ export class WorkerDelegationController {
|
|
|
166
170
|
getParentSessionId: () => this.deps.getSessionId(),
|
|
167
171
|
ownerId: this.agentControl.getProcessOwnerId(),
|
|
168
172
|
drainQueuedWorkers: () => {
|
|
169
|
-
if (
|
|
170
|
-
|
|
173
|
+
if (this.deps.isDisposed())
|
|
174
|
+
return;
|
|
175
|
+
this.scheduler.drain(true);
|
|
176
|
+
this.agentControl.signalStateChanged();
|
|
171
177
|
},
|
|
172
178
|
warn: (message) => this.safeWarn(message),
|
|
173
179
|
});
|
|
@@ -427,20 +433,27 @@ export class WorkerDelegationController {
|
|
|
427
433
|
createTaskProfile(input) {
|
|
428
434
|
return this.getTaskProfileWriter().createTaskProfile(input);
|
|
429
435
|
}
|
|
430
|
-
|
|
431
|
-
const resolved = this.getWorkerProfileResolver().
|
|
432
|
-
return resolved.ok ? { ok: true,
|
|
436
|
+
resolveWorkerPreset(request, settings) {
|
|
437
|
+
const resolved = this.getWorkerProfileResolver().resolvePreset(request, settings.orchestrationProfile);
|
|
438
|
+
return resolved.ok ? { ok: true, preset: resolved.resolved } : { ok: false, skipReason: resolved.reason };
|
|
433
439
|
}
|
|
434
|
-
resolveRequiredVerifier(profile) {
|
|
440
|
+
resolveRequiredVerifier(profile, modelPinPolicy) {
|
|
435
441
|
if (!profile.requireIndependentVerification)
|
|
436
442
|
return { ok: true };
|
|
437
|
-
const
|
|
438
|
-
if (!
|
|
439
|
-
return { ok: false, skipReason: `independent_verifier_unavailable:${
|
|
443
|
+
const preset = this.getWorkerProfileResolver().resolveVerifierPreset(profile);
|
|
444
|
+
if (!preset.ok)
|
|
445
|
+
return { ok: false, skipReason: `independent_verifier_unavailable:${preset.reason}` };
|
|
446
|
+
const modelPin = resolveWorkerModelPin(modelPinPolicy, "verifier");
|
|
447
|
+
const resolved = this.getWorkerProfileResolver().bindPreset(preset.resolved, modelPin?.binding);
|
|
448
|
+
if (!resolved.ok) {
|
|
449
|
+
const reason = modelPin ? "worker_model_pin_unavailable:verifier" : resolved.reason;
|
|
450
|
+
return { ok: false, skipReason: `independent_verifier_unavailable:${reason}` };
|
|
451
|
+
}
|
|
440
452
|
// Fresh verifier profiles pass through the same shipment admission owner as fresh workers.
|
|
441
453
|
// Recovery-pinned verifier contracts bypass this path and preserve their immutable grant.
|
|
442
454
|
const admitted = resolveWorkerAuthority({
|
|
443
455
|
base: resolved.resolved,
|
|
456
|
+
...(modelPin ? { modelPin: modelPin.binding } : {}),
|
|
444
457
|
modelRegistry: this.deps.getModelRegistry(),
|
|
445
458
|
isModelExhausted: (model) => this.deps.isModelExhausted(model),
|
|
446
459
|
});
|
|
@@ -449,9 +462,10 @@ export class WorkerDelegationController {
|
|
|
449
462
|
: { ok: false, skipReason: `independent_verifier_unavailable:${admitted.reason}` };
|
|
450
463
|
}
|
|
451
464
|
/**
|
|
452
|
-
* A descendant may select a different routing profile, but that preset cannot introduce context
|
|
453
|
-
* its ancestor never admitted. Pointer ids alone are insufficient authority:
|
|
454
|
-
* whose complete immutable metadata matches the ancestral contract,
|
|
465
|
+
* A descendant may select a different routing profile, but that preset cannot introduce context or
|
|
466
|
+
* recursive authority its ancestor never admitted. Pointer ids alone are insufficient authority:
|
|
467
|
+
* retain only pointers whose complete immutable metadata matches the ancestral contract, require
|
|
468
|
+
* exact soul text, and intersect durable delegation limits.
|
|
455
469
|
*/
|
|
456
470
|
narrowWorkerShipmentContext(shipment, boundary) {
|
|
457
471
|
const boundaryPointers = new Map(boundary.resourcePointers.map((pointer) => [pointer.id, pointer]));
|
|
@@ -466,10 +480,15 @@ export class WorkerDelegationController {
|
|
|
466
480
|
if (shipment.soul !== undefined && shipment.soul !== boundary.soul) {
|
|
467
481
|
return { ok: false, skipReason: "orchestration_context_authority_exceeded" };
|
|
468
482
|
}
|
|
483
|
+
const delegationLimits = intersectWorkerDelegationLimits(shipment.profile.delegationLimits, boundary.profile.delegationLimits);
|
|
469
484
|
return {
|
|
470
485
|
ok: true,
|
|
471
486
|
shipment: {
|
|
472
487
|
...shipment,
|
|
488
|
+
profile: {
|
|
489
|
+
...shipment.profile,
|
|
490
|
+
...(delegationLimits ? { delegationLimits } : {}),
|
|
491
|
+
},
|
|
473
492
|
resourcePointers,
|
|
474
493
|
...(shipment.soul ? { soul: shipment.soul } : {}),
|
|
475
494
|
},
|
|
@@ -494,7 +513,11 @@ export class WorkerDelegationController {
|
|
|
494
513
|
}
|
|
495
514
|
/** Reject a new logical identity before creating its task, transcript, agent, or queue entry. */
|
|
496
515
|
newWorkerFleetSkipReason(request, requiredAgentSlots = 1) {
|
|
497
|
-
const
|
|
516
|
+
const parentAttempt = request.parentAgentId
|
|
517
|
+
? this.lifecycle.getLatestAgentAttempt(request.parentAgentId)
|
|
518
|
+
: undefined;
|
|
519
|
+
const limits = resolveWorkerFleetLimits(parentAttempt?.dispatch.executionContract?.worker.profile.delegationLimits);
|
|
520
|
+
const decision = evaluateNewWorkerAdmission(this.lifecycle.getTaskRuntimeSnapshot().agents, request.parentAgentId, limits, requiredAgentSlots);
|
|
498
521
|
return decision.ok ? undefined : decision.reasonCode;
|
|
499
522
|
}
|
|
500
523
|
requiredAgentSlotsForAdmission(request, admission) {
|
|
@@ -515,6 +538,12 @@ export class WorkerDelegationController {
|
|
|
515
538
|
const settings = this.deps.getSettingsManager().getWorkerDelegationSettings();
|
|
516
539
|
if (!settings.enabled)
|
|
517
540
|
return { ok: false, skipReason: "worker_delegation_disabled" };
|
|
541
|
+
const modelPinPolicy = pinnedContract
|
|
542
|
+
? { status: "absent" }
|
|
543
|
+
: this.deps.getSettingsManager().getWorkerModelPinPolicy();
|
|
544
|
+
if (modelPinPolicy.status === "invalid") {
|
|
545
|
+
return { ok: false, skipReason: "worker_model_pins_invalid" };
|
|
546
|
+
}
|
|
518
547
|
const parentAgent = request.parentAgentId ? this.lifecycle.getAgent(request.parentAgentId) : undefined;
|
|
519
548
|
if (request.parentAgentId && !parentAgent) {
|
|
520
549
|
return { ok: false, skipReason: "orchestration_parent_agent_unknown" };
|
|
@@ -540,6 +569,7 @@ export class WorkerDelegationController {
|
|
|
540
569
|
}
|
|
541
570
|
}
|
|
542
571
|
let baseShipment;
|
|
572
|
+
let basePreset;
|
|
543
573
|
if (pinnedContract) {
|
|
544
574
|
const pinned = this.getWorkerProfileResolver().resolveContract(pinnedContract.worker);
|
|
545
575
|
if (!pinned.ok)
|
|
@@ -553,22 +583,41 @@ export class WorkerDelegationController {
|
|
|
553
583
|
baseShipment = inherited.resolved;
|
|
554
584
|
}
|
|
555
585
|
else if (request.profileId || settings.orchestrationProfile) {
|
|
556
|
-
const configured = this.
|
|
586
|
+
const configured = this.resolveWorkerPreset(request, settings);
|
|
557
587
|
if (!configured.ok)
|
|
558
588
|
return configured;
|
|
559
|
-
|
|
589
|
+
basePreset = configured.preset;
|
|
590
|
+
}
|
|
591
|
+
const effectiveRole = authority?.role ?? baseShipment?.profile.role ?? basePreset?.profile.role ?? "orchestrator";
|
|
592
|
+
const modelPin = resolveWorkerModelPin(modelPinPolicy, effectiveRole);
|
|
593
|
+
if (basePreset) {
|
|
594
|
+
const bound = this.getWorkerProfileResolver().bindPreset(basePreset, modelPin?.binding);
|
|
595
|
+
if (!bound.ok) {
|
|
596
|
+
return {
|
|
597
|
+
ok: false,
|
|
598
|
+
skipReason: modelPin ? `worker_model_pin_unavailable:${effectiveRole}` : bound.reason,
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
baseShipment = bound.resolved;
|
|
560
602
|
}
|
|
561
603
|
const adaptive = pinnedContract
|
|
562
604
|
? { ok: true, shipment: baseShipment }
|
|
563
605
|
: resolveWorkerAuthority({
|
|
564
606
|
authority,
|
|
565
607
|
...(baseShipment ? { base: baseShipment } : {}),
|
|
608
|
+
...(modelPin ? { modelPin: modelPin.binding } : {}),
|
|
566
609
|
...(this.deps.getModel() ? { foregroundModel: this.deps.getModel() } : {}),
|
|
567
610
|
modelRegistry: this.deps.getModelRegistry(),
|
|
568
611
|
isModelExhausted: (model) => this.deps.isModelExhausted(model),
|
|
569
612
|
});
|
|
570
|
-
if (!adaptive.ok)
|
|
571
|
-
return {
|
|
613
|
+
if (!adaptive.ok) {
|
|
614
|
+
return {
|
|
615
|
+
ok: false,
|
|
616
|
+
skipReason: modelPin && adaptive.reason === "orchestration_model_unavailable"
|
|
617
|
+
? `worker_model_pin_unavailable:${effectiveRole}`
|
|
618
|
+
: adaptive.reason,
|
|
619
|
+
};
|
|
620
|
+
}
|
|
572
621
|
let shipment = adaptive.shipment;
|
|
573
622
|
if (parentContract) {
|
|
574
623
|
const narrowed = this.narrowWorkerShipmentContext(shipment, parentContract.worker);
|
|
@@ -594,7 +643,7 @@ export class WorkerDelegationController {
|
|
|
594
643
|
verifierShipment = verifier.resolved;
|
|
595
644
|
}
|
|
596
645
|
else {
|
|
597
|
-
const verifier = this.resolveRequiredVerifier(shipment.profile);
|
|
646
|
+
const verifier = this.resolveRequiredVerifier(shipment.profile, modelPinPolicy);
|
|
598
647
|
if (!verifier.ok)
|
|
599
648
|
return verifier;
|
|
600
649
|
verifierShipment = verifier.shipment;
|
|
@@ -829,37 +878,89 @@ export class WorkerDelegationController {
|
|
|
829
878
|
const status = snapshot.attempts[attemptId]?.status;
|
|
830
879
|
if (status === "leased" || status === "running")
|
|
831
880
|
yielded += 1;
|
|
832
|
-
else
|
|
881
|
+
else {
|
|
833
882
|
this.yieldedCapacityAttemptIds.delete(attemptId);
|
|
883
|
+
this.yieldedWriteReservations.delete(attemptId);
|
|
884
|
+
}
|
|
834
885
|
}
|
|
835
886
|
return Math.max(0, this.getWorkerLifecycle().getRunningCount() - yielded) < settings.maxConcurrent;
|
|
836
887
|
}
|
|
837
|
-
|
|
888
|
+
waitTargetsBlockedByCaller(callerAgentId, targetAgentIds) {
|
|
838
889
|
const caller = this.lifecycle.getAgent(callerAgentId);
|
|
839
|
-
const
|
|
840
|
-
if (!
|
|
841
|
-
return
|
|
890
|
+
const callerAttempt = caller ? this.lifecycle.getLatestAgentAttempt(caller.agentId) : undefined;
|
|
891
|
+
if (!callerAttempt || (callerAttempt.status !== "leased" && callerAttempt.status !== "running"))
|
|
892
|
+
return [];
|
|
893
|
+
const blockedAgentIds = [];
|
|
894
|
+
for (const targetAgentId of targetAgentIds) {
|
|
895
|
+
const target = this.lifecycle.getAgent(targetAgentId);
|
|
896
|
+
const targetAttempt = target ? this.lifecycle.getLatestAgentAttempt(target.agentId) : undefined;
|
|
897
|
+
if (targetAttempt?.status === "queued" &&
|
|
898
|
+
this.writeReservations.isBlockedBy(targetAttempt.taskId, callerAttempt.taskId)) {
|
|
899
|
+
blockedAgentIds.push(targetAgentId);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
return blockedAgentIds;
|
|
903
|
+
}
|
|
904
|
+
yieldWorkerForWait(callerAgentId) {
|
|
905
|
+
const caller = this.lifecycle.getAgent(callerAgentId);
|
|
906
|
+
if (!caller)
|
|
907
|
+
return () => true;
|
|
842
908
|
const attempt = this.lifecycle.getLatestAgentAttempt(caller.agentId);
|
|
843
909
|
if (!attempt || (attempt.status !== "leased" && attempt.status !== "running"))
|
|
844
|
-
return () =>
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
910
|
+
return () => true;
|
|
911
|
+
const existingYields = this.yieldedCapacityAttemptIds.get(attempt.attemptId) ?? 0;
|
|
912
|
+
if (existingYields === 0 && attempt.lease) {
|
|
913
|
+
const yieldedReservation = this.writeReservations.yieldForWait(attempt.taskId, attempt.attemptId, attempt.lease.fencingToken);
|
|
914
|
+
if (yieldedReservation)
|
|
915
|
+
this.yieldedWriteReservations.set(attempt.attemptId, yieldedReservation);
|
|
916
|
+
}
|
|
917
|
+
this.yieldedCapacityAttemptIds.set(attempt.attemptId, existingYields + 1);
|
|
918
|
+
let restored = false;
|
|
919
|
+
const restore = () => {
|
|
920
|
+
if (restored)
|
|
921
|
+
return true;
|
|
852
922
|
const leases = this.yieldedCapacityAttemptIds.get(attempt.attemptId);
|
|
853
|
-
if (leases === undefined)
|
|
854
|
-
|
|
923
|
+
if (leases === undefined) {
|
|
924
|
+
restored = true;
|
|
925
|
+
return true;
|
|
926
|
+
}
|
|
855
927
|
if (leases > 1) {
|
|
856
928
|
this.yieldedCapacityAttemptIds.set(attempt.attemptId, leases - 1);
|
|
857
|
-
|
|
929
|
+
restored = true;
|
|
930
|
+
return true;
|
|
931
|
+
}
|
|
932
|
+
const current = this.lifecycle.getLatestAgentAttempt(caller.agentId);
|
|
933
|
+
if (!this.deps.isDisposed() &&
|
|
934
|
+
current?.attemptId === attempt.attemptId &&
|
|
935
|
+
(current.status === "leased" || current.status === "running")) {
|
|
936
|
+
const yieldedReservation = this.yieldedWriteReservations.get(attempt.attemptId);
|
|
937
|
+
if (yieldedReservation) {
|
|
938
|
+
const reservation = this.writeReservations.restoreAfterWait(yieldedReservation);
|
|
939
|
+
if (reservation.kind === "blocked")
|
|
940
|
+
return false;
|
|
941
|
+
if (reservation.kind === "denied") {
|
|
942
|
+
this.laneAbortControllers.get(attempt.taskId)?.abort(reservation.reasonCode);
|
|
943
|
+
throw new Error(`Worker wait could not restore its write reservation: ${reservation.reasonCode}.`);
|
|
944
|
+
}
|
|
945
|
+
}
|
|
858
946
|
}
|
|
859
947
|
this.yieldedCapacityAttemptIds.delete(attempt.attemptId);
|
|
948
|
+
this.yieldedWriteReservations.delete(attempt.attemptId);
|
|
949
|
+
restored = true;
|
|
860
950
|
if (!this.deps.isDisposed())
|
|
861
|
-
this.scheduler.drain();
|
|
951
|
+
this.scheduler.drain(true);
|
|
952
|
+
return true;
|
|
862
953
|
};
|
|
954
|
+
try {
|
|
955
|
+
this.scheduler.drain(true);
|
|
956
|
+
}
|
|
957
|
+
catch (error) {
|
|
958
|
+
if (!restore()) {
|
|
959
|
+
throw new AggregateError([error], "Worker wait dispatch failed before its write reservation could be restored.");
|
|
960
|
+
}
|
|
961
|
+
throw error;
|
|
962
|
+
}
|
|
963
|
+
return restore;
|
|
863
964
|
}
|
|
864
965
|
workerDispatchAdmission(request, record) {
|
|
865
966
|
if (this.recovery.deferRetryIfNeeded(record, request))
|
|
@@ -942,13 +1043,14 @@ export class WorkerDelegationController {
|
|
|
942
1043
|
workerContextForkMode(request, contract) {
|
|
943
1044
|
if (request.verificationOfTaskId)
|
|
944
1045
|
return { kind: "none" };
|
|
1046
|
+
const mode = request.forkTurns ?? (request.parentAgentId ? "none" : undefined);
|
|
945
1047
|
return resolveWorkerContextInheritanceMode({
|
|
946
1048
|
parent: this.workerContextParentModel(request),
|
|
947
1049
|
worker: {
|
|
948
1050
|
provider: contract.worker.modelBinding.provider,
|
|
949
1051
|
model: contract.worker.modelBinding.modelId,
|
|
950
1052
|
},
|
|
951
|
-
...(
|
|
1053
|
+
...(mode !== undefined ? { mode } : {}),
|
|
952
1054
|
});
|
|
953
1055
|
}
|
|
954
1056
|
workerContextForkAdmissionSkipReason(request, contract) {
|
|
@@ -1412,6 +1514,7 @@ export class WorkerDelegationController {
|
|
|
1412
1514
|
startWorkerDelegation: (childRequest) => this.start({ ...childRequest, parentAgentId: agentId }),
|
|
1413
1515
|
runWorkerDelegation: (childRequest) => this.runOnce({ ...childRequest, parentAgentId: agentId }),
|
|
1414
1516
|
orchestrationProfiles: this.getProfileCatalog(),
|
|
1517
|
+
workerModelPinPolicy: this.deps.getSettingsManager().getWorkerModelPinPolicy(),
|
|
1415
1518
|
workerAgentControl: this.agentControl,
|
|
1416
1519
|
caller: { kind: "worker", agentId },
|
|
1417
1520
|
resolveMessageReplayScope: () => ({
|
|
@@ -1499,6 +1602,16 @@ export class WorkerDelegationController {
|
|
|
1499
1602
|
const laneAbortController = new AbortController();
|
|
1500
1603
|
this.laneAbortControllers.set(startedRecord.laneId, laneAbortController);
|
|
1501
1604
|
const workerSignal = AbortSignal.any([this.workerAbort.signal, laneAbortController.signal]);
|
|
1605
|
+
const leaseHeartbeat = new WorkerLeaseHeartbeat({
|
|
1606
|
+
leaseTtlMs: immutableProfile.leaseTtlMs,
|
|
1607
|
+
renew: () => {
|
|
1608
|
+
lifecycle.renewLease(startedRecord.laneId, immutableProfile.leaseTtlMs);
|
|
1609
|
+
},
|
|
1610
|
+
onFailure: (error) => {
|
|
1611
|
+
this.safeWarn(`Worker ${startedRecord.laneId} lease renewal failed: ${error.message}`);
|
|
1612
|
+
laneAbortController.abort(error);
|
|
1613
|
+
},
|
|
1614
|
+
});
|
|
1502
1615
|
// Registered for the lane's full run so the reload gate waits it out; deregistered in the
|
|
1503
1616
|
// finally below no matter how this lane terminates (success, disposal, or a thrown error).
|
|
1504
1617
|
// registerInFlightWork is a pure sync map op (cannot throw), so placing it as the last
|
|
@@ -1551,7 +1664,9 @@ export class WorkerDelegationController {
|
|
|
1551
1664
|
request: workerRequest,
|
|
1552
1665
|
handle: durableHandle,
|
|
1553
1666
|
});
|
|
1667
|
+
leaseHeartbeat.start();
|
|
1554
1668
|
const executionResult = await executor.run();
|
|
1669
|
+
leaseHeartbeat.assertHealthy();
|
|
1555
1670
|
const rawOutcome = executionResult.rawOutcome;
|
|
1556
1671
|
// Attempt ladder: a retryable bounded failure suspends and re-enqueues instead of
|
|
1557
1672
|
// terminalizing, resuming from the persisted transcript under a fresh fence.
|
|
@@ -1733,7 +1848,10 @@ export class WorkerDelegationController {
|
|
|
1733
1848
|
return { started: true, record };
|
|
1734
1849
|
}
|
|
1735
1850
|
finally {
|
|
1851
|
+
leaseHeartbeat.stop();
|
|
1736
1852
|
this.writeReservations.release(startedRecord.laneId, durableHandle.attemptId, durableHandle.fencingToken);
|
|
1853
|
+
this.yieldedCapacityAttemptIds.delete(durableHandle.attemptId);
|
|
1854
|
+
this.yieldedWriteReservations.delete(durableHandle.attemptId);
|
|
1737
1855
|
this.inFlightLedgers.delete(startedRecord.laneId);
|
|
1738
1856
|
this.laneAbortControllers.delete(startedRecord.laneId);
|
|
1739
1857
|
try {
|