UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

103 lines (102 loc) • 7.07 kB
/** * The run body's TERMINAL ADOPTION (R14), verbatim from `Runner.runLocked`, between the leg's finally and * the settle: the typed causes lifted over the leg's anonymous end (the brain-call guardrail's stall, the tool gate's own * stop, the platform lane's external cause — which alone overrides a real throw), the usage ledger's FINAL charge with its * slow-charge disclosure, the live-abort orphan reconcile and its synthetic `tool_end` frames, the held session-write * drain, the user-interruption marker, the durable park's carried caller input and the held agent_end account's settle, * the dropped post-compact announce disclosure, and the end-of-task compaction pass (`finish` — since S7 the lane's * own module-private function, verbatim from the Runner's private method: the pass has one caller, and a sibling file would be a * lane-to-lane reach, the S6 legs' reading). * * Async (six first-level awaits, the same awaits at the same positions). It ends by entering the settle lane (`next`) in * its LAST continuation — the settle's first read sits on the tick `finish` resolved on, as it did in the one-function * body — and returns what it returns. What crosses the boundary is exactly what the settle reads of this lane's work: the * ADOPTED cause (`threw`, possibly lifted here) and the compaction outcome (`comp`); the pause / interruption / reconcile * facts are consumed here. */ import type { AssistantMessage } from "../../internal/llm.js"; import type { Model } from "../../internal/llm.js"; import { type MaybeCompactOptions } from "../auto-compaction.js"; import type { SessionStore } from "../session.js"; import type { PushQueue } from "../push-queue.js"; import type { Brain, OwedUserInputAccount, TaskEvent, TaskSpec } from "../types.js"; import { type Stats } from "./assemble-result.js"; import type { EndOfTaskCompaction, Prepared, RunnerDepsSeat, RunState } from "./contracts.js"; export interface RunTerminalAdoptionInput<R> { /** borrowed-readonly — the task spec: the task id the account's notices name; `finish`'s first argument (the end-of-task pass below). */ spec: TaskSpec; /** borrowed-mutable — the run's event queue: the reconcile's synthetic `tool_end` frames and the end-of-task compaction's failure frame. */ queue: PushQueue<TaskEvent>; /** borrowed-mutable — the leg's prepared seat: the guardrail / gate-stop / paused refs are read, the usage ledger charged, the session * reconciled and the marker appended, the harness's parkable inputs read and dropped. */ prepared: Prepared; /** borrowed-readonly — the run's mutable state: the platform terminal, the limit flags, the attachment state and the telemetry seat. */ rs: RunState; /** borrowed-readonly — this leg's usage counters (the final charge's cumulative total). */ stats: Stats; /** borrowed-readonly — the run's event-identity mint (the synthetic `tool_end` frames, the compaction failure frame). */ ident: () => { eventId: string; parentToolCallId?: string; sourceTaskId?: string; }; /** borrowed-readonly — the `message_committed` mint (the reconcile's appended toolResults, the marker). */ emitCommitted: (entryId: string, role: "user" | "assistant" | "toolResult", toolCallId?: string) => void; /** borrowed-readonly — the observed tool-start ids the reconcile splits orphans by (EMPTIED by the reconcile's commit). */ startedToolCallIds: Set<string>; /** borrowed-readonly — the label map the synthetic `tool_end` frames carry. */ toolLabels: Map<string, string>; /** borrowed-readonly — the hard walltime timer: `fired` is one of the interruption facts. */ timeout: { readonly fired: boolean; }; /** borrowed-readonly — the compaction machinery's accounted brain (the end-of-task summary call is accounted too). */ compactionBrain: Brain; /** borrowed-readonly — the shared compaction breaker: an open breaker skips the end-of-task attempt. */ compactionBreaker: { readonly failures: number; }; /** borrowed-readonly — the window-safety builder the end-of-task lane shares with the boundary / PTL lanes. */ windowSafetyOptions: (mainModel: Model) => Pick<MaybeCompactOptions, "fallbackBudget" | "onWindowSafety">; /** borrowed-readonly — the held agent_end account, as the read face on the identity lane's Result. */ undrainedUserAtEnd: { readonly current: { steer: number; followUp: number; } | undefined; }; /** borrowed-readonly — did the run end with a person's steer / follow-up still pending (the identity lane's read face)? Folded * into the answer-settled verdict this lane evaluates once. */ userInputLostAtEnd: { readonly current: boolean; }; /** borrowed-readonly — the leg lane's final assistant message (its `stopReason` is one of the interruption facts). */ final: AssistantMessage | undefined; /** borrowed-readonly — what the leg threw (undefined on a clean end); this lane may LIFT a typed cause over it and hands the adopted value on. */ threw: unknown; /** borrowed-readonly — the live-abort flag the leg captured before its release-abort. */ abortedLive: boolean; /** borrowed-readonly — the leg's snapshot of `loopLatch.userInterrupted` (gates the interruption marker). */ userInterruptedLive: boolean; /** borrowed-readonly — the Runner's deployment deps, read LIVE (`onError`, `checkpointStore`, `onNotice`); the one home of why it is * a seat and not a captured object is {@link RunnerDepsSeat}. */ runner: RunnerDepsSeat; /** borrowed-readonly — the session store: the end-of-task pass touches the leg's session through it (`finish`'s teardown legs). */ sessions: SessionStore; /** borrowed-readonly — the settle lane, entered in this lane's last continuation with the adopted cause and the compaction outcome. */ next: (adopted: RunTerminalAdoptionResult) => Promise<R>; } /** What the settle reads of this lane's work. */ export interface RunTerminalAdoptionResult { /** The ADOPTED terminal cause: the leg's throw, or the typed cause lifted over it here (guardrail stall / gate stop / platform terminal). */ threw: unknown; /** The end-of-task compaction pass's outcome. */ comp: EndOfTaskCompaction; /** This lane's ONE evaluation of {@link answerSettled}: a clean `"stop"` final with no queued continuation lost. The * settle lane hands it to the arbitration (`ResultFlags.answerSettled`), the teardown attribution and the notice. */ answerSettled: boolean; /** The undrained-input account, UNSETTLED: this lane knows every fact but one — whether this leg's consumed * checkpoint row comes back — and that one is the next lane's compensation to perform, not to predict. */ owedUserInput: OwedUserInputAccount; } export declare function runTerminalAdoption<R>(input: RunTerminalAdoptionInput<R>): Promise<R>;