import type { BidiConnectParams, BidiProvider, BidiSession, BidiTurnEvent } from '../../types/bidi/index.js'; import type { ToolResultGuardrailSpec } from '../../types/guardrail/index.js'; import type { SessionId, TurnId } from '../../types/ids/index.js'; import type { ToolRegistryContract } from '../../types/tool/index.js'; import { type Logger } from '../../utils/logger.js'; export declare class BidiSessionCloseTimeoutError extends Error { readonly timeoutMs: number; constructor(timeoutMs: number); } /** * Run tools for a duplex session. * * The turn-based loop can execute a batch of calls because it knows when * the batch is complete: the model stopped talking. Here nothing stops. * Two consequences shape everything below. * * **A tool must not block the stream.** The model keeps producing while a * tool runs, and the human keeps talking. Awaiting a tool inline would * stall the events that the interruption arrives on — so the loop would * only notice it was interrupted after finishing work the interruption * made pointless. * * **An interruption invalidates work in flight.** When the human speaks * over the model, a tool the model asked for is answering a question * nobody is asking. Sending its result anyway would put a stale answer * into a conversation that has moved on, so a call that was running when * the interruption arrived is abandoned rather than delivered. */ export interface BidiTurnParams { readonly provider: BidiProvider; readonly tools: ToolRegistryContract; readonly connect: BidiConnectParams; readonly workingDirectory: string; readonly env?: Record; /** * Owns the complete run lifetime, not only connection establishment. * Aborting it closes the provider session, ends local events and revokes * every tool context without mutating the caller-owned controller. */ readonly signal?: AbortSignal; /** * How long `close()` waits for provider cleanup after fencing locally. * Defaults to five seconds. `0` preserves an unbounded provider-close wait. */ readonly closeTimeoutMs?: number; readonly log?: Logger; /** The session this duplex turn belongs to. Absent: a new session id is generated. */ readonly sessionId?: SessionId; /** Overrides the generated turn id, so a host can correlate its own. */ readonly turnId?: TurnId; /** * Screens for the results this session's tools produce. Absent installs * {@link DEFAULT_TOOL_RESULT_GUARDRAILS}; an empty array installs none. * * Here rather than nowhere because this path builds its OWN tool context: * a duplex session executes the tools the model asks for, and its results * reach a model just as a turn's do. A registry built with * `resultGuardrails` still wins, as it does on the query path. */ readonly toolResultGuardrails?: readonly ToolResultGuardrailSpec[]; } export interface BidiTurn { readonly sessionId: SessionId; readonly turnId: TurnId; /** What the loop reports, in order. Ends when the session closes. */ events(): AsyncIterable; /** Push input from the human. */ send(input: Parameters[0]): Promise; /** * Fence the local turn immediately, abort tool contexts and close the * provider once. It does not wait for tool code that ignores cancellation; * provider cleanup is observed for `BidiTurnParams.closeTimeoutMs`. */ close(): Promise; } export declare function startBidiTurn(params: BidiTurnParams): Promise; //# sourceMappingURL=session.d.ts.map