@sema-agent/core 7.19.0 → 7.20.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 +183 -2
- package/dist/agents/subagent.js +12 -20
- package/dist/agents/teacher.js +2 -5
- package/dist/agents/verify.js +21 -10
- package/dist/brain/anthropic.js +3 -1
- package/dist/brain/open-responses.js +4 -2
- package/dist/brain/openai.js +3 -1
- package/dist/brain/stream-engine.d.ts +4 -0
- package/dist/brain/stream-engine.js +4 -0
- package/dist/core/auto-mode.d.ts +37 -18
- package/dist/core/auto-mode.js +1 -1
- package/dist/core/child-clamp-seats.d.ts +79 -0
- package/dist/core/child-clamp-seats.js +29 -0
- package/dist/core/engine-notice.d.ts +67 -49
- package/dist/core/fs-write-gate-policy.d.ts +17 -9
- package/dist/core/fs-write-gate-policy.js +51 -4
- package/dist/core/gate-bounded-await.d.ts +38 -0
- package/dist/core/gate-bounded-await.js +53 -0
- package/dist/core/gate-fold.js +16 -48
- package/dist/core/gate-lanes.js +11 -3
- package/dist/core/gate-outcome.d.ts +9 -6
- package/dist/core/governance-codes.d.ts +16 -1
- package/dist/core/governance-codes.js +12 -0
- package/dist/core/hooks.d.ts +8 -8
- package/dist/core/memory-engine/engine.d.ts +14 -9
- package/dist/core/memory-engine/engine.js +21 -8
- package/dist/core/memory-engine/layout.d.ts +31 -0
- package/dist/core/memory-engine/layout.js +68 -3
- package/dist/core/memory-engine/types.d.ts +24 -0
- package/dist/core/memory.d.ts +19 -0
- package/dist/core/memory.js +12 -0
- package/dist/core/remote-env.d.ts +32 -0
- package/dist/core/remote-env.js +4 -1
- package/dist/core/runner/advertised-writable-dirs.d.ts +59 -1
- package/dist/core/runner/advertised-writable-dirs.js +51 -3
- package/dist/core/runner/announce-once-ledger.d.ts +15 -0
- package/dist/core/runner/announce-once-ledger.js +8 -0
- package/dist/core/runner/classifier-ladder.d.ts +5 -0
- package/dist/core/runner/classifier-ladder.js +13 -2
- package/dist/core/runner/contracts.d.ts +44 -1
- package/dist/core/runner/denial-limit-arms.d.ts +14 -1
- package/dist/core/runner/denial-limit-arms.js +5 -4
- package/dist/core/runner/env-capability-census.d.ts +30 -0
- package/dist/core/runner/env-capability-census.js +38 -0
- package/dist/core/runner/forward-sink.d.ts +32 -0
- package/dist/core/runner/forward-sink.js +41 -0
- package/dist/core/runner/gate-exit.d.ts +4 -0
- package/dist/core/runner/gate-exit.js +4 -1
- package/dist/core/runner/git-status-frame.d.ts +0 -9
- package/dist/core/runner/listing-fold.d.ts +57 -0
- package/dist/core/runner/listing-fold.js +75 -0
- package/dist/core/runner/prepare-execution-env.d.ts +1 -1
- package/dist/core/runner/prepare-execution-env.js +2 -0
- package/dist/core/runner/prepare-gate-stations.d.ts +8 -0
- package/dist/core/runner/prepare-gate-stations.js +6 -2
- package/dist/core/runner/prepare-hands-readface.d.ts +4 -0
- package/dist/core/runner/prepare-hands-readface.js +3 -5
- package/dist/core/runner/prepare-listings.d.ts +3 -0
- package/dist/core/runner/prepare-listings.js +4 -2
- package/dist/core/runner/prepare-memory.js +7 -1
- package/dist/core/runner/prepare-policy-chain.js +5 -5
- package/dist/core/runner/prepare-prompt-inputs.d.ts +2 -2
- package/dist/core/runner/prepare-run-refs.d.ts +4 -2
- package/dist/core/runner/prepare-run-refs.js +5 -4
- package/dist/core/runner/prepare-task.js +7 -5
- package/dist/core/runner/run-clock-and-content.js +3 -7
- package/dist/core/runner/run-harness-handlers.js +10 -10
- package/dist/core/runner/run-leg.js +28 -19
- package/dist/core/runner/run-settle-and-teardown.js +2 -5
- package/dist/core/runner/run-turn-boundary.js +44 -33
- package/dist/core/runner/runtask.js +2 -1
- package/dist/core/runner/synthetic-tools.d.ts +13 -39
- package/dist/core/runner/synthetic-tools.js +15 -59
- package/dist/core/runner/task-root-canonical.d.ts +45 -0
- package/dist/core/runner/task-root-canonical.js +18 -0
- package/dist/core/runner/turn-attachments.d.ts +125 -49
- package/dist/core/runner/turn-attachments.js +124 -66
- package/dist/core/safe-notify.d.ts +5 -0
- package/dist/core/safe-notify.js +24 -2
- package/dist/core/sensitive-path-policy.d.ts +53 -27
- package/dist/core/sensitive-path-policy.js +16 -26
- package/dist/core/skill-listing-budget.d.ts +34 -40
- package/dist/core/skill-listing-budget.js +25 -26
- package/dist/core/skills-directory.js +17 -10
- package/dist/core/task-registry.js +2 -1
- package/dist/core/task-spec.d.ts +8 -7
- package/dist/core/tool-policy.d.ts +12 -1
- package/dist/core/tool-policy.js +39 -25
- package/dist/core/write-protect.d.ts +98 -18
- package/dist/core/write-protect.js +88 -34
- package/dist/index.d.ts +6 -5
- package/dist/index.js +5 -4
- package/dist/orchestration/workflow-primitives.js +10 -20
- package/dist/stores/file/memory-store.d.ts +5 -2
- package/dist/stores/file/memory-store.js +8 -4
- package/dist/tools/fs/bash-readonly-classifier.d.ts +13 -2
- package/dist/tools/fs/bash-readonly-classifier.js +317 -35
- package/dist/tools/fs/fs-bash.d.ts +1 -1
- package/dist/tools/fs/fs-bash.js +12 -25
- package/dist/tools/fs/fs-shared.d.ts +22 -0
- package/dist/tools/fs/fs-shared.js +30 -0
- package/dist/tools/fs/index.d.ts +1 -1
- package/dist/tools/fs/index.js +1 -1
- package/package.json +2 -1
- package/test/export-surface.snapshot.json +19 -3
- package/wire-changes/core@7.20.0.json +568 -0
|
@@ -303,9 +303,9 @@ export async function preparePolicyChain(input) {
|
|
|
303
303
|
}
|
|
304
304
|
if (re.updatedInput !== undefined)
|
|
305
305
|
editArgs = re.updatedInput;
|
|
306
|
-
const judged = await judgeInheritedClassifier({ autoMode: ancestorDecider !== undefined ? { decider: ancestorDecider, denialTracking: ancestorTracker } : undefined, ask: re, req: { ...creq, args: editArgs }, signal: csignal ?? abortController.signal, subject: "the approved edit" });
|
|
306
|
+
const judged = await judgeInheritedClassifier({ autoMode: ancestorDecider !== undefined ? { decider: ancestorDecider, denialTracking: ancestorTracker } : undefined, ask: re, req: { ...creq, args: editArgs }, signal: csignal ?? abortController.signal, subject: "the approved edit", allowRewrite: editArgs });
|
|
307
307
|
if (judged.kind === "allow")
|
|
308
|
-
return
|
|
308
|
+
return judged.result;
|
|
309
309
|
if (judged.kind === "deny")
|
|
310
310
|
return judged.result;
|
|
311
311
|
const { ask: editAsk, fallback: editFallback, mintedHere: editMintedHere } = judged;
|
|
@@ -371,7 +371,7 @@ export async function preparePolicyChain(input) {
|
|
|
371
371
|
}
|
|
372
372
|
const judged = await judgeInheritedClassifier({ autoMode: pc.autoMode, ask: first, req: creq, signal: csignal ?? abortController.signal, subject: "this call" });
|
|
373
373
|
if (judged.kind === "allow")
|
|
374
|
-
return
|
|
374
|
+
return judged.result;
|
|
375
375
|
if (judged.kind === "deny")
|
|
376
376
|
return judged.result;
|
|
377
377
|
const { ask: inheritedAsk, fallback, mintedHere } = judged;
|
|
@@ -439,9 +439,9 @@ export async function preparePolicyChain(input) {
|
|
|
439
439
|
return mandateUnreconstructibleDeny(creq);
|
|
440
440
|
}
|
|
441
441
|
const presentedArgs = decision.updatedInput !== undefined ? decision.updatedInput : creq.args;
|
|
442
|
-
const judged = await judgeInheritedClassifier({ autoMode: pc.autoMode, ask: decision, req: { ...creq, args: presentedArgs }, signal: csignal ?? abortController.signal, subject: "this call" });
|
|
442
|
+
const judged = await judgeInheritedClassifier({ autoMode: pc.autoMode, ask: decision, req: { ...creq, args: presentedArgs }, signal: csignal ?? abortController.signal, subject: "this call", allowRewrite: decision.updatedInput });
|
|
443
443
|
if (judged.kind === "allow")
|
|
444
|
-
return
|
|
444
|
+
return judged.result;
|
|
445
445
|
if (judged.kind === "deny")
|
|
446
446
|
return judged.result;
|
|
447
447
|
const { ask: inheritedAsk, fallback, mintedHere } = judged;
|
|
@@ -117,8 +117,8 @@ export interface PreparePromptInputsResult {
|
|
|
117
117
|
tzValid: boolean;
|
|
118
118
|
/** owned — the client's declared zone as given (paired with `tzValid`; unvalidated on its own). */
|
|
119
119
|
userTz: string | undefined;
|
|
120
|
-
/** owned — the git-status lane's run-local state (empty on a hands-less leg); the run loop and the
|
|
121
|
-
*
|
|
120
|
+
/** owned — the git-status lane's run-local state (empty on a hands-less leg); the run loop and the checkpoint
|
|
121
|
+
* serializer mutate its fields from here on (`announced`, `mirrorOwed`, …; the frame's receipt rides the leg's shared `Prepared.frameReceipts`). */
|
|
122
122
|
gitStatusRef: GitStatusLaneRef;
|
|
123
123
|
}
|
|
124
124
|
/** The M10 phase body — prepareTask's prompt-inputs stretch, verbatim (see the module header). */
|
|
@@ -28,8 +28,10 @@ export interface PrepareRunRefsInput {
|
|
|
28
28
|
* worktree helper). Never mutated. */
|
|
29
29
|
spec: Pick<TaskSpec, "forwardSubagentEvents" | "retainSubagentSessions" | "handsReadOnly">;
|
|
30
30
|
/** borrowed-readonly — the trusted spawn-side channel; only `onForwardEvent` (the deployment's display
|
|
31
|
-
* sink) is read,
|
|
32
|
-
|
|
31
|
+
* sink) is read, to decide whether a forwarding wrapper exists at all, and `forwardScope` (the run's
|
|
32
|
+
* forwarding containment, read by the door). The OBJECT is what the wrapper hands the door rather than
|
|
33
|
+
* the pulled-out function: the sink keeps its receiver and the run keeps one failure count. */
|
|
34
|
+
internals: Pick<RunInternals, "onForwardEvent" | "forwardScope"> | undefined;
|
|
33
35
|
/** borrowed-readonly — the run's resolved env; the worktree helper closes over it (lazy: no I/O until a
|
|
34
36
|
* delegation actually mints a worktree). */
|
|
35
37
|
executionEnv: ExecutionEnv;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createSubagentWorktreeHelper } from "../../agents/subagent.js";
|
|
2
2
|
import { SubagentRetainLedger } from "../../agents/retain-ledger.js";
|
|
3
3
|
import { ActiveSkillScope } from "./active-skill-scope.js";
|
|
4
|
+
import { forwardSafely } from "./forward-sink.js";
|
|
4
5
|
import { createEditedFilesLedger } from "./edited-files-ledger.js";
|
|
5
6
|
export function forwardsSubagentEvents(spec) {
|
|
6
7
|
return spec.forwardSubagentEvents === true;
|
|
@@ -14,14 +15,14 @@ export function prepareRunRefs(input) {
|
|
|
14
15
|
const harnessRef = {};
|
|
15
16
|
const toolProgressRef = {};
|
|
16
17
|
const skillScope = new ActiveSkillScope();
|
|
17
|
-
const
|
|
18
|
-
const forwardEvent =
|
|
18
|
+
const sinkWired = internals?.onForwardEvent !== undefined;
|
|
19
|
+
const forwardEvent = sinkWired
|
|
19
20
|
? (e) => {
|
|
20
21
|
if (e.type === "task_progress")
|
|
21
|
-
|
|
22
|
+
forwardSafely(internals, e);
|
|
22
23
|
else if (spec.forwardSubagentEvents === true &&
|
|
23
24
|
(e.type === "text_delta" || e.type === "text_end" || e.type === "reasoning_delta" || e.type === "tool_start" || e.type === "tool_progress" || e.type === "tool_end")) {
|
|
24
|
-
|
|
25
|
+
forwardSafely(internals, e);
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
: undefined;
|
|
@@ -78,6 +78,7 @@ import { ToolRosterDeltaSeat } from "../tool-roster.js";
|
|
|
78
78
|
import { faceOf } from "../tool-roster.js";
|
|
79
79
|
import { catalogEntriesNamed, pathTargetOf } from "../tool-registry.js";
|
|
80
80
|
import { AdvertisedWritableDirs } from "./advertised-writable-dirs.js";
|
|
81
|
+
import { resolveTaskRootCanonical } from "./task-root-canonical.js";
|
|
81
82
|
import { createStructuredProjector } from "./tool-output-projection.js";
|
|
82
83
|
function warnCompactionWindowHazard(tracer, spec, model, compModel, hostTaskId) {
|
|
83
84
|
if (compModel === undefined)
|
|
@@ -365,6 +366,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
365
366
|
}
|
|
366
367
|
const ownedEnv = ownedEnvSeat.current;
|
|
367
368
|
const { taskRootFinal, rebaseRestoredPath } = await prepareWorkspaceRestore({ ownedEnv, deps, spec, internals, resume, taskRootInitial, abortController, sessionId });
|
|
369
|
+
const { canonical: taskRootCanonical } = await resolveTaskRootCanonical({ env: executionEnv, given: taskRootFinal, onNotice: deps.onNotice, sessionId, runId });
|
|
368
370
|
const { trackFileEdit, fileHistoryBoundary, restoredFilePaths, rewindNotes, fileHistoryEnabled, historyScope, historyRoot, historyFs } = await prepareFileHistory({ deps, spec, internals, executionEnv, taskRootFinal, handsEnabled, sessionId, session, resumeAtBeforeParentId, abortController });
|
|
369
371
|
const { noteFileEdited, editedFilesSnapshot, harnessRef, toolProgressRef, skillScope, forwardEvent, reviewRequestRef, requestReview, stopRequestedRef, requestStopAfterTurn, planModeRef, enterPlanMode, subagentRetain, worktreeIsolation } = prepareRunRefs({ spec, internals, executionEnv, taskRootFinal });
|
|
370
372
|
let resolvedReadFace;
|
|
@@ -438,7 +440,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
438
440
|
const callIssuedAtRef = {};
|
|
439
441
|
const workCutRef = { continuation: false, abortedBeforeTurnEnd: false };
|
|
440
442
|
const advertisedWritableDirs = handsEnabled
|
|
441
|
-
? new AdvertisedWritableDirs(executionEnv, (dir, reason) => deps.onError?.(new Error(`${dir.advertiser} advertised writable directory skipped
|
|
443
|
+
? new AdvertisedWritableDirs(executionEnv, (dir, reason) => deps.onError?.(new Error(`${dir.advertiser} advertised writable directory skipped: ${dir.path} — ${reason}`), { phase: "config", sessionId }), taskRootCanonical, [...(spec.additionalDirectories ?? []), ...(spec.additionalReadDirectories ?? [])])
|
|
442
444
|
: undefined;
|
|
443
445
|
const handsWriteHalfPlanned = handsEnabled && handsWriteHalfMounts({ readOnly: spec.handsReadOnly === true });
|
|
444
446
|
const memoryPairNameDomain = new Set();
|
|
@@ -508,7 +510,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
508
510
|
if (internals?.ownOrgAdmissionRef !== undefined && ownOrgVerdictRef.current !== undefined) {
|
|
509
511
|
internals.ownOrgAdmissionRef.current = ownOrgVerdictRef.current;
|
|
510
512
|
}
|
|
511
|
-
const handsReadFaceInput = { handsEnabled, executionEnv, taskRootFinal, rebaseRestoredPath, resume, session, sessionId, hostTaskId, taskScope, fullShellReachable, effectiveShellGate, toolFaceSnapshot, model, spec, deps, internals, memoryWriteGate, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), firstPartyOffload, roster, egressTools, irreversibilityTier, irreversibleTools, reversibilityProbes, reminderMark, reminderDisclosureCounts, ...(trackFileEdit !== undefined ? { trackFileEdit } : {}), onFileEdited: noteFileEdited, harnessRef, toolProgressRef, ...(restoredFilePaths.length > 0 ? { restoredFilePaths } : {}) };
|
|
513
|
+
const handsReadFaceInput = { handsEnabled, executionEnv, taskRootFinal, taskRootCanonical, rebaseRestoredPath, resume, session, sessionId, hostTaskId, taskScope, fullShellReachable, effectiveShellGate, toolFaceSnapshot, model, spec, deps, internals, memoryWriteGate, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), firstPartyOffload, roster, egressTools, irreversibilityTier, irreversibleTools, reversibilityProbes, reminderMark, reminderDisclosureCounts, ...(trackFileEdit !== undefined ? { trackFileEdit } : {}), onFileEdited: noteFileEdited, harnessRef, toolProgressRef, ...(restoredFilePaths.length > 0 ? { restoredFilePaths } : {}) };
|
|
512
514
|
const handsReadFace = handsEnabled ? await prepareHandsMount(handsReadFaceInput) : resolveHandsLessReadFace(handsReadFaceInput);
|
|
513
515
|
const { readFileStateForCheckpoint, seedContextFiles, handsCwdRef, workspaceStateSettle, wsSnapshot, rebaseWsPath, backgroundTaskToolsActive, additionalRootsCanonical, additionalReadRootsCanonical, attachmentRootCanonical, readDenyMatcher, envHandToolNames, sealReadStateSeat } = handsReadFace;
|
|
514
516
|
resolvedReadFace = handsReadFace.resolvedReadFace;
|
|
@@ -590,7 +592,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
590
592
|
declaredCards: toolRoster.entries.flatMap((e) => e.renderHints?.resultCards ?? []),
|
|
591
593
|
onUndeclared: (type) => deliverEngineNotice(deps.onNotice, { code: "config.tool_card_undeclared", message: `a tool minted a \`details.type\` card ${JSON.stringify(type)} its definition never declared — dropped from tool_end.structured (declare it on the definition's catalog row or the caller's renderHints.resultCards)`, detail: { type, sessionId, runId } }),
|
|
592
594
|
});
|
|
593
|
-
const { agentListing, announcedListingsRef, dateChange } = prepareListings({ spec, tools, onceLedger, sessionId, toolFaceSnapshot, activeTools, resume, skillsListing, listingRideRef, renderWithDate, envFacts, tzValid, userTz });
|
|
595
|
+
const { agentListing, announcedListingsRef, dateChange } = prepareListings({ spec, tools, onceLedger, sessionId, toolFaceSnapshot, activeTools, resume, skillsListing, listingBudget: doors.skillListingBudget, listingRideRef, renderWithDate, envFacts, tzValid, userTz });
|
|
594
596
|
const lastBrainContextRef = {};
|
|
595
597
|
const requestLossyRef = { current: false };
|
|
596
598
|
const staleOffloadWrittenRefs = new Set();
|
|
@@ -699,12 +701,12 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
699
701
|
const { saga } = prepareSuspendSaga({ gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, writeFaceCheckpointSection, reminderMark, handsCwdRef, worktreeSessionRef, undeliveredContinuationRef, inheritedParentConstraints, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, autoModeIntent, inheritedAdmittedOrgScopes, ownOrgVerdictRef, orgGovernedProvenance, announcedListingsRef, gitStatusRef, hookIdentity, placementRootResolved, externalContentTargetActive, remoteEnvFailures, memoryEngineSession, suspendLoopRef, ownedEnv, incompleteSuspendAdapter });
|
|
700
702
|
const { suspendForResource, suspendForPlatformLimit, suspendForReview } = prepareBoundaryParks({ saga, spec, checkpointStore, abortController, harness, session, sessions, sessionId, deps, priorLedger, maxSlices, maxSuspends, resourceTotal, priorSuspendCount, suspendChainBase, humanReviewRef, liveSpendRef, now, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, pausedRef, remoteEnvFailures, resourceSuspendEligible, durableSuspendInfraReady, incompleteSuspendAdapter });
|
|
701
703
|
const { parkAsk } = prepareParkAsk({ askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas: rosterSeat, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, now, humanReviewRef, abortController, harness, pausedRef });
|
|
702
|
-
prepareGateStations({ askLane, parkAsk, tools, toolRosterDeltas: rosterSeat, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, gateOutcomes, batchHaltRef, blockedTracked, hookIdentity, reminderMark, planModeRef, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, hookEnvFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash });
|
|
704
|
+
prepareGateStations({ askLane, parkAsk, tools, toolRosterDeltas: rosterSeat, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, gateOutcomes, batchHaltRef, blockedTracked, hookIdentity, reminderMark, planModeRef, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, hookEnvFace, handsEnv: handsEnabled ? executionEnv : undefined, taskRootFinal, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash });
|
|
703
705
|
const { microCompact, charsPerToken } = prepareContextLane({ model, deps, sessionId, runId, hostTaskId, offloadStore, microCompactKnob, harness, batchHaltRef, gitStatusRef, requestLossyRef, trimPressureRef });
|
|
704
706
|
const preparedHolder = {};
|
|
705
707
|
const { cacheBreakDetector, cacheFingerprint, promptOverheadTokens, readTaskFile, normalizeAttachmentPath, isDedupStubResult, recentlyReadFiles, onCompactionApplied, detectExternalChanges, listBackgroundTasks, centerCompactionCandidate, effectiveReadFaceObserved, effectiveWriteFaceObserved, effectiveReadDenyObserved } = prepareTurnWiring({ deps, systemPromptSeat, harnessTools, fpRef, model, epochArtifactDigestForSnapshot, promptProfile, fableMitigations, systemBlocks, thinking, spec, sessionId, turnSnapshotRef, promptManifest, charsPerToken, handsEnabled, executionEnv, attachmentRootCanonical, additionalRootsCanonical, additionalReadRootsCanonical, readDenyMatcher, resolvedReadFace, handsCwdRef, readFileStateForCheckpoint, denyNarrowingPolicy, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder });
|
|
706
708
|
await onceLedger.settle(session, announcedListingsRef);
|
|
707
|
-
const buildPrepared = () => ({ harness, session, sessionId, runId, reminderMark, reminderDisclosureCounts, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, gateOutcomes, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved, effectiveWriteFace: effectiveWriteFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, ...(permissionRuleLane !== undefined ? { persistedRuleLane: permissionRuleLane } : {}), ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, pausedRef, undeliveredContinuationRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, workCutRef, brainCallGuardrailRef, gateStopRef, suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolRoster, toolRosterDeltas: rosterSeat, structuredProjector, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, gitStatusRef, listBackgroundTasks, hookIdentity, hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}), ...(toolDisclosureSeat !== undefined ? { toolDisclosure: toolDisclosureSeat } : {}) });
|
|
709
|
+
const buildPrepared = () => ({ harness, session, sessionId, runId, reminderMark, reminderDisclosureCounts, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, gateOutcomes, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved, effectiveWriteFace: effectiveWriteFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, ...(permissionRuleLane !== undefined ? { persistedRuleLane: permissionRuleLane } : {}), ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, pausedRef, undeliveredContinuationRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, workCutRef, brainCallGuardrailRef, gateStopRef, suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolRoster, toolRosterDeltas: rosterSeat, structuredProjector, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, frameReceipts: { pending: [], listingSnapshotOwed: false }, gitStatusRef, listBackgroundTasks, hookIdentity, hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}), ...(toolDisclosureSeat !== undefined ? { toolDisclosure: toolDisclosureSeat } : {}) });
|
|
708
710
|
rollback.commit();
|
|
709
711
|
const prepared = buildPrepared();
|
|
710
712
|
preparedHolder.current = prepared;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { startTimeout } from "./clock-and-limits.js";
|
|
2
|
+
import { forwardSafely } from "./forward-sink.js";
|
|
2
3
|
export function runClockAndContent(input) {
|
|
3
4
|
const { spec, prepared, queue, internals, rs, ident, parentToolCallId, startedToolCallIds } = input;
|
|
4
5
|
const effectiveTimeoutMs = spec.limits?.maxWalltimeMs;
|
|
@@ -7,13 +8,8 @@ export function runClockAndContent(input) {
|
|
|
7
8
|
const timeout = startTimeout(prepared.harness, prepared.abortController, walltimeMonotonicDeadline !== undefined ? walltimeMonotonicDeadline - performance.now() : undefined, prepared.suspendForResource !== undefined);
|
|
8
9
|
const pushContent = (e) => {
|
|
9
10
|
queue.push(e);
|
|
10
|
-
if (parentToolCallId !== undefined
|
|
11
|
-
|
|
12
|
-
internals.onForwardEvent(e);
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
}
|
|
16
|
-
}
|
|
11
|
+
if (parentToolCallId !== undefined)
|
|
12
|
+
forwardSafely(internals, e);
|
|
17
13
|
};
|
|
18
14
|
const ownCommittedTailRef = { current: undefined };
|
|
19
15
|
const emitCommitted = (entryId, role, toolCallId) => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createSafeNotifier, observeThenableRejection } from "../safe-notify.js";
|
|
2
|
+
import { forwardSafely } from "./forward-sink.js";
|
|
2
3
|
import { emitTrace } from "../trace.js";
|
|
3
4
|
import { primaryActivityArg } from "../arg-summary.js";
|
|
4
5
|
import { readDegradation } from "../../brain/degrading.js";
|
|
@@ -58,17 +59,20 @@ export function createHarnessHandlers(input) {
|
|
|
58
59
|
}
|
|
59
60
|
if (event.entryId !== undefined && m.role === "user")
|
|
60
61
|
prepared.fileHistoryBoundary?.begin(event.entryId);
|
|
61
|
-
if (event.entryId !== undefined && m.role === "user" && prepared.
|
|
62
|
-
const pr = prepared.gitStatusRef.pendingReceipt;
|
|
62
|
+
if (event.entryId !== undefined && m.role === "user" && prepared.frameReceipts.pending.length > 0) {
|
|
63
63
|
const c = m.content;
|
|
64
64
|
const text = typeof c === "string"
|
|
65
65
|
? c
|
|
66
66
|
: Array.isArray(c) && c.length >= 1 && c[0].type === "text"
|
|
67
67
|
? c[0].text
|
|
68
68
|
: undefined;
|
|
69
|
-
if (text
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
if (text !== undefined) {
|
|
70
|
+
const settled = prepared.frameReceipts.pending.filter((r) => r.text === text);
|
|
71
|
+
if (settled.length > 0) {
|
|
72
|
+
prepared.frameReceipts.pending = prepared.frameReceipts.pending.filter((r) => r.text !== text);
|
|
73
|
+
for (const r of settled)
|
|
74
|
+
r.commit(event.entryId);
|
|
75
|
+
}
|
|
72
76
|
}
|
|
73
77
|
}
|
|
74
78
|
if (rs.degrade.degraded === undefined && m.role === "assistant") {
|
|
@@ -309,11 +313,7 @@ export function createHarnessHandlers(input) {
|
|
|
309
313
|
...ident(),
|
|
310
314
|
};
|
|
311
315
|
queue.push(progress);
|
|
312
|
-
|
|
313
|
-
internals?.onForwardEvent?.(progress);
|
|
314
|
-
}
|
|
315
|
-
catch {
|
|
316
|
-
}
|
|
316
|
+
forwardSafely(internals, progress);
|
|
317
317
|
}
|
|
318
318
|
emitTrace(rs.telemetry.tracer, () => ({ kind: "turn.end", version: 1, taskId: rs.telemetry.taskId, turn: stats.turns, ts: Date.now() }));
|
|
319
319
|
rs.turn.turnUsage = undefined;
|
|
@@ -26,8 +26,9 @@ import { maybeHumanRejectionHalt } from "./prepare-gate-stations.js";
|
|
|
26
26
|
import { nextHumanInputSeq } from "./steer-admission.js";
|
|
27
27
|
import { settleTeardownLeg } from "./teardown-bounded.js";
|
|
28
28
|
import { toolEndBodyFrom, toolResultMsg } from "./tool-end-body.js";
|
|
29
|
-
import {
|
|
30
|
-
import { attachmentEnvelopeTags, commitAgentListing, commitSkillsListing, reduceToolEnd,
|
|
29
|
+
import { announceListingTruncation } from "../skill-listing-budget.js";
|
|
30
|
+
import { attachmentEnvelopeTags, commitAgentListing, commitSkillsListing, reduceToolEnd, renderAgentListingFrame, renderOrphanedBackgroundTasks, renderSkillsListingFrame, stampWriteAnchor } from "./turn-attachments.js";
|
|
31
|
+
import { flushOwedAnnouncedSnapshot } from "./announce-once-ledger.js";
|
|
31
32
|
export async function runLeg(input) {
|
|
32
33
|
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;
|
|
33
34
|
let final;
|
|
@@ -234,7 +235,8 @@ export async function runLeg(input) {
|
|
|
234
235
|
if (gitResumeDelivered !== undefined) {
|
|
235
236
|
const delivered = gitResumeDelivered;
|
|
236
237
|
prepared.gitStatusRef.protectedText = delivered.wrapped;
|
|
237
|
-
prepared.
|
|
238
|
+
prepared.frameReceipts.pending.push({
|
|
239
|
+
source: "git_status",
|
|
238
240
|
text: continuation,
|
|
239
241
|
commit: (entryId) => {
|
|
240
242
|
prepared.gitStatusRef.announced = { kind: delivered.kind, hash: delivered.hash, entryId };
|
|
@@ -242,7 +244,7 @@ export async function runLeg(input) {
|
|
|
242
244
|
rs.attach.attachmentsInjected += 1;
|
|
243
245
|
prepared.gitStatusRef.mirrorOwed = { kind: delivered.kind, hash: delivered.hash, entryId };
|
|
244
246
|
},
|
|
245
|
-
};
|
|
247
|
+
});
|
|
246
248
|
}
|
|
247
249
|
const pending = resume.cp.pendingAction;
|
|
248
250
|
const rejectionHalt = pending.kind === "tool_approval" && resume.outcome.gate === "policy_ask"
|
|
@@ -332,22 +334,22 @@ export async function runLeg(input) {
|
|
|
332
334
|
}
|
|
333
335
|
}
|
|
334
336
|
const firstFrames = [];
|
|
335
|
-
let skillsListingCost;
|
|
336
337
|
if (rs.attach.attachState !== undefined) {
|
|
337
338
|
const attach = rs.attach.attachState;
|
|
338
339
|
if (rs.attach.agentListingOn && prepared.agentListing !== undefined) {
|
|
339
340
|
const listing = prepared.agentListing;
|
|
340
|
-
const
|
|
341
|
-
if (
|
|
341
|
+
const frame = renderAgentListingFrame(attach, listing.entries, listing.toolName, listing.models, listing.budget);
|
|
342
|
+
if (frame !== undefined) {
|
|
342
343
|
firstFrames.push({
|
|
343
344
|
source: "agent_listing",
|
|
344
|
-
body,
|
|
345
|
+
body: frame.text,
|
|
345
346
|
commit: () => {
|
|
346
347
|
commitAgentListing(attach, listing.entries, listing.models);
|
|
347
348
|
prepared.announcedListingsRef.agents = listing.entries.map((e) => e.name);
|
|
348
349
|
if (listing.models !== undefined)
|
|
349
350
|
prepared.announcedListingsRef.models = [...listing.models];
|
|
350
351
|
},
|
|
352
|
+
disclose: () => announceListingTruncation(runner.deps.onNotice, { listing: "agents", total: frame.listed, nameOnly: frame.nameOnly, dropped: frame.dropped, budget: listing.budget, sessionId: prepared.sessionId }),
|
|
351
353
|
});
|
|
352
354
|
}
|
|
353
355
|
}
|
|
@@ -361,8 +363,8 @@ export async function runLeg(input) {
|
|
|
361
363
|
commit: () => {
|
|
362
364
|
commitSkillsListing(attach, listing.entries);
|
|
363
365
|
prepared.announcedListingsRef.skills = listing.entries.map((e) => e.name);
|
|
364
|
-
skillsListingCost = { total: frame.listed, nameOnly: frame.nameOnly, dropped: frame.dropped, budget: listing.budget };
|
|
365
366
|
},
|
|
367
|
+
disclose: () => announceListingTruncation(runner.deps.onNotice, { listing: "skills", total: frame.listed, nameOnly: frame.nameOnly, dropped: frame.dropped, budget: listing.budget, sessionId: prepared.sessionId }),
|
|
366
368
|
});
|
|
367
369
|
}
|
|
368
370
|
}
|
|
@@ -418,7 +420,8 @@ export async function runLeg(input) {
|
|
|
418
420
|
if (delivered.standalone)
|
|
419
421
|
await prepared.harness.nextTurn(delivered.wrapped, { engineMinted: true });
|
|
420
422
|
prepared.gitStatusRef.protectedText = delivered.wrapped;
|
|
421
|
-
prepared.
|
|
423
|
+
prepared.frameReceipts.pending.push({
|
|
424
|
+
source: "git_status",
|
|
422
425
|
text: delivered.standalone ? delivered.wrapped : effectiveObjective,
|
|
423
426
|
commit: (entryId) => {
|
|
424
427
|
prepared.gitStatusRef.announced = { kind: delivered.kind, hash: delivered.hash, entryId };
|
|
@@ -426,17 +429,20 @@ export async function runLeg(input) {
|
|
|
426
429
|
rs.attach.attachmentsInjected += 1;
|
|
427
430
|
prepared.gitStatusRef.mirrorOwed = { kind: delivered.kind, hash: delivered.hash, entryId };
|
|
428
431
|
},
|
|
429
|
-
};
|
|
432
|
+
});
|
|
430
433
|
}
|
|
431
434
|
for (const f of firstFrames) {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
435
|
+
prepared.frameReceipts.pending.push({
|
|
436
|
+
source: f.source,
|
|
437
|
+
text: effectiveObjective,
|
|
438
|
+
commit: () => {
|
|
439
|
+
f.commit();
|
|
440
|
+
queue.push({ type: "steering_injected", source: f.source, preview: redactThenCut(f.body, 220), ...ident() });
|
|
441
|
+
rs.attach.attachmentsInjected += 1;
|
|
442
|
+
prepared.frameReceipts.listingSnapshotOwed = true;
|
|
443
|
+
f.disclose();
|
|
444
|
+
},
|
|
445
|
+
});
|
|
440
446
|
}
|
|
441
447
|
const enginePrefixChars = effectiveObjective.length - projectedObjective.length;
|
|
442
448
|
queue.push({
|
|
@@ -481,6 +487,9 @@ export async function runLeg(input) {
|
|
|
481
487
|
timeout.clear();
|
|
482
488
|
prepared.lspDiagnostics?.registry.releaseRun(prepared.lspDiagnostics.runIdent);
|
|
483
489
|
prepared.toolProgressRef.current?.clear();
|
|
490
|
+
if (prepared.frameReceipts.listingSnapshotOwed) {
|
|
491
|
+
await settleTeardownLeg(() => flushOwedAnnouncedSnapshot(prepared), "announced-listing snapshot (leg exit)", (e) => runner.deps.onError?.(e, { phase: "degraded", sessionId: prepared.sessionId }));
|
|
492
|
+
}
|
|
484
493
|
prepared.abortController.abort();
|
|
485
494
|
prepared.releaseSignal();
|
|
486
495
|
strandedHumanAnswers = prepared.settleContentAskBindings();
|
|
@@ -12,6 +12,7 @@ import { emitTrace } from "../trace.js";
|
|
|
12
12
|
import { deliverEngineNotice } from "../types.js";
|
|
13
13
|
import { assembleResult } from "./assemble-result.js";
|
|
14
14
|
import { discloseUnconsumedHalt } from "./halt-attribution.js";
|
|
15
|
+
import { forwardSafely } from "./forward-sink.js";
|
|
15
16
|
import { TIMER_LATENESS_REPORT_MS } from "./clock-and-limits.js";
|
|
16
17
|
import { resumeDecisionWasNegative } from "./decide-continuation.js";
|
|
17
18
|
import { drainForwardedFramesBeforeDone, forwardsSubagentEvents } from "./prepare-run-refs.js";
|
|
@@ -276,11 +277,7 @@ export async function runSettleAndTeardown(input) {
|
|
|
276
277
|
...ident(),
|
|
277
278
|
};
|
|
278
279
|
queue.push(terminalTick);
|
|
279
|
-
|
|
280
|
-
internals?.onForwardEvent?.(terminalTick);
|
|
281
|
-
}
|
|
282
|
-
catch {
|
|
283
|
-
}
|
|
280
|
+
forwardSafely(internals, terminalTick);
|
|
284
281
|
}
|
|
285
282
|
if (manualCompactRef.waiters.length > 0) {
|
|
286
283
|
queue.push({ type: "compaction_outcome", outcome: "mooted", trigger: "manual", reason: "task_ending", ...ident() });
|
|
@@ -4,8 +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,
|
|
8
|
-
import {
|
|
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
|
+
import { announceListingTruncation } from "../skill-listing-budget.js";
|
|
9
9
|
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption } 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";
|
|
@@ -203,7 +203,7 @@ export function createTurnBoundary(input) {
|
|
|
203
203
|
}
|
|
204
204
|
let boundaryAttachmentBytes = 0;
|
|
205
205
|
let attachmentsPayload;
|
|
206
|
-
|
|
206
|
+
const listingCommits = [];
|
|
207
207
|
if ((rs.attach.dateState !== undefined ||
|
|
208
208
|
rs.attach.instrState !== undefined ||
|
|
209
209
|
rs.attach.sizeGuidelineState !== undefined ||
|
|
@@ -215,6 +215,7 @@ export function createTurnBoundary(input) {
|
|
|
215
215
|
!prepared.abortController.signal.aborted) {
|
|
216
216
|
const due = [];
|
|
217
217
|
if (rs.attach.attachState !== undefined) {
|
|
218
|
+
const attachState = rs.attach.attachState;
|
|
218
219
|
const changedFilesOn = Boolean(rs.attach.attachmentsCfg?.changedFiles);
|
|
219
220
|
let changed;
|
|
220
221
|
if (changedFilesOn && prepared.detectExternalChanges !== undefined) {
|
|
@@ -265,6 +266,10 @@ export function createTurnBoundary(input) {
|
|
|
265
266
|
const undiscoveredTools = toolSearchReminderOn
|
|
266
267
|
? [...prepared.deferredToolNames].filter((n) => !prepared.activeTools.has(n)).sort()
|
|
267
268
|
: undefined;
|
|
269
|
+
const receiptPending = (source) => prepared.frameReceipts.pending.some((r) => r.source === source);
|
|
270
|
+
const agentListingDue = rs.attach.agentListingOn && prepared.agentListing !== undefined && !receiptPending("agent_listing");
|
|
271
|
+
const skillsListingDue = rs.attach.skillsListingOn && prepared.skillsListing !== undefined && !receiptPending("skills_listing");
|
|
272
|
+
const listingBudget = prepared.skillsListing?.budget ?? prepared.agentListing?.budget;
|
|
268
273
|
due.push(...collectDueAttachments(rs.attach.attachState, {
|
|
269
274
|
turn: stats.turns,
|
|
270
275
|
cadenceTurn: rs.counters.cadenceTurns,
|
|
@@ -308,16 +313,15 @@ export function createTurnBoundary(input) {
|
|
|
308
313
|
? { readdedToolsSwappedUnderStatic: pendingReaddedTools.filter((n) => prepared.staticFaceFor?.(n) !== true) }
|
|
309
314
|
: {}),
|
|
310
315
|
...(mcpToolsDelta !== undefined ? { mcpToolsDelta } : {}),
|
|
311
|
-
...(
|
|
316
|
+
...(agentListingDue
|
|
312
317
|
? {
|
|
313
318
|
agentListing: prepared.agentListing.entries,
|
|
314
319
|
agentToolName: prepared.agentListing.toolName,
|
|
315
320
|
...(prepared.agentListing.models !== undefined ? { agentModels: prepared.agentListing.models } : {}),
|
|
316
321
|
}
|
|
317
322
|
: {}),
|
|
318
|
-
...(
|
|
319
|
-
|
|
320
|
-
: {}),
|
|
323
|
+
...(skillsListingDue ? { skillsListing: prepared.skillsListing.entries } : {}),
|
|
324
|
+
...(listingBudget !== undefined ? { listingBudget } : {}),
|
|
321
325
|
...(mcpAdds !== undefined || mcpRemovals !== undefined
|
|
322
326
|
? { mcpInstructions: { added: mcpAdds ?? [], removed: mcpRemovals ?? [] } }
|
|
323
327
|
: {}),
|
|
@@ -367,31 +371,36 @@ export function createTurnBoundary(input) {
|
|
|
367
371
|
announcedOnceDirty = true;
|
|
368
372
|
}
|
|
369
373
|
}
|
|
370
|
-
if (
|
|
374
|
+
if (agentListingDue && due.some((a) => a.source === "agent_listing")) {
|
|
371
375
|
const listing = prepared.agentListing;
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
prepared.announcedListingsRef.
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
376
|
+
const frame = renderAgentListingFrame(attachState, listing.entries, listing.toolName, listing.models, listing.budget);
|
|
377
|
+
listingCommits.push({
|
|
378
|
+
source: "agent_listing",
|
|
379
|
+
commit: () => {
|
|
380
|
+
commitAgentListing(attachState, listing.entries, listing.models);
|
|
381
|
+
prepared.announcedListingsRef.agents = listing.entries.map((e) => e.name);
|
|
382
|
+
if (listing.models !== undefined)
|
|
383
|
+
prepared.announcedListingsRef.models = [...listing.models];
|
|
384
|
+
prepared.frameReceipts.listingSnapshotOwed = true;
|
|
385
|
+
announceListingTruncation(deps.runner.deps.onNotice, { listing: "agents", total: frame.listed, nameOnly: frame.nameOnly, dropped: frame.dropped, budget: listing.budget, sessionId: prepared.sessionId });
|
|
386
|
+
},
|
|
387
|
+
});
|
|
381
388
|
}
|
|
382
|
-
if (
|
|
389
|
+
if (skillsListingDue && due.some((a) => a.source === "skills_listing")) {
|
|
383
390
|
const listing = prepared.skillsListing;
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
391
|
+
const frame = renderSkillsListingFrame(attachState, listing.entries, listing.budget);
|
|
392
|
+
listingCommits.push({
|
|
393
|
+
source: "skills_listing",
|
|
394
|
+
commit: () => {
|
|
395
|
+
commitSkillsListing(attachState, listing.entries);
|
|
396
|
+
prepared.announcedListingsRef.skills = listing.entries.map((e) => e.name);
|
|
397
|
+
prepared.frameReceipts.listingSnapshotOwed = true;
|
|
398
|
+
announceListingTruncation(deps.runner.deps.onNotice, { listing: "skills", total: frame.listed, nameOnly: frame.nameOnly, dropped: frame.dropped, budget: listing.budget, sessionId: prepared.sessionId });
|
|
399
|
+
},
|
|
400
|
+
});
|
|
392
401
|
}
|
|
393
|
-
if (announcedOnceDirty
|
|
394
|
-
|
|
402
|
+
if (announcedOnceDirty)
|
|
403
|
+
prepared.frameReceipts.listingSnapshotOwed = true;
|
|
395
404
|
}
|
|
396
405
|
if (rs.attach.dateState !== undefined && rs.turn.lastTurnHadToolCalls) {
|
|
397
406
|
const today = prepared.dateChange.today();
|
|
@@ -434,7 +443,8 @@ export function createTurnBoundary(input) {
|
|
|
434
443
|
if (due.length > 0) {
|
|
435
444
|
attachmentsPayload = due.map((a) => mintSystemReminder(sanitizeUntrustedText(a.body, attachmentEnvelopeTags(a.source)), prepared.reminderMark)).join("\n");
|
|
436
445
|
for (const a of due)
|
|
437
|
-
|
|
446
|
+
if (!isIntactSource(a.source))
|
|
447
|
+
boundaryAttachmentBytes += Buffer.byteLength(a.body, "utf8");
|
|
438
448
|
rs.attach.attachmentsInjected += due.length;
|
|
439
449
|
for (const a of due) {
|
|
440
450
|
queue.push({ type: "steering_injected", source: a.source, preview: redactThenCut(a.body, 220), ...ident() });
|
|
@@ -478,10 +488,11 @@ export function createTurnBoundary(input) {
|
|
|
478
488
|
}
|
|
479
489
|
if ((attachmentsPayload !== undefined || batchContextBlock !== undefined) && prepared.batchHaltRef.current === undefined) {
|
|
480
490
|
const payload = attachmentsPayload !== undefined && batchContextBlock !== undefined ? `${attachmentsPayload}\n${batchContextBlock}` : (attachmentsPayload ?? batchContextBlock);
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
491
|
+
for (const c of listingCommits)
|
|
492
|
+
prepared.frameReceipts.pending.push({ source: c.source, text: payload, commit: c.commit });
|
|
493
|
+
void prepared.harness.steer(payload, { engineMinted: true }).catch(() => {
|
|
494
|
+
prepared.frameReceipts.pending = prepared.frameReceipts.pending.filter((r) => r.text !== payload);
|
|
495
|
+
});
|
|
485
496
|
}
|
|
486
497
|
const forceManual = manualCompactRef.requested;
|
|
487
498
|
if ((!withinTaskCompaction && !forceManual) ||
|
|
@@ -50,6 +50,7 @@ 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
52
|
import { createToolProgressLane } from "./tool-progress-lane.js";
|
|
53
|
+
import { createForwardSinkScope } from "./forward-sink.js";
|
|
53
54
|
import { runBrainSinks } from "./run-brain-sinks.js";
|
|
54
55
|
import { runCompactionMachinery } from "./run-compaction-machinery.js";
|
|
55
56
|
import { runStopAndFinalVerify } from "./run-stop-and-final-verify.js";
|
|
@@ -344,7 +345,7 @@ export class Runner {
|
|
|
344
345
|
manualCompactRef,
|
|
345
346
|
taskIdRef,
|
|
346
347
|
resume,
|
|
347
|
-
internals: { ...(internals ?? {}), detachHub },
|
|
348
|
+
internals: { ...(internals ?? {}), detachHub, forwardScope: createForwardSinkScope(this.deps.onNotice) },
|
|
348
349
|
notifyRef,
|
|
349
350
|
captureOptOutRef,
|
|
350
351
|
entryActor,
|