@@ -9,8 +9,9 @@ import chalk from "@oh-my-pi/pi-utils/chalk";
99import { Settings , settings } from "../config/settings" ;
1010import { checkPythonKernelAvailability } from "../eval/py/kernel" ;
1111import { theme } from "../modes/theme/theme" ;
12+ import { appleSpeechClient } from "../stt/apple-speech-client" ;
1213import { downloadSttModel , isSttModelCached } from "../stt/downloader" ;
13- import { isSttModelKey , STT_MODEL_OPTIONS } from "../stt/models" ;
14+ import { isSttModelKey , resolveSttModelSpec , STT_MODEL_OPTIONS } from "../stt/models" ;
1415import { downloadTtsModel , isTtsLocalModelKey , isTtsModelCached , TTS_LOCAL_MODEL_OPTIONS } from "../tts" ;
1516import { selectSetupModel } from "./setup-model-picker" ;
1617
@@ -147,9 +148,9 @@ async function handlePythonSetup(flags: { json?: boolean; check?: boolean }): Pr
147148}
148149
149150/**
150- * One installable speech dependency. `isReady`/`status` are read-only probes;
151- * `pick` (optional) lets an interactive user choose + persist a model ; `ensure`
152- * performs the download, streaming a normalized progress event .
151+ * One speech dependency. `isReady`/`status` are read-only probes; `pick`
152+ * (optional) lets an interactive user choose + persist an engine ; `ensure`
153+ * prepares its application-managed model or system-managed locale asset .
153154 */
154155interface SpeechComponent {
155156 name : string ;
@@ -163,10 +164,23 @@ function buildSpeechComponents(): SpeechComponent[] {
163164 return [
164165 {
165166 name : "Speech-to-Text model" ,
166- isReady : ( ) => isSttModelCached ( settings . get ( "stt.modelName" ) ) ,
167+ isReady : async ( ) => {
168+ const spec = resolveSttModelSpec ( settings . get ( "stt.modelName" ) ) ;
169+ if ( spec . engine === "speech-analyzer" ) {
170+ return ( await appleSpeechClient . status ( settings . get ( "stt.language" ) ) ) . installed ;
171+ }
172+ return await isSttModelCached ( spec . key ) ;
173+ } ,
167174 status : async ( ) => {
168- const key = settings . get ( "stt.modelName" ) ;
169- return ( await isSttModelCached ( key ) ) ? key : `${ key } — not downloaded` ;
175+ const spec = resolveSttModelSpec ( settings . get ( "stt.modelName" ) ) ;
176+ if ( spec . engine === "speech-analyzer" ) {
177+ const status = await appleSpeechClient . status ( settings . get ( "stt.language" ) ) ;
178+ if ( status . installed ) {
179+ return `${ spec . key } — ${ status . locale ?? "system locale" } (system-managed)` ;
180+ }
181+ return `${ spec . key } — ${ status . error ?? "locale asset not prepared" } ` ;
182+ }
183+ return ( await isSttModelCached ( spec . key ) ) ? spec . key : `${ spec . key } — not downloaded` ;
170184 } ,
171185 pick : async ( ) => {
172186 const chosen = await selectSetupModel (
@@ -181,10 +195,21 @@ function buildSpeechComponents(): SpeechComponent[] {
181195 }
182196 return true ;
183197 } ,
184- ensure : onProgress =>
185- downloadSttModel ( settings . get ( "stt.modelName" ) , progress =>
198+ ensure : async onProgress => {
199+ const spec = resolveSttModelSpec ( settings . get ( "stt.modelName" ) ) ;
200+ if ( spec . engine === "speech-analyzer" ) {
201+ onProgress ( { stage : "Preparing system-managed Apple speech recognition" } ) ;
202+ const status = await appleSpeechClient . prepare ( settings . get ( "stt.language" ) ) ;
203+ onProgress ( {
204+ stage : `Apple speech recognition ready${ status . locale ? ` (${ status . locale } )` : "" } ` ,
205+ percent : 100 ,
206+ } ) ;
207+ return ;
208+ }
209+ await downloadSttModel ( spec . key , progress =>
186210 onProgress ( { stage : `Downloading ${ progress . label } model` , percent : progress . percent } ) ,
187- ) ,
211+ ) ;
212+ } ,
188213 } ,
189214 {
190215 name : "Text-to-Speech model" ,
0 commit comments