export const MAX_REALTIME_VOICE_INPUT_BYTES = 32 * 1024; export function renderRealtimeDelegation(input: string, transcriptDelta?: string): string { const transcript = transcriptDelta ? `\n ${escapeXml(transcriptDelta)}` : ""; return `\n ${escapeXml(input)}${transcript}\n`; } export function renderRealtimeConversationInput(input: string): string { return `\n ${escapeXml(input)}\n handled by realtime voice; no Pi action requested\n`; } export function renderRealtimeTranscriptTail(transcriptDelta: string): string { return `\n transcript_tail_flush\n The user just ended their realtime session. Here is the remaining transcript tail. Do not respond unless it contains an unhandled request.\n ${escapeXml(transcriptDelta)}\n`; } export function renderPiSteer(input: unknown): string | undefined { if (typeof input !== "string") return undefined; const text = input.trim(); if (!text || Buffer.byteLength(text) > MAX_REALTIME_VOICE_INPUT_BYTES) return undefined; return `\n ${escapeXml(text)}\n already delivered to the active Pi run; update context, do not delegate it, and wait for authoritative Pi updates\n`; } function escapeXml(value: string): string { return value .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">"); }