/** * Second-opinion re-transcription for DIRECT koi addresses. * * In a noisy room the realtime STT reliably catches the wake word (context * biasing) but garbles the QUESTION — 2026-07-07 the owner asked "Koi, where * does that water live?" and the live stream delivered "Koi, what is it? * What are the." The koi then confidently answers a question that was never * asked. The SAME audio re-run through Whisper recovered the real question, * so: when the owner addresses the koi, re-transcribe just that utterance's * audio through Groq Whisper (concurrently with the context load — no added * latency) and hand BOTH hearings to the responder. * * Audio sources, in order: * 1. the per-utterance PCM clip (precise, but the voice-ID bridge deletes * clips seconds after embedding — often already gone by eval time), * 2. the 60s rolling WAV buffer chunk covering the utterance timestamp * (lives 24h; upload the chunk, keep only segments overlapping the * utterance window). */ /** * Preserve the DIARIZED per-utterance clip the moment its trigger arrives. * The voice-ID bridge reaps clips seconds after embedding, so by eval time * the precise single-speaker audio is usually gone and the second opinion * would fall back to UNSEPARATED room audio — losing exactly what Soniox's * diarization+endpointing provides. Copy is a few hundred KB; stale * snapshots are pruned on each call. Returns the snapshot path, or null. */ export declare function snapshotClip(audioPath: string | undefined): string | null; /** Wrap raw 16 kHz mono s16le PCM (the daemon's clip format) in a WAV header. */ export declare function wavFromPcm16(pcm: Buffer, sampleRate?: number): Buffer; /** Find the rolling-buffer chunk whose 60s window covers `ts`. */ export declare function findBufferChunk(ts: number, dir?: string): { path: string; startMs: number; } | null; export interface SecondOpinion { text: string; /** "clip" = the diarized single-utterance audio (trustworthy attribution); * "window" = unseparated room audio around the moment (may mix speakers). */ source: "clip" | "window"; } /** * Re-transcribe the addressed utterance's audio and return the alternate * hearing when it MATERIALLY differs from the realtime transcript. Returns * null when the second engine agrees, the audio is gone, or Groq is * unavailable — callers treat null as "nothing to add". */ export declare function secondOpinionTranscript(opts: { text: string; ts: number; audioPath?: string; bufferDir?: string; apiKey?: string; timeoutMs?: number; fetchImpl?: typeof fetch; }): Promise;