import { type ContentBlock, type PromptResponse, type SessionUpdate } from "@agentclientprotocol/sdk"; import type { ImageContent } from "@earendil-works/pi-ai"; import type { SessionStats } from "../../core/agent-session.ts"; import type { RpcEvent, RpcSlashCommand } from "../rpc/rpc-types.ts"; /** Product limit for the fully rendered prompt text, including resource labels and separators. */ export declare const MAX_PROMPT_BYTES: number; /** * Maximum decoded bytes accepted for one prompt image. Selesai's own inline-image pipeline resizes * anything above 4.5 MiB decoded (`src/utils/image-resize-core.ts`), so an accepted image is always * forwarded unchanged instead of being silently re-encoded by the child. */ export declare const MAX_PROMPT_IMAGE_BYTES: number; /** * Maximum decoded bytes across every image in one prompt (two maximum-size images). Images travel in * the separate RPC `images` array, so the 1 MiB text rule does not apply: a single ordinary phone * photo already exceeds it once base64-encoded. */ export declare const MAX_PROMPT_IMAGE_TOTAL_BYTES: number; /** MIME types accepted for a prompt image. T3 sends exactly these four (`packages/contracts/src/chatAttachment.ts:12-27`). */ export declare const PROMPT_IMAGE_MIME_TYPES: readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]; /** T3 drops untrimmed or longer command names and caps the list at 128 (`probe.ts:41-54,214-245`). */ export declare const MAX_COMMAND_NAME_LENGTH = 128; export declare const MAX_COMMAND_DESCRIPTION_LENGTH = 1024; export declare const MAX_AVAILABLE_COMMANDS = 128; /** Maximum UTF-8 bytes of text displayed for one tool call. */ export declare const MAX_TOOL_CONTENT_BYTES: number; /** Rendered prompt text plus the images that ride beside it in the RPC prompt. */ export interface RenderedPromptContent { text: string; images: ImageContent[]; } /** * Render text, attributed resource links and inline images; this never resolves or fetches a URI. * Images are forwarded in block order and do not consume the text byte budget. Text is required * unless an image is present: T3 sends a later turn whose prompt holds image blocks only once its * interaction instructions are no longer repeated (`provider-acp/src/server/adapter.ts:7347-7352,7366-7368`), * and `AgentSession.prompt` accepts an empty message beside images, so a screenshot sent alone must * not fail. Whitespace never survives as the text, matching Selesai's TUI. */ export declare function renderPromptContent(content: readonly ContentBlock[]): RenderedPromptContent; /** * Convert Selesai's slash commands into one ACP command list. T3 drops a name that is untrimmed or * longer than 128 characters, treats a `$`-prefixed name as a skill and inserts it as `$name`, and * keeps the first 128 accepted entries (`probe.ts:41-54,214-245`); `ChatComposer.tsx:1912-1930` * inserts `$name` and `/name` respectively. T3 sends a picked skill as plain `$name` text, so skills * are advertised as `$name` (what T3's `$` menu lists) and the adapter rewrites a leading `$name` * to the `/skill:name` Selesai expands (`agent-session.ts:2160-2192,2289-2291`). Other `$`-prefixed * names are dropped instead of being shown as dead skills. */ export declare function createAvailableCommandsUpdate(commands: readonly RpcSlashCommand[]): Extract; /** Names of the skills advertised as `$name`, used to rewrite a leading `$name` mention. */ export declare function skillNames(update: ReturnType): Set; /** Rewrite a leading `$skill args` mention of a known skill to Selesai's `/skill:skill args`. */ export declare function expandSkillMention(text: string, skills: ReadonlySet): string; /** * Convert Selesai's context accounting into an ACP usage sample. The context window must be a * positive size because T3 only shows a meter for `size > 0`; a null estimate skips the sample. * Cost is Selesai's cumulative session cost in USD, matching its own `formatCost` display. */ export declare function createUsageUpdate(stats: SessionStats): Extract | undefined; export interface RpcEventMapper { /** Map one JSON-RPC event into zero or more stable ACP session updates. */ mapEvent(event: RpcEvent): SessionUpdate[]; } /** * Create one mapper per ACP session turn. `sessionNamespace` and `turnNamespace` must be unique * within their respective scopes (UUIDs are suitable); this keeps ACP tool IDs unique across turns. */ export declare function createRpcEventMapper(sessionNamespace: string, turnNamespace: string): RpcEventMapper; export interface TerminalResultMapper { /** Returns a prompt result only when the input event is agent_settled; agent_end is not terminal. */ mapEvent(event: RpcEvent, options?: { cancelRequested?: boolean; }): PromptResponse | undefined; } /** Track the last assistant outcome, ignoring intermediate errors that a later retry replaces. */ export declare function createTerminalResultMapper(): TerminalResultMapper;