assemblyai 4.0.1 → 4.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.2.0] - 2024-01-11
4
+
5
+ ### Added
6
+
7
+ - Add `content_safety_confidence` to `TranscriptParams` & `TranscriptOptionalParams`.
8
+
9
+ ### Changed
10
+
11
+ - The `RealtimeService` now sends audio as binary instead of a base64-encoded JSON object.
12
+
13
+ ## [4.1.0] - 2023-12-22
14
+
15
+ ### Added
16
+
17
+ - Add `"anthropic/claude-2-1"` to `LemurModel` type
18
+ - Add `encoding` option to the real-time service and factory. `encoding` can be `"pcm_s16le"` or `"pcm_mulaw"`.
19
+ - `"pcm_mulaw"` is a newly supported audio encoding for the real-time service.
20
+
21
+ ### Changed
22
+
23
+ - Allow any string into `final_model` for LeMUR requests
24
+
3
25
  ## [4.0.1] - 2023-12-14
4
26
 
5
27
  ### Added
@@ -202,11 +202,12 @@
202
202
  this.realtimeUrl = (_a = params.realtimeUrl) !== null && _a !== void 0 ? _a : defaultRealtimeUrl;
203
203
  this.sampleRate = (_b = params.sampleRate) !== null && _b !== void 0 ? _b : 16000;
204
204
  this.wordBoost = params.wordBoost;
205
- if ("apiKey" in params && params.apiKey)
206
- this.apiKey = params.apiKey;
205
+ this.encoding = params.encoding;
207
206
  if ("token" in params && params.token)
208
207
  this.token = params.token;
209
- if (!(this.apiKey || this.token)) {
208
+ if ("apiKey" in params && params.apiKey)
209
+ this.apiKey = params.apiKey;
210
+ if (!(this.token || this.apiKey)) {
210
211
  throw new Error("API key or temporary token is required.");
211
212
  }
212
213
  }
@@ -223,6 +224,9 @@
223
224
  if (this.wordBoost && this.wordBoost.length > 0) {
224
225
  searchParams.set("word_boost", JSON.stringify(this.wordBoost));
225
226
  }
227
+ if (this.encoding) {
228
+ searchParams.set("encoding", this.encoding);
229
+ }
226
230
  url.search = searchParams.toString();
227
231
  return url;
228
232
  }
@@ -244,6 +248,7 @@
244
248
  headers: { Authorization: this.apiKey },
245
249
  });
246
250
  }
251
+ this.socket.binaryType = "arraybuffer";
247
252
  this.socket.onclose = ({ code, reason }) => {
248
253
  var _a, _b;
249
254
  if (!reason) {
@@ -303,19 +308,7 @@
303
308
  if (!this.socket || this.socket.readyState !== WebSocket$1.OPEN) {
304
309
  throw new Error("Socket is not open for communication");
305
310
  }
306
- let audioData;
307
- if (typeof Buffer !== "undefined") {
308
- audioData = Buffer.from(audio).toString("base64");
309
- }
310
- else {
311
- // Buffer is not available in the browser by default
312
- // https://stackoverflow.com/a/42334410/2919731
313
- audioData = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), ""));
314
- }
315
- const payload = {
316
- audio_data: audioData,
317
- };
318
- this.socket.send(JSON.stringify(payload));
311
+ this.socket.send(audio);
319
312
  }
