/** * LivePromptAssembler — Port for building system prompts optimized for * realtime audio models (Gemini Live, OpenAI Realtime, etc.). * * This is the PORT (interface) in the Ports & Adapters pattern. * The default implementation (`DefaultLivePromptAssembler`) bridges * CapabilityHost with Runtime context (working memory, long-term memory, * policy injections) and structures the output per audio-model best practices. * * Adapters can extend or replace * the default with backend-specific voice rules and guardrails. * * Prompt structure follows Google's Live API best practices and * OpenAI's Realtime Prompting Guide: * * 1. Persona — WHO you are * 2. Voice Rules — Audio-specific constraints * 3. Conversation Flow — Current task + collected state * 4. Tool Directives — WHEN to call each tool * 5. Context — Working memory + long-term memory * 6. Guardrails — Safety, escalation, unclear audio * * @see https://ai.google.dev/gemini-api/docs/live-api/best-practices * @see https://developers.openai.com/cookbook/examples/realtime_prompting_guide */ import type { Session } from '../types/index.js'; import type { CapabilityHost, ToolDeclaration } from './index.js'; import type { ExtractedValueStore } from '../memory/extract/store.js'; import { type ContextBudgetConfig } from '../runtime/ContextBudget.js'; /** * Input context for prompt assembly. Passed on every connect/reconfigure. */ export interface LivePromptContext { /** The CapabilityHost providing tools and prompt sections. */ host: CapabilityHost; /** Base agent prompt (persona, role, core instructions). */ basePrompt: string; /** Current session — used for working memory injection. */ session?: Session; /** Cross-session extracted facts store for long-term context. */ extractedValueStore?: ExtractedValueStore; /** Latest user input — used as search query for memory retrieval. */ lastUserInput?: string; /** Policy injection strings (from InjectionQueue.getFor('system')). */ policyInjections?: string; } /** * PORT: Assembles system prompts for realtime audio LLM sessions. * * Implementations control voice rules, guardrails, tool directive formatting, * and section ordering. The realtime orchestration authority calls this on * every connect and reconfigure, passing the current CapabilityHost state and * session context. */ export interface LivePromptAssembler { /** * Build a complete system prompt string from the given context. * May be async to support memory preloading. */ assemble(ctx: LivePromptContext): Promise; /** * Synchronous variant for initial connect (before any user input). * Skips async memory preloading. */ assembleSync(ctx: Omit): string; } export declare const DEFAULT_VOICE_RULES = "## Voice Rules\n- Keep responses to 2-3 sentences per turn. Be concise.\n- Do NOT output markdown, bullet points, numbered lists, or any formatting.\n- Do NOT include sound effects, onomatopoeia, or non-speech sounds.\n- Speak numbers digit-by-digit when reading codes or IDs: \"4-1-5\" not \"four fifteen\".\n- If user audio is unclear, ask for clarification. Do not guess.\n- Do NOT repeat back what the user just said. Move the conversation forward.\n- Vary your responses. Do not use the same opening or confirmation phrase twice in a row."; export declare const DEFAULT_GUARDRAILS = "## Guardrails\n- Only respond to clear audio or text input.\n- If you cannot help with a request, say so briefly and offer to help with something else.\n- All claims must be grounded in provided context or tool results. Do not fabricate information.\n- If unsure about any action, ask for clarification rather than guessing."; export interface DefaultLivePromptAssemblerConfig { /** Custom voice rules to override DEFAULT_VOICE_RULES. */ voiceRules?: string; /** Custom guardrails to override DEFAULT_GUARDRAILS. */ guardrails?: string; /** Working memory allowlist — only these keys are injected. */ promptMemoryAllowlist?: string[]; /** Token budget overrides. */ budget?: Partial; } /** * Default LivePromptAssembler implementation. * * Backend-agnostic — produces a plain string suitable for any realtime * audio model. Adapters can extend this class to add backend-specific * sections or override the voice rules. */ export declare class DefaultLivePromptAssembler implements LivePromptAssembler { private voiceRules; private guardrails; private allowlist?; private budget; constructor(config?: DefaultLivePromptAssemblerConfig); assemble(ctx: LivePromptContext): Promise; assembleSync(ctx: Omit): string; /** * Build the core sections array. Shared by both sync and async paths. * Subclasses can override to add/reorder sections. */ protected buildCoreSections(ctx: Omit): string[]; /** * Format tool declarations as in-prompt directives. * Subclasses can override for backend-specific formatting. */ protected buildToolDirectives(tools: ToolDeclaration[]): string; /** * Extract and format working memory from the session. */ private buildWorkingMemorySection; }