@sema-agent/core
Version:
Stateless, task-oriented AI agent core
103 lines (102 loc) • 7.49 kB
TypeScript
/**
* PrepareTask's three BOUNDARY-FAMILY park lanes, verbatim from the driver's
* gate-machinery block: the ONE resource mint (`mintResourceSuspend`) behind the task-axis `suspendForResource` (exposed
* under the caller's `resourceSuspend` opt-in) and the infrastructure `suspendForPlatformLimit` (exposed on durable infra
* alone), and the `plan_review` mint behind `suspendForReview` (exposed with a checkpoint store). Every mint reuses the
* suspend saga's serializer, commit saga, loop cap and env split — this phase adds no second copy of any of them. The
* interface is the dependency list the segment had implicitly; the three lanes used to be forward-declared
* `let`s at task scope, assigned inside the block, so the driver's Prepared could expose them — they are this phase's
* Result now, and the driver binds them as consts.
*
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await of its own (the mints run at a turn boundary), so the
* phase adds no yield between the suspend saga before it and the park closure after it. Read-stability
* of the host handles for the call: {@link RunInternals} (`@contract prepare.deps-read-stable`).
*
* The lanes exist exactly when the saga does (the ask lane's presence law) — an absent saga answers three absent lanes,
* so the orchestrator grows no branch.
*/
import type { AgentHarness } from "../../internal/harness.js";
import { type CheckpointStore } from "../checkpoint-store.js";
import type { SessionStore } from "../session.js";
import type { RunnerDeps, TaskSpec } from "../types.js";
import type { Prepared, SuspendSaga } from "./contracts.js";
export interface PrepareBoundaryParksInput {
/** borrowed-readonly — the suspend saga's eight seats (the serializer, the commit saga, the loop cap, the env split, the
* park-only handle, the in-flight spend), or undefined when the gate machinery is inactive (then all three lanes are
* absent). Called at park time; never rebuilt here. */
saga: SuspendSaga | undefined;
/** borrowed-readonly — the REBOUND spec. Read: `resourceSuspend` (the slice scope/ttl/maxSlices), `retainBackgroundProcesses`
* (the park-only sweep gate), `durableApproval` (the review pause's ttl), `principal` (the rows' identity record and
* the review scope). Never mutated. */
spec: Pick<TaskSpec, "resourceSuspend" | "retainBackgroundProcesses" | "durableApproval" | "principal">;
/** borrowed-readonly — the leg's checkpoint store, or undefined (then the review lane is absent and the resource mint
* answers false). */
checkpointStore: CheckpointStore | undefined;
/** borrowed-mutable — prepare's abort seat. `.signal` is read (a cancelling run mints nothing); `abort()` is called on
* the review lane's commit (the review pause stops the run the human gate's way). */
abortController: {
readonly signal: AbortSignal;
abort(): void;
};
/** borrowed-mutable — the built harness. Writers here: `requestStopAfterTurn()` (the resource lanes' clean stop) and
* `abort()` (the review lane's stop). */
harness: Pick<AgentHarness, "abort" | "requestStopAfterTurn">;
/** borrowed-readonly — the acquired session; only `getLeafId` is read (no committed leaf ⇒ no consistent resume point). */
session: Pick<Prepared["session"], "getLeafId">;
/** borrowed-readonly — the session store; only the optional `pin` is called (best-effort, after commit). */
sessions: Pick<SessionStore, "pin">;
/** borrowed-readonly — the acquired session id (the rows' session, the source attribution, every disclosure's tag). */
sessionId: string;
/** borrowed-readonly — the deployment's error face, as a Pick over the SAME `deps` object (receiver preserved for
* `deps.onError?.()`): the suspendVM refusals, the skipped-review lines, the pin failures. */
deps: Pick<RunnerDeps, "onError">;
/** borrowed-readonly — the cross-slice ledger carried on the resumed checkpoint, or undefined on the first slice. */
priorLedger: Prepared["resourceLedger"];
/** borrowed-readonly — the resource-slice cap, or undefined (no slice ceiling). */
maxSlices: number | undefined;
/** borrowed-readonly — the restart-loop cap the review lane is bounded by. */
maxSuspends: number;
/** borrowed-readonly — the human total the first slice seeds the ledger from, or undefined. */
resourceTotal: {
totalBudgetMicroUsd?: number;
totalTokens?: number;
} | undefined;
/** borrowed-readonly — how many times this task already suspended (carried on the resumed checkpoint); a slice carries
* it UNCHANGED. */
priorSuspendCount: number;
/** borrowed-readonly — the restart-loop chain base (resets after an approved execution); the review lane's count. */
suspendChainBase: () => number;
/** borrowed-readonly — the per-task human-review accumulator; snapshotted onto every row (never written here). */
humanReviewRef: Prepared["humanReviewRef"];
/** borrowed-readonly — the loop's live spend seat; `.get` is read at mint time for the review ledger. */
liveSpendRef: Prepared["liveSpendRef"];
/** borrowed-readonly — the injectable wall clock (the review pause's `suspendedAt`). */
now: () => number;
/** borrowed-readonly — the inherited-gate phase's three version-stamp predicates (face / F-012 / org admission). */
faceCheckpointState: () => boolean;
/** borrowed-readonly — see `faceCheckpointState`. */
f012CheckpointState: () => boolean;
/** borrowed-readonly — see `faceCheckpointState`. */
orgAdmissionCheckpointState: () => boolean;
/** borrowed-mutable — the run's committed-pause holder (`Prepared.pausedRef`). Writer here: the commit-side publication
* of a committed resource / platform / plan-review checkpoint. */
pausedRef: Prepared["pausedRef"];
/** borrowed-mutable — the run-scoped remote-lifecycle failure log. Writer here: a refused `suspendVM` (`push`). */
remoteEnvFailures: Prepared["remoteEnvFailures"];
/** borrowed-readonly — the wiring-manifest phase's task-axis predicate (opt-in ∧ durable infra): exposes `suspendForResource`. */
resourceSuspendEligible: boolean;
/** borrowed-readonly — the wiring-manifest phase's durable-infra predicate: exposes `suspendForPlatformLimit`. */
durableSuspendInfraReady: boolean;
/** borrowed-readonly — the restore-incomplete adapter's missing members, or undefined (the review lane refuses loudly). */
incompleteSuspendAdapter: readonly ("resumeVM" | "postResumeInit")[] | undefined;
}
export interface PrepareBoundaryParksResult {
/** owned — the task-axis resource lane (`Prepared.suspendForResource`), or undefined (no opt-in / no infra / inactive). */
suspendForResource: Prepared["suspendForResource"];
/** owned — the platform lane (`Prepared.suspendForPlatformLimit`), or undefined (no durable infra / inactive). */
suspendForPlatformLimit: Prepared["suspendForPlatformLimit"];
/** owned — the plan-review lane (`Prepared.suspendForReview`), or undefined (no store / inactive). */
suspendForReview: Prepared["suspendForReview"];
}
/** The M19 boundary-parks phase body — prepareTask's three boundary lanes, verbatim (see the module header). */
export declare function prepareBoundaryParks(input: PrepareBoundaryParksInput): PrepareBoundaryParksResult;