/** * Saved tool output: text too long to hand the model in one tool result, * kept whole in the run's globals under a name the model can read it back * by. It lives beside the fetch cache under the `__internal` module, so it * is per run, carried by every checkpoint, copied into a fork branch, and * shared by a tool call. See docs/dev/stdlib/spill.md. */ import type { Run } from "./asyncContext.js"; /** One saved output. `source` is what produced it, for a human: the command * that ran, or the tool and its first string argument. Entries saved before * the field existed have none. */ export type SavedOutput = { name: string; text: string; source?: string; }; /** The store: entries oldest first, so eviction drops from the front. */ export type ToolOutputStore = { entries: SavedOutput[]; }; /** Characters the store holds across every entry before the oldest goes. * The store rides in every checkpoint, and a hosted resume posts every * interrupt's checkpoint back in one body of at most 10 MB, which an * isolated branch can double. One million characters leaves room for * that, and still holds ten pages of 100 KB. */ export declare const MAX_STORE_CHARS = 1000000; /** Characters of preview, newlines included, taken from each end of a long * output. Two of these plus the notice around them stay near 2000, under * `safeBash`'s own limit. A tool loop with a smaller `maxToolResultChars` * passes it to `outputNotice`, which shrinks the preview to fit. */ export declare const PREVIEW_CHARS = 700; /** Longest line the preview shows before cutting it. */ export declare const PREVIEW_LINE_LEN = 200; /** Longest source kept beside a saved output. */ export declare const SPILL_SOURCE_CHARS = 80; export declare function isOutputName(name: string): boolean; /** The two reader tools a model was offered, by the names it sees them * under. `grep` is null when only `readSpill` was offered. */ export type SpillReaders = { read: string; grep: string | null; }; /** The names `safeBash` puts in its notice. It does not know the call's * tool list, and `shellTools()` hands the readers out beside it. */ export declare const DEFAULT_READERS: SpillReaders; export type ToolIdentity = { name: string; module: string; registeredName: string; }; /** Whether `tool` reads saved output back. Its own result is already in * the store, so the loop never saves it a second time. */ export declare function isSpillReader(tool: ToolIdentity): boolean; /** The readers among `tools`, or null when `readSpill` is not one of * them: then nothing the loop saved could be read back. */ export declare function spillReaders(tools: ToolIdentity[]): SpillReaders | null; /** The source as the store keeps it and the notice shows it; null when the * caller gave none (an empty string). */ export declare function spillSourceLabel(source: string | null): string | null; /** Keep `text` whole under a fresh name and return the name. The oldest * entries go first until the new one fits; an entry larger than the whole * cap is kept alone, because the notice will already have promised it. */ export declare function storeOutput(run: Run, text: string, source: string): string; /** The saved text, or null when the name is not in the store: evicted, saved * before a checkpoint this run resumed from, or saved by another run. */ export declare function findOutput(run: Run, name: string): string | null; /** What produced the saved output, or null when the name is not in the * store or the entry was saved before sources were kept. */ export declare function findOutputSource(run: Run, name: string): string | null; /** What a reader says about a name it cannot find. One message for every * cause, since the model can do the same thing about each. */ export declare function missingOutputMessage(name: string): string; /** * The preview that stands in for a long output: what happened, a glimpse of * both ends, the name it was saved under, and how to read the rest with * `readers`. `exitCode` is null for a tool result that is not a command's * output. The preview shrinks so the notice fits in `maxChars`; only when * the text around the preview is longer than that on its own does the * notice come out longer, and the caller cuts it. `source` names what * produced the output in the first line. */ export declare function outputNotice(text: string, name: string, exitCode: number | null, readers: SpillReaders, maxChars?: number, source?: string | null): string;