import type { Message } from "@oh-my-pi/pi-ai"; import type { CallContext, ShapedTool } from "../types.js"; /** What of the model's context a result's lines are checked against before they collapse as shown before. */ export interface Seen { /** Normalised lines (≥ {@link WITNESS_CHARS} chars). */ lines: Set; /** * Each normalised line paired with the next of the same text ({@link pairKey}), short and blank lines included: a * run collapses only in the order the context holds it, so a dropped, moved or changed line splits it. */ pairs: Set; } /** Keys of one text (or several) for a {@link Seen}. */ interface SeenKeys { lines: string[]; pairs: string[]; } /** * Per-session shaping state. Every result is decided once, at arrival; this is what later results read: * what the agent has already seen, what cuts hid, which code spans were folded. */ export interface ShapeState { /** * Lines already in the agent's context, and their order: task, its words, commands, earlier results. Rebuilt * from the model's context before each result ({@link syncSeen}), so lines that left it (compaction, a prune, a * clear, another branch) no longer count. */ seen: Seen; /** * Keys noted per call whose result is not in the context yet (a sibling call of the same turn): they stay seen * across a {@link syncSeen} until the call's result lands there or the call leaves the context. */ pending: Map; /** Identifiers of the conversation (task, what the agent said, intents, commands): bodies it names stay open. */ names: Set; /** Lowercase words of the conversation, for the window's lexical score. */ words: Set; /** Normalised lines a window or valve cut hid: a later result holding enough of them is a re-ask, shown whole. */ hidden: Set; /** Folded code spans (1-based, inclusive) per absolute path: a later read overlapping one is shown whole. */ folded: Map; /** The task text last recorded, so it is added once. */ task: string; /** The `said` text last recorded, so a turn with several calls adds it once. */ said: string; /** Shaped results so far. */ calls: number; } export declare function newShapeState(): ShapeState; /** * Rebuilds what the agent has seen from the model's context as it stands (`messages`, as sent to the model): the * text of every message in it ({@link messageTexts}) and the lines noted for calls whose results have not landed yet. * Whatever left the context (a compaction, a prune or elision of old results, a clear, a move to another branch) no * longer counts, so its lines never collapse to "as shown before". Each call shaped resyncs first. */ export declare function syncSeen(state: ShapeState, messages: readonly Message[]): void; /** * Records what the agent has said and run up to and including this call: the task, its last words, its earlier * commands and this call's command count as seen; the intent only feeds names and words (the seen set * leaves `i` out). What it notes for call `toolCallId` stays seen until its result is in the context ({@link syncSeen}). */ export declare function noteCall(state: ShapeState, ctx: CallContext, tool: ShapedTool, command: string, toolCallId?: string): void; /** Records a result of call `toolCallId` as the agent is shown it. */ export declare function noteShown(state: ShapeState, text: string, toolCallId?: string): void; export {};