import { type ColorFunction } from "../utils/termcolors.js"; /** What `agency local serve` prints about one request that reached its front * door. The front door times the request and collects the reply; everything * here is formatting, so it can be tested without a server. */ /** How much of a reply body is kept for the log. A long generation is worth * reading; a whole context window pasted back is not, and the cap keeps a * runaway reply from growing memory. */ export declare const CAPTURE_LIMIT: number; export type Capture = { push: (chunk: Buffer) => void; text: () => string; /** True once a chunk arrived that did not fit. */ truncated: boolean; /** Every byte pushed, whether kept or not. An audio reply is logged by * this count. */ total: number; }; /** Collects up to `limit` bytes of a reply as it streams to the client. It * never changes what the client gets; it only keeps a copy. */ export declare function createCapture(limit?: number): Capture; export type ReplySummary = { /** The reply body as the client received it, for the verbose block: one * JSON object, or the whole `data:` stream. */ body: string; /** Whether the body is a stream of frames rather than one JSON object. */ streamed: boolean; promptTokens?: number; completionTokens?: number; truncated: boolean; /** Set for an audio reply, whose bytes are never logged: how many there were. */ audioBytes?: number; /** Set for a successful image reply, whose base64 is never logged: how * many bytes the reply had, and the format the request asked for. */ image?: { bytes: number; format: string; }; /** Set for a successful vision reply: what it was, counted, or its size * when the reply is too long to count. */ vision?: string; }; /** One reply as it went out: the status, the body the capture kept, its * content type, whether the capture was cut short, and how many bytes * there were in all. */ export type Reply = { status: number; body: string; contentType: string | undefined; truncated: boolean; totalBytes: number; }; export type LogEntry = { method: string; path: string; /** The model the request named, or null when it named none. */ model: string | null; status: number; durationMs: number; /** The request body as it arrived, for the verbose block. */ request: string | null; reply: ReplySummary | null; }; export type LogOptions = { verbose: boolean; color: ColorFunction; }; /** The request body for the log: the JSON that was forwarded, indented so a * long messages array is readable. An input image is shown as a note of * its count and size, never as its base64. */ export declare function describeRequest(body: Record): string | null; /** Where image servers answer. A reply there holds about a megabyte of * base64, which does not belong in a terminal. */ export declare const IMAGES_PATH = "/v1/images/generations"; /** Where vision servers answer. */ export declare const VISION_PATHS: string[]; /** What the log knows about the request a reply answers. */ export type RequestFacts = { path: string; outputFormat?: string; }; /** One reply, kept whole for the log. A body that is a single JSON object is * indented; a stream of `data:` frames is left exactly as it came, since the * framing is often what you are debugging. Audio is summarized by its size. * A successful image reply is summarized from the request and the byte * count alone, never parsed, so a capture cut short makes no difference. * An image server returns one image per request. */ export declare function describeReply(reply: Reply, request?: RequestFacts): ReplySummary; /** Milliseconds as something quick to read: under a second in whole * milliseconds, above it in tenths of a second. */ export declare function formatDuration(ms: number): string; /** One line's worth of text from a request: control characters escaped, so a * model name carrying a newline or an ANSI sequence cannot forge log lines or * drive the terminal. */ export declare function oneLine(text: string): string; /** The lines to print for one request: a summary always, and the prompt and * the reply under it when verbose. */ export declare function serveLogLines(entry: LogEntry, options: LogOptions): string[];