assemblyai 4.35.0 → 4.35.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.35.3]
4
+
5
+ - Allow `language_codes` in `updateConfiguration()` — re-steer the transcription language mid-stream without reconnecting; pass `[]` to clear steering and restore the model's default multilingual code-switching (Universal-3.5 Pro Streaming only)
6
+
7
+ ## [4.35.2]
8
+
9
+ - Add `opus` and `ogg_opus` streaming `encoding` values — accepts compressed Opus audio (raw packet-per-message or Ogg-encapsulated). `sampleRate` is ignored for both; the Opus stream is self-describing
10
+
11
+ ## [4.35.1]
12
+
13
+ - Add `languageCodes` streaming parameter — steers transcription toward a set of languages (Universal-3.5 Pro Streaming only). Recommended replacement for `languageCode`, which is now deprecated but still supported
14
+
3
15
  ## [4.34.6]
4
16
 
5
17
  - Add `keepAlive()` method to `StreamingTranscriber` — sends a `KeepAlive` message to reset the server's inactivity timer when `inactivityTimeout` is configured
package/README.md CHANGED
@@ -129,7 +129,7 @@ const audioFile = "https://assembly.ai/sports_injuries.mp3";
129
129
 
130
130
  const params = {
131
131
  audio: audioFile,
132
- speech_models: ["universal-3-pro", "universal-2"],
132
+ speech_models: ["universal-3-5-pro", "universal-2"],
133
133
  language_detection: true,
134
134
  };
135
135
 
@@ -151,7 +151,7 @@ If you don't want to wait until the transcript is ready, you can use `submit`:
151
151
  ```js
152
152
  let transcript = await client.transcripts.submit({
153
153
  audio: "https://assembly.ai/espn.m4a",
154
- speech_models: ["universal-3-pro", "universal-2"],
154
+ speech_models: ["universal-3-5-pro", "universal-2"],
155
155
  language_detection: true,
156
156
  });
157
157
  ```
@@ -167,7 +167,7 @@ When you create a transcript, you can either pass in a URL to an audio file or u
167
167
  // Upload a file via local path and transcribe
168
168
  let transcript = await client.transcripts.transcribe({
169
169
  audio: "./news.mp4",
170
- speech_models: ["universal-3-pro", "universal-2"],
170
+ speech_models: ["universal-3-5-pro", "universal-2"],
171
171
  language_detection: true,
172
172
  });
173
173
  ```
@@ -182,7 +182,7 @@ If you don't want to wait until the transcript is ready, you can use `submit`:
182
182
  ```js
183
183
  let transcript = await client.transcripts.submit({
184
184
  audio: "./news.mp4",
185
- speech_models: ["universal-3-pro", "universal-2"],
185
+ speech_models: ["universal-3-5-pro", "universal-2"],
186
186
  language_detection: true,
187
187
  });
188
188
  ```
@@ -206,7 +206,7 @@ const audioFile = "https://assembly.ai/wildfires.mp3";
206
206
 
207
207
  const params = {
208
208
  audio: audioFile,
209
- speech_models: ["universal-3-pro", "universal-2"],
209
+ speech_models: ["universal-3-5-pro", "universal-2"],
210
210
  language_detection: true,
211
211
  speaker_labels: true,
212
212
  };
@@ -313,15 +313,14 @@ const res = await client.transcripts.delete(transcript.id);
313
313
 
314
314
  ### Transcribe streaming audio
315
315
 
316
- Refer to [AssemblyAI's streaming documentation](https://www.assemblyai.com/docs/getting-started/transcribe-streaming-audio) for full code examples.
316
+ Refer to [AssemblyAI's streaming documentation](https://www.assemblyai.com/docs/streaming/getting-started/transcribe-streaming-audio) for full code examples.
317
317
 
318
318
  Create the streaming transcriber.
319
319
 
320
320
  ```typescript
321
321
  const transcriber = client.streaming.transcriber({
322
- speechModel: "u3-rt-pro",
322
+ speechModel: "universal-3-5-pro",
323
323
  sampleRate: 16_000,
324
- formatTurns: true,
325
324
  });