320
313
  stream() {
321
314
  return new WritableStream({
@@ -356,12 +349,11 @@
356
349
  this.rtFactoryParams = params;
357
350
  }
358
351
  createService(params) {
359
- if (!params)
360
- params = { apiKey: this.rtFactoryParams.apiKey };
361
- else if (!("token" in params) && !params.apiKey) {
362
- params.apiKey = this.rtFactoryParams.apiKey;
352
+ const serviceParams = Object.assign({}, params);
353
+ if (!serviceParams.token && !serviceParams.apiKey) {
354
+ serviceParams.apiKey = this.rtFactoryParams.apiKey;
363
355
  }
364
- return new RealtimeService(params);
356
+ return new RealtimeService(serviceParams);
365
357
  }
366
358
  createTemporaryToken(params) {
367
359
  return __awaiter(this, void 0, void 0, function* () {
@@ -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";function t(e,t,s,o){return new(s||(s=Promise))((function(i,n){function r(e){try{c(o.next(e))}catch(e){n(e)}}function a(e){try{c(o.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,a)}c((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class s{constructor(e){this.params=e}fetch(e,s){var o;return t(this,void 0,void 0,(function*(){(s=null!=s?s:{}).headers=null!==(o=s.headers)&&void 0!==o?o:{},s.headers=Object.assign({Authorization:this.params.apiKey,"Content-Type":"application/json"},s.headers),e.startsWith("http")||(e=this.params.baseUrl+e);const t=yield fetch(e,s);if(t.status>=400){let e;const s=yield t.text();if(s){try{e=JSON.parse(s)}catch(e){}if(null==e?void 0:e.error)throw new Error(e.error);throw new Error(s)}throw new Error(`HTTP Error: ${t.status} ${t.statusText}`)}return t}))}fetchJson(e,s){return t(this,void 0,void 0,(function*(){return(yield this.fetch(e,s)).json()}))}}class o extends s{summary(e){return this.fetchJson("/lemur/v3/generate/summary",{method:"POST",body:JSON.stringify(e)})}questionAnswer(e){return this.fetchJson("/lemur/v3/generate/question-answer",{method:"POST",body:JSON.stringify(e)})}actionItems(e){return this.fetchJson("/lemur/v3/generate/action-items",{method:"POST",body:JSON.stringify(e)})}task(e){return this.fetchJson("/lemur/v3/generate/task",{method:"POST",body:JSON.stringify(e)})}purgeRequestData(e){return this.fetchJson(`/lemur/v3/${e}`,{method:"DELETE"})}}const{WritableStream:i}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var n=null;"undefined"!=typeof WebSocket?n=WebSocket:"undefined"!=typeof MozWebSocket?n=MozWebSocket:"undefined"!=typeof global?n=global.WebSocket||global.MozWebSocket:"undefined"!=typeof window?n=window.WebSocket||window.MozWebSocket:"undefined"!=typeof self&&(n=self.WebSocket||self.MozWebSocket);var r,a=n;!function(e){e[e.BadSampleRate=4e3]="BadSampleRate",e[e.AuthFailed=4001]="AuthFailed",e[e.InsufficientFundsOrFreeAccount=4002]="InsufficientFundsOrFreeAccount",e[e.NonexistentSessionId=4004]="NonexistentSessionId",e[e.SessionExpired=4008]="SessionExpired",e[e.ClosedSession=4010]="ClosedSession",e[e.RateLimited=4029]="RateLimited",e[e.UniqueSessionViolation=4030]="UniqueSessionViolation",e[e.SessionTimeout=4031]="SessionTimeout",e[e.AudioTooShort=4032]="AudioTooShort",e[e.AudioTooLong=4033]="AudioTooLong",e[e.BadJson=4100]="BadJson",e[e.BadSchema=4101]="BadSchema",e[e.TooManyStreams=4102]="TooManyStreams",e[e.Reconnected=4103]="Reconnected",e[e.ReconnectAttemptsExhausted=1013]="ReconnectAttemptsExhausted"}(r||(r={}));const c={[r.BadSampleRate]:"Sample rate must be a positive integer",[r.AuthFailed]:"Not Authorized",[r.InsufficientFundsOrFreeAccount]:"Insufficient funds or you are using a free account. This feature is paid-only and requires you to add a credit card. Please visit https://assemblyai.com/dashboard/ to add a credit card to your account.",[r.NonexistentSessionId]:"Session ID does not exist",[r.SessionExpired]:"Session has expired",[r.ClosedSession]:"Session is closed",[r.RateLimited]:"Rate limited",[r.UniqueSessionViolation]:"Unique session violation",[r.SessionTimeout]:"Session Timeout",[r.AudioTooShort]:"Audio too short",[r.AudioTooLong]:"Audio too long",[r.BadJson]:"Bad JSON",[r.BadSchema]:"Bad schema",[r.TooManyStreams]:"Too many streams",[r.Reconnected]:"Reconnected",[r.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class l extends Error{}class d{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,"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),"token"in e&&e.token&&(this.token=e.token),!this.apiKey&&!this.token)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)),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=new a(t.toString()):this.socket=new a(t.toString(),{headers:{Authorization:this.apiKey}}),this.socket.onclose=({code:e,reason:t})=>{var s,o;t||e in r&&(t=c[e]),null===(o=(s=this.listeners).close)||void 0===o||o.call(s,e,t)},this.socket.onerror=e=>{var t,s,o,i;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(i=(o=this.listeners).error)||void 0===i||i.call(o,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,o,i,n,r,a,c,d,u,h,f,p,m;const y=JSON.parse(t.toString());if("error"in y)null===(o=(s=this.listeners).error)||void 0===o||o.call(s,new l(y.error));else switch(y.message_type){case"SessionBegins":{const t={sessionId:y.session_id,expiresAt:new Date(y.expires_at)};e(t),null===(n=(i=this.listeners).open)||void 0===n||n.call(i,t);break}case"PartialTranscript":y.created=new Date(y.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,y),null===(d=(c=this.listeners)["transcript.partial"])||void 0===d||d.call(c,y);break;case"FinalTranscript":y.created=new Date(y.created),null===(h=(u=this.listeners).transcript)||void 0===h||h.call(u,y),null===(p=(f=this.listeners)["transcript.final"])||void 0===p||p.call(f,y);break;case"SessionTerminated":null===(m=this.sessionTerminatedResolve)||void 0===m||m.call(this)}}}))}sendAudio(e){if(!this.socket||this.socket.readyState!==a.OPEN)throw new Error("Socket is not open for communication");let t;t="undefined"!=typeof Buffer?Buffer.from(e).toString("base64"):btoa(new Uint8Array(e).reduce(((e,t)=>e+String.fromCharCode(t)),""));const s={audio_data:t};this.socket.send(JSON.stringify(s))}stream(){return new i({write:e=>{this.sendAudio(e)}})}close(e=!0){return t(this,void 0,void 0,(function*(){if(this.socket){if(this.socket.readyState===a.OPEN){const t='{"terminate_session": true}';if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(t),yield e}else this.socket.send(t)}"removeAllListeners"in this.socket&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class u extends s{constructor(e){super(e),this.rtFactoryParams=e}createService(e){return e?"token"in e||e.apiKey||(e.apiKey=this.rtFactoryParams.apiKey):e={apiKey:this.rtFactoryParams.apiKey},new d(e)}createTemporaryToken(e){return t(this,void 0,void 0,(function*(){return(yield this.fetchJson("/v2/realtime/token",{method:"POST",body:JSON.stringify(e)})).token}))}}class h extends s{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){const t=yield this.submit(e);return yield this.waitUntilReady(t.id,s)}))}submit(e){return t(this,void 0,void 0,(function*(){const{audio:t}=e,s=function(e,t){var s={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(s[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(e);i<o.length;i++)t.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(s[o[i]]=e[o[i]])}return s}(e,["audio"]);let o;if("string"==typeof t){const e=f(t);o=null!==e?yield this.files.upload(e):t}else o=yield this.files.upload(t);return yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(Object.assign(Object.assign({},s),{audio_url:o}))})}))}create(e,s){var o;return t(this,void 0,void 0,(function*(){const t=f(e.audio_url);if(null!==t){const s=yield this.files.upload(t);e.audio_url=s}const i=yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(e)});return null===(o=null==s?void 0:s.poll)||void 0===o||o?yield this.waitUntilReady(i.id,s):i}))}waitUntilReady(e,s){var o,i;return t(this,void 0,void 0,(function*(){const t=null!==(o=null==s?void 0:s.pollingInterval)&&void 0!==o?o:3e3,n=null!==(i=null==s?void 0:s.pollingTimeout)&&void 0!==i?i:-1,r=Date.now();for(;;){const s=yield this.get(e);if("completed"===s.status||"error"===s.status)return s;if(n>0&&Date.now()-r>n)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,t)))}}))}get(e){return this.fetchJson(`/v2/transcript/${e}`)}list(e){return t(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,s="srt",o){return t(this,void 0,void 0,(function*(){let t=`/v2/transcript/${e}/${s}`;if(o){const e=new URLSearchParams;e.set("chars_per_caption",o.toString()),t+=`?${e.toString()}`}const i=yield this.fetch(t);return yield i.text()}))}redactions(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}}function f(e){let t;try{return t=new URL(e),"file:"===t.protocol?t.pathname:null}catch(t){return e}}class p extends s{upload(e){return t(this,void 0,void 0,(function*(){let s;s="string"==typeof e?yield function(e){return t(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:s,headers:{"Content-Type":"application/octet-stream"},duplex:"half"})).upload_url}))}}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 p(e),this.transcripts=new h(e,this.files),this.lemur=new o(e),this.realtime=new u(e)}},e.FileService=p,e.LemurService=o,e.RealtimeService=d,e.RealtimeServiceFactory=u,e.TranscriptService=h}));
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";function t(e,t,s,i){return new(s||(s=Promise))((function(o,n){function r(e){try{c(i.next(e))}catch(e){n(e)}}function a(e){try{c(i.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,a)}c((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class s{constructor(e){this.params=e}fetch(e,s){var i;return t(this,void 0,void 0,(function*(){(s=null!=s?s:{}).headers=null!==(i=s.headers)&&void 0!==i?i:{},s.headers=Object.assign({Authorization:this.params.apiKey,"Content-Type":"application/json"},s.headers),e.startsWith("http")||(e=this.params.baseUrl+e);const t=yield fetch(e,s);if(t.status>=400){let e;const s=yield t.text();if(s){try{e=JSON.parse(s)}catch(e){}if(null==e?void 0:e.error)throw new Error(e.error);throw new Error(s)}throw new Error(`HTTP Error: ${t.status} ${t.statusText}`)}return t}))}fetchJson(e,s){return t(this,void 0,void 0,(function*(){return(yield this.fetch(e,s)).json()}))}}class i extends s{summary(e){return this.fetchJson("/lemur/v3/generate/summary",{method:"POST",body:JSON.stringify(e)})}questionAnswer(e){return this.fetchJson("/lemur/v3/generate/question-answer",{method:"POST",body:JSON.stringify(e)})}actionItems(e){return this.fetchJson("/lemur/v3/generate/action-items",{method:"POST",body:JSON.stringify(e)})}task(e){return this.fetchJson("/lemur/v3/generate/task",{method:"POST",body:JSON.stringify(e)})}purgeRequestData(e){return this.fetchJson(`/lemur/v3/${e}`,{method:"DELETE"})}}const{WritableStream:o}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var n=null;"undefined"!=typeof WebSocket?n=WebSocket:"undefined"!=typeof MozWebSocket?n=MozWebSocket:"undefined"!=typeof global?n=global.WebSocket||global.MozWebSocket:"undefined"!=typeof window?n=window.WebSocket||window.MozWebSocket:"undefined"!=typeof self&&(n=self.WebSocket||self.MozWebSocket);var r,a=n;!function(e){e[e.BadSampleRate=4e3]="BadSampleRate",e[e.AuthFailed=4001]="AuthFailed",e[e.InsufficientFundsOrFreeAccount=4002]="InsufficientFundsOrFreeAccount",e[e.NonexistentSessionId=4004]="NonexistentSessionId",e[e.SessionExpired=4008]="SessionExpired",e[e.ClosedSession=4010]="ClosedSession",e[e.RateLimited=4029]="RateLimited",e[e.UniqueSessionViolation=4030]="UniqueSessionViolation",e[e.SessionTimeout=4031]="SessionTimeout",e[e.AudioTooShort=4032]="AudioTooShort",e[e.AudioTooLong=4033]="AudioTooLong",e[e.BadJson=4100]="BadJson",e[e.BadSchema=4101]="BadSchema",e[e.TooManyStreams=4102]="TooManyStreams",e[e.Reconnected=4103]="Reconnected",e[e.ReconnectAttemptsExhausted=1013]="ReconnectAttemptsExhausted"}(r||(r={}));const c={[r.BadSampleRate]:"Sample rate must be a positive integer",[r.AuthFailed]:"Not Authorized",[r.InsufficientFundsOrFreeAccount]:"Insufficient funds or you are using a free account. This feature is paid-only and requires you to add a credit card. Please visit https://assemblyai.com/dashboard/ to add a credit card to your account.",[r.NonexistentSessionId]:"Session ID does not exist",[r.SessionExpired]:"Session has expired",[r.ClosedSession]:"Session is closed",[r.RateLimited]:"Rate limited",[r.UniqueSessionViolation]:"Unique session violation",[r.SessionTimeout]:"Session Timeout",[r.AudioTooShort]:"Audio too short",[r.AudioTooLong]:"Audio too long",[r.BadJson]:"Bad JSON",[r.BadSchema]:"Bad schema",[r.TooManyStreams]:"Too many streams",[r.Reconnected]:"Reconnected",[r.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class l extends Error{}class d{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,"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),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=new a(t.toString()):this.socket=new a(t.toString(),{headers:{Authorization:this.apiKey}}),this.socket.binaryType="arraybuffer",this.socket.onclose=({code:e,reason:t})=>{var s,i;t||e in r&&(t=c[e]),null===(i=(s=this.listeners).close)||void 0===i||i.call(s,e,t)},this.socket.onerror=e=>{var t,s,i,o;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(o=(i=this.listeners).error)||void 0===o||o.call(i,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,i,o,n,r,a,c,d,u,h,f,p,m;const y=JSON.parse(t.toString());if("error"in y)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new l(y.error));else switch(y.message_type){case"SessionBegins":{const t={sessionId:y.session_id,expiresAt:new Date(y.expires_at)};e(t),null===(n=(o=this.listeners).open)||void 0===n||n.call(o,t);break}case"PartialTranscript":y.created=new Date(y.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,y),null===(d=(c=this.listeners)["transcript.partial"])||void 0===d||d.call(c,y);break;case"FinalTranscript":y.created=new Date(y.created),null===(h=(u=this.listeners).transcript)||void 0===h||h.call(u,y),null===(p=(f=this.listeners)["transcript.final"])||void 0===p||p.call(f,y);break;case"SessionTerminated":null===(m=this.sessionTerminatedResolve)||void 0===m||m.call(this)}}}))}sendAudio(e){if(!this.socket||this.socket.readyState!==a.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}stream(){return new o({write:e=>{this.sendAudio(e)}})}close(e=!0){return t(this,void 0,void 0,(function*(){if(this.socket){if(this.socket.readyState===a.OPEN){const t='{"terminate_session": true}';if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(t),yield e}else this.socket.send(t)}"removeAllListeners"in this.socket&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class u extends s{constructor(e){super(e),this.rtFactoryParams=e}createService(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.rtFactoryParams.apiKey),new d(t)}createTemporaryToken(e){return t(this,void 0,void 0,(function*(){return(yield this.fetchJson("/v2/realtime/token",{method:"POST",body:JSON.stringify(e)})).token}))}}class h extends s{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){const t=yield this.submit(e);return yield this.waitUntilReady(t.id,s)}))}submit(e){return t(this,void 0,void 0,(function*(){const{audio:t}=e,s=function(e,t){var s={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(s[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(e);o<i.length;o++)t.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(s[i[o]]=e[i[o]])}return s}(e,["audio"]);let i;if("string"==typeof t){const e=f(t);i=null!==e?yield this.files.upload(e):t}else i=yield this.files.upload(t);return yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(Object.assign(Object.assign({},s),{audio_url:i}))})}))}create(e,s){var i;return t(this,void 0,void 0,(function*(){const t=f(e.audio_url);if(null!==t){const s=yield this.files.upload(t);e.audio_url=s}const o=yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(e)});return null===(i=null==s?void 0:s.poll)||void 0===i||i?yield this.waitUntilReady(o.id,s):o}))}waitUntilReady(e,s){var i,o;return t(this,void 0,void 0,(function*(){const t=null!==(i=null==s?void 0:s.pollingInterval)&&void 0!==i?i:3e3,n=null!==(o=null==s?void 0:s.pollingTimeout)&&void 0!==o?o:-1,r=Date.now();for(;;){const s=yield this.get(e);if("completed"===s.status||"error"===s.status)return s;if(n>0&&Date.now()-r>n)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,t)))}}))}get(e){return this.fetchJson(`/v2/transcript/${e}`)}list(e){return t(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,s="srt",i){return t(this,void 0,void 0,(function*(){let t=`/v2/transcript/${e}/${s}`;if(i){const e=new URLSearchParams;e.set("chars_per_caption",i.toString()),t+=`?${e.toString()}`}const o=yield this.fetch(t);return yield o.text()}))}redactions(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}}function f(e){let t;try{return t=new URL(e),"file:"===t.protocol?t.pathname:null}catch(t){return e}}class p extends s{upload(e){return t(this,void 0,void 0,(function*(){let s;s="string"==typeof e?yield function(e){return t(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:s,headers:{"Content-Type":"application/octet-stream"},duplex:"half"})).upload_url}))}}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 p(e),this.transcripts=new h(e,this.files),this.lemur=new i(e),this.realtime=new u(e)}},e.FileService=p,e.LemurService=i,e.RealtimeService=d,e.RealtimeServiceFactory=u,e.TranscriptService=h}));
package/dist/bun.mjs CHANGED
@@ -136,11 +136,12 @@ class RealtimeService {
136
136
  this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
137
137
  this.sampleRate = params.sampleRate ?? 16000;
138
138
  this.wordBoost = params.wordBoost;
139
- if ("apiKey" in params && params.apiKey)
140
- this.apiKey = params.apiKey;
139
+ this.encoding = params.encoding;
141
140
  if ("token" in params && params.token)
142
141
  this.token = params.token;
143
- if (!(this.apiKey || this.token)) {
142
+ if ("apiKey" in params && params.apiKey)
143
+ this.apiKey = params.apiKey;
144
+ if (!(this.token || this.apiKey)) {
144
145
  throw new Error("API key or temporary token is required.");
145
146
  }
146
147
  }
@@ -157,6 +158,9 @@ class RealtimeService {
157
158
  if (this.wordBoost && this.wordBoost.length > 0) {
158
159
  searchParams.set("word_boost", JSON.stringify(this.wordBoost));
159
160
  }
161
+ if (this.encoding) {
162
+ searchParams.set("encoding", this.encoding);
163
+ }
160
164
  url.search = searchParams.toString();
161
165
  return url;
162
166
  }
@@ -178,6 +182,7 @@ class RealtimeService {
178
182
  headers: { Authorization: this.apiKey },
179
183
  });
180
184
  }
185
+ this.socket.binaryType = "arraybuffer";
181
186
  this.socket.onclose = ({ code, reason }) => {
182
187
  if (!reason) {
183
188
  if (code in RealtimeErrorType) {
@@ -234,19 +239,7 @@ class RealtimeService {
234
239
  if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
235
240
  throw new Error("Socket is not open for communication");
236
241
  }
237
- let audioData;
238
- if (typeof Buffer !== "undefined") {
239
- audioData = Buffer.from(audio).toString("base64");
240
- }
241
- else {
242
- // Buffer is not available in the browser by default
243
- // https://stackoverflow.com/a/42334410/2919731
244
- audioData = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), ""));
245
- }
246
- const payload = {
247
- audio_data: audioData,
248
- };
249
- this.socket.send(JSON.stringify(payload));
242
+ this.socket.send(audio);
250
243
  }
251
244
  stream() {
252
245
  return new WritableStream({
@@ -285,12 +278,11 @@ class RealtimeServiceFactory extends BaseService {
285
278
  this.rtFactoryParams = params;
286
279
  }
287
280
  createService(params) {
288
- if (!params)
289
- params = { apiKey: this.rtFactoryParams.apiKey };
290
- else if (!("token" in params) && !params.apiKey) {
291
- params.apiKey = this.rtFactoryParams.apiKey;
281
+ const serviceParams = { ...params };
282
+ if (!serviceParams.token && !serviceParams.apiKey) {
283
+ serviceParams.apiKey = this.rtFactoryParams.apiKey;
292
284
  }
293
- return new RealtimeService(params);
285
+ return new RealtimeService(serviceParams);
294
286
  }
295
287
  async createTemporaryToken(params) {
296
288
  const data = await this.fetchJson("/v2/realtime/token", {
package/dist/deno.mjs CHANGED
@@ -136,11 +136,12 @@ class RealtimeService {
136
136
  this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
137
137
  this.sampleRate = params.sampleRate ?? 16000;
138
138
  this.wordBoost = params.wordBoost;
139
- if ("apiKey" in params && params.apiKey)
140
- this.apiKey = params.apiKey;
139
+ this.encoding = params.encoding;
141
140
  if ("token" in params && params.token)
142
141
  this.token = params.token;
143
- if (!(this.apiKey || this.token)) {
142
+ if ("apiKey" in params && params.apiKey)
143
+ this.apiKey = params.apiKey;
144
+ if (!(this.token || this.apiKey)) {
144
145
  throw new Error("API key or temporary token is required.");
145
146
  }
146
147
  }
@@ -157,6 +158,9 @@ class RealtimeService {
157
158
  if (this.wordBoost && this.wordBoost.length > 0) {
158
159
  searchParams.set("word_boost", JSON.stringify(this.wordBoost));
159
160
  }
161
+ if (this.encoding) {
162
+ searchParams.set("encoding", this.encoding);
163
+ }
160
164
  url.search = searchParams.toString();
161
165
  return url;
162
166
  }
@@ -178,6 +182,7 @@ class RealtimeService {
178
182
  headers: { Authorization: this.apiKey },
179
183
  });
180
184
  }
185
+ this.socket.binaryType = "arraybuffer";
181
186
  this.socket.onclose = ({ code, reason }) => {
182
187
  if (!reason) {
183
188
  if (code in RealtimeErrorType) {
@@ -234,19 +239,7 @@ class RealtimeService {
234
239
  if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
235
240
  throw new Error("Socket is not open for communication");
236
241
  }
237
- let audioData;
238
- if (typeof Buffer !== "undefined") {
239
- audioData = Buffer.from(audio).toString("base64");
240
- }
241
- else {
242
- // Buffer is not available in the browser by default
243
- // https://stackoverflow.com/a/42334410/2919731
244
- audioData = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), ""));
245
- }
246
- const payload = {
247
- audio_data: audioData,
248
- };
249
- this.socket.send(JSON.stringify(payload));
242
+ this.socket.send(audio);
250
243
  }
251
244
  stream() {
252
245
  return new WritableStream({
@@ -285,12 +278,11 @@ class RealtimeServiceFactory extends BaseService {
285
278
  this.rtFactoryParams = params;
286
279
  }
287
280
  createService(params) {
288
- if (!params)
289
- params = { apiKey: this.rtFactoryParams.apiKey };
290
- else if (!("token" in params) && !params.apiKey) {
291
- params.apiKey = this.rtFactoryParams.apiKey;
281
+ const serviceParams = { ...params };
282
+ if (!serviceParams.token && !serviceParams.apiKey) {
283
+ serviceParams.apiKey = this.rtFactoryParams.apiKey;
292
284
  }
293
- return new RealtimeService(params);
285
+ return new RealtimeService(serviceParams);
294
286
  }
295
287
  async createTemporaryToken(params) {
296
288
  const data = await this.fetchJson("/v2/realtime/token", {
package/dist/index.cjs CHANGED
@@ -184,11 +184,12 @@ class RealtimeService {
184
184
  this.realtimeUrl = (_a = params.realtimeUrl) !== null && _a !== void 0 ? _a : defaultRealtimeUrl;
185
185
  this.sampleRate = (_b = params.sampleRate) !== null && _b !== void 0 ? _b : 16000;
186
186
  this.wordBoost = params.wordBoost;
187
- if ("apiKey" in params && params.apiKey)
188
- this.apiKey = params.apiKey;
187
+ this.encoding = params.encoding;
189
188
  if ("token" in params && params.token)
190
189
  this.token = params.token;
191
- if (!(this.apiKey || this.token)) {
190
+ if ("apiKey" in params && params.apiKey)
191
+ this.apiKey = params.apiKey;
192
+ if (!(this.token || this.apiKey)) {
192
193
  throw new Error("API key or temporary token is required.");
193
194
  }
194
195
  }
@@ -205,6 +206,9 @@ class RealtimeService {
205
206
  if (this.wordBoost && this.wordBoost.length > 0) {
206
207
  searchParams.set("word_boost", JSON.stringify(this.wordBoost));
207
208
  }
209
+ if (this.encoding) {
210
+ searchParams.set("encoding", this.encoding);
211
+ }
208
212
  url.search = searchParams.toString();
209
213
  return url;
210
214
  }
@@ -226,6 +230,7 @@ class RealtimeService {
226
230
  headers: { Authorization: this.apiKey },
227
231
  });
228
232
  }
233
+ this.socket.binaryType = "arraybuffer";
229
234
  this.socket.onclose = ({ code, reason }) => {
230
235
  var _a, _b;
231
236
  if (!reason) {
@@ -285,19 +290,7 @@ class RealtimeService {
285
290
  if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
286
291
  throw new Error("Socket is not open for communication");
287
292
  }
288
- let audioData;
289
- if (typeof Buffer !== "undefined") {
290
- audioData = Buffer.from(audio).toString("base64");
291
- }
292
- else {
293
- // Buffer is not available in the browser by default
294
- // https://stackoverflow.com/a/42334410/2919731
295
- audioData = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), ""));
296
- }
297
- const payload = {
298
- audio_data: audioData,
299
- };
300
- this.socket.send(JSON.stringify(payload));
293
+ this.socket.send(audio);
301
294
  }
302
295
  stream() {
303
296
  return new WritableStream({
@@ -338,12 +331,11 @@ class RealtimeServiceFactory extends BaseService {
338
331
  this.rtFactoryParams = params;
339
332
  }
340
333
  createService(params) {
341
- if (!params)
342
- params = { apiKey: this.rtFactoryParams.apiKey };
343
- else if (!("token" in params) && !params.apiKey) {
344
- params.apiKey = this.rtFactoryParams.apiKey;
334
+ const serviceParams = Object.assign({}, params);
335
+ if (!serviceParams.token && !serviceParams.apiKey) {
336
+ serviceParams.apiKey = this.rtFactoryParams.apiKey;
345
337
  }
346
- return new RealtimeService(params);
338
+ return new RealtimeService(serviceParams);
347
339
  }
348
340
  createTemporaryToken(params) {
349
341
  return __awaiter(this, void 0, void 0, function* () {
package/dist/index.mjs CHANGED
@@ -182,11 +182,12 @@ class RealtimeService {
182
182
  this.realtimeUrl = (_a = params.realtimeUrl) !== null && _a !== void 0 ? _a : defaultRealtimeUrl;
183
183
  this.sampleRate = (_b = params.sampleRate) !== null && _b !== void 0 ? _b : 16000;
184
184
  this.wordBoost = params.wordBoost;
185
- if ("apiKey" in params && params.apiKey)
186
- this.apiKey = params.apiKey;
185
+ this.encoding = params.encoding;
187
186
  if ("token" in params && params.token)
188
187
  this.token = params.token;
189
- if (!(this.apiKey || this.token)) {
188
+ if ("apiKey" in params && params.apiKey)
189
+ this.apiKey = params.apiKey;
190
+ if (!(this.token || this.apiKey)) {
190
191
  throw new Error("API key or temporary token is required.");
191
192
  }
192
193
  }
@@ -203,6 +204,9 @@ class RealtimeService {
203
204
  if (this.wordBoost && this.wordBoost.length > 0) {
204
205
  searchParams.set("word_boost", JSON.stringify(this.wordBoost));
205
206
  }
207
+ if (this.encoding) {
208
+ searchParams.set("encoding", this.encoding);
209
+ }
206
210
  url.search = searchParams.toString();
207
211
  return url;
208
212
  }
@@ -224,6 +228,7 @@ class RealtimeService {
224
228
  headers: { Authorization: this.apiKey },
225
229
  });
226
230
  }
231
+ this.socket.binaryType = "arraybuffer";
227
232
  this.socket.onclose = ({ code, reason }) => {
228
233
  var _a, _b;
229
234
  if (!reason) {
@@ -283,19 +288,7 @@ class RealtimeService {
283
288
  if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
284
289
  throw new Error("Socket is not open for communication");
285
290
  }
286
- let audioData;
287
- if (typeof Buffer !== "undefined") {
288
- audioData = Buffer.from(audio).toString("base64");
289
- }
290
- else {
291
- // Buffer is not available in the browser by default
292
- // https://stackoverflow.com/a/42334410/2919731
293
- audioData = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), ""));
294
- }
295
- const payload = {
296
- audio_data: audioData,
297
- };
298
- this.socket.send(JSON.stringify(payload));
291
+ this.socket.send(audio);
299
292
  }
300
293
  stream() {
301
294
  return new WritableStream({
@@ -336,12 +329,11 @@ class RealtimeServiceFactory extends BaseService {
336
329
  this.rtFactoryParams = params;
337
330
  }
338
331
  createService(params) {
339
- if (!params)
340
- params = { apiKey: this.rtFactoryParams.apiKey };
341
- else if (!("token" in params) && !params.apiKey) {
342
- params.apiKey = this.rtFactoryParams.apiKey;
332
+ const serviceParams = Object.assign({}, params);
333
+ if (!serviceParams.token && !serviceParams.apiKey) {
334
+ serviceParams.apiKey = this.rtFactoryParams.apiKey;
343
335
  }
344
- return new RealtimeService(params);
336
+ return new RealtimeService(serviceParams);
345
337
  }
346
338
  createTemporaryToken(params) {
347
339
  return __awaiter(this, void 0, void 0, function* () {
package/dist/node.cjs CHANGED
@@ -135,11 +135,12 @@ class RealtimeService {
135
135
  this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
136
136
  this.sampleRate = params.sampleRate ?? 16000;
137
137
  this.wordBoost = params.wordBoost;
138
- if ("apiKey" in params && params.apiKey)
139
- this.apiKey = params.apiKey;
138
+ this.encoding = params.encoding;
140
139
  if ("token" in params && params.token)
141
140
  this.token = params.token;
142
- if (!(this.apiKey || this.token)) {
141
+ if ("apiKey" in params && params.apiKey)
142
+ this.apiKey = params.apiKey;
143
+ if (!(this.token || this.apiKey)) {
143
144
  throw new Error("API key or temporary token is required.");
144
145
  }
145
146
  }
@@ -156,6 +157,9 @@ class RealtimeService {
156
157
  if (this.wordBoost && this.wordBoost.length > 0) {
157
158
  searchParams.set("word_boost", JSON.stringify(this.wordBoost));
158
159
  }
160
+ if (this.encoding) {
161
+ searchParams.set("encoding", this.encoding);
162
+ }
159
163
  url.search = searchParams.toString();
160
164
  return url;
161
165
  }
@@ -177,6 +181,7 @@ class RealtimeService {
177
181
  headers: { Authorization: this.apiKey },
178
182
  });
179
183
  }
184
+ this.socket.binaryType = "arraybuffer";
180
185
  this.socket.onclose = ({ code, reason }) => {
181
186
  if (!reason) {
182
187
  if (code in RealtimeErrorType) {
@@ -233,19 +238,7 @@ class RealtimeService {
233
238
  if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
234
239
  throw new Error("Socket is not open for communication");
235
240
  }
236
- let audioData;
237
- if (typeof Buffer !== "undefined") {
238
- audioData = Buffer.from(audio).toString("base64");
239
- }
240
- else {
241
- // Buffer is not available in the browser by default
242
- // https://stackoverflow.com/a/42334410/2919731
243
- audioData = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), ""));
244
- }
245
- const payload = {
246
- audio_data: audioData,
247
- };
248
- this.socket.send(JSON.stringify(payload));
241
+ this.socket.send(audio);
249
242
  }
250
243
  stream() {
251
244
  return new web.WritableStream({
@@ -284,12 +277,11 @@ class RealtimeServiceFactory extends BaseService {
284
277
  this.rtFactoryParams = params;
285
278
  }
286
279
  createService(params) {
287
- if (!params)
288
- params = { apiKey: this.rtFactoryParams.apiKey };
289
- else if (!("token" in params) && !params.apiKey) {
290
- params.apiKey = this.rtFactoryParams.apiKey;
280
+ const serviceParams = { ...params };
281
+ if (!serviceParams.token && !serviceParams.apiKey) {
282
+ serviceParams.apiKey = this.rtFactoryParams.apiKey;
291
283
  }
292
- return new RealtimeService(params);
284
+ return new RealtimeService(serviceParams);
293
285
  }
294
286
  async createTemporaryToken(params) {
295
287
  const data = await this.fetchJson("/v2/realtime/token", {
package/dist/node.mjs CHANGED
@@ -133,11 +133,12 @@ class RealtimeService {
133
133
  this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
134
134
  this.sampleRate = params.sampleRate ?? 16000;
135
135
  this.wordBoost = params.wordBoost;
136
- if ("apiKey" in params && params.apiKey)
137
- this.apiKey = params.apiKey;
136
+ this.encoding = params.encoding;
138
137
  if ("token" in params && params.token)
139
138
  this.token = params.token;
140
- if (!(this.apiKey || this.token)) {
139
+ if ("apiKey" in params && params.apiKey)
140
+ this.apiKey = params.apiKey;
141
+ if (!(this.token || this.apiKey)) {
141
142
  throw new Error("API key or temporary token is required.");
142
143
  }
143
144
  }
@@ -154,6 +155,9 @@ class RealtimeService {
154
155
  if (this.wordBoost && this.wordBoost.length > 0) {
155
156
  searchParams.set("word_boost", JSON.stringify(this.wordBoost));
156
157
  }
158
+ if (this.encoding) {
159
+ searchParams.set("encoding", this.encoding);
160
+ }
157
161
  url.search = searchParams.toString();
158
162
  return url;
159
163
  }
@@ -175,6 +179,7 @@ class RealtimeService {
175
179
  headers: { Authorization: this.apiKey },
176
180
  });
177
181
  }
182
+ this.socket.binaryType = "arraybuffer";
178
183
  this.socket.onclose = ({ code, reason }) => {
179
184
  if (!reason) {
180
185
  if (code in RealtimeErrorType) {
@@ -231,19 +236,7 @@ class RealtimeService {
231
236
  if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
232
237
  throw new Error("Socket is not open for communication");
233
238
  }
234
- let audioData;
235
- if (typeof Buffer !== "undefined") {
236
- audioData = Buffer.from(audio).toString("base64");
237
- }
238
- else {
239
- // Buffer is not available in the browser by default
240
- // https://stackoverflow.com/a/42334410/2919731
241
- audioData = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), ""));
242
- }
243
- const payload = {
244
- audio_data: audioData,
245
- };
246
- this.socket.send(JSON.stringify(payload));
239
+ this.socket.send(audio);
247
240
  }
248
241
  stream() {
249
242
  return new WritableStream({
@@ -282,12 +275,11 @@ class RealtimeServiceFactory extends BaseService {
282
275
  this.rtFactoryParams = params;
283
276
  }
284
277
  createService(params) {
285
- if (!params)
286
- params = { apiKey: this.rtFactoryParams.apiKey };
287
- else if (!("token" in params) && !params.apiKey) {
288
- params.apiKey = this.rtFactoryParams.apiKey;
278
+ const serviceParams = { ...params };
279
+ if (!serviceParams.token && !serviceParams.apiKey) {
280
+ serviceParams.apiKey = this.rtFactoryParams.apiKey;
289
281
  }
290
- return new RealtimeService(params);
282
+ return new RealtimeService(serviceParams);
291
283
  }
292
284
  async createTemporaryToken(params) {
293
285
  const data = await this.fetchJson("/v2/realtime/token", {
@@ -1,2 +1 @@
1
- /// <reference types="node" />
2
1
  export { WritableStream } from "stream/web";
@@ -3,6 +3,7 @@ export declare class RealtimeService {
3
3
  private realtimeUrl;
4
4
  private sampleRate;
5
5
  private wordBoost?;
6
+ private encoding?;
6
7
  private apiKey?;
7
8
  private token?;
8
9
  private socket?;
@@ -2,6 +2,12 @@ export type AudioData = {
2
2
  /** @description Base64 encoded raw audio data */
3
3
  audio_data: string;
4
4
  };
5
+ /**
6
+ * @description The encoding of the audio data
7
+ * @default pcm_s16le
8
+ * @enum {string}
9
+ */
10
+ export type AudioEncoding = "pcm_s16le" | "pcm_mulaw";
5
11
  export type FinalTranscript = RealtimeBaseTranscript & {
6
12
  /**
7
13
  * @description Describes the type of message
@@ -0,0 +1 @@
1
+ export type LiteralUnion<LiteralType, BaseType> = LiteralType | (BaseType & Record<never, never>);
@@ -1,3 +1,4 @@
1
+ import { LiteralUnion } from "./helpers";
1
2
  /** OneOf type helpers */
2
3
  type Without<T, U> = {
3
4
  [P in Exclude<keyof T, keyof U>]?: never;
@@ -459,7 +460,13 @@ export type LemurBaseParams = {
459
460
  [key: string]: unknown;
460
461
  }
461
462
  ]>;
462
- final_model?: LemurModel;
463
+ /**
464
+ * @description The model that is used for the final prompt after compression is performed.
465
+ * Defaults to "default".
466
+ *
467
+ * @default default
468
+ */
469
+ final_model?: LiteralUnion<LemurModel, string>;
463
470
  /**
464
471
  * @description Custom formatted transcript data. Maximum size is the context limit of the selected model, which defaults to 100000.
465
472
  * Use either transcript_ids or input_text as input into LeMUR.
@@ -497,7 +504,7 @@ export type LemurBaseResponse = {
497
504
  *
498
505
  * @enum {string}
499
506
  */
500
- export type LemurModel = "default" | "basic" | "assemblyai/mistral-7b";
507
+ export type LemurModel = "default" | "basic" | "assemblyai/mistral-7b" | "anthropic/claude-2-1";
501
508
  /**
502
509
  * @example {
503
510
  * "question": "Where are there wildfires?",
@@ -2156,6 +2163,8 @@ export type TranscriptOptionalParams = {
2156
2163
  boost_param?: TranscriptBoostParam;
2157
2164
  /** @description Enable [Content Moderation](https://www.assemblyai.com/docs/models/content-moderation), can be true or false */
2158
2165
  content_safety?: boolean;
2166
+ /** @description The confidence threshold for content moderation. Values must be between 25 and 100. */
2167
+ content_safety_confidence?: number;
2159
2168
  /** @description Customize how words are spelled and formatted using to and from values */
2160
2169
  custom_spelling?: TranscriptCustomSpelling[];
2161
2170
  /** @description Whether custom topics is enabled, either true or false */
@@ -1,8 +1,9 @@
1
- import { FinalTranscript, PartialTranscript, RealtimeTranscript, RealtimeTranscriptType } from "../asyncapi.generated";
1
+ import { AudioEncoding, FinalTranscript, PartialTranscript, RealtimeTranscript, RealtimeTranscriptType } from "../asyncapi.generated";
2
2
  type CreateRealtimeServiceParams = {
3
3
  realtimeUrl?: string;
4
4
  sampleRate?: number;
5
5
  wordBoost?: string[];
6
+ encoding?: AudioEncoding;
6
7
  } & ({
7
8
  apiKey?: string;
8
9
  } | {
@@ -12,6 +13,7 @@ type RealtimeServiceParams = {
12
13
  realtimeUrl?: string;
13
14
  sampleRate?: number;
14
15
  wordBoost?: string[];
16
+ encoding?: AudioEncoding;
15
17
  } & ({
16
18
  apiKey: string;
17
19
  } | {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assemblyai",
3
- "version": "4.0.1",
3
+ "version": "4.2.0-beta.0",
4
4
  "description": "The AssemblyAI JavaScript SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription, as well as the latest LeMUR models.",
5
5
  "engines": {
6
6
  "node": ">=18"
@@ -61,7 +61,7 @@
61
61
  "url": "git+https://github.com/AssemblyAI/assemblyai-node-sdk.git"
62
62
  },
63
63
  "publishConfig": {
64
- "tag": "latest",
64
+ "tag": "beta",
65
65
  "access": "public",
66
66
  "registry": "https://registry.npmjs.org/"
67
67
  },
@@ -16,12 +16,12 @@ export class RealtimeServiceFactory extends BaseService {
16
16
  }
17
17
 
18
18
  createService(params?: CreateRealtimeServiceParams): RealtimeService {
19
- if (!params) params = { apiKey: this.rtFactoryParams.apiKey };
20
- else if (!("token" in params) && !params.apiKey) {
21
- params.apiKey = this.rtFactoryParams.apiKey;
19
+ const serviceParams = { ...params } as Record<string, unknown>;
20
+ if (!serviceParams.token && !serviceParams.apiKey) {
21
+ serviceParams.apiKey = this.rtFactoryParams.apiKey;
22
22
  }
23
23
 
24
- return new RealtimeService(params as RealtimeServiceParams);
24
+ return new RealtimeService(serviceParams as RealtimeServiceParams);
25
25
  }
26
26
 
27
27
  async createTemporaryToken(params: RealtimeTokenParams) {
@@ -10,6 +10,7 @@ import {
10
10
  PartialTranscript,
11
11
  FinalTranscript,
12
12
  SessionBeginsEventData,
13
+ AudioEncoding,
13
14
  } from "../..";
14
15
  import {
15
16
  RealtimeError,
@@ -23,6 +24,7 @@ export class RealtimeService {
23
24
  private realtimeUrl: string;
24
25
  private sampleRate: number;
25
26
  private wordBoost?: string[];
27
+ private encoding?: AudioEncoding;
26
28
  private apiKey?: string;
27
29
  private token?: string;
28
30
  private socket?: WebSocket;
@@ -33,10 +35,11 @@ export class RealtimeService {
33
35
  this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
34
36
  this.sampleRate = params.sampleRate ?? 16_000;
35
37
  this.wordBoost = params.wordBoost;
36
- if ("apiKey" in params && params.apiKey) this.apiKey = params.apiKey;
38
+ this.encoding = params.encoding;
37
39
  if ("token" in params && params.token) this.token = params.token;
40
+ if ("apiKey" in params && params.apiKey) this.apiKey = params.apiKey;
38
41
 
39
- if (!(this.apiKey || this.token)) {
42
+ if (!(this.token || this.apiKey)) {
40
43
  throw new Error("API key or temporary token is required.");
41
44
  }
42
45
  }
@@ -56,6 +59,9 @@ export class RealtimeService {
56
59
  if (this.wordBoost && this.wordBoost.length > 0) {
57
60
  searchParams.set("word_boost", JSON.stringify(this.wordBoost));
58
61
  }
62
+ if (this.encoding) {
63
+ searchParams.set("encoding", this.encoding);
64
+ }
59
65
  url.search = searchParams.toString();
60
66
 
61
67
  return url;
@@ -96,6 +102,7 @@ export class RealtimeService {
96
102
  headers: { Authorization: this.apiKey },
97
103
  });
98
104
  }
105
+ this.socket.binaryType = "arraybuffer";
99
106
 
100
107
  this.socket.onclose = ({ code, reason }: CloseEvent) => {
101
108
  if (!reason) {
@@ -154,23 +161,7 @@ export class RealtimeService {
154
161
  if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
155
162
  throw new Error("Socket is not open for communication");
156
163
  }
157
- let audioData;
158
- if (typeof Buffer !== "undefined") {
159
- audioData = Buffer.from(audio).toString("base64");
160
- } else {
161
- // Buffer is not available in the browser by default
162
- // https://stackoverflow.com/a/42334410/2919731
163
- audioData = btoa(
164
- new Uint8Array(audio).reduce(
165
- (data, byte) => data + String.fromCharCode(byte),
166
- ""
167
- )
168
- );
169
- }
170
- const payload = {
171
- audio_data: audioData,
172
- };
173
- this.socket.send(JSON.stringify(payload));
164
+ this.socket.send(audio);
174
165
  }
175
166
 
176
167
  stream(): WritableStream<ArrayBufferLike> {
@@ -2,6 +2,8 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
+ import { LiteralUnion } from "./helpers";
6
+
5
7
  /** OneOf type helpers */
6
8
  type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
7
9
  type XOR<T, U> = T | U extends object
@@ -18,6 +20,13 @@ export type AudioData = {
18
20
  audio_data: string;
19
21
  };
20
22
 
23
+ /**
24
+ * @description The encoding of the audio data
25
+ * @default pcm_s16le
26
+ * @enum {string}
27
+ */
28
+ export type AudioEncoding = "pcm_s16le" | "pcm_mulaw";
29
+
21
30
  export type FinalTranscript = RealtimeBaseTranscript & {
22
31
  /**
23
32
  * @description Describes the type of message
@@ -0,0 +1,4 @@
1
+ // source: https://github.com/sindresorhus/type-fest/blob/main/source/literal-union.d.ts
2
+ export type LiteralUnion<LiteralType, BaseType> =
3
+ | LiteralType
4
+ | (BaseType & Record<never, never>);
@@ -2,6 +2,8 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
+ import { LiteralUnion } from "./helpers";
6
+
5
7
  /** OneOf type helpers */
6
8
  type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
7
9
  type XOR<T, U> = T | U extends object
@@ -512,7 +514,13 @@ export type LemurBaseParams = {
512
514
  }
513
515
  ]
514
516
  >;
515
- final_model?: LemurModel;
517
+ /**
518
+ * @description The model that is used for the final prompt after compression is performed.
519
+ * Defaults to "default".
520
+ *
521
+ * @default default
522
+ */
523
+ final_model?: LiteralUnion<LemurModel, string>;
516
524
  /**
517
525
  * @description Custom formatted transcript data. Maximum size is the context limit of the selected model, which defaults to 100000.
518
526
  * Use either transcript_ids or input_text as input into LeMUR.
@@ -552,7 +560,11 @@ export type LemurBaseResponse = {
552
560
  *
553
561
  * @enum {string}
554
562
  */
555
- export type LemurModel = "default" | "basic" | "assemblyai/mistral-7b";
563
+ export type LemurModel =
564
+ | "default"
565
+ | "basic"
566
+ | "assemblyai/mistral-7b"
567
+ | "anthropic/claude-2-1";
556
568
 
557
569
  /**
558
570
  * @example {
@@ -2299,6 +2311,8 @@ export type TranscriptOptionalParams = {
2299
2311
  boost_param?: TranscriptBoostParam;
2300
2312
  /** @description Enable [Content Moderation](https://www.assemblyai.com/docs/models/content-moderation), can be true or false */
2301
2313
  content_safety?: boolean;
2314
+ /** @description The confidence threshold for content moderation. Values must be between 25 and 100. */
2315
+ content_safety_confidence?: number;
2302
2316
  /** @description Customize how words are spelled and formatted using to and from values */
2303
2317
  custom_spelling?: TranscriptCustomSpelling[];
2304
2318
  /** @description Whether custom topics is enabled, either true or false */
@@ -1,4 +1,5 @@
1
1
  import {
2
+ AudioEncoding,
2
3
  FinalTranscript,
3
4
  PartialTranscript,
4
5
  RealtimeTranscript,
@@ -9,6 +10,7 @@ type CreateRealtimeServiceParams = {
9
10
  realtimeUrl?: string;
10
11
  sampleRate?: number;
11
12
  wordBoost?: string[];
13
+ encoding?: AudioEncoding;
12
14
  } & (
13
15
  | {
14
16
  apiKey?: string;
@@ -22,6 +24,7 @@ type RealtimeServiceParams = {
22
24
  realtimeUrl?: string;
23
25
  sampleRate?: number;
24
26
  wordBoost?: string[];
27
+ encoding?: AudioEncoding;
25
28
  } & (
26
29
  | {
27
30
  apiKey: string;