@sema-agent/core 7.17.7 → 7.19.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 +233 -13
- package/dist/agents/send-message-tool.js +1 -0
- package/dist/agents/subagent.d.ts +1 -0
- package/dist/agents/subagent.js +5 -0
- package/dist/agents/teacher.js +1 -0
- package/dist/agents/verify.js +3 -0
- package/dist/brain/anthropic.js +6 -3
- package/dist/brain/open-responses.js +10 -4
- package/dist/brain/openai.js +5 -2
- package/dist/brain/reasoning.d.ts +13 -13
- package/dist/brain/reasoning.js +2 -2
- package/dist/brain/route-adjudicator.d.ts +18 -0
- package/dist/brain/route-adjudicator.js +16 -0
- package/dist/brain/stream-engine.js +2 -1
- package/dist/brain/stream-shared.d.ts +3 -0
- package/dist/brain/stream-shared.js +1 -0
- package/dist/core/agent-definition.d.ts +10 -0
- package/dist/core/artifact-host.d.ts +41 -4
- package/dist/core/artifact-host.js +18 -2
- package/dist/core/ask-origin.d.ts +16 -0
- package/dist/core/ask-origin.js +8 -0
- package/dist/core/auto-mode-arming.d.ts +6 -0
- package/dist/core/auto-mode-arming.js +5 -5
- package/dist/core/auto-mode-defaults.d.ts +43 -15
- package/dist/core/auto-mode-defaults.js +4 -1
- package/dist/core/auto-mode.d.ts +184 -59
- package/dist/core/auto-mode.js +188 -13
- package/dist/core/checkpoint-store.d.ts +23 -2
- package/dist/core/checkpoint-store.js +2 -2
- package/dist/core/engine-notice.d.ts +77 -1
- package/dist/core/engine-notice.js +7 -0
- package/dist/core/gate-fold.js +5 -1
- package/dist/core/gate-lanes.js +9 -8
- package/dist/core/gate-outcome.d.ts +42 -2
- package/dist/core/gate-outcome.js +23 -0
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +14 -0
- package/dist/core/hook-seats.d.ts +66 -0
- package/dist/core/hook-seats.js +37 -0
- package/dist/core/hooks.d.ts +1 -1
- package/dist/core/read-root-candidate.d.ts +12 -0
- package/dist/core/read-root-candidate.js +24 -0
- package/dist/core/roles.d.ts +9 -1
- package/dist/core/roles.js +4 -0
- package/dist/core/runner/advertised-writable-dirs.d.ts +8 -3
- package/dist/core/runner/assemble-result.d.ts +2 -1
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/classifier-ladder.d.ts +227 -0
- package/dist/core/runner/classifier-ladder.js +214 -0
- package/dist/core/runner/contracts.d.ts +71 -13
- package/dist/core/runner/decide-continuation.d.ts +1 -3
- package/dist/core/runner/decide-continuation.js +1 -7
- package/dist/core/runner/deferral-census.d.ts +52 -0
- package/dist/core/runner/deferral-census.js +44 -0
- package/dist/core/runner/denial-limit-arms.js +2 -2
- package/dist/core/runner/derived-route-fallback.d.ts +8 -4
- package/dist/core/runner/derived-route-fallback.js +8 -3
- package/dist/core/runner/gate-exit.d.ts +12 -0
- package/dist/core/runner/gate-exit.js +6 -3
- package/dist/core/runner/prepare-artifact.d.ts +10 -2
- package/dist/core/runner/prepare-artifact.js +5 -4
- package/dist/core/runner/prepare-ask-lane.js +1 -0
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
- package/dist/core/runner/prepare-caps-and-workflow.js +43 -55
- package/dist/core/runner/prepare-config-doors.d.ts +7 -1
- package/dist/core/runner/prepare-config-doors.js +13 -13
- package/dist/core/runner/prepare-defer-classify.d.ts +13 -19
- package/dist/core/runner/prepare-defer-classify.js +8 -3
- package/dist/core/runner/prepare-gate-stations.d.ts +26 -0
- package/dist/core/runner/prepare-gate-stations.js +1 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +24 -7
- package/dist/core/runner/prepare-hands-readface.js +60 -24
- package/dist/core/runner/prepare-inherited-gate.d.ts +17 -4
- package/dist/core/runner/prepare-inherited-gate.js +10 -2
- package/dist/core/runner/prepare-lsp.d.ts +2 -2
- package/dist/core/runner/prepare-lsp.js +1 -1
- package/dist/core/runner/prepare-policy-chain.js +2 -0
- package/dist/core/runner/prepare-project-context.d.ts +5 -1
- package/dist/core/runner/prepare-project-context.js +7 -4
- package/dist/core/runner/prepare-prompt-inputs.d.ts +4 -2
- package/dist/core/runner/prepare-prompt-inputs.js +4 -1
- package/dist/core/runner/prepare-run-refs.d.ts +9 -1
- package/dist/core/runner/prepare-run-refs.js +3 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +5 -0
- package/dist/core/runner/prepare-suspend-saga.js +5 -2
- package/dist/core/runner/prepare-task.js +19 -14
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +5 -0
- package/dist/core/runner/prepare-tool-disclosure-mount.js +10 -2
- package/dist/core/runner/prepare-turn-wiring.d.ts +8 -4
- package/dist/core/runner/prepare-turn-wiring.js +3 -2
- package/dist/core/runner/prepare-wiring-manifest.d.ts +5 -5
- package/dist/core/runner/prepare-wiring-manifest.js +5 -2
- package/dist/core/runner/resume-apply.js +3 -3
- package/dist/core/runner/resume-checkpoint-screen.js +7 -0
- package/dist/core/runner/run-harness-handlers.js +4 -1
- package/dist/core/runner/run-identity-wiring.js +6 -2
- package/dist/core/runner/run-leg.d.ts +2 -0
- package/dist/core/runner/run-leg.js +45 -45
- package/dist/core/runner/run-notification-lane.js +55 -27
- package/dist/core/runner/run-settle-and-teardown.js +1 -0
- package/dist/core/runner/run-terminal-adoption.js +16 -13
- package/dist/core/runner/run-turn-boundary.js +15 -5
- package/dist/core/runner/runtask.d.ts +6 -5
- package/dist/core/runner/runtask.js +26 -14
- package/dist/core/runner/skill-base-dir.d.ts +54 -0
- package/dist/core/runner/skill-base-dir.js +42 -0
- package/dist/core/runner/synthetic-tools.d.ts +83 -48
- package/dist/core/runner/synthetic-tools.js +69 -32
- package/dist/core/runner/tool-defer-gate.d.ts +22 -9
- package/dist/core/runner/tool-defer-gate.js +15 -5
- package/dist/core/runner/tool-disclosure.d.ts +5 -0
- package/dist/core/runner/tool-disclosure.js +2 -0
- package/dist/core/runner/tool-progress-lane.d.ts +42 -0
- package/dist/core/runner/tool-progress-lane.js +61 -0
- package/dist/core/runner/turn-attachments.d.ts +43 -12
- package/dist/core/runner/turn-attachments.js +58 -14
- package/dist/core/runner-deps.d.ts +48 -7
- package/dist/core/sensitive-path-policy.d.ts +58 -17
- package/dist/core/sensitive-path-policy.js +33 -5
- package/dist/core/skill-listing-budget.d.ts +112 -0
- package/dist/core/skill-listing-budget.js +58 -0
- package/dist/core/swappable-deps.d.ts +9 -7
- package/dist/core/swappable-deps.js +7 -3
- package/dist/core/task-event.d.ts +96 -29
- package/dist/core/task-notification.d.ts +142 -16
- package/dist/core/task-notification.js +106 -0
- package/dist/core/task-result.d.ts +9 -1
- package/dist/core/task-spec.d.ts +46 -3
- package/dist/core/tighten-task-spec.js +7 -5
- package/dist/core/tool-model-gate.d.ts +1 -1
- package/dist/core/tool-policy.d.ts +19 -4
- package/dist/core/tool-policy.js +6 -7
- package/dist/core/tool-search-setting.d.ts +78 -0
- package/dist/core/tool-search-setting.js +90 -0
- package/dist/core/tool-spec.d.ts +45 -4
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/wiring-manifest.d.ts +46 -0
- package/dist/core/wiring-manifest.js +9 -1
- package/dist/core/write-protect.d.ts +8 -3
- package/dist/core/write-protect.js +8 -5
- package/dist/engine/execution-env/node-execution-env.js +10 -4
- package/dist/engine/harness/agent-harness.d.ts +42 -0
- package/dist/engine/harness/agent-harness.js +61 -29
- package/dist/engine/loop/agent-loop.d.ts +68 -3
- package/dist/engine/loop/agent-loop.js +109 -16
- package/dist/index.d.ts +13 -8
- package/dist/index.js +11 -7
- package/dist/internal/harness.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +3 -0
- package/dist/orchestration/run-workflow-tool.js +6 -1
- package/dist/orchestration/workflow-governance.d.ts +7 -1
- package/dist/orchestration/workflow-governance.js +9 -5
- package/dist/orchestration/workflow-primitives.d.ts +3 -0
- package/dist/orchestration/workflow-primitives.js +6 -1
- package/dist/orchestration/workflow-types.d.ts +48 -13
- package/dist/orchestration/workflow-types.js +1 -1
- package/dist/orchestration/workflow.js +45 -17
- package/dist/prompt-assembly/epoch.js +2 -0
- package/dist/prompt-assembly/packs/sema-default.js +2 -2
- package/dist/prompt-assembly/section-usage.d.ts +26 -0
- package/dist/prompt-assembly/section-usage.js +10 -0
- package/dist/prompt-assembly/types.d.ts +8 -6
- package/dist/prompts/default.d.ts +13 -0
- package/dist/prompts/default.js +16 -8
- package/dist/tools/artifact/artifact-text.d.ts +10 -1
- package/dist/tools/artifact/artifact-text.js +6 -3
- package/dist/tools/artifact/artifact-tool.d.ts +12 -2
- package/dist/tools/artifact/artifact-tool.js +203 -70
- package/dist/tools/artifact/conformance.d.ts +56 -0
- package/dist/tools/artifact/conformance.js +349 -0
- package/dist/tools/artifact/local-stub.js +1 -1
- package/dist/tools/artifact/reject-breaker.d.ts +28 -0
- package/dist/tools/artifact/reject-breaker.js +42 -0
- package/dist/tools/fs/bash-lexer.d.ts +132 -0
- package/dist/tools/fs/bash-lexer.js +563 -0
- package/dist/tools/fs/bash-program-position.d.ts +142 -0
- package/dist/tools/fs/bash-program-position.js +125 -0
- package/dist/tools/fs/bash-readonly-classifier.d.ts +81 -16
- package/dist/tools/fs/bash-readonly-classifier.js +180 -558
- package/dist/tools/fs/containment-face.d.ts +89 -0
- package/dist/tools/fs/containment-face.js +81 -0
- package/dist/tools/fs/fs-bash.d.ts +46 -1
- package/dist/tools/fs/fs-bash.js +165 -25
- package/dist/tools/fs/fs-read.d.ts +1 -1
- package/dist/tools/fs/fs-search-tools.d.ts +3 -3
- package/dist/tools/fs/fs-write.d.ts +4 -3
- package/dist/tools/fs/fs-write.js +9 -9
- package/dist/tools/fs/index.d.ts +24 -5
- package/dist/tools/fs/index.js +18 -6
- package/dist/tools/fs/read-deny.d.ts +4 -3
- package/dist/tools/fs/repo-map.d.ts +2 -2
- package/dist/tools/fs/safety.d.ts +18 -3
- package/dist/tools/fs/safety.js +11 -4
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +99 -13
- package/wire-changes/core@7.17.7.json +49 -0
- package/wire-changes/core@7.18.0.json +1273 -0
- package/wire-changes/core@7.19.0.json +457 -0
- package/dist/tools/fs/read-face.d.ts +0 -68
- package/dist/tools/fs/read-face.js +0 -47
|
@@ -16,18 +16,20 @@ import { deliverEngineNotice } from "../types.js";
|
|
|
16
16
|
import { delimitUntrusted, inlineUntrusted, REVIEWER_NOTE_MAX_BODY, sanitizeUntrustedText } from "../untrusted-text.js";
|
|
17
17
|
import { errorCodeOf } from "./assemble-result.js";
|
|
18
18
|
import { DEFAULT_PRECALL_OUTPUT_TOKENS, platformLimitTerminal } from "./clock-and-limits.js";
|
|
19
|
-
import { deepJsonEqual,
|
|
19
|
+
import { deepJsonEqual, resumeContinuation } from "./decide-continuation.js";
|
|
20
20
|
import { settleExecutionRecord } from "./execution-record.js";
|
|
21
21
|
import { mintGateOutcome } from "./gate-exit.js";
|
|
22
22
|
import { resolveGitLegDelivery, wrapGitFrame } from "./git-leg-delivery.js";
|
|
23
23
|
import { GIT_STATUS_ECHO_PREVIEW } from "./git-status-frame.js";
|
|
24
24
|
import { toImageContent } from "./image.js";
|
|
25
|
+
import { maybeHumanRejectionHalt } from "./prepare-gate-stations.js";
|
|
25
26
|
import { nextHumanInputSeq } from "./steer-admission.js";
|
|
26
27
|
import { settleTeardownLeg } from "./teardown-bounded.js";
|
|
27
28
|
import { toolEndBodyFrom, toolResultMsg } from "./tool-end-body.js";
|
|
28
|
-
import {
|
|
29
|
+
import { announceSkillListingTruncation } from "../skill-listing-budget.js";
|
|
30
|
+
import { attachmentEnvelopeTags, commitAgentListing, commitSkillsListing, reduceToolEnd, renderAgentListingDelta, renderOrphanedBackgroundTasks, renderSkillsListingFrame, stampWriteAnchor } from "./turn-attachments.js";
|
|
29
31
|
export async function runLeg(input) {
|
|
30
|
-
const { spec, queue, prepared, resume, rs, entryActor, effectiveTimeoutMs, timeout, pushContent, ident, emitCommitted, writeFamilyOf, startedToolCallIds, announceWorkspaceMove, withBrainSinks, flushGitMirror, loopLatch, notificationLane, unsubscribeTaskNotifications, unsubGitRetry, unsubBoundary, unsub, runner, next } = input;
|
|
32
|
+
const { spec, queue, prepared, resume, rs, isDelegatedChild, entryActor, effectiveTimeoutMs, timeout, pushContent, ident, emitCommitted, writeFamilyOf, startedToolCallIds, announceWorkspaceMove, withBrainSinks, flushGitMirror, loopLatch, notificationLane, unsubscribeTaskNotifications, unsubGitRetry, unsubBoundary, unsub, runner, next } = input;
|
|
31
33
|
let final;
|
|
32
34
|
let threw;
|
|
33
35
|
let abortedLive = false;
|
|
@@ -101,11 +103,12 @@ export async function runLeg(input) {
|
|
|
101
103
|
else {
|
|
102
104
|
let continuation = resumeContinuation(resume, prepared.reminderMark);
|
|
103
105
|
const bgSnapshot = resume.cp.state.runningBackgroundTasks;
|
|
106
|
+
let orphanTasks = [];
|
|
104
107
|
if (bgSnapshot !== undefined && bgSnapshot.length > 0) {
|
|
105
108
|
const alive = new Set(prepared.listBackgroundTasks().map((t) => t.id));
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
continuation += "\n\n" + formatHookFeedback(renderOrphanedBackgroundTasks(
|
|
109
|
+
orphanTasks = bgSnapshot.filter((t) => !alive.has(t.id));
|
|
110
|
+
if (orphanTasks.length > 0) {
|
|
111
|
+
continuation += "\n\n" + formatHookFeedback(renderOrphanedBackgroundTasks(orphanTasks), prepared.reminderMark);
|
|
109
112
|
}
|
|
110
113
|
}
|
|
111
114
|
let gitResumeDelivered;
|
|
@@ -128,10 +131,13 @@ export async function runLeg(input) {
|
|
|
128
131
|
}
|
|
129
132
|
}
|
|
130
133
|
const engineSegments = continuation.length > 0 ? [{ start: 0, end: continuation.length }] : [];
|
|
134
|
+
const parkedSteers = readPendingSteerQueue(resume.cp.state);
|
|
131
135
|
const resumeFrames = [
|
|
132
|
-
...
|
|
136
|
+
...parkedSteers.map((entry) => ({ entry, source: "steer" })),
|
|
133
137
|
...(resume.wakeMessage !== undefined ? [{ entry: resume.wakeMessage, source: "wake" }] : []),
|
|
134
138
|
];
|
|
139
|
+
const appliedEvents = [];
|
|
140
|
+
const withheldSteerIds = new Set();
|
|
135
141
|
for (const { entry: steer, source } of resumeFrames) {
|
|
136
142
|
if (source === "wake" && resume.wakeMessageHookContext !== undefined) {
|
|
137
143
|
const hookStart = continuation.length;
|
|
@@ -166,6 +172,8 @@ export async function runLeg(input) {
|
|
|
166
172
|
outcome = { blocked: `the screen crashed (${inlineUntrusted(err.message)}; fail-closed)` };
|
|
167
173
|
}
|
|
168
174
|
if ("blocked" in outcome) {
|
|
175
|
+
if (steer.inputId !== undefined)
|
|
176
|
+
withheldSteerIds.add(steer.inputId);
|
|
169
177
|
deliverEngineNotice(runner.deps.onNotice, {
|
|
170
178
|
code: "steering.parked_input_blocked",
|
|
171
179
|
message: "a parked steering input was withheld by the deployment's userPromptSubmit screen when this resume redelivered it: " +
|
|
@@ -207,7 +215,7 @@ export async function runLeg(input) {
|
|
|
207
215
|
(steer.trusted ? formatHookFeedback(projected, prepared.reminderMark) : delimitUntrusted("supervisor steering message", projected));
|
|
208
216
|
if (steer.trusted)
|
|
209
217
|
engineSegments.push({ start, end: continuation.length });
|
|
210
|
-
|
|
218
|
+
appliedEvents.push({
|
|
211
219
|
...buildHumanInputEvent({
|
|
212
220
|
carrier: source,
|
|
213
221
|
source,
|
|
@@ -236,7 +244,22 @@ export async function runLeg(input) {
|
|
|
236
244
|
},
|
|
237
245
|
};
|
|
238
246
|
}
|
|
239
|
-
|
|
247
|
+
const pending = resume.cp.pendingAction;
|
|
248
|
+
const rejectionHalt = pending.kind === "tool_approval" && resume.outcome.gate === "policy_ask"
|
|
249
|
+
? maybeHumanRejectionHalt({ gate: resume.outcome.gateOutcome, isDelegatedChild, toolName: pending.toolName, toolCallId: pending.toolCallId })
|
|
250
|
+
: undefined;
|
|
251
|
+
if (rejectionHalt !== undefined && pending.kind === "tool_approval")
|
|
252
|
+
prepared.batchHaltRef.current = { rejectedToolCallId: pending.toolCallId };
|
|
253
|
+
prepared.undeliveredContinuationRef.current = { parkedSteers: resumeFrames.map(({ entry }) => entry).filter((e) => !withheldSteerIds.has(e.inputId)), orphanTasks };
|
|
254
|
+
final = await withBrainSinks(() => prepared.harness.prompt(continuation, {
|
|
255
|
+
engineSegments,
|
|
256
|
+
settleUnansweredToolCalls: rejectionHalt !== undefined ? { halt: rejectionHalt } : {},
|
|
257
|
+
onDelivered: () => {
|
|
258
|
+
prepared.undeliveredContinuationRef.current = { parkedSteers: [], orphanTasks: [] };
|
|
259
|
+
for (const e of appliedEvents)
|
|
260
|
+
queue.push(e);
|
|
261
|
+
},
|
|
262
|
+
}));
|
|
240
263
|
await flushGitMirror();
|
|
241
264
|
if (prepared.gitStatusRef.announced?.pending === true)
|
|
242
265
|
await prepared.gitStatusRef.reassert?.();
|
|
@@ -309,6 +332,7 @@ export async function runLeg(input) {
|
|
|
309
332
|
}
|
|
310
333
|
}
|
|
311
334
|
const firstFrames = [];
|
|
335
|
+
let skillsListingCost;
|
|
312
336
|
if (rs.attach.attachState !== undefined) {
|
|
313
337
|
const attach = rs.attach.attachState;
|
|
314
338
|
if (rs.attach.agentListingOn && prepared.agentListing !== undefined) {
|
|
@@ -329,14 +353,15 @@ export async function runLeg(input) {
|
|
|
329
353
|
}
|
|
330
354
|
if (rs.attach.skillsListingOn && prepared.skillsListing !== undefined) {
|
|
331
355
|
const listing = prepared.skillsListing;
|
|
332
|
-
const
|
|
333
|
-
if (
|
|
356
|
+
const frame = renderSkillsListingFrame(attach, listing.entries, listing.budget);
|
|
357
|
+
if (frame !== undefined) {
|
|
334
358
|
firstFrames.push({
|
|
335
359
|
source: "skills_listing",
|
|
336
|
-
body,
|
|
360
|
+
body: frame.text,
|
|
337
361
|
commit: () => {
|
|
338
362
|
commitSkillsListing(attach, listing.entries);
|
|
339
363
|
prepared.announcedListingsRef.skills = listing.entries.map((e) => e.name);
|
|
364
|
+
skillsListingCost = { total: frame.listed, nameOnly: frame.nameOnly, dropped: frame.dropped, budget: listing.budget };
|
|
340
365
|
},
|
|
341
366
|
});
|
|
342
367
|
}
|
|
@@ -410,6 +435,9 @@ export async function runLeg(input) {
|
|
|
410
435
|
rs.attach.attachmentsInjected += firstFrames.length;
|
|
411
436
|
if (firstFrames.length > 0 && prepared.announcedSnapshotRecovered)
|
|
412
437
|
await prepared.session.appendAnnouncedListing(prepared.announcedListingsRef).catch(() => undefined);
|
|
438
|
+
if (skillsListingCost !== undefined) {
|
|
439
|
+
announceSkillListingTruncation(runner.deps.onNotice, { ...skillsListingCost, sessionId: prepared.sessionId });
|
|
440
|
+
}
|
|
413
441
|
const enginePrefixChars = effectiveObjective.length - projectedObjective.length;
|
|
414
442
|
queue.push({
|
|
415
443
|
...buildHumanInputEvent({
|
|
@@ -452,6 +480,7 @@ export async function runLeg(input) {
|
|
|
452
480
|
finally {
|
|
453
481
|
timeout.clear();
|
|
454
482
|
prepared.lspDiagnostics?.registry.releaseRun(prepared.lspDiagnostics.runIdent);
|
|
483
|
+
prepared.toolProgressRef.current?.clear();
|
|
455
484
|
prepared.abortController.abort();
|
|
456
485
|
prepared.releaseSignal();
|
|
457
486
|
strandedHumanAnswers = prepared.settleContentAskBindings();
|
|
@@ -463,6 +492,7 @@ export async function runLeg(input) {
|
|
|
463
492
|
notificationLane.live = false;
|
|
464
493
|
unsubscribeTaskNotifications();
|
|
465
494
|
prepared.toolRosterDeltas.unsubscribe();
|
|
495
|
+
prepared.toolDisclosure?.unsubscribe();
|
|
466
496
|
unsubGitRetry();
|
|
467
497
|
unsubBoundary();
|
|
468
498
|
unsub();
|
|
@@ -491,39 +521,7 @@ async function applyResumeDecision(runner, prepared, resume, emit, emitCommitted
|
|
|
491
521
|
e.code = "resume.tool_contract_mismatch";
|
|
492
522
|
throw e;
|
|
493
523
|
}
|
|
494
|
-
|
|
495
|
-
const deferredIds = pendingAction.batchToolCallIds.filter((id) => id !== pendingAction.toolCallId && !completed.has(id));
|
|
496
|
-
const names = new Map();
|
|
497
|
-
const deferredArgs = new Map();
|
|
498
|
-
if (deferredIds.length > 0) {
|
|
499
|
-
const { messages } = await prepared.session.buildContext();
|
|
500
|
-
for (const m of messages) {
|
|
501
|
-
if (m.role === "assistant") {
|
|
502
|
-
for (const c of m.content) {
|
|
503
|
-
if (c.type === "toolCall") {
|
|
504
|
-
names.set(c.id, c.name);
|
|
505
|
-
deferredArgs.set(c.id, c.arguments);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
for (const id of pendingAction.batchToolCallIds) {
|
|
512
|
-
if (id === pendingAction.toolCallId) {
|
|
513
|
-
await resolvePendingCall(runner, prepared, resume, emit, emitCommitted, onResolvedToolSuccess, onExecuteStart);
|
|
514
|
-
}
|
|
515
|
-
else if (!completed.has(id)) {
|
|
516
|
-
const name = names.get(id) ?? "unknown";
|
|
517
|
-
const displayLabel = (() => {
|
|
518
|
-
const l = prepared.tools.find((t) => t.name === name)?.label;
|
|
519
|
-
return l !== undefined && l !== name ? { label: l } : {};
|
|
520
|
-
})();
|
|
521
|
-
emit({ type: "tool_start", toolCallId: id, toolName: name, ...displayLabel, args: deferredArgs.get(id) ?? {} });
|
|
522
|
-
emit({ type: "tool_end", toolCallId: id, toolName: name, ...displayLabel, isError: true, ...toolEndBodyFrom({ content: formatHookFeedback(DEFERRED_REISSUE, prepared.reminderMark) }, true, prepared.structuredProjector) });
|
|
523
|
-
const eid = await prepared.session.appendMessage(toolResultMsg(id, name, formatHookFeedback(DEFERRED_REISSUE, prepared.reminderMark), true));
|
|
524
|
-
emitCommitted(eid, "toolResult", id);
|
|
525
|
-
}
|
|
526
|
-
}
|
|
524
|
+
await resolvePendingCall(runner, prepared, resume, emit, emitCommitted, onResolvedToolSuccess, onExecuteStart);
|
|
527
525
|
}
|
|
528
526
|
async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted, onResolvedToolSuccess, onExecuteStart) {
|
|
529
527
|
const { pendingAction } = resume.cp;
|
|
@@ -538,6 +536,7 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
538
536
|
const pendingLabel = (() => { const l = prepared.tools.find((t) => t.name === pendingAction.toolName)?.label; return l !== undefined && l !== pendingAction.toolName ? { label: l } : {}; })();
|
|
539
537
|
emit({ type: "tool_start", toolCallId: pendingAction.toolCallId, toolName: pendingAction.toolName, ...pendingLabel, args: resolvedArgs });
|
|
540
538
|
const settleEnd = async (isError, result, gate = decidedGate) => {
|
|
539
|
+
prepared.toolProgressRef.current?.noteEnd(pendingAction.toolCallId);
|
|
541
540
|
emit({ type: "tool_end", toolCallId: pendingAction.toolCallId, toolName: pendingAction.toolName, ...pendingLabel, isError, ...toolEndBodyFrom(result, isError, prepared.structuredProjector, gate) });
|
|
542
541
|
const word = await resume.recordExecutionOutcome(gate);
|
|
543
542
|
settleExecutionRecord(runner.deps.onNotice, word, { toolName: pendingAction.toolName, gate, sessionId: prepared.sessionId, runId: prepared.runId, scope: resume.cp.scope, ...(resume.cp.checkpointId !== undefined ? { checkpointId: resume.cp.checkpointId } : {}) });
|
|
@@ -676,6 +675,7 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
676
675
|
}
|
|
677
676
|
const args = resolvedArgs;
|
|
678
677
|
onExecuteStart?.(pendingAction.toolCallId);
|
|
678
|
+
prepared.toolProgressRef.current?.noteStart(pendingAction.toolCallId, pendingAction.toolName);
|
|
679
679
|
prepared.suspendProgressRef.executedApproved = true;
|
|
680
680
|
let res;
|
|
681
681
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createPeerInboundChainRef, createPeerSelfRef } from "../../agents/peer-admission.js";
|
|
2
2
|
import { boundInputHashOf } from "../canonical-json.js";
|
|
3
|
-
import { isDelegatedAgentTerminal, isTerminalTaskNotification, renderTaskNotificationXml,
|
|
3
|
+
import { createLiveNotificationLane, isDelegatedAgentTerminal, isTerminalTaskNotification, renderTaskNotificationXml, routeOrParkNotification, SystemInjectionQueue } from "../task-notification.js";
|
|
4
4
|
import { ToolDetachHub } from "../tool-detach.js";
|
|
5
5
|
import { pendingContentAskCallId } from "./decide-continuation.js";
|
|
6
6
|
export async function runNotificationLane(input) {
|
|
@@ -32,9 +32,13 @@ export async function runNotificationLane(input) {
|
|
|
32
32
|
let notificationLaneLive = true;
|
|
33
33
|
let notificationSessionId;
|
|
34
34
|
let descendantAnchorDisclosed = false;
|
|
35
|
-
const parkTaskNotification = (payload, priority) => {
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
const parkTaskNotification = (payload, priority, onDisposition) => {
|
|
36
|
+
laneSeat.handOff(payload);
|
|
37
|
+
const ownSession = notificationSessionId;
|
|
38
|
+
if (ownSession !== undefined)
|
|
39
|
+
routeOrParkNotification(pendingSessionNotifications, ownSession, payload, priority, onDisposition);
|
|
40
|
+
else
|
|
41
|
+
onDisposition?.("parked");
|
|
38
42
|
if (!isDelegatedAgentTerminal(payload))
|
|
39
43
|
return;
|
|
40
44
|
const uplink = internals?.parentNotify;
|
|
@@ -49,12 +53,12 @@ export async function runNotificationLane(input) {
|
|
|
49
53
|
}
|
|
50
54
|
const rootAnchor = internals?.rootSessionId;
|
|
51
55
|
if (rootAnchor !== undefined && rootAnchor !== notificationSessionId) {
|
|
52
|
-
pendingSessionNotifications
|
|
56
|
+
routeOrParkNotification(pendingSessionNotifications, rootAnchor, payload, priority);
|
|
53
57
|
return;
|
|
54
58
|
}
|
|
55
59
|
if (internals?.parentSessionId !== undefined && !descendantAnchorDisclosed) {
|
|
56
60
|
descendantAnchorDisclosed = true;
|
|
57
|
-
runner.deps.onError?.(new Error(`background-agent terminal ${payload.task_id}
|
|
61
|
+
runner.deps.onError?.(new Error(`background-agent terminal ${payload.task_id} stayed on this run's own session — the delegation tree's root session is not reachable from this run (no uplink, no root anchor)`), { phase: "degraded", sessionId: notificationSessionId ?? "", classification: "descendant-terminal-unrouted" });
|
|
58
62
|
}
|
|
59
63
|
};
|
|
60
64
|
const unsubscribeTaskNotifications = taskNotificationQueue.subscribe((item) => {
|
|
@@ -70,34 +74,33 @@ export async function runNotificationLane(input) {
|
|
|
70
74
|
? notificationHarness.followUp(xml, noteOptions)
|
|
71
75
|
: notificationHarness.steer(xml, { ...noteOptions, ...(item.priority === "now" ? { immediate: true } : {}) });
|
|
72
76
|
void deliver.then(() => item.onDisposition?.("queued"), () => {
|
|
73
|
-
parkTaskNotification(item.payload, item.priority);
|
|
74
|
-
item.onDisposition?.("parked");
|
|
77
|
+
parkTaskNotification(item.payload, item.priority, item.onDisposition);
|
|
75
78
|
});
|
|
76
79
|
}
|
|
77
80
|
else {
|
|
78
|
-
parkTaskNotification(item.payload, item.priority);
|
|
79
|
-
item.onDisposition?.("parked");
|
|
81
|
+
parkTaskNotification(item.payload, item.priority, item.onDisposition);
|
|
80
82
|
}
|
|
81
83
|
});
|
|
82
84
|
const upstreamTaskNotification = internals?.onTaskNotification;
|
|
83
85
|
const deliveredAtTurnOpen = new Set();
|
|
86
|
+
const laneSeat = createLiveNotificationLane({
|
|
87
|
+
queue: taskNotificationQueue,
|
|
88
|
+
canTakeNow: () => notificationLaneLive && notificationHarness?.acceptsInjections === true,
|
|
89
|
+
isLive: () => notificationLaneLive,
|
|
90
|
+
alreadyDelivered: (key) => deliveredAtTurnOpen.has(key),
|
|
91
|
+
});
|
|
92
|
+
const takeOnThisLane = laneSeat.take;
|
|
93
|
+
const takeAsDestination = laneSeat.takeAsDestination;
|
|
84
94
|
const injectTaskNotification = (notification, opts) => {
|
|
85
|
-
|
|
86
|
-
return Promise.resolve("dropped_duplicate");
|
|
87
|
-
if (!notificationLaneLive) {
|
|
88
|
-
parkTaskNotification(notification, opts?.priority ?? "later");
|
|
89
|
-
return Promise.resolve("parked");
|
|
90
|
-
}
|
|
95
|
+
const priority = opts?.priority ?? "later";
|
|
91
96
|
return new Promise((resolve) => {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
payload: notification,
|
|
97
|
-
onDisposition: resolve,
|
|
98
|
-
});
|
|
99
|
-
if (!accepted)
|
|
97
|
+
const own = takeOnThisLane(notification, priority, resolve);
|
|
98
|
+
if (own === "duplicate")
|
|
99
|
+
resolve("dropped_duplicate");
|
|
100
|
+
else if (own === "pending")
|
|
100
101
|
resolve("queued");
|
|
102
|
+
else if (own === "unavailable")
|
|
103
|
+
parkTaskNotification(notification, priority, resolve);
|
|
101
104
|
});
|
|
102
105
|
};
|
|
103
106
|
const peerSelfRef = internals?.peerSelfRef ?? createPeerSelfRef(internals?.registryScope ?? spec.principal ?? "default");
|
|
@@ -120,9 +123,34 @@ export async function runNotificationLane(input) {
|
|
|
120
123
|
}, self, taskIdRef);
|
|
121
124
|
const notificationLane = {
|
|
122
125
|
get harness() { return notificationHarness; }, set harness(h) { notificationHarness = h; },
|
|
123
|
-
get sessionId() { return notificationSessionId; },
|
|
126
|
+
get sessionId() { return notificationSessionId; },
|
|
127
|
+
set sessionId(s) {
|
|
128
|
+
if (notificationSessionId !== undefined)
|
|
129
|
+
pendingSessionNotifications.liveLanes.unregister(notificationSessionId, takeAsDestination);
|
|
130
|
+
notificationSessionId = s;
|
|
131
|
+
if (s !== undefined && notificationLaneLive)
|
|
132
|
+
pendingSessionNotifications.liveLanes.register(s, takeAsDestination);
|
|
133
|
+
},
|
|
124
134
|
get ident() { return notificationIdent; }, set ident(f) { notificationIdent = f; },
|
|
125
|
-
get live() { return notificationLaneLive; },
|
|
135
|
+
get live() { return notificationLaneLive; },
|
|
136
|
+
set live(v) {
|
|
137
|
+
notificationLaneLive = v;
|
|
138
|
+
if (notificationSessionId === undefined)
|
|
139
|
+
return;
|
|
140
|
+
if (v) {
|
|
141
|
+
pendingSessionNotifications.liveLanes.register(notificationSessionId, takeAsDestination);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
pendingSessionNotifications.liveLanes.unregister(notificationSessionId, takeAsDestination);
|
|
145
|
+
laneSeat.release();
|
|
146
|
+
}
|
|
147
|
+
},
|
|
126
148
|
};
|
|
127
|
-
|
|
149
|
+
try {
|
|
150
|
+
return await next({ prepared, injectTaskNotification, deliveredAtTurnOpen, peerInboundChainRef, modelCatalog, notificationLane, unsubscribeTaskNotifications });
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
if (notificationSessionId !== undefined)
|
|
154
|
+
pendingSessionNotifications.liveLanes.unregister(notificationSessionId, takeAsDestination);
|
|
155
|
+
}
|
|
128
156
|
}
|
|
@@ -107,6 +107,7 @@ export async function runSettleAndTeardown(input) {
|
|
|
107
107
|
strandedHumanAnswers,
|
|
108
108
|
remoteEnvFailures: prepared.remoteEnvFailures,
|
|
109
109
|
effectiveReadFace: prepared.effectiveReadFace,
|
|
110
|
+
effectiveWriteFace: prepared.effectiveWriteFace,
|
|
110
111
|
effectiveReadDenyPatterns: prepared.effectiveReadDenyPatterns,
|
|
111
112
|
effectiveMemoryScopes: prepared.effectiveMemoryScopes,
|
|
112
113
|
effectiveReasoning: reasoningResolution.current,
|
|
@@ -3,7 +3,7 @@ import { DEFAULT_COMPACTION_SETTINGS } from "../../internal/harness.js";
|
|
|
3
3
|
import { eventDefaultOn } from "../../prompt-assembly/event-registry.js";
|
|
4
4
|
import { appendInterruptionMarker, reconcileInterruptedSession } from "../session-reconcile.js";
|
|
5
5
|
import { emitTrace } from "../trace.js";
|
|
6
|
-
import { deliverEngineNotice, undrainedUserInputNotices } from "../types.js";
|
|
6
|
+
import { deliverEngineNotice, owedUserInputCounts, undrainedUserInputNotices } from "../types.js";
|
|
7
7
|
import { answerSettled, errorCodeOf } from "./assemble-result.js";
|
|
8
8
|
import { awaitChargeWithSlowDisclosure, discloseUnevaluableWindow } from "./clock-and-limits.js";
|
|
9
9
|
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption } from "./compaction-call-options.js";
|
|
@@ -14,7 +14,7 @@ import { reconciledToolEndBody } from "./tool-end-body.js";
|
|
|
14
14
|
export async function runTerminalAdoption(input) {
|
|
15
15
|
const { spec, queue, prepared, rs, stats, ident, emitCommitted, startedToolCallIds, toolLabels, timeout, compactionBrain, compactionBreaker, windowSafetyOptions, undrainedUserAtEnd, userInputLostAtEnd, final, abortedLive, userInterruptedLive, runner, sessions, next } = input;
|
|
16
16
|
let { threw } = input;
|
|
17
|
-
const settled = answerSettled(final, userInputLostAtEnd.current || prepared.workCutRef.continuation || prepared.workCutRef.abortedBeforeTurnEnd);
|
|
17
|
+
const settled = answerSettled(final, userInputLostAtEnd.current || prepared.undeliveredContinuationRef.current.parkedSteers.length > 0 || prepared.workCutRef.continuation || prepared.workCutRef.abortedBeforeTurnEnd);
|
|
18
18
|
if (threw === undefined && prepared.brainCallGuardrailRef.timedOut !== undefined) {
|
|
19
19
|
threw = prepared.brainCallGuardrailRef.timedOut;
|
|
20
20
|
}
|
|
@@ -77,16 +77,24 @@ export async function runTerminalAdoption(input) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
let migratedParked = { steer: 0, followUp: 0 };
|
|
80
|
+
let carriedContinuation = 0;
|
|
80
81
|
if (committedPause !== undefined && runner.deps.checkpointStore !== undefined) {
|
|
81
82
|
const parkToken = committedPause.cause.token;
|
|
82
83
|
const parkScope = committedPause.scope;
|
|
83
84
|
const store = runner.deps.checkpointStore;
|
|
84
85
|
const carried = [];
|
|
85
|
-
|
|
86
|
+
const owed = [
|
|
87
|
+
...prepared.undeliveredContinuationRef.current.parkedSteers.map(({ seq: _seq, ...input }) => ({ input })),
|
|
88
|
+
...prepared.harness.readParkableUserInputs().map((record) => ({ input: record, live: record })),
|
|
89
|
+
];
|
|
90
|
+
for (const { input, live } of owed) {
|
|
86
91
|
try {
|
|
87
|
-
if (!(await store.setPendingSteer(parkToken, parkScope,
|
|
92
|
+
if (!(await store.setPendingSteer(parkToken, parkScope, input)))
|
|
88
93
|
break;
|
|
89
|
-
|
|
94
|
+
if (live !== undefined)
|
|
95
|
+
carried.push(live);
|
|
96
|
+
else
|
|
97
|
+
carriedContinuation += 1;
|
|
90
98
|
}
|
|
91
99
|
catch (parkErr) {
|
|
92
100
|
runner.deps.onError?.(parkErr instanceof Error ? parkErr : new Error(String(parkErr)), {
|
|
@@ -101,14 +109,9 @@ export async function runTerminalAdoption(input) {
|
|
|
101
109
|
}
|
|
102
110
|
migratedParked = prepared.harness.dropParkedUserInputs(carried);
|
|
103
111
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
followUp: Math.max(0, undrainedUserAtEnd.current.followUp - migratedParked.followUp),
|
|
108
|
-
};
|
|
109
|
-
for (const notice of undrainedUserInputNotices(remaining, spec.taskId ?? prepared.sessionId, prepared.sessionId, prepared.runId)) {
|
|
110
|
-
deliverEngineNotice(runner.deps.onNotice, notice);
|
|
111
|
-
}
|
|
112
|
+
const owed = owedUserInputCounts(undrainedUserAtEnd.current, migratedParked, { frames: prepared.undeliveredContinuationRef.current.parkedSteers, carried: carriedContinuation, rowMayReturn: committedPause === undefined && !prepared.suspendProgressRef.executedApproved });
|
|
113
|
+
for (const notice of undrainedUserInputNotices(owed, spec.taskId ?? prepared.sessionId, prepared.sessionId, prepared.runId)) {
|
|
114
|
+
deliverEngineNotice(runner.deps.onNotice, notice);
|
|
112
115
|
}
|
|
113
116
|
if (rs.attach.attachState?.postCompactPending === true && (rs.attach.attachmentsCfg?.backgroundTasks ?? eventDefaultOn("background_tasks")) === true) {
|
|
114
117
|
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.announce_dropped", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
@@ -4,7 +4,8 @@ import { eventDefaultOn } from "../../prompt-assembly/event-registry.js";
|
|
|
4
4
|
import { DEFAULT_COMPACTION_INSTRUCTIONS, isCompactionManualCancel, maybeCompact, nextTrimForceBackoff, recordCompactionAndCheckRapidRefill } from "../auto-compaction.js";
|
|
5
5
|
import { emitTrace } from "../trace.js";
|
|
6
6
|
import { redactThenCut } from "../../agents/subagent-steps.js";
|
|
7
|
-
import { ATTACHMENT_BYTE_CAP, CHANGED_FILES_MAX, TOTAL_TOKENS_REMINDER_DEFAULT_MODE, attachmentEnvelopeTags, clipToBytes, collectDateChange, collectDueAttachments, collectInstructionsChange, commitAgentListing, commitInstructionsChange, commitSkillsListing, rebaseCadenceWindows, renderAgentListingDelta, renderMcpDroppedTools, renderMcpInstructionsDelta, selectMcpDroppedBatch,
|
|
7
|
+
import { ATTACHMENT_BYTE_CAP, CHANGED_FILES_MAX, TOTAL_TOKENS_REMINDER_DEFAULT_MODE, attachmentEnvelopeTags, clipToBytes, collectDateChange, collectDueAttachments, collectInstructionsChange, commitAgentListing, commitInstructionsChange, commitSkillsListing, rebaseCadenceWindows, renderAgentListingDelta, renderMcpDroppedTools, renderMcpInstructionsDelta, selectMcpDroppedBatch, renderSkillsListingFrame, renderToolsDelta } from "./turn-attachments.js";
|
|
8
|
+
import { announceSkillListingTruncation } from "../skill-listing-budget.js";
|
|
8
9
|
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption } from "./compaction-call-options.js";
|
|
9
10
|
import { hookSeatExpiredError, runHookSeat } from "../hooks.js";
|
|
10
11
|
import { sanitizeUntrustedText, SHELLED_BODY_ENVELOPE_TAGS } from "../untrusted-text.js";
|
|
@@ -15,6 +16,7 @@ import { awaitChargeWithSlowDisclosure, discloseUnevaluableWindow, ENV_DUE_GOVER
|
|
|
15
16
|
import { gitRestateOption } from "./git-leg-delivery.js";
|
|
16
17
|
import { COMPACTION_FREED_EPSILON, COMPACTION_REGROWTH_FACTOR, MAX_CONSECUTIVE_COMPACTION_FAILURES } from "./compaction-knobs.js";
|
|
17
18
|
import { compactionHookOptions, recordCompactionReuse, seamCCompactionOptions } from "./compaction-seams.js";
|
|
19
|
+
import { contextUsageSections } from "../../prompt-assembly/section-usage.js";
|
|
18
20
|
const BATCH_CONTEXT_MIN_KEEP_BYTES = 160;
|
|
19
21
|
const BATCH_TRUNCATION_MARKER = "\n…[truncated]";
|
|
20
22
|
export function createTurnBoundary(input) {
|
|
@@ -201,6 +203,7 @@ export function createTurnBoundary(input) {
|
|
|
201
203
|
}
|
|
202
204
|
let boundaryAttachmentBytes = 0;
|
|
203
205
|
let attachmentsPayload;
|
|
206
|
+
let skillsListingCost;
|
|
204
207
|
if ((rs.attach.dateState !== undefined ||
|
|
205
208
|
rs.attach.instrState !== undefined ||
|
|
206
209
|
rs.attach.sizeGuidelineState !== undefined ||
|
|
@@ -312,7 +315,9 @@ export function createTurnBoundary(input) {
|
|
|
312
315
|
...(prepared.agentListing.models !== undefined ? { agentModels: prepared.agentListing.models } : {}),
|
|
313
316
|
}
|
|
314
317
|
: {}),
|
|
315
|
-
...(rs.attach.skillsListingOn && prepared.skillsListing !== undefined
|
|
318
|
+
...(rs.attach.skillsListingOn && prepared.skillsListing !== undefined
|
|
319
|
+
? { skillsListing: prepared.skillsListing.entries, skillsListingBudget: prepared.skillsListing.budget }
|
|
320
|
+
: {}),
|
|
316
321
|
...(mcpAdds !== undefined || mcpRemovals !== undefined
|
|
317
322
|
? { mcpInstructions: { added: mcpAdds ?? [], removed: mcpRemovals ?? [] } }
|
|
318
323
|
: {}),
|
|
@@ -376,9 +381,10 @@ export function createTurnBoundary(input) {
|
|
|
376
381
|
}
|
|
377
382
|
if (rs.attach.skillsListingOn && prepared.skillsListing !== undefined && due.some((a) => a.source === "skills_listing")) {
|
|
378
383
|
const listing = prepared.skillsListing;
|
|
379
|
-
const
|
|
380
|
-
if (
|
|
384
|
+
const intact = renderSkillsListingFrame(rs.attach.attachState, listing.entries, listing.budget);
|
|
385
|
+
if (intact !== undefined && due.some((a) => a.source === "skills_listing" && a.body === intact.text)) {
|
|
381
386
|
commitSkillsListing(rs.attach.attachState, listing.entries);
|
|
387
|
+
skillsListingCost = { total: intact.listed, nameOnly: intact.nameOnly, dropped: intact.dropped, budget: listing.budget };
|
|
382
388
|
prepared.announcedListingsRef.skills = listing.entries.map((e) => e.name);
|
|
383
389
|
if (prepared.announcedSnapshotRecovered)
|
|
384
390
|
await prepared.session.appendAnnouncedListing(prepared.announcedListingsRef).catch(() => undefined);
|
|
@@ -473,6 +479,9 @@ export function createTurnBoundary(input) {
|
|
|
473
479
|
if ((attachmentsPayload !== undefined || batchContextBlock !== undefined) && prepared.batchHaltRef.current === undefined) {
|
|
474
480
|
const payload = attachmentsPayload !== undefined && batchContextBlock !== undefined ? `${attachmentsPayload}\n${batchContextBlock}` : (attachmentsPayload ?? batchContextBlock);
|
|
475
481
|
void prepared.harness.steer(payload, { engineMinted: true }).catch(() => { });
|
|
482
|
+
if (skillsListingCost !== undefined) {
|
|
483
|
+
announceSkillListingTruncation(deps.runner.deps.onNotice, { ...skillsListingCost, sessionId: prepared.sessionId });
|
|
484
|
+
}
|
|
476
485
|
}
|
|
477
486
|
const forceManual = manualCompactRef.requested;
|
|
478
487
|
if ((!withinTaskCompaction && !forceManual) ||
|
|
@@ -580,7 +589,8 @@ export function createTurnBoundary(input) {
|
|
|
580
589
|
}
|
|
581
590
|
rs.counters.trimForceBackoff = nextTrimForceBackoff(rs.counters.trimForceBackoff, comp, trimPressure);
|
|
582
591
|
if (comp.contextUsage) {
|
|
583
|
-
|
|
592
|
+
const sections = contextUsageSections(prepared.promptManifest.sections);
|
|
593
|
+
queue.push({ type: "context_usage", ...comp.contextUsage, ...(sections !== undefined ? { sections } : {}), ...ident() });
|
|
584
594
|
}
|
|
585
595
|
if (comp.unevaluableWindow) {
|
|
586
596
|
discloseUnevaluableWindow(comp.unevaluableWindow, prepared, rs.telemetry.tracer, rs.telemetry.taskId, runnerHooks.onError);
|
|
@@ -91,14 +91,14 @@ export declare class Runner implements RunnerSelfSeat {
|
|
|
91
91
|
/**
|
|
92
92
|
* Hot-swap the deployment seats a running Runner may change without a restart — the ONE door for every
|
|
93
93
|
* hot-swappable seat ({@link SWAPPABLE_DEP_SEATS}: the model catalog generation `models` + its `tiers`
|
|
94
|
-
* bindings, and the deployment's
|
|
94
|
+
* bindings, and the deployment's two containment-face declarations `readFace` / `writeFace`), and the ONLY sanctioned way to
|
|
95
95
|
* change any of them after construction. It replaces the former `swapModels` verb (retired, no alias):
|
|
96
96
|
* one verb per seat restated the same laws with a list of verbs as the only record of what is swappable.
|
|
97
97
|
*
|
|
98
98
|
* The laws, stated once (see the vocabulary module for the seat-by-seat meaning):
|
|
99
99
|
* - **Screened first, written once — atomic.** The candidate is screened whole
|
|
100
100
|
* ({@link screenSwappableDeps}: the key set is the closed one, at least one seat, `tiers` rides with
|
|
101
|
-
* `models`, each seat's own value gate —
|
|
101
|
+
* `models`, each seat's own value gate — both face seats through the very `assertContainmentFaceValue` every
|
|
102
102
|
* prepare door applies) and the catalog is tier-expanded on the candidate (an illegal binding throws
|
|
103
103
|
* exactly like the constructor's boot error) BEFORE the deps object is replaced. On any throw the
|
|
104
104
|
* current deps stay in force, byte-identical.
|
|
@@ -108,14 +108,15 @@ export declare class Runner implements RunnerSelfSeat {
|
|
|
108
108
|
* redirects never re-route or re-price a task mid-run; a read-face change never re-fences a mounted
|
|
109
109
|
* band; the divergence window is exactly the in-flight legs' lifetime, by design.
|
|
110
110
|
* - **Presence is the instruction.** A key present on the candidate is replaced (an explicit
|
|
111
|
-
* `undefined` clears an optional seat: `tiers: undefined` ⇒ no bindings, `
|
|
111
|
+
* `undefined` clears an optional seat: `tiers: undefined` ⇒ no bindings, a face seat `undefined` ⇒ the
|
|
112
112
|
* engine default); a key absent is kept. `tiers` omitted beside `models` ⇒ the current bindings are
|
|
113
113
|
* re-applied over the new catalog.
|
|
114
114
|
* - **Announced per seat.** `config.models_swapped` (models/tiers counts — key material only, never the
|
|
115
115
|
* catalog itself; plus the advisory `route.base_url_changed_key_unchanged` for same-name entries
|
|
116
116
|
* whose URL moved while the Model-visible credential fingerprint did not) and
|
|
117
|
-
* `config.read_face_swapped` (`{ from, to, occurrenceId }`, the seat's
|
|
118
|
-
* = no declaration) — the table {@link SWAP_SEAT_NOTICE} binds every
|
|
117
|
+
* `config.read_face_swapped` / `config.write_face_swapped` (`{ from, to, occurrenceId }`, the seat's
|
|
118
|
+
* previous and new value, `null` = no declaration) — the table {@link SWAP_SEAT_NOTICE} binds every
|
|
119
|
+
* seat to its line.
|
|
119
120
|
*/
|
|
120
121
|
swapDeps(next: SwappableDeps): void;
|
|
121
122
|
/** one-shot brain-routed utility query (see {@link runSideQuery} for the full contract):
|
|
@@ -49,6 +49,7 @@ import { runAttachmentSeats } from "./run-attachment-seats.js";
|
|
|
49
49
|
import { runToolMountFacts } from "./run-tool-mount-facts.js";
|
|
50
50
|
import { runReasoningSeat } from "./run-reasoning-seat.js";
|
|
51
51
|
import { runClockAndContent } from "./run-clock-and-content.js";
|
|
52
|
+
import { createToolProgressLane } from "./tool-progress-lane.js";
|
|
52
53
|
import { runBrainSinks } from "./run-brain-sinks.js";
|
|
53
54
|
import { runCompactionMachinery } from "./run-compaction-machinery.js";
|
|
54
55
|
import { runStopAndFinalVerify } from "./run-stop-and-final-verify.js";
|
|
@@ -212,18 +213,25 @@ export class Runner {
|
|
|
212
213
|
}
|
|
213
214
|
}
|
|
214
215
|
}
|
|
215
|
-
const
|
|
216
|
-
const
|
|
216
|
+
const faceSeats = ["readFace", "writeFace"].filter((seat) => seats.includes(seat));
|
|
217
|
+
const priorFaces = {
|
|
218
|
+
readFace: this.deps.readFace,
|
|
219
|
+
writeFace: this.deps.writeFace,
|
|
220
|
+
};
|
|
217
221
|
const written = {
|
|
218
222
|
...this.deps,
|
|
219
223
|
...(expanded !== undefined ? { models: expanded } : {}),
|
|
220
224
|
...(catalogSwap && tiers !== undefined ? { tiers } : {}),
|
|
221
|
-
...(faceSwap && candidate.readFace !== undefined ? { readFace: candidate.readFace } : {}),
|
|
222
225
|
};
|
|
223
226
|
if (catalogSwap && tiers === undefined)
|
|
224
227
|
delete written.tiers;
|
|
225
|
-
|
|
226
|
-
|
|
228
|
+
const writtenFaceSeats = written;
|
|
229
|
+
for (const seat of faceSeats) {
|
|
230
|
+
if (candidate[seat] !== undefined)
|
|
231
|
+
writtenFaceSeats[seat] = candidate[seat];
|
|
232
|
+
else
|
|
233
|
+
delete writtenFaceSeats[seat];
|
|
234
|
+
}
|
|
227
235
|
this.deps = written;
|
|
228
236
|
if (catalogSwap) {
|
|
229
237
|
const modelCount = Object.keys(candidate.models).length;
|
|
@@ -245,13 +253,15 @@ export class Runner {
|
|
|
245
253
|
});
|
|
246
254
|
}
|
|
247
255
|
}
|
|
248
|
-
|
|
249
|
-
const to = candidate
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
256
|
+
for (const seat of faceSeats) {
|
|
257
|
+
const to = candidate[seat] ?? null;
|
|
258
|
+
const from = priorFaces[seat] ?? null;
|
|
259
|
+
const message = `deployment ${seat === "readFace" ? "read" : "write"} face swapped: ${from ?? "(no declaration)"} → ${to ?? "(no declaration)"}; in-flight legs keep the face they prepared under, new legs resolve against the new declaration`;
|
|
260
|
+
const detail = { from, to, occurrenceId: uuidv7() };
|
|
261
|
+
if (seat === "readFace")
|
|
262
|
+
deliverEngineNotice(this.deps.onNotice, { code: "config.read_face_swapped", message, detail });
|
|
263
|
+
else
|
|
264
|
+
deliverEngineNotice(this.deps.onNotice, { code: "config.write_face_swapped", message, detail });
|
|
255
265
|
}
|
|
256
266
|
}
|
|
257
267
|
sideQuery(spec) {
|
|
@@ -413,6 +423,8 @@ export class Runner {
|
|
|
413
423
|
const { todoToolMounted, taskToolsMounted, writeFamilyOf, toolStartAt, startedToolCallIds } = runToolMountFacts({ spec, prepared, rs });
|
|
414
424
|
const { observeReasoningWireFacts, reasoningResolution } = runReasoningSeat({ prepared, rs, taskIdRef });
|
|
415
425
|
const { effectiveTimeoutMs, walltimeMonotonicDeadline, timeout, pushContent, ownCommittedTailRef, emitCommitted } = runClockAndContent({ spec, prepared, queue, internals, rs, ident, parentToolCallId, startedToolCallIds });
|
|
426
|
+
const toolProgress = createToolProgressLane(pushContent, ident);
|
|
427
|
+
prepared.toolProgressRef.current = toolProgress;
|
|
416
428
|
const { subagentName, withBrainSinks } = runBrainSinks({ queue, internals, rs, ident, parentToolCallId, observeReasoningWireFacts });
|
|
417
429
|
const toolLabels = new Map(prepared.tools.flatMap((t) => (t.label !== undefined && t.label !== t.name ? [[t.name, t.label]] : [])));
|
|
418
430
|
for (const orphan of prepared.wakeRecovered) {
|
|
@@ -426,7 +438,7 @@ export class Runner {
|
|
|
426
438
|
prepared, stats, rs,
|
|
427
439
|
deps: {
|
|
428
440
|
spec, queue, internals, ident, parentToolCallId, subagentName,
|
|
429
|
-
pushContent, emitCommitted, startedToolCallIds, toolStartAt, writeFamilyOf,
|
|
441
|
+
pushContent, emitCommitted, startedToolCallIds, toolStartAt, toolProgress, writeFamilyOf,
|
|
430
442
|
toolLabels, postToolBatchHook, batchArgs,
|
|
431
443
|
runnerHooks: { onError: (e, info) => this.deps.onError?.(e, info) },
|
|
432
444
|
},
|
|
@@ -453,7 +465,7 @@ export class Runner {
|
|
|
453
465
|
});
|
|
454
466
|
const { flushGitMirror, unsubGitRetry, unsubBoundary, unsub } = runGitLane({ prepared, queue, rs, ident, onMessageUpdate, onMessageEnd, onToolStart, onToolEnd, onTurnEnd, onTurnBoundary, runner: this.depsSeat });
|
|
455
467
|
return runLeg({
|
|
456
|
-
spec, queue, prepared, resume, rs, entryActor, effectiveTimeoutMs, timeout, pushContent, ident, emitCommitted, writeFamilyOf, startedToolCallIds,
|
|
468
|
+
spec, queue, prepared, resume, rs, isDelegatedChild: internals?.isDelegatedChild === true, entryActor, effectiveTimeoutMs, timeout, pushContent, ident, emitCommitted, writeFamilyOf, startedToolCallIds,
|
|
457
469
|
announceWorkspaceMove, withBrainSinks, flushGitMirror, loopLatch, notificationLane, unsubscribeTaskNotifications, unsubGitRetry, unsubBoundary, unsub,
|
|
458
470
|
runner: this.depsSeat,
|
|
459
471
|
next: ({ final, threw, abortedLive, userInterruptedLive, strandedHumanAnswers }) => runTerminalAdoption({
|