assemblyai 4.34.0 → 4.34.5

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/README.md CHANGED
@@ -23,6 +23,28 @@ It is written primarily for Node.js in TypeScript with all types exported, but a
23
23
 
24
24
  This repository includes a [`CLAUDE.md`](CLAUDE.md) file that provides context to Claude Code about this SDK — key APIs, common patterns, and gotchas. When you open this repo in Claude Code, it automatically reads this file to give better assistance.
25
25
 
26
+ ## Using with AI coding agents
27
+
28
+ If you're integrating this SDK with Claude Code, Cursor, Copilot, or another AI coding assistant, give your agent current API context so it doesn't generate code against outdated model names or parameters.
29
+
30
+ The most effective option is project instructions. Add this to your `CLAUDE.md`, `.cursorrules`, `AGENTS.md`, or equivalent agent instructions file:
31
+
32
+ > Always fetch https://assemblyai.com/docs/llms.txt before writing AssemblyAI code. The API has changed, do not rely on memorized parameter names.
33
+
34
+ For on-demand documentation lookups during a session, connect the AssemblyAI docs MCP server:
35
+
36
+ ```
37
+ claude mcp add assemblyai-docs --transport http https://mcp.assemblyai.com/docs
38
+ ```
39
+
40
+ For deep SDK context in Claude Code specifically, install the [AssemblyAI skill](https://github.com/AssemblyAI/assemblyai-skill):
41
+
42
+ ```
43
+ claude install-skill https://github.com/AssemblyAI/assemblyai-skill
44
+ ```
45
+
46
+ See [Coding agent prompts](https://www.assemblyai.com/docs/coding-agent-prompts) for Cursor setup, MCP tool details, and tips for best results.
47
+
26
48
  ## Documentation
27
49
 
28
50
  Visit the [AssemblyAI documentation](https://www.assemblyai.com/docs) for step-by-step instructions and a lot more details about our AI models and API.
@@ -710,13 +710,21 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
710
710
  if (this.params.prompt) {
711
711
  searchParams.set("prompt", this.params.prompt);
712
712
  }
713
+ if (this.params.agentContext) {
714
+ searchParams.set("agent_context", this.params.agentContext);
715
+ }
713
716
  if (this.params.filterProfanity) {
714
717
  searchParams.set("filter_profanity", this.params.filterProfanity.toString());
715
718
  }
716
719
  if (this.params.speechModel === "u3-pro") {
717
720
  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.");
718
721
  }
719
- searchParams.set("speech_model", this.params.speechModel.toString());
722
+ if (this.params.speechModel !== undefined) {
723
+ searchParams.set("speech_model", this.params.speechModel.toString());
724
+ }
725
+ if (this.params.languageCode !== undefined) {
726
+ searchParams.set("language_code", this.params.languageCode);
727
+ }
720
728
  if (this.params.languageDetection !== undefined) {
721
729
  searchParams.set("language_detection", this.params.languageDetection.toString());
722
730
  }
@@ -777,6 +785,9 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
777
785
  if (this.params.redactPiiSub !== undefined) {
778
786
  searchParams.set("redact_pii_sub", this.params.redactPiiSub);
779
787
  }
788
+ if (this.params.mode !== undefined) {
789
+ searchParams.set("mode", this.params.mode);
790
+ }
780
791
  if (this.params.llmGateway !== undefined) {
781
792
  searchParams.set("llm_gateway", JSON.stringify(this.params.llmGateway));
782
793
  }
@@ -831,7 +842,7 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
831
842
  (_d = (_c = this.listeners).error) === null || _d === void 0 ? void 0 : _d.call(_c, new Error(event.message));
832
843
  };
833
844
  this.socket.onmessage = ({ data }) => {
834
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
845
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
835
846
  const message = JSON.parse(data.toString());
836
847
  if ("error" in message) {
837
848
  const err = new StreamingError(message.error);
@@ -873,14 +884,18 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
873
884
  (_k = (_j = this.listeners).llmGatewayResponse) === null || _k === void 0 ? void 0 : _k.call(_j, message);
874
885
  break;
875
886
  }
887
+ case "SpeakerRevision": {
888
+ (_m = (_l = this.listeners).speakerRevision) === null || _m === void 0 ? void 0 : _m.call(_l, message);
889
+ break;
890
+ }
876
891
  case "Warning": {
877
892
  const warning = message;
878
893
  console.warn(`Streaming warning (code=${warning.warning_code}): ${warning.warning}`);
879
- (_m = (_l = this.listeners).warning) === null || _m === void 0 ? void 0 : _m.call(_l, warning);
894
+ (_p = (_o = this.listeners).warning) === null || _p === void 0 ? void 0 : _p.call(_o, warning);
880
895
  break;
881
896
  }
882
897
  case "Termination": {
883
- (_o = this.sessionTerminatedResolve) === null || _o === void 0 ? void 0 : _o.call(this);
898
+ (_q = this.sessionTerminatedResolve) === null || _q === void 0 ? void 0 : _q.call(this);
884
899
  break;
885
900
  }
886
901
  }
@@ -1218,7 +1233,7 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
1218
1233
  defaultUserAgentString += navigator.userAgent;
1219
1234
  }
1220
1235
  const defaultUserAgent = {
1221
- sdk: { name: "JavaScript", version: "4.34.0" },
1236
+ sdk: { name: "JavaScript", version: "4.34.5" },
1222
1237
  };
1223
1238
  if (typeof process !== "undefined") {
1224
1239
  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 h extends Error{}const c={[3005]:"Server error",[3006]:"Input validation error",[3007]:"Audio chunk duration violation",[3008]:"Session expired: maximum session duration exceeded",[3009]:"Too many concurrent sessions",[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",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid."};class d extends Error{}const u='{"terminate_session":true}';class m{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,c,d,u,m,p,f,v,w;const g=JSON.parse(t.toString());if("error"in g)null===(n=(s=this.listeners).error)||void 0===n||n.call(s,new h(g.error));else switch(g.message_type){case"SessionBegins":{const t={sessionId:g.session_id,expiresAt:new Date(g.expires_at)};e(t),null===(r=(i=this.listeners).open)||void 0===r||r.call(i,t);break}case"PartialTranscript":g.created=new Date(g.created),null===(a=(o=this.listeners).transcript)||void 0===a||a.call(o,g),null===(c=(l=this.listeners)["transcript.partial"])||void 0===c||c.call(l,g);break;case"FinalTranscript":g.created=new Date(g.created),null===(u=(d=this.listeners).transcript)||void 0===u||u.call(d,g),null===(p=(m=this.listeners)["transcript.final"])||void 0===p||p.call(m,g);break;case"SessionInformation":null===(v=(f=this.listeners).session_information)||void 0===v||v.call(f,g);break;case"SessionTerminated":null===(w=this.sessionTerminatedResolve)||void 0===w||w.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(u),yield e}else this.socket.send(u);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class p{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 f{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 v(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 w(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 g(e,t,s){for(const n of e.words)n.channel=v(n,t,s);e.channel=w(e.words)}const y='{"type":"Terminate"}';class k{constructor(e){var t,s,n,i,r,o,a,l,h;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 c=e.channels.map((e=>e.name));if(new Set(c).size!==c.length)throw new Error("StreamingTranscriber.channels names must be unique.");this.isDualChannel=!0,this.channelNames=c;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 p,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!==(h=d.speakerHistoryDominanceRatio)&&void 0!==h?h: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(c.map((e=>[e,[]]))),this.channelSamplesReceived=new Map(c.map((e=>[e,0]))),this.channelVadFloatBuffers=new Map(c.map((e=>[e,new Float32Array(this.vadFrameSamples)]))),this.channelVadBufferIdx=new Map(c.map((e=>[e,0]))),this.channelVads=new Map(c.map((e=>[e,this.attributionParams.createVad(e)]))),this.timeline=new f(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.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."),n.set("speech_model",this.params.speechModel.toString()),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.llmGateway&&n.set("llm_gateway",JSON.stringify(this.params.llmGateway)),s.search=n.toString(),s}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 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(t.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in c&&(t=c[e]),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,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,c,u,m,p,f;const v=JSON.parse(t.toString());if("error"in v){const e=new d(v.error);return"error_code"in v&&(e.code=v.error_code),void(null===(n=(s=this.listeners).error)||void 0===n||n.call(s,e))}switch(v.type){case"Begin":e(v),null===(r=(i=this.listeners).open)||void 0===r||r.call(i,v);break;case"Turn":if(this.isDualChannel&&this.timeline&&this.attributionParams)switch(g(v,this.timeline,{dominanceRatio:this.attributionParams.dominanceRatio}),this.attributionParams.resolveUnknownChannelsMethod){case"window":this.resolveUnknownChannelsByWindow(v);break;case"speaker-history":this.resolveUnknownChannelsBySpeakerHistory(v)}null===(a=(o=this.listeners).turn)||void 0===a||a.call(o,v);break;case"SpeechStarted":null===(h=(l=this.listeners).speechStarted)||void 0===h||h.call(l,v);break;case"LLMGatewayResponse":null===(u=(c=this.listeners).llmGatewayResponse)||void 0===u||u.call(c,v);break;case"Warning":{const e=v;console.warn(`Streaming warning (code=${e.warning_code}): ${e.warning}`),null===(p=(m=this.listeners).warning)||void 0===p||p.call(m,e);break}case"Termination":null===(f=this.sessionTerminatedResolve)||void 0===f||f.call(this)}}}))}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 h=this.channelVads.get(e),c=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=h.process(o),i={ts:l/c*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,h=0,c=!1;for(const[e,t]of r)t>h?(l=e,h=t,c=!1):t===h&&(c=!0);l&&!c&&(n[e].channel=l,n[e].channelResolved=!0,i=!0)}i&&(e.channel=w(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=w(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"}))}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(y),yield e}else this.socket.send(y);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}const S={cache:"no-store"};let b="";"undefined"!=typeof navigator&&navigator.userAgent&&(b+=navigator.userAgent);const _={sdk:{name:"JavaScript",version:"4.34.0"}};"undefined"!=typeof process&&(process.versions.node&&-1===b.indexOf("Node")&&(_.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===b.indexOf("Bun")&&(_.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===b.indexOf("Deno")&&(_.runtime_env={name:"Deno",version:Deno.version.deno});class T{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},b+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},_),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({},S),t);let s={Authorization:this.params.apiKey,"Content-Type":"application/json"};(null==S?void 0:S.headers)&&(s=Object.assign(Object.assign({},s),S.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 A extends T{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 k(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=p,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 m{},e.RealtimeTranscriber=m,e.StreamingServiceFactory=class extends A{},e.StreamingTranscriber=k,e.StreamingTranscriberFactory=A,e.VadTimeline=f,e.attributeTurn=g,e.attributeWord=v,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=w}));
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 h extends Error{}const c={[3005]:"Server error",[3006]:"Input validation error",[3007]:"Audio chunk duration violation",[3008]:"Session expired: maximum session duration exceeded",[3009]:"Too many concurrent sessions",[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",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid."};class d extends Error{}const u='{"terminate_session":true}';class m{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,c,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 h(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===(c=(l=this.listeners)["transcript.partial"])||void 0===c||c.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(u),yield e}else this.socket.send(u);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class p{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 f{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 v(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 g(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 w(e,t,s){for(const n of e.words)n.channel=v(n,t,s);e.channel=g(e.words)}const k='{"type":"Terminate"}';class y{constructor(e){var t,s,n,i,r,o,a,l,h;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 c=e.channels.map((e=>e.name));if(new Set(c).size!==c.length)throw new Error("StreamingTranscriber.channels names must be unique.");this.isDualChannel=!0,this.channelNames=c;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 p,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!==(h=d.speakerHistoryDominanceRatio)&&void 0!==h?h: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(c.map((e=>[e,[]]))),this.channelSamplesReceived=new Map(c.map((e=>[e,0]))),this.channelVadFloatBuffers=new Map(c.map((e=>[e,new Float32Array(this.vadFrameSamples)]))),this.channelVadBufferIdx=new Map(c.map((e=>[e,0]))),this.channelVads=new Map(c.map((e=>[e,this.attributionParams.createVad(e)]))),this.timeline=new f(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 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 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(t.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in c&&(t=c[e]),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,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,c,u,m,p,f,v,g;const k=JSON.parse(t.toString());if("error"in k){const e=new d(k.error);return"error_code"in k&&(e.code=k.error_code),void(null===(n=(s=this.listeners).error)||void 0===n||n.call(s,e))}switch(k.type){case"Begin":e(k),null===(r=(i=this.listeners).open)||void 0===r||r.call(i,k);break;case"Turn":if(this.isDualChannel&&this.timeline&&this.attributionParams)switch(w(k,this.timeline,{dominanceRatio:this.attributionParams.dominanceRatio}),this.attributionParams.resolveUnknownChannelsMethod){case"window":this.resolveUnknownChannelsByWindow(k);break;case"speaker-history":this.resolveUnknownChannelsBySpeakerHistory(k)}null===(a=(o=this.listeners).turn)||void 0===a||a.call(o,k);break;case"SpeechStarted":null===(h=(l=this.listeners).speechStarted)||void 0===h||h.call(l,k);break;case"LLMGatewayResponse":null===(u=(c=this.listeners).llmGatewayResponse)||void 0===u||u.call(c,k);break;case"SpeakerRevision":null===(p=(m=this.listeners).speakerRevision)||void 0===p||p.call(m,k);break;case"Warning":{const e=k;console.warn(`Streaming warning (code=${e.warning_code}): ${e.warning}`),null===(v=(f=this.listeners).warning)||void 0===v||v.call(f,e);break}case"Termination":null===(g=this.sessionTerminatedResolve)||void 0===g||g.call(this)}}}))}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 h=this.channelVads.get(e),c=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=h.process(o),i={ts:l/c*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,h=0,c=!1;for(const[e,t]of r)t>h?(l=e,h=t,c=!1):t===h&&(c=!0);l&&!c&&(n[e].channel=l,n[e].channelResolved=!0,i=!0)}i&&(e.channel=g(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=g(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"}))}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(k),yield e}else this.socket.send(k);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}const S={cache:"no-store"};let b="";"undefined"!=typeof navigator&&navigator.userAgent&&(b+=navigator.userAgent);const _={sdk:{name:"JavaScript",version:"4.34.5"}};"undefined"!=typeof process&&(process.versions.node&&-1===b.indexOf("Node")&&(_.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===b.indexOf("Bun")&&(_.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===b.indexOf("Deno")&&(_.runtime_env={name:"Deno",version:Deno.version.deno});class T{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},b+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},_),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({},S),t);let s={Authorization:this.params.apiKey,"Content-Type":"application/json"};(null==S?void 0:S.headers)&&(s=Object.assign(Object.assign({},s),S.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 A extends T{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 y(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=p,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 m{},e.RealtimeTranscriber=m,e.StreamingServiceFactory=class extends A{},e.StreamingTranscriber=y,e.StreamingTranscriberFactory=A,e.VadTimeline=f,e.attributeTurn=w,e.attributeWord=v,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=g}));
@@ -78,7 +78,7 @@
78
78
  defaultUserAgentString += navigator.userAgent;
79
79
  }
80
80
  const defaultUserAgent = {
81
- sdk: { name: "JavaScript", version: "4.34.0" },
81
+ sdk: { name: "JavaScript", version: "4.34.5" },
82
82
  };
83
83
  if (typeof process !== "undefined") {
84
84
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1208,13 +1208,21 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
1208
1208
  if (this.params.prompt) {
1209
1209
  searchParams.set("prompt", this.params.prompt);
1210
1210
  }
1211
+ if (this.params.agentContext) {
1212
+ searchParams.set("agent_context", this.params.agentContext);
1213
+ }
1211
1214
  if (this.params.filterProfanity) {
1212
1215
  searchParams.set("filter_profanity", this.params.filterProfanity.toString());
1213
1216
  }
1214
1217
  if (this.params.speechModel === "u3-pro") {
1215
1218
  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.");
1216
1219
  }
1217
- searchParams.set("speech_model", this.params.speechModel.toString());
1220
+ if (this.params.speechModel !== undefined) {
1221
+ searchParams.set("speech_model", this.params.speechModel.toString());
1222
+ }
1223
+ if (this.params.languageCode !== undefined) {
1224
+ searchParams.set("language_code", this.params.languageCode);
1225
+ }
1218
1226
  if (this.params.languageDetection !== undefined) {
1219
1227
  searchParams.set("language_detection", this.params.languageDetection.toString());
1220
1228
  }
@@ -1275,6 +1283,9 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
1275
1283
  if (this.params.redactPiiSub !== undefined) {
1276
1284
  searchParams.set("redact_pii_sub", this.params.redactPiiSub);
1277
1285
  }
1286
+ if (this.params.mode !== undefined) {
1287
+ searchParams.set("mode", this.params.mode);
1288
+ }
1278
1289
  if (this.params.llmGateway !== undefined) {
1279
1290
  searchParams.set("llm_gateway", JSON.stringify(this.params.llmGateway));
1280
1291
  }
@@ -1329,7 +1340,7 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
1329
1340
  (_d = (_c = this.listeners).error) === null || _d === void 0 ? void 0 : _d.call(_c, new Error(event.message));
1330
1341
  };
1331
1342
  this.socket.onmessage = ({ data }) => {
1332
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
1343
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
1333
1344
  const message = JSON.parse(data.toString());
1334
1345
  if ("error" in message) {
1335
1346
  const err = new StreamingError(message.error);
@@ -1371,14 +1382,18 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
1371
1382
  (_k = (_j = this.listeners).llmGatewayResponse) === null || _k === void 0 ? void 0 : _k.call(_j, message);
1372
1383
  break;
1373
1384
  }
1385
+ case "SpeakerRevision": {
1386
+ (_m = (_l = this.listeners).speakerRevision) === null || _m === void 0 ? void 0 : _m.call(_l, message);
1387
+ break;
1388
+ }
1374
1389
  case "Warning": {
1375
1390
  const warning = message;
1376
1391
  console.warn(`Streaming warning (code=${warning.warning_code}): ${warning.warning}`);
1377
- (_m = (_l = this.listeners).warning) === null || _m === void 0 ? void 0 : _m.call(_l, warning);
1392
+ (_p = (_o = this.listeners).warning) === null || _p === void 0 ? void 0 : _p.call(_o, warning);
1378
1393
  break;
1379
1394
  }
1380
1395
  case "Termination": {
1381
- (_o = this.sessionTerminatedResolve) === null || _o === void 0 ? void 0 : _o.call(this);
1396
+ (_q = this.sessionTerminatedResolve) === null || _q === void 0 ? void 0 : _q.call(this);
1382
1397
  break;
1383
1398
  }
1384
1399
  }
@@ -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.34.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={[3005]:"Server error",[3006]:"Input validation error",[3007]:"Audio chunk duration violation",[3008]:"Session expired: maximum session duration exceeded",[3009]:"Too many concurrent sessions",[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",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid."};class g extends Error{}const y='{"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=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(y),yield e}else this.socket.send(y);(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.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 w(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 S(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 k 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=S(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=S(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 _ 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 T{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 A{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 P(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 O(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 x(e,t,s){for(const n of e.words)n.channel=P(n,t,s);e.channel=O(e.words)}const R='{"type":"Terminate"}';class E{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 T,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 A(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.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."),n.set("speech_model",this.params.speechModel.toString()),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.llmGateway&&n.set("llm_gateway",JSON.stringify(this.params.llmGateway)),s.search=n.toString(),s}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 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(t.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in v&&(t=v[e]),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,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;const f=JSON.parse(t.toString());if("error"in f){const e=new g(f.error);return"error_code"in f&&(e.code=f.error_code),void(null===(n=(s=this.listeners).error)||void 0===n||n.call(s,e))}switch(f.type){case"Begin":e(f),null===(r=(i=this.listeners).open)||void 0===r||r.call(i,f);break;case"Turn":if(this.isDualChannel&&this.timeline&&this.attributionParams)switch(x(f,this.timeline,{dominanceRatio:this.attributionParams.dominanceRatio}),this.attributionParams.resolveUnknownChannelsMethod){case"window":this.resolveUnknownChannelsByWindow(f);break;case"speaker-history":this.resolveUnknownChannelsBySpeakerHistory(f)}null===(a=(o=this.listeners).turn)||void 0===a||a.call(o,f);break;case"SpeechStarted":null===(c=(l=this.listeners).speechStarted)||void 0===c||c.call(l,f);break;case"LLMGatewayResponse":null===(d=(h=this.listeners).llmGatewayResponse)||void 0===d||d.call(h,f);break;case"Warning":{const e=f;console.warn(`Streaming warning (code=${e.warning_code}): ${e.warning}`),null===(m=(u=this.listeners).warning)||void 0===m||m.call(u,e);break}case"Termination":null===(p=this.sessionTerminatedResolve)||void 0===p||p.call(this)}}}))}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=O(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=O(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"}))}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(R),yield e}else this.socket.send(R);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class U 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 E(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 _(e),this.transcripts=new k(e,this.files),this.lemur=new l(e),this.realtime=new b(e),this.streaming=new U(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=T,e.FileService=_,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 w{},e.RealtimeServiceFactory=class extends b{},e.RealtimeTranscriber=w,e.RealtimeTranscriberFactory=b,e.StreamingTranscriber=E,e.TranscriptService=k,e.VadTimeline=A,e.attributeTurn=x,e.attributeWord=P,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=O}));
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.34.5"}};"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={[3005]:"Server error",[3006]:"Input validation error",[3007]:"Audio chunk duration violation",[3008]:"Session expired: maximum session duration exceeded",[3009]:"Too many concurrent sessions",[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",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid."};class g extends Error{}const y='{"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=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(y),yield e}else this.socket.send(y);(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.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 w(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 S(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 k 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=S(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=S(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 _ 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 T{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 A{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 P(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 x(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 R(e,t,s){for(const n of e.words)n.channel=P(n,t,s);e.channel=x(e.words)}const O='{"type":"Terminate"}';class E{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 T,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 A(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 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 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(t.toString(),{headers:{Authorization:this.apiKey}})),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in v&&(t=v[e]),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,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,f,v;const y=JSON.parse(t.toString());if("error"in y){const e=new g(y.error);return"error_code"in y&&(e.code=y.error_code),void(null===(n=(s=this.listeners).error)||void 0===n||n.call(s,e))}switch(y.type){case"Begin":e(y),null===(r=(i=this.listeners).open)||void 0===r||r.call(i,y);break;case"Turn":if(this.isDualChannel&&this.timeline&&this.attributionParams)switch(R(y,this.timeline,{dominanceRatio:this.attributionParams.dominanceRatio}),this.attributionParams.resolveUnknownChannelsMethod){case"window":this.resolveUnknownChannelsByWindow(y);break;case"speaker-history":this.resolveUnknownChannelsBySpeakerHistory(y)}null===(a=(o=this.listeners).turn)||void 0===a||a.call(o,y);break;case"SpeechStarted":null===(c=(l=this.listeners).speechStarted)||void 0===c||c.call(l,y);break;case"LLMGatewayResponse":null===(d=(h=this.listeners).llmGatewayResponse)||void 0===d||d.call(h,y);break;case"SpeakerRevision":null===(m=(u=this.listeners).speakerRevision)||void 0===m||m.call(u,y);break;case"Warning":{const e=y;console.warn(`Streaming warning (code=${e.warning_code}): ${e.warning}`),null===(f=(p=this.listeners).warning)||void 0===f||f.call(p,e);break}case"Termination":null===(v=this.sessionTerminatedResolve)||void 0===v||v.call(this)}}}))}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=x(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=x(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"}))}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(O),yield e}else this.socket.send(O);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class U 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 E(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 _(e),this.transcripts=new k(e,this.files),this.lemur=new l(e),this.realtime=new b(e),this.streaming=new U(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=T,e.FileService=_,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 w{},e.RealtimeServiceFactory=class extends b{},e.RealtimeTranscriber=w,e.RealtimeTranscriberFactory=b,e.StreamingTranscriber=E,e.TranscriptService=k,e.VadTimeline=A,e.attributeTurn=R,e.attributeWord=P,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=x}));
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.34.0" },
31
+ sdk: { name: "JavaScript", version: "4.34.5" },
32
32
  };
33
33
  if (typeof process !== "undefined") {
34
34
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1120,13 +1120,21 @@ class StreamingTranscriber {
1120
1120
  if (this.params.prompt) {
1121
1121
  searchParams.set("prompt", this.params.prompt);
1122
1122
  }
1123
+ if (this.params.agentContext) {
1124
+ searchParams.set("agent_context", this.params.agentContext);
1125
+ }
1123
1126
  if (this.params.filterProfanity) {
1124
1127
  searchParams.set("filter_profanity", this.params.filterProfanity.toString());
1125
1128
  }
1126
1129
  if (this.params.speechModel === "u3-pro") {
1127
1130
  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.");
1128
1131
  }
1129
- searchParams.set("speech_model", this.params.speechModel.toString());
1132
+ if (this.params.speechModel !== undefined) {
1133
+ searchParams.set("speech_model", this.params.speechModel.toString());
1134
+ }
1135
+ if (this.params.languageCode !== undefined) {
1136
+ searchParams.set("language_code", this.params.languageCode);
1137
+ }
1130
1138
  if (this.params.languageDetection !== undefined) {
1131
1139
  searchParams.set("language_detection", this.params.languageDetection.toString());
1132
1140
  }
@@ -1187,6 +1195,9 @@ class StreamingTranscriber {
1187
1195
  if (this.params.redactPiiSub !== undefined) {
1188
1196
  searchParams.set("redact_pii_sub", this.params.redactPiiSub);
1189
1197
  }
1198
+ if (this.params.mode !== undefined) {
1199
+ searchParams.set("mode", this.params.mode);
1200
+ }
1190
1201
  if (this.params.llmGateway !== undefined) {
1191
1202
  searchParams.set("llm_gateway", JSON.stringify(this.params.llmGateway));
1192
1203
  }
@@ -1280,6 +1291,10 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
1280
1291
  this.listeners.llmGatewayResponse?.(message);
1281
1292
  break;
1282
1293
  }
1294
+ case "SpeakerRevision": {
1295
+ this.listeners.speakerRevision?.(message);
1296
+ break;
1297
+ }
1283
1298
  case "Warning": {
1284
1299
  const warning = message;
1285
1300
  console.warn(`Streaming warning (code=${warning.warning_code}): ${warning.warning}`);
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.34.0" },
33
+ sdk: { name: "JavaScript", version: "4.34.5" },
34
34
  };
35
35
  if (typeof process !== "undefined") {
36
36
  if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
@@ -1101,13 +1101,21 @@ class StreamingTranscriber {
1101
1101
  if (this.params.prompt) {
1102
1102
  searchParams.set("prompt", this.params.prompt);
1103
1103
  }
1104
+ if (this.params.agentContext) {
1105
+ searchParams.set("agent_context", this.params.agentContext);
1106
+ }
1104
1107
  if (this.params.filterProfanity) {
1105
1108
  searchParams.set("filter_profanity", this.params.filterProfanity.toString());
1106
1109
  }
1107
1110
  if (this.params.speechModel === "u3-pro") {
1108
1111
  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.");
1109
1112
  }
1110
- searchParams.set("speech_model", this.params.speechModel.toString());
1113
+ if (this.params.speechModel !== undefined) {
1114
+ searchParams.set("speech_model", this.params.speechModel.toString());
1115
+ }
1116
+ if (this.params.languageCode !== undefined) {
1117
+ searchParams.set("language_code", this.params.languageCode);
1118
+ }
1111
1119
  if (this.params.languageDetection !== undefined) {
1112
1120
  searchParams.set("language_detection", this.params.languageDetection.toString());
1113
1121
  }
@@ -1168,6 +1176,9 @@ class StreamingTranscriber {
1168
1176
  if (this.params.redactPiiSub !== undefined) {
1169
1177
  searchParams.set("redact_pii_sub", this.params.redactPiiSub);
1170
1178
  }
1179
+ if (this.params.mode !== undefined) {
1180
+ searchParams.set("mode", this.params.mode);
1181
+ }
1171
1182
  if (this.params.llmGateway !== undefined) {
1172
1183
  searchParams.set("llm_gateway", JSON.stringify(this.params.llmGateway));
1173
1184
  }
@@ -1257,6 +1268,10 @@ class StreamingTranscriber {
1257
1268
  this.listeners.llmGatewayResponse?.(message);
1258
1269
  break;
1259
1270
  }
1271
+ case "SpeakerRevision": {
1272
+ this.listeners.speakerRevision?.(message);
1273
+ break;
1274
+ }
1260
1275
  case "Warning": {
1261
1276
  const warning = message;
1262
1277
  console.warn(`Streaming warning (code=${warning.warning_code}): ${warning.warning}`);