import { VoiceSessionSnapshot } from './voiceSession'; export type VoiceStageState = 'connecting' | 'listening' | 'endpoint-grace' | 'thinking' | 'speaking' | 'interrupting' | 'mic-error' | 'ended'; export interface StageInputs { snapshot: VoiceSessionSnapshot; /** Is the recogniser genuinely running? False during start-up. */ capturing: boolean; /** True from the moment the user cuts the assistant off until listening resumes. */ interrupting?: boolean; /** * The user has stopped producing new words and the submit timer is running. * * Its own state because the checklist asks for it: the two-second correction * window should look like a deliberate pause the user can still speak into, * not like the session has already moved on. */ awaitingEndpoint?: boolean; } /** * Precedence is the whole design. A failure outranks a phase — a session that * cannot hear must never render as "Listening…", which is precisely the lie the * operator screenshotted. */ export declare function voiceStageState({ snapshot, capturing, interrupting, awaitingEndpoint, }: StageInputs): VoiceStageState; /** Does this stage show the user's live transcript rather than the reply? */ export declare function showsUserCaption(state: VoiceStageState): boolean; /** Does this stage show the assistant's caption? */ export declare function showsAssistantCaption(state: VoiceStageState): boolean; /** * Is the microphone control an INTERRUPT rather than a mute toggle? * * ★★ `thinking` too, as of the cancellation work. It used to be `speaking` * only, which meant the orb was inert for the whole time the model was * generating — the user could only stop an answer that had already finished, * which is not really interrupting. Everything that makes stopping a running * turn safe now ships: the sandbox `/abort` route (verified in prod), * `planTurnAbort` so a late abort cannot kill a newer turn, `planAbandonedTurn` * so the cancelled turn's own loop stops, and `publishedChunks` so its caption * cannot survive it. Those guards existed for an action the UI did not allow. * * ★ This is NOT the same question as "does this stage show the assistant's * caption" — use `showsAssistantCaption` for that. The two coincided while both * meant `speaking`, and one call site was reading this one to pick a caption. */ export declare function micIsInterrupt(state: VoiceStageState): boolean; /** * Does this stage show a LIVE waveform? * * ★ Shared rather than repeated, because the two surfaces had already drifted: * the full stage and the docked strip each answered this question with their * own inline expression, so teaching one about a new state silently left the * other frozen. `endpoint-grace` in particular MUST animate — it is the window * in which the user may still be talking, and a still waveform beside the words * "still listening" says the opposite of the label. */ export declare function waveformIsActive(state: VoiceStageState): boolean; /** * Is the waveform open but WAITING rather than actively hearing speech? * * The correction window is not the same as mid-sentence listening, and a status * line is a weak way to say so: a calmer, shorter profile makes the pause * visible without implying the microphone closed. */ export declare function waveformIsSettled(state: VoiceStageState): boolean; //# sourceMappingURL=voiceStageState.d.ts.map