@@ -5,6 +5,7 @@ import { type AudioFrame } from '@livekit/rtc-node';
55import type { WebSocket } from 'ws' ;
66import { APIError , APIStatusError } from '../_exceptions.js' ;
77import { AudioByteStream } from '../audio.js' ;
8+ import { type LanguageCode , areLanguagesEquivalent , normalizeLanguage } from '../language.js' ;
89import { log } from '../log.js' ;
910import { createStreamChannel } from '../stream/stream_channel.js' ;
1011import {
@@ -121,10 +122,10 @@ export interface STTFallbackModel {
121122export type STTFallbackModelType = STTFallbackModel | string ;
122123
123124/** Parse a model string into [model, language]. Language is undefined if not specified. */
124- export function parseSTTModelString ( model : string ) : [ string , string | undefined ] {
125+ export function parseSTTModelString ( model : string ) : [ string , LanguageCode | undefined ] {
125126 const idx = model . lastIndexOf ( ':' ) ;
126127 if ( idx !== - 1 ) {
127- return [ model . slice ( 0 , idx ) , model . slice ( idx + 1 ) ] ;
128+ return [ model . slice ( 0 , idx ) , normalizeLanguage ( model . slice ( idx + 1 ) ) ] ;
128129 }
129130 return [ model , undefined ] ;
130131}
@@ -156,7 +157,7 @@ const DEFAULT_CANCEL_TIMEOUT = 5000;
156157
157158export interface InferenceSTTOptions < TModel extends STTModels > {
158159 model ?: TModel ;
159- language ?: STTLanguages ;
160+ language ?: LanguageCode ;
160161 encoding : STTEncoding ;
161162 sampleRate : number ;
162163 baseURL : string ;
@@ -219,25 +220,24 @@ export class STT<TModel extends STTModels> extends BaseSTT {
219220 let nextModel = model ;
220221 let nextLanguage = language ;
221222 if ( typeof nextModel === 'string' ) {
222- const idx = nextModel . lastIndexOf ( ':' ) ;
223- if ( idx !== - 1 ) {
224- const languageFromModel = nextModel . slice ( idx + 1 ) as STTLanguages ;
225- if ( nextLanguage && nextLanguage !== languageFromModel ) {
223+ const [ parsedModel , parsedLanguage ] = parseSTTModelString ( nextModel ) ;
224+ if ( parsedLanguage !== undefined ) {
225+ if ( nextLanguage && ! areLanguagesEquivalent ( nextLanguage , parsedLanguage ) ) {
226226 this . #logger. warn (
227227 '`language` is provided via both argument and model, using the one from the argument' ,
228228 { language : nextLanguage , model : nextModel } ,
229229 ) ;
230230 } else {
231- nextLanguage = languageFromModel ;
231+ nextLanguage = parsedLanguage as STTLanguages ;
232232 }
233- nextModel = nextModel . slice ( 0 , idx ) as TModel ;
233+ nextModel = parsedModel as TModel ;
234234 }
235235 }
236236 const normalizedFallback = fallback ? normalizeSTTFallback ( fallback ) : undefined ;
237237
238238 this . opts = {
239239 model : nextModel as TModel ,
240- language : nextLanguage ,
240+ language : nextLanguage ? normalizeLanguage ( nextLanguage ) : undefined ,
241241 encoding,
242242 sampleRate,
243243 baseURL : lkBaseURL ,
@@ -263,7 +263,11 @@ export class STT<TModel extends STTModels> extends BaseSTT {
263263 }
264264
265265 updateOptions ( opts : Partial < Pick < InferenceSTTOptions < TModel > , 'model' | 'language' > > ) : void {
266- this . opts = { ...this . opts , ...opts } ;
266+ this . opts = {
267+ ...this . opts ,
268+ ...opts ,
269+ language : opts . language !== undefined ? normalizeLanguage ( opts . language ) : this . opts . language ,
270+ } ;
267271
268272 for ( const stream of this . streams ) {
269273 stream . updateOptions ( opts ) ;
@@ -278,7 +282,7 @@ export class STT<TModel extends STTModels> extends BaseSTT {
278282 options || { } ;
279283 const streamOpts = {
280284 ...this . opts ,
281- language : language ?? this . opts . language ,
285+ language : language !== undefined ? normalizeLanguage ( language ) : this . opts . language ,
282286 } as InferenceSTTOptions < TModel > ;
283287
284288 const stream = new SpeechStream ( this , streamOpts , connOptions ) ;
@@ -364,7 +368,11 @@ export class SpeechStream<TModel extends STTModels> extends BaseSpeechStream {
364368 }
365369
366370 updateOptions ( opts : Partial < Pick < InferenceSTTOptions < TModel > , 'model' | 'language' > > ) : void {
367- this . opts = { ...this . opts , ...opts } ;
371+ this . opts = {
372+ ...this . opts ,
373+ ...opts ,
374+ language : opts . language !== undefined ? normalizeLanguage ( opts . language ) : this . opts . language ,
375+ } ;
368376 this . reconnectEvent . set ( ) ;
369377 }
370378
@@ -569,7 +577,7 @@ export class SpeechStream<TModel extends STTModels> extends BaseSpeechStream {
569577
570578 const requestId = data . session_id || this . requestId ;
571579 const text = data . transcript ;
572- const language = data . language || this . opts . language || 'en' ;
580+ const language = normalizeLanguage ( data . language || this . opts . language || 'en' ) ;
573581
574582 if ( ! text && ! isFinal ) return ;
575583
0 commit comments