@sema-agent/core
Version:
Stateless, task-oriented AI agent core
62 lines (61 loc) • 4.63 kB
TypeScript
import { Type } from "typebox";
import type { RunnerSelfSeat } from "../core/runner/contracts.js";
/** Model-facing name of the child-transcript read tool (residual lane C). */
export declare const AGENT_TRANSCRIPT_TOOL_NAME = "AgentTranscript";
export interface AgentTranscriptToolOptions {
/** Runner whose `sessions` store holds the child's persisted history. */
runner: RunnerSelfSeat;
/** The unified registry the background Agent lane registered its a* handles in (scopes reads to lineage).
* Only the exact-id lookup is required; a registry that also offers `agentStateSource` (the engine's
* own does) puts the agent's current state on every answer that resolved its live row — one without it
* answers with steps alone. */
registry: Pick<import("../core/task-registry.js").TaskRegistry, "getAccessibleTask"> & Partial<Pick<import("../core/task-registry.js").TaskRegistry, "agentStateSource">>;
/** design/151 S1b: the durable ledger — when the live row/retain entry is gone (restart, terminal GC,
* retain off), the row's `sessionId` still anchors the PRESERVED transcript session (the S1b
* lifecycle flip skipped its release). Reads go through `runner.sessions` — a split-store child
* (caller-mounted Agent tool with its own runner) is honestly unreadable here after a restart. */
agentStore?: import("../core/background-agent-store.js").BackgroundAgentStore;
/** Access identity (mirrors SendMessage/TaskOutput — the mount fills these). */
owner?: string;
scope?: string;
sessionId?: string;
/**
* RB-409 seat, wired by RB-448 — the mount's per-call ctx builder, forwarded to {@link defineTool}
* (see {@link import("../core/tools.js").ToolCtxEnricher}). This tool is a `defineTool` PRODUCT, so
* without it the body sees exactly `{toolCallId, signal}` and `ctx.subagentRetain` below is always
* undefined — the run-scoped retain ledger has NO other channel (its own doc calls itself "threaded
* to delegation tools as the TRUSTED ctx.subagentRetain"), so the ordinary retained child this tool
* advertises reading was structurally unreachable and every such call fell through to the durable
* lane and then to "not retained". Same seat, same builder and same rationale as the SendMessage
* twin (RB-409 fixed it there and left this sibling — extracted from the same source file in
* design/157 A7 — behind). Absent ⇒ unchanged behavior: the `opts` axes alone supply the identity.
*/
enrichCtx?: import("../core/tools.js").ToolCtxEnricher;
/** Subagent transcript persistence — the declared-durability integrity-gap disclosure sink (see
* the SendMessage twin): a durable row with a bound sessionId whose session store attests
* not_found. Announced once per (handle, process); absent ⇒ the honest per-call degrade alone. */
onTranscriptIntegrityGap?: (handle: string, scope: string | undefined) => void;
/** The run's checkpoint seat — where a PARKED agent's approval card is read from for the state line
* (the same seat the Agent tool parks children into). Absent ⇒ the ctx seat
* (`checkpointStoreForChildren`) when the mount's ctx builder supplies one, else the card reads
* `unreadable`. */
checkpointSeat?: import("../core/checkpoint-seat.js").CheckpointSeat;
}
/**
* Residual observability (lane C) — build the MODEL-VISIBLE **AgentTranscript** tool: read the last N tool steps of a
* previously spawned background agent ON DEMAND (a PULL face — it does NOT inflate the parent's context
* the way an injected residual would). `id` is the a* task_id the Agent tool returned. This is the
* complement to the stop-time residual (which the notification already carries): use it to look deeper
* into a child's tail when the residual isn't enough.
*
* Safety: reads are bounded to the parent's OWN lineage — the same non-leaking registry access scope as
* SendMessage/TaskOutput (an unknown or out-of-scope id reads identically to "not found"). Two read
* paths keep a child's session reachable: the retain ledger (a RETAINED child), and the durable
* agent-store fallback (`agentStore` wired + accessible row + preserved `sessionId` — readable even
* with retain off/expired/evicted). Only when BOTH miss does the call return the honest
* "not retained" / "not found".
*/
export declare function createAgentTranscriptTool(opts: AgentTranscriptToolOptions): import("../core/types.js").AgentTool<Type.TObject<{
id: Type.TString;
lastN: Type.TOptional<Type.TInteger>;
}>, unknown>;