/** * Reading back how a preset agent's session ended: its result or events, cleaned and * bounded, with the summary autopilot appends to the item's log * (autopilot-reads-agent-result/AC-4, AC-7, AC-8, AC-12, AC-14, AC-16, AC-28, AC-29, * AC-33, AC-34). * * The agent's output is untrusted input. Everything read here is parsed in a `try`, * checked field by field, stripped of terminal escapes and control characters, and cut * to a bound before it can reach a park reason, a log line, a notification or * `state.json`. The send side is `typed.ts`. * * @module */ import { type AgentOutcome, type Harness } from './typed.js'; /** A reason or an error, as it reaches a park reason or a log line (AC-29). */ export declare const REASON_MAX = 200; /** A tool name, a tool input or a command (AC-29). */ export declare const INPUT_MAX = 80; /** The outcome's instance and phase. */ export declare const NAME_MAX = 64; /** An error text kept whole enough to classify and to read a reset time from. */ export declare const ERROR_TEXT_MAX = 2000; /** Refused calls and failed commands kept per session (AC-28). */ export declare const LIST_MAX = 10; /** Text with terminal escapes and control characters removed; newlines kept for splitting. */ export declare function plain(text: string): string; /** One line: plain, whitespace runs collapsed to one space, trimmed, at most `max`. */ export declare function oneLine(text: string, max: number): string; /** The first non-blank line of plain(text), trimmed, at most `max`; null when there is none. */ export declare function firstLine(text: string, max: number): string | null; /** * The agent's outcome, or null unless it has exactly the four keys, each a string, the * outcome one of the four (AC-4, AC-13). Its strings are bounded on the way in, so a * megabyte of `reason` is never stored. */ export declare function parseOutcome(value: unknown): AgentOutcome | null; /** How a session ended. Stored on the item, so every field is bounded. */ export interface SessionEnd { harness: Harness; /** Claude's `error_max_budget_usd` / `error_max_turns` (AC-7, AC-8). */ limit: 'budget' | 'turns' | null; /** The error text defined above AC-6, narrowed for Codex by AC-34; null when none. */ error: string | null; outcome: AgentOutcome | null; /** A UUID or null; `session_unusable` when an id was there but was not one (AC-33). */ session_id: string | null; session_unusable: boolean; /** micro-USD; null = unpriced (AC-19, AC-21). */ cost_micro: number | null; /** Tokens as the cost ledger counts them; null = not reported (cost-in-tokens/AC-18). */ tokens: number | null; turns: number | null; refused: { tool: string; input: string; }[]; refused_total: number; failed: { command: string; exit_code: number; }[]; failed_total: number; /** Lines that looked like JSON and did not parse: a format change shows as a count, not as silence. */ unreadable: number; } /** * The last `type: "result"` object in a launch's log segment, or null when there is none. * Claude prints it as one line at the end of `--output-format json`; the agent's stderr * shares the log, so every other line is skipped. */ export declare function readClaudeResult(segment: string): SessionEnd | null; /** Codex events seen so far for one launch. Persisted between passes, bounded like SessionEnd. */ export interface CodexProgress { /** A terminal event was seen: with a non-empty -o file, the "readable result" test (AC-14, AC-15). */ ended: boolean; thread_id: string | null; thread_unusable: boolean; /** `turn.completed` events. */ turns: number; /** Summed `turn.completed` usage, as Codex counts it: cached input is inside input. */ usage: { input: number; cached: number; output: number; }; /** The last `turn.failed` / `error` message, cleared by a later `turn.completed` (AC-34). */ error: string | null; failed: { command: string; exit_code: number; }[]; failed_total: number; unreadable: number; } export declare function emptyCodexProgress(): CodexProgress; /** * Fold complete JSONL lines into `p`. Lines that are not JSON — Codex's own stderr shares * the log — are skipped; JSON that does not parse is counted; unknown event types are * ignored, so a new Codex event changes nothing here. */ export declare function readCodexEvents(lines: string, p: CodexProgress): void; /** * The end of a Codex launch: its folded events, its `-o` file's text, and its usage * priced by the caller. Null when the launch wrote no terminal event and no outcome — a * crash or a signal before its first turn ended, which today's launch-failure check * reports better (AC-15). */ export declare function codexEnd(p: CodexProgress, outcomeText: string | null, costMicro: number | null): SessionEnd | null; /** * Whether an error text is a session limit or a dropped connection, the two endings a * session is resumed from (AC-23, AC-24). A session limit is checked first: it must not * contain `rate limit`, which the connection list holds. */ export declare function stoppedBy(error: string): 'session-limit' | 'connection' | null; /** * When a session limit resets, as epoch ms (AC-24). The epoch form is tried first — the * seconds after a `|` — then `resets [:]am|pm`, with an optional `(