@sema-agent/core 7.29.0 → 7.30.0
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 +361 -0
- package/dist/agents/child-model-seat.d.ts +59 -7
- package/dist/agents/child-model-seat.js +33 -7
- package/dist/agents/cross-session-judge.d.ts +27 -5
- package/dist/agents/cross-session-judge.js +23 -12
- package/dist/agents/list-agents-tool.d.ts +31 -6
- package/dist/agents/list-agents-tool.js +66 -14
- package/dist/agents/peer-admission.d.ts +20 -8
- package/dist/agents/peer-admission.js +21 -12
- package/dist/agents/peer-directory.d.ts +29 -0
- package/dist/agents/peer-directory.js +20 -0
- package/dist/agents/peer-held-queue.d.ts +31 -4
- package/dist/agents/peer-held-queue.js +32 -1
- package/dist/agents/peer-session-drain.d.ts +91 -13
- package/dist/agents/peer-session-drain.js +409 -102
- package/dist/agents/read-inbox-tool.d.ts +22 -0
- package/dist/agents/read-inbox-tool.js +39 -0
- package/dist/agents/roster-store.d.ts +2 -4
- package/dist/agents/roster-store.js +1 -1
- package/dist/agents/send-message-tool.d.ts +4 -4
- package/dist/agents/send-message-tool.js +22 -2
- package/dist/agents/subagent.js +62 -44
- package/dist/agents/team-role.d.ts +34 -0
- package/dist/agents/team-role.js +17 -0
- package/dist/agents/verify.js +2 -2
- package/dist/core/auto-compaction.d.ts +42 -0
- package/dist/core/auto-compaction.js +35 -2
- package/dist/core/child-clamp-seats.d.ts +11 -0
- package/dist/core/child-clamp-seats.js +3 -0
- package/dist/core/context-edit.d.ts +3 -2
- package/dist/core/context-edit.js +6 -5
- package/dist/core/context-guard.d.ts +2 -1
- package/dist/core/context-guard.js +3 -2
- package/dist/core/context-settings.d.ts +103 -0
- package/dist/core/context-settings.js +60 -0
- package/dist/core/engine-notice.d.ts +11 -1
- package/dist/core/frame-settlement.d.ts +97 -0
- package/dist/core/frame-settlement.js +36 -0
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +2 -0
- package/dist/core/hooks.d.ts +10 -10
- package/dist/core/mailbox-store.d.ts +41 -7
- package/dist/core/mailbox-store.js +9 -3
- package/dist/core/parent-spec-seat.d.ts +14 -1
- package/dist/core/parent-spec-seat.js +6 -0
- package/dist/core/permission-rule-model.js +1 -1
- package/dist/core/roles.d.ts +20 -0
- package/dist/core/roles.js +35 -16
- package/dist/core/runner/assemble-result.d.ts +2 -0
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/compaction-call-options.d.ts +26 -2
- package/dist/core/runner/compaction-call-options.js +9 -0
- package/dist/core/runner/compaction-seams.d.ts +4 -3
- package/dist/core/runner/compaction-seams.js +13 -6
- package/dist/core/runner/contracts.d.ts +56 -7
- package/dist/core/runner/decide-continuation.d.ts +2 -1
- package/dist/core/runner/decide-continuation.js +11 -10
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/prepare-caps-and-workflow.js +9 -1
- package/dist/core/runner/prepare-config-doors.js +4 -1
- package/dist/core/runner/prepare-context-lane.d.ts +9 -2
- package/dist/core/runner/prepare-context-lane.js +15 -10
- package/dist/core/runner/prepare-delegation-surface.d.ts +3 -2
- package/dist/core/runner/prepare-delegation-surface.js +9 -3
- package/dist/core/runner/prepare-file-history.js +10 -8
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -0
- package/dist/core/runner/prepare-gate-stations.js +3 -1
- package/dist/core/runner/prepare-inherited-gate.js +1 -0
- package/dist/core/runner/prepare-prompt-inputs.d.ts +6 -0
- package/dist/core/runner/prepare-prompt-inputs.js +2 -1
- package/dist/core/runner/prepare-task.js +22 -9
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -1
- package/dist/core/runner/prepare-wiring-manifest.js +6 -1
- package/dist/core/runner/retired-runner-deps.d.ts +3 -1
- package/dist/core/runner/retired-runner-deps.js +1 -0
- package/dist/core/runner/run-compaction-machinery.d.ts +4 -2
- package/dist/core/runner/run-compaction-machinery.js +5 -3
- package/dist/core/runner/run-harness-handlers.js +1 -1
- package/dist/core/runner/run-identity-wiring.js +19 -1
- package/dist/core/runner/run-leg.js +1 -1
- package/dist/core/runner/run-notification-lane.js +8 -2
- package/dist/core/runner/run-recovery-lanes.js +9 -5
- package/dist/core/runner/run-settle-and-teardown.d.ts +4 -22
- package/dist/core/runner/run-settle-and-teardown.js +6 -10
- package/dist/core/runner/run-stop-and-final-verify.js +1 -0
- package/dist/core/runner/run-terminal-adoption.js +5 -5
- package/dist/core/runner/run-turn-boundary.js +32 -5
- package/dist/core/runner/runtask.d.ts +8 -1
- package/dist/core/runner/runtask.js +32 -1
- package/dist/core/runner-deps.d.ts +44 -13
- package/dist/core/swappable-deps.d.ts +20 -4
- package/dist/core/swappable-deps.js +6 -1
- package/dist/core/task-event.d.ts +5 -0
- package/dist/core/task-notification.d.ts +144 -2
- package/dist/core/task-notification.js +154 -5
- package/dist/core/task-result.d.ts +14 -0
- package/dist/core/task-spec.d.ts +7 -0
- package/dist/core/tool-catalog-entries.js +2 -1
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-policy.d.ts +9 -4
- package/dist/core/tool-spec.d.ts +14 -0
- package/dist/core/wiring-manifest.d.ts +12 -0
- package/dist/core/wiring-manifest.js +5 -1
- package/dist/engine/harness/agent-harness.d.ts +14 -1
- package/dist/engine/harness/agent-harness.js +28 -3
- package/dist/engine/harness/types.d.ts +3 -1
- package/dist/engine/llm/types.d.ts +8 -7
- package/dist/engine/llm/types.js +1 -1
- package/dist/engine/session/import-validate.js +4 -0
- package/dist/index.d.ts +10 -7
- package/dist/index.js +7 -5
- package/dist/orchestration/run-workflow-tool.d.ts +4 -4
- package/dist/orchestration/workflow.d.ts +1 -1
- package/dist/orchestration/workflow.js +8 -5
- package/dist/shell/lex.d.ts +30 -51
- package/dist/shell/lex.js +237 -284
- package/dist/stores/cc/mailbox-store.js +3 -2
- package/dist/stores/file/corrupt-read-sink.d.ts +28 -2
- package/dist/stores/file/file-history-store.d.ts +2 -4
- package/dist/stores/file/file-history-store.js +1 -1
- package/dist/stores/file/fs-atomic.d.ts +16 -11
- package/dist/stores/file/fs-atomic.js +17 -6
- package/dist/stores/file/index.d.ts +5 -6
- package/dist/stores/file/index.js +1 -1
- package/dist/stores/file/mailbox-store.d.ts +4 -9
- package/dist/stores/file/mailbox-store.js +29 -30
- package/dist/stores/file/session-policy-store.d.ts +2 -0
- package/dist/stores/file/session-policy-store.js +1 -1
- package/dist/stores/file/session-store.d.ts +11 -7
- package/dist/stores/file/session-store.js +23 -16
- package/dist/stores/file/shared-ledger.js +3 -14
- package/dist/stores/file/tool-result-store.d.ts +2 -0
- package/dist/stores/file/tool-result-store.js +5 -2
- package/dist/stores/file/workflow-journal-store.js +14 -9
- package/dist/tools/fs/bash-program-position.d.ts +15 -24
- package/dist/tools/fs/bash-program-position.js +11 -29
- package/dist/tools/fs/bash-readonly-classifier.d.ts +125 -117
- package/dist/tools/fs/bash-readonly-classifier.js +400 -272
- package/dist/tools/fs/shell-read-check.js +3 -3
- package/dist/tools/fs/shell-read-establish.js +1 -1
- package/dist/tools/fs/shell-read-plan.d.ts +11 -6
- package/dist/tools/fs/shell-read-plan.js +167 -183
- package/dist/tools/fs/shell-read-word.d.ts +50 -0
- package/dist/tools/fs/shell-read-word.js +59 -0
- package/dist/tools/fs/shell-reentry-text.d.ts +10 -0
- package/dist/tools/fs/shell-reentry-text.js +73 -0
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +58 -8
- package/wire-changes/core@7.30.0.json +1821 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { bindPeerLaneDrain } from "../../agents/peer-session-drain.js";
|
|
2
|
+
import { teamRoleOf } from "../../agents/team-role.js";
|
|
2
3
|
import { resolveCheckpointStore } from "../checkpoint-store.js";
|
|
3
4
|
import { createHookEnvCapabilities, mintHookInvocationIdentity } from "../hooks.js";
|
|
4
5
|
import { wiredHookEntries } from "../hook-seats.js";
|
|
@@ -115,7 +116,7 @@ function announceDurableGateUnavailable(args) {
|
|
|
115
116
|
});
|
|
116
117
|
}
|
|
117
118
|
export function prepareWiringManifest(input) {
|
|
118
|
-
const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, sessionBox, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive, lspManagerWired, shellReadStationArmed, lspDiagnosticsLive } = input;
|
|
119
|
+
const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, frameSettlement, sessionBox, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive, lspManagerWired, shellReadStationArmed, lspDiagnosticsLive } = input;
|
|
119
120
|
const onAsk = spec.onAsk ?? deps.onAsk;
|
|
120
121
|
const handWriteTools = toolRoster.entries.filter((e) => e.mountedBy === "hands" && (e.effect === "write" || e.effect === "idempotent")).map((e) => e.name);
|
|
121
122
|
const hasEffectAwareGate = Boolean(policyLayers.length > 0 || (hooks?.preToolUse !== undefined && !preToolUseObservational));
|
|
@@ -179,6 +180,8 @@ export function prepareWiringManifest(input) {
|
|
|
179
180
|
const wiringManifest = deriveWiringManifest({
|
|
180
181
|
half: "effective",
|
|
181
182
|
leg: resume !== undefined ? "resume" : internals?.isDelegatedChild === true ? "child" : "root",
|
|
183
|
+
teamRole: teamRoleOf({ isDelegatedChild: delegation.isDelegatedChild, ...(internals?.explicitAgentName !== undefined ? { spawnName: internals.explicitAgentName } : {}) }),
|
|
184
|
+
...(spec.peerPresence !== undefined ? { peerPresence: spec.peerPresence } : {}),
|
|
182
185
|
askForm: wiringAskSeam.form,
|
|
183
186
|
...(wiringAskSeam.provenance !== undefined ? { askProvenance: wiringAskSeam.provenance } : {}),
|
|
184
187
|
questionWired: wiringQuestionSeam.wired,
|
|
@@ -227,9 +230,11 @@ export function prepareWiringManifest(input) {
|
|
|
227
230
|
inject: internals.onTaskNotification,
|
|
228
231
|
ownTokens: () => internals?.peerSelfRef?.current.ownTokens ?? [],
|
|
229
232
|
refs: peerLaneRefs,
|
|
233
|
+
settlement: frameSettlement,
|
|
230
234
|
selfName: () => internals?.explicitAgentName,
|
|
231
235
|
parked: () => pausedRef.current !== undefined,
|
|
232
236
|
});
|
|
237
|
+
frameSettlement.boxBacked = (payload) => peerLaneRefs.isBoxBacked?.(payload) ?? false;
|
|
233
238
|
}
|
|
234
239
|
const parkLaneArmed = wiringManifest.parkLane.effective === true;
|
|
235
240
|
const gateMachineryActive = effectivePolicy !== undefined ||
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { RunnerDeps } from "../types.js";
|
|
2
|
-
/** Runs
|
|
2
|
+
/** Runs on the caller's own argument at `new Runner` (the only point that still sees an inherited or
|
|
3
|
+
* non-enumerable seat — construction spreads deps into plain objects), and again in the pre-first-await
|
|
4
|
+
* config-doors phase and pre-CAS on a resume. */
|
|
3
5
|
export declare function assertNoRetiredRunnerDeps(deps: RunnerDeps): void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { assertNoRetiredKeys } from "../retired-keys.js";
|
|
2
2
|
const RETIRED_RUNNER_DEPS_KEYS = {
|
|
3
3
|
legacyRewindBoundaryProbe: "the rewind refusal always names both possibilities (never existed / retired whole-tree era); a deployment that holds that era's table answers the question on its own surface",
|
|
4
|
+
peerAdmission: "the peer lane's knob table is `RunnerDeps.peerLane` (the same fields: admission gate, delivery budgets, listing window)",
|
|
4
5
|
};
|
|
5
6
|
export function assertNoRetiredRunnerDeps(deps) {
|
|
6
7
|
assertNoRetiredKeys(deps, RETIRED_RUNNER_DEPS_KEYS, "RunnerDeps");
|
|
@@ -23,8 +23,10 @@ export interface RunCompactionMachineryInput {
|
|
|
23
23
|
export interface RunCompactionMachineryResult {
|
|
24
24
|
/** The accounted compaction brain — `complete` always provided, usage recorded inline. */
|
|
25
25
|
compactionBrain: Brain;
|
|
26
|
-
/** Whether ROUTINE turn-boundary compaction runs for this task.
|
|
27
|
-
|
|
26
|
+
/** Whether ROUTINE turn-boundary compaction runs for this task, asked AT THE BOUNDARY. The request's own
|
|
27
|
+
* `compaction` is fixed for the leg, but the deployment's per-model overlay is a live seat — an operator
|
|
28
|
+
* who turns routine compaction off for a model reaches the legs already on it. */
|
|
29
|
+
withinTaskCompaction: () => boolean;
|
|
28
30
|
/** §17.4: the consecutive-failure circuit breaker shared by every compaction lane of the run. */
|
|
29
31
|
compactionBreaker: {
|
|
30
32
|
failures: number;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_COMPACTION_SETTINGS } from "../../internal/harness.js";
|
|
2
2
|
import { resolveTriggerWindow } from "../context-edit.js";
|
|
3
|
+
import { compactionEnabled, contextOverlayFor } from "../context-settings.js";
|
|
3
4
|
import { sanitizeCompactionSettings } from "../auto-compaction.js";
|
|
4
5
|
import { isModelPriced, modelCostToPricing } from "../pricing.js";
|
|
5
6
|
import { emitTrace } from "../trace.js";
|
|
@@ -45,10 +46,11 @@ export function runCompactionMachinery(input) {
|
|
|
45
46
|
return msg;
|
|
46
47
|
},
|
|
47
48
|
};
|
|
48
|
-
const
|
|
49
|
+
const legOverlay = () => contextOverlayFor(runner.deps.contextSettings, prepared.harness.getModelRef(), runner.deps);
|
|
50
|
+
const withinTaskCompaction = () => compactionEnabled(spec.compaction?.enabled, legOverlay()) && (spec.compaction?.withinTask ?? true);
|
|
49
51
|
const compactionBreaker = { failures: 0 };
|
|
50
|
-
if (spec.compaction?.enabled
|
|
51
|
-
const prefixWindow = resolveTriggerWindow(prepared.model).window;
|
|
52
|
+
if (compactionEnabled(spec.compaction?.enabled, legOverlay())) {
|
|
53
|
+
const prefixWindow = resolveTriggerWindow(prepared.model, legOverlay()).window;
|
|
52
54
|
if (Number.isFinite(prefixWindow) && prefixWindow > 0) {
|
|
53
55
|
const prefixSettings = sanitizeCompactionSettings({ ...DEFAULT_COMPACTION_SETTINGS, ...spec.compaction }, prefixWindow);
|
|
54
56
|
const prefixCompactAt = prefixWindow - prefixSettings.reserveTokens;
|
|
@@ -343,7 +343,7 @@ export function createHarnessHandlers(input) {
|
|
|
343
343
|
rs.degrade.degradeToModel &&
|
|
344
344
|
rs.budget.maxCostMicroUsd !== undefined &&
|
|
345
345
|
stats.costMicroUsd >= spec.limits.degrade.atCostFraction * rs.budget.maxCostMicroUsd) {
|
|
346
|
-
void prepared.harness.setModel(rs.degrade.degradeToModel);
|
|
346
|
+
void prepared.harness.setModel(rs.degrade.degradeToModel, spec.limits.degrade.to);
|
|
347
347
|
rs.degrade.recordDegraded({ from: prepared.model.id, to: rs.degrade.degradeToModel.id, reason: "budget", atTurn: stats.turns }, rs.degrade.degradeToModel);
|
|
348
348
|
}
|
|
349
349
|
const overAxis = rs.limits.budgetHit ? undefined : rs.budget.overBudget();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { uuidv7 } from "../../internal/harness.js";
|
|
2
2
|
import { createSafeNotifier, observeThenableRejection } from "../safe-notify.js";
|
|
3
|
+
import { recordFrameReceipt, toolResultReceiptKey } from "../frame-settlement.js";
|
|
3
4
|
import { discloseDroppedPending, renderTaskNotificationXml, taskNotificationDedupKey } from "../task-notification.js";
|
|
4
5
|
import { deliverDelegationLifecycle, deliverEngineNotice, undrainedUserInputNotices } from "../types.js";
|
|
5
6
|
export function runIdentityWiring(input) {
|
|
@@ -42,8 +43,12 @@ export function runIdentityWiring(input) {
|
|
|
42
43
|
prepared.harness.onUndrainedEngineNotes = (payloads) => {
|
|
43
44
|
if (notificationLane.sessionId === undefined)
|
|
44
45
|
return;
|
|
45
|
-
|
|
46
|
+
const boxBacked = prepared.frameSettlement.boxBacked;
|
|
47
|
+
for (const p of payloads) {
|
|
48
|
+
if (boxBacked !== undefined && boxBacked(p))
|
|
49
|
+
continue;
|
|
46
50
|
pendingSessionNotifications.pend(notificationLane.sessionId, p);
|
|
51
|
+
}
|
|
47
52
|
};
|
|
48
53
|
prepared.harness.engineInjectionsHeld = () => prepared.batchHaltRef.current !== undefined;
|
|
49
54
|
let undrainedUserAtEnd;
|
|
@@ -66,6 +71,19 @@ export function runIdentityWiring(input) {
|
|
|
66
71
|
if (notificationLane.sessionId !== undefined && typeof payload?.task_id === "string" && typeof payload.status === "string")
|
|
67
72
|
pendingSessionNotifications.markDelivered(notificationLane.sessionId, taskNotificationDedupKey(payload));
|
|
68
73
|
};
|
|
74
|
+
prepared.harness.onFrameCommitted = (carrier, entryId) => {
|
|
75
|
+
const seam = prepared.frameSettlement;
|
|
76
|
+
if (seam.awaiting.size === 0)
|
|
77
|
+
return;
|
|
78
|
+
const key = carrier.kind === "tool_result"
|
|
79
|
+
? toolResultReceiptKey(carrier.toolCallId)
|
|
80
|
+
: (() => {
|
|
81
|
+
const payload = carrier.payload;
|
|
82
|
+
return typeof payload?.task_id === "string" && typeof payload.status === "string" ? taskNotificationDedupKey(payload) : undefined;
|
|
83
|
+
})();
|
|
84
|
+
if (key !== undefined)
|
|
85
|
+
recordFrameReceipt(seam, key, carrier.kind === "tool_result" ? carrier.content : undefined, entryId);
|
|
86
|
+
};
|
|
69
87
|
if (notifyRef)
|
|
70
88
|
notifyRef.inject = injectTaskNotification;
|
|
71
89
|
if (captureOptOutRef && prepared.memoryEngineSession?.captureOptOut !== undefined) {
|
|
@@ -107,7 +107,7 @@ export async function runLeg(input) {
|
|
|
107
107
|
rs.limits.budgetAxis = "cost";
|
|
108
108
|
}
|
|
109
109
|
else {
|
|
110
|
-
let continuation = resumeContinuation(resume, prepared.reminderMark);
|
|
110
|
+
let continuation = resumeContinuation(resume, prepared.reminderMark, prepared.fullShellReachable);
|
|
111
111
|
const bgSnapshot = resume.cp.state.runningBackgroundTasks;
|
|
112
112
|
let orphanTasks = [];
|
|
113
113
|
if (bgSnapshot !== undefined && bgSnapshot.length > 0) {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { createPeerInboundChainRef, createPeerSelfRef } from "../../agents/peer-admission.js";
|
|
2
2
|
import { boundInputHashOf } from "../canonical-json.js";
|
|
3
|
-
import { createLiveNotificationLane, isDelegatedAgentTerminal, isTerminalTaskNotification, renderTaskNotificationXml, routeOrParkNotification, SystemInjectionQueue } from "../task-notification.js";
|
|
3
|
+
import { createLiveNotificationLane, DurableAppendObligations, isDelegatedAgentTerminal, isTerminalTaskNotification, renderTaskNotificationXml, routeOrParkNotification, SystemInjectionQueue, taskNotificationDedupKey } from "../task-notification.js";
|
|
4
4
|
import { ToolDetachHub } from "../tool-detach.js";
|
|
5
5
|
import { pendingContentAskCallId } from "./decide-continuation.js";
|
|
6
|
-
export
|
|
6
|
+
export function runNotificationLane(input) {
|
|
7
|
+
const obligations = new DurableAppendObligations();
|
|
8
|
+
return obligations.run(() => runNotificationLaneAs(input, obligations));
|
|
9
|
+
}
|
|
10
|
+
async function runNotificationLaneAs(input, obligations) {
|
|
7
11
|
const { spec, queue, resume, internals, taskIdRef, runner, self, sessions, sessionReadStates, pendingSessionNotifications, prepareTask, next } = input;
|
|
8
12
|
const prepareResume = resume
|
|
9
13
|
? {
|
|
@@ -68,6 +72,7 @@ export async function runNotificationLane(input) {
|
|
|
68
72
|
const noteOptions = {
|
|
69
73
|
provenance: "engine-note",
|
|
70
74
|
enginePayload: item.payload,
|
|
75
|
+
engineNoteKey: taskNotificationDedupKey(item.payload),
|
|
71
76
|
...(item.payload.task_type !== "external" && isTerminalTaskNotification(item.payload) ? { capPreferred: true } : {}),
|
|
72
77
|
};
|
|
73
78
|
const deliver = item.priority === "later"
|
|
@@ -153,5 +158,6 @@ export async function runNotificationLane(input) {
|
|
|
153
158
|
finally {
|
|
154
159
|
if (notificationSessionId !== undefined)
|
|
155
160
|
pendingSessionNotifications.liveLanes.unregister(notificationSessionId, takeAsDestination);
|
|
161
|
+
await obligations.settle();
|
|
156
162
|
}
|
|
157
163
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { compactionKindOf } from "../task-notification.js";
|
|
2
2
|
import { planRejectionClears } from "../context-edit.js";
|
|
3
3
|
import { landStaleResultClears } from "./prepare-context-lane.js";
|
|
4
4
|
import { DEFAULT_COMPACTION_INSTRUCTIONS, maybeCompact, mintCompactedEvent } from "../auto-compaction.js";
|
|
5
5
|
import { emitTrace } from "../trace.js";
|
|
6
6
|
import { isDegenerateCutMessage } from "../../brain/terminal-cause.js";
|
|
7
7
|
import { rebaseCadenceWindows } from "./turn-attachments.js";
|
|
8
|
-
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption } from "./compaction-call-options.js";
|
|
8
|
+
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption, legCompactionSettings, legContextOverlayOption } from "./compaction-call-options.js";
|
|
9
|
+
import { compactionEnabled } from "../context-settings.js";
|
|
9
10
|
import { compactionRestateOptions } from "./compaction-restate.js";
|
|
10
11
|
import { COMPACTION_FREED_EPSILON, COMPACTION_REGROWTH_FACTOR, MAX_CONSECUTIVE_COMPACTION_FAILURES } from "./compaction-knobs.js";
|
|
11
12
|
import { compactionHookOptions, recordCompactionReuse, seamCCompactionOptions } from "./compaction-seams.js";
|
|
@@ -13,7 +14,7 @@ import { asThrownError, thrownText } from "../thrown-value.js";
|
|
|
13
14
|
export function runRecoveryLanes(input) {
|
|
14
15
|
const { spec, prepared, queue, rs, ident, compactionBrain, compactionBreaker, windowSafetyOptions, runner } = input;
|
|
15
16
|
const runForcedCompactionPass = async (lane, turnSignal) => {
|
|
16
|
-
if (!(spec.compaction?.enabled
|
|
17
|
+
if (!compactionEnabled(spec.compaction?.enabled, legContextOverlayOption(prepared, runner).contextOverlay))
|
|
17
18
|
return false;
|
|
18
19
|
if (compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES)
|
|
19
20
|
return false;
|
|
@@ -24,12 +25,13 @@ export function runRecoveryLanes(input) {
|
|
|
24
25
|
epochDeclaredSections: prepared.epochDeclaredSections,
|
|
25
26
|
...centerAdoptionOption(prepared),
|
|
26
27
|
model: prepared.harness.getModel(),
|
|
28
|
+
...legContextOverlayOption(prepared, runner),
|
|
27
29
|
compactionModel: prepared.compModel,
|
|
28
30
|
...forkContextOption(prepared, true),
|
|
29
31
|
brain: compactionBrain,
|
|
30
32
|
getApiKeyAndHeaders: spec.getApiKeyAndHeaders,
|
|
31
33
|
thinking: prepared.thinking,
|
|
32
|
-
settings:
|
|
34
|
+
settings: legCompactionSettings(spec, legContextOverlayOption(prepared, runner).contextOverlay),
|
|
33
35
|
customInstructions: spec.compaction?.instructions ?? DEFAULT_COMPACTION_INSTRUCTIONS,
|
|
34
36
|
signal: passSignal,
|
|
35
37
|
minTokens: 0,
|
|
@@ -52,6 +54,8 @@ export function runRecoveryLanes(input) {
|
|
|
52
54
|
rs.counters.compactionFloor = Math.ceil(comp.postTriggerTokens * COMPACTION_REGROWTH_FACTOR);
|
|
53
55
|
}
|
|
54
56
|
queue.push(mintCompactedEvent(comp, "forced", ident()));
|
|
57
|
+
rs.counters.compactionPasses += 1;
|
|
58
|
+
rs.counters.compactionKind = compactionKindOf("forced");
|
|
55
59
|
if (comp.phaseDurations !== undefined && comp.durationMs !== undefined) {
|
|
56
60
|
const pd = comp.phaseDurations;
|
|
57
61
|
const pdDur = comp.durationMs;
|
|
@@ -112,7 +116,7 @@ export function runRecoveryLanes(input) {
|
|
|
112
116
|
return false;
|
|
113
117
|
if (prepared.microCompact.clearOnRejection && attempt === 1) {
|
|
114
118
|
const proj = prepared.microCompact.projectionRef.current;
|
|
115
|
-
const compactionAvailable = (spec.compaction?.enabled
|
|
119
|
+
const compactionAvailable = compactionEnabled(spec.compaction?.enabled, legContextOverlayOption(prepared, runner).contextOverlay) && compactionBreaker.failures < MAX_CONSECUTIVE_COMPACTION_FAILURES;
|
|
116
120
|
const declineArm = compactionAvailable ? "forced_compaction" : "none";
|
|
117
121
|
const plan = proj === undefined
|
|
118
122
|
? { declined: "no_candidates" }
|
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The run body's SETTLE AND TEARDOWN (R15), verbatim from `Runner.runLocked`: the end-of-task
|
|
3
|
-
* compaction's frames and detector reset, the nested-stats fold, the prefix-cache observability and its loud
|
|
4
|
-
* mismatch / low-hit disclosures, the cross-slice cumulative spend fold, the human-review and mechanism counters,
|
|
5
|
-
* the result assembly (`assembleResult` — the one place the leg's facts become a TaskResult), the resume leg's
|
|
6
|
-
* unstarted-action reopen compensation, the read-state seal and the settle-time workspace-state write, the
|
|
7
|
-
* StopFailure observer, the delegation-lifecycle terminal, the reap-stash for a committed pause, the resumed-terminal
|
|
8
|
-
* unpin, the memory harvest, the `task.end` trace, `setResult`, the sub-agent's terminal tick, the mooted manual
|
|
9
|
-
* compaction, the forwarded-frame drain and the queue's `done` + close, the file-history boundary settle and the
|
|
10
|
-
* prompt-suggestion kickoff — then, in its finally, the four teardown legs in the order they were: the shell-lane
|
|
11
|
-
* children settle, the background-shell sweep, the registry clears / the background-agent abort / the retained
|
|
12
|
-
* child sessions, and the owned env's teardown. The suggestion pass (`suggestNextPrompts`, with its four bounds) and the
|
|
13
|
-
* owned-env teardown (`teardownOwnedEnv`) are the lane's own module-private functions since S7, verbatim from
|
|
14
|
-
* the Runner's private methods: each has this one caller, and a sibling file would be a lane-to-lane reach (the S6 legs' reading).
|
|
15
|
-
*
|
|
16
|
-
* Async (eleven first-level awaits, all of them the same awaits at the same positions). The `queue.push("done")` and
|
|
17
|
-
* the teardown legs' order are contract (the forwarded-frame drain lands before `done`; the env is torn down after
|
|
18
|
-
* every reader of it); nothing here reorders them. Products: the result is PUBLISHED through `setResult` and the
|
|
19
|
-
* effects are installed on the borrowed seats — nothing comes back to the driver (the same empty Result the seat
|
|
20
|
-
* lanes whose products are all installations carry).
|
|
21
|
-
*/
|
|
22
1
|
import type { AssistantMessage } from "../../internal/llm.js";
|
|
23
2
|
import type { ResolvedReasoning } from "../../brain/reasoning.js";
|
|
24
3
|
import type { PushQueue } from "../push-queue.js";
|
|
@@ -27,7 +6,7 @@ import { type CompactOutcome, type DelegationLifecycleEvent, type OwedUserInputA
|
|
|
27
6
|
import { type Stats } from "./assemble-result.js";
|
|
28
7
|
import type { EndOfTaskCompaction, InstallingPhaseResult, ManualCompactRef, Prepared, ResumeRun, RunInternals, RunnerDepsSeat, RunState, SuspendReap, TaskIdRef } from "./contracts.js";
|
|
29
8
|
export interface RunSettleAndTeardownInput {
|
|
30
|
-
/** borrowed-readonly — the task spec: the hooks slot, the suggestion opt-in, the retain / forward flags, the task id
|
|
9
|
+
/** borrowed-readonly — the task spec: the hooks slot, the suggestion opt-in, the retain / forward flags, the task id. */
|
|
31
10
|
spec: TaskSpec;
|
|
32
11
|
/** borrowed-mutable — the run's event queue: the compaction / human-input / task_progress / done frames, then CLOSED here. */
|
|
33
12
|
queue: PushQueue<TaskEvent>;
|
|
@@ -94,6 +73,9 @@ export interface RunSettleAndTeardownInput {
|
|
|
94
73
|
};
|
|
95
74
|
/** borrowed-readonly — the end-of-task compaction's outcome (the terminal-adoption lane's `finish` call). */
|
|
96
75
|
comp: EndOfTaskCompaction;
|
|
76
|
+
/** borrowed-readonly — the run's compaction breaker: the ONE source of `TaskResult.compaction.breakerOpen`. */ compactionBreaker: {
|
|
77
|
+
readonly failures: number;
|
|
78
|
+
};
|
|
97
79
|
/** borrowed-readonly — the adoption lane's unsettled undrained-input account, closed below (after the reopen). */
|
|
98
80
|
owedUserInput: OwedUserInputAccount;
|
|
99
81
|
/** borrowed-readonly — the stream's result setter: the assembled TaskResult is published through it exactly once. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MAX_CONSECUTIVE_COMPACTION_FAILURES } from "./compaction-knobs.js";
|
|
1
2
|
import { isSyntheticApiErrorMessage } from "../../internal/harness.js";
|
|
2
3
|
import { adjudicateDerivedRoute, fallbackToPrimaryNotice, sameRouteIdentity } from "../../brain/route-adjudicator.js";
|
|
3
4
|
import { isDegenerateCutMessage } from "../../brain/terminal-cause.js";
|
|
@@ -23,7 +24,7 @@ import { amendTerminal, terminalProjection } from "./terminal-projection.js";
|
|
|
23
24
|
import { mintCompactedEvent } from "../auto-compaction.js";
|
|
24
25
|
import { asThrownError } from "../thrown-value.js";
|
|
25
26
|
export async function runSettleAndTeardown(input) {
|
|
26
|
-
const { spec, queue, prepared, resume, internals, rs, stats, ident, parentToolCallId, subagentName, loopLatch, timeout, ownCommittedTailRef, emitDelegationLifecycle, taskIdRef, manualCompactRef, drainManualCompact, final, threw, abortedLive, userInterruptedLive, answerSettled, strandedHumanAnswers, reasoningResolution, comp, owedUserInput, setResult, onSuggestions, onSuspend, runner, sessions } = input;
|
|
27
|
+
const { spec, queue, prepared, resume, internals, rs, stats, ident, parentToolCallId, subagentName, loopLatch, timeout, ownCommittedTailRef, emitDelegationLifecycle, taskIdRef, manualCompactRef, drainManualCompact, final, threw, abortedLive, userInterruptedLive, answerSettled, strandedHumanAnswers, reasoningResolution, comp, compactionBreaker, owedUserInput, setResult, onSuggestions, onSuspend, runner, sessions } = input;
|
|
27
28
|
try {
|
|
28
29
|
if (comp?.compacted) {
|
|
29
30
|
queue.push(mintCompactedEvent(comp, "auto", ident()));
|
|
@@ -100,6 +101,7 @@ export async function runSettleAndTeardown(input) {
|
|
|
100
101
|
effectiveReadDenyPatterns: prepared.effectiveReadDenyPatterns,
|
|
101
102
|
effectiveMemoryScopes: prepared.effectiveMemoryScopes,
|
|
102
103
|
effectiveReasoning: reasoningResolution.current,
|
|
104
|
+
...(rs.counters.compactionPasses > 0 || compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES ? { compaction: { passes: rs.counters.compactionPasses, breakerOpen: compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES, ...(rs.counters.compactionKind !== undefined ? { kind: rs.counters.compactionKind } : {}) } } : {}),
|
|
103
105
|
retryAfterMs: rs.limits.platformTerminal?.retryAfterMs,
|
|
104
106
|
abortedForTimeout: timeout.fired,
|
|
105
107
|
abortedForTurns: rs.limits.turnsExceeded,
|
|
@@ -295,7 +297,7 @@ export async function runSettleAndTeardown(input) {
|
|
|
295
297
|
hasDestroy(prepared.ownedEnv) &&
|
|
296
298
|
isIsolated(prepared.ownedEnv) &&
|
|
297
299
|
prepared.pausedRef.current === undefined;
|
|
298
|
-
await settleTeardownLeg(() => defaultTaskRegistry.settleKilledForOwner({
|
|
300
|
+
await settleTeardownLeg(() => defaultTaskRegistry.settleKilledForOwner({ ...prepared.registryAccess, sessionId: prepared.sessionId }, {
|
|
299
301
|
source: abortedLive &&
|
|
300
302
|
!answerSettled &&
|
|
301
303
|
!timeout.fired &&
|
|
@@ -325,14 +327,8 @@ export async function runSettleAndTeardown(input) {
|
|
|
325
327
|
runner.deps.onError?.(e, { phase: "config", sessionId: prepared.sessionId });
|
|
326
328
|
}
|
|
327
329
|
}
|
|
328
|
-
defaultTaskRegistry.clearBackgroundForOwner(
|
|
329
|
-
|
|
330
|
-
scope: spec.principal ?? "default",
|
|
331
|
-
});
|
|
332
|
-
defaultTaskRegistry.abortBackgroundAgentsForOwner({
|
|
333
|
-
owner: spec.taskId ?? prepared.sessionId,
|
|
334
|
-
scope: spec.principal ?? "default",
|
|
335
|
-
}, { skipSessionScoped: true });
|
|
330
|
+
defaultTaskRegistry.clearBackgroundForOwner(prepared.registryAccess);
|
|
331
|
+
defaultTaskRegistry.abortBackgroundAgentsForOwner(prepared.registryAccess, { skipSessionScoped: true });
|
|
336
332
|
if (prepared.subagentRetain) {
|
|
337
333
|
await settleTeardownLeg(() => prepared.subagentRetain.disposeAll(), "subagentRetain.disposeAll", (e) => runner.deps.onError?.(e, { phase: "config", sessionId: prepared.sessionId }));
|
|
338
334
|
}
|
|
@@ -108,6 +108,7 @@ export function runStopAndFinalVerify(input) {
|
|
|
108
108
|
stopHookActive: consecutiveBlocks > 0,
|
|
109
109
|
consecutiveBlocks,
|
|
110
110
|
getBranch: () => prepared.session.getBranch(),
|
|
111
|
+
backgroundTasks: () => prepared.listBackgroundTasks(),
|
|
111
112
|
identity: prepared.hookIdentity,
|
|
112
113
|
signal: sig,
|
|
113
114
|
}));
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { DEFAULT_COMPACTION_INSTRUCTIONS, maybeCompact } from "../auto-compaction.js";
|
|
2
|
-
import { DEFAULT_COMPACTION_SETTINGS } from "../../internal/harness.js";
|
|
3
2
|
import { eventDefaultOn } from "../../prompt-assembly/event-registry.js";
|
|
4
3
|
import { appendInterruptionMarker, reconcileInterruptedSession } from "../session-reconcile.js";
|
|
5
4
|
import { emitTrace } from "../trace.js";
|
|
6
5
|
import { answerSettled, errorCodeOf } from "./assemble-result.js";
|
|
7
6
|
import { awaitChargeWithSlowDisclosure, discloseUnevaluableWindow } from "./clock-and-limits.js";
|
|
8
|
-
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption } from "./compaction-call-options.js";
|
|
7
|
+
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption, legCompactionSettings, legContextOverlayOption } from "./compaction-call-options.js";
|
|
9
8
|
import { compactionHookOptions, recordCompactionReuse, seamCCompactionOptions } from "./compaction-seams.js";
|
|
10
9
|
import { compactionRestateOptions } from "./compaction-restate.js";
|
|
11
10
|
import { MAX_CONSECUTIVE_COMPACTION_FAILURES } from "./compaction-knobs.js";
|
|
@@ -118,7 +117,7 @@ export async function runTerminalAdoption(input) {
|
|
|
118
117
|
skipCompaction: durablyPaused || (abortedLive && settled) || compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES,
|
|
119
118
|
minTokens: rs.counters.compactionFloor,
|
|
120
119
|
brain: compactionBrain,
|
|
121
|
-
windowSafety: windowSafetyOptions(prepared.
|
|
120
|
+
windowSafety: windowSafetyOptions(prepared.harness.getModel()),
|
|
122
121
|
onCompactionFailed: (reason) => queue.push({ type: "compaction_outcome", outcome: "failed", trigger: "auto", reason, ...ident() }),
|
|
123
122
|
cancelled: abortedLive,
|
|
124
123
|
}, runner, sessions);
|
|
@@ -132,13 +131,14 @@ async function finish(spec, prepared, opts, runner, sessions) {
|
|
|
132
131
|
session: prepared.session,
|
|
133
132
|
epochDeclaredSections: prepared.epochDeclaredSections,
|
|
134
133
|
...centerAdoptionOption(prepared),
|
|
135
|
-
model: prepared.
|
|
134
|
+
model: prepared.harness.getModel(),
|
|
135
|
+
...legContextOverlayOption(prepared, runner),
|
|
136
136
|
compactionModel: prepared.compModel,
|
|
137
137
|
...forkContextOption(prepared, false),
|
|
138
138
|
brain: opts?.brain ?? runner.deps.brain,
|
|
139
139
|
getApiKeyAndHeaders: spec.getApiKeyAndHeaders,
|
|
140
140
|
thinking: prepared.thinking,
|
|
141
|
-
settings:
|
|
141
|
+
settings: legCompactionSettings(spec, legContextOverlayOption(prepared, runner).contextOverlay),
|
|
142
142
|
customInstructions: spec.compaction?.instructions ?? DEFAULT_COMPACTION_INSTRUCTIONS,
|
|
143
143
|
minTokens: opts?.minTokens,
|
|
144
144
|
overheadTokens: prepared.promptOverheadTokens,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { compactionKindOf } from "../task-notification.js";
|
|
1
2
|
import { mintSystemReminder } from "../reminder-mint.js";
|
|
2
|
-
import { DEFAULT_COMPACTION_SETTINGS } from "../../internal/harness.js";
|
|
3
3
|
import { eventDefaultOn } from "../../prompt-assembly/event-registry.js";
|
|
4
4
|
import { DEFAULT_COMPACTION_INSTRUCTIONS, isCompactionManualCancel, maybeCompact, mintCompactedEvent, nextTrimForceBackoff, recordCompactionAndCheckRapidRefill } from "../auto-compaction.js";
|
|
5
5
|
import { emitTrace } from "../trace.js";
|
|
6
6
|
import { redactThenCut } from "../../agents/subagent-steps.js";
|
|
7
7
|
import { ATTACHMENT_BYTE_CAP, CHANGED_FILES_MAX, TOTAL_TOKENS_REMINDER_DEFAULT_MODE, attachmentEnvelopeTags, clipToBytes, collectDateChange, collectDueAttachments, collectInstructionsChange, commitAgentListing, commitInstructionsChange, commitSkillsListing, isIntactSource, rebaseCadenceWindows, renderAgentListingFrame, renderMcpDroppedTools, renderMcpInstructionsDelta, selectMcpDroppedBatch, renderSkillsListingFrame, renderToolsDelta } from "./turn-attachments.js";
|
|
8
8
|
import { announceListingTruncation } from "../skill-listing-budget.js";
|
|
9
|
-
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption } from "./compaction-call-options.js";
|
|
9
|
+
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption, legCompactionSettings, legContextOverlayOption } from "./compaction-call-options.js";
|
|
10
10
|
import { hookSeatExpiredError, runHookSeat } from "../hooks.js";
|
|
11
11
|
import { sanitizeUntrustedText, SHELLED_BODY_ENVELOPE_TAGS } from "../untrusted-text.js";
|
|
12
12
|
import { droppedToolDigest, withAnnounceDigests } from "./announce-once-ledger.js";
|
|
@@ -24,7 +24,8 @@ export function createTurnBoundary(input) {
|
|
|
24
24
|
const { prepared, stats, rs, deps } = input;
|
|
25
25
|
const { spec, queue, manualCompactRef, todoToolMounted, taskToolsMounted, walltimeMonotonicDeadline, timeout, ident, postToolBatchHook, batchArgs, compactionBrain, withinTaskCompaction, compactionBreaker, windowSafetyOptions, rapidRefill, drainManualCompact, runnerHooks, runner } = deps;
|
|
26
26
|
let finalVerifySeenAtLastBoundary = 0;
|
|
27
|
-
|
|
27
|
+
let legContinues = true;
|
|
28
|
+
const boundaryPass = async (event) => {
|
|
28
29
|
let boundarySteered = false;
|
|
29
30
|
const noNextRequest = () => prepared.stopRequestedRef.current || deps.loopLatch.userHalted;
|
|
30
31
|
const walltimeHit = walltimeMonotonicDeadline !== undefined && performance.now() >= walltimeMonotonicDeadline;
|
|
@@ -75,6 +76,7 @@ export function createTurnBoundary(input) {
|
|
|
75
76
|
rs.limits.platformTerminal = asThrownError(govErr);
|
|
76
77
|
void prepared.harness.abort();
|
|
77
78
|
prepared.abortController.abort();
|
|
79
|
+
legContinues = false;
|
|
78
80
|
return undefined;
|
|
79
81
|
}
|
|
80
82
|
}
|
|
@@ -89,6 +91,7 @@ export function createTurnBoundary(input) {
|
|
|
89
91
|
if (committed) {
|
|
90
92
|
rs.limits.turnsExceeded = false;
|
|
91
93
|
rs.limits.budgetHit = undefined;
|
|
94
|
+
legContinues = false;
|
|
92
95
|
return undefined;
|
|
93
96
|
}
|
|
94
97
|
const terminal = platformLimitTerminal(platformCause, platformRetryAfterMs);
|
|
@@ -100,6 +103,7 @@ export function createTurnBoundary(input) {
|
|
|
100
103
|
}
|
|
101
104
|
void prepared.harness.abort();
|
|
102
105
|
prepared.abortController.abort();
|
|
106
|
+
legContinues = false;
|
|
103
107
|
return undefined;
|
|
104
108
|
}
|
|
105
109
|
if (prepared.suspendForResource &&
|
|
@@ -123,6 +127,7 @@ export function createTurnBoundary(input) {
|
|
|
123
127
|
void prepared.harness.abort();
|
|
124
128
|
prepared.abortController.abort();
|
|
125
129
|
}
|
|
130
|
+
legContinues = false;
|
|
126
131
|
return undefined;
|
|
127
132
|
}
|
|
128
133
|
if (walltimeMonotonicDeadline !== undefined &&
|
|
@@ -136,6 +141,7 @@ export function createTurnBoundary(input) {
|
|
|
136
141
|
void prepared.harness.abort();
|
|
137
142
|
prepared.abortController.abort();
|
|
138
143
|
}
|
|
144
|
+
legContinues = false;
|
|
139
145
|
return undefined;
|
|
140
146
|
}
|
|
141
147
|
const approachCfg = spec.limits?.approachNotice;
|
|
@@ -186,6 +192,7 @@ export function createTurnBoundary(input) {
|
|
|
186
192
|
prepared.pausedRef.current === undefined;
|
|
187
193
|
if (honorable && prepared.suspendForReview) {
|
|
188
194
|
await prepared.suspendForReview(reason);
|
|
195
|
+
legContinues = !prepared.abortController.signal.aborted && prepared.pausedRef.current === undefined;
|
|
189
196
|
return undefined;
|
|
190
197
|
}
|
|
191
198
|
emitTrace(rs.telemetry.tracer, () => ({ kind: "review.dropped", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
@@ -496,7 +503,7 @@ export function createTurnBoundary(input) {
|
|
|
496
503
|
});
|
|
497
504
|
}
|
|
498
505
|
const forceManual = manualCompactRef.requested;
|
|
499
|
-
if ((!withinTaskCompaction && !forceManual) ||
|
|
506
|
+
if ((!withinTaskCompaction() && !forceManual) ||
|
|
500
507
|
prepared.abortController.signal.aborted ||
|
|
501
508
|
prepared.pausedRef.current !== undefined) {
|
|
502
509
|
if (forceManual) {
|
|
@@ -504,6 +511,7 @@ export function createTurnBoundary(input) {
|
|
|
504
511
|
queue.push({ type: "compaction_outcome", outcome: "mooted", trigger: "manual", reason: "task_ending", ...ident() });
|
|
505
512
|
drainManualCompact("mooted");
|
|
506
513
|
}
|
|
514
|
+
legContinues = !prepared.abortController.signal.aborted && prepared.pausedRef.current === undefined;
|
|
507
515
|
return undefined;
|
|
508
516
|
}
|
|
509
517
|
if (compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES) {
|
|
@@ -564,12 +572,13 @@ export function createTurnBoundary(input) {
|
|
|
564
572
|
epochDeclaredSections: prepared.epochDeclaredSections,
|
|
565
573
|
...centerAdoptionOption(prepared),
|
|
566
574
|
model: event.model,
|
|
575
|
+
...legContextOverlayOption(prepared, runner),
|
|
567
576
|
compactionModel: prepared.compModel,
|
|
568
577
|
...forkContextOption(prepared, false),
|
|
569
578
|
brain: compactionBrain,
|
|
570
579
|
getApiKeyAndHeaders: spec.getApiKeyAndHeaders,
|
|
571
580
|
thinking: prepared.thinking,
|
|
572
|
-
settings:
|
|
581
|
+
settings: legCompactionSettings(spec, legContextOverlayOption(prepared, runner).contextOverlay),
|
|
573
582
|
customInstructions: manualInstructions ?? spec.compaction?.instructions ?? DEFAULT_COMPACTION_INSTRUCTIONS,
|
|
574
583
|
signal: compactionPassSignal,
|
|
575
584
|
...(manualCancelSignal !== undefined ? { manualCancelSignal } : {}),
|
|
@@ -644,6 +653,8 @@ export function createTurnBoundary(input) {
|
|
|
644
653
|
recordCompactionReuse(runner, prepared, comp);
|
|
645
654
|
if (comp.compacted) {
|
|
646
655
|
queue.push(mintCompactedEvent(comp, passTrigger, ident()));
|
|
656
|
+
rs.counters.compactionPasses += 1;
|
|
657
|
+
rs.counters.compactionKind = compactionKindOf(passTrigger);
|
|
647
658
|
if (!forceManual && recordCompactionAndCheckRapidRefill(rapidRefill, stats.turns)) {
|
|
648
659
|
compactionBreaker.failures = MAX_CONSECUTIVE_COMPACTION_FAILURES;
|
|
649
660
|
queue.push({ type: "compaction_outcome", outcome: "disabled", trigger: passTrigger, reason: "rapid_refill: compaction disabled for the rest of this task", ...ident() });
|
|
@@ -695,5 +706,21 @@ export function createTurnBoundary(input) {
|
|
|
695
706
|
resolveClaimedWaiters(manualOutcome);
|
|
696
707
|
return undefined;
|
|
697
708
|
};
|
|
709
|
+
const onTurnBoundary = async (event) => {
|
|
710
|
+
legContinues = true;
|
|
711
|
+
try {
|
|
712
|
+
return await boundaryPass(event);
|
|
713
|
+
}
|
|
714
|
+
finally {
|
|
715
|
+
const round = prepared.peerBoundaryRound;
|
|
716
|
+
if (round !== undefined) {
|
|
717
|
+
try {
|
|
718
|
+
await round({ continues: legContinues });
|
|
719
|
+
}
|
|
720
|
+
catch {
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
};
|
|
698
725
|
return onTurnBoundary;
|
|
699
726
|
}
|
|
@@ -4,7 +4,8 @@ import { type TaskOutcome } from "../task-outcome.js";
|
|
|
4
4
|
import { type SwappableDeps } from "../swappable-deps.js";
|
|
5
5
|
import { type SideQuerySpec, type SideQueryResult } from "../side-query.js";
|
|
6
6
|
import type { SessionStore } from "../session.js";
|
|
7
|
-
import type { AgentDefinition, ModelRoles, RunnerDeps, TaskEvent, TaskResult, TaskSpec, TaskStream } from "../types.js";
|
|
7
|
+
import type { AgentDefinition, ModelRef, ModelRoles, RunnerDeps, TaskEvent, TaskResult, TaskSpec, TaskStream } from "../types.js";
|
|
8
|
+
import { type ContextSettings, type ContextWindowOverlay } from "../context-settings.js";
|
|
8
9
|
import type { ResumeRun, ResumeTaskConfig, RunInternals, RunnerSelfSeat } from "./contracts.js";
|
|
9
10
|
export type { ResumeTaskConfig } from "./contracts.js";
|
|
10
11
|
/**
|
|
@@ -77,6 +78,12 @@ export declare class Runner implements RunnerSelfSeat {
|
|
|
77
78
|
models?: Record<string, Model>;
|
|
78
79
|
roles?: ModelRoles;
|
|
79
80
|
};
|
|
81
|
+
/** The deployment's per-model context-window overlay as declared ({@link RunnerDeps.contextSettings}); a fresh
|
|
82
|
+
* read every call, the overlay objects frozen at their gate. */
|
|
83
|
+
get contextSettings(): ContextSettings | undefined;
|
|
84
|
+
/** The overlay a leg on `ref` reads RIGHT NOW — the one lookup ({@link contextOverlayFor}, tier aliases
|
|
85
|
+
* followed) against the seat and catalog in force, so a `swapDeps` reaches legs already running. */
|
|
86
|
+
contextOverlayOf(ref: ModelRef | undefined): ContextWindowOverlay | undefined;
|
|
80
87
|
/** The deployment-level gating baseline, exposed READ-ONLY so thin
|
|
81
88
|
* assemblers over the Runner (`runSpec`) can COMPOSE with it. The task-level engine semantic is a
|
|
82
89
|
* WHOLE-SLOT override (`spec.toolPolicy ?? deps.toolPolicy`, same for hooks — prepare-task), so any
|
|
@@ -21,6 +21,7 @@ import { PAUSE_REGISTRY } from "../pause-registry.js";
|
|
|
21
21
|
import { toolPolicyNameSets } from "../tool-policy.js";
|
|
22
22
|
import { PendingSessionNotifications } from "../task-notification.js";
|
|
23
23
|
import { ToolDetachHub } from "../tool-detach.js";
|
|
24
|
+
import { assertContextSettingsValue, assertContextSettingsWords, contextOverlayFor } from "../context-settings.js";
|
|
24
25
|
import { createRunState } from "./initial-run-state.js";
|
|
25
26
|
import { reconciledToolEndBody } from "./tool-end-body.js";
|
|
26
27
|
import { answerFaceForRedeemedCall } from "./decide-continuation.js";
|
|
@@ -40,6 +41,7 @@ import { streamSteerVerb } from "./stream-steer-verb.js";
|
|
|
40
41
|
import { streamLifecycleVerbs } from "./stream-lifecycle-verbs.js";
|
|
41
42
|
import { streamHaltVerbs } from "./stream-halt-verbs.js";
|
|
42
43
|
import { runNotificationLane } from "./run-notification-lane.js";
|
|
44
|
+
import { assertNoRetiredRunnerDeps } from "./retired-runner-deps.js";
|
|
43
45
|
import { runLeg } from "./run-leg.js";
|
|
44
46
|
import { runTerminalAdoption } from "./run-terminal-adoption.js";
|
|
45
47
|
import { runSettleAndTeardown } from "./run-settle-and-teardown.js";
|
|
@@ -69,12 +71,16 @@ export class Runner {
|
|
|
69
71
|
static PARENT_CONSTRAINT_REGISTRY_CAP = 1024;
|
|
70
72
|
depsSeat;
|
|
71
73
|
constructor(deps) {
|
|
74
|
+
assertNoRetiredRunnerDeps(deps);
|
|
72
75
|
const runner = this;
|
|
73
76
|
this.depsSeat = { get deps() { return runner.deps; } };
|
|
74
77
|
this.deps = deps;
|
|
75
78
|
if (this.deps.tiers) {
|
|
76
79
|
this.deps = { ...this.deps, models: expandTiers(this.deps.models, this.deps.tiers) };
|
|
77
80
|
}
|
|
81
|
+
if (this.deps.contextSettings !== undefined) {
|
|
82
|
+
this.deps = { ...this.deps, contextSettings: assertContextSettingsWords(assertContextSettingsValue(this.deps.contextSettings, "RunnerDeps"), this.deps.models, "RunnerDeps") };
|
|
83
|
+
}
|
|
78
84
|
if (this.deps.onError) {
|
|
79
85
|
const rawOnError = this.deps.onError;
|
|
80
86
|
const reportSinkFailure = (sinkErr, context) => {
|
|
@@ -121,6 +127,12 @@ export class Runner {
|
|
|
121
127
|
...(this.deps.models ? { models: { ...this.deps.models } } : {}), ...(this.deps.roles ? { roles: { ...this.deps.roles } } : {}),
|
|
122
128
|
};
|
|
123
129
|
}
|
|
130
|
+
get contextSettings() {
|
|
131
|
+
return this.deps.contextSettings;
|
|
132
|
+
}
|
|
133
|
+
contextOverlayOf(ref) {
|
|
134
|
+
return contextOverlayFor(this.deps.contextSettings, ref, this.deps);
|
|
135
|
+
}
|
|
124
136
|
get gateBaseline() {
|
|
125
137
|
const deps = this.deps;
|
|
126
138
|
const h = deps.hooks;
|
|
@@ -232,6 +244,14 @@ export class Runner {
|
|
|
232
244
|
else
|
|
233
245
|
delete writtenFaceSeats[seat];
|
|
234
246
|
}
|
|
247
|
+
const priorContextSettings = this.deps.contextSettings;
|
|
248
|
+
if (seats.includes("contextSettings")) {
|
|
249
|
+
if (candidate.contextSettings !== undefined)
|
|
250
|
+
written.contextSettings = candidate.contextSettings;
|
|
251
|
+
else
|
|
252
|
+
delete written.contextSettings;
|
|
253
|
+
}
|
|
254
|
+
assertContextSettingsWords(written.contextSettings, written.models, "swapDeps");
|
|
235
255
|
this.deps = written;
|
|
236
256
|
if (catalogSwap) {
|
|
237
257
|
const modelCount = Object.keys(candidate.models).length;
|
|
@@ -253,6 +273,17 @@ export class Runner {
|
|
|
253
273
|
});
|
|
254
274
|
}
|
|
255
275
|
}
|
|
276
|
+
if (seats.includes("contextSettings")) {
|
|
277
|
+
const to = candidate.contextSettings;
|
|
278
|
+
const words = to !== undefined ? Object.keys(to) : [];
|
|
279
|
+
deliverEngineNotice(this.deps.onNotice, {
|
|
280
|
+
code: "config.context_settings_swapped",
|
|
281
|
+
message: `deployment context-window settings swapped: ${words.length} model word(s) declared` +
|
|
282
|
+
`${priorContextSettings !== undefined ? ` (was ${Object.keys(priorContextSettings).length})` : ""}` +
|
|
283
|
+
"; unlike every other swappable seat this one is read LIVE — running legs measure their next boundary against the new windows, while their routing stays on the generation they prepared under",
|
|
284
|
+
detail: { words: words.slice(0, 8), declared: words.length, previousDeclared: priorContextSettings !== undefined ? Object.keys(priorContextSettings).length : 0, occurrenceId: uuidv7() },
|
|
285
|
+
});
|
|
286
|
+
}
|
|
256
287
|
for (const seat of faceSeats) {
|
|
257
288
|
const to = candidate[seat] ?? null;
|
|
258
289
|
const from = priorFaces[seat] ?? null;
|
|
@@ -476,7 +507,7 @@ export class Runner {
|
|
|
476
507
|
undrainedUserAtEnd, userInputLostAtEnd, final, threw, abortedLive, userInterruptedLive, runner: this.depsSeat, sessions: this.sessions,
|
|
477
508
|
next: ({ threw, comp, answerSettled, owedUserInput }) => runSettleAndTeardown({
|
|
478
509
|
spec, queue, prepared, resume, internals, rs, stats, ident, parentToolCallId, subagentName, loopLatch, timeout, ownCommittedTailRef,
|
|
479
|
-
emitDelegationLifecycle, taskIdRef, manualCompactRef, drainManualCompact, final, threw, abortedLive, userInterruptedLive, answerSettled, strandedHumanAnswers, reasoningResolution, comp, owedUserInput,
|
|
510
|
+
emitDelegationLifecycle, taskIdRef, manualCompactRef, drainManualCompact, final, threw, abortedLive, userInterruptedLive, answerSettled, strandedHumanAnswers, reasoningResolution, comp, compactionBreaker, owedUserInput,
|
|
480
511
|
setResult, onSuggestions, onSuspend, runner: this.depsSeat, sessions: this.sessions,
|
|
481
512
|
}),
|
|
482
513
|
}),
|