@sema-agent/core 7.12.0 → 7.13.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 +44 -0
- package/dist/core/ask-origin.d.ts +55 -0
- package/dist/core/ask-origin.js +21 -0
- package/dist/core/engine-notice.d.ts +18 -0
- package/dist/core/gate-lanes.d.ts +0 -40
- package/dist/core/gate-lanes.js +3 -17
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +2 -0
- package/dist/core/hooks.d.ts +1 -1
- package/dist/core/hooks.js +1 -1
- package/dist/core/runner/assemble-result.d.ts +45 -1
- package/dist/core/runner/assemble-result.js +4 -1
- package/dist/core/runner/compaction-seams.d.ts +42 -0
- package/dist/core/runner/compaction-seams.js +80 -0
- package/dist/core/runner/contracts.d.ts +44 -6
- package/dist/core/runner/denial-limit-arms.js +3 -2
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -1
- package/dist/core/runner/permission-rule-lanes.js +2 -1
- package/dist/core/runner/prepare-policy-chain.js +3 -2
- package/dist/core/runner/prepare-protocol-tools.js +5 -0
- package/dist/core/runner/prepare-safety-scan.js +11 -16
- package/dist/core/runner/prepare-task.d.ts +9 -1
- package/dist/core/runner/prepare-task.js +6 -1
- package/dist/core/runner/resume-claim.d.ts +2 -2
- package/dist/core/runner/resume-preflight.d.ts +2 -2
- package/dist/core/runner/run-attachment-seats.d.ts +2 -2
- package/dist/core/runner/run-git-lane.d.ts +1 -1
- package/dist/core/runner/run-harness-handlers.js +2 -0
- package/dist/core/runner/run-identity-wiring.d.ts +7 -0
- package/dist/core/runner/run-identity-wiring.js +3 -1
- package/dist/core/runner/run-leg.d.ts +7 -5
- package/dist/core/runner/run-leg.js +256 -5
- package/dist/core/runner/run-notification-lane.d.ts +4 -3
- package/dist/core/runner/run-recovery-lanes.d.ts +4 -17
- package/dist/core/runner/run-recovery-lanes.js +5 -4
- package/dist/core/runner/run-settle-and-teardown.d.ts +14 -10
- package/dist/core/runner/run-settle-and-teardown.js +112 -4
- package/dist/core/runner/run-stop-and-final-verify.d.ts +2 -2
- package/dist/core/runner/run-terminal-adoption.d.ts +16 -16
- package/dist/core/runner/run-terminal-adoption.js +87 -7
- package/dist/core/runner/run-turn-boundary.js +5 -4
- package/dist/core/runner/runtask.d.ts +10 -90
- package/dist/core/runner/runtask.js +77 -596
- package/dist/core/runner/stream-lifecycle-verbs.js +10 -1
- package/dist/core/task-stream.d.ts +10 -1
- package/dist/core/tool-face.d.ts +8 -0
- package/dist/core/tool-face.js +1 -0
- package/dist/core/tool-policy.d.ts +5 -3
- package/dist/core/tool-registry.d.ts +11 -3
- package/dist/core/tool-registry.js +7 -1
- package/dist/core/tool-roster.d.ts +26 -0
- package/dist/core/tool-roster.js +38 -7
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/server/http.js +2 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +11 -1
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* stop, the platform lane's external cause — which alone overrides a real throw), the usage ledger's FINAL charge with its
|
|
5
5
|
* slow-charge disclosure, the live-abort orphan reconcile and its synthetic `tool_end` frames, the held session-write
|
|
6
6
|
* drain, the user-interruption marker, the durable park's carried caller input and the held agent_end account's settle,
|
|
7
|
-
* the dropped post-compact announce disclosure, and the end-of-task compaction pass (`finish`
|
|
7
|
+
* the dropped post-compact announce disclosure, and the end-of-task compaction pass (`finish` — since design/393 S7 the lane's
|
|
8
|
+
* own module-private function, verbatim from the Runner's private method: the pass has one caller, and a sibling file would be a
|
|
9
|
+
* lane-to-lane reach, the S6 legs' reading).
|
|
8
10
|
*
|
|
9
11
|
* Async (six first-level awaits, the same awaits at the same positions). It ends by entering the settle lane (`next`) in
|
|
10
12
|
* its LAST continuation — the settle's first read sits on the tick `finish` resolved on, as it did in the one-function
|
|
@@ -14,13 +16,14 @@
|
|
|
14
16
|
*/
|
|
15
17
|
import type { AssistantMessage } from "../../internal/llm.js";
|
|
16
18
|
import type { Model } from "../../internal/llm.js";
|
|
17
|
-
import type
|
|
19
|
+
import { type MaybeCompactOptions } from "../auto-compaction.js";
|
|
20
|
+
import type { SessionStore } from "../session.js";
|
|
18
21
|
import type { PushQueue } from "../push-queue.js";
|
|
19
22
|
import { type Brain, type TaskEvent, type TaskSpec } from "../types.js";
|
|
20
23
|
import { type Stats } from "./assemble-result.js";
|
|
21
24
|
import type { EndOfTaskCompaction, Prepared, RunnerDepsSeat, RunState } from "./contracts.js";
|
|
22
25
|
export interface RunTerminalAdoptionInput<R> {
|
|
23
|
-
/** borrowed-readonly — the task spec: the task id the account's notices name; `finish`'s first argument. */
|
|
26
|
+
/** borrowed-readonly — the task spec: the task id the account's notices name; `finish`'s first argument (the end-of-task pass below). */
|
|
24
27
|
spec: TaskSpec;
|
|
25
28
|
/** borrowed-mutable — the run's event queue: the reconcile's synthetic `tool_end` frames and the end-of-task compaction's failure frame. */
|
|
26
29
|
queue: PushQueue<TaskEvent>;
|
|
@@ -62,6 +65,11 @@ export interface RunTerminalAdoptionInput<R> {
|
|
|
62
65
|
followUp: number;
|
|
63
66
|
} | undefined;
|
|
64
67
|
};
|
|
68
|
+
/** borrowed-readonly — #677: did the run end with a person's steer / follow-up still pending (the identity lane's read face)? Folded
|
|
69
|
+
* into the answer-settled verdict this lane evaluates once. */
|
|
70
|
+
userInputLostAtEnd: {
|
|
71
|
+
readonly current: boolean;
|
|
72
|
+
};
|
|
65
73
|
/** borrowed-readonly — the leg lane's final assistant message (its `stopReason` is one of the interruption facts). */
|
|
66
74
|
final: AssistantMessage | undefined;
|
|
67
75
|
/** borrowed-readonly — what the leg threw (undefined on a clean end); this lane may LIFT a typed cause over it and hands the adopted value on. */
|
|
@@ -73,19 +81,8 @@ export interface RunTerminalAdoptionInput<R> {
|
|
|
73
81
|
/** borrowed-readonly — the Runner's deployment deps, read LIVE (`onError`, `checkpointStore`, `onNotice`); the one home of why it is
|
|
74
82
|
* a seat and not a captured object is {@link RunnerDepsSeat}. */
|
|
75
83
|
runner: RunnerDepsSeat;
|
|
76
|
-
/** borrowed-readonly — the
|
|
77
|
-
|
|
78
|
-
skipCompaction?: boolean;
|
|
79
|
-
minTokens?: number;
|
|
80
|
-
brain?: Brain;
|
|
81
|
-
windowSafety?: Pick<MaybeCompactOptions, "fallbackBudget" | "onWindowSafety">;
|
|
82
|
-
onCompactionFailed?: (reason: string) => void;
|
|
83
|
-
telemetry?: {
|
|
84
|
-
tracer: TaskSpec["tracer"];
|
|
85
|
-
taskId: string;
|
|
86
|
-
};
|
|
87
|
-
cancelled?: boolean;
|
|
88
|
-
}) => Promise<EndOfTaskCompaction>;
|
|
84
|
+
/** borrowed-readonly — the session store: the end-of-task pass touches the leg's session through it (`finish`'s teardown legs). */
|
|
85
|
+
sessions: SessionStore;
|
|
89
86
|
/** borrowed-readonly — the settle lane, entered in this lane's last continuation with the adopted cause and the compaction outcome. */
|
|
90
87
|
next: (adopted: RunTerminalAdoptionResult) => Promise<R>;
|
|
91
88
|
}
|
|
@@ -95,5 +92,8 @@ export interface RunTerminalAdoptionResult {
|
|
|
95
92
|
threw: unknown;
|
|
96
93
|
/** The end-of-task compaction pass's outcome. */
|
|
97
94
|
comp: EndOfTaskCompaction;
|
|
95
|
+
/** #677 — this lane's ONE evaluation of {@link answerSettled}: a clean `"stop"` final with no queued continuation lost. The
|
|
96
|
+
* settle lane hands it to the arbitration (`ResultFlags.answerSettled`), the teardown attribution and the notice. */
|
|
97
|
+
answerSettled: boolean;
|
|
98
98
|
}
|
|
99
99
|
export declare function runTerminalAdoption<R>(input: RunTerminalAdoptionInput<R>): Promise<R>;
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import { DEFAULT_COMPACTION_INSTRUCTIONS, maybeCompact } from "../auto-compaction.js";
|
|
2
|
+
import { DEFAULT_COMPACTION_SETTINGS } from "../../internal/harness.js";
|
|
1
3
|
import { eventDefaultOn } from "../../prompt-assembly/event-registry.js";
|
|
2
4
|
import { appendInterruptionMarker, reconcileInterruptedSession } from "../session-reconcile.js";
|
|
3
5
|
import { emitTrace } from "../trace.js";
|
|
4
6
|
import { deliverEngineNotice, undrainedUserInputNotices } from "../types.js";
|
|
5
|
-
import { errorCodeOf } from "./assemble-result.js";
|
|
6
|
-
import { awaitChargeWithSlowDisclosure } from "./clock-and-limits.js";
|
|
7
|
+
import { answerSettled, errorCodeOf } from "./assemble-result.js";
|
|
8
|
+
import { awaitChargeWithSlowDisclosure, discloseUnevaluableWindow } from "./clock-and-limits.js";
|
|
9
|
+
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption } from "./compaction-call-options.js";
|
|
10
|
+
import { compactionHookOptions, recordCompactionReuse, seamCCompactionOptions } from "./compaction-seams.js";
|
|
11
|
+
import { gitRestateOption } from "./git-leg-delivery.js";
|
|
7
12
|
import { MAX_CONSECUTIVE_COMPACTION_FAILURES } from "./compaction-knobs.js";
|
|
8
13
|
import { reconciledToolEndBody } from "./tool-end-body.js";
|
|
9
14
|
export async function runTerminalAdoption(input) {
|
|
10
|
-
const { spec, queue, prepared, rs, stats, ident, emitCommitted, startedToolCallIds, toolLabels, timeout, compactionBrain, compactionBreaker, windowSafetyOptions, undrainedUserAtEnd, final, abortedLive, userInterruptedLive, runner,
|
|
15
|
+
const { spec, queue, prepared, rs, stats, ident, emitCommitted, startedToolCallIds, toolLabels, timeout, compactionBrain, compactionBreaker, windowSafetyOptions, undrainedUserAtEnd, userInputLostAtEnd, final, abortedLive, userInterruptedLive, runner, sessions, next } = input;
|
|
11
16
|
let { threw } = input;
|
|
17
|
+
const settled = answerSettled(final, userInputLostAtEnd.current || prepared.workCutRef.continuation || prepared.workCutRef.abortedBeforeTurnEnd);
|
|
12
18
|
if (threw === undefined && prepared.brainCallGuardrailRef.timedOut !== undefined) {
|
|
13
19
|
threw = prepared.brainCallGuardrailRef.timedOut;
|
|
14
20
|
}
|
|
@@ -58,7 +64,7 @@ export async function runTerminalAdoption(input) {
|
|
|
58
64
|
});
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
|
-
if (interrupted && userInterruptedLive && reconcileComplete) {
|
|
67
|
+
if (interrupted && userInterruptedLive && reconcileComplete && !settled) {
|
|
62
68
|
try {
|
|
63
69
|
const entryId = await appendInterruptionMarker(prepared.session, { toolUseInFlight: orphansClosed > 0 });
|
|
64
70
|
emitCommitted(entryId, "user");
|
|
@@ -109,12 +115,86 @@ export async function runTerminalAdoption(input) {
|
|
|
109
115
|
}
|
|
110
116
|
const comp = await finish(spec, prepared, {
|
|
111
117
|
telemetry: { tracer: rs.telemetry.tracer, taskId: rs.telemetry.taskId },
|
|
112
|
-
skipCompaction: durablyPaused || compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES,
|
|
118
|
+
skipCompaction: durablyPaused || (abortedLive && settled) || compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES,
|
|
113
119
|
minTokens: rs.counters.compactionFloor,
|
|
114
120
|
brain: compactionBrain,
|
|
115
121
|
windowSafety: windowSafetyOptions(prepared.model),
|
|
116
122
|
onCompactionFailed: (reason) => queue.push({ type: "compaction_outcome", outcome: "failed", trigger: "auto", reason, ...ident() }),
|
|
117
123
|
cancelled: abortedLive,
|
|
118
|
-
});
|
|
119
|
-
return await next({ threw, comp });
|
|
124
|
+
}, runner, sessions);
|
|
125
|
+
return await next({ threw, comp, answerSettled: settled });
|
|
126
|
+
}
|
|
127
|
+
async function finish(spec, prepared, opts, runner, sessions) {
|
|
128
|
+
let comp;
|
|
129
|
+
if (!opts?.skipCompaction) {
|
|
130
|
+
try {
|
|
131
|
+
const finishComp = await maybeCompact({
|
|
132
|
+
session: prepared.session,
|
|
133
|
+
epochDeclaredSections: prepared.epochDeclaredSections,
|
|
134
|
+
...centerAdoptionOption(prepared),
|
|
135
|
+
model: prepared.model,
|
|
136
|
+
compactionModel: prepared.compModel,
|
|
137
|
+
...forkContextOption(prepared, false),
|
|
138
|
+
brain: opts?.brain ?? runner.deps.brain,
|
|
139
|
+
getApiKeyAndHeaders: spec.getApiKeyAndHeaders,
|
|
140
|
+
thinking: prepared.thinking,
|
|
141
|
+
settings: { ...DEFAULT_COMPACTION_SETTINGS, ...spec.compaction },
|
|
142
|
+
customInstructions: spec.compaction?.instructions ?? DEFAULT_COMPACTION_INSTRUCTIONS,
|
|
143
|
+
minTokens: opts?.minTokens,
|
|
144
|
+
overheadTokens: prepared.promptOverheadTokens,
|
|
145
|
+
...(prepared.activeTools.size > 0 ? { activeTools: [...prepared.activeTools] } : {}),
|
|
146
|
+
onInputTruncated: emitInputTruncated(opts?.telemetry?.tracer ?? spec.tracer ?? runner.deps.tracer, opts?.telemetry?.taskId ?? spec.taskId ?? prepared.sessionId),
|
|
147
|
+
...(opts?.windowSafety ?? {}),
|
|
148
|
+
workingFileAttachments: buildWorkingFileAttachments(spec, prepared),
|
|
149
|
+
...contextInstructionFilesOption(prepared),
|
|
150
|
+
...(prepared.onCompactionApplied ? { onApplied: prepared.onCompactionApplied } : {}),
|
|
151
|
+
...seamCCompactionOptions(runner, prepared),
|
|
152
|
+
...gitRestateOption(prepared),
|
|
153
|
+
...compactionHookOptions(runner, spec, prepared.sessionId, "auto", prepared.hookIdentity, {
|
|
154
|
+
timeoutMs: prepared.hookTimeoutMs,
|
|
155
|
+
...(opts?.cancelled === true ? { signal: prepared.abortController.signal } : {}),
|
|
156
|
+
}),
|
|
157
|
+
});
|
|
158
|
+
recordCompactionReuse(runner, prepared, finishComp);
|
|
159
|
+
if (finishComp.unevaluableWindow) {
|
|
160
|
+
discloseUnevaluableWindow(finishComp.unevaluableWindow, prepared, opts?.telemetry?.tracer ?? spec.tracer ?? runner.deps.tracer, opts?.telemetry?.taskId ?? spec.taskId ?? prepared.sessionId, runner.deps.onError);
|
|
161
|
+
}
|
|
162
|
+
comp = finishComp;
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
const failMsg = String(err instanceof Error ? err.message : err);
|
|
166
|
+
const failReason = failMsg.length > 512 ? `${failMsg.slice(0, 512)}…` : failMsg;
|
|
167
|
+
emitTrace(opts?.telemetry?.tracer ?? spec.tracer ?? runner.deps.tracer, () => ({
|
|
168
|
+
kind: "compaction.failed",
|
|
169
|
+
version: 1,
|
|
170
|
+
taskId: opts?.telemetry?.taskId ?? spec.taskId ?? prepared.sessionId,
|
|
171
|
+
trigger: "auto",
|
|
172
|
+
reason: failReason,
|
|
173
|
+
ts: Date.now(),
|
|
174
|
+
}));
|
|
175
|
+
opts?.onCompactionFailed?.(failReason);
|
|
176
|
+
runner.deps.onError?.(err, { phase: "compaction", sessionId: prepared.sessionId });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
await sessions.touch(prepared.sessionId);
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
runner.deps.onError?.(err, { phase: "config", sessionId: prepared.sessionId });
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
await prepared.mcp.dispose();
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
runner.deps.onError?.(err, { phase: "mcp", sessionId: prepared.sessionId });
|
|
190
|
+
}
|
|
191
|
+
if (prepared.a2a !== undefined) {
|
|
192
|
+
try {
|
|
193
|
+
await prepared.a2a.dispose();
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
runner.deps.onError?.(err, { phase: "a2a", sessionId: prepared.sessionId });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return comp;
|
|
120
200
|
}
|
|
@@ -14,11 +14,12 @@ import { workflowSizeGuidelineChangeNotice } from "../../orchestration/workflow-
|
|
|
14
14
|
import { awaitChargeWithSlowDisclosure, discloseUnevaluableWindow, ENV_DUE_GOVERNANCE_READ_BUDGET_MS, GOVERNANCE_READ_STALLED, LIMIT_APPROACH_DEFAULT_THRESHOLDS, limitApproachFrames, platformLimitTerminal, raceUntilDeadline } from "./clock-and-limits.js";
|
|
15
15
|
import { gitRestateOption } from "./git-leg-delivery.js";
|
|
16
16
|
import { COMPACTION_FREED_EPSILON, COMPACTION_REGROWTH_FACTOR, MAX_CONSECUTIVE_COMPACTION_FAILURES } from "./compaction-knobs.js";
|
|
17
|
+
import { compactionHookOptions, recordCompactionReuse, seamCCompactionOptions } from "./compaction-seams.js";
|
|
17
18
|
const BATCH_CONTEXT_MIN_KEEP_BYTES = 160;
|
|
18
19
|
const BATCH_TRUNCATION_MARKER = "\n…[truncated]";
|
|
19
20
|
export function createTurnBoundary(input) {
|
|
20
21
|
const { prepared, stats, rs, deps } = input;
|
|
21
|
-
const { spec, queue, manualCompactRef, todoToolMounted, taskToolsMounted, walltimeMonotonicDeadline, timeout, ident, postToolBatchHook, batchArgs, compactionBrain, withinTaskCompaction, compactionBreaker, windowSafetyOptions, rapidRefill, drainManualCompact, runnerHooks } = deps;
|
|
22
|
+
const { spec, queue, manualCompactRef, todoToolMounted, taskToolsMounted, walltimeMonotonicDeadline, timeout, ident, postToolBatchHook, batchArgs, compactionBrain, withinTaskCompaction, compactionBreaker, windowSafetyOptions, rapidRefill, drainManualCompact, runnerHooks, runner } = deps;
|
|
22
23
|
let finalVerifySeenAtLastBoundary = 0;
|
|
23
24
|
const onTurnBoundary = async (event) => {
|
|
24
25
|
let boundarySteered = false;
|
|
@@ -560,10 +561,10 @@ export function createTurnBoundary(input) {
|
|
|
560
561
|
workingFileAttachments: buildWorkingFileAttachments(spec, prepared),
|
|
561
562
|
...contextInstructionFilesOption(prepared),
|
|
562
563
|
...(prepared.onCompactionApplied ? { onApplied: prepared.onCompactionApplied } : {}),
|
|
563
|
-
...
|
|
564
|
+
...seamCCompactionOptions(runner, prepared),
|
|
564
565
|
...gitRestateOption(prepared),
|
|
565
566
|
...windowSafetyOptions(event.model),
|
|
566
|
-
...
|
|
567
|
+
...compactionHookOptions(runner, spec, prepared.sessionId, passTrigger, prepared.hookIdentity, { timeoutMs: prepared.hookTimeoutMs, signal: prepared.abortController.signal }),
|
|
567
568
|
});
|
|
568
569
|
if (comp.blocked) {
|
|
569
570
|
emitTrace(rs.telemetry.tracer, () => ({
|
|
@@ -618,7 +619,7 @@ export function createTurnBoundary(input) {
|
|
|
618
619
|
queue.push({ type: "compaction_outcome", outcome, trigger: passTrigger, ...ident() });
|
|
619
620
|
}
|
|
620
621
|
}
|
|
621
|
-
|
|
622
|
+
recordCompactionReuse(runner, prepared, comp);
|
|
622
623
|
if (comp.compacted) {
|
|
623
624
|
queue.push({
|
|
624
625
|
type: "compacted",
|
|
@@ -132,27 +132,18 @@ export declare class Runner implements RunnerSelfSeat {
|
|
|
132
132
|
* on first iteration — you do NOT need to pull events for the run (and its `finish()`/env teardown) to
|
|
133
133
|
* happen. Iterating just observes events (the buffer is backpressure-free); `.result()` awaits completion. */
|
|
134
134
|
runTaskStream(spec: TaskSpec, resume?: ResumeRun, internals?: RunInternals): TaskStream;
|
|
135
|
-
private runLocked;
|
|
136
|
-
/**
|
|
137
|
-
* design/393 S6 — the run body after `prepared` exists: the seat lanes R1–R3 (design/393 S5) — the identity wiring, the
|
|
138
|
-
* telemetry and budget seats, and the attachment seats, whose continuation carries the rest. Entered by the notification
|
|
139
|
-
* lane in its last continuation, with what it prepared and bound. Not `async`: it hands back the attachment lane's own
|
|
140
|
-
* promise, so the driver adds no frame — and no microtask — of its own between the lanes and `runLocked`'s settlement.
|
|
141
|
-
*/
|
|
142
|
-
private runSeatLanes;
|
|
143
|
-
/**
|
|
144
|
-
* design/393 S6 — the run body after the seat lanes' async rung: the seat lanes R4–R12 (design/393 S5), the two assemblies
|
|
145
|
-
* the driver keeps (the harness handlers, the turn boundary) and the leg lanes. Entered by the attachment-seats lane in
|
|
146
|
-
* its last continuation, with what the notification lane prepared and what the identity / budget lanes handed back.
|
|
147
|
-
* Not `async` for the same reason as `runSeatLanes`: the leg lane's promise IS this method's.
|
|
148
|
-
*/
|
|
149
|
-
private runAssembliesAndLegs;
|
|
150
135
|
/**
|
|
151
|
-
* design/
|
|
152
|
-
*
|
|
153
|
-
*
|
|
136
|
+
* design/393 S7 (#674) — the run body as ONE driver method: `runLocked`'s signature, the lane order, and the two assemblies
|
|
137
|
+
* the driver keeps (the harness handlers, the turn boundary). The lanes' products are threaded under the names they hand
|
|
138
|
+
* back; the two continuations the S6 driver spelled as private methods (`runSeatLanes` / `runAssembliesAndLegs`, joined by
|
|
139
|
+
* a `RunSeatsHandoff` re-spelling of two lanes' Results) are the `next` closures of the two async lanes they follow — the
|
|
140
|
+
* notification lane's (R0) and the attachment seats' (R3) — because a closure sees what the lanes before it bound, so
|
|
141
|
+
* nothing is re-spelled and nothing is re-destructured. Neither this method nor either closure is `async`: each lane's
|
|
142
|
+
* own promise IS this method's, so a prepare that throws reaches the run IIFE's catch / finally (the failure backstop,
|
|
143
|
+
* the session lock's release) on the tick it did, and each successor is entered on the tick its lane's last await
|
|
144
|
+
* resolved on (the S6 TICKS pin holds unchanged: no first host read moved off the tick the one-function body read it on).
|
|
154
145
|
*/
|
|
155
|
-
private
|
|
146
|
+
private runLocked;
|
|
156
147
|
/** Run a task to completion and return a machine-readable result. */
|
|
157
148
|
runTask(spec: TaskSpec, internals?: RunInternals): Promise<TaskResult>;
|
|
158
149
|
/**
|
|
@@ -260,77 +251,6 @@ export declare class Runner implements RunnerSelfSeat {
|
|
|
260
251
|
* twin. Entered in the claim rung's last continuation, so its first statement runs on the tick the win was read.
|
|
261
252
|
*/
|
|
262
253
|
private resumeHandoff;
|
|
263
|
-
/**
|
|
264
|
-
* design/45 resume step: with the harness idle and the branch rewound to the suspension leaf, resolve
|
|
265
|
-
* the gated tool call and close the rest of the suspended batch, all by appending `toolResult`s to the
|
|
266
|
-
* session (the next `harness.prompt(continuation)` replays them as context).
|
|
267
|
-
* - `allow` → execute the pending tool ONCE (re-validating `updatedInput`/captured post-hook args),
|
|
268
|
-
* append its real result. This deliberately bypasses the tool gate (the human already adjudicated)
|
|
269
|
-
* and the PostToolUse hook (documented v1 gap — rare, acceptable).
|
|
270
|
-
* - `deny` → append a model-readable denial result instead.
|
|
271
|
-
* - the remaining batch siblings (#k+1..N) → deferred-reissue results (v1 doesn't blind-run them).
|
|
272
|
-
*/
|
|
273
|
-
private applyResumeDecision;
|
|
274
|
-
/** Resolve the single gated call of a resumed batch (design/45): execute it once on `allow`, or inject
|
|
275
|
-
* a model-readable denial on `deny`. Appends exactly one `toolResult` for `pendingAction.toolCallId`.
|
|
276
|
-
* `emit` streams `tool_start`/`tool_end` for the resolved call so a `resumeStream` observer sees the
|
|
277
|
-
* approved tool actually execute (API#2 observability parity — service [15]/[37]; the gated call never
|
|
278
|
-
* emitted execution events in the original run, it suspended at the gate before running).
|
|
279
|
-
*
|
|
280
|
-
* RB-22 RULING (2026-07-18, deliberate — the $ counterpart of RB-21's walltime question): a HUMAN-
|
|
281
|
-
* APPROVED call executes even when the $ budget is already exhausted (`maxCostMicroUsd` ≤ spent).
|
|
282
|
-
* The tool execution itself consumes no model spend — the budget's coordinate is LLM cost, and the
|
|
283
|
-
* very next turn boundary's budget gate stops the run — so the overrun is ≈0 while refusing would
|
|
284
|
-
* WASTE the human approval (the review effort is already sunk). This deliberately differs from the
|
|
285
|
-
* walltime ruling (RB-21: NOT exempt) on principle: wall-clock exhaustion endangers the write-out
|
|
286
|
-
* window (time cannot be clawed back), $ exhaustion after an approved no-spend action endangers
|
|
287
|
-
* nothing. Pinned in resume tests; do not "fix" this into a pre-execution budget check. */
|
|
288
|
-
private resolvePendingCall;
|
|
289
|
-
/**
|
|
290
|
-
* design/84 Seam C — the cost-optimization compaction options threaded into BOTH `maybeCompact` call
|
|
291
|
-
* sites (within-task turn boundary + `finish()`). All three fields come from `RunnerDeps` (a trusted
|
|
292
|
-
* FUNCTION seam — never `TaskSpec`, which is serializable/durable-resumable/untrusted-caller). The
|
|
293
|
-
* Runner OWNS the consecutive-reuse counter (`prepared.compactionReuseRef`) so the
|
|
294
|
-
* `maxConsecutiveProviderReuse` drift guard spans the whole task across both sites: it FEEDS the current
|
|
295
|
-
* count in as `consecutiveProviderReuse`, and {@link recordCompactionReuse} updates it from the result.
|
|
296
|
-
* Returns `undefined` when no provider is wired (so the call site spreads nothing → byte-identical to
|
|
297
|
-
* the pre-design/84 behavior).
|
|
298
|
-
*/
|
|
299
|
-
private seamCCompactionOptions;
|
|
300
|
-
/** design/134 §3.2 — resolve the pre/postCompact lifecycle callbacks (whole-slot `spec.hooks ??
|
|
301
|
-
* deps.hooks`, same resolution as the stop hook) and wrap each in a SWALLOW+TRACE shell before
|
|
302
|
-
* threading them into maybeCompact. The wrapper owns the observability half of the R3 MED contract
|
|
303
|
-
* (maybeCompact swallows defensively too, but has no sink): a throwing callback is reported via
|
|
304
|
-
* `onError(phase:"hook")` and treated as absent; a `block` returned under a "forced" trigger is
|
|
305
|
-
* reported as ignored (maybeCompact enforces the ignore — blocking a compaction the provider/trim
|
|
306
|
-
* layer already demanded would kill the run). */
|
|
307
|
-
private compactionHookOptions;
|
|
308
|
-
/** design/84 Seam C — fold a finished compaction's `reused` flag into the run-scoped consecutive-reuse
|
|
309
|
-
* counter: a reused (provider) summary increments it, a real (LLM) summary resets it to 0. A no-op
|
|
310
|
-
* compaction (`compacted:false`) leaves the counter untouched. No-op when no provider is wired. */
|
|
311
|
-
private recordCompactionReuse;
|
|
312
|
-
private finish;
|
|
313
|
-
/**
|
|
314
|
-
* design/48 remote seam +: tear down a per-task env minted by `executionEnvFactory` (e.g. a
|
|
315
|
-
* remote container, or a `withWorktreeIsolation` worktree) — this task owned its lifetime. Best-effort, like
|
|
316
|
-
* `mcp.dispose`: a `destroy()` failure must not break the run. Only `ownedEnv` (factory-produced) is destroyed;
|
|
317
|
-
* a caller-owned static `deps.executionEnv` outlives the task and is left untouched. The service control plane's
|
|
318
|
-
* reaper is the backstop for an env orphaned by a rare pre-teardown throw (same posture as `mcp`).
|
|
319
|
-
*
|
|
320
|
-
* Runs from the run-loop tail AFTER every env-reader (finish()'s compaction `attachWorkingFiles` +
|
|
321
|
-
* the file-history boundary settle), so the working tree is still readable when they run. This ORDER is
|
|
322
|
-
* the fix for a teardown-order defect: the old in-`finish` destroy ran BEFORE the capture seat, so a
|
|
323
|
-
* factory-minted remote/worktree lane captured an already-destroyed env (plain host/static lanes were
|
|
324
|
-
* false-green).
|
|
325
|
-
*
|
|
326
|
-
* design/49 v1.5 / design/76 §2.5: a committed durable pause (`pausedRef.current`, any gate kind)
|
|
327
|
-
* `suspendVM`-paused the env and persisted its `workspaceHandle` into the checkpoint — destroying it would
|
|
328
|
-
* discard the paused VM and make resume fail to restore. Skip teardown; `resume()` rebuilds + `resumeVM`s it. A
|
|
329
|
-
* cancelled pause is reaped via `TaskStream.destroy()` (design/51); an abandoned one is the service container
|
|
330
|
-
* reaper's backstop. The gate here MIRRORS the tail's reap-stash (same durable fact
|
|
331
|
-
* `pausedRef.current === undefined`), so exactly one path owns the env's fate.
|
|
332
|
-
*/
|
|
333
|
-
private teardownOwnedEnv;
|
|
334
254
|
}
|
|
335
255
|
/** Convenience: one-shot run with explicit deps (creates a throwaway Runner). */
|
|
336
256
|
export declare function runTask(spec: TaskSpec, deps: RunnerDeps): Promise<TaskResult>;
|