import type { AttentionMode, ChannelMode } from "@cotal-ai/core"; import type { AdmittedChatSession, CloseReport, SessionMessage } from "./session.js"; export declare const STDIO_SCHEMA_VERSION = 1; /** Bound on one request line, in UTF-16 code units. Provisional; set at review. */ export declare const MAX_REQUEST_LINE = 1048576; /** Bound on a caller-chosen request id. */ export declare const MAX_REQUEST_ID = 128; /** Bound on a `replyTo` message id and a DM target (name or `.`). Provisional. */ export declare const MAX_MESSAGE_ID = 512; export declare const MAX_DM_TARGET = 512; /** Invoke bounds, the same as the agent tool's (`cotal_invoke`). */ export declare const INVOKE_DEFAULT_TIMEOUT_MS = 30000; export declare const INVOKE_MAX_TIMEOUT_MS = 120000; /** The closed request set. Seat-only requests (turn yield, spawn, despawn, run) are deliberately absent. */ export declare const REQUEST_TYPES: readonly ["send", "dm", "anycast", "status", "attention", "channelMode", "join", "leave", "inbox", "roster", "channelInfo", "connection", "invoke"]; export type RequestType = (typeof REQUEST_TYPES)[number]; export type StdioRequest = { readonly type: "send"; readonly id: string; readonly text: string; readonly channel: string; readonly mentions: readonly string[]; } | { readonly type: "dm"; readonly id: string; readonly to: string; readonly text: string; readonly replyTo?: string; } | { readonly type: "anycast"; readonly id: string; readonly role: string; readonly text: string; } | { readonly type: "status"; readonly id: string; readonly status: "idle" | "working" | "waiting"; readonly activity?: string; } | { readonly type: "attention"; readonly id: string; readonly mode: AttentionMode; } | { readonly type: "channelMode"; readonly id: string; readonly channel: string; readonly mode: ChannelMode | "normal"; } | { readonly type: "join"; readonly id: string; readonly channel: string; } | { readonly type: "leave"; readonly id: string; readonly channel: string; } | { readonly type: "inbox"; readonly id: string; readonly peek: boolean; } | { readonly type: "roster"; readonly id: string; } | { readonly type: "channelInfo"; readonly id: string; readonly channel: string; } | { readonly type: "connection"; readonly id: string; } | { readonly type: "invoke"; readonly id: string; readonly endpoint: string; readonly command: string; readonly args?: Readonly>; readonly timeoutMs: number; }; export interface ProtocolError { readonly code: string; readonly message: string; readonly cause?: { readonly code?: string; readonly detail?: unknown; }; } /** A parsed line: a valid request, or a refusal carrying the id when one could be recovered. */ export type ParsedLine = { readonly ok: true; readonly request: StdioRequest; } | { readonly ok: false; readonly id: string | null; readonly error: ProtocolError; }; /** Parse and validate one request line. Never throws and never touches a session. */ export declare function parseRequestLine(line: string): ParsedLine; export type ResultOutcome = "ok" | "stored" | "refused" | "unknown" | "failed"; export interface ResultRecord { readonly schemaVersion: 1; readonly type: "result"; readonly id: string; readonly outcome: ResultOutcome; readonly result?: unknown; readonly error?: ProtocolError; } export type OutputRecord = ResultRecord | { readonly schemaVersion: 1; readonly type: "message"; readonly message: MessageRecord; } | { readonly schemaVersion: 1; readonly type: "presence"; readonly change: "joined" | "updated" | "left"; readonly row: unknown; } | { readonly schemaVersion: 1; readonly type: "gap"; readonly scope: string; readonly reason: string; } | { readonly schemaVersion: 1; readonly type: "error"; readonly id: null; readonly error: ProtocolError; } | { readonly schemaVersion: 1; readonly type: "end"; readonly reason: string; readonly close?: CloseReport; }; /** A received message as a program reads it. The delivery key is internal and never exported. */ export type MessageRecord = Omit; export declare function messageRecord(m: SessionMessage): MessageRecord; /** Serialize one record as one line. JSON escapes every control character, so a hostile message * body can never start a second record. */ export declare function serializeRecord(record: OutputRecord): string; /** Run one validated request against the session and return its result record. */ export declare function dispatch(session: AdmittedChatSession, req: StdioRequest): Promise<{ record: ResultRecord; surfaced: readonly string[]; }>; /** * One `--stdio` run over one admitted session. The caller feeds complete lines (without the * trailing newline) and signals end of input; `write` puts one serialized record on stdout. All * other diagnostics belong on stderr, never through `write`. */ export declare class StdioParticipant { private readonly session; private readonly write; /** Called once, after the `end` record is written, whatever ended the session. The stdin * driver uses it to stop reading when the session ends on its own. */ private readonly onEnd; private chain; private readonly inFlight; private ended; /** Set the moment an end is decided, before close runs, so every later request is refused * (with a result, before the end record) rather than queued behind the close. */ private closing; private readonly unsubscribe; constructor(session: AdmittedChatSession, write: (line: string) => void, /** Called once, after the `end` record is written, whatever ended the session. The stdin * driver uses it to stop reading when the session ends on its own. */ onEnd?: (close: CloseReport) => void); /** Queue one input line. Blank lines are ignored. After the end record nothing is written. A * refusal is decided on arrival but written in its turn, so every line's record comes back in * arrival order. */ acceptLine(line: string): void; /** Refuse a line that never reached {@link acceptLine}, such as one too long to frame, in its turn * with the other records. */ refuseLine(error: ProtocolError): void; /** stdin closed: finish already accepted requests in order, close the session, then write the end record. */ endOfInput(): Promise; /** Wait until every queued record is written, including refusals queued while waiting. */ private drain; private finish; private onEvent; private queueRefusal; private emit; } //# sourceMappingURL=stdio.d.ts.map