/** Local AI 0.13.0 bundled speech engine and managed voice models. Optional at runtime; inspect speech/status first. * This is a Sidecar contract, not a new published @capp npm package. */ export type LocalSpeechVoice = 'bm_george'|'bf_emma'|'af_heart'|'af_sarah'|'am_michael'; export type LocalSpeechStartup = 'manual'|'download'|'download-load'; export interface LocalSpeechSettings { enabled:boolean; voice:LocalSpeechVoice; speed:number; volume:number; startupPolicy:LocalSpeechStartup; threads:number; idleSeconds:number; } export interface LocalSpeechPreparation {ok:true;prepared:true;loaded:boolean;synthesisVerified?:boolean;integrityVerified?:boolean;requestId:string;} export interface LocalSpeechResult { ok:boolean; provider?:string; voice?:string; segments:number; firstAudioMs?:number; synthesisMs?:number; elapsedMs?:number; nativeRoundTripMs?:number; decodeMs?:number; audioDurationMs?:number; playbackGapMs?:number; realTimeFactor?:number|null; cacheHits?:number; normalizationMs?:number; phonemizationMs?:number; inferenceMs?:number; encodingMs?:number; error?:string; } export interface LocalSpeechProgress { phase:string; asset?:string; bytes?:number; totalBytes?:number; fileIndex?:number; fileCount?:number; prepared?:boolean; error?:string|null; requestId?:string; } export interface LocalSpeechStatus { protocol:'capp.local-speech.v1'; supported:boolean; prepared:boolean; loaded:boolean; busy:boolean; enabled:boolean; allowed:boolean; settings:LocalSpeechSettings; textModelIndependent:true; streaming:'bounded-sentence-segments'; error?:string|null; engineBundled?:boolean; weightsBundled?:false; engine?:{bundled:boolean;delivery:string;target:string;backend:string;dependencies:string}; model?:{id:string;label:string;downloaded:boolean;shared?:boolean;directory?:string;files?:Record}; last:LocalSpeechResult|null; managed?:boolean; autoPrepare?:boolean; runtimeId?:string; progress?:LocalSpeechProgress; } export interface LocalSpeechConnection { protocol:'capp.local-speech.v1'; /** Call from a user gesture. Arms playback, then ensures managed speech readiness. * The engine is installed with the app. Missing model assets are fetched only when compiled speechAutoPrepare permits it. * Joins existing boot preparation; cancellation releases only this client's wait. * Resolves only after a fixed synthesis probe; does not load/change the GGUF slot. */ activate():Promise<{ok:true}>; status():Promise; /** 1–1200 characters; short first phrase, <=12 bounded segments. * One lookahead is synthesised during playback and scheduled on the audio clock. * realTimeFactor below 1 means synthesis took less time than the resulting audio. * Rejects when busy; cancellation stops current and scheduled audio. */ speak(options:{text:string;voice?:LocalSpeechVoice;speed?:number;volume?:number; onProgress?:(event:LocalSpeechProgress)=>void;onStart?:(event:{id:string;firstAudioMs?:number;firstSegmentChars?:number})=>void;onSegment?:(event:{index:number;text:string})=>void}):Promise; /** Requests cancellation of this connection only; await original speak() settlement. */ cancel():Promise<{ok:true;cancelled:boolean}>; dispose():void; } export interface LocalSpeechOwner { protocol:'capp.local-speech.v1'; connect(options:{protocol:string;clientName?:string;appId?:string}):LocalSpeechConnection; status():Promise; getSettings():LocalSpeechSettings; configure(settings:Partial):Promise; /** Owner-only explicit preparation/repair; never downloads from an arbitrary URL. */ prepare(options?:{repair?:boolean;load?:boolean;onProgress?:(event:LocalSpeechProgress)=>void}):Promise; /** Owner boot hook; no audio context or audible playback. At most once per shell. */ startup():Promise; /** Offline load; does not download. Tests synthesis without playing audio. */ load():Promise; /** Hash-checks the installed engine and model files; no synthesis. */ verify():Promise; /** Native owner dialogs select the supported ONNX/voice pair; no caller paths. */ importModels():Promise; /** Preserve engine/GGUF, remove this voice model pair and set startup Manual. */ /** Windows deletion removes the shared pair for every app; requires explicit user confirmation. */ deleteModel(options?:{sharedConfirmed?:boolean}):Promise<{ok:true;prepared:false;loaded:false;enginePreserved:true}>; cancelPreparation():Promise<{ok:true;cancelled:boolean}>; subscribe(listener:(event:LocalSpeechProgress)=>void):()=>void; unload():Promise<{ok:true;loaded:false}>; dispose():void; } export interface LocalAIModelSlots { protocol:'capp.local-ai.slots.v1'; text:{kind:'gguf-text';residentLimit:1}; speech:LocalSpeechStatus&{kind:'kokoro-onnx-tts';residentLimit:1}; vision:{supported:false};transcription:{supported:false}; }