import { AssistantConversationProcessing, AssistantTurnStage } from './conversation'; import { AssistantTr } from './i18n'; /** * The waiting copy for a live turn, derived from its processing state. * * ★★ Nothing here reads or writes message content (BOFF-7277). Everything is a * pure function of the processing entry and elapsed time; the clock that * advances it lives in the leaf that renders it, `AssistantTurnActivity`. */ /** * The step to describe, or `null` when there is nothing honest to say. * * ★ `provisioning` with no stage is the synchronous write before the runtime * has looked at anything. Guessing "Starting..." there would flash the wrong * word on every reused sandbox a moment before the real step arrives, so it * says nothing and the avatar and caret carry the wait. */ export declare function turnActivityStage(processing: AssistantConversationProcessing | null | undefined): AssistantTurnStage | null; export interface TurnActivityCopy { /** For the eye. Rotates while thinking; otherwise identical to `label`. */ readonly shown: string; /** For assistive tech. Changes only when the step does. */ readonly label: string; /** * Whether this step is ELIGIBLE to rotate (thinking). The component holds it * still under reduced motion by passing no elapsed time — see * `AssistantTurnActivity`. */ readonly rotating: boolean; } /** * What to show for a live turn that has produced nothing yet. * * ★ Environment steps are informative and hold still. Only `thinking` rotates: * a single frozen word for the length of a turn reads as a hang. * * ★★ A phrase is shown only in the SAME translation state as the thinking * label, as on the voice status line. The phrases are separately seeded keys; if * the label is translated and a phrase is not, rotating would alternate the * user's language with English, so the line holds on the translated label. * * Pure in `elapsedMs` — the caller owns the clock. */ export declare function turnActivityCopy(tr: AssistantTr, processing: AssistantConversationProcessing | null | undefined, elapsedMs: number): TurnActivityCopy | null; /** * Time a rotation has run: from the stage's stored `origin` to the last tick. * * `null` origin — not rotating, or holding still for reduced motion — is 0, * which is the stable label. Never negative: `now` lags the real clock, so a * stage that began after the last tick reads as just started. */ export declare function elapsedSince(origin: number | null, now: number): number; /** * Milliseconds until the phrase at `elapsedMs` is replaced by the next one. * * Always in (0, PHRASE_ROTATE_MS], so a tick scheduled with it lands on the * boundary instead of up to a whole phrase late. */ export declare function msUntilNextPhrase(elapsedMs: number): number; /** * Call `onTick(now)` at each phrase boundary after `startedAt`, until stopped. * * ★ Boundary-aligned timeouts rather than a fixed interval: the origin is the * stage's stored start, which is usually well before this component mounted, so * an interval started at mount would change phrase at the wrong moments. * * Returns the stop function — an effect's cleanup. */ export declare function startPhraseTicker(startedAt: number, onTick: (now: number) => void, clock?: () => number): () => void; //# sourceMappingURL=turnActivity.d.ts.map