326
325
  ```
327
326
 
@@ -741,8 +741,12 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
741
741
  searchParams.set("speech_model", this.params.speechModel.toString());
742
742
  }
743
743
  if (this.params.languageCode !== undefined) {
744
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
744
745
  searchParams.set("language_code", this.params.languageCode);
745
746
  }
747
+ if (this.params.languageCodes !== undefined) {
748
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
749
+ }
746
750
  if (this.params.languageDetection !== undefined) {
747
751
  searchParams.set("language_detection", this.params.languageDetection.toString());
748
752
  }
@@ -1369,7 +1373,7 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
1369
1373
  defaultUserAgentString += navigator.userAgent;
1370
1374
  }
1371
1375
  const defaultUserAgent = {
1372
- sdk: { name: "JavaScript", version: "4.35.0" },
1376
+ sdk: { name: "JavaScript", version: "4.35.3" },
1373
1377
  };
1374
1378
  if (typeof process !== "undefined") {
1375
1379
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).assemblyai={})}(this,(function(e){"use strict";class t extends Error{constructor(e="DualChannelCapture requires a browser environment (AudioContext is undefined)."){super(e),this.name="BrowserOnlyError"}}function s(e,t,s,n){return new(s||(s=Promise))((function(i,r){function o(e){try{l(n.next(e))}catch(e){r(e)}}function a(e){try{l(n.throw(e))}catch(e){r(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}l((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const{WritableStream:n}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var i,r;const o=null!==(r=null!==(i=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==i?i:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==r?r:null===self||void 0===self?void 0:self.WebSocket,a=(e,t)=>t?new o(e,t):new o(e),l={[4e3]:"Sample rate must be a positive integer",[4001]:"Not Authorized",[4002]:"Insufficient funds",[4003]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[4100]:"Bad JSON",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid.",[1013]:"Reconnect attempts exhausted",[4104]:"Could not parse word boost parameter"};class c extends Error{}const h=4e3,d=4001,u=4002,m=4003,p=4101,f={[3005]:"Server error",[3006]:"Input validation error",[3007]:"Audio chunk duration violation",[3008]:"Session expired: maximum session duration exceeded",[3009]:"Too many concurrent sessions",[h]:"Sample rate must be a positive integer",[d]:"Not Authorized",[u]:"Insufficient funds",[m]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[p]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid."};class v extends Error{}const g='{"terminate_session":true}';class w{constructor(e){var t,s;if(this.listeners={},this.realtimeUrl=null!==(t=e.realtimeUrl)&&void 0!==t?t:"wss://api.assemblyai.com/v2/realtime/ws",this.sampleRate=null!==(s=e.sampleRate)&&void 0!==s?s:16e3,this.wordBoost=e.wordBoost,this.encoding=e.encoding,this.endUtteranceSilenceThreshold=e.endUtteranceSilenceThreshold,this.disablePartialTranscripts=e.disablePartialTranscripts,"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.")}connectionUrl(){const e=new URL(this.realtimeUrl);if("wss:"!==e.protocol)throw new Error("Invalid protocol, must be wss");const t=new URLSearchParams;return this.token&&t.set("token",this.token),t.set("sample_rate",this.sampleRate.toString()),this.wordBoost&&this.wordBoost.length>0&&t.set("word_boost",JSON.stringify(this.wordBoost)),this.encoding&&t.set("encoding",this.encoding),t.set("enable_extra_session_information","true"),this.disablePartialTranscripts&&t.set("disable_partial_transcripts",this.disablePartialTranscripts.toString()),e.search=t.toString(),e}on(e,t){this.listeners[e]=t}connect(){return new Promise((e=>{if(this.socket)throw new Error("Already connected");const t=this.connectionUrl();this.token?this.socket=a(t.toString()):(console.warn("API key authentication is not supported for the RealtimeTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=a(t.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{void 0!==this.endUtteranceSilenceThreshold&&null!==this.endUtteranceSilenceThreshold&&this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold)},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in l&&(t=l[e]),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n,i;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(i=(n=this.listeners).error)||void 0===i||i.call(n,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,n,i,r,o,a,l,h,d,u,m,p,f,v,g;const w=JSON.parse(t.toString());if("error"in w)null===(n=(s=this.listeners).error)||void 0===n||n.call(s,new c(w.error));else switch(w.message_type){case"SessionBegins":{const t={sessionId:w.session_id,expiresAt:new Date(w.expires_at)};e(t),null===(r=(i=this.listeners).open)||void 0===r||r.call(i,t);break}case"PartialTranscript":w.created=new Date(w.created),null===(a=(o=this.listeners).transcript)||void 0===a||a.call(o,w),null===(h=(l=this.listeners)["transcript.partial"])||void 0===h||h.call(l,w);break;case"FinalTranscript":w.created=new Date(w.created),null===(u=(d=this.listeners).transcript)||void 0===u||u.call(d,w),null===(p=(m=this.listeners)["transcript.final"])||void 0===p||p.call(m,w);break;case"SessionInformation":null===(v=(f=this.listeners).session_information)||void 0===v||v.call(f,w);break;case"SessionTerminated":null===(g=this.sessionTerminatedResolve)||void 0===g||g.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new n({write:e=>{this.sendAudio(e)}})}forceEndUtterance(){this.send('{"force_end_utterance":true}')}configureEndUtteranceSilenceThreshold(e){this.send(`{"end_utterance_silence_threshold":${e}}`)}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return s(this,arguments,void 0,(function*(e=!0){var t;if(this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(g),yield e}else this.socket.send(g);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class y{constructor(e={}){var t,s,n,i;this.hangoverRemaining=0,this.thresholdRatio=null!==(t=e.thresholdRatio)&&void 0!==t?t:3,this.noiseFloorAlpha=null!==(s=e.noiseFloorAlpha)&&void 0!==s?s:.05,this.hangoverFrames=null!==(n=e.hangoverFrames)&&void 0!==n?n:10,this.initialNoiseFloor=null!==(i=e.initialNoiseFloor)&&void 0!==i?i:1e-4,this.noiseFloor=this.initialNoiseFloor}process(e){let t=0;for(let s=0;s<e.length;s++)t+=e[s]*e[s];const s=e.length>0?Math.sqrt(t/e.length):0;let n=s>this.noiseFloor*this.thresholdRatio;return n?this.hangoverRemaining=this.hangoverFrames:this.hangoverRemaining>0?(this.hangoverRemaining--,n=!0):this.noiseFloor=this.noiseFloor*(1-this.noiseFloorAlpha)+s*this.noiseFloorAlpha,{active:n,energy:s}}reset(){this.noiseFloor=this.initialNoiseFloor,this.hangoverRemaining=0}}class k{constructor(e){this.windowMs=e,this.frames=[],this.head=0}pushFrame(e){this.frames.push(e);const t=e.ts-this.windowMs;for(;this.head<this.frames.length&&this.frames[this.head].ts<t;)this.head++;this.head>1024&&2*this.head>this.frames.length&&(this.frames=this.frames.slice(this.head),this.head=0)}framesInWindow(e,t){const s=[];for(let n=this.head;n<this.frames.length;n++){const i=this.frames[n];if(!(i.ts<e)){if(i.ts>t)break;s.push(i)}}return s}clear(){this.frames=[],this.head=0}}function S(e,t,s){const n=function(e){var t;const s=new Map;for(const n of e)n.active&&s.set(n.channel,(null!==(t=s.get(n.channel))&&void 0!==t?t:0)+n.rms);return s}(t.framesInWindow(e.start,e.end));if(0===n.size)return"unknown";const i=[...n.entries()].sort(((e,t)=>t[1]-e[1]));if(1===i.length)return i[0][0];const[r,o]=i[0],[a,l]=i[1];return o>=s.dominanceRatio*l||o>l?r:l>o?a:"unknown"}function b(e){var t;const s=new Map;for(const n of e){if(!n.channel||"unknown"===n.channel)continue;const e=Math.max(0,n.end-n.start);s.set(n.channel,(null!==(t=s.get(n.channel))&&void 0!==t?t:0)+e)}if(0===s.size)return"unknown";const n=[...s.entries()].sort(((e,t)=>t[1]-e[1]));if(1===n.length)return n[0][0];const[i,r]=n[0],[,o]=n[1];return r===o?"unknown":i}function _(e,t,s){for(const n of e.words)n.channel=S(n,t,s);e.channel=b(e.words)}const T='{"type":"Terminate"}',A=new Set([h,d,u,m,p]);function x(e){return 1e3!==e&&!A.has(e)}class P{constructor(e){var t,s,n,i,r,o,a,l,c;if(this.listeners={},this.isDualChannel=!1,this.vadFrameSamples=0,this.minChunkSamples=0,this.maxChunkSamples=0,this.params=Object.assign(Object.assign({},e),{websocketBaseUrl:e.websocketBaseUrl||"wss://streaming.assemblyai.com/v3/ws"}),"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.");if(e.channels){if(2!==e.channels.length)throw new Error("StreamingTranscriber.channels must have exactly 2 entries.");const h=e.channels.map((e=>e.name));if(new Set(h).size!==h.length)throw new Error("StreamingTranscriber.channels names must be unique.");this.isDualChannel=!0,this.channelNames=h;const d=null!==(t=e.channelAttribution)&&void 0!==t?t:{};this.attributionParams={dominanceRatio:null!==(s=d.dominanceRatio)&&void 0!==s?s:4,timelineWindowMs:null!==(n=d.timelineWindowMs)&&void 0!==n?n:3e4,createVad:null!==(i=d.createVad)&&void 0!==i?i:()=>new y,flushIntervalMs:null!==(r=d.flushIntervalMs)&&void 0!==r?r:50,resolveUnknownChannelsMethod:null!==(o=d.resolveUnknownChannelsMethod)&&void 0!==o?o:"window",resolutionWindowWords:null!==(a=d.resolutionWindowWords)&&void 0!==a?a:2,speakerHistoryMinRmsEvidence:null!==(l=d.speakerHistoryMinRmsEvidence)&&void 0!==l?l:.5,speakerHistoryDominanceRatio:null!==(c=d.speakerHistoryDominanceRatio)&&void 0!==c?c:3},"speaker-history"===this.attributionParams.resolveUnknownChannelsMethod&&(this.speakerHistory=new Map),this.vadFrameSamples=Math.max(1,Math.round(.02*e.sampleRate)),this.minChunkSamples=Math.max(1,Math.round(.05*e.sampleRate)),this.maxChunkSamples=Math.max(this.minChunkSamples,Math.round(.2*e.sampleRate)),this.channelBuffers=new Map(h.map((e=>[e,[]]))),this.channelSamplesReceived=new Map(h.map((e=>[e,0]))),this.channelVadFloatBuffers=new Map(h.map((e=>[e,new Float32Array(this.vadFrameSamples)]))),this.channelVadBufferIdx=new Map(h.map((e=>[e,0]))),this.channelVads=new Map(h.map((e=>[e,this.attributionParams.createVad(e)]))),this.timeline=new k(this.attributionParams.timelineWindowMs)}}connectionUrl(){var e,t;const s=new URL(null!==(e=this.params.websocketBaseUrl)&&void 0!==e?e:"");if("wss:"!==s.protocol)throw new Error("Invalid protocol, must be wss");const n=new URLSearchParams;this.token&&n.set("token",this.token),n.set("sample_rate",this.params.sampleRate.toString()),this.params.endOfTurnConfidenceThreshold&&n.set("end_of_turn_confidence_threshold",this.params.endOfTurnConfidenceThreshold.toString()),void 0!==this.params.minEndOfTurnSilenceWhenConfident&&(void 0!==this.params.minTurnSilence?console.warn("[Deprecation Warning] Both `minEndOfTurnSilenceWhenConfident` and `minTurnSilence` are set. Using `minTurnSilence`; `minEndOfTurnSilenceWhenConfident` is deprecated."):console.warn("[Deprecation Warning] `minEndOfTurnSilenceWhenConfident` is deprecated and will be removed in a future release. Please use `minTurnSilence` instead."));const i=null!==(t=this.params.minTurnSilence)&&void 0!==t?t:this.params.minEndOfTurnSilenceWhenConfident;return void 0!==i&&n.set("min_turn_silence",i.toString()),this.params.maxTurnSilence&&n.set("max_turn_silence",this.params.maxTurnSilence.toString()),void 0!==this.params.vadThreshold&&n.set("vad_threshold",this.params.vadThreshold.toString()),this.params.formatTurns&&n.set("format_turns",this.params.formatTurns.toString()),this.params.encoding&&n.set("encoding",this.params.encoding.toString()),this.params.keytermsPrompt?n.set("keyterms_prompt",JSON.stringify(this.params.keytermsPrompt)):this.params.keyterms&&(console.warn("[Deprecation Warning] `keyterms` is deprecated and will be removed in a future release. Please use `keytermsPrompt` instead."),n.set("keyterms_prompt",JSON.stringify(this.params.keyterms))),this.params.prompt&&n.set("prompt",this.params.prompt),this.params.agentContext&&n.set("agent_context",this.params.agentContext),this.params.filterProfanity&&n.set("filter_profanity",this.params.filterProfanity.toString()),"u3-pro"===this.params.speechModel&&console.warn("[Deprecation Warning] The speech model `u3-pro` is deprecated and will be removed in a future release. Please use `u3-rt-pro` instead."),void 0!==this.params.speechModel&&n.set("speech_model",this.params.speechModel.toString()),void 0!==this.params.languageCode&&n.set("language_code",this.params.languageCode),void 0!==this.params.languageDetection&&n.set("language_detection",this.params.languageDetection.toString()),this.params.domain&&n.set("domain",this.params.domain),void 0!==this.params.inactivityTimeout&&n.set("inactivity_timeout",this.params.inactivityTimeout.toString()),void 0!==this.params.speakerLabels&&n.set("speaker_labels",this.params.speakerLabels.toString()),void 0!==this.params.maxSpeakers&&n.set("max_speakers",this.params.maxSpeakers.toString()),this.params.voiceFocus&&n.set("voice_focus",this.params.voiceFocus),void 0!==this.params.voiceFocusThreshold&&n.set("voice_focus_threshold",this.params.voiceFocusThreshold.toString()),void 0!==this.params.continuousPartials&&n.set("continuous_partials",this.params.continuousPartials.toString()),void 0!==this.params.interruptionDelay&&n.set("interruption_delay",this.params.interruptionDelay.toString()),void 0!==this.params.turnLeftPadMs&&n.set("turn_left_pad_ms",this.params.turnLeftPadMs.toString()),this.params.customerSupportAudioCapture&&(console.warn("`customerSupportAudioCapture=true` will record session audio. Only enable this when explicitly coordinating with AssemblyAI support."),n.set("_customer_support_audio_capture",this.params.customerSupportAudioCapture.toString())),this.params.webhookUrl&&n.set("webhook_url",this.params.webhookUrl),this.params.webhookAuthHeaderName&&n.set("webhook_auth_header_name",this.params.webhookAuthHeaderName),this.params.webhookAuthHeaderValue&&n.set("webhook_auth_header_value",this.params.webhookAuthHeaderValue),void 0!==this.params.includePartialTurns&&n.set("include_partial_turns",this.params.includePartialTurns.toString()),void 0!==this.params.redactPii&&n.set("redact_pii",this.params.redactPii.toString()),void 0!==this.params.redactPiiPolicies&&n.set("redact_pii_policies",JSON.stringify(this.params.redactPiiPolicies)),void 0!==this.params.redactPiiSub&&n.set("redact_pii_sub",this.params.redactPiiSub),void 0!==this.params.mode&&n.set("mode",this.params.mode),void 0!==this.params.llmGateway&&n.set("llm_gateway",JSON.stringify(this.params.llmGateway)),s.search=n.toString(),s}on(e,t){this.listeners[e]=t}connect(){return s(this,void 0,void 0,(function*(){var e,t;if(this.socket)throw new Error("Already connected");const s=null!==(e=this.params.maxConnectionRetries)&&void 0!==e?e:2,n=null!==(t=this.params.connectionRetryDelay)&&void 0!==t?t:500;let i;for(let e=0;e<=s;e++)try{return yield this.connectOnce()}catch(t){i=t;if(!(!0===t.retryable)||e===s)throw t;console.warn(`Streaming connect attempt ${e+1}/${s+1} failed (${t.message}); retrying`),n>0&&(yield new Promise((e=>setTimeout(e,n))))}throw null!=i?i:new Error("Failed to connect to streaming server")}))}connectOnce(){return new Promise(((e,t)=>{var s;const n=this.connectionUrl(),i=null!==(s=this.params.connectTimeout)&&void 0!==s?s:1e3;let r,o=!1;const l=e=>{o||(o=!0,r&&clearTimeout(r),this.discardPendingSocket(),t(e))};i>0&&(r=setTimeout((()=>{const e=new v(`Streaming connection timed out after ${i}ms`);e.retryable=!0,l(e)}),i)),this.token?this.socket=a(n.toString()):(console.warn("API key authentication is not supported for the StreamingTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=a(n.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{},this.socket.onclose=({code:e,reason:t})=>{var s,n;if(t||e in f&&(t=f[e]),!o){const s=new v(t||`Streaming connection closed (code=${e})`);return s.code=e,s.retryable=x(e),void l(s)}this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n;const i=null!==(t=e.error)&&void 0!==t?t:new Error(e.message);if(!o)return i.retryable=!0,void l(i);null===(n=(s=this.listeners).error)||void 0===n||n.call(s,i)},this.socket.onmessage=({data:t})=>{var s,n,i,a,c,h,d,u,m,p,f,g,w,y,k;const S=JSON.parse(t.toString());if("error"in S){const e=new v(S.error);if("error_code"in S&&(e.code=S.error_code),!o){const t=e;return t.retryable=void 0===e.code||x(e.code),void l(t)}null===(n=(s=this.listeners).error)||void 0===n||n.call(s,e)}else{switch(S.type){case"Begin":b=S,o||(o=!0,r&&clearTimeout(r),e(b)),null===(a=(i=this.listeners).open)||void 0===a||a.call(i,S);break;case"Turn":if(this.isDualChannel&&this.timeline&&this.attributionParams)switch(_(S,this.timeline,{dominanceRatio:this.attributionParams.dominanceRatio}),this.attributionParams.resolveUnknownChannelsMethod){case"window":this.resolveUnknownChannelsByWindow(S);break;case"speaker-history":this.resolveUnknownChannelsBySpeakerHistory(S)}null===(h=(c=this.listeners).turn)||void 0===h||h.call(c,S);break;case"SpeechStarted":null===(u=(d=this.listeners).speechStarted)||void 0===u||u.call(d,S);break;case"LLMGatewayResponse":null===(p=(m=this.listeners).llmGatewayResponse)||void 0===p||p.call(m,S);break;case"SpeakerRevision":null===(g=(f=this.listeners).speakerRevision)||void 0===g||g.call(f,S);break;case"Warning":{const e=S;console.warn(`Streaming warning (code=${e.warning_code}): ${e.warning}`),null===(y=(w=this.listeners).warning)||void 0===y||y.call(w,e);break}case"Termination":null===(k=this.sessionTerminatedResolve)||void 0===k||k.call(this)}var b}}}))}discardPendingSocket(){if(this.socket){try{this.socket.removeAllListeners&&this.socket.removeAllListeners(),this.socket.close()}catch(e){}this.socket=void 0}}stream(){return new n({write:e=>{this.sendAudio(e)}})}sendAudio(e,t){if(this.isDualChannel){if(!(null==t?void 0:t.channel))throw new Error("StreamingTranscriber is in dual-channel mode; sendAudio requires { channel }.");if(!this.channelNames.includes(t.channel))throw new Error(`Unknown channel "${t.channel}"; declared channels: ${this.channelNames.join(", ")}.`);this.ingestChannelAudio(t.channel,e)}else this.send(e)}ingestChannelAudio(e,t){var s,n;const i=function(e){if(e instanceof Int16Array)return e;if(ArrayBuffer.isView(e)){const t=e;return new Int16Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/2))}return new Int16Array(e)}(t),r=this.channelBuffers.get(e),o=this.channelVadFloatBuffers.get(e);let a=this.channelVadBufferIdx.get(e),l=this.channelSamplesReceived.get(e);const c=this.channelVads.get(e),h=this.params.sampleRate,d=this.vadFrameSamples;for(let t=0;t<i.length;t++){const u=i[t];if(r.push(u),o[a++]=u/32768,l++,a===d){const t=c.process(o),i={ts:l/h*1e3,channel:e,active:t.active,rms:t.energy};this.timeline.pushFrame(i),null===(n=(s=this.listeners).vad)||void 0===n||n.call(s,i),a=0}}this.channelVadBufferIdx.set(e,a),this.channelSamplesReceived.set(e,l),this.flushTimer||this.startFlushTimer()}startFlushTimer(){this.flushTimer=setInterval((()=>this.flushMix()),this.attributionParams.flushIntervalMs)}flushMix(e=!1){var t,s;if(!this.channelNames||!this.channelBuffers)return;const n=this.channelNames.map((e=>this.channelBuffers.get(e))),i=n.length;for(;;){let r=1/0;for(const e of n)e.length<r&&(r=e.length);if(!Number.isFinite(r)||0===r)return;if(!e&&r<this.minChunkSamples)return;r>this.maxChunkSamples&&(r=this.maxChunkSamples);const o=new Int16Array(r);for(let e=0;e<r;e++){let t=0;for(let s=0;s<i;s++)t+=n[s][e];const s=Math.round(t/i);o[e]=s<-32768?-32768:s>32767?32767:s}for(const e of n)e.splice(0,r);try{this.send(o.buffer)}catch(e){return void(null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e))}}}resolveUnknownChannelsByWindow(e){var t;if(!this.attributionParams)return;const s=this.attributionParams.resolutionWindowWords,n=e.words;let i=!1;for(let e=0;e<n.length;e++){if("unknown"!==n[e].channel)continue;const r=new Map,o=Math.max(0,e-s),a=Math.min(n.length-1,e+s);for(let s=o;s<=a;s++){if(s===e)continue;const i=n[s].channel;i&&"unknown"!==i&&r.set(i,(null!==(t=r.get(i))&&void 0!==t?t:0)+1)}if(0===r.size)continue;let l,c=0,h=!1;for(const[e,t]of r)t>c?(l=e,c=t,h=!1):t===c&&(h=!0);l&&!h&&(n[e].channel=l,n[e].channelResolved=!0,i=!0)}i&&(e.channel=b(n))}resolveUnknownChannelsBySpeakerHistory(e){var t;if(!this.timeline||!this.attributionParams||!this.speakerHistory)return;const s=this.attributionParams.speakerHistoryMinRmsEvidence,n=this.attributionParams.speakerHistoryDominanceRatio;for(const s of e.words){if(!s.speaker)continue;const e=this.timeline.framesInWindow(s.start,s.end);let n=this.speakerHistory.get(s.speaker);n||(n=new Map,this.speakerHistory.set(s.speaker,n));for(const s of e)s.active&&n.set(s.channel,(null!==(t=n.get(s.channel))&&void 0!==t?t:0)+s.rms)}let i=!1;for(const t of e.words){if("unknown"!==t.channel||!t.speaker)continue;const e=this.speakerHistory.get(t.speaker);if(!e||0===e.size)continue;let r,o=0,a=0,l=0;for(const[t,s]of e)o+=s,s>a?(l=a,a=s,r=t):s>l&&(l=s);o<s||(l>0&&a<n*l||r&&(t.channel=r,t.channelResolved=!0,i=!0))}i&&(e.channel=b(e.words))}updateConfiguration(e){const{min_end_of_turn_silence_when_confident:t,min_turn_silence:s}=e,n=function(e,t){var s={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(s[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(n=Object.getOwnPropertySymbols(e);i<n.length;i++)t.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(s[n[i]]=e[n[i]])}return s}(e,["min_end_of_turn_silence_when_confident","min_turn_silence"]);void 0!==t&&(void 0!==s?console.warn("[Deprecation Warning] Both `min_end_of_turn_silence_when_confident` and `min_turn_silence` are set. Using `min_turn_silence`; `min_end_of_turn_silence_when_confident` is deprecated."):console.warn("[Deprecation Warning] `min_end_of_turn_silence_when_confident` is deprecated and will be removed in a future release. Please use `min_turn_silence` instead."));const i=null!=s?s:t,r=Object.assign(Object.assign({type:"UpdateConfiguration"},n),void 0!==i?{min_turn_silence:i}:{});this.send(JSON.stringify(r))}forceEndpoint(){this.send(JSON.stringify({type:"ForceEndpoint"}))}keepAlive(){this.send(JSON.stringify({type:"KeepAlive"}))}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return s(this,arguments,void 0,(function*(e=!0){var t;if(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0,this.flushMix(!0)),this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(T),yield e}else this.socket.send(T);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}const R={cache:"no-store"};let E="";"undefined"!=typeof navigator&&navigator.userAgent&&(E+=navigator.userAgent);const O={sdk:{name:"JavaScript",version:"4.35.0"}};"undefined"!=typeof process&&(process.versions.node&&-1===E.indexOf("Node")&&(O.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===E.indexOf("Bun")&&(O.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===E.indexOf("Deno")&&(O.runtime_env={name:"Deno",version:Deno.version.deno});class M{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},E+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},O),t)).map((([e,t])=>t?`${e}=${t.name}/${t.version}`:"")).join(" ")+")"))}fetch(e,t){return s(this,void 0,void 0,(function*(){t=Object.assign(Object.assign({},R),t);let s={Authorization:this.params.apiKey,"Content-Type":"application/json"};(null==R?void 0:R.headers)&&(s=Object.assign(Object.assign({},s),R.headers)),(null==t?void 0:t.headers)&&(s=Object.assign(Object.assign({},s),t.headers)),this.userAgent&&(s["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(s["AssemblyAI-Agent"]=this.userAgent)),t.headers=s,e.startsWith("http")||(e=this.params.baseUrl+e);const n=yield fetch(e,t);if(n.status>=400){let e;const t=yield n.text();if(t){try{e=JSON.parse(t)}catch(e){}if(null==e?void 0:e.error)throw new Error(e.error);throw new Error(t)}throw new Error(`HTTP Error: ${n.status} ${n.statusText}`)}return n}))}fetchJson(e,t){return s(this,void 0,void 0,(function*(){return(yield this.fetch(e,t)).json()}))}}class C extends M{constructor(e){super(e),this.baseServiceParams=e}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.baseServiceParams.apiKey),new P(t)}createTemporaryToken(e){return s(this,void 0,void 0,(function*(){const t=new URLSearchParams;Object.entries(e).forEach((([e,s])=>{null!=s&&t.append(e,String(s))}));const s=t.toString(),n=s?`/v3/token?${s}`:"/v3/token";return(yield this.fetchJson(n,{method:"GET"})).token}))}}e.BrowserOnlyError=t,e.DualChannelCapture=class{constructor(e){var s;if(this.running=!1,void 0===globalThis.AudioContext)throw new t;this.params={micStream:e.micStream,systemStream:e.systemStream,transcriber:e.transcriber,targetSampleRate:null!==(s=e.targetSampleRate)&&void 0!==s?s:16e3}}on(e,t){"error"===e&&(this.errorListener=t)}start(){return s(this,void 0,void 0,(function*(){if(this.running)throw new Error("DualChannelCapture already started");this.context=new AudioContext;const e=new Blob(['\nclass Pcm16EncoderProcessor extends AudioWorkletProcessor {\n constructor(options) {\n super();\n const opts = (options && options.processorOptions) || {};\n this.targetRate = opts.targetRate || 16000;\n this.chunkMs = opts.chunkMs || 50;\n this.ratio = sampleRate / this.targetRate;\n this.chunkSize = Math.round(this.targetRate * this.chunkMs / 1000);\n this.buffer = new Int16Array(this.chunkSize);\n this.bufferIdx = 0;\n this.samplesSent = 0;\n this.lastSample = 0;\n this.fractional = 0;\n }\n\n process(inputs) {\n const input = inputs[0];\n if (!input || input.length === 0 || !input[0] || input[0].length === 0) {\n return true;\n }\n const mono = input[0];\n let pos = this.fractional;\n while (pos < mono.length) {\n const i = Math.floor(pos);\n const frac = pos - i;\n const a = i === 0 ? this.lastSample : mono[i - 1];\n const b = mono[i];\n const sample = a + (b - a) * frac;\n const clamped = sample < -1 ? -1 : sample > 1 ? 1 : sample;\n this.buffer[this.bufferIdx++] = clamped < 0 ? clamped * 0x8000 : clamped * 0x7fff;\n if (this.bufferIdx === this.chunkSize) {\n const out = new Int16Array(this.chunkSize);\n out.set(this.buffer);\n this.samplesSent += this.chunkSize;\n this.port.postMessage(\n { pcm: out.buffer, samplesSent: this.samplesSent },\n [out.buffer],\n );\n this.bufferIdx = 0;\n }\n pos += this.ratio;\n }\n this.lastSample = mono[mono.length - 1];\n this.fractional = pos - mono.length;\n return true;\n }\n}\nregisterProcessor("aai-pcm16-encoder", Pcm16EncoderProcessor);\n'],{type:"application/javascript"}),t=URL.createObjectURL(e);try{yield this.context.audioWorklet.addModule(t)}finally{URL.revokeObjectURL(t)}this.micSource=this.context.createMediaStreamSource(this.params.micStream),this.sysSource=this.context.createMediaStreamSource(this.params.systemStream),this.micEncoder=this.makeEncoder("mic"),this.sysEncoder=this.makeEncoder("system"),this.micSource.connect(this.micEncoder),this.sysSource.connect(this.sysEncoder),this.running=!0}))}makeEncoder(e){const t=new AudioWorkletNode(this.context,"aai-pcm16-encoder",{numberOfInputs:1,numberOfOutputs:0,channelCount:1,channelCountMode:"explicit",channelInterpretation:"speakers",processorOptions:{targetRate:this.params.targetSampleRate,chunkMs:50}});return t.port.onmessage=t=>{var s;try{this.params.transcriber.sendAudio(t.data.pcm,{channel:e})}catch(e){null===(s=this.errorListener)||void 0===s||s.call(this,e)}},t}stop(){return s(this,void 0,void 0,(function*(){var e,t,s,n,i,r;if(this.running){this.running=!1;try{null===(e=this.micEncoder)||void 0===e||e.port.close(),null===(t=this.sysEncoder)||void 0===t||t.port.close(),null===(s=this.micEncoder)||void 0===s||s.disconnect(),null===(n=this.sysEncoder)||void 0===n||n.disconnect(),null===(i=this.micSource)||void 0===i||i.disconnect(),null===(r=this.sysSource)||void 0===r||r.disconnect()}catch(e){}this.context&&"closed"!==this.context.state&&(yield this.context.close()),this.context=void 0,this.micSource=void 0,this.sysSource=void 0,this.micEncoder=void 0,this.sysEncoder=void 0}}))}},e.EnergyVad=y,e.LinearResampler=class{constructor(e,t){if(this.sourceRate=e,this.targetRate=t,this.lastSample=0,this.fractional=0,e<=0||t<=0)throw new Error("sourceRate and targetRate must be positive");this.ratio=e/t}process(e){var t;if(this.sourceRate===this.targetRate)return e;const s=new Float32Array(Math.ceil(e.length/this.ratio)+1);let n=0,i=this.fractional;for(;i<e.length;){const t=Math.floor(i),r=i-t,o=0===t?this.lastSample:e[t-1],a=e[t];s[n++]=o+(a-o)*r,i+=this.ratio}return this.lastSample=null!==(t=e[e.length-1])&&void 0!==t?t:this.lastSample,this.fractional=i-e.length,s.subarray(0,n)}reset(){this.lastSample=0,this.fractional=0}},e.RealtimeService=class extends w{},e.RealtimeTranscriber=w,e.StreamingServiceFactory=class extends C{},e.StreamingTranscriber=P,e.StreamingTranscriberFactory=C,e.VadTimeline=k,e.attributeTurn=_,e.attributeWord=S,e.float32ToPcm16=function(e){const t=new ArrayBuffer(2*e.length),s=new DataView(t);for(let t=0;t<e.length;t++){const n=Math.max(-1,Math.min(1,e[t]));s.setInt16(2*t,n<0?32768*n:32767*n,!0)}return t},e.rollUpTurnChannel=b}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).assemblyai={})}(this,(function(e){"use strict";class t extends Error{constructor(e="DualChannelCapture requires a browser environment (AudioContext is undefined)."){super(e),this.name="BrowserOnlyError"}}function s(e,t,s,n){return new(s||(s=Promise))((function(i,r){function o(e){try{l(n.next(e))}catch(e){r(e)}}function a(e){try{l(n.throw(e))}catch(e){r(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}l((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const{WritableStream:n}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var i,r;const o=null!==(r=null!==(i=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==i?i:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==r?r:null===self||void 0===self?void 0:self.WebSocket,a=(e,t)=>t?new o(e,t):new o(e),l={[4e3]:"Sample rate must be a positive integer",[4001]:"Not Authorized",[4002]:"Insufficient funds",[4003]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[4100]:"Bad JSON",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid.",[1013]:"Reconnect attempts exhausted",[4104]:"Could not parse word boost parameter"};class c extends Error{}const h=4e3,d=4001,u=4002,m=4003,p=4101,f={[3005]:"Server error",[3006]:"Input validation error",[3007]:"Audio chunk duration violation",[3008]:"Session expired: maximum session duration exceeded",[3009]:"Too many concurrent sessions",[h]:"Sample rate must be a positive integer",[d]:"Not Authorized",[u]:"Insufficient funds",[m]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[p]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid."};class v extends Error{}const g='{"terminate_session":true}';class w{constructor(e){var t,s;if(this.listeners={},this.realtimeUrl=null!==(t=e.realtimeUrl)&&void 0!==t?t:"wss://api.assemblyai.com/v2/realtime/ws",this.sampleRate=null!==(s=e.sampleRate)&&void 0!==s?s:16e3,this.wordBoost=e.wordBoost,this.encoding=e.encoding,this.endUtteranceSilenceThreshold=e.endUtteranceSilenceThreshold,this.disablePartialTranscripts=e.disablePartialTranscripts,"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.")}connectionUrl(){const e=new URL(this.realtimeUrl);if("wss:"!==e.protocol)throw new Error("Invalid protocol, must be wss");const t=new URLSearchParams;return this.token&&t.set("token",this.token),t.set("sample_rate",this.sampleRate.toString()),this.wordBoost&&this.wordBoost.length>0&&t.set("word_boost",JSON.stringify(this.wordBoost)),this.encoding&&t.set("encoding",this.encoding),t.set("enable_extra_session_information","true"),this.disablePartialTranscripts&&t.set("disable_partial_transcripts",this.disablePartialTranscripts.toString()),e.search=t.toString(),e}on(e,t){this.listeners[e]=t}connect(){return new Promise((e=>{if(this.socket)throw new Error("Already connected");const t=this.connectionUrl();this.token?this.socket=a(t.toString()):(console.warn("API key authentication is not supported for the RealtimeTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=a(t.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{void 0!==this.endUtteranceSilenceThreshold&&null!==this.endUtteranceSilenceThreshold&&this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold)},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in l&&(t=l[e]),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n,i;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(i=(n=this.listeners).error)||void 0===i||i.call(n,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,n,i,r,o,a,l,h,d,u,m,p,f,v,g;const w=JSON.parse(t.toString());if("error"in w)null===(n=(s=this.listeners).error)||void 0===n||n.call(s,new c(w.error));else switch(w.message_type){case"SessionBegins":{const t={sessionId:w.session_id,expiresAt:new Date(w.expires_at)};e(t),null===(r=(i=this.listeners).open)||void 0===r||r.call(i,t);break}case"PartialTranscript":w.created=new Date(w.created),null===(a=(o=this.listeners).transcript)||void 0===a||a.call(o,w),null===(h=(l=this.listeners)["transcript.partial"])||void 0===h||h.call(l,w);break;case"FinalTranscript":w.created=new Date(w.created),null===(u=(d=this.listeners).transcript)||void 0===u||u.call(d,w),null===(p=(m=this.listeners)["transcript.final"])||void 0===p||p.call(m,w);break;case"SessionInformation":null===(v=(f=this.listeners).session_information)||void 0===v||v.call(f,w);break;case"SessionTerminated":null===(g=this.sessionTerminatedResolve)||void 0===g||g.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new n({write:e=>{this.sendAudio(e)}})}forceEndUtterance(){this.send('{"force_end_utterance":true}')}configureEndUtteranceSilenceThreshold(e){this.send(`{"end_utterance_silence_threshold":${e}}`)}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return s(this,arguments,void 0,(function*(e=!0){var t;if(this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(g),yield e}else this.socket.send(g);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class y{constructor(e={}){var t,s,n,i;this.hangoverRemaining=0,this.thresholdRatio=null!==(t=e.thresholdRatio)&&void 0!==t?t:3,this.noiseFloorAlpha=null!==(s=e.noiseFloorAlpha)&&void 0!==s?s:.05,this.hangoverFrames=null!==(n=e.hangoverFrames)&&void 0!==n?n:10,this.initialNoiseFloor=null!==(i=e.initialNoiseFloor)&&void 0!==i?i:1e-4,this.noiseFloor=this.initialNoiseFloor}process(e){let t=0;for(let s=0;s<e.length;s++)t+=e[s]*e[s];const s=e.length>0?Math.sqrt(t/e.length):0;let n=s>this.noiseFloor*this.thresholdRatio;return n?this.hangoverRemaining=this.hangoverFrames:this.hangoverRemaining>0?(this.hangoverRemaining--,n=!0):this.noiseFloor=this.noiseFloor*(1-this.noiseFloorAlpha)+s*this.noiseFloorAlpha,{active:n,energy:s}}reset(){this.noiseFloor=this.initialNoiseFloor,this.hangoverRemaining=0}}class k{constructor(e){this.windowMs=e,this.frames=[],this.head=0}pushFrame(e){this.frames.push(e);const t=e.ts-this.windowMs;for(;this.head<this.frames.length&&this.frames[this.head].ts<t;)this.head++;this.head>1024&&2*this.head>this.frames.length&&(this.frames=this.frames.slice(this.head),this.head=0)}framesInWindow(e,t){const s=[];for(let n=this.head;n<this.frames.length;n++){const i=this.frames[n];if(!(i.ts<e)){if(i.ts>t)break;s.push(i)}}return s}clear(){this.frames=[],this.head=0}}function S(e,t,s){const n=function(e){var t;const s=new Map;for(const n of e)n.active&&s.set(n.channel,(null!==(t=s.get(n.channel))&&void 0!==t?t:0)+n.rms);return s}(t.framesInWindow(e.start,e.end));if(0===n.size)return"unknown";const i=[...n.entries()].sort(((e,t)=>t[1]-e[1]));if(1===i.length)return i[0][0];const[r,o]=i[0],[a,l]=i[1];return o>=s.dominanceRatio*l||o>l?r:l>o?a:"unknown"}function b(e){var t;const s=new Map;for(const n of e){if(!n.channel||"unknown"===n.channel)continue;const e=Math.max(0,n.end-n.start);s.set(n.channel,(null!==(t=s.get(n.channel))&&void 0!==t?t:0)+e)}if(0===s.size)return"unknown";const n=[...s.entries()].sort(((e,t)=>t[1]-e[1]));if(1===n.length)return n[0][0];const[i,r]=n[0],[,o]=n[1];return r===o?"unknown":i}function _(e,t,s){for(const n of e.words)n.channel=S(n,t,s);e.channel=b(e.words)}const T='{"type":"Terminate"}',A=new Set([h,d,u,m,p]);function x(e){return 1e3!==e&&!A.has(e)}class P{constructor(e){var t,s,n,i,r,o,a,l,c;if(this.listeners={},this.isDualChannel=!1,this.vadFrameSamples=0,this.minChunkSamples=0,this.maxChunkSamples=0,this.params=Object.assign(Object.assign({},e),{websocketBaseUrl:e.websocketBaseUrl||"wss://streaming.assemblyai.com/v3/ws"}),"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.");if(e.channels){if(2!==e.channels.length)throw new Error("StreamingTranscriber.channels must have exactly 2 entries.");const h=e.channels.map((e=>e.name));if(new Set(h).size!==h.length)throw new Error("StreamingTranscriber.channels names must be unique.");this.isDualChannel=!0,this.channelNames=h;const d=null!==(t=e.channelAttribution)&&void 0!==t?t:{};this.attributionParams={dominanceRatio:null!==(s=d.dominanceRatio)&&void 0!==s?s:4,timelineWindowMs:null!==(n=d.timelineWindowMs)&&void 0!==n?n:3e4,createVad:null!==(i=d.createVad)&&void 0!==i?i:()=>new y,flushIntervalMs:null!==(r=d.flushIntervalMs)&&void 0!==r?r:50,resolveUnknownChannelsMethod:null!==(o=d.resolveUnknownChannelsMethod)&&void 0!==o?o:"window",resolutionWindowWords:null!==(a=d.resolutionWindowWords)&&void 0!==a?a:2,speakerHistoryMinRmsEvidence:null!==(l=d.speakerHistoryMinRmsEvidence)&&void 0!==l?l:.5,speakerHistoryDominanceRatio:null!==(c=d.speakerHistoryDominanceRatio)&&void 0!==c?c:3},"speaker-history"===this.attributionParams.resolveUnknownChannelsMethod&&(this.speakerHistory=new Map),this.vadFrameSamples=Math.max(1,Math.round(.02*e.sampleRate)),this.minChunkSamples=Math.max(1,Math.round(.05*e.sampleRate)),this.maxChunkSamples=Math.max(this.minChunkSamples,Math.round(.2*e.sampleRate)),this.channelBuffers=new Map(h.map((e=>[e,[]]))),this.channelSamplesReceived=new Map(h.map((e=>[e,0]))),this.channelVadFloatBuffers=new Map(h.map((e=>[e,new Float32Array(this.vadFrameSamples)]))),this.channelVadBufferIdx=new Map(h.map((e=>[e,0]))),this.channelVads=new Map(h.map((e=>[e,this.attributionParams.createVad(e)]))),this.timeline=new k(this.attributionParams.timelineWindowMs)}}connectionUrl(){var e,t;const s=new URL(null!==(e=this.params.websocketBaseUrl)&&void 0!==e?e:"");if("wss:"!==s.protocol)throw new Error("Invalid protocol, must be wss");const n=new URLSearchParams;this.token&&n.set("token",this.token),n.set("sample_rate",this.params.sampleRate.toString()),this.params.endOfTurnConfidenceThreshold&&n.set("end_of_turn_confidence_threshold",this.params.endOfTurnConfidenceThreshold.toString()),void 0!==this.params.minEndOfTurnSilenceWhenConfident&&(void 0!==this.params.minTurnSilence?console.warn("[Deprecation Warning] Both `minEndOfTurnSilenceWhenConfident` and `minTurnSilence` are set. Using `minTurnSilence`; `minEndOfTurnSilenceWhenConfident` is deprecated."):console.warn("[Deprecation Warning] `minEndOfTurnSilenceWhenConfident` is deprecated and will be removed in a future release. Please use `minTurnSilence` instead."));const i=null!==(t=this.params.minTurnSilence)&&void 0!==t?t:this.params.minEndOfTurnSilenceWhenConfident;return void 0!==i&&n.set("min_turn_silence",i.toString()),this.params.maxTurnSilence&&n.set("max_turn_silence",this.params.maxTurnSilence.toString()),void 0!==this.params.vadThreshold&&n.set("vad_threshold",this.params.vadThreshold.toString()),this.params.formatTurns&&n.set("format_turns",this.params.formatTurns.toString()),this.params.encoding&&n.set("encoding",this.params.encoding.toString()),this.params.keytermsPrompt?n.set("keyterms_prompt",JSON.stringify(this.params.keytermsPrompt)):this.params.keyterms&&(console.warn("[Deprecation Warning] `keyterms` is deprecated and will be removed in a future release. Please use `keytermsPrompt` instead."),n.set("keyterms_prompt",JSON.stringify(this.params.keyterms))),this.params.prompt&&n.set("prompt",this.params.prompt),this.params.agentContext&&n.set("agent_context",this.params.agentContext),this.params.filterProfanity&&n.set("filter_profanity",this.params.filterProfanity.toString()),"u3-pro"===this.params.speechModel&&console.warn("[Deprecation Warning] The speech model `u3-pro` is deprecated and will be removed in a future release. Please use `u3-rt-pro` instead."),void 0!==this.params.speechModel&&n.set("speech_model",this.params.speechModel.toString()),void 0!==this.params.languageCode&&(console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead."),n.set("language_code",this.params.languageCode)),void 0!==this.params.languageCodes&&n.set("language_codes",JSON.stringify(this.params.languageCodes)),void 0!==this.params.languageDetection&&n.set("language_detection",this.params.languageDetection.toString()),this.params.domain&&n.set("domain",this.params.domain),void 0!==this.params.inactivityTimeout&&n.set("inactivity_timeout",this.params.inactivityTimeout.toString()),void 0!==this.params.speakerLabels&&n.set("speaker_labels",this.params.speakerLabels.toString()),void 0!==this.params.maxSpeakers&&n.set("max_speakers",this.params.maxSpeakers.toString()),this.params.voiceFocus&&n.set("voice_focus",this.params.voiceFocus),void 0!==this.params.voiceFocusThreshold&&n.set("voice_focus_threshold",this.params.voiceFocusThreshold.toString()),void 0!==this.params.continuousPartials&&n.set("continuous_partials",this.params.continuousPartials.toString()),void 0!==this.params.interruptionDelay&&n.set("interruption_delay",this.params.interruptionDelay.toString()),void 0!==this.params.turnLeftPadMs&&n.set("turn_left_pad_ms",this.params.turnLeftPadMs.toString()),this.params.customerSupportAudioCapture&&(console.warn("`customerSupportAudioCapture=true` will record session audio. Only enable this when explicitly coordinating with AssemblyAI support."),n.set("_customer_support_audio_capture",this.params.customerSupportAudioCapture.toString())),this.params.webhookUrl&&n.set("webhook_url",this.params.webhookUrl),this.params.webhookAuthHeaderName&&n.set("webhook_auth_header_name",this.params.webhookAuthHeaderName),this.params.webhookAuthHeaderValue&&n.set("webhook_auth_header_value",this.params.webhookAuthHeaderValue),void 0!==this.params.includePartialTurns&&n.set("include_partial_turns",this.params.includePartialTurns.toString()),void 0!==this.params.redactPii&&n.set("redact_pii",this.params.redactPii.toString()),void 0!==this.params.redactPiiPolicies&&n.set("redact_pii_policies",JSON.stringify(this.params.redactPiiPolicies)),void 0!==this.params.redactPiiSub&&n.set("redact_pii_sub",this.params.redactPiiSub),void 0!==this.params.mode&&n.set("mode",this.params.mode),void 0!==this.params.llmGateway&&n.set("llm_gateway",JSON.stringify(this.params.llmGateway)),s.search=n.toString(),s}on(e,t){this.listeners[e]=t}connect(){return s(this,void 0,void 0,(function*(){var e,t;if(this.socket)throw new Error("Already connected");const s=null!==(e=this.params.maxConnectionRetries)&&void 0!==e?e:2,n=null!==(t=this.params.connectionRetryDelay)&&void 0!==t?t:500;let i;for(let e=0;e<=s;e++)try{return yield this.connectOnce()}catch(t){i=t;if(!(!0===t.retryable)||e===s)throw t;console.warn(`Streaming connect attempt ${e+1}/${s+1} failed (${t.message}); retrying`),n>0&&(yield new Promise((e=>setTimeout(e,n))))}throw null!=i?i:new Error("Failed to connect to streaming server")}))}connectOnce(){return new Promise(((e,t)=>{var s;const n=this.connectionUrl(),i=null!==(s=this.params.connectTimeout)&&void 0!==s?s:1e3;let r,o=!1;const l=e=>{o||(o=!0,r&&clearTimeout(r),this.discardPendingSocket(),t(e))};i>0&&(r=setTimeout((()=>{const e=new v(`Streaming connection timed out after ${i}ms`);e.retryable=!0,l(e)}),i)),this.token?this.socket=a(n.toString()):(console.warn("API key authentication is not supported for the StreamingTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=a(n.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{},this.socket.onclose=({code:e,reason:t})=>{var s,n;if(t||e in f&&(t=f[e]),!o){const s=new v(t||`Streaming connection closed (code=${e})`);return s.code=e,s.retryable=x(e),void l(s)}this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n;const i=null!==(t=e.error)&&void 0!==t?t:new Error(e.message);if(!o)return i.retryable=!0,void l(i);null===(n=(s=this.listeners).error)||void 0===n||n.call(s,i)},this.socket.onmessage=({data:t})=>{var s,n,i,a,c,h,d,u,m,p,f,g,w,y,k;const S=JSON.parse(t.toString());if("error"in S){const e=new v(S.error);if("error_code"in S&&(e.code=S.error_code),!o){const t=e;return t.retryable=void 0===e.code||x(e.code),void l(t)}null===(n=(s=this.listeners).error)||void 0===n||n.call(s,e)}else{switch(S.type){case"Begin":b=S,o||(o=!0,r&&clearTimeout(r),e(b)),null===(a=(i=this.listeners).open)||void 0===a||a.call(i,S);break;case"Turn":if(this.isDualChannel&&this.timeline&&this.attributionParams)switch(_(S,this.timeline,{dominanceRatio:this.attributionParams.dominanceRatio}),this.attributionParams.resolveUnknownChannelsMethod){case"window":this.resolveUnknownChannelsByWindow(S);break;case"speaker-history":this.resolveUnknownChannelsBySpeakerHistory(S)}null===(h=(c=this.listeners).turn)||void 0===h||h.call(c,S);break;case"SpeechStarted":null===(u=(d=this.listeners).speechStarted)||void 0===u||u.call(d,S);break;case"LLMGatewayResponse":null===(p=(m=this.listeners).llmGatewayResponse)||void 0===p||p.call(m,S);break;case"SpeakerRevision":null===(g=(f=this.listeners).speakerRevision)||void 0===g||g.call(f,S);break;case"Warning":{const e=S;console.warn(`Streaming warning (code=${e.warning_code}): ${e.warning}`),null===(y=(w=this.listeners).warning)||void 0===y||y.call(w,e);break}case"Termination":null===(k=this.sessionTerminatedResolve)||void 0===k||k.call(this)}var b}}}))}discardPendingSocket(){if(this.socket){try{this.socket.removeAllListeners&&this.socket.removeAllListeners(),this.socket.close()}catch(e){}this.socket=void 0}}stream(){return new n({write:e=>{this.sendAudio(e)}})}sendAudio(e,t){if(this.isDualChannel){if(!(null==t?void 0:t.channel))throw new Error("StreamingTranscriber is in dual-channel mode; sendAudio requires { channel }.");if(!this.channelNames.includes(t.channel))throw new Error(`Unknown channel "${t.channel}"; declared channels: ${this.channelNames.join(", ")}.`);this.ingestChannelAudio(t.channel,e)}else this.send(e)}ingestChannelAudio(e,t){var s,n;const i=function(e){if(e instanceof Int16Array)return e;if(ArrayBuffer.isView(e)){const t=e;return new Int16Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/2))}return new Int16Array(e)}(t),r=this.channelBuffers.get(e),o=this.channelVadFloatBuffers.get(e);let a=this.channelVadBufferIdx.get(e),l=this.channelSamplesReceived.get(e);const c=this.channelVads.get(e),h=this.params.sampleRate,d=this.vadFrameSamples;for(let t=0;t<i.length;t++){const u=i[t];if(r.push(u),o[a++]=u/32768,l++,a===d){const t=c.process(o),i={ts:l/h*1e3,channel:e,active:t.active,rms:t.energy};this.timeline.pushFrame(i),null===(n=(s=this.listeners).vad)||void 0===n||n.call(s,i),a=0}}this.channelVadBufferIdx.set(e,a),this.channelSamplesReceived.set(e,l),this.flushTimer||this.startFlushTimer()}startFlushTimer(){this.flushTimer=setInterval((()=>this.flushMix()),this.attributionParams.flushIntervalMs)}flushMix(e=!1){var t,s;if(!this.channelNames||!this.channelBuffers)return;const n=this.channelNames.map((e=>this.channelBuffers.get(e))),i=n.length;for(;;){let r=1/0;for(const e of n)e.length<r&&(r=e.length);if(!Number.isFinite(r)||0===r)return;if(!e&&r<this.minChunkSamples)return;r>this.maxChunkSamples&&(r=this.maxChunkSamples);const o=new Int16Array(r);for(let e=0;e<r;e++){let t=0;for(let s=0;s<i;s++)t+=n[s][e];const s=Math.round(t/i);o[e]=s<-32768?-32768:s>32767?32767:s}for(const e of n)e.splice(0,r);try{this.send(o.buffer)}catch(e){return void(null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e))}}}resolveUnknownChannelsByWindow(e){var t;if(!this.attributionParams)return;const s=this.attributionParams.resolutionWindowWords,n=e.words;let i=!1;for(let e=0;e<n.length;e++){if("unknown"!==n[e].channel)continue;const r=new Map,o=Math.max(0,e-s),a=Math.min(n.length-1,e+s);for(let s=o;s<=a;s++){if(s===e)continue;const i=n[s].channel;i&&"unknown"!==i&&r.set(i,(null!==(t=r.get(i))&&void 0!==t?t:0)+1)}if(0===r.size)continue;let l,c=0,h=!1;for(const[e,t]of r)t>c?(l=e,c=t,h=!1):t===c&&(h=!0);l&&!h&&(n[e].channel=l,n[e].channelResolved=!0,i=!0)}i&&(e.channel=b(n))}resolveUnknownChannelsBySpeakerHistory(e){var t;if(!this.timeline||!this.attributionParams||!this.speakerHistory)return;const s=this.attributionParams.speakerHistoryMinRmsEvidence,n=this.attributionParams.speakerHistoryDominanceRatio;for(const s of e.words){if(!s.speaker)continue;const e=this.timeline.framesInWindow(s.start,s.end);let n=this.speakerHistory.get(s.speaker);n||(n=new Map,this.speakerHistory.set(s.speaker,n));for(const s of e)s.active&&n.set(s.channel,(null!==(t=n.get(s.channel))&&void 0!==t?t:0)+s.rms)}let i=!1;for(const t of e.words){if("unknown"!==t.channel||!t.speaker)continue;const e=this.speakerHistory.get(t.speaker);if(!e||0===e.size)continue;let r,o=0,a=0,l=0;for(const[t,s]of e)o+=s,s>a?(l=a,a=s,r=t):s>l&&(l=s);o<s||(l>0&&a<n*l||r&&(t.channel=r,t.channelResolved=!0,i=!0))}i&&(e.channel=b(e.words))}updateConfiguration(e){const{min_end_of_turn_silence_when_confident:t,min_turn_silence:s}=e,n=function(e,t){var s={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(s[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(n=Object.getOwnPropertySymbols(e);i<n.length;i++)t.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(s[n[i]]=e[n[i]])}return s}(e,["min_end_of_turn_silence_when_confident","min_turn_silence"]);void 0!==t&&(void 0!==s?console.warn("[Deprecation Warning] Both `min_end_of_turn_silence_when_confident` and `min_turn_silence` are set. Using `min_turn_silence`; `min_end_of_turn_silence_when_confident` is deprecated."):console.warn("[Deprecation Warning] `min_end_of_turn_silence_when_confident` is deprecated and will be removed in a future release. Please use `min_turn_silence` instead."));const i=null!=s?s:t,r=Object.assign(Object.assign({type:"UpdateConfiguration"},n),void 0!==i?{min_turn_silence:i}:{});this.send(JSON.stringify(r))}forceEndpoint(){this.send(JSON.stringify({type:"ForceEndpoint"}))}keepAlive(){this.send(JSON.stringify({type:"KeepAlive"}))}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return s(this,arguments,void 0,(function*(e=!0){var t;if(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0,this.flushMix(!0)),this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(T),yield e}else this.socket.send(T);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}const R={cache:"no-store"};let E="";"undefined"!=typeof navigator&&navigator.userAgent&&(E+=navigator.userAgent);const O={sdk:{name:"JavaScript",version:"4.35.3"}};"undefined"!=typeof process&&(process.versions.node&&-1===E.indexOf("Node")&&(O.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===E.indexOf("Bun")&&(O.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===E.indexOf("Deno")&&(O.runtime_env={name:"Deno",version:Deno.version.deno});class M{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},E+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},O),t)).map((([e,t])=>t?`${e}=${t.name}/${t.version}`:"")).join(" ")+")"))}fetch(e,t){return s(this,void 0,void 0,(function*(){t=Object.assign(Object.assign({},R),t);let s={Authorization:this.params.apiKey,"Content-Type":"application/json"};(null==R?void 0:R.headers)&&(s=Object.assign(Object.assign({},s),R.headers)),(null==t?void 0:t.headers)&&(s=Object.assign(Object.assign({},s),t.headers)),this.userAgent&&(s["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(s["AssemblyAI-Agent"]=this.userAgent)),t.headers=s,e.startsWith("http")||(e=this.params.baseUrl+e);const n=yield fetch(e,t);if(n.status>=400){let e;const t=yield n.text();if(t){try{e=JSON.parse(t)}catch(e){}if(null==e?void 0:e.error)throw new Error(e.error);throw new Error(t)}throw new Error(`HTTP Error: ${n.status} ${n.statusText}`)}return n}))}fetchJson(e,t){return s(this,void 0,void 0,(function*(){return(yield this.fetch(e,t)).json()}))}}class C extends M{constructor(e){super(e),this.baseServiceParams=e}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.baseServiceParams.apiKey),new P(t)}createTemporaryToken(e){return s(this,void 0,void 0,(function*(){const t=new URLSearchParams;Object.entries(e).forEach((([e,s])=>{null!=s&&t.append(e,String(s))}));const s=t.toString(),n=s?`/v3/token?${s}`:"/v3/token";return(yield this.fetchJson(n,{method:"GET"})).token}))}}e.BrowserOnlyError=t,e.DualChannelCapture=class{constructor(e){var s;if(this.running=!1,void 0===globalThis.AudioContext)throw new t;this.params={micStream:e.micStream,systemStream:e.systemStream,transcriber:e.transcriber,targetSampleRate:null!==(s=e.targetSampleRate)&&void 0!==s?s:16e3}}on(e,t){"error"===e&&(this.errorListener=t)}start(){return s(this,void 0,void 0,(function*(){if(this.running)throw new Error("DualChannelCapture already started");this.context=new AudioContext;const e=new Blob(['\nclass Pcm16EncoderProcessor extends AudioWorkletProcessor {\n constructor(options) {\n super();\n const opts = (options && options.processorOptions) || {};\n this.targetRate = opts.targetRate || 16000;\n this.chunkMs = opts.chunkMs || 50;\n this.ratio = sampleRate / this.targetRate;\n this.chunkSize = Math.round(this.targetRate * this.chunkMs / 1000);\n this.buffer = new Int16Array(this.chunkSize);\n this.bufferIdx = 0;\n this.samplesSent = 0;\n this.lastSample = 0;\n this.fractional = 0;\n }\n\n process(inputs) {\n const input = inputs[0];\n if (!input || input.length === 0 || !input[0] || input[0].length === 0) {\n return true;\n }\n const mono = input[0];\n let pos = this.fractional;\n while (pos < mono.length) {\n const i = Math.floor(pos);\n const frac = pos - i;\n const a = i === 0 ? this.lastSample : mono[i - 1];\n const b = mono[i];\n const sample = a + (b - a) * frac;\n const clamped = sample < -1 ? -1 : sample > 1 ? 1 : sample;\n this.buffer[this.bufferIdx++] = clamped < 0 ? clamped * 0x8000 : clamped * 0x7fff;\n if (this.bufferIdx === this.chunkSize) {\n const out = new Int16Array(this.chunkSize);\n out.set(this.buffer);\n this.samplesSent += this.chunkSize;\n this.port.postMessage(\n { pcm: out.buffer, samplesSent: this.samplesSent },\n [out.buffer],\n );\n this.bufferIdx = 0;\n }\n pos += this.ratio;\n }\n this.lastSample = mono[mono.length - 1];\n this.fractional = pos - mono.length;\n return true;\n }\n}\nregisterProcessor("aai-pcm16-encoder", Pcm16EncoderProcessor);\n'],{type:"application/javascript"}),t=URL.createObjectURL(e);try{yield this.context.audioWorklet.addModule(t)}finally{URL.revokeObjectURL(t)}this.micSource=this.context.createMediaStreamSource(this.params.micStream),this.sysSource=this.context.createMediaStreamSource(this.params.systemStream),this.micEncoder=this.makeEncoder("mic"),this.sysEncoder=this.makeEncoder("system"),this.micSource.connect(this.micEncoder),this.sysSource.connect(this.sysEncoder),this.running=!0}))}makeEncoder(e){const t=new AudioWorkletNode(this.context,"aai-pcm16-encoder",{numberOfInputs:1,numberOfOutputs:0,channelCount:1,channelCountMode:"explicit",channelInterpretation:"speakers",processorOptions:{targetRate:this.params.targetSampleRate,chunkMs:50}});return t.port.onmessage=t=>{var s;try{this.params.transcriber.sendAudio(t.data.pcm,{channel:e})}catch(e){null===(s=this.errorListener)||void 0===s||s.call(this,e)}},t}stop(){return s(this,void 0,void 0,(function*(){var e,t,s,n,i,r;if(this.running){this.running=!1;try{null===(e=this.micEncoder)||void 0===e||e.port.close(),null===(t=this.sysEncoder)||void 0===t||t.port.close(),null===(s=this.micEncoder)||void 0===s||s.disconnect(),null===(n=this.sysEncoder)||void 0===n||n.disconnect(),null===(i=this.micSource)||void 0===i||i.disconnect(),null===(r=this.sysSource)||void 0===r||r.disconnect()}catch(e){}this.context&&"closed"!==this.context.state&&(yield this.context.close()),this.context=void 0,this.micSource=void 0,this.sysSource=void 0,this.micEncoder=void 0,this.sysEncoder=void 0}}))}},e.EnergyVad=y,e.LinearResampler=class{constructor(e,t){if(this.sourceRate=e,this.targetRate=t,this.lastSample=0,this.fractional=0,e<=0||t<=0)throw new Error("sourceRate and targetRate must be positive");this.ratio=e/t}process(e){var t;if(this.sourceRate===this.targetRate)return e;const s=new Float32Array(Math.ceil(e.length/this.ratio)+1);let n=0,i=this.fractional;for(;i<e.length;){const t=Math.floor(i),r=i-t,o=0===t?this.lastSample:e[t-1],a=e[t];s[n++]=o+(a-o)*r,i+=this.ratio}return this.lastSample=null!==(t=e[e.length-1])&&void 0!==t?t:this.lastSample,this.fractional=i-e.length,s.subarray(0,n)}reset(){this.lastSample=0,this.fractional=0}},e.RealtimeService=class extends w{},e.RealtimeTranscriber=w,e.StreamingServiceFactory=class extends C{},e.StreamingTranscriber=P,e.StreamingTranscriberFactory=C,e.VadTimeline=k,e.attributeTurn=_,e.attributeWord=S,e.float32ToPcm16=function(e){const t=new ArrayBuffer(2*e.length),s=new DataView(t);for(let t=0;t<e.length;t++){const n=Math.max(-1,Math.min(1,e[t]));s.setInt16(2*t,n<0?32768*n:32767*n,!0)}return t},e.rollUpTurnChannel=b}));
@@ -78,7 +78,7 @@
78
78
  defaultUserAgentString += navigator.userAgent;
79
79
  }
80
80
  const defaultUserAgent = {
81
- sdk: { name: "JavaScript", version: "4.35.0" },
81
+ sdk: { name: "JavaScript", version: "4.35.3" },
82
82
  };
83
83
  if (typeof process !== "undefined") {
84
84
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1239,8 +1239,12 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
1239
1239
  searchParams.set("speech_model", this.params.speechModel.toString());
1240
1240
  }
1241
1241
  if (this.params.languageCode !== undefined) {
1242
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
1242
1243
  searchParams.set("language_code", this.params.languageCode);
1243
1244
  }
1245
+ if (this.params.languageCodes !== undefined) {
1246
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
1247
+ }
1244
1248
  if (this.params.languageDetection !== undefined) {
1245
1249
  searchParams.set("language_detection", this.params.languageDetection.toString());
1246
1250
  }
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).assemblyai={})}(this,(function(e){"use strict";class t extends Error{constructor(e="DualChannelCapture requires a browser environment (AudioContext is undefined)."){super(e),this.name="BrowserOnlyError"}}function s(e,t){var s={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(s[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(n=Object.getOwnPropertySymbols(e);i<n.length;i++)t.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(s[n[i]]=e[n[i]])}return s}function n(e,t,s,n){return new(s||(s=Promise))((function(i,r){function o(e){try{l(n.next(e))}catch(e){r(e)}}function a(e){try{l(n.throw(e))}catch(e){r(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}l((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const i={cache:"no-store"};let r="";"undefined"!=typeof navigator&&navigator.userAgent&&(r+=navigator.userAgent);const o={sdk:{name:"JavaScript",version:"4.35.0"}};"undefined"!=typeof process&&(process.versions.node&&-1===r.indexOf("Node")&&(o.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===r.indexOf("Bun")&&(o.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===r.indexOf("Deno")&&(o.runtime_env={name:"Deno",version:Deno.version.deno});class a{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},r+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},o),t)).map((([e,t])=>t?`${e}=${t.name}/${t.version}`:"")).join(" ")+")"))}fetch(e,t){return n(this,void 0,void 0,(function*(){t=Object.assign(Object.assign({},i),t);let s={Authorization:this.params.apiKey,"Content-Type":"application/json"};(null==i?void 0:i.headers)&&(s=Object.assign(Object.assign({},s),i.headers)),(null==t?void 0:t.headers)&&(s=Object.assign(Object.assign({},s),t.headers)),this.userAgent&&(s["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(s["AssemblyAI-Agent"]=this.userAgent)),t.headers=s,e.startsWith("http")||(e=this.params.baseUrl+e);const n=yield fetch(e,t);if(n.status>=400){let e;const t=yield n.text();if(t){try{e=JSON.parse(t)}catch(e){}if(null==e?void 0:e.error)throw new Error(e.error);throw new Error(t)}throw new Error(`HTTP Error: ${n.status} ${n.statusText}`)}return n}))}fetchJson(e,t){return n(this,void 0,void 0,(function*(){return(yield this.fetch(e,t)).json()}))}}class l extends a{summary(e,t){return this.fetchJson("/lemur/v3/generate/summary",{method:"POST",body:JSON.stringify(e),signal:t})}questionAnswer(e,t){return this.fetchJson("/lemur/v3/generate/question-answer",{method:"POST",body:JSON.stringify(e),signal:t})}actionItems(e,t){return this.fetchJson("/lemur/v3/generate/action-items",{method:"POST",body:JSON.stringify(e),signal:t})}task(e,t){return this.fetchJson("/lemur/v3/generate/task",{method:"POST",body:JSON.stringify(e),signal:t})}getResponse(e,t){return this.fetchJson(`/lemur/v3/${e}`,{signal:t})}purgeRequestData(e,t){return this.fetchJson(`/lemur/v3/${e}`,{method:"DELETE",signal:t})}}const{WritableStream:c}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var h,d;const u=null!==(d=null!==(h=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==h?h:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==d?d:null===self||void 0===self?void 0:self.WebSocket,m=(e,t)=>t?new u(e,t):new u(e),p={[4e3]:"Sample rate must be a positive integer",[4001]:"Not Authorized",[4002]:"Insufficient funds",[4003]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[4100]:"Bad JSON",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid.",[1013]:"Reconnect attempts exhausted",[4104]:"Could not parse word boost parameter"};class f extends Error{}const v=4e3,g=4001,y=4002,w=4003,b=4101,S={[3005]:"Server error",[3006]:"Input validation error",[3007]:"Audio chunk duration violation",[3008]:"Session expired: maximum session duration exceeded",[3009]:"Too many concurrent sessions",[v]:"Sample rate must be a positive integer",[g]:"Not Authorized",[y]:"Insufficient funds",[w]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[b]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid."};class k extends Error{}const _='{"terminate_session":true}';class T{constructor(e){var t,s;if(this.listeners={},this.realtimeUrl=null!==(t=e.realtimeUrl)&&void 0!==t?t:"wss://api.assemblyai.com/v2/realtime/ws",this.sampleRate=null!==(s=e.sampleRate)&&void 0!==s?s:16e3,this.wordBoost=e.wordBoost,this.encoding=e.encoding,this.endUtteranceSilenceThreshold=e.endUtteranceSilenceThreshold,this.disablePartialTranscripts=e.disablePartialTranscripts,"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.")}connectionUrl(){const e=new URL(this.realtimeUrl);if("wss:"!==e.protocol)throw new Error("Invalid protocol, must be wss");const t=new URLSearchParams;return this.token&&t.set("token",this.token),t.set("sample_rate",this.sampleRate.toString()),this.wordBoost&&this.wordBoost.length>0&&t.set("word_boost",JSON.stringify(this.wordBoost)),this.encoding&&t.set("encoding",this.encoding),t.set("enable_extra_session_information","true"),this.disablePartialTranscripts&&t.set("disable_partial_transcripts",this.disablePartialTranscripts.toString()),e.search=t.toString(),e}on(e,t){this.listeners[e]=t}connect(){return new Promise((e=>{if(this.socket)throw new Error("Already connected");const t=this.connectionUrl();this.token?this.socket=m(t.toString()):(console.warn("API key authentication is not supported for the RealtimeTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=m(t.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{void 0!==this.endUtteranceSilenceThreshold&&null!==this.endUtteranceSilenceThreshold&&this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold)},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in p&&(t=p[e]),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n,i;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(i=(n=this.listeners).error)||void 0===i||i.call(n,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,n,i,r,o,a,l,c,h,d,u,m,p,v,g;const y=JSON.parse(t.toString());if("error"in y)null===(n=(s=this.listeners).error)||void 0===n||n.call(s,new f(y.error));else switch(y.message_type){case"SessionBegins":{const t={sessionId:y.session_id,expiresAt:new Date(y.expires_at)};e(t),null===(r=(i=this.listeners).open)||void 0===r||r.call(i,t);break}case"PartialTranscript":y.created=new Date(y.created),null===(a=(o=this.listeners).transcript)||void 0===a||a.call(o,y),null===(c=(l=this.listeners)["transcript.partial"])||void 0===c||c.call(l,y);break;case"FinalTranscript":y.created=new Date(y.created),null===(d=(h=this.listeners).transcript)||void 0===d||d.call(h,y),null===(m=(u=this.listeners)["transcript.final"])||void 0===m||m.call(u,y);break;case"SessionInformation":null===(v=(p=this.listeners).session_information)||void 0===v||v.call(p,y);break;case"SessionTerminated":null===(g=this.sessionTerminatedResolve)||void 0===g||g.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new c({write:e=>{this.sendAudio(e)}})}forceEndUtterance(){this.send('{"force_end_utterance":true}')}configureEndUtteranceSilenceThreshold(e){this.send(`{"end_utterance_silence_threshold":${e}}`)}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return n(this,arguments,void 0,(function*(e=!0){var t;if(this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(_),yield e}else this.socket.send(_);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class A extends a{constructor(e){super(e),this.rtFactoryParams=e}createService(e){return this.transcriber(e)}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.rtFactoryParams.apiKey),new T(t)}createTemporaryToken(e){return n(this,void 0,void 0,(function*(){return(yield this.fetchJson("/v2/realtime/token",{method:"POST",body:JSON.stringify(e)})).token}))}}function P(e){return e.startsWith("http")||e.startsWith("https")||e.startsWith("data:")?null:e.startsWith("file://")?e.substring(7):e.startsWith("file:")?e.substring(5):e}class x extends a{constructor(e,t){super(e),this.files=t}transcribe(e,t){return n(this,void 0,void 0,(function*(){const s=yield this.submit(e);return yield this.waitUntilReady(s.id,t)}))}submit(e){return n(this,void 0,void 0,(function*(){let t,n;if("audio"in e){const{audio:i}=e,r=s(e,["audio"]);if("string"==typeof i){const e=P(i);t=null!==e?yield this.files.upload(e):i.startsWith("data:")?yield this.files.upload(i):i}else t=yield this.files.upload(i);n=Object.assign(Object.assign({},r),{audio_url:t})}else n=e;return yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(n)})}))}create(e,t){return n(this,void 0,void 0,(function*(){var s;const n=P(e.audio_url);if(null!==n){const t=yield this.files.upload(n);e.audio_url=t}const i=yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(e)});return null===(s=null==t?void 0:t.poll)||void 0===s||s?yield this.waitUntilReady(i.id,t):i}))}waitUntilReady(e,t){return n(this,void 0,void 0,(function*(){var s,n;const i=null!==(s=null==t?void 0:t.pollingInterval)&&void 0!==s?s:3e3,r=null!==(n=null==t?void 0:t.pollingTimeout)&&void 0!==n?n:-1,o=Date.now();for(;;){const t=yield this.get(e);if("completed"===t.status||"error"===t.status)return t;if(r>0&&Date.now()-o>r)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,i)))}}))}get(e){return this.fetchJson(`/v2/transcript/${e}`)}list(e){return n(this,void 0,void 0,(function*(){let t="/v2/transcript";"string"==typeof e?t=e:e&&(t=`${t}?${new URLSearchParams(Object.keys(e).map((t=>{var s;return[t,(null===(s=e[t])||void 0===s?void 0:s.toString())||""]})))}`);const s=yield this.fetchJson(t);for(const e of s.transcripts)e.created=new Date(e.created),e.completed&&(e.completed=new Date(e.completed));return s}))}delete(e){return this.fetchJson(`/v2/transcript/${e}`,{method:"DELETE"})}wordSearch(e,t){const s=new URLSearchParams({words:t.join(",")});return this.fetchJson(`/v2/transcript/${e}/word-search?${s.toString()}`)}sentences(e){return this.fetchJson(`/v2/transcript/${e}/sentences`)}paragraphs(e){return this.fetchJson(`/v2/transcript/${e}/paragraphs`)}subtitles(e){return n(this,arguments,void 0,(function*(e,t="srt",s){let n=`/v2/transcript/${e}/${t}`;if(s){const e=new URLSearchParams;e.set("chars_per_caption",s.toString()),n+=`?${e.toString()}`}const i=yield this.fetch(n);return yield i.text()}))}redactions(e){return this.redactedAudio(e)}redactedAudio(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}redactedAudioFile(e){return n(this,void 0,void 0,(function*(){const{redacted_audio_url:t,status:s}=yield this.redactedAudio(e);if("redacted_audio_ready"!==s)throw new Error(`Redacted audio status is ${s}`);const n=yield fetch(t);if(!n.ok)throw new Error(`Failed to fetch redacted audio: ${n.statusText}`);return{arrayBuffer:n.arrayBuffer.bind(n),blob:n.blob.bind(n),body:n.body,bodyUsed:n.bodyUsed}}))}}class O extends a{upload(e){return n(this,void 0,void 0,(function*(){let t;t="string"==typeof e?e.startsWith("data:")?function(e){const t=e.split(","),s=t[0].match(/:(.*?);/)[1],n=atob(t[1]);let i=n.length;const r=new Uint8Array(i);for(;i--;)r[i]=n.charCodeAt(i);return new Blob([r],{type:s})}(e):yield function(e){return n(this,void 0,void 0,(function*(){throw new Error("Interacting with the file system is not supported in this environment.")}))}():e;return(yield this.fetchJson("/v2/upload",{method:"POST",body:t,headers:{"Content-Type":"application/octet-stream"},duplex:"half"})).upload_url}))}}class R{constructor(e={}){var t,s,n,i;this.hangoverRemaining=0,this.thresholdRatio=null!==(t=e.thresholdRatio)&&void 0!==t?t:3,this.noiseFloorAlpha=null!==(s=e.noiseFloorAlpha)&&void 0!==s?s:.05,this.hangoverFrames=null!==(n=e.hangoverFrames)&&void 0!==n?n:10,this.initialNoiseFloor=null!==(i=e.initialNoiseFloor)&&void 0!==i?i:1e-4,this.noiseFloor=this.initialNoiseFloor}process(e){let t=0;for(let s=0;s<e.length;s++)t+=e[s]*e[s];const s=e.length>0?Math.sqrt(t/e.length):0;let n=s>this.noiseFloor*this.thresholdRatio;return n?this.hangoverRemaining=this.hangoverFrames:this.hangoverRemaining>0?(this.hangoverRemaining--,n=!0):this.noiseFloor=this.noiseFloor*(1-this.noiseFloorAlpha)+s*this.noiseFloorAlpha,{active:n,energy:s}}reset(){this.noiseFloor=this.initialNoiseFloor,this.hangoverRemaining=0}}class E{constructor(e){this.windowMs=e,this.frames=[],this.head=0}pushFrame(e){this.frames.push(e);const t=e.ts-this.windowMs;for(;this.head<this.frames.length&&this.frames[this.head].ts<t;)this.head++;this.head>1024&&2*this.head>this.frames.length&&(this.frames=this.frames.slice(this.head),this.head=0)}framesInWindow(e,t){const s=[];for(let n=this.head;n<this.frames.length;n++){const i=this.frames[n];if(!(i.ts<e)){if(i.ts>t)break;s.push(i)}}return s}clear(){this.frames=[],this.head=0}}function U(e,t,s){const n=function(e){var t;const s=new Map;for(const n of e)n.active&&s.set(n.channel,(null!==(t=s.get(n.channel))&&void 0!==t?t:0)+n.rms);return s}(t.framesInWindow(e.start,e.end));if(0===n.size)return"unknown";const i=[...n.entries()].sort(((e,t)=>t[1]-e[1]));if(1===i.length)return i[0][0];const[r,o]=i[0],[a,l]=i[1];return o>=s.dominanceRatio*l||o>l?r:l>o?a:"unknown"}function M(e){var t;const s=new Map;for(const n of e){if(!n.channel||"unknown"===n.channel)continue;const e=Math.max(0,n.end-n.start);s.set(n.channel,(null!==(t=s.get(n.channel))&&void 0!==t?t:0)+e)}if(0===s.size)return"unknown";const n=[...s.entries()].sort(((e,t)=>t[1]-e[1]));if(1===n.length)return n[0][0];const[i,r]=n[0],[,o]=n[1];return r===o?"unknown":i}function C(e,t,s){for(const n of e.words)n.channel=U(n,t,s);e.channel=M(e.words)}const I='{"type":"Terminate"}',W=new Set([v,g,y,w,b]);function F(e){return 1e3!==e&&!W.has(e)}class N{constructor(e){var t,s,n,i,r,o,a,l,c;if(this.listeners={},this.isDualChannel=!1,this.vadFrameSamples=0,this.minChunkSamples=0,this.maxChunkSamples=0,this.params=Object.assign(Object.assign({},e),{websocketBaseUrl:e.websocketBaseUrl||"wss://streaming.assemblyai.com/v3/ws"}),"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.");if(e.channels){if(2!==e.channels.length)throw new Error("StreamingTranscriber.channels must have exactly 2 entries.");const h=e.channels.map((e=>e.name));if(new Set(h).size!==h.length)throw new Error("StreamingTranscriber.channels names must be unique.");this.isDualChannel=!0,this.channelNames=h;const d=null!==(t=e.channelAttribution)&&void 0!==t?t:{};this.attributionParams={dominanceRatio:null!==(s=d.dominanceRatio)&&void 0!==s?s:4,timelineWindowMs:null!==(n=d.timelineWindowMs)&&void 0!==n?n:3e4,createVad:null!==(i=d.createVad)&&void 0!==i?i:()=>new R,flushIntervalMs:null!==(r=d.flushIntervalMs)&&void 0!==r?r:50,resolveUnknownChannelsMethod:null!==(o=d.resolveUnknownChannelsMethod)&&void 0!==o?o:"window",resolutionWindowWords:null!==(a=d.resolutionWindowWords)&&void 0!==a?a:2,speakerHistoryMinRmsEvidence:null!==(l=d.speakerHistoryMinRmsEvidence)&&void 0!==l?l:.5,speakerHistoryDominanceRatio:null!==(c=d.speakerHistoryDominanceRatio)&&void 0!==c?c:3},"speaker-history"===this.attributionParams.resolveUnknownChannelsMethod&&(this.speakerHistory=new Map),this.vadFrameSamples=Math.max(1,Math.round(.02*e.sampleRate)),this.minChunkSamples=Math.max(1,Math.round(.05*e.sampleRate)),this.maxChunkSamples=Math.max(this.minChunkSamples,Math.round(.2*e.sampleRate)),this.channelBuffers=new Map(h.map((e=>[e,[]]))),this.channelSamplesReceived=new Map(h.map((e=>[e,0]))),this.channelVadFloatBuffers=new Map(h.map((e=>[e,new Float32Array(this.vadFrameSamples)]))),this.channelVadBufferIdx=new Map(h.map((e=>[e,0]))),this.channelVads=new Map(h.map((e=>[e,this.attributionParams.createVad(e)]))),this.timeline=new E(this.attributionParams.timelineWindowMs)}}connectionUrl(){var e,t;const s=new URL(null!==(e=this.params.websocketBaseUrl)&&void 0!==e?e:"");if("wss:"!==s.protocol)throw new Error("Invalid protocol, must be wss");const n=new URLSearchParams;this.token&&n.set("token",this.token),n.set("sample_rate",this.params.sampleRate.toString()),this.params.endOfTurnConfidenceThreshold&&n.set("end_of_turn_confidence_threshold",this.params.endOfTurnConfidenceThreshold.toString()),void 0!==this.params.minEndOfTurnSilenceWhenConfident&&(void 0!==this.params.minTurnSilence?console.warn("[Deprecation Warning] Both `minEndOfTurnSilenceWhenConfident` and `minTurnSilence` are set. Using `minTurnSilence`; `minEndOfTurnSilenceWhenConfident` is deprecated."):console.warn("[Deprecation Warning] `minEndOfTurnSilenceWhenConfident` is deprecated and will be removed in a future release. Please use `minTurnSilence` instead."));const i=null!==(t=this.params.minTurnSilence)&&void 0!==t?t:this.params.minEndOfTurnSilenceWhenConfident;return void 0!==i&&n.set("min_turn_silence",i.toString()),this.params.maxTurnSilence&&n.set("max_turn_silence",this.params.maxTurnSilence.toString()),void 0!==this.params.vadThreshold&&n.set("vad_threshold",this.params.vadThreshold.toString()),this.params.formatTurns&&n.set("format_turns",this.params.formatTurns.toString()),this.params.encoding&&n.set("encoding",this.params.encoding.toString()),this.params.keytermsPrompt?n.set("keyterms_prompt",JSON.stringify(this.params.keytermsPrompt)):this.params.keyterms&&(console.warn("[Deprecation Warning] `keyterms` is deprecated and will be removed in a future release. Please use `keytermsPrompt` instead."),n.set("keyterms_prompt",JSON.stringify(this.params.keyterms))),this.params.prompt&&n.set("prompt",this.params.prompt),this.params.agentContext&&n.set("agent_context",this.params.agentContext),this.params.filterProfanity&&n.set("filter_profanity",this.params.filterProfanity.toString()),"u3-pro"===this.params.speechModel&&console.warn("[Deprecation Warning] The speech model `u3-pro` is deprecated and will be removed in a future release. Please use `u3-rt-pro` instead."),void 0!==this.params.speechModel&&n.set("speech_model",this.params.speechModel.toString()),void 0!==this.params.languageCode&&n.set("language_code",this.params.languageCode),void 0!==this.params.languageDetection&&n.set("language_detection",this.params.languageDetection.toString()),this.params.domain&&n.set("domain",this.params.domain),void 0!==this.params.inactivityTimeout&&n.set("inactivity_timeout",this.params.inactivityTimeout.toString()),void 0!==this.params.speakerLabels&&n.set("speaker_labels",this.params.speakerLabels.toString()),void 0!==this.params.maxSpeakers&&n.set("max_speakers",this.params.maxSpeakers.toString()),this.params.voiceFocus&&n.set("voice_focus",this.params.voiceFocus),void 0!==this.params.voiceFocusThreshold&&n.set("voice_focus_threshold",this.params.voiceFocusThreshold.toString()),void 0!==this.params.continuousPartials&&n.set("continuous_partials",this.params.continuousPartials.toString()),void 0!==this.params.interruptionDelay&&n.set("interruption_delay",this.params.interruptionDelay.toString()),void 0!==this.params.turnLeftPadMs&&n.set("turn_left_pad_ms",this.params.turnLeftPadMs.toString()),this.params.customerSupportAudioCapture&&(console.warn("`customerSupportAudioCapture=true` will record session audio. Only enable this when explicitly coordinating with AssemblyAI support."),n.set("_customer_support_audio_capture",this.params.customerSupportAudioCapture.toString())),this.params.webhookUrl&&n.set("webhook_url",this.params.webhookUrl),this.params.webhookAuthHeaderName&&n.set("webhook_auth_header_name",this.params.webhookAuthHeaderName),this.params.webhookAuthHeaderValue&&n.set("webhook_auth_header_value",this.params.webhookAuthHeaderValue),void 0!==this.params.includePartialTurns&&n.set("include_partial_turns",this.params.includePartialTurns.toString()),void 0!==this.params.redactPii&&n.set("redact_pii",this.params.redactPii.toString()),void 0!==this.params.redactPiiPolicies&&n.set("redact_pii_policies",JSON.stringify(this.params.redactPiiPolicies)),void 0!==this.params.redactPiiSub&&n.set("redact_pii_sub",this.params.redactPiiSub),void 0!==this.params.mode&&n.set("mode",this.params.mode),void 0!==this.params.llmGateway&&n.set("llm_gateway",JSON.stringify(this.params.llmGateway)),s.search=n.toString(),s}on(e,t){this.listeners[e]=t}connect(){return n(this,void 0,void 0,(function*(){var e,t;if(this.socket)throw new Error("Already connected");const s=null!==(e=this.params.maxConnectionRetries)&&void 0!==e?e:2,n=null!==(t=this.params.connectionRetryDelay)&&void 0!==t?t:500;let i;for(let e=0;e<=s;e++)try{return yield this.connectOnce()}catch(t){i=t;if(!(!0===t.retryable)||e===s)throw t;console.warn(`Streaming connect attempt ${e+1}/${s+1} failed (${t.message}); retrying`),n>0&&(yield new Promise((e=>setTimeout(e,n))))}throw null!=i?i:new Error("Failed to connect to streaming server")}))}connectOnce(){return new Promise(((e,t)=>{var s;const n=this.connectionUrl(),i=null!==(s=this.params.connectTimeout)&&void 0!==s?s:1e3;let r,o=!1;const a=e=>{o||(o=!0,r&&clearTimeout(r),this.discardPendingSocket(),t(e))};i>0&&(r=setTimeout((()=>{const e=new k(`Streaming connection timed out after ${i}ms`);e.retryable=!0,a(e)}),i)),this.token?this.socket=m(n.toString()):(console.warn("API key authentication is not supported for the StreamingTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=m(n.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{},this.socket.onclose=({code:e,reason:t})=>{var s,n;if(t||e in S&&(t=S[e]),!o){const s=new k(t||`Streaming connection closed (code=${e})`);return s.code=e,s.retryable=F(e),void a(s)}this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n;const i=null!==(t=e.error)&&void 0!==t?t:new Error(e.message);if(!o)return i.retryable=!0,void a(i);null===(n=(s=this.listeners).error)||void 0===n||n.call(s,i)},this.socket.onmessage=({data:t})=>{var s,n,i,l,c,h,d,u,m,p,f,v,g,y,w;const b=JSON.parse(t.toString());if("error"in b){const e=new k(b.error);if("error_code"in b&&(e.code=b.error_code),!o){const t=e;return t.retryable=void 0===e.code||F(e.code),void a(t)}null===(n=(s=this.listeners).error)||void 0===n||n.call(s,e)}else{switch(b.type){case"Begin":S=b,o||(o=!0,r&&clearTimeout(r),e(S)),null===(l=(i=this.listeners).open)||void 0===l||l.call(i,b);break;case"Turn":if(this.isDualChannel&&this.timeline&&this.attributionParams)switch(C(b,this.timeline,{dominanceRatio:this.attributionParams.dominanceRatio}),this.attributionParams.resolveUnknownChannelsMethod){case"window":this.resolveUnknownChannelsByWindow(b);break;case"speaker-history":this.resolveUnknownChannelsBySpeakerHistory(b)}null===(h=(c=this.listeners).turn)||void 0===h||h.call(c,b);break;case"SpeechStarted":null===(u=(d=this.listeners).speechStarted)||void 0===u||u.call(d,b);break;case"LLMGatewayResponse":null===(p=(m=this.listeners).llmGatewayResponse)||void 0===p||p.call(m,b);break;case"SpeakerRevision":null===(v=(f=this.listeners).speakerRevision)||void 0===v||v.call(f,b);break;case"Warning":{const e=b;console.warn(`Streaming warning (code=${e.warning_code}): ${e.warning}`),null===(y=(g=this.listeners).warning)||void 0===y||y.call(g,e);break}case"Termination":null===(w=this.sessionTerminatedResolve)||void 0===w||w.call(this)}var S}}}))}discardPendingSocket(){if(this.socket){try{this.socket.removeAllListeners&&this.socket.removeAllListeners(),this.socket.close()}catch(e){}this.socket=void 0}}stream(){return new c({write:e=>{this.sendAudio(e)}})}sendAudio(e,t){if(this.isDualChannel){if(!(null==t?void 0:t.channel))throw new Error("StreamingTranscriber is in dual-channel mode; sendAudio requires { channel }.");if(!this.channelNames.includes(t.channel))throw new Error(`Unknown channel "${t.channel}"; declared channels: ${this.channelNames.join(", ")}.`);this.ingestChannelAudio(t.channel,e)}else this.send(e)}ingestChannelAudio(e,t){var s,n;const i=function(e){if(e instanceof Int16Array)return e;if(ArrayBuffer.isView(e)){const t=e;return new Int16Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/2))}return new Int16Array(e)}(t),r=this.channelBuffers.get(e),o=this.channelVadFloatBuffers.get(e);let a=this.channelVadBufferIdx.get(e),l=this.channelSamplesReceived.get(e);const c=this.channelVads.get(e),h=this.params.sampleRate,d=this.vadFrameSamples;for(let t=0;t<i.length;t++){const u=i[t];if(r.push(u),o[a++]=u/32768,l++,a===d){const t=c.process(o),i={ts:l/h*1e3,channel:e,active:t.active,rms:t.energy};this.timeline.pushFrame(i),null===(n=(s=this.listeners).vad)||void 0===n||n.call(s,i),a=0}}this.channelVadBufferIdx.set(e,a),this.channelSamplesReceived.set(e,l),this.flushTimer||this.startFlushTimer()}startFlushTimer(){this.flushTimer=setInterval((()=>this.flushMix()),this.attributionParams.flushIntervalMs)}flushMix(e=!1){var t,s;if(!this.channelNames||!this.channelBuffers)return;const n=this.channelNames.map((e=>this.channelBuffers.get(e))),i=n.length;for(;;){let r=1/0;for(const e of n)e.length<r&&(r=e.length);if(!Number.isFinite(r)||0===r)return;if(!e&&r<this.minChunkSamples)return;r>this.maxChunkSamples&&(r=this.maxChunkSamples);const o=new Int16Array(r);for(let e=0;e<r;e++){let t=0;for(let s=0;s<i;s++)t+=n[s][e];const s=Math.round(t/i);o[e]=s<-32768?-32768:s>32767?32767:s}for(const e of n)e.splice(0,r);try{this.send(o.buffer)}catch(e){return void(null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e))}}}resolveUnknownChannelsByWindow(e){var t;if(!this.attributionParams)return;const s=this.attributionParams.resolutionWindowWords,n=e.words;let i=!1;for(let e=0;e<n.length;e++){if("unknown"!==n[e].channel)continue;const r=new Map,o=Math.max(0,e-s),a=Math.min(n.length-1,e+s);for(let s=o;s<=a;s++){if(s===e)continue;const i=n[s].channel;i&&"unknown"!==i&&r.set(i,(null!==(t=r.get(i))&&void 0!==t?t:0)+1)}if(0===r.size)continue;let l,c=0,h=!1;for(const[e,t]of r)t>c?(l=e,c=t,h=!1):t===c&&(h=!0);l&&!h&&(n[e].channel=l,n[e].channelResolved=!0,i=!0)}i&&(e.channel=M(n))}resolveUnknownChannelsBySpeakerHistory(e){var t;if(!this.timeline||!this.attributionParams||!this.speakerHistory)return;const s=this.attributionParams.speakerHistoryMinRmsEvidence,n=this.attributionParams.speakerHistoryDominanceRatio;for(const s of e.words){if(!s.speaker)continue;const e=this.timeline.framesInWindow(s.start,s.end);let n=this.speakerHistory.get(s.speaker);n||(n=new Map,this.speakerHistory.set(s.speaker,n));for(const s of e)s.active&&n.set(s.channel,(null!==(t=n.get(s.channel))&&void 0!==t?t:0)+s.rms)}let i=!1;for(const t of e.words){if("unknown"!==t.channel||!t.speaker)continue;const e=this.speakerHistory.get(t.speaker);if(!e||0===e.size)continue;let r,o=0,a=0,l=0;for(const[t,s]of e)o+=s,s>a?(l=a,a=s,r=t):s>l&&(l=s);o<s||(l>0&&a<n*l||r&&(t.channel=r,t.channelResolved=!0,i=!0))}i&&(e.channel=M(e.words))}updateConfiguration(e){const{min_end_of_turn_silence_when_confident:t,min_turn_silence:n}=e,i=s(e,["min_end_of_turn_silence_when_confident","min_turn_silence"]);void 0!==t&&(void 0!==n?console.warn("[Deprecation Warning] Both `min_end_of_turn_silence_when_confident` and `min_turn_silence` are set. Using `min_turn_silence`; `min_end_of_turn_silence_when_confident` is deprecated."):console.warn("[Deprecation Warning] `min_end_of_turn_silence_when_confident` is deprecated and will be removed in a future release. Please use `min_turn_silence` instead."));const r=null!=n?n:t,o=Object.assign(Object.assign({type:"UpdateConfiguration"},i),void 0!==r?{min_turn_silence:r}:{});this.send(JSON.stringify(o))}forceEndpoint(){this.send(JSON.stringify({type:"ForceEndpoint"}))}keepAlive(){this.send(JSON.stringify({type:"KeepAlive"}))}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return n(this,arguments,void 0,(function*(e=!0){var t;if(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0,this.flushMix(!0)),this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(I),yield e}else this.socket.send(I);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class B extends a{constructor(e){super(e),this.baseServiceParams=e}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.baseServiceParams.apiKey),new N(t)}createTemporaryToken(e){return n(this,void 0,void 0,(function*(){const t=new URLSearchParams;Object.entries(e).forEach((([e,s])=>{null!=s&&t.append(e,String(s))}));const s=t.toString(),n=s?`/v3/token?${s}`:"/v3/token";return(yield this.fetchJson(n,{method:"GET"})).token}))}}e.AssemblyAI=class{constructor(e){e.baseUrl=e.baseUrl||"https://api.assemblyai.com",e.baseUrl&&e.baseUrl.endsWith("/")&&(e.baseUrl=e.baseUrl.slice(0,-1)),this.files=new O(e),this.transcripts=new x(e,this.files),this.lemur=new l(e),this.realtime=new A(e),this.streaming=new B(Object.assign(Object.assign({},e),{baseUrl:e.streamingBaseUrl||"https://streaming.assemblyai.com"}))}},e.BrowserOnlyError=t,e.DualChannelCapture=class{constructor(e){var s;if(this.running=!1,void 0===globalThis.AudioContext)throw new t;this.params={micStream:e.micStream,systemStream:e.systemStream,transcriber:e.transcriber,targetSampleRate:null!==(s=e.targetSampleRate)&&void 0!==s?s:16e3}}on(e,t){"error"===e&&(this.errorListener=t)}start(){return n(this,void 0,void 0,(function*(){if(this.running)throw new Error("DualChannelCapture already started");this.context=new AudioContext;const e=new Blob(['\nclass Pcm16EncoderProcessor extends AudioWorkletProcessor {\n constructor(options) {\n super();\n const opts = (options && options.processorOptions) || {};\n this.targetRate = opts.targetRate || 16000;\n this.chunkMs = opts.chunkMs || 50;\n this.ratio = sampleRate / this.targetRate;\n this.chunkSize = Math.round(this.targetRate * this.chunkMs / 1000);\n this.buffer = new Int16Array(this.chunkSize);\n this.bufferIdx = 0;\n this.samplesSent = 0;\n this.lastSample = 0;\n this.fractional = 0;\n }\n\n process(inputs) {\n const input = inputs[0];\n if (!input || input.length === 0 || !input[0] || input[0].length === 0) {\n return true;\n }\n const mono = input[0];\n let pos = this.fractional;\n while (pos < mono.length) {\n const i = Math.floor(pos);\n const frac = pos - i;\n const a = i === 0 ? this.lastSample : mono[i - 1];\n const b = mono[i];\n const sample = a + (b - a) * frac;\n const clamped = sample < -1 ? -1 : sample > 1 ? 1 : sample;\n this.buffer[this.bufferIdx++] = clamped < 0 ? clamped * 0x8000 : clamped * 0x7fff;\n if (this.bufferIdx === this.chunkSize) {\n const out = new Int16Array(this.chunkSize);\n out.set(this.buffer);\n this.samplesSent += this.chunkSize;\n this.port.postMessage(\n { pcm: out.buffer, samplesSent: this.samplesSent },\n [out.buffer],\n );\n this.bufferIdx = 0;\n }\n pos += this.ratio;\n }\n this.lastSample = mono[mono.length - 1];\n this.fractional = pos - mono.length;\n return true;\n }\n}\nregisterProcessor("aai-pcm16-encoder", Pcm16EncoderProcessor);\n'],{type:"application/javascript"}),t=URL.createObjectURL(e);try{yield this.context.audioWorklet.addModule(t)}finally{URL.revokeObjectURL(t)}this.micSource=this.context.createMediaStreamSource(this.params.micStream),this.sysSource=this.context.createMediaStreamSource(this.params.systemStream),this.micEncoder=this.makeEncoder("mic"),this.sysEncoder=this.makeEncoder("system"),this.micSource.connect(this.micEncoder),this.sysSource.connect(this.sysEncoder),this.running=!0}))}makeEncoder(e){const t=new AudioWorkletNode(this.context,"aai-pcm16-encoder",{numberOfInputs:1,numberOfOutputs:0,channelCount:1,channelCountMode:"explicit",channelInterpretation:"speakers",processorOptions:{targetRate:this.params.targetSampleRate,chunkMs:50}});return t.port.onmessage=t=>{var s;try{this.params.transcriber.sendAudio(t.data.pcm,{channel:e})}catch(e){null===(s=this.errorListener)||void 0===s||s.call(this,e)}},t}stop(){return n(this,void 0,void 0,(function*(){var e,t,s,n,i,r;if(this.running){this.running=!1;try{null===(e=this.micEncoder)||void 0===e||e.port.close(),null===(t=this.sysEncoder)||void 0===t||t.port.close(),null===(s=this.micEncoder)||void 0===s||s.disconnect(),null===(n=this.sysEncoder)||void 0===n||n.disconnect(),null===(i=this.micSource)||void 0===i||i.disconnect(),null===(r=this.sysSource)||void 0===r||r.disconnect()}catch(e){}this.context&&"closed"!==this.context.state&&(yield this.context.close()),this.context=void 0,this.micSource=void 0,this.sysSource=void 0,this.micEncoder=void 0,this.sysEncoder=void 0}}))}},e.EnergyVad=R,e.FileService=O,e.LemurService=l,e.LinearResampler=class{constructor(e,t){if(this.sourceRate=e,this.targetRate=t,this.lastSample=0,this.fractional=0,e<=0||t<=0)throw new Error("sourceRate and targetRate must be positive");this.ratio=e/t}process(e){var t;if(this.sourceRate===this.targetRate)return e;const s=new Float32Array(Math.ceil(e.length/this.ratio)+1);let n=0,i=this.fractional;for(;i<e.length;){const t=Math.floor(i),r=i-t,o=0===t?this.lastSample:e[t-1],a=e[t];s[n++]=o+(a-o)*r,i+=this.ratio}return this.lastSample=null!==(t=e[e.length-1])&&void 0!==t?t:this.lastSample,this.fractional=i-e.length,s.subarray(0,n)}reset(){this.lastSample=0,this.fractional=0}},e.RealtimeService=class extends T{},e.RealtimeServiceFactory=class extends A{},e.RealtimeTranscriber=T,e.RealtimeTranscriberFactory=A,e.StreamingTranscriber=N,e.TranscriptService=x,e.VadTimeline=E,e.attributeTurn=C,e.attributeWord=U,e.float32ToPcm16=function(e){const t=new ArrayBuffer(2*e.length),s=new DataView(t);for(let t=0;t<e.length;t++){const n=Math.max(-1,Math.min(1,e[t]));s.setInt16(2*t,n<0?32768*n:32767*n,!0)}return t},e.rollUpTurnChannel=M}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).assemblyai={})}(this,(function(e){"use strict";class t extends Error{constructor(e="DualChannelCapture requires a browser environment (AudioContext is undefined)."){super(e),this.name="BrowserOnlyError"}}function s(e,t){var s={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(s[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(n=Object.getOwnPropertySymbols(e);i<n.length;i++)t.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(s[n[i]]=e[n[i]])}return s}function n(e,t,s,n){return new(s||(s=Promise))((function(i,r){function o(e){try{l(n.next(e))}catch(e){r(e)}}function a(e){try{l(n.throw(e))}catch(e){r(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}l((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const i={cache:"no-store"};let r="";"undefined"!=typeof navigator&&navigator.userAgent&&(r+=navigator.userAgent);const o={sdk:{name:"JavaScript",version:"4.35.3"}};"undefined"!=typeof process&&(process.versions.node&&-1===r.indexOf("Node")&&(o.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===r.indexOf("Bun")&&(o.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===r.indexOf("Deno")&&(o.runtime_env={name:"Deno",version:Deno.version.deno});class a{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},r+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},o),t)).map((([e,t])=>t?`${e}=${t.name}/${t.version}`:"")).join(" ")+")"))}fetch(e,t){return n(this,void 0,void 0,(function*(){t=Object.assign(Object.assign({},i),t);let s={Authorization:this.params.apiKey,"Content-Type":"application/json"};(null==i?void 0:i.headers)&&(s=Object.assign(Object.assign({},s),i.headers)),(null==t?void 0:t.headers)&&(s=Object.assign(Object.assign({},s),t.headers)),this.userAgent&&(s["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(s["AssemblyAI-Agent"]=this.userAgent)),t.headers=s,e.startsWith("http")||(e=this.params.baseUrl+e);const n=yield fetch(e,t);if(n.status>=400){let e;const t=yield n.text();if(t){try{e=JSON.parse(t)}catch(e){}if(null==e?void 0:e.error)throw new Error(e.error);throw new Error(t)}throw new Error(`HTTP Error: ${n.status} ${n.statusText}`)}return n}))}fetchJson(e,t){return n(this,void 0,void 0,(function*(){return(yield this.fetch(e,t)).json()}))}}class l extends a{summary(e,t){return this.fetchJson("/lemur/v3/generate/summary",{method:"POST",body:JSON.stringify(e),signal:t})}questionAnswer(e,t){return this.fetchJson("/lemur/v3/generate/question-answer",{method:"POST",body:JSON.stringify(e),signal:t})}actionItems(e,t){return this.fetchJson("/lemur/v3/generate/action-items",{method:"POST",body:JSON.stringify(e),signal:t})}task(e,t){return this.fetchJson("/lemur/v3/generate/task",{method:"POST",body:JSON.stringify(e),signal:t})}getResponse(e,t){return this.fetchJson(`/lemur/v3/${e}`,{signal:t})}purgeRequestData(e,t){return this.fetchJson(`/lemur/v3/${e}`,{method:"DELETE",signal:t})}}const{WritableStream:c}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var h,d;const u=null!==(d=null!==(h=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==h?h:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==d?d:null===self||void 0===self?void 0:self.WebSocket,m=(e,t)=>t?new u(e,t):new u(e),p={[4e3]:"Sample rate must be a positive integer",[4001]:"Not Authorized",[4002]:"Insufficient funds",[4003]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[4100]:"Bad JSON",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid.",[1013]:"Reconnect attempts exhausted",[4104]:"Could not parse word boost parameter"};class f extends Error{}const v=4e3,g=4001,y=4002,w=4003,b=4101,S={[3005]:"Server error",[3006]:"Input validation error",[3007]:"Audio chunk duration violation",[3008]:"Session expired: maximum session duration exceeded",[3009]:"Too many concurrent sessions",[v]:"Sample rate must be a positive integer",[g]:"Not Authorized",[y]:"Insufficient funds",[w]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[b]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid."};class k extends Error{}const _='{"terminate_session":true}';class T{constructor(e){var t,s;if(this.listeners={},this.realtimeUrl=null!==(t=e.realtimeUrl)&&void 0!==t?t:"wss://api.assemblyai.com/v2/realtime/ws",this.sampleRate=null!==(s=e.sampleRate)&&void 0!==s?s:16e3,this.wordBoost=e.wordBoost,this.encoding=e.encoding,this.endUtteranceSilenceThreshold=e.endUtteranceSilenceThreshold,this.disablePartialTranscripts=e.disablePartialTranscripts,"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.")}connectionUrl(){const e=new URL(this.realtimeUrl);if("wss:"!==e.protocol)throw new Error("Invalid protocol, must be wss");const t=new URLSearchParams;return this.token&&t.set("token",this.token),t.set("sample_rate",this.sampleRate.toString()),this.wordBoost&&this.wordBoost.length>0&&t.set("word_boost",JSON.stringify(this.wordBoost)),this.encoding&&t.set("encoding",this.encoding),t.set("enable_extra_session_information","true"),this.disablePartialTranscripts&&t.set("disable_partial_transcripts",this.disablePartialTranscripts.toString()),e.search=t.toString(),e}on(e,t){this.listeners[e]=t}connect(){return new Promise((e=>{if(this.socket)throw new Error("Already connected");const t=this.connectionUrl();this.token?this.socket=m(t.toString()):(console.warn("API key authentication is not supported for the RealtimeTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=m(t.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{void 0!==this.endUtteranceSilenceThreshold&&null!==this.endUtteranceSilenceThreshold&&this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold)},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in p&&(t=p[e]),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n,i;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(i=(n=this.listeners).error)||void 0===i||i.call(n,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,n,i,r,o,a,l,c,h,d,u,m,p,v,g;const y=JSON.parse(t.toString());if("error"in y)null===(n=(s=this.listeners).error)||void 0===n||n.call(s,new f(y.error));else switch(y.message_type){case"SessionBegins":{const t={sessionId:y.session_id,expiresAt:new Date(y.expires_at)};e(t),null===(r=(i=this.listeners).open)||void 0===r||r.call(i,t);break}case"PartialTranscript":y.created=new Date(y.created),null===(a=(o=this.listeners).transcript)||void 0===a||a.call(o,y),null===(c=(l=this.listeners)["transcript.partial"])||void 0===c||c.call(l,y);break;case"FinalTranscript":y.created=new Date(y.created),null===(d=(h=this.listeners).transcript)||void 0===d||d.call(h,y),null===(m=(u=this.listeners)["transcript.final"])||void 0===m||m.call(u,y);break;case"SessionInformation":null===(v=(p=this.listeners).session_information)||void 0===v||v.call(p,y);break;case"SessionTerminated":null===(g=this.sessionTerminatedResolve)||void 0===g||g.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new c({write:e=>{this.sendAudio(e)}})}forceEndUtterance(){this.send('{"force_end_utterance":true}')}configureEndUtteranceSilenceThreshold(e){this.send(`{"end_utterance_silence_threshold":${e}}`)}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return n(this,arguments,void 0,(function*(e=!0){var t;if(this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(_),yield e}else this.socket.send(_);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class A extends a{constructor(e){super(e),this.rtFactoryParams=e}createService(e){return this.transcriber(e)}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.rtFactoryParams.apiKey),new T(t)}createTemporaryToken(e){return n(this,void 0,void 0,(function*(){return(yield this.fetchJson("/v2/realtime/token",{method:"POST",body:JSON.stringify(e)})).token}))}}function P(e){return e.startsWith("http")||e.startsWith("https")||e.startsWith("data:")?null:e.startsWith("file://")?e.substring(7):e.startsWith("file:")?e.substring(5):e}class O extends a{constructor(e,t){super(e),this.files=t}transcribe(e,t){return n(this,void 0,void 0,(function*(){const s=yield this.submit(e);return yield this.waitUntilReady(s.id,t)}))}submit(e){return n(this,void 0,void 0,(function*(){let t,n;if("audio"in e){const{audio:i}=e,r=s(e,["audio"]);if("string"==typeof i){const e=P(i);t=null!==e?yield this.files.upload(e):i.startsWith("data:")?yield this.files.upload(i):i}else t=yield this.files.upload(i);n=Object.assign(Object.assign({},r),{audio_url:t})}else n=e;return yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(n)})}))}create(e,t){return n(this,void 0,void 0,(function*(){var s;const n=P(e.audio_url);if(null!==n){const t=yield this.files.upload(n);e.audio_url=t}const i=yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(e)});return null===(s=null==t?void 0:t.poll)||void 0===s||s?yield this.waitUntilReady(i.id,t):i}))}waitUntilReady(e,t){return n(this,void 0,void 0,(function*(){var s,n;const i=null!==(s=null==t?void 0:t.pollingInterval)&&void 0!==s?s:3e3,r=null!==(n=null==t?void 0:t.pollingTimeout)&&void 0!==n?n:-1,o=Date.now();for(;;){const t=yield this.get(e);if("completed"===t.status||"error"===t.status)return t;if(r>0&&Date.now()-o>r)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,i)))}}))}get(e){return this.fetchJson(`/v2/transcript/${e}`)}list(e){return n(this,void 0,void 0,(function*(){let t="/v2/transcript";"string"==typeof e?t=e:e&&(t=`${t}?${new URLSearchParams(Object.keys(e).map((t=>{var s;return[t,(null===(s=e[t])||void 0===s?void 0:s.toString())||""]})))}`);const s=yield this.fetchJson(t);for(const e of s.transcripts)e.created=new Date(e.created),e.completed&&(e.completed=new Date(e.completed));return s}))}delete(e){return this.fetchJson(`/v2/transcript/${e}`,{method:"DELETE"})}wordSearch(e,t){const s=new URLSearchParams({words:t.join(",")});return this.fetchJson(`/v2/transcript/${e}/word-search?${s.toString()}`)}sentences(e){return this.fetchJson(`/v2/transcript/${e}/sentences`)}paragraphs(e){return this.fetchJson(`/v2/transcript/${e}/paragraphs`)}subtitles(e){return n(this,arguments,void 0,(function*(e,t="srt",s){let n=`/v2/transcript/${e}/${t}`;if(s){const e=new URLSearchParams;e.set("chars_per_caption",s.toString()),n+=`?${e.toString()}`}const i=yield this.fetch(n);return yield i.text()}))}redactions(e){return this.redactedAudio(e)}redactedAudio(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}redactedAudioFile(e){return n(this,void 0,void 0,(function*(){const{redacted_audio_url:t,status:s}=yield this.redactedAudio(e);if("redacted_audio_ready"!==s)throw new Error(`Redacted audio status is ${s}`);const n=yield fetch(t);if(!n.ok)throw new Error(`Failed to fetch redacted audio: ${n.statusText}`);return{arrayBuffer:n.arrayBuffer.bind(n),blob:n.blob.bind(n),body:n.body,bodyUsed:n.bodyUsed}}))}}class x extends a{upload(e){return n(this,void 0,void 0,(function*(){let t;t="string"==typeof e?e.startsWith("data:")?function(e){const t=e.split(","),s=t[0].match(/:(.*?);/)[1],n=atob(t[1]);let i=n.length;const r=new Uint8Array(i);for(;i--;)r[i]=n.charCodeAt(i);return new Blob([r],{type:s})}(e):yield function(e){return n(this,void 0,void 0,(function*(){throw new Error("Interacting with the file system is not supported in this environment.")}))}():e;return(yield this.fetchJson("/v2/upload",{method:"POST",body:t,headers:{"Content-Type":"application/octet-stream"},duplex:"half"})).upload_url}))}}class R{constructor(e={}){var t,s,n,i;this.hangoverRemaining=0,this.thresholdRatio=null!==(t=e.thresholdRatio)&&void 0!==t?t:3,this.noiseFloorAlpha=null!==(s=e.noiseFloorAlpha)&&void 0!==s?s:.05,this.hangoverFrames=null!==(n=e.hangoverFrames)&&void 0!==n?n:10,this.initialNoiseFloor=null!==(i=e.initialNoiseFloor)&&void 0!==i?i:1e-4,this.noiseFloor=this.initialNoiseFloor}process(e){let t=0;for(let s=0;s<e.length;s++)t+=e[s]*e[s];const s=e.length>0?Math.sqrt(t/e.length):0;let n=s>this.noiseFloor*this.thresholdRatio;return n?this.hangoverRemaining=this.hangoverFrames:this.hangoverRemaining>0?(this.hangoverRemaining--,n=!0):this.noiseFloor=this.noiseFloor*(1-this.noiseFloorAlpha)+s*this.noiseFloorAlpha,{active:n,energy:s}}reset(){this.noiseFloor=this.initialNoiseFloor,this.hangoverRemaining=0}}class E{constructor(e){this.windowMs=e,this.frames=[],this.head=0}pushFrame(e){this.frames.push(e);const t=e.ts-this.windowMs;for(;this.head<this.frames.length&&this.frames[this.head].ts<t;)this.head++;this.head>1024&&2*this.head>this.frames.length&&(this.frames=this.frames.slice(this.head),this.head=0)}framesInWindow(e,t){const s=[];for(let n=this.head;n<this.frames.length;n++){const i=this.frames[n];if(!(i.ts<e)){if(i.ts>t)break;s.push(i)}}return s}clear(){this.frames=[],this.head=0}}function U(e,t,s){const n=function(e){var t;const s=new Map;for(const n of e)n.active&&s.set(n.channel,(null!==(t=s.get(n.channel))&&void 0!==t?t:0)+n.rms);return s}(t.framesInWindow(e.start,e.end));if(0===n.size)return"unknown";const i=[...n.entries()].sort(((e,t)=>t[1]-e[1]));if(1===i.length)return i[0][0];const[r,o]=i[0],[a,l]=i[1];return o>=s.dominanceRatio*l||o>l?r:l>o?a:"unknown"}function M(e){var t;const s=new Map;for(const n of e){if(!n.channel||"unknown"===n.channel)continue;const e=Math.max(0,n.end-n.start);s.set(n.channel,(null!==(t=s.get(n.channel))&&void 0!==t?t:0)+e)}if(0===s.size)return"unknown";const n=[...s.entries()].sort(((e,t)=>t[1]-e[1]));if(1===n.length)return n[0][0];const[i,r]=n[0],[,o]=n[1];return r===o?"unknown":i}function C(e,t,s){for(const n of e.words)n.channel=U(n,t,s);e.channel=M(e.words)}const W='{"type":"Terminate"}',I=new Set([v,g,y,w,b]);function F(e){return 1e3!==e&&!I.has(e)}class N{constructor(e){var t,s,n,i,r,o,a,l,c;if(this.listeners={},this.isDualChannel=!1,this.vadFrameSamples=0,this.minChunkSamples=0,this.maxChunkSamples=0,this.params=Object.assign(Object.assign({},e),{websocketBaseUrl:e.websocketBaseUrl||"wss://streaming.assemblyai.com/v3/ws"}),"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.");if(e.channels){if(2!==e.channels.length)throw new Error("StreamingTranscriber.channels must have exactly 2 entries.");const h=e.channels.map((e=>e.name));if(new Set(h).size!==h.length)throw new Error("StreamingTranscriber.channels names must be unique.");this.isDualChannel=!0,this.channelNames=h;const d=null!==(t=e.channelAttribution)&&void 0!==t?t:{};this.attributionParams={dominanceRatio:null!==(s=d.dominanceRatio)&&void 0!==s?s:4,timelineWindowMs:null!==(n=d.timelineWindowMs)&&void 0!==n?n:3e4,createVad:null!==(i=d.createVad)&&void 0!==i?i:()=>new R,flushIntervalMs:null!==(r=d.flushIntervalMs)&&void 0!==r?r:50,resolveUnknownChannelsMethod:null!==(o=d.resolveUnknownChannelsMethod)&&void 0!==o?o:"window",resolutionWindowWords:null!==(a=d.resolutionWindowWords)&&void 0!==a?a:2,speakerHistoryMinRmsEvidence:null!==(l=d.speakerHistoryMinRmsEvidence)&&void 0!==l?l:.5,speakerHistoryDominanceRatio:null!==(c=d.speakerHistoryDominanceRatio)&&void 0!==c?c:3},"speaker-history"===this.attributionParams.resolveUnknownChannelsMethod&&(this.speakerHistory=new Map),this.vadFrameSamples=Math.max(1,Math.round(.02*e.sampleRate)),this.minChunkSamples=Math.max(1,Math.round(.05*e.sampleRate)),this.maxChunkSamples=Math.max(this.minChunkSamples,Math.round(.2*e.sampleRate)),this.channelBuffers=new Map(h.map((e=>[e,[]]))),this.channelSamplesReceived=new Map(h.map((e=>[e,0]))),this.channelVadFloatBuffers=new Map(h.map((e=>[e,new Float32Array(this.vadFrameSamples)]))),this.channelVadBufferIdx=new Map(h.map((e=>[e,0]))),this.channelVads=new Map(h.map((e=>[e,this.attributionParams.createVad(e)]))),this.timeline=new E(this.attributionParams.timelineWindowMs)}}connectionUrl(){var e,t;const s=new URL(null!==(e=this.params.websocketBaseUrl)&&void 0!==e?e:"");if("wss:"!==s.protocol)throw new Error("Invalid protocol, must be wss");const n=new URLSearchParams;this.token&&n.set("token",this.token),n.set("sample_rate",this.params.sampleRate.toString()),this.params.endOfTurnConfidenceThreshold&&n.set("end_of_turn_confidence_threshold",this.params.endOfTurnConfidenceThreshold.toString()),void 0!==this.params.minEndOfTurnSilenceWhenConfident&&(void 0!==this.params.minTurnSilence?console.warn("[Deprecation Warning] Both `minEndOfTurnSilenceWhenConfident` and `minTurnSilence` are set. Using `minTurnSilence`; `minEndOfTurnSilenceWhenConfident` is deprecated."):console.warn("[Deprecation Warning] `minEndOfTurnSilenceWhenConfident` is deprecated and will be removed in a future release. Please use `minTurnSilence` instead."));const i=null!==(t=this.params.minTurnSilence)&&void 0!==t?t:this.params.minEndOfTurnSilenceWhenConfident;return void 0!==i&&n.set("min_turn_silence",i.toString()),this.params.maxTurnSilence&&n.set("max_turn_silence",this.params.maxTurnSilence.toString()),void 0!==this.params.vadThreshold&&n.set("vad_threshold",this.params.vadThreshold.toString()),this.params.formatTurns&&n.set("format_turns",this.params.formatTurns.toString()),this.params.encoding&&n.set("encoding",this.params.encoding.toString()),this.params.keytermsPrompt?n.set("keyterms_prompt",JSON.stringify(this.params.keytermsPrompt)):this.params.keyterms&&(console.warn("[Deprecation Warning] `keyterms` is deprecated and will be removed in a future release. Please use `keytermsPrompt` instead."),n.set("keyterms_prompt",JSON.stringify(this.params.keyterms))),this.params.prompt&&n.set("prompt",this.params.prompt),this.params.agentContext&&n.set("agent_context",this.params.agentContext),this.params.filterProfanity&&n.set("filter_profanity",this.params.filterProfanity.toString()),"u3-pro"===this.params.speechModel&&console.warn("[Deprecation Warning] The speech model `u3-pro` is deprecated and will be removed in a future release. Please use `u3-rt-pro` instead."),void 0!==this.params.speechModel&&n.set("speech_model",this.params.speechModel.toString()),void 0!==this.params.languageCode&&(console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead."),n.set("language_code",this.params.languageCode)),void 0!==this.params.languageCodes&&n.set("language_codes",JSON.stringify(this.params.languageCodes)),void 0!==this.params.languageDetection&&n.set("language_detection",this.params.languageDetection.toString()),this.params.domain&&n.set("domain",this.params.domain),void 0!==this.params.inactivityTimeout&&n.set("inactivity_timeout",this.params.inactivityTimeout.toString()),void 0!==this.params.speakerLabels&&n.set("speaker_labels",this.params.speakerLabels.toString()),void 0!==this.params.maxSpeakers&&n.set("max_speakers",this.params.maxSpeakers.toString()),this.params.voiceFocus&&n.set("voice_focus",this.params.voiceFocus),void 0!==this.params.voiceFocusThreshold&&n.set("voice_focus_threshold",this.params.voiceFocusThreshold.toString()),void 0!==this.params.continuousPartials&&n.set("continuous_partials",this.params.continuousPartials.toString()),void 0!==this.params.interruptionDelay&&n.set("interruption_delay",this.params.interruptionDelay.toString()),void 0!==this.params.turnLeftPadMs&&n.set("turn_left_pad_ms",this.params.turnLeftPadMs.toString()),this.params.customerSupportAudioCapture&&(console.warn("`customerSupportAudioCapture=true` will record session audio. Only enable this when explicitly coordinating with AssemblyAI support."),n.set("_customer_support_audio_capture",this.params.customerSupportAudioCapture.toString())),this.params.webhookUrl&&n.set("webhook_url",this.params.webhookUrl),this.params.webhookAuthHeaderName&&n.set("webhook_auth_header_name",this.params.webhookAuthHeaderName),this.params.webhookAuthHeaderValue&&n.set("webhook_auth_header_value",this.params.webhookAuthHeaderValue),void 0!==this.params.includePartialTurns&&n.set("include_partial_turns",this.params.includePartialTurns.toString()),void 0!==this.params.redactPii&&n.set("redact_pii",this.params.redactPii.toString()),void 0!==this.params.redactPiiPolicies&&n.set("redact_pii_policies",JSON.stringify(this.params.redactPiiPolicies)),void 0!==this.params.redactPiiSub&&n.set("redact_pii_sub",this.params.redactPiiSub),void 0!==this.params.mode&&n.set("mode",this.params.mode),void 0!==this.params.llmGateway&&n.set("llm_gateway",JSON.stringify(this.params.llmGateway)),s.search=n.toString(),s}on(e,t){this.listeners[e]=t}connect(){return n(this,void 0,void 0,(function*(){var e,t;if(this.socket)throw new Error("Already connected");const s=null!==(e=this.params.maxConnectionRetries)&&void 0!==e?e:2,n=null!==(t=this.params.connectionRetryDelay)&&void 0!==t?t:500;let i;for(let e=0;e<=s;e++)try{return yield this.connectOnce()}catch(t){i=t;if(!(!0===t.retryable)||e===s)throw t;console.warn(`Streaming connect attempt ${e+1}/${s+1} failed (${t.message}); retrying`),n>0&&(yield new Promise((e=>setTimeout(e,n))))}throw null!=i?i:new Error("Failed to connect to streaming server")}))}connectOnce(){return new Promise(((e,t)=>{var s;const n=this.connectionUrl(),i=null!==(s=this.params.connectTimeout)&&void 0!==s?s:1e3;let r,o=!1;const a=e=>{o||(o=!0,r&&clearTimeout(r),this.discardPendingSocket(),t(e))};i>0&&(r=setTimeout((()=>{const e=new k(`Streaming connection timed out after ${i}ms`);e.retryable=!0,a(e)}),i)),this.token?this.socket=m(n.toString()):(console.warn("API key authentication is not supported for the StreamingTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=m(n.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{},this.socket.onclose=({code:e,reason:t})=>{var s,n;if(t||e in S&&(t=S[e]),!o){const s=new k(t||`Streaming connection closed (code=${e})`);return s.code=e,s.retryable=F(e),void a(s)}this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n;const i=null!==(t=e.error)&&void 0!==t?t:new Error(e.message);if(!o)return i.retryable=!0,void a(i);null===(n=(s=this.listeners).error)||void 0===n||n.call(s,i)},this.socket.onmessage=({data:t})=>{var s,n,i,l,c,h,d,u,m,p,f,v,g,y,w;const b=JSON.parse(t.toString());if("error"in b){const e=new k(b.error);if("error_code"in b&&(e.code=b.error_code),!o){const t=e;return t.retryable=void 0===e.code||F(e.code),void a(t)}null===(n=(s=this.listeners).error)||void 0===n||n.call(s,e)}else{switch(b.type){case"Begin":S=b,o||(o=!0,r&&clearTimeout(r),e(S)),null===(l=(i=this.listeners).open)||void 0===l||l.call(i,b);break;case"Turn":if(this.isDualChannel&&this.timeline&&this.attributionParams)switch(C(b,this.timeline,{dominanceRatio:this.attributionParams.dominanceRatio}),this.attributionParams.resolveUnknownChannelsMethod){case"window":this.resolveUnknownChannelsByWindow(b);break;case"speaker-history":this.resolveUnknownChannelsBySpeakerHistory(b)}null===(h=(c=this.listeners).turn)||void 0===h||h.call(c,b);break;case"SpeechStarted":null===(u=(d=this.listeners).speechStarted)||void 0===u||u.call(d,b);break;case"LLMGatewayResponse":null===(p=(m=this.listeners).llmGatewayResponse)||void 0===p||p.call(m,b);break;case"SpeakerRevision":null===(v=(f=this.listeners).speakerRevision)||void 0===v||v.call(f,b);break;case"Warning":{const e=b;console.warn(`Streaming warning (code=${e.warning_code}): ${e.warning}`),null===(y=(g=this.listeners).warning)||void 0===y||y.call(g,e);break}case"Termination":null===(w=this.sessionTerminatedResolve)||void 0===w||w.call(this)}var S}}}))}discardPendingSocket(){if(this.socket){try{this.socket.removeAllListeners&&this.socket.removeAllListeners(),this.socket.close()}catch(e){}this.socket=void 0}}stream(){return new c({write:e=>{this.sendAudio(e)}})}sendAudio(e,t){if(this.isDualChannel){if(!(null==t?void 0:t.channel))throw new Error("StreamingTranscriber is in dual-channel mode; sendAudio requires { channel }.");if(!this.channelNames.includes(t.channel))throw new Error(`Unknown channel "${t.channel}"; declared channels: ${this.channelNames.join(", ")}.`);this.ingestChannelAudio(t.channel,e)}else this.send(e)}ingestChannelAudio(e,t){var s,n;const i=function(e){if(e instanceof Int16Array)return e;if(ArrayBuffer.isView(e)){const t=e;return new Int16Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/2))}return new Int16Array(e)}(t),r=this.channelBuffers.get(e),o=this.channelVadFloatBuffers.get(e);let a=this.channelVadBufferIdx.get(e),l=this.channelSamplesReceived.get(e);const c=this.channelVads.get(e),h=this.params.sampleRate,d=this.vadFrameSamples;for(let t=0;t<i.length;t++){const u=i[t];if(r.push(u),o[a++]=u/32768,l++,a===d){const t=c.process(o),i={ts:l/h*1e3,channel:e,active:t.active,rms:t.energy};this.timeline.pushFrame(i),null===(n=(s=this.listeners).vad)||void 0===n||n.call(s,i),a=0}}this.channelVadBufferIdx.set(e,a),this.channelSamplesReceived.set(e,l),this.flushTimer||this.startFlushTimer()}startFlushTimer(){this.flushTimer=setInterval((()=>this.flushMix()),this.attributionParams.flushIntervalMs)}flushMix(e=!1){var t,s;if(!this.channelNames||!this.channelBuffers)return;const n=this.channelNames.map((e=>this.channelBuffers.get(e))),i=n.length;for(;;){let r=1/0;for(const e of n)e.length<r&&(r=e.length);if(!Number.isFinite(r)||0===r)return;if(!e&&r<this.minChunkSamples)return;r>this.maxChunkSamples&&(r=this.maxChunkSamples);const o=new Int16Array(r);for(let e=0;e<r;e++){let t=0;for(let s=0;s<i;s++)t+=n[s][e];const s=Math.round(t/i);o[e]=s<-32768?-32768:s>32767?32767:s}for(const e of n)e.splice(0,r);try{this.send(o.buffer)}catch(e){return void(null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e))}}}resolveUnknownChannelsByWindow(e){var t;if(!this.attributionParams)return;const s=this.attributionParams.resolutionWindowWords,n=e.words;let i=!1;for(let e=0;e<n.length;e++){if("unknown"!==n[e].channel)continue;const r=new Map,o=Math.max(0,e-s),a=Math.min(n.length-1,e+s);for(let s=o;s<=a;s++){if(s===e)continue;const i=n[s].channel;i&&"unknown"!==i&&r.set(i,(null!==(t=r.get(i))&&void 0!==t?t:0)+1)}if(0===r.size)continue;let l,c=0,h=!1;for(const[e,t]of r)t>c?(l=e,c=t,h=!1):t===c&&(h=!0);l&&!h&&(n[e].channel=l,n[e].channelResolved=!0,i=!0)}i&&(e.channel=M(n))}resolveUnknownChannelsBySpeakerHistory(e){var t;if(!this.timeline||!this.attributionParams||!this.speakerHistory)return;const s=this.attributionParams.speakerHistoryMinRmsEvidence,n=this.attributionParams.speakerHistoryDominanceRatio;for(const s of e.words){if(!s.speaker)continue;const e=this.timeline.framesInWindow(s.start,s.end);let n=this.speakerHistory.get(s.speaker);n||(n=new Map,this.speakerHistory.set(s.speaker,n));for(const s of e)s.active&&n.set(s.channel,(null!==(t=n.get(s.channel))&&void 0!==t?t:0)+s.rms)}let i=!1;for(const t of e.words){if("unknown"!==t.channel||!t.speaker)continue;const e=this.speakerHistory.get(t.speaker);if(!e||0===e.size)continue;let r,o=0,a=0,l=0;for(const[t,s]of e)o+=s,s>a?(l=a,a=s,r=t):s>l&&(l=s);o<s||(l>0&&a<n*l||r&&(t.channel=r,t.channelResolved=!0,i=!0))}i&&(e.channel=M(e.words))}updateConfiguration(e){const{min_end_of_turn_silence_when_confident:t,min_turn_silence:n}=e,i=s(e,["min_end_of_turn_silence_when_confident","min_turn_silence"]);void 0!==t&&(void 0!==n?console.warn("[Deprecation Warning] Both `min_end_of_turn_silence_when_confident` and `min_turn_silence` are set. Using `min_turn_silence`; `min_end_of_turn_silence_when_confident` is deprecated."):console.warn("[Deprecation Warning] `min_end_of_turn_silence_when_confident` is deprecated and will be removed in a future release. Please use `min_turn_silence` instead."));const r=null!=n?n:t,o=Object.assign(Object.assign({type:"UpdateConfiguration"},i),void 0!==r?{min_turn_silence:r}:{});this.send(JSON.stringify(o))}forceEndpoint(){this.send(JSON.stringify({type:"ForceEndpoint"}))}keepAlive(){this.send(JSON.stringify({type:"KeepAlive"}))}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return n(this,arguments,void 0,(function*(e=!0){var t;if(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0,this.flushMix(!0)),this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(W),yield e}else this.socket.send(W);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class J extends a{constructor(e){super(e),this.baseServiceParams=e}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.baseServiceParams.apiKey),new N(t)}createTemporaryToken(e){return n(this,void 0,void 0,(function*(){const t=new URLSearchParams;Object.entries(e).forEach((([e,s])=>{null!=s&&t.append(e,String(s))}));const s=t.toString(),n=s?`/v3/token?${s}`:"/v3/token";return(yield this.fetchJson(n,{method:"GET"})).token}))}}e.AssemblyAI=class{constructor(e){e.baseUrl=e.baseUrl||"https://api.assemblyai.com",e.baseUrl&&e.baseUrl.endsWith("/")&&(e.baseUrl=e.baseUrl.slice(0,-1)),this.files=new x(e),this.transcripts=new O(e,this.files),this.lemur=new l(e),this.realtime=new A(e),this.streaming=new J(Object.assign(Object.assign({},e),{baseUrl:e.streamingBaseUrl||"https://streaming.assemblyai.com"}))}},e.BrowserOnlyError=t,e.DualChannelCapture=class{constructor(e){var s;if(this.running=!1,void 0===globalThis.AudioContext)throw new t;this.params={micStream:e.micStream,systemStream:e.systemStream,transcriber:e.transcriber,targetSampleRate:null!==(s=e.targetSampleRate)&&void 0!==s?s:16e3}}on(e,t){"error"===e&&(this.errorListener=t)}start(){return n(this,void 0,void 0,(function*(){if(this.running)throw new Error("DualChannelCapture already started");this.context=new AudioContext;const e=new Blob(['\nclass Pcm16EncoderProcessor extends AudioWorkletProcessor {\n constructor(options) {\n super();\n const opts = (options && options.processorOptions) || {};\n this.targetRate = opts.targetRate || 16000;\n this.chunkMs = opts.chunkMs || 50;\n this.ratio = sampleRate / this.targetRate;\n this.chunkSize = Math.round(this.targetRate * this.chunkMs / 1000);\n this.buffer = new Int16Array(this.chunkSize);\n this.bufferIdx = 0;\n this.samplesSent = 0;\n this.lastSample = 0;\n this.fractional = 0;\n }\n\n process(inputs) {\n const input = inputs[0];\n if (!input || input.length === 0 || !input[0] || input[0].length === 0) {\n return true;\n }\n const mono = input[0];\n let pos = this.fractional;\n while (pos < mono.length) {\n const i = Math.floor(pos);\n const frac = pos - i;\n const a = i === 0 ? this.lastSample : mono[i - 1];\n const b = mono[i];\n const sample = a + (b - a) * frac;\n const clamped = sample < -1 ? -1 : sample > 1 ? 1 : sample;\n this.buffer[this.bufferIdx++] = clamped < 0 ? clamped * 0x8000 : clamped * 0x7fff;\n if (this.bufferIdx === this.chunkSize) {\n const out = new Int16Array(this.chunkSize);\n out.set(this.buffer);\n this.samplesSent += this.chunkSize;\n this.port.postMessage(\n { pcm: out.buffer, samplesSent: this.samplesSent },\n [out.buffer],\n );\n this.bufferIdx = 0;\n }\n pos += this.ratio;\n }\n this.lastSample = mono[mono.length - 1];\n this.fractional = pos - mono.length;\n return true;\n }\n}\nregisterProcessor("aai-pcm16-encoder", Pcm16EncoderProcessor);\n'],{type:"application/javascript"}),t=URL.createObjectURL(e);try{yield this.context.audioWorklet.addModule(t)}finally{URL.revokeObjectURL(t)}this.micSource=this.context.createMediaStreamSource(this.params.micStream),this.sysSource=this.context.createMediaStreamSource(this.params.systemStream),this.micEncoder=this.makeEncoder("mic"),this.sysEncoder=this.makeEncoder("system"),this.micSource.connect(this.micEncoder),this.sysSource.connect(this.sysEncoder),this.running=!0}))}makeEncoder(e){const t=new AudioWorkletNode(this.context,"aai-pcm16-encoder",{numberOfInputs:1,numberOfOutputs:0,channelCount:1,channelCountMode:"explicit",channelInterpretation:"speakers",processorOptions:{targetRate:this.params.targetSampleRate,chunkMs:50}});return t.port.onmessage=t=>{var s;try{this.params.transcriber.sendAudio(t.data.pcm,{channel:e})}catch(e){null===(s=this.errorListener)||void 0===s||s.call(this,e)}},t}stop(){return n(this,void 0,void 0,(function*(){var e,t,s,n,i,r;if(this.running){this.running=!1;try{null===(e=this.micEncoder)||void 0===e||e.port.close(),null===(t=this.sysEncoder)||void 0===t||t.port.close(),null===(s=this.micEncoder)||void 0===s||s.disconnect(),null===(n=this.sysEncoder)||void 0===n||n.disconnect(),null===(i=this.micSource)||void 0===i||i.disconnect(),null===(r=this.sysSource)||void 0===r||r.disconnect()}catch(e){}this.context&&"closed"!==this.context.state&&(yield this.context.close()),this.context=void 0,this.micSource=void 0,this.sysSource=void 0,this.micEncoder=void 0,this.sysEncoder=void 0}}))}},e.EnergyVad=R,e.FileService=x,e.LemurService=l,e.LinearResampler=class{constructor(e,t){if(this.sourceRate=e,this.targetRate=t,this.lastSample=0,this.fractional=0,e<=0||t<=0)throw new Error("sourceRate and targetRate must be positive");this.ratio=e/t}process(e){var t;if(this.sourceRate===this.targetRate)return e;const s=new Float32Array(Math.ceil(e.length/this.ratio)+1);let n=0,i=this.fractional;for(;i<e.length;){const t=Math.floor(i),r=i-t,o=0===t?this.lastSample:e[t-1],a=e[t];s[n++]=o+(a-o)*r,i+=this.ratio}return this.lastSample=null!==(t=e[e.length-1])&&void 0!==t?t:this.lastSample,this.fractional=i-e.length,s.subarray(0,n)}reset(){this.lastSample=0,this.fractional=0}},e.RealtimeService=class extends T{},e.RealtimeServiceFactory=class extends A{},e.RealtimeTranscriber=T,e.RealtimeTranscriberFactory=A,e.StreamingTranscriber=N,e.TranscriptService=O,e.VadTimeline=E,e.attributeTurn=C,e.attributeWord=U,e.float32ToPcm16=function(e){const t=new ArrayBuffer(2*e.length),s=new DataView(t);for(let t=0;t<e.length;t++){const n=Math.max(-1,Math.min(1,e[t]));s.setInt16(2*t,n<0?32768*n:32767*n,!0)}return t},e.rollUpTurnChannel=M}));
package/dist/browser.mjs CHANGED
@@ -28,7 +28,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
28
28
  defaultUserAgentString += navigator.userAgent;
29
29
  }
30
30
  const defaultUserAgent = {
31
- sdk: { name: "JavaScript", version: "4.35.0" },
31
+ sdk: { name: "JavaScript", version: "4.35.3" },
32
32
  };
33
33
  if (typeof process !== "undefined") {
34
34
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1151,8 +1151,12 @@ class StreamingTranscriber {
1151
1151
  searchParams.set("speech_model", this.params.speechModel.toString());
1152
1152
  }
1153
1153
  if (this.params.languageCode !== undefined) {
1154
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
1154
1155
  searchParams.set("language_code", this.params.languageCode);
1155
1156
  }
1157
+ if (this.params.languageCodes !== undefined) {
1158
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
1159
+ }
1156
1160
  if (this.params.languageDetection !== undefined) {
1157
1161
  searchParams.set("language_detection", this.params.languageDetection.toString());
1158
1162
  }
package/dist/bun.mjs CHANGED
@@ -30,7 +30,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
30
30
  defaultUserAgentString += navigator.userAgent;
31
31
  }
32
32
  const defaultUserAgent = {
33
- sdk: { name: "JavaScript", version: "4.35.0" },
33
+ sdk: { name: "JavaScript", version: "4.35.3" },
34
34
  };
35
35
  if (typeof process !== "undefined") {
36
36
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1132,8 +1132,12 @@ class StreamingTranscriber {
1132
1132
  searchParams.set("speech_model", this.params.speechModel.toString());
1133
1133
  }
1134
1134
  if (this.params.languageCode !== undefined) {
1135
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
1135
1136
  searchParams.set("language_code", this.params.languageCode);
1136
1137
  }
1138
+ if (this.params.languageCodes !== undefined) {
1139
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
1140
+ }
1137
1141
  if (this.params.languageDetection !== undefined) {
1138
1142
  searchParams.set("language_detection", this.params.languageDetection.toString());
1139
1143
  }
package/dist/deno.mjs CHANGED
@@ -30,7 +30,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
30
30
  defaultUserAgentString += navigator.userAgent;
31
31
  }
32
32
  const defaultUserAgent = {
33
- sdk: { name: "JavaScript", version: "4.35.0" },
33
+ sdk: { name: "JavaScript", version: "4.35.3" },
34
34
  };
35
35
  if (typeof process !== "undefined") {
36
36
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1132,8 +1132,12 @@ class StreamingTranscriber {
1132
1132
  searchParams.set("speech_model", this.params.speechModel.toString());
1133
1133
  }
1134
1134
  if (this.params.languageCode !== undefined) {
1135
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
1135
1136
  searchParams.set("language_code", this.params.languageCode);
1136
1137
  }
1138
+ if (this.params.languageCodes !== undefined) {
1139
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
1140
+ }
1137
1141
  if (this.params.languageDetection !== undefined) {
1138
1142
  searchParams.set("language_detection", this.params.languageDetection.toString());
1139
1143
  }
@@ -1,7 +1,7 @@
1
1
  export * from "../types/asyncapi.generated";
2
2
  export * from "../types/realtime";
3
3
  export * from "../types/helpers";
4
- export * from "../types/streaming/dual-channel";
4
+ export * from "../types/streaming";
5
5
  export * from "../services/realtime/service";
6
6
  export * from "../services/streaming/service";
7
7
  export * from "../services/streaming/factory";
package/dist/index.cjs CHANGED
@@ -76,7 +76,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
76
76
  defaultUserAgentString += navigator.userAgent;
77
77
  }
78
78
  const defaultUserAgent = {
79
- sdk: { name: "JavaScript", version: "4.35.0" },
79
+ sdk: { name: "JavaScript", version: "4.35.3" },
80
80
  };
81
81
  if (typeof process !== "undefined") {
82
82
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1226,8 +1226,12 @@ class StreamingTranscriber {
1226
1226
  searchParams.set("speech_model", this.params.speechModel.toString());
1227
1227
  }
1228
1228
  if (this.params.languageCode !== undefined) {
1229
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
1229
1230
  searchParams.set("language_code", this.params.languageCode);
1230
1231
  }
1232
+ if (this.params.languageCodes !== undefined) {
1233
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
1234
+ }
1231
1235
  if (this.params.languageDetection !== undefined) {
1232
1236
  searchParams.set("language_detection", this.params.languageDetection.toString());
1233
1237
  }
package/dist/index.mjs CHANGED
@@ -74,7 +74,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
74
74
  defaultUserAgentString += navigator.userAgent;
75
75
  }
76
76
  const defaultUserAgent = {
77
- sdk: { name: "JavaScript", version: "4.35.0" },
77
+ sdk: { name: "JavaScript", version: "4.35.3" },
78
78
  };
79
79
  if (typeof process !== "undefined") {
80
80
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1224,8 +1224,12 @@ class StreamingTranscriber {
1224
1224
  searchParams.set("speech_model", this.params.speechModel.toString());
1225
1225
  }
1226
1226
  if (this.params.languageCode !== undefined) {
1227
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
1227
1228
  searchParams.set("language_code", this.params.languageCode);
1228
1229
  }
1230
+ if (this.params.languageCodes !== undefined) {
1231
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
1232
+ }
1229
1233
  if (this.params.languageDetection !== undefined) {
1230
1234
  searchParams.set("language_detection", this.params.languageDetection.toString());
1231
1235
  }
package/dist/node.cjs CHANGED
@@ -35,7 +35,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
35
35
  defaultUserAgentString += navigator.userAgent;
36
36
  }
37
37
  const defaultUserAgent = {
38
- sdk: { name: "JavaScript", version: "4.35.0" },
38
+ sdk: { name: "JavaScript", version: "4.35.3" },
39
39
  };
40
40
  if (typeof process !== "undefined") {
41
41
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1131,8 +1131,12 @@ class StreamingTranscriber {
1131
1131
  searchParams.set("speech_model", this.params.speechModel.toString());
1132
1132
  }
1133
1133
  if (this.params.languageCode !== undefined) {
1134
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
1134
1135
  searchParams.set("language_code", this.params.languageCode);
1135
1136
  }
1137
+ if (this.params.languageCodes !== undefined) {
1138
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
1139
+ }
1136
1140
  if (this.params.languageDetection !== undefined) {
1137
1141
  searchParams.set("language_detection", this.params.languageDetection.toString());
1138
1142
  }
package/dist/node.mjs CHANGED
@@ -33,7 +33,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
33
33
  defaultUserAgentString += navigator.userAgent;
34
34
  }
35
35
  const defaultUserAgent = {
36
- sdk: { name: "JavaScript", version: "4.35.0" },
36
+ sdk: { name: "JavaScript", version: "4.35.3" },
37
37
  };
38
38
  if (typeof process !== "undefined") {
39
39
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1129,8 +1129,12 @@ class StreamingTranscriber {
1129
1129
  searchParams.set("speech_model", this.params.speechModel.toString());
1130
1130
  }
1131
1131
  if (this.params.languageCode !== undefined) {
1132
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
1132
1133
  searchParams.set("language_code", this.params.languageCode);
1133
1134
  }
1135
+ if (this.params.languageCodes !== undefined) {
1136
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
1137
+ }
1134
1138
  if (this.params.languageDetection !== undefined) {
1135
1139
  searchParams.set("language_detection", this.params.languageDetection.toString());
1136
1140
  }
@@ -682,8 +682,12 @@ class StreamingTranscriber {
682
682
  searchParams.set("speech_model", this.params.speechModel.toString());
683
683
  }
684
684
  if (this.params.languageCode !== undefined) {
685
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
685
686
  searchParams.set("language_code", this.params.languageCode);
686
687
  }
688
+ if (this.params.languageCodes !== undefined) {
689
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
690
+ }
687
691
  if (this.params.languageDetection !== undefined) {
688
692
  searchParams.set("language_detection", this.params.languageDetection.toString());
689
693
  }
@@ -1300,7 +1304,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
1300
1304
  defaultUserAgentString += navigator.userAgent;
1301
1305
  }
1302
1306
  const defaultUserAgent = {
1303
- sdk: { name: "JavaScript", version: "4.35.0" },
1307
+ sdk: { name: "JavaScript", version: "4.35.3" },
1304
1308
  };
1305
1309
  if (typeof process !== "undefined") {
1306
1310
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -728,8 +728,12 @@ class StreamingTranscriber {
728
728
  searchParams.set("speech_model", this.params.speechModel.toString());
729
729
  }
730
730
  if (this.params.languageCode !== undefined) {
731
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
731
732
  searchParams.set("language_code", this.params.languageCode);
732
733
  }
734
+ if (this.params.languageCodes !== undefined) {
735
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
736
+ }
733
737
  if (this.params.languageDetection !== undefined) {
734
738
  searchParams.set("language_detection", this.params.languageDetection.toString());
735
739
  }
@@ -726,8 +726,12 @@ class StreamingTranscriber {
726
726
  searchParams.set("speech_model", this.params.speechModel.toString());
727
727
  }
728
728
  if (this.params.languageCode !== undefined) {
729
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
729
730
  searchParams.set("language_code", this.params.languageCode);
730
731
  }
732
+ if (this.params.languageCodes !== undefined) {
733
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
734
+ }
731
735
  if (this.params.languageDetection !== undefined) {
732
736
  searchParams.set("language_detection", this.params.languageDetection.toString());
733
737
  }
@@ -6,7 +6,7 @@ export type AudioData = ArrayBufferLike;
6
6
  * The encoding of the audio data
7
7
  * @defaultValue "pcm_s16"le
8
8
  */
9
- export type AudioEncoding = "pcm_s16le" | "pcm_mulaw";
9
+ export type AudioEncoding = "pcm_s16le" | "pcm_mulaw" | "opus" | "ogg_opus";
10
10
  /**
11
11
  * Configure the threshold for how long to wait before ending an utterance. Default is 700ms.
12
12
  */
@@ -104,7 +104,19 @@ export type StreamingTranscriberParams = {
104
104
  prompt?: string;
105
105
  agentContext?: string;
106
106
  speechModel?: StreamingSpeechModel;
107
+ /**
108
+ * @deprecated Use `languageCodes` instead (pass a single-element array, e.g. `["es"]`,
109
+ * for the same behavior). Still supported for backward compatibility.
110
+ */
107
111
  languageCode?: string;
112
+ /**
113
+ * Recommended way to select languages. Steers transcription toward a set of
114
+ * languages by biasing output toward them on a per-token basis while still
115
+ * allowing native code-switching among them. Pass the languages you expect
116
+ * (e.g. `["en", "es"]`), or a single-element array (e.g. `["es"]`) for a
117
+ * monolingual session. Universal-3.5 Pro Streaming only.
118
+ */
119
+ languageCodes?: string[];
108
120
  languageDetection?: boolean;
109
121
  domain?: StreamingDomain;
110
122
  inactivityTimeout?: number;
@@ -255,6 +267,12 @@ export type StreamingUpdateConfiguration = {
255
267
  filter_profanity?: boolean;
256
268
  interruption_delay?: number;
257
269
  turn_left_pad_ms?: number;
270
+ /**
271
+ * Steer transcription toward a set of languages mid-stream. Pass an empty
272
+ * array (`[]`) to clear steering and restore the model's default
273
+ * multilingual code-switching. Universal-3.5 Pro Streaming only.
274
+ */
275
+ language_codes?: string[];
258
276
  };
259
277
  export type StreamingForceEndpoint = {
260
278
  type: "ForceEndpoint";
package/dist/workerd.mjs CHANGED
@@ -28,7 +28,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
28
28
  defaultUserAgentString += navigator.userAgent;
29
29
  }
30
30
  const defaultUserAgent = {
31
- sdk: { name: "JavaScript", version: "4.35.0" },
31
+ sdk: { name: "JavaScript", version: "4.35.3" },
32
32
  };
33
33
  if (typeof process !== "undefined") {
34
34
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1134,8 +1134,12 @@ class StreamingTranscriber {
1134
1134
  searchParams.set("speech_model", this.params.speechModel.toString());
1135
1135
  }
1136
1136
  if (this.params.languageCode !== undefined) {
1137
+ console.warn("[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.");
1137
1138
  searchParams.set("language_code", this.params.languageCode);
1138
1139
  }
1140
+ if (this.params.languageCodes !== undefined) {
1141
+ searchParams.set("language_codes", JSON.stringify(this.params.languageCodes));
1142
+ }
1139
1143
  if (this.params.languageDetection !== undefined) {
1140
1144
  searchParams.set("language_detection", this.params.languageDetection.toString());
1141
1145
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assemblyai",
3
- "version": "4.35.0",
3
+ "version": "4.35.3",
4
4
  "description": "The AssemblyAI JavaScript SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription, as well as the latest LeMUR models.",
5
5
  "engines": {
6
6
  "node": ">=18"
@@ -1,7 +1,7 @@
1
1
  export * from "../types/asyncapi.generated";
2
2
  export * from "../types/realtime";
3
3
  export * from "../types/helpers";
4
- export * from "../types/streaming/dual-channel";
4
+ export * from "../types/streaming";
5
5
  export * from "../services/realtime/service";
6
6
  export * from "../services/streaming/service";
7
7
  export * from "../services/streaming/factory";
@@ -313,9 +313,19 @@ export class StreamingTranscriber {
313
313
  }
314
314
 
315
315
  if (this.params.languageCode !== undefined) {
316
+ console.warn(
317
+ "[Deprecation Warning] `languageCode` is deprecated and will be removed in a future release. Please use `languageCodes` instead.",
318
+ );
316
319
  searchParams.set("language_code", this.params.languageCode);
317
320
  }
318
321
 
322
+ if (this.params.languageCodes !== undefined) {
323
+ searchParams.set(
324
+ "language_codes",
325
+ JSON.stringify(this.params.languageCodes),
326
+ );
327
+ }
328
+
319
329
  if (this.params.languageDetection !== undefined) {
320
330
  searchParams.set(
321
331
  "language_detection",
@@ -25,7 +25,7 @@ export type AudioData = ArrayBufferLike;
25
25
  * The encoding of the audio data
26
26
  * @defaultValue "pcm_s16"le
27
27
  */
28
- export type AudioEncoding = "pcm_s16le" | "pcm_mulaw";
28
+ export type AudioEncoding = "pcm_s16le" | "pcm_mulaw" | "opus" | "ogg_opus";
29
29
 
30
30
  /**
31
31
  * Configure the threshold for how long to wait before ending an utterance. Default is 700ms.
@@ -109,7 +109,19 @@ export type StreamingTranscriberParams = {
109
109
  prompt?: string;
110
110
  agentContext?: string;
111
111
  speechModel?: StreamingSpeechModel;
112
+ /**
113
+ * @deprecated Use `languageCodes` instead (pass a single-element array, e.g. `["es"]`,
114
+ * for the same behavior). Still supported for backward compatibility.
115
+ */
112
116
  languageCode?: string;
117
+ /**
118
+ * Recommended way to select languages. Steers transcription toward a set of
119
+ * languages by biasing output toward them on a per-token basis while still
120
+ * allowing native code-switching among them. Pass the languages you expect
121
+ * (e.g. `["en", "es"]`), or a single-element array (e.g. `["es"]`) for a
122
+ * monolingual session. Universal-3.5 Pro Streaming only.
123
+ */
124
+ languageCodes?: string[];
113
125
  languageDetection?: boolean;
114
126
  domain?: StreamingDomain;
115
127
  inactivityTimeout?: number;
@@ -359,6 +371,12 @@ export type StreamingUpdateConfiguration = {
359
371
  filter_profanity?: boolean;
360
372
  interruption_delay?: number;
361
373
  turn_left_pad_ms?: number;
374
+ /**
375
+ * Steer transcription toward a set of languages mid-stream. Pass an empty
376
+ * array (`[]`) to clear steering and restore the model's default
377
+ * multilingual code-switching. Universal-3.5 Pro Streaming only.
378
+ */
379
+ language_codes?: string[];
362
380
  };
363
381
 
364
382
  export type StreamingForceEndpoint = {