@sema-agent/core
Version:
Stateless, task-oriented AI agent core
62 lines (61 loc) • 4.83 kB
TypeScript
import { type PeerInboundChainRef } from "../../agents/peer-admission.js";
import type { PushQueue } from "../push-queue.js";
import type { SessionStore } from "../session.js";
import { type NotificationInjectionOutcome, type PendingSessionNotifications, type SystemInjectionPriority, type TaskNotificationPayload } from "../task-notification.js";
import type { RunnerDeps, TaskEvent, TaskSpec } from "../types.js";
import type { SessionReadFileStates } from "./session-read-file-states.js";
import type { SessionModeSeats } from "./session-mode-seats.js";
import type { NotificationLaneBindings, Prepared, PrepareTaskFn, ResumeRun, RunInternals, RunnerDepsSeat, RunnerSelfSeat, TaskIdRef } from "./contracts.js";
export interface RunNotificationLaneInput<R> {
/** borrowed-readonly — the task spec: prepare's input, and the principal the peer scope is minted from. */
spec: TaskSpec;
/** borrowed-mutable — the run's event queue: the routed `task_notification` frames are pushed here. */
queue: PushQueue<TaskEvent>;
/** borrowed-readonly — the resume plan when this leg resumes a checkpoint (prepare's resume seed is derived from it). */
resume: ResumeRun | undefined;
/** borrowed-readonly — the trusted run-scoped channel: the detach hub, the uplink, the root / parent anchors, the peer refs, the upstream notification observer. */
internals: RunInternals | undefined;
/** borrowed-mutable — the stream layer's backstop carrier, handed to prepare so a prepare THROW still names its run. */
taskIdRef: TaskIdRef | undefined;
/** borrowed-readonly — the stream layer's session-lock verb, handed to prepare; absent when the spec named its session. */
holdSessionLock: ((sessionId: string) => Promise<void>) | undefined;
/** borrowed-readonly — the Runner's deployment deps, read LIVE (`onError` in the park closure — after the run, on a swapped
* catalog it is still the CURRENT sink; `models` and prepare's `deps` at the natural-snapshot pin); the one home of why it
* is a seat and not a captured object is {@link RunnerDepsSeat}. */
runner: RunnerDepsSeat;
/** borrowed-readonly — the TRUSTED Runner self-reference prepare mounts the `run_workflow` tool over (never a TaskSpec field). */
self: RunnerSelfSeat;
/** borrowed-readonly — the session store prepare acquires / creates the leg's session through. */
sessions: SessionStore;
/** borrowed-mutable — the Runner's own per-session read-state seat, ALWAYS this Runner's (a caller-supplied one is overridden). */
sessionReadStates: SessionReadFileStates;
/** borrowed-mutable — the Runner's per-session permission-mode seats, ALWAYS this Runner's (a caller-supplied one is overridden). */
sessionModeSeats: SessionModeSeats;
/** borrowed-mutable — the Runner's per-session parked-notification store: the torn-down lane and the escalation pend here. */
pendingSessionNotifications: PendingSessionNotifications;
/** borrowed-readonly — the orchestrator's entry (a lane may not name the orchestrator; the driver hands it in), as the ONE
* contract the orchestrator's own declaration is pinned to ({@link PrepareTaskFn}, contracts.ts). */
prepareTask: PrepareTaskFn;
/** borrowed-readonly — the lanes after this one, entered in this lane's last continuation with what it prepared and bound. */
next: (lane: RunNotificationLaneResult) => Promise<R>;
}
/** What the lane prepared and bound — the seats every lane after it reads. */
export interface RunNotificationLaneResult {
/** The leg's prepared seat. */
prepared: Prepared;
/** The ONE injection entry every notification producer rides (the identity lane binds the notify() bridge to it). */
injectTaskNotification: (notification: TaskNotificationPayload, opts?: {
priority?: SystemInjectionPriority;
}) => Promise<NotificationInjectionOutcome>;
/** The turn-open dedup set (the cross-layer double-park dedup): the identity lane registers a redelivered frame's key here. */
deliveredAtTurnOpen: Set<string>;
/** The peer inbound chain ref this run carries (the spawn chain's, or a fresh one). */
peerInboundChainRef: PeerInboundChainRef;
/** The model catalog pinned BEFORE prepare (the natural-snapshot closure for swapDeps): the budget seats resolve against it. */
modelCatalog: RunnerDeps["models"];
/** The lane's bindings as one seat over its own variables — see {@link NotificationLaneBindings}. */
notificationLane: NotificationLaneBindings;
/** The queue subscription's release; the leg lane's finally calls it right after flipping `live`. */
unsubscribeTaskNotifications: () => void;
}
export declare function runNotificationLane<R>(input: RunNotificationLaneInput<R>): Promise<R>;