import type { GenericMessage, GenericContentBlock, GenericTextBlock, GenericSkillBlock } from '../../../shared/types.js'; import { ToolResult } from '../../../shared/toolResult.js'; /** * Typed, OOP representation of one conversation message. * * `Session` keeps an immutable list of these as the single source of truth. * They are an internal server representation: every external consumer (the LLM * providers, persistence, the transcript, the state hash) keeps consuming the * plain `GenericMessage` wire shape produced by {@link toWire}. The pruning that * used to mutate the message array is now a pure projection (see * `ConversationHistory`) that compresses *copies* produced by these classes. * * Message kind is explicit (`kind`) rather than inferred from content shape, * replacing the old `isToolResultOnly` / `countUserTurns` heuristics. */ export declare abstract class ConversationMessage { abstract readonly kind: 'userPrompt' | 'assistant' | 'toolRelay'; abstract toWire(): GenericMessage; /** * Rehydrate a message from its wire form (persistence restore). Tool names on * relay results are NOT resolved here (a single message lacks the preceding * assistant); `ConversationHistory.replaceAll` resolves them. */ static fromWire(msg: GenericMessage): ConversationMessage; } /** * A genuine user turn — the prompt text, optionally preceded by auto-loaded * skill blocks. Never compressed (a prompt's text is content, not a tool result), * so prompt text can never be stripped and the content array can never be emptied. */ export declare class UserPromptMessage extends ConversationMessage { private readonly content; readonly kind: "userPrompt"; constructor(content: string | GenericContentBlock[]); toWire(): GenericMessage; /** Pure: a copy with `text` merged in (string concat or appended text block). */ appendText(text: string): UserPromptMessage; } /** * An assistant turn: an ordered list of text / reasoning / tool_use blocks * (or, rarely, a plain string when rehydrated). The content union is preserved * verbatim so projection re-serialises byte-identically. */ export declare class AssistantMessage extends ConversationMessage { private readonly content; readonly kind: "assistant"; constructor(content: string | GenericContentBlock[]); toWire(): GenericMessage; /** Map of `tool_use` id → tool name, for resolving relay tool names. */ toolUseNames(): Map; /** * Pure: a copy with every `tool_use` input collapsed to `{ _pruned: true }`. * `text` / `reasoning` / `skill` blocks are left untouched. */ withPrunedToolUseInputs(): AssistantMessage; } /** One tool result inside a relay, with the tool name that produced it. */ export type ToolRelayEntry = { toolUseId: string; /** Resolved from the preceding assistant's `tool_use`; drives volatile checks. */ toolName: string | undefined; result: ToolResult; }; /** * A tool-result relay: `{ role: 'user', content: [tool_result, ...auxBlocks] }`. * The protocol encodes tool results as user-role messages; this class makes that * explicit. Carries the resolved tool name per result so the projection needs no * back-scan. */ export declare class ToolRelayMessage extends ConversationMessage { private readonly results; private readonly auxBlocks; readonly kind: "toolRelay"; constructor(results: ToolRelayEntry[], auxBlocks?: (GenericTextBlock | GenericSkillBlock)[]); static fromWire(msg: GenericMessage): ToolRelayMessage; get entries(): readonly ToolRelayEntry[]; toWire(): GenericMessage; /** Estimated token cost of the full (uncompressed) tool-result content. */ estimatedTokens(): number; /** * Estimated tokens once the given results are marked stale — used by the * budget walk so a large stale result doesn't consume budget (the * volatile/staleness decision logically precedes the size ceiling). */ projectedTokens(staleToolUseIds: Set): number; /** Pure: a copy with an auxiliary text/skill block appended. */ appendAux(block: GenericTextBlock | GenericSkillBlock): ToolRelayMessage; /** * Pure projection: per-result, stale results (by tool_use id) collapse to * `{ stale }`, otherwise compress the body when `compressBody`. Aux blocks are * dropped when `stripAux`. */ project(opts: { staleToolUseIds: Set; compressBody: boolean; stripAux: boolean; }): ToolRelayMessage; /** Pure: a copy with one result replaced (create_plan post-approval swap). */ replaceResult(toolUseId: string, result: ToolResult): ToolRelayMessage; /** Pure: a copy with tool names resolved via the given lookup (rehydration). */ withResolvedNames(resolve: (toolUseId: string) => string | undefined): ToolRelayMessage; }