/** * @license * Copyright 2026 Qwen * SPDX-License-Identifier: Apache-2.0 */ export type InjectorItemKind = 'complete' | 'progress' | 'permission' | 'task_result' | 'task_rejection' | 'error' | 'speak' | 'control' | 'peer_report' | 'search_result' | 'proactive'; export interface InjectorItem { kind: InjectorItemKind; /** Silent context body; peer reports use this only as a quoted speech body. */ context: string; /** Verbatim spoken line; omitted items inject silently. */ spoken?: string; jobHandle?: string; /** For permission items: lets a remote resolution retract the ask. */ requestId?: string; announce?: boolean; /** Stable scheduler delivery id for a queued Proactive announcement. */ deliveryId?: string; /** Daemon-owned text receipt, acknowledged only after full context delivery. */ controlId?: string; /** Call-scoped external report identity, separate from jobs and controls. */ reportId?: string; /** Call-scoped search task identity, separate from backend job handles. */ searchId?: string; } export interface InjectorSink { /** Silent context injection; false when the transport refused. */ injectContext(text: string): boolean; /** Verbatim speech request; false when the transport refused. */ injectSpeech(text: string): boolean; /** Model-authored permission question; never fall back to verbatim speech. */ injectPermission?(text: string): boolean; /** Model-authored task outcome; must never inherit a tool capability. */ injectTaskResult?(text: string): boolean; /** Locally authored correction; never merge into the main conversation. */ injectTaskRejection?(text: string): boolean; /** A model-authored Proactive response request; false when refused. */ injectProactive?(text: string): boolean; /** Isolated external quotation; must never fall back to ordinary speech. */ injectPeerReport?(text: string, reportId?: string): boolean; /** Answer from quoted search evidence; never fall back to ordinary speech. */ injectSearchResult?(text: string, searchId?: string): boolean; /** Accepted by the transport; this does not acknowledge Host playback. */ onInjected?(item: InjectorItem, spoken: boolean): void; } export interface InjectorOptions { sink: InjectorSink; now?: () => number; quietGapMs?: number; progressThrottleMs?: number; } export declare class Injector { private readonly sink; private readonly now; private readonly quietGapMs; private readonly progressThrottleMs; private queue; private speechInProgress; private responseInFlight; private directResponsePending; private responseRequestPending; private notificationRequestPending; private transportRecovering; private recoveredInputPending; private recoveredInputTimer; private playbackInProgress; private playbackCompletedAt; private proactiveCycle; private peerReportCycle; private readonly seenPeerReports; private searchResultCycle; private readonly seenSearchResults; private lastProgressAt; private timer; private disposed; private flushing; constructor(options: InjectorOptions); noteSpeechStarted(): boolean; noteInputCommitted(responsePending?: boolean): void; /** Direct responses can establish a newer input without a preceding VAD event. */ discardTaskRejections(): void; noteResponseCreated(authority?: string): void; noteResponseDone(authority?: string): void; /** Fence stale transport state without treating it as a completed response. */ beginTransportRecovery(): void; /** Preserve the order of undelivered Proactive items ahead of newer events. */ restoreProactiveAfterRecovery(items: readonly InjectorItem[]): void; completeTransportRecovery(inputKind: 'text' | 'audio' | 'none'): void; private clearRecoveredInputTimer; notePlaybackStarted(): void; notePlaybackCompleted(): void; noteOutputCleared(): void; /** * Release playback suppressed by an explicit user mute. A Proactive cycle * is completed only when the caller confirms that real response audio was * present; muting before any audio must not turn a silent response into a * successful delivery. */ noteOutputSuppressed(completeProactive?: boolean): void; enqueue(item: InjectorItem): boolean; /** Retract a queued permission ask that was resolved elsewhere. */ retractPermission(requestId: string): boolean; /** Retract a Proactive event that has not been submitted to Realtime yet. */ retractProactive(deliveryId: string): boolean; /** Release an accepted Proactive cycle after cancellation or fatal failure. */ abortProactive(deliveryId: string): boolean; /** * Atomically put an interrupted Proactive delivery back at the head of its * lane. Resetting the active cycle and prepending must be one operation; * otherwise aborting first could let the next queued delivery overtake it. */ retryProactiveAtFront(item: InjectorItem): boolean; get pendingCount(): number; /** A user mute consumes queued reports without blocking ordinary context. */ dropPeerReports(): string[]; /** Retract a result not yet submitted; active responses require Realtime cancellation. */ retractSearchResult(searchId: string): boolean; /** Muting or ending a call can discard pending speech without changing task outcomes. */ dropSearchResults(): string[]; dispose(): void; private windowClosedForMs; private poke; private flush; private flushProactive; private flushNotification; private flushControl; private flushPeerReport; private finishPeerReportCycleIfComplete; private flushSearchResult; private finishSearchResultCycleIfComplete; private finishProactiveCycleIfComplete; }