import type { SessionStateMap } from "#harness/types.js"; import { AGENT_HANDLES_STATE_KEY } from "./state-key.js"; export { AGENT_HANDLES_STATE_KEY }; /** * Stable identity of one delegated child, minted before its start side * effect runs. The model-visible `id` derives from the first start * operation, never from the child session id, so it exists before the * child does and cannot collide on externally supplied session suffixes. */ export interface AgentIdentity { /** Model-visible identifier: `ag_:`. */ readonly id: string; /** Subagent tool name. */ readonly name: string; /** Agent-graph node used to re-resolve delivery configuration. */ readonly nodeId: string; } /** * One dispatch the parent intends to perform or has performed. Repeating * the same operation is a replay; a different operation against a * starting/running handle is a busy conflict. */ export interface StartOperation { readonly kind: "start"; /** Derived via {@link deriveAgentOperationId}; stable across replays. */ readonly id: string; readonly callId: string; readonly parentTurnId: string; } /** A continuation delivery against a parked handle. */ export interface ContinueOperation { readonly kind: "continue"; /** Derived via {@link deriveAgentOperationId}; stable across replays. */ readonly id: string; readonly callId: string; readonly parentTurnId: string; /** * Status the handle showed before this delivery, restored when the * delivery is rejected as retryable so the handle returns to `parked` * without optional state. */ readonly previousStatus: string; } /** Where a fresh child will be started. No session exists yet. */ export type AgentStartTarget = { readonly kind: "agent/local"; /** Deterministic child continuation token chosen at dispatch. */ readonly continuationToken: string; } | { readonly kind: "agent/self"; readonly continuationToken: string; } | { readonly kind: "agent/remote"; /** Deliver target base URL; never model-visible. */ readonly url: string; /** Callback base URL stub captured at dispatch; never model-visible. */ readonly callbackBaseUrl: string; }; /** Confirmed delivery coordinates of a started child. */ export type AgentAddress = { readonly kind: "agent/local"; readonly sessionId: string; readonly continuationToken: string; } | { readonly kind: "agent/self"; readonly sessionId: string; readonly continuationToken: string; } | { readonly kind: "agent/remote"; readonly sessionId: string; readonly url: string; readonly callbackBaseUrl: string; }; /** * Durable ownership record for one delegated child. * * The store owns the full nonterminal lifecycle: * * - `starting` — the parent committed intent to start; the child may or * may not exist yet. * - `running` — one identified child turn is outstanding. * - `parked` — the child is idle and resumable; only this phase is * model-visible. * * A terminal child has no handle: settlement deletes it. */ export type AgentHandle = { readonly phase: "starting"; readonly identity: AgentIdentity; readonly operation: StartOperation; readonly target: AgentStartTarget; } | { readonly phase: "running"; readonly identity: AgentIdentity; readonly operation: StartOperation | ContinueOperation; readonly address: AgentAddress; } | { readonly phase: "parked"; readonly identity: AgentIdentity; readonly address: AgentAddress; readonly lastStatus: string; }; /** Lifecycle phase of a delegated agent handle. */ export type AgentHandlePhase = AgentHandle["phase"]; /** Session-state collection of delegated agent handles. */ export interface AgentHandleStore { readonly handles: readonly AgentHandle[]; } /** Derives the model-visible agent id from the first start operation. */ export declare function deriveAgentId(name: string, startOperationId: string): string; /** Collapses whitespace and truncates output into a handle status line. */ export declare function formatAgentStatus(output: unknown): string; /** * Validates one agent handle store about to be persisted, returning the * parsed value. Throws instead of writing an invalid store: transitions run * this on every write, which is the invariant that lets the schema-free * driver-side reader (`query.ts`) trust stored values without revalidating. */ export declare function assertPersistableAgentHandleStore(store: AgentHandleStore): AgentHandleStore; /** * Reads and validates the agent handle store from session state. * * Returns `undefined` only when no store has been written. A present but * invalid store throws: treating corruption as absence would let the next * transition silently replace every delegated child's delivery coordinates. */ export declare function getAgentHandleStore(state: SessionStateMap | undefined): AgentHandleStore | undefined;