@sema-agent/core 7.28.1 → 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 +473 -1
- 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/brain/anthropic.js +4 -2
- package/dist/brain/open-responses.js +4 -3
- package/dist/brain/openai.js +2 -1
- package/dist/brain/stream-engine.js +6 -0
- package/dist/brain/stream-shared.d.ts +8 -0
- package/dist/brain/stream-shared.js +8 -0
- 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 +18 -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 +4 -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/message-utils.d.ts +13 -0
- package/dist/core/message-utils.js +6 -0
- 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 +3 -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 +61 -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 +2 -2
- 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/response-model-seat.d.ts +16 -0
- package/dist/core/runner/response-model-seat.js +27 -0
- 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 +9 -2
- 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 +33 -2
- package/dist/core/runner-deps.d.ts +44 -13
- package/dist/core/side-query.d.ts +6 -5
- package/dist/core/side-query.js +3 -1
- package/dist/core/swappable-deps.d.ts +20 -4
- package/dist/core/swappable-deps.js +6 -1
- package/dist/core/task-event.d.ts +13 -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 +27 -3
- 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.29.0.json +185 -0
- package/wire-changes/core@7.30.0.json +1821 -0
|
@@ -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;
|
|
@@ -443,7 +474,7 @@ export class Runner {
|
|
|
443
474
|
spec, queue, internals, ident, parentToolCallId, subagentName,
|
|
444
475
|
pushContent, emitCommitted, startedToolCallIds, toolStartAt, toolProgress, writeFamilyOf,
|
|
445
476
|
toolLabels, postToolBatchHook, batchArgs, internalsNotifier,
|
|
446
|
-
runnerHooks: { onError: (e, info) => this.deps.onError?.(e, info) },
|
|
477
|
+
runnerHooks: { onError: (e, info) => this.deps.onError?.(e, info), onNotice: this.deps.onNotice },
|
|
447
478
|
},
|
|
448
479
|
});
|
|
449
480
|
const { compactionBrain, withinTaskCompaction, compactionBreaker, windowSafetyOptions } = runCompactionMachinery({ spec, prepared, rs, stats, noteUnevaluablePriceTable, runner: this.depsSeat });
|
|
@@ -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
|
}),
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { Model } from "../internal/llm.js";
|
|
8
8
|
import type { AgentDefinition } from "./agent-definition.js";
|
|
9
|
+
import type { ContextSettings } from "./context-settings.js";
|
|
9
10
|
import type { BackgroundChildEvent, DelegationLifecycleEvent } from "./delegation-frames.js";
|
|
10
11
|
import type { EngineNotice } from "./engine-notice.js";
|
|
11
12
|
import type { HandsBandOptions } from "./hands-band.js";
|
|
@@ -113,6 +114,22 @@ export interface RunnerDeps {
|
|
|
113
114
|
brain: Brain;
|
|
114
115
|
/** Catalog used to resolve string ModelRefs to Model objects. */
|
|
115
116
|
models?: Record<string, Model>;
|
|
117
|
+
/**
|
|
118
|
+
* The deployment's per-model CONTEXT-WINDOW overlay, keyed by CATALOG WORD ({@link ContextSettings}):
|
|
119
|
+
* `contextTokens` / `autoCompactTokens` / `enabled` over what the model card declares.
|
|
120
|
+
*
|
|
121
|
+
* It is the ONE hot-swappable seat an IN-FLIGHT leg re-reads. Every other seat follows the snapshot law
|
|
122
|
+
* (a running task keeps the deps object it prepared under) because those seats are the routing card —
|
|
123
|
+
* endpoint, credentials, price, fence — and a request in flight must reach what it was priced for. The
|
|
124
|
+
* usable window is not the card: it is a setting, and an operator who lowers it is asking the legs
|
|
125
|
+
* running RIGHT NOW to compact sooner, which is exactly what they were unable to do while the number
|
|
126
|
+
* lived on the model object. Read at every turn boundary, every recovery pass, the end-of-task summary
|
|
127
|
+
* and every request build; clamped to the physical window by the one resolver.
|
|
128
|
+
*
|
|
129
|
+
* A leg that was handed a `Model` OBJECT (or resolved one through a `select` criteria) has no catalog
|
|
130
|
+
* word and therefore no overlay — the pin is the caller saying "this exact model, as declared".
|
|
131
|
+
*/
|
|
132
|
+
contextSettings?: ContextSettings;
|
|
116
133
|
/**
|
|
117
134
|
* design/338 (mid-turn MCP revocation) — the HOST's revocation ledger, probed synchronously at
|
|
118
135
|
* every MCP dispatch (tool call + the three resource tools) BEFORE the transport. The engine
|
|
@@ -512,9 +529,11 @@ export interface RunnerDeps {
|
|
|
512
529
|
* {@link InMemoryFileHistoryStore}; a deployment supplies a durable backend behind the same seam
|
|
513
530
|
* (backends MUST reuse the exported env-half helpers — see the contract JSDoc). Works against ANY
|
|
514
531
|
* ExecutionEnv (local or remote): bytes are read/written through the env's FileSystem face and
|
|
515
|
-
* stored host-side, so an env rebuild does not lose history.
|
|
532
|
+
* stored host-side, so an env rebuild does not lose history. `"disabled"` = the deployment DECIDED
|
|
533
|
+
* not to capture: the omitted-key semantics minus the once-per-Runner `onError` advisory an omitted
|
|
534
|
+
* key earns on a filesystem-capable run (`classification: "file-history-no-store"`).
|
|
516
535
|
*/
|
|
517
|
-
fileHistoryStore?: import("./file-history-store.js").FileHistoryStore;
|
|
536
|
+
fileHistoryStore?: import("./file-history-store.js").FileHistoryStore | "disabled";
|
|
518
537
|
/**
|
|
519
538
|
* design/381 DV-14 (终审落锤) — what an Edit/Write/NotebookEdit does when its FIRST-TOUCH history
|
|
520
539
|
* record cannot be persisted (`FileHistoryStore.trackEdit` answered `{ok:false}` = NO durable
|
|
@@ -877,12 +896,12 @@ export interface RunnerDeps {
|
|
|
877
896
|
maxConcurrent?: number;
|
|
878
897
|
maxCumulativePerSession?: number;
|
|
879
898
|
};
|
|
880
|
-
/**
|
|
881
|
-
*
|
|
882
|
-
*
|
|
883
|
-
* absent means the default table
|
|
884
|
-
* `SendMessageToolOptions.
|
|
885
|
-
|
|
899
|
+
/** The peer lane's ONE knob table (`PeerLaneConfig`): the always-on admission gate (rate/dedup/hop-chain/
|
|
900
|
+
* queue bounds), the wake and per-pass delivery budgets, and the `ListAgents` freshness window. Per-field
|
|
901
|
+
* range-validated with out-of-range values falling back to that field's default, announced once; there
|
|
902
|
+
* is NO off switch — absent means the default table. Threaded into the auto-mounted SendMessage as
|
|
903
|
+
* `SendMessageToolOptions.lane` and into the session-box drain; read per call / per pass. */
|
|
904
|
+
peerLane?: Partial<import("../agents/peer-admission.js").PeerLaneConfig>;
|
|
886
905
|
/**
|
|
887
906
|
* design/385 §2.1 / §5.1 — the peer-session DIRECTORY: the discovery truth of the cross-session
|
|
888
907
|
* lane (other sessions of this engine for the same user). A HOST implements the contract (cli: the
|
|
@@ -917,6 +936,16 @@ export interface RunnerDeps {
|
|
|
917
936
|
* {@link peerDirectory}.
|
|
918
937
|
*/
|
|
919
938
|
crossSessionDialogExpiry?: import("../agents/peer-notices.js").CrossSessionDialogExpiry | (() => import("../agents/peer-notices.js").CrossSessionDialogExpiry | undefined);
|
|
939
|
+
/**
|
|
940
|
+
* The deployment's CAPABILITY FLOOR for durable engine frames: `true` declares that EVERY process
|
|
941
|
+
* that drains this deployment's session boxes reads `engine_frame` records (this engine's codec or
|
|
942
|
+
* newer). With it, an engine-minted task-notification frame addressed to an idle session parks in
|
|
943
|
+
* the session's durable box (`MailboxPeerMeta.kind: "engine_frame"`) and survives a process restart;
|
|
944
|
+
* without it (absent / `false`) such a frame parks in process exactly as before. A deployment flips
|
|
945
|
+
* it only after every drainer is upgraded — a pre-codec drainer reads the record as a peer's words.
|
|
946
|
+
* Inert without a cross-process-safe {@link mailboxStore}.
|
|
947
|
+
*/
|
|
948
|
+
sessionBoxEngineFrames?: boolean;
|
|
920
949
|
/**
|
|
921
950
|
* design/164 件五 — DEPLOYMENT-level usage governance: allowances that span TASKS, evaluated per
|
|
922
951
|
* principal (or once for the whole deployment when a task declares none). A different axis from
|
|
@@ -1266,11 +1295,13 @@ export interface RunnerDeps {
|
|
|
1266
1295
|
phase: "compaction" | "prompt-cache" | "prompt-constitution" | "degraded" | "config" | "memory" | "mcp" | "a2a" | "interrupt-reconcile" | "suggestions" | "rewind" | "hook";
|
|
1267
1296
|
sessionId: string;
|
|
1268
1297
|
/**
|
|
1269
|
-
* Machine-readable sub-classification when the
|
|
1270
|
-
* cache-break detector's root cause (`"model-switch" | "tool-schema" |
|
|
1271
|
-
* "system-prefix" | "server-or-ttl"`)
|
|
1272
|
-
*
|
|
1273
|
-
*
|
|
1298
|
+
* Machine-readable sub-classification when the site has one (a kebab-case word naming the arm) —
|
|
1299
|
+
* e.g. the design/31 cache-break detector's root cause (`"model-switch" | "tool-schema" |
|
|
1300
|
+
* "tool-set" | "system-prefix" | "server-or-ttl"`), or the file-history liveness arms
|
|
1301
|
+
* (`"file-history-no-store"` / `"file-history-no-env"`). Lets the host pick its own log level:
|
|
1302
|
+
* `"server-or-ttl"` is usually benign in agentic tasks (slow tools ⇒ 5min+ request gaps expire
|
|
1303
|
+
* provider caches — service[64] flag②) and warrants info/warn, while the prefix-bug causes
|
|
1304
|
+
* warrant attention.
|
|
1274
1305
|
*/
|
|
1275
1306
|
classification?: string;
|
|
1276
1307
|
}) => void;
|
|
@@ -83,15 +83,16 @@ export interface SideQueryResult {
|
|
|
83
83
|
args: unknown;
|
|
84
84
|
}>;
|
|
85
85
|
/** The RESOLVED pool model id the query was ROUTED to (the caller's ref resolved). See
|
|
86
|
-
* `servedModel` for the
|
|
86
|
+
* `servedModel` for the engine-selected id the reply came back stamped with. */
|
|
87
87
|
model: string;
|
|
88
|
-
/** The
|
|
89
|
-
*
|
|
90
|
-
*
|
|
88
|
+
/** The ENGINE-SELECTED id the reply came back stamped with (a degrading deployment may fall back
|
|
89
|
+
* mid-query — attribution follows the entry that ran, not the routing intent); equals `model` when
|
|
90
|
+
* nothing degraded. Still THIS catalog's id: what the PROVIDER called it is `responseModel` below. */
|
|
91
91
|
servedModel: string;
|
|
92
92
|
/** Structured degradation marker when a fallback model served (from/to/reason/chain). */
|
|
93
93
|
degraded?: DegradationInfo;
|
|
94
|
-
/**
|
|
94
|
+
/** The PROVIDER's own name for the model that answered, when it differs from `servedModel` above.
|
|
95
|
+
* Absent ⇒ it named the same id or named none — one reading, as on `AssistantMessage.responseModel`. */
|
|
95
96
|
responseModel?: string;
|
|
96
97
|
/** Usage with `input` NORMALIZED to the uncached prompt quantity (the Anthropic-protocol
|
|
97
98
|
* `input_tokens` meaning) for EVERY provider family — the same gate the run loop's accounting
|
package/dist/core/side-query.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolveTaskModel } from "./roles.js";
|
|
2
2
|
import { readDegradation } from "../brain/degrading.js";
|
|
3
3
|
import { cacheFamilyOf, uncachedInputTokensOf } from "./runner/usage-accounting.js";
|
|
4
|
+
import { providerReportedModel } from "./message-utils.js";
|
|
4
5
|
function normalizeSideQueryUsage(model, u) {
|
|
5
6
|
const input = uncachedInputTokensOf(cacheFamilyOf(model), u);
|
|
6
7
|
return input === u.input ? u : { ...u, input };
|
|
@@ -63,13 +64,14 @@ export async function runSideQuery(spec, deps) {
|
|
|
63
64
|
.map((c) => ({ id: c.id, name: c.name, args: c.arguments }));
|
|
64
65
|
const degraded = readDegradation(msg);
|
|
65
66
|
const servedModel = typeof msg.model === "string" && msg.model.length > 0 ? msg.model : resolved.model.id;
|
|
67
|
+
const reportedModel = providerReportedModel(msg);
|
|
66
68
|
return {
|
|
67
69
|
text,
|
|
68
70
|
toolCalls,
|
|
69
71
|
model: resolved.model.id,
|
|
70
72
|
servedModel,
|
|
71
73
|
...(degraded !== undefined ? { degraded } : {}),
|
|
72
|
-
...(
|
|
74
|
+
...(reportedModel !== undefined ? { responseModel: reportedModel } : {}),
|
|
73
75
|
usage: normalizeSideQueryUsage(resolved.model, msg.usage),
|
|
74
76
|
...(msg.usageMissing === true ? { usageMissing: true } : {}),
|
|
75
77
|
stopReason: msg.stopReason,
|
|
@@ -12,11 +12,23 @@
|
|
|
12
12
|
* the door refuses a key outside the set at run time (never a silent ignore — a hot-config driver
|
|
13
13
|
* handing `{ brain }` must learn that the brain is not a swappable seat, not watch nothing happen).
|
|
14
14
|
*
|
|
15
|
-
* WHAT A SWAP MEANS — the natural snapshot, one sentence for every seat: a running task reads the
|
|
16
|
-
* object it was handed at its prepare and holds that reference; a swap replaces the Runner's object, so
|
|
15
|
+
* WHAT A SWAP MEANS — the natural snapshot, one sentence for every ROUTING seat: a running task reads the
|
|
16
|
+
* deps object it was handed at its prepare and holds that reference; a swap replaces the Runner's object, so
|
|
17
17
|
* every LATER prepare reads the new seat and every in-flight leg keeps the value it prepared under.
|
|
18
18
|
* Nothing is re-routed, re-priced or re-fenced mid-run; the divergence window is exactly the in-flight
|
|
19
|
-
* legs' lifetime, by design (the `swapModels` precedent
|
|
19
|
+
* legs' lifetime, by design (the `swapModels` precedent).
|
|
20
|
+
*
|
|
21
|
+
* …WITH ONE SEAT OUTSIDE IT, and the boundary is the point rather than the exception: `contextSettings` is
|
|
22
|
+
* read LIVE by in-flight legs. The snapshot law protects the routing CARD — a request already in flight must
|
|
23
|
+
* reach the endpoint it was priced, credentialed and fenced for, and re-reading any of that mid-run buys
|
|
24
|
+
* nothing and breaks the request. A leg's usable WINDOW is not on that card: it is a setting about how much
|
|
25
|
+
* conversation may accumulate before the leg summarizes, the reference implementation keeps it off the model
|
|
26
|
+
* object for exactly this reason and re-reads it on every request (clamped to the model's physical window),
|
|
27
|
+
* and an operator who lowers it is asking the legs running RIGHT NOW to compact sooner — which is the whole
|
|
28
|
+
* request. So the window declarations live on their own seat (`context-settings.ts`), keyed by catalog word,
|
|
29
|
+
* and the legs read them at every boundary, every recovery pass, the end-of-task summary and every request
|
|
30
|
+
* build. Routing stays snapshotted; geometry follows the operator. The two are not the same question, and
|
|
31
|
+
* one law over both could only be wrong about one of them.
|
|
20
32
|
*
|
|
21
33
|
* KEY PRESENCE IS THE INSTRUCTION: a key present on the candidate is REPLACED (an explicit `undefined`
|
|
22
34
|
* CLEARS an optional seat back to its engine default — `readFace: undefined` ⇒ the deployment declares
|
|
@@ -44,8 +56,11 @@ import type { RunnerDeps } from "./runner-deps.js";
|
|
|
44
56
|
* deployment seat that resolution reads.
|
|
45
57
|
* - `writeFace` — the deployment's write-face declaration ({@link RunnerDeps.writeFace}); the read seat's
|
|
46
58
|
* twin (same value gate, same in-flight snapshot rule, its own notice) and independent of it.
|
|
59
|
+
* - `contextSettings` — the per-model context-window overlay ({@link RunnerDeps.contextSettings}); screened
|
|
60
|
+
* by the same value gate construction applies (`assertContextSettingsValue`). THE ONE SEAT
|
|
61
|
+
* IN-FLIGHT LEGS RE-READ — see the header: it carries geometry, not route.
|
|
47
62
|
*/
|
|
48
|
-
export declare const SWAPPABLE_DEP_SEATS: readonly ["models", "tiers", "readFace", "writeFace"];
|
|
63
|
+
export declare const SWAPPABLE_DEP_SEATS: readonly ["models", "tiers", "readFace", "writeFace", "contextSettings"];
|
|
49
64
|
export type SwappableDepSeat = (typeof SWAPPABLE_DEP_SEATS)[number];
|
|
50
65
|
/** The candidate a swap takes: the swappable seats of {@link RunnerDeps}, each optional (presence = instruction). */
|
|
51
66
|
export type SwappableDeps = Pick<RunnerDeps, SwappableDepSeat>;
|
|
@@ -61,6 +76,7 @@ export declare const SWAP_SEAT_NOTICE: {
|
|
|
61
76
|
readonly tiers: "config.models_swapped";
|
|
62
77
|
readonly readFace: "config.read_face_swapped";
|
|
63
78
|
readonly writeFace: "config.write_face_swapped";
|
|
79
|
+
readonly contextSettings: "config.context_settings_swapped";
|
|
64
80
|
};
|
|
65
81
|
/** The fence over the notice table: `never` while every seat has a row. */
|
|
66
82
|
export type SwapNoticeTableCoversEverySeat = AssertAllKeysHandled<Exclude<SwappableDepSeat, keyof typeof SWAP_SEAT_NOTICE>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assertContainmentFaceValue } from "../tools/fs/containment-face.js";
|
|
2
|
-
|
|
2
|
+
import { assertContextSettingsValue } from "./context-settings.js";
|
|
3
|
+
export const SWAPPABLE_DEP_SEATS = ["models", "tiers", "readFace", "writeFace", "contextSettings"];
|
|
3
4
|
const SWAPPABLE_DEP_SEAT_SET = new Set(SWAPPABLE_DEP_SEATS);
|
|
4
5
|
export function isSwappableDepSeat(k) {
|
|
5
6
|
return SWAPPABLE_DEP_SEAT_SET.has(k);
|
|
@@ -9,6 +10,7 @@ export const SWAP_SEAT_NOTICE = {
|
|
|
9
10
|
tiers: "config.models_swapped",
|
|
10
11
|
readFace: "config.read_face_swapped",
|
|
11
12
|
writeFace: "config.write_face_swapped",
|
|
13
|
+
contextSettings: "config.context_settings_swapped",
|
|
12
14
|
};
|
|
13
15
|
export function screenSwappableDeps(next) {
|
|
14
16
|
if (next === null || typeof next !== "object" || Array.isArray(next)) {
|
|
@@ -49,6 +51,9 @@ export function screenSwappableDeps(next) {
|
|
|
49
51
|
case "writeFace":
|
|
50
52
|
candidate.writeFace = assertContainmentFaceValue(v, "write", "deps");
|
|
51
53
|
break;
|
|
54
|
+
case "contextSettings":
|
|
55
|
+
candidate.contextSettings = assertContextSettingsValue(v, "swapDeps");
|
|
56
|
+
break;
|
|
52
57
|
default: {
|
|
53
58
|
const _exhaustive = seat;
|
|
54
59
|
throw new Error(`swapDeps: unhandled seat ${String(_exhaustive)}`);
|
|
@@ -581,6 +581,14 @@ export type TaskEvent = ({
|
|
|
581
581
|
* no assistant message. Typed `string` (not the internal `StopReason`) to keep the engine's union
|
|
582
582
|
* private, but the value set is exactly those five tokens. */
|
|
583
583
|
stopReason?: string;
|
|
584
|
+
/** The PROVIDER'S OWN name for the model that answered this turn, when it DIFFERS from the id the
|
|
585
|
+
* request was sent with — a SECOND fact beside `TaskResult.model` / the trace's `brain.call.model`,
|
|
586
|
+
* which stay the ENGINE-SELECTED pool id a resume re-seeds and a catalog resolves, never an
|
|
587
|
+
* overwrite of either. PRESENCE: the turn's LAST assistant message carried one
|
|
588
|
+
* (`AssistantMessage.responseModel`). ABSENT ⇒ the provider named the requested id or named nothing —
|
|
589
|
+
* ONE reading, not two, as on the reference mismatch latch, also written only for a disagreeing pair.
|
|
590
|
+
* A mismatch is additionally announced once per leg per pair as `route.response_model_mismatch`. */
|
|
591
|
+
responseModel?: string;
|
|
584
592
|
} & TaskEventIdentity) | ({
|
|
585
593
|
/** design/99 MF-18: a compaction boundary (or, since design/119 #1, mid-turn when the prompt-too-long recovery force-compacts between a failed request and its retry). `trigger` = what caused it: `"auto"` (the context-threshold
|
|
586
594
|
* auto-compaction), `"manual"` (the `TaskStream.compact` / `/compact` path), or `"forced"` (RB-398-b
|
|
@@ -621,6 +629,11 @@ export type TaskEvent = ({
|
|
|
621
629
|
preserved_segment?: {
|
|
622
630
|
firstKeptEntryId: string;
|
|
623
631
|
};
|
|
632
|
+
/** Cross-session message frames that sat in the SUMMARIZED prefix of this pass — delivered
|
|
633
|
+
* earlier and visible to the model for the turns since. A record still in the session's box is
|
|
634
|
+
* handed over again by the engine (once; a second loss is disclosed `resupply_exhausted`), so
|
|
635
|
+
* this counts what the summary swallowed, not what is gone. Present iff at least one. */
|
|
636
|
+
summarizedCrossSessionMessages?: number;
|
|
624
637
|
/** CC post-compact file-restore parity (2026-07-03): the working files the engine
|
|
625
638
|
* re-read into the summary (attachWorkingFiles), attachment order. A shell renders CC's
|
|
626
639
|
* `Read {path} (…)` cards under the compaction divider from this. Absent when the feature is
|