assemblyai 4.4.3 → 4.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.4.5]
4
+
5
+ - Add new `PiiPolicy` enum values
6
+
7
+ ## [4.4.4]
8
+
9
+ - Add an export that only includes the Streaming STT code. You can use the export
10
+ - by importing `assemblyai/streaming`,
11
+ - or by loading the `assemblyai.streaming.umd.js` file, or `assemblyai.streaming.umd.min.js` file in a script-tag.
12
+ - Add new `EntityType` enum values
13
+
3
14
  ## [4.4.3] - 2024-05-09
4
15
 
5
16
  - Add react-native exports that resolve to the browser version of the library.
package/README.md CHANGED
@@ -59,9 +59,17 @@ You can use automatic CDNs like [UNPKG](https://unpkg.com/) to load the library
59
59
 
60
60
  - Replace `:version` with the desired version or `latest`.
61
61
  - Remove `.min` to load the non-minified version.
62
+ - Remove `.streaming` to load the entire SDK. Keep `.streaming` to load the Streaming STT specific version.
62
63
 
63
64
  ```html
65
+ <!-- Unminified full SDK -->
66
+ <script src="https://www.unpkg.com/assemblyai@:version/dist/assemblyai.umd.js"></script>
67
+ <!-- Minified full SDK -->
64
68
  <script src="https://www.unpkg.com/assemblyai@:version/dist/assemblyai.umd.min.js"></script>
69
+ <!-- Unminified Streaming STT only -->
70
+ <script src="https://www.unpkg.com/assemblyai@:version/dist/assemblyai.streaming.umd.js"></script>
71
+ <!-- Minified Streaming STT only -->
72
+ <script src="https://www.unpkg.com/assemblyai@:version/dist/assemblyai.streaming.umd.min.js"></script>
65
73
  ```
66
74
 
67
75
  The script creates a global `assemblyai` variable containing all the services.
@@ -264,7 +272,7 @@ const rt = client.realtime.transcriber({
264
272
  > _Client code_:
265
273
  >
266
274
  > ```typescript
267
- > import { RealtimeTranscriber } from "assemblyai";
275
+ > import { RealtimeTranscriber } from "assemblyai"; // or "assemblyai/streaming"
268
276
  > // TODO: implement getToken to retrieve token from server
269
277
  > const token = await getToken();
270
278
  > const rt = new RealtimeTranscriber({
@@ -0,0 +1,288 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.assemblyai = {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ /******************************************************************************
8
+ Copyright (c) Microsoft Corporation.
9
+
10
+ Permission to use, copy, modify, and/or distribute this software for any
11
+ purpose with or without fee is hereby granted.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19
+ PERFORMANCE OF THIS SOFTWARE.
20
+ ***************************************************************************** */
21
+ /* global Reflect, Promise, SuppressedError, Symbol */
22
+
23
+
24
+ function __awaiter(thisArg, _arguments, P, generator) {
25
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
26
+ return new (P || (P = Promise))(function (resolve, reject) {
27
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
28
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
29
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
30
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
31
+ });
32
+ }
33
+
34
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
35
+ var e = new Error(message);
36
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
37
+ };
38
+
39
+ const { WritableStream } = typeof window !== "undefined"
40
+ ? window
41
+ : typeof global !== "undefined"
42
+ ? global
43
+ : globalThis;
44
+
45
+ var _a, _b;
46
+ const PolyfillWebSocket = (_b = (_a = WebSocket !== null && WebSocket !== void 0 ? WebSocket : global === null || global === void 0 ? void 0 : global.WebSocket) !== null && _a !== void 0 ? _a : window === null || window === void 0 ? void 0 : window.WebSocket) !== null && _b !== void 0 ? _b : self === null || self === void 0 ? void 0 : self.WebSocket;
47
+ const factory = (url, params) => {
48
+ if (params) {
49
+ return new PolyfillWebSocket(url, params);
50
+ }
51
+ return new PolyfillWebSocket(url);
52
+ };
53
+
54
+ var RealtimeErrorType;
55
+ (function (RealtimeErrorType) {
56
+ RealtimeErrorType[RealtimeErrorType["BadSampleRate"] = 4000] = "BadSampleRate";
57
+ RealtimeErrorType[RealtimeErrorType["AuthFailed"] = 4001] = "AuthFailed";
58
+ // Both InsufficientFunds and FreeAccount error use 4002
59
+ RealtimeErrorType[RealtimeErrorType["InsufficientFundsOrFreeAccount"] = 4002] = "InsufficientFundsOrFreeAccount";
60
+ RealtimeErrorType[RealtimeErrorType["NonexistentSessionId"] = 4004] = "NonexistentSessionId";
61
+ RealtimeErrorType[RealtimeErrorType["SessionExpired"] = 4008] = "SessionExpired";
62
+ RealtimeErrorType[RealtimeErrorType["ClosedSession"] = 4010] = "ClosedSession";
63
+ RealtimeErrorType[RealtimeErrorType["RateLimited"] = 4029] = "RateLimited";
64
+ RealtimeErrorType[RealtimeErrorType["UniqueSessionViolation"] = 4030] = "UniqueSessionViolation";
65
+ RealtimeErrorType[RealtimeErrorType["SessionTimeout"] = 4031] = "SessionTimeout";
66
+ RealtimeErrorType[RealtimeErrorType["AudioTooShort"] = 4032] = "AudioTooShort";
67
+ RealtimeErrorType[RealtimeErrorType["AudioTooLong"] = 4033] = "AudioTooLong";
68
+ RealtimeErrorType[RealtimeErrorType["BadJson"] = 4100] = "BadJson";
69
+ RealtimeErrorType[RealtimeErrorType["BadSchema"] = 4101] = "BadSchema";
70
+ RealtimeErrorType[RealtimeErrorType["TooManyStreams"] = 4102] = "TooManyStreams";
71
+ RealtimeErrorType[RealtimeErrorType["Reconnected"] = 4103] = "Reconnected";
72
+ RealtimeErrorType[RealtimeErrorType["ReconnectAttemptsExhausted"] = 1013] = "ReconnectAttemptsExhausted";
73
+ })(RealtimeErrorType || (RealtimeErrorType = {}));
74
+ const RealtimeErrorMessages = {
75
+ [RealtimeErrorType.BadSampleRate]: "Sample rate must be a positive integer",
76
+ [RealtimeErrorType.AuthFailed]: "Not Authorized",
77
+ [RealtimeErrorType.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.",
78
+ [RealtimeErrorType.NonexistentSessionId]: "Session ID does not exist",
79
+ [RealtimeErrorType.SessionExpired]: "Session has expired",
80
+ [RealtimeErrorType.ClosedSession]: "Session is closed",
81
+ [RealtimeErrorType.RateLimited]: "Rate limited",
82
+ [RealtimeErrorType.UniqueSessionViolation]: "Unique session violation",
83
+ [RealtimeErrorType.SessionTimeout]: "Session Timeout",
84
+ [RealtimeErrorType.AudioTooShort]: "Audio too short",
85
+ [RealtimeErrorType.AudioTooLong]: "Audio too long",
86
+ [RealtimeErrorType.BadJson]: "Bad JSON",
87
+ [RealtimeErrorType.BadSchema]: "Bad schema",
88
+ [RealtimeErrorType.TooManyStreams]: "Too many streams",
89
+ [RealtimeErrorType.Reconnected]: "Reconnected",
90
+ [RealtimeErrorType.ReconnectAttemptsExhausted]: "Reconnect attempts exhausted",
91
+ };
92
+ class RealtimeError extends Error {
93
+ }
94
+
95
+ const defaultRealtimeUrl = "wss://api.assemblyai.com/v2/realtime/ws";
96
+ const forceEndOfUtteranceMessage = `{"force_end_utterance":true}`;
97
+ const terminateSessionMessage = `{"terminate_session":true}`;
98
+ class RealtimeTranscriber {
99
+ constructor(params) {
100
+ var _a, _b;
101
+ this.listeners = {};
102
+ this.realtimeUrl = (_a = params.realtimeUrl) !== null && _a !== void 0 ? _a : defaultRealtimeUrl;
103
+ this.sampleRate = (_b = params.sampleRate) !== null && _b !== void 0 ? _b : 16000;
104
+ this.wordBoost = params.wordBoost;
105
+ this.encoding = params.encoding;
106
+ this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
107
+ this.disablePartialTranscripts = params.disablePartialTranscripts;
108
+ if ("token" in params && params.token)
109
+ this.token = params.token;
110
+ if ("apiKey" in params && params.apiKey)
111
+ this.apiKey = params.apiKey;
112
+ if (!(this.token || this.apiKey)) {
113
+ throw new Error("API key or temporary token is required.");
114
+ }
115
+ }
116
+ connectionUrl() {
117
+ const url = new URL(this.realtimeUrl);
118
+ if (url.protocol !== "wss:") {
119
+ throw new Error("Invalid protocol, must be wss");
120
+ }
121
+ const searchParams = new URLSearchParams();
122
+ if (this.token) {
123
+ searchParams.set("token", this.token);
124
+ }
125
+ searchParams.set("sample_rate", this.sampleRate.toString());
126
+ if (this.wordBoost && this.wordBoost.length > 0) {
127
+ searchParams.set("word_boost", JSON.stringify(this.wordBoost));
128
+ }
129
+ if (this.encoding) {
130
+ searchParams.set("encoding", this.encoding);
131
+ }
132
+ searchParams.set("enable_extra_session_information", "true");
133
+ if (this.disablePartialTranscripts) {
134
+ searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
135
+ }
136
+ url.search = searchParams.toString();
137
+ return url;
138
+ }
139
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
+ on(event, listener) {
141
+ this.listeners[event] = listener;
142
+ }
143
+ connect() {
144
+ return new Promise((resolve) => {
145
+ if (this.socket) {
146
+ throw new Error("Already connected");
147
+ }
148
+ const url = this.connectionUrl();
149
+ if (this.token) {
150
+ this.socket = factory(url.toString());
151
+ }
152
+ else {
153
+ this.socket = factory(url.toString(), {
154
+ headers: { Authorization: this.apiKey },
155
+ });
156
+ }
157
+ this.socket.binaryType = "arraybuffer";
158
+ this.socket.onopen = () => {
159
+ if (this.endUtteranceSilenceThreshold === undefined ||
160
+ this.endUtteranceSilenceThreshold === null) {
161
+ return;
162
+ }
163
+ this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold);
164
+ };
165
+ this.socket.onclose = ({ code, reason }) => {
166
+ var _a, _b;
167
+ if (!reason) {
168
+ if (code in RealtimeErrorType) {
169
+ reason = RealtimeErrorMessages[code];
170
+ }
171
+ }
172
+ (_b = (_a = this.listeners).close) === null || _b === void 0 ? void 0 : _b.call(_a, code, reason);
173
+ };
174
+ this.socket.onerror = (event) => {
175
+ var _a, _b, _c, _d;
176
+ if (event.error)
177
+ (_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, event.error);
178
+ else
179
+ (_d = (_c = this.listeners).error) === null || _d === void 0 ? void 0 : _d.call(_c, new Error(event.message));
180
+ };
181
+ this.socket.onmessage = ({ data }) => {
182
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
183
+ const message = JSON.parse(data.toString());
184
+ if ("error" in message) {
185
+ (_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, new RealtimeError(message.error));
186
+ return;
187
+ }
188
+ switch (message.message_type) {
189
+ case "SessionBegins": {
190
+ const openObject = {
191
+ sessionId: message.session_id,
192
+ expiresAt: new Date(message.expires_at),
193
+ };
194
+ resolve(openObject);
195
+ (_d = (_c = this.listeners).open) === null || _d === void 0 ? void 0 : _d.call(_c, openObject);
196
+ break;
197
+ }
198
+ case "PartialTranscript": {
199
+ // message.created is actually a string when coming from the socket
200
+ message.created = new Date(message.created);
201
+ (_f = (_e = this.listeners).transcript) === null || _f === void 0 ? void 0 : _f.call(_e, message);
202
+ (_h = (_g = this.listeners)["transcript.partial"]) === null || _h === void 0 ? void 0 : _h.call(_g, message);
203
+ break;
204
+ }
205
+ case "FinalTranscript": {
206
+ // message.created is actually a string when coming from the socket
207
+ message.created = new Date(message.created);
208
+ (_k = (_j = this.listeners).transcript) === null || _k === void 0 ? void 0 : _k.call(_j, message);
209
+ (_m = (_l = this.listeners)["transcript.final"]) === null || _m === void 0 ? void 0 : _m.call(_l, message);
210
+ break;
211
+ }
212
+ case "SessionInformation": {
213
+ (_p = (_o = this.listeners).session_information) === null || _p === void 0 ? void 0 : _p.call(_o, message);
214
+ break;
215
+ }
216
+ case "SessionTerminated": {
217
+ (_q = this.sessionTerminatedResolve) === null || _q === void 0 ? void 0 : _q.call(this);
218
+ break;
219
+ }
220
+ }
221
+ };
222
+ });
223
+ }
224
+ sendAudio(audio) {
225
+ this.send(audio);
226
+ }
227
+ stream() {
228
+ return new WritableStream({
229
+ write: (chunk) => {
230
+ this.sendAudio(chunk);
231
+ },
232
+ });
233
+ }
234
+ /**
235
+ * Manually end an utterance
236
+ */
237
+ forceEndUtterance() {
238
+ this.send(forceEndOfUtteranceMessage);
239
+ }
240
+ /**
241
+ * Configure the threshold for how long to wait before ending an utterance. Default is 700ms.
242
+ * @param threshold - The duration of the end utterance silence threshold in milliseconds.
243
+ * This value must be an integer between 0 and 20_000.
244
+ */
245
+ configureEndUtteranceSilenceThreshold(threshold) {
246
+ this.send(`{"end_utterance_silence_threshold":${threshold}}`);
247
+ }
248
+ send(data) {
249
+ if (!this.socket || this.socket.readyState !== this.socket.OPEN) {
250
+ throw new Error("Socket is not open for communication");
251
+ }
252
+ this.socket.send(data);
253
+ }
254
+ close() {
255
+ return __awaiter(this, arguments, void 0, function* (waitForSessionTermination = true) {
256
+ var _a;
257
+ if (this.socket) {
258
+ if (this.socket.readyState === this.socket.OPEN) {
259
+ if (waitForSessionTermination) {
260
+ const sessionTerminatedPromise = new Promise((resolve) => {
261
+ this.sessionTerminatedResolve = resolve;
262
+ });
263
+ this.socket.send(terminateSessionMessage);
264
+ yield sessionTerminatedPromise;
265
+ }
266
+ else {
267
+ this.socket.send(terminateSessionMessage);
268
+ }
269
+ }
270
+ if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.removeAllListeners)
271
+ this.socket.removeAllListeners();
272
+ this.socket.close();
273
+ }
274
+ this.listeners = {};
275
+ this.socket = undefined;
276
+ });
277
+ }
278
+ }
279
+ /**
280
+ * @deprecated Use RealtimeTranscriber instead
281
+ */
282
+ class RealtimeService extends RealtimeTranscriber {
283
+ }
284
+
285
+ exports.RealtimeService = RealtimeService;
286
+ exports.RealtimeTranscriber = RealtimeTranscriber;
287
+
288
+ }));
@@ -0,0 +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,i){return new(s||(s=Promise))((function(o,n){function r(e){try{l(i.next(e))}catch(e){n(e)}}function a(e){try{l(i.throw(e))}catch(e){n(e)}}function l(e){var t;e.done?o(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,a)}l((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const{WritableStream:s}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var i,o;const n=null!==(o=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!==o?o:null===self||void 0===self?void 0:self.WebSocket,r=(e,t)=>t?new n(e,t):new n(e);var a;!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"}(a||(a={}));const l={[a.BadSampleRate]:"Sample rate must be a positive integer",[a.AuthFailed]:"Not Authorized",[a.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.",[a.NonexistentSessionId]:"Session ID does not exist",[a.SessionExpired]:"Session has expired",[a.ClosedSession]:"Session is closed",[a.RateLimited]:"Rate limited",[a.UniqueSessionViolation]:"Unique session violation",[a.SessionTimeout]:"Session Timeout",[a.AudioTooShort]:"Audio too short",[a.AudioTooLong]:"Audio too long",[a.BadJson]:"Bad JSON",[a.BadSchema]:"Bad schema",[a.TooManyStreams]:"Too many streams",[a.Reconnected]:"Reconnected",[a.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class c extends Error{}const d='{"terminate_session":true}';class h{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=r(t.toString()):this.socket=r(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,i;t||e in a&&(t=l[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,l,d,h,u,p,m,S,f,v;const w=JSON.parse(t.toString());if("error"in w)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new c(w.error));else switch(w.message_type){case"SessionBegins":{const t={sessionId:w.session_id,expiresAt:new Date(w.expires_at)};e(t),null===(n=(o=this.listeners).open)||void 0===n||n.call(o,t);break}case"PartialTranscript":w.created=new Date(w.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,w),null===(d=(l=this.listeners)["transcript.partial"])||void 0===d||d.call(l,w);break;case"FinalTranscript":w.created=new Date(w.created),null===(u=(h=this.listeners).transcript)||void 0===u||u.call(h,w),null===(m=(p=this.listeners)["transcript.final"])||void 0===m||m.call(p,w);break;case"SessionInformation":null===(f=(S=this.listeners).session_information)||void 0===f||f.call(S,w);break;case"SessionTerminated":null===(v=this.sessionTerminatedResolve)||void 0===v||v.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new s({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 t(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(d),yield e}else this.socket.send(d);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}e.RealtimeService=class extends h{},e.RealtimeTranscriber=h}));
@@ -48,6 +48,41 @@
48
48
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
49
49
  };
50
50
 
51
+ const buildUserAgent = (userAgent) => defaultUserAgentString +
52
+ (userAgent === false
53
+ ? ""
54
+ : " AssemblyAI/1.0 (" +
55
+ Object.entries(Object.assign(Object.assign({}, defaultUserAgent), userAgent))
56
+ .map(([key, item]) => item ? `${key}=${item.name}/${item.version}` : "")
57
+ .join(" ") +
58
+ ")");
59
+ let defaultUserAgentString = "";
60
+ if (typeof navigator !== "undefined" && navigator.userAgent) {
61
+ defaultUserAgentString += navigator.userAgent;
62
+ }
63
+ const defaultUserAgent = {
64
+ sdk: { name: "JavaScript", version: "4.4.5" },
65
+ };
66
+ if (typeof process !== "undefined") {
67
+ if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
68
+ defaultUserAgent.runtime_env = {
69
+ name: "Node",
70
+ version: process.versions.node,
71
+ };
72
+ }
73
+ if (process.versions.bun && defaultUserAgentString.indexOf("Bun") === -1) {
74
+ defaultUserAgent.runtime_env = {
75
+ name: "Bun",
76
+ version: process.versions.bun,
77
+ };
78
+ }
79
+ }
80
+ if (typeof Deno !== "undefined") {
81
+ if (process.versions.bun && defaultUserAgentString.indexOf("Deno") === -1) {
82
+ defaultUserAgent.runtime_env = { name: "Deno", version: Deno.version.deno };
83
+ }
84
+ }
85
+
51
86
  /**
52
87
  * Base class for services that communicate with the API.
53
88
  */
@@ -58,13 +93,28 @@
58
93
  */
59
94
  constructor(params) {
60
95
  this.params = params;
96
+ if (params.userAgent === false) {
97
+ this.userAgent = undefined;
98
+ }
99
+ else {
100
+ this.userAgent = buildUserAgent(params.userAgent || {});
101
+ }
61
102
  }
62
103
  fetch(input, init) {
63
104
  return __awaiter(this, void 0, void 0, function* () {
64
105
  var _a;
65
106
  init = init !== null && init !== void 0 ? init : {};
66
- init.headers = (_a = init.headers) !== null && _a !== void 0 ? _a : {};
67
- init.headers = Object.assign({ Authorization: this.params.apiKey, "Content-Type": "application/json" }, init.headers);
107
+ let headers = (_a = init.headers) !== null && _a !== void 0 ? _a : {};
108
+ headers = Object.assign({ Authorization: this.params.apiKey, "Content-Type": "application/json" }, init.headers);
109
+ if (this.userAgent) {
110
+ headers["User-Agent"] = this.userAgent;
111
+ // chromium browsers have a bug where the user agent can't be modified
112
+ if (typeof window !== "undefined" && "chrome" in window) {
113
+ headers["AssemblyAI-Agent"] =
114
+ this.userAgent;
115
+ }
116
+ }
117
+ init.headers = headers;
68
118
  init.cache = "no-store";
69
119
  if (!input.startsWith("http"))
70
120
  input = this.params.baseUrl + input;
@@ -709,8 +759,9 @@
709
759
  */
710
760
  constructor(params) {
711
761
  params.baseUrl = params.baseUrl || defaultBaseUrl;
712
- if (params.baseUrl && params.baseUrl.endsWith("/"))
762
+ if (params.baseUrl && params.baseUrl.endsWith("/")) {
713
763
  params.baseUrl = params.baseUrl.slice(0, -1);
764
+ }
714
765
  this.files = new FileService(params);
715
766
  this.transcripts = new TranscriptService(params, this.files);
716
767
  this.lemur = new LemurService(params);
@@ -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,i){return new(s||(s=Promise))((function(n,o){function r(e){try{l(i.next(e))}catch(e){o(e)}}function a(e){try{l(i.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?n(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,a)}l((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class s{constructor(e){this.params=e}fetch(e,s){return t(this,void 0,void 0,(function*(){var t;(s=null!=s?s:{}).headers=null!==(t=s.headers)&&void 0!==t?t:{},s.headers=Object.assign({Authorization:this.params.apiKey,"Content-Type":"application/json"},s.headers),s.cache="no-store",e.startsWith("http")||(e=this.params.baseUrl+e);const i=yield fetch(e,s);if(i.status>=400){let e;const t=yield i.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: ${i.status} ${i.statusText}`)}return i}))}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:n}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var o,r;const a=null!==(r=null!==(o=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==o?o:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==r?r:null===self||void 0===self?void 0:self.WebSocket,l=(e,t)=>t?new a(e,t):new a(e);var c;!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"}(c||(c={}));const d={[c.BadSampleRate]:"Sample rate must be a positive integer",[c.AuthFailed]:"Not Authorized",[c.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.",[c.NonexistentSessionId]:"Session ID does not exist",[c.SessionExpired]:"Session has expired",[c.ClosedSession]:"Session is closed",[c.RateLimited]:"Rate limited",[c.UniqueSessionViolation]:"Unique session violation",[c.SessionTimeout]:"Session Timeout",[c.AudioTooShort]:"Audio too short",[c.AudioTooLong]:"Audio too long",[c.BadJson]:"Bad JSON",[c.BadSchema]:"Bad schema",[c.TooManyStreams]:"Too many streams",[c.Reconnected]:"Reconnected",[c.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class h extends Error{}const u='{"terminate_session":true}';class p{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=l(t.toString()):this.socket=l(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,i;t||e in c&&(t=d[e]),null===(i=(s=this.listeners).close)||void 0===i||i.call(s,e,t)},this.socket.onerror=e=>{var t,s,i,n;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(n=(i=this.listeners).error)||void 0===n||n.call(i,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,i,n,o,r,a,l,c,d,u,p,f,m,v,y;const S=JSON.parse(t.toString());if("error"in S)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new h(S.error));else switch(S.message_type){case"SessionBegins":{const t={sessionId:S.session_id,expiresAt:new Date(S.expires_at)};e(t),null===(o=(n=this.listeners).open)||void 0===o||o.call(n,t);break}case"PartialTranscript":S.created=new Date(S.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,S),null===(c=(l=this.listeners)["transcript.partial"])||void 0===c||c.call(l,S);break;case"FinalTranscript":S.created=new Date(S.created),null===(u=(d=this.listeners).transcript)||void 0===u||u.call(d,S),null===(f=(p=this.listeners)["transcript.final"])||void 0===f||f.call(p,S);break;case"SessionInformation":null===(v=(m=this.listeners).session_information)||void 0===v||v.call(m,S);break;case"SessionTerminated":null===(y=this.sessionTerminatedResolve)||void 0===y||y.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 t(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 f extends s{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 p(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}))}}function m(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 v extends s{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){y(e);const t=yield this.submit(e);return yield this.waitUntilReady(t.id,s)}))}submit(e){return t(this,void 0,void 0,(function*(){let t,s;if(y(e),"audio"in e){const{audio:i}=e,n=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 n=0;for(i=Object.getOwnPropertySymbols(e);n<i.length;n++)t.indexOf(i[n])<0&&Object.prototype.propertyIsEnumerable.call(e,i[n])&&(s[i[n]]=e[i[n]])}return s}(e,["audio"]);if("string"==typeof i){const e=m(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);s=Object.assign(Object.assign({},n),{audio_url:t})}else s=e;return yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(s)})}))}create(e,s){return t(this,void 0,void 0,(function*(){var t;y(e);const i=m(e.audio_url);if(null!==i){const t=yield this.files.upload(i);e.audio_url=t}const n=yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(e)});return null===(t=null==s?void 0:s.poll)||void 0===t||t?yield this.waitUntilReady(n.id,s):n}))}waitUntilReady(e,s){return t(this,void 0,void 0,(function*(){var t,i;const n=null!==(t=null==s?void 0:s.pollingInterval)&&void 0!==t?t:3e3,o=null!==(i=null==s?void 0:s.pollingTimeout)&&void 0!==i?i:-1,r=Date.now();for(;;){const t=yield this.get(e);if("completed"===t.status||"error"===t.status)return t;if(o>0&&Date.now()-r>o)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,n)))}}))}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){return t(this,arguments,void 0,(function*(e,t="srt",s){let i=`/v2/transcript/${e}/${t}`;if(s){const e=new URLSearchParams;e.set("chars_per_caption",s.toString()),i+=`?${e.toString()}`}const n=yield this.fetch(i);return yield n.text()}))}redactions(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}}function y(e){e&&"conformer-2"===e.speech_model&&console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.")}class S extends s{upload(e){return t(this,void 0,void 0,(function*(){let s;s="string"==typeof e?e.startsWith("data:")?function(e){const t=e.split(","),s=t[0].match(/:(.*?);/)[1],i=atob(t[1]);let n=i.length;const o=new Uint8Array(n);for(;n--;)o[n]=i.charCodeAt(n);return new Blob([o],{type:s})}(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 S(e),this.transcripts=new v(e,this.files),this.lemur=new i(e),this.realtime=new f(e)}},e.FileService=S,e.LemurService=i,e.RealtimeService=class extends p{},e.RealtimeServiceFactory=class extends f{},e.RealtimeTranscriber=p,e.RealtimeTranscriberFactory=f,e.TranscriptService=v}));
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,n){return new(s||(s=Promise))((function(i,o){function r(e){try{c(n.next(e))}catch(e){o(e)}}function a(e){try{c(n.throw(e))}catch(e){o(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((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;let s="";"undefined"!=typeof navigator&&navigator.userAgent&&(s+=navigator.userAgent);const n={sdk:{name:"JavaScript",version:"4.4.5"}};"undefined"!=typeof process&&(process.versions.node&&-1===s.indexOf("Node")&&(n.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===s.indexOf("Bun")&&(n.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===s.indexOf("Deno")&&(n.runtime_env={name:"Deno",version:Deno.version.deno});class i{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},s+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},n),t)).map((([e,t])=>t?`${e}=${t.name}/${t.version}`:"")).join(" ")+")"))}fetch(e,s){return t(this,void 0,void 0,(function*(){var t;let n=null!==(t=(s=null!=s?s:{}).headers)&&void 0!==t?t:{};n=Object.assign({Authorization:this.params.apiKey,"Content-Type":"application/json"},s.headers),this.userAgent&&(n["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(n["AssemblyAI-Agent"]=this.userAgent)),s.headers=n,s.cache="no-store",e.startsWith("http")||(e=this.params.baseUrl+e);const i=yield fetch(e,s);if(i.status>=400){let e;const t=yield i.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: ${i.status} ${i.statusText}`)}return i}))}fetchJson(e,s){return t(this,void 0,void 0,(function*(){return(yield this.fetch(e,s)).json()}))}}class o extends i{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:r}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var a,c;const l=null!==(c=null!==(a=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==a?a:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==c?c:null===self||void 0===self?void 0:self.WebSocket,d=(e,t)=>t?new l(e,t):new l(e);var h;!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"}(h||(h={}));const u={[h.BadSampleRate]:"Sample rate must be a positive integer",[h.AuthFailed]:"Not Authorized",[h.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.",[h.NonexistentSessionId]:"Session ID does not exist",[h.SessionExpired]:"Session has expired",[h.ClosedSession]:"Session is closed",[h.RateLimited]:"Rate limited",[h.UniqueSessionViolation]:"Unique session violation",[h.SessionTimeout]:"Session Timeout",[h.AudioTooShort]:"Audio too short",[h.AudioTooLong]:"Audio too long",[h.BadJson]:"Bad JSON",[h.BadSchema]:"Bad schema",[h.TooManyStreams]:"Too many streams",[h.Reconnected]:"Reconnected",[h.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class p extends Error{}const f='{"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=d(t.toString()):this.socket=d(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 h&&(t=u[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,o,r,a,c,l,d,h,u,f,m,v,y;const S=JSON.parse(t.toString());if("error"in S)null===(n=(s=this.listeners).error)||void 0===n||n.call(s,new p(S.error));else switch(S.message_type){case"SessionBegins":{const t={sessionId:S.session_id,expiresAt:new Date(S.expires_at)};e(t),null===(o=(i=this.listeners).open)||void 0===o||o.call(i,t);break}case"PartialTranscript":S.created=new Date(S.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,S),null===(l=(c=this.listeners)["transcript.partial"])||void 0===l||l.call(c,S);break;case"FinalTranscript":S.created=new Date(S.created),null===(h=(d=this.listeners).transcript)||void 0===h||h.call(d,S),null===(f=(u=this.listeners)["transcript.final"])||void 0===f||f.call(u,S);break;case"SessionInformation":null===(v=(m=this.listeners).session_information)||void 0===v||v.call(m,S);break;case"SessionTerminated":null===(y=this.sessionTerminatedResolve)||void 0===y||y.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new r({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 t(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(f),yield e}else this.socket.send(f);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class v extends i{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 m(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}))}}function y(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 S extends i{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){w(e);const t=yield this.submit(e);return yield this.waitUntilReady(t.id,s)}))}submit(e){return t(this,void 0,void 0,(function*(){let t,s;if(w(e),"audio"in e){const{audio:n}=e,i=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,["audio"]);if("string"==typeof n){const e=y(n);t=null!==e?yield this.files.upload(e):n.startsWith("data:")?yield this.files.upload(n):n}else t=yield this.files.upload(n);s=Object.assign(Object.assign({},i),{audio_url:t})}else s=e;return yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(s)})}))}create(e,s){return t(this,void 0,void 0,(function*(){var t;w(e);const n=y(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===(t=null==s?void 0:s.poll)||void 0===t||t?yield this.waitUntilReady(i.id,s):i}))}waitUntilReady(e,s){return t(this,void 0,void 0,(function*(){var t,n;const i=null!==(t=null==s?void 0:s.pollingInterval)&&void 0!==t?t:3e3,o=null!==(n=null==s?void 0:s.pollingTimeout)&&void 0!==n?n:-1,r=Date.now();for(;;){const t=yield this.get(e);if("completed"===t.status||"error"===t.status)return t;if(o>0&&Date.now()-r>o)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,i)))}}))}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){return t(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.fetchJson(`/v2/transcript/${e}/redacted-audio`)}}function w(e){e&&"conformer-2"===e.speech_model&&console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.")}class g extends i{upload(e){return t(this,void 0,void 0,(function*(){let s;s="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 o=new Uint8Array(i);for(;i--;)o[i]=n.charCodeAt(i);return new Blob([o],{type:s})}(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 g(e),this.transcripts=new S(e,this.files),this.lemur=new o(e),this.realtime=new v(e)}},e.FileService=g,e.LemurService=o,e.RealtimeService=class extends m{},e.RealtimeServiceFactory=class extends v{},e.RealtimeTranscriber=m,e.RealtimeTranscriberFactory=v,e.TranscriptService=S}));
package/dist/browser.mjs CHANGED
@@ -1,3 +1,38 @@
1
+ const buildUserAgent = (userAgent) => defaultUserAgentString +
2
+ (userAgent === false
3
+ ? ""
4
+ : " AssemblyAI/1.0 (" +
5
+ Object.entries({ ...defaultUserAgent, ...userAgent })
6
+ .map(([key, item]) => item ? `${key}=${item.name}/${item.version}` : "")
7
+ .join(" ") +
8
+ ")");
9
+ let defaultUserAgentString = "";
10
+ if (typeof navigator !== "undefined" && navigator.userAgent) {
11
+ defaultUserAgentString += navigator.userAgent;
12
+ }
13
+ const defaultUserAgent = {
14
+ sdk: { name: "JavaScript", version: "__SDK_VERSION__" },
15
+ };
16
+ if (typeof process !== "undefined") {
17
+ if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
18
+ defaultUserAgent.runtime_env = {
19
+ name: "Node",
20
+ version: process.versions.node,
21
+ };
22
+ }
23
+ if (process.versions.bun && defaultUserAgentString.indexOf("Bun") === -1) {
24
+ defaultUserAgent.runtime_env = {
25
+ name: "Bun",
26
+ version: process.versions.bun,
27
+ };
28
+ }
29
+ }
30
+ if (typeof Deno !== "undefined") {
31
+ if (process.versions.bun && defaultUserAgentString.indexOf("Deno") === -1) {
32
+ defaultUserAgent.runtime_env = { name: "Deno", version: Deno.version.deno };
33
+ }
34
+ }
35
+
1
36
  /**
2
37
  * Base class for services that communicate with the API.
3
38
  */
@@ -8,15 +43,30 @@ class BaseService {
8
43
  */
9
44
  constructor(params) {
10
45
  this.params = params;
46
+ if (params.userAgent === false) {
47
+ this.userAgent = undefined;
48
+ }
49
+ else {
50
+ this.userAgent = buildUserAgent(params.userAgent || {});
51
+ }
11
52
  }
12
53
  async fetch(input, init) {
13
54
  init = init ?? {};
14
- init.headers = init.headers ?? {};
15
- init.headers = {
55
+ let headers = init.headers ?? {};
56
+ headers = {
16
57
  Authorization: this.params.apiKey,
17
58
  "Content-Type": "application/json",
18
59
  ...init.headers,
19
60
  };
61
+ if (this.userAgent) {
62
+ headers["User-Agent"] = this.userAgent;
63
+ // chromium browsers have a bug where the user agent can't be modified
64
+ if (typeof window !== "undefined" && "chrome" in window) {
65
+ headers["AssemblyAI-Agent"] =
66
+ this.userAgent;
67
+ }
68
+ }
69
+ init.headers = headers;
20
70
  init.cache = "no-store";
21
71
  if (!input.startsWith("http"))
22
72
  input = this.params.baseUrl + input;
@@ -627,8 +677,9 @@ class AssemblyAI {
627
677
  */
628
678
  constructor(params) {
629
679
  params.baseUrl = params.baseUrl || defaultBaseUrl;
630
- if (params.baseUrl && params.baseUrl.endsWith("/"))
680
+ if (params.baseUrl && params.baseUrl.endsWith("/")) {
631
681
  params.baseUrl = params.baseUrl.slice(0, -1);
682
+ }
632
683
  this.files = new FileService(params);
633
684
  this.transcripts = new TranscriptService(params, this.files);
634
685
  this.lemur = new LemurService(params);