assemblyai 4.12.2 → 4.13.0-beta.1
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/dist/assemblyai.umd.js +210 -4
- package/dist/assemblyai.umd.min.js +1 -1
- package/dist/browser.mjs +207 -5
- package/dist/bun.mjs +207 -5
- package/dist/deno.mjs +207 -5
- package/dist/index.cjs +210 -4
- package/dist/index.mjs +210 -5
- package/dist/node.cjs +207 -4
- package/dist/node.mjs +207 -5
- package/dist/services/index.d.ts +6 -1
- package/dist/services/streaming/factory.d.ts +10 -0
- package/dist/services/streaming/index.d.ts +2 -0
- package/dist/services/streaming/service.d.ts +20 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/services/index.d.ts +1 -0
- package/dist/types/streaming/index.d.ts +71 -0
- package/dist/utils/errors/index.d.ts +1 -0
- package/dist/utils/errors/streaming.d.ts +23 -0
- package/dist/workerd.mjs +207 -5
- package/package.json +1 -1
- package/src/services/index.ts +14 -0
- package/src/services/streaming/factory.ts +39 -0
- package/src/services/streaming/index.ts +2 -0
- package/src/services/streaming/service.ts +219 -0
- package/src/types/index.ts +2 -1
- package/src/types/services/index.ts +1 -0
- package/src/types/streaming/index.ts +94 -0
- package/src/utils/errors/index.ts +6 -0
- package/src/utils/errors/streaming.ts +51 -0
package/dist/assemblyai.umd.js
CHANGED
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
defaultUserAgentString += navigator.userAgent;
|
|
66
66
|
}
|
|
67
67
|
const defaultUserAgent = {
|
|
68
|
-
sdk: { name: "JavaScript", version: "4.
|
|
68
|
+
sdk: { name: "JavaScript", version: "4.13.0-beta.1" },
|
|
69
69
|
};
|
|
70
70
|
if (typeof process !== "undefined") {
|
|
71
71
|
if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
|
|
@@ -265,9 +265,48 @@
|
|
|
265
265
|
class RealtimeError extends Error {
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
+
const StreamingErrorType = {
|
|
269
|
+
BadSampleRate: 4000,
|
|
270
|
+
AuthFailed: 4001,
|
|
271
|
+
InsufficientFunds: 4002,
|
|
272
|
+
FreeTierUser: 4003,
|
|
273
|
+
NonexistentSessionId: 4004,
|
|
274
|
+
SessionExpired: 4008,
|
|
275
|
+
ClosedSession: 4010,
|
|
276
|
+
RateLimited: 4029,
|
|
277
|
+
UniqueSessionViolation: 4030,
|
|
278
|
+
SessionTimeout: 4031,
|
|
279
|
+
AudioTooShort: 4032,
|
|
280
|
+
AudioTooLong: 4033,
|
|
281
|
+
AudioTooSmallToTranscode: 4034,
|
|
282
|
+
BadSchema: 4101,
|
|
283
|
+
TooManyStreams: 4102,
|
|
284
|
+
Reconnected: 4103,
|
|
285
|
+
};
|
|
286
|
+
const StreamingErrorMessages = {
|
|
287
|
+
[StreamingErrorType.BadSampleRate]: "Sample rate must be a positive integer",
|
|
288
|
+
[StreamingErrorType.AuthFailed]: "Not Authorized",
|
|
289
|
+
[StreamingErrorType.InsufficientFunds]: "Insufficient funds",
|
|
290
|
+
[StreamingErrorType.FreeTierUser]: "This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",
|
|
291
|
+
[StreamingErrorType.NonexistentSessionId]: "Session ID does not exist",
|
|
292
|
+
[StreamingErrorType.SessionExpired]: "Session has expired",
|
|
293
|
+
[StreamingErrorType.ClosedSession]: "Session is closed",
|
|
294
|
+
[StreamingErrorType.RateLimited]: "Rate limited",
|
|
295
|
+
[StreamingErrorType.UniqueSessionViolation]: "Unique session violation",
|
|
296
|
+
[StreamingErrorType.SessionTimeout]: "Session Timeout",
|
|
297
|
+
[StreamingErrorType.AudioTooShort]: "Audio too short",
|
|
298
|
+
[StreamingErrorType.AudioTooLong]: "Audio too long",
|
|
299
|
+
[StreamingErrorType.AudioTooSmallToTranscode]: "Audio too small to transcode",
|
|
300
|
+
[StreamingErrorType.BadSchema]: "Bad schema",
|
|
301
|
+
[StreamingErrorType.TooManyStreams]: "Too many streams",
|
|
302
|
+
[StreamingErrorType.Reconnected]: "This session has been reconnected. This WebSocket is no longer valid.",
|
|
303
|
+
};
|
|
304
|
+
class StreamingError extends Error {
|
|
305
|
+
}
|
|
306
|
+
|
|
268
307
|
const defaultRealtimeUrl = "wss://api.assemblyai.com/v2/realtime/ws";
|
|
269
308
|
const forceEndOfUtteranceMessage = `{"force_end_utterance":true}`;
|
|
270
|
-
const terminateSessionMessage = `{"terminate_session":true}`;
|
|
309
|
+
const terminateSessionMessage$1 = `{"terminate_session":true}`;
|
|
271
310
|
/**
|
|
272
311
|
* RealtimeTranscriber connects to the Streaming Speech-to-Text API and lets you transcribe audio in real-time.
|
|
273
312
|
*/
|
|
@@ -466,11 +505,11 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
|
|
|
466
505
|
const sessionTerminatedPromise = new Promise((resolve) => {
|
|
467
506
|
this.sessionTerminatedResolve = resolve;
|
|
468
507
|
});
|
|
469
|
-
this.socket.send(terminateSessionMessage);
|
|
508
|
+
this.socket.send(terminateSessionMessage$1);
|
|
470
509
|
yield sessionTerminatedPromise;
|
|
471
510
|
}
|
|
472
511
|
else {
|
|
473
|
-
this.socket.send(terminateSessionMessage);
|
|
512
|
+
this.socket.send(terminateSessionMessage$1);
|
|
474
513
|
}
|
|
475
514
|
}
|
|
476
515
|
if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.removeAllListeners)
|
|
@@ -833,7 +872,172 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
|
|
|
833
872
|
return new Blob([u8arr], { type: mime });
|
|
834
873
|
}
|
|
835
874
|
|
|
875
|
+
const defaultStreamingUrl$1 = "wss://streaming.assemblyai.com/v3/ws";
|
|
876
|
+
const terminateSessionMessage = `{"type":"Terminate"}`;
|
|
877
|
+
class StreamingTranscriber {
|
|
878
|
+
constructor(params) {
|
|
879
|
+
this.listeners = {};
|
|
880
|
+
this.params = Object.assign(Object.assign({}, params), { websocketBaseUrl: params.websocketBaseUrl || defaultStreamingUrl$1 });
|
|
881
|
+
if ("token" in params && params.token)
|
|
882
|
+
this.token = params.token;
|
|
883
|
+
if ("apiKey" in params && params.apiKey)
|
|
884
|
+
this.apiKey = params.apiKey;
|
|
885
|
+
if (!(this.token || this.apiKey)) {
|
|
886
|
+
throw new Error("API key or temporary token is required.");
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
connectionUrl() {
|
|
890
|
+
var _a;
|
|
891
|
+
const url = new URL((_a = this.params.websocketBaseUrl) !== null && _a !== void 0 ? _a : "");
|
|
892
|
+
if (url.protocol !== "wss:") {
|
|
893
|
+
throw new Error("Invalid protocol, must be wss");
|
|
894
|
+
}
|
|
895
|
+
const searchParams = new URLSearchParams();
|
|
896
|
+
searchParams.set("sample_rate", this.params.sampleRate.toString());
|
|
897
|
+
if (this.params.wordFinalizationMaxWaitTime) {
|
|
898
|
+
searchParams.set("word_finalization_max_wait_time", this.params.wordFinalizationMaxWaitTime.toString());
|
|
899
|
+
}
|
|
900
|
+
if (this.params.endOfTurnConfidenceThreshold) {
|
|
901
|
+
searchParams.set("end_of_turn_confidence_threshold", this.params.endOfTurnConfidenceThreshold.toString());
|
|
902
|
+
}
|
|
903
|
+
if (this.params.minEndOfTurnSilenceWhenConfident) {
|
|
904
|
+
searchParams.set("min_end_of_turn_silence_when_confident", this.params.minEndOfTurnSilenceWhenConfident.toString());
|
|
905
|
+
}
|
|
906
|
+
if (this.params.maxTurnSilence) {
|
|
907
|
+
searchParams.set("max_turn_silence", this.params.maxTurnSilence.toString());
|
|
908
|
+
}
|
|
909
|
+
if (this.params.formattedFinals) {
|
|
910
|
+
searchParams.set("formatted_finals", this.params.formattedFinals.toString());
|
|
911
|
+
}
|
|
912
|
+
url.search = searchParams.toString();
|
|
913
|
+
return url;
|
|
914
|
+
}
|
|
915
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
916
|
+
on(event, listener) {
|
|
917
|
+
this.listeners[event] = listener;
|
|
918
|
+
}
|
|
919
|
+
connect() {
|
|
920
|
+
return new Promise((resolve) => {
|
|
921
|
+
if (this.socket) {
|
|
922
|
+
throw new Error("Already connected");
|
|
923
|
+
}
|
|
924
|
+
const url = this.connectionUrl();
|
|
925
|
+
this.socket = factory(url.toString(), {
|
|
926
|
+
headers: { Authorization: this.token || this.apiKey },
|
|
927
|
+
});
|
|
928
|
+
this.socket.binaryType = "arraybuffer";
|
|
929
|
+
this.socket.onopen = () => { };
|
|
930
|
+
this.socket.onclose = ({ code, reason }) => {
|
|
931
|
+
var _a, _b;
|
|
932
|
+
if (!reason) {
|
|
933
|
+
if (code in StreamingErrorMessages) {
|
|
934
|
+
reason = StreamingErrorMessages[code];
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
(_b = (_a = this.listeners).close) === null || _b === void 0 ? void 0 : _b.call(_a, code, reason);
|
|
938
|
+
};
|
|
939
|
+
this.socket.onerror = (event) => {
|
|
940
|
+
var _a, _b, _c, _d;
|
|
941
|
+
if (event.error)
|
|
942
|
+
(_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, event.error);
|
|
943
|
+
else
|
|
944
|
+
(_d = (_c = this.listeners).error) === null || _d === void 0 ? void 0 : _d.call(_c, new Error(event.message));
|
|
945
|
+
};
|
|
946
|
+
this.socket.onmessage = ({ data }) => {
|
|
947
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
948
|
+
const message = JSON.parse(data.toString());
|
|
949
|
+
if ("error" in message) {
|
|
950
|
+
(_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, new StreamingError(message.error));
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
switch (message.type) {
|
|
954
|
+
case "Begin": {
|
|
955
|
+
resolve(message);
|
|
956
|
+
(_d = (_c = this.listeners).open) === null || _d === void 0 ? void 0 : _d.call(_c, message);
|
|
957
|
+
break;
|
|
958
|
+
}
|
|
959
|
+
case "Turn": {
|
|
960
|
+
(_f = (_e = this.listeners).turn) === null || _f === void 0 ? void 0 : _f.call(_e, message);
|
|
961
|
+
break;
|
|
962
|
+
}
|
|
963
|
+
case "Termination": {
|
|
964
|
+
(_g = this.sessionTerminatedResolve) === null || _g === void 0 ? void 0 : _g.call(this);
|
|
965
|
+
break;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
stream() {
|
|
972
|
+
return new WritableStream({
|
|
973
|
+
write: (chunk) => {
|
|
974
|
+
this.sendAudio(chunk);
|
|
975
|
+
},
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
sendAudio(audio) {
|
|
979
|
+
this.send(audio);
|
|
980
|
+
}
|
|
981
|
+
send(data) {
|
|
982
|
+
if (!this.socket || this.socket.readyState !== this.socket.OPEN) {
|
|
983
|
+
throw new Error("Socket is not open for communication");
|
|
984
|
+
}
|
|
985
|
+
this.socket.send(data);
|
|
986
|
+
}
|
|
987
|
+
close() {
|
|
988
|
+
return __awaiter(this, arguments, void 0, function* (waitForSessionTermination = true) {
|
|
989
|
+
var _a;
|
|
990
|
+
if (this.socket) {
|
|
991
|
+
if (this.socket.readyState === this.socket.OPEN) {
|
|
992
|
+
if (waitForSessionTermination) {
|
|
993
|
+
const sessionTerminatedPromise = new Promise((resolve) => {
|
|
994
|
+
this.sessionTerminatedResolve = resolve;
|
|
995
|
+
});
|
|
996
|
+
this.socket.send(terminateSessionMessage);
|
|
997
|
+
yield sessionTerminatedPromise;
|
|
998
|
+
}
|
|
999
|
+
else {
|
|
1000
|
+
this.socket.send(terminateSessionMessage);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.removeAllListeners)
|
|
1004
|
+
this.socket.removeAllListeners();
|
|
1005
|
+
this.socket.close();
|
|
1006
|
+
}
|
|
1007
|
+
this.listeners = {};
|
|
1008
|
+
this.socket = undefined;
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
class StreamingTranscriberFactory extends BaseService {
|
|
1014
|
+
constructor(params) {
|
|
1015
|
+
super(params);
|
|
1016
|
+
}
|
|
1017
|
+
transcriber(params) {
|
|
1018
|
+
return new StreamingTranscriber(params);
|
|
1019
|
+
}
|
|
1020
|
+
createTemporaryToken(params) {
|
|
1021
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1022
|
+
const searchParams = new URLSearchParams();
|
|
1023
|
+
// Add each param to the search params
|
|
1024
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
1025
|
+
if (value !== undefined && value !== null) {
|
|
1026
|
+
searchParams.append(key, String(value));
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
const queryString = searchParams.toString();
|
|
1030
|
+
const url = queryString ? `/v3/token?${queryString}` : "/v3/token";
|
|
1031
|
+
const data = yield this.fetchJson(url, {
|
|
1032
|
+
method: "GET",
|
|
1033
|
+
});
|
|
1034
|
+
return data.token;
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
836
1039
|
const defaultBaseUrl = "https://api.assemblyai.com";
|
|
1040
|
+
const defaultStreamingUrl = "https://streaming.assemblyai.com";
|
|
837
1041
|
class AssemblyAI {
|
|
838
1042
|
/**
|
|
839
1043
|
* Create a new AssemblyAI client.
|
|
@@ -848,6 +1052,7 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
|
|
|
848
1052
|
this.transcripts = new TranscriptService(params, this.files);
|
|
849
1053
|
this.lemur = new LemurService(params);
|
|
850
1054
|
this.realtime = new RealtimeTranscriberFactory(params);
|
|
1055
|
+
this.streaming = new StreamingTranscriberFactory(Object.assign(Object.assign({}, params), { baseUrl: params.streamingBaseUrl || defaultStreamingUrl }));
|
|
851
1056
|
}
|
|
852
1057
|
}
|
|
853
1058
|
|
|
@@ -858,6 +1063,7 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
|
|
|
858
1063
|
exports.RealtimeServiceFactory = RealtimeServiceFactory;
|
|
859
1064
|
exports.RealtimeTranscriber = RealtimeTranscriber;
|
|
860
1065
|
exports.RealtimeTranscriberFactory = RealtimeTranscriberFactory;
|
|
1066
|
+
exports.StreamingTranscriber = StreamingTranscriber;
|
|
861
1067
|
exports.TranscriptService = TranscriptService;
|
|
862
1068
|
|
|
863
1069
|
}));
|
|
@@ -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(r,n){function o(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?r(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}l((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const s={cache:"no-store"};let i="";"undefined"!=typeof navigator&&navigator.userAgent&&(i+=navigator.userAgent);const r={sdk:{name:"JavaScript",version:"4.12.2"}};"undefined"!=typeof process&&(process.versions.node&&-1===i.indexOf("Node")&&(r.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===i.indexOf("Bun")&&(r.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===i.indexOf("Deno")&&(r.runtime_env={name:"Deno",version:Deno.version.deno});class n{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},i+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},r),t)).map((([e,t])=>t?`${e}=${t.name}/${t.version}`:"")).join(" ")+")"))}fetch(e,i){return t(this,void 0,void 0,(function*(){i=Object.assign(Object.assign({},s),i);let t={Authorization:this.params.apiKey,"Content-Type":"application/json"};(null==s?void 0:s.headers)&&(t=Object.assign(Object.assign({},t),s.headers)),(null==i?void 0:i.headers)&&(t=Object.assign(Object.assign({},t),i.headers)),this.userAgent&&(t["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(t["AssemblyAI-Agent"]=this.userAgent)),i.headers=t,e.startsWith("http")||(e=this.params.baseUrl+e);const r=yield fetch(e,i);if(r.status>=400){let e;const t=yield r.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: ${r.status} ${r.statusText}`)}return r}))}fetchJson(e,s){return t(this,void 0,void 0,(function*(){return(yield this.fetch(e,s)).json()}))}}class o extends n{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)})}getResponse(e){return this.fetchJson(`/lemur/v3/${e}`)}purgeRequestData(e){return this.fetchJson(`/lemur/v3/${e}`,{method:"DELETE"})}}const{WritableStream:a}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var l,c;const d=null!==(c=null!==(l=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==l?l:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==c?c:null===self||void 0===self?void 0:self.WebSocket,h=(e,t)=>t?new d(e,t):new d(e),u={[4e3]:"Sample rate must be a positive integer",[4001]:"Not Authorized",[4002]:"Insufficient funds",[4003]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[4100]:"Bad JSON",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid.",[1013]:"Reconnect attempts exhausted",[4104]:"Could not parse word boost parameter"};class p extends Error{}const f='{"terminate_session":true}';class v{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=h(t.toString()):(console.warn("API key authentication is not supported for the RealtimeTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=h(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 u&&(t=u[e]),null===(i=(s=this.listeners).close)||void 0===i||i.call(s,e,t)},this.socket.onerror=e=>{var t,s,i,r;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(r=(i=this.listeners).error)||void 0===r||r.call(i,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,i,r,n,o,a,l,c,d,h,u,f,v,m,y;const b=JSON.parse(t.toString());if("error"in b)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new p(b.error));else switch(b.message_type){case"SessionBegins":{const t={sessionId:b.session_id,expiresAt:new Date(b.expires_at)};e(t),null===(n=(r=this.listeners).open)||void 0===n||n.call(r,t);break}case"PartialTranscript":b.created=new Date(b.created),null===(a=(o=this.listeners).transcript)||void 0===a||a.call(o,b),null===(c=(l=this.listeners)["transcript.partial"])||void 0===c||c.call(l,b);break;case"FinalTranscript":b.created=new Date(b.created),null===(h=(d=this.listeners).transcript)||void 0===h||h.call(d,b),null===(f=(u=this.listeners)["transcript.final"])||void 0===f||f.call(u,b);break;case"SessionInformation":null===(m=(v=this.listeners).session_information)||void 0===m||m.call(v,b);break;case"SessionTerminated":null===(y=this.sessionTerminatedResolve)||void 0===y||y.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new a({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 m extends n{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 v(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 b extends n{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*(){let t,s;if("audio"in e){const{audio:i}=e,r=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 r=0;for(i=Object.getOwnPropertySymbols(e);r<i.length;r++)t.indexOf(i[r])<0&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(s[i[r]]=e[i[r]])}return s}(e,["audio"]);if("string"==typeof i){const e=y(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({},r),{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;const i=y(e.audio_url);if(null!==i){const t=yield this.files.upload(i);e.audio_url=t}const r=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(r.id,s):r}))}waitUntilReady(e,s){return t(this,void 0,void 0,(function*(){var t,i;const r=null!==(t=null==s?void 0:s.pollingInterval)&&void 0!==t?t:3e3,n=null!==(i=null==s?void 0:s.pollingTimeout)&&void 0!==i?i:-1,o=Date.now();for(;;){const t=yield this.get(e);if("completed"===t.status||"error"===t.status)return t;if(n>0&&Date.now()-o>n)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,r)))}}))}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 r=yield this.fetch(i);return yield r.text()}))}redactions(e){return this.redactedAudio(e)}redactedAudio(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}redactedAudioFile(e){return t(this,void 0,void 0,(function*(){const{redacted_audio_url:t,status:s}=yield this.redactedAudio(e);if("redacted_audio_ready"!==s)throw new Error(`Redacted audio status is ${s}`);const i=yield fetch(t);if(!i.ok)throw new Error(`Failed to fetch redacted audio: ${i.statusText}`);return{arrayBuffer:i.arrayBuffer.bind(i),blob:i.blob.bind(i),body:i.body,bodyUsed:i.bodyUsed}}))}}class w extends n{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 r=i.length;const n=new Uint8Array(r);for(;r--;)n[r]=i.charCodeAt(r);return new Blob([n],{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 w(e),this.transcripts=new b(e,this.files),this.lemur=new o(e),this.realtime=new m(e)}},e.FileService=w,e.LemurService=o,e.RealtimeService=class extends v{},e.RealtimeServiceFactory=class extends m{},e.RealtimeTranscriber=v,e.RealtimeTranscriberFactory=m,e.TranscriptService=b}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).assemblyai={})}(this,(function(e){"use strict";function t(e,t,s,i){return new(s||(s=Promise))((function(n,r){function o(e){try{c(i.next(e))}catch(e){r(e)}}function a(e){try{c(i.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}c((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const s={cache:"no-store"};let i="";"undefined"!=typeof navigator&&navigator.userAgent&&(i+=navigator.userAgent);const n={sdk:{name:"JavaScript",version:"4.13.0-beta.1"}};"undefined"!=typeof process&&(process.versions.node&&-1===i.indexOf("Node")&&(n.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===i.indexOf("Bun")&&(n.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===i.indexOf("Deno")&&(n.runtime_env={name:"Deno",version:Deno.version.deno});class r{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},i+(!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,i){return t(this,void 0,void 0,(function*(){i=Object.assign(Object.assign({},s),i);let t={Authorization:this.params.apiKey,"Content-Type":"application/json"};(null==s?void 0:s.headers)&&(t=Object.assign(Object.assign({},t),s.headers)),(null==i?void 0:i.headers)&&(t=Object.assign(Object.assign({},t),i.headers)),this.userAgent&&(t["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(t["AssemblyAI-Agent"]=this.userAgent)),i.headers=t,e.startsWith("http")||(e=this.params.baseUrl+e);const n=yield fetch(e,i);if(n.status>=400){let e;const t=yield n.text();if(t){try{e=JSON.parse(t)}catch(e){}if(null==e?void 0:e.error)throw new Error(e.error);throw new Error(t)}throw new Error(`HTTP Error: ${n.status} ${n.statusText}`)}return n}))}fetchJson(e,s){return t(this,void 0,void 0,(function*(){return(yield this.fetch(e,s)).json()}))}}class o extends r{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)})}getResponse(e){return this.fetchJson(`/lemur/v3/${e}`)}purgeRequestData(e){return this.fetchJson(`/lemur/v3/${e}`,{method:"DELETE"})}}const{WritableStream:a}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var c,l;const d=null!==(l=null!==(c=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==c?c:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==l?l:null===self||void 0===self?void 0:self.WebSocket,h=(e,t)=>t?new d(e,t):new d(e),u={[4e3]:"Sample rate must be a positive integer",[4001]:"Not Authorized",[4002]:"Insufficient funds",[4003]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[4100]:"Bad JSON",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid.",[1013]:"Reconnect attempts exhausted",[4104]:"Could not parse word boost parameter"};class p extends Error{}const m={[4e3]:"Sample rate must be a positive integer",[4001]:"Not Authorized",[4002]:"Insufficient funds",[4003]:"This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",[4004]:"Session ID does not exist",[4008]:"Session has expired",[4010]:"Session is closed",[4029]:"Rate limited",[4030]:"Unique session violation",[4031]:"Session Timeout",[4032]:"Audio too short",[4033]:"Audio too long",[4034]:"Audio too small to transcode",[4101]:"Bad schema",[4102]:"Too many streams",[4103]:"This session has been reconnected. This WebSocket is no longer valid."};class f extends Error{}const v='{"terminate_session":true}';class y{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=h(t.toString()):(console.warn("API key authentication is not supported for the RealtimeTranscriber in browser environment. Use temporary token authentication instead.\nLearn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/compat.md#browser-compatibility."),this.socket=h(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 u&&(t=u[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,r,o,a,c,l,d,h,u,m,f,v,y;const b=JSON.parse(t.toString());if("error"in b)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new p(b.error));else switch(b.message_type){case"SessionBegins":{const t={sessionId:b.session_id,expiresAt:new Date(b.expires_at)};e(t),null===(r=(n=this.listeners).open)||void 0===r||r.call(n,t);break}case"PartialTranscript":b.created=new Date(b.created),null===(a=(o=this.listeners).transcript)||void 0===a||a.call(o,b),null===(l=(c=this.listeners)["transcript.partial"])||void 0===l||l.call(c,b);break;case"FinalTranscript":b.created=new Date(b.created),null===(h=(d=this.listeners).transcript)||void 0===h||h.call(d,b),null===(m=(u=this.listeners)["transcript.final"])||void 0===m||m.call(u,b);break;case"SessionInformation":null===(v=(f=this.listeners).session_information)||void 0===v||v.call(f,b);break;case"SessionTerminated":null===(y=this.sessionTerminatedResolve)||void 0===y||y.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new a({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(v),yield e}else this.socket.send(v);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class b extends r{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 y(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 w(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 g extends r{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*(){let t,s;if("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=w(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;const i=w(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,r=null!==(i=null==s?void 0:s.pollingTimeout)&&void 0!==i?i:-1,o=Date.now();for(;;){const t=yield this.get(e);if("completed"===t.status||"error"===t.status)return t;if(r>0&&Date.now()-o>r)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,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.redactedAudio(e)}redactedAudio(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}redactedAudioFile(e){return t(this,void 0,void 0,(function*(){const{redacted_audio_url:t,status:s}=yield this.redactedAudio(e);if("redacted_audio_ready"!==s)throw new Error(`Redacted audio status is ${s}`);const i=yield fetch(t);if(!i.ok)throw new Error(`Failed to fetch redacted audio: ${i.statusText}`);return{arrayBuffer:i.arrayBuffer.bind(i),blob:i.blob.bind(i),body:i.body,bodyUsed:i.bodyUsed}}))}}class S extends r{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 r=new Uint8Array(n);for(;n--;)r[n]=i.charCodeAt(n);return new Blob([r],{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}))}}const k='{"type":"Terminate"}';class T{constructor(e){if(this.listeners={},this.params=Object.assign(Object.assign({},e),{websocketBaseUrl:e.websocketBaseUrl||"wss://streaming.assemblyai.com/v3/ws"}),"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.")}connectionUrl(){var e;const t=new URL(null!==(e=this.params.websocketBaseUrl)&&void 0!==e?e:"");if("wss:"!==t.protocol)throw new Error("Invalid protocol, must be wss");const s=new URLSearchParams;return s.set("sample_rate",this.params.sampleRate.toString()),this.params.wordFinalizationMaxWaitTime&&s.set("word_finalization_max_wait_time",this.params.wordFinalizationMaxWaitTime.toString()),this.params.endOfTurnConfidenceThreshold&&s.set("end_of_turn_confidence_threshold",this.params.endOfTurnConfidenceThreshold.toString()),this.params.minEndOfTurnSilenceWhenConfident&&s.set("min_end_of_turn_silence_when_confident",this.params.minEndOfTurnSilenceWhenConfident.toString()),this.params.maxTurnSilence&&s.set("max_turn_silence",this.params.maxTurnSilence.toString()),this.params.formattedFinals&&s.set("formatted_finals",this.params.formattedFinals.toString()),t.search=s.toString(),t}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.socket=h(t.toString(),{headers:{Authorization:this.token||this.apiKey}}),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{},this.socket.onclose=({code:e,reason:t})=>{var s,i;t||e in m&&(t=m[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,r,o,a,c;const l=JSON.parse(t.toString());if("error"in l)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new f(l.error));else switch(l.type){case"Begin":e(l),null===(r=(n=this.listeners).open)||void 0===r||r.call(n,l);break;case"Turn":null===(a=(o=this.listeners).turn)||void 0===a||a.call(o,l);break;case"Termination":null===(c=this.sessionTerminatedResolve)||void 0===c||c.call(this)}}}))}stream(){return new a({write:e=>{this.sendAudio(e)}})}sendAudio(e){this.send(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(k),yield e}else this.socket.send(k);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class O extends r{constructor(e){super(e)}transcriber(e){return new T(e)}createTemporaryToken(e){return t(this,void 0,void 0,(function*(){const t=new URLSearchParams;Object.entries(e).forEach((([e,s])=>{null!=s&&t.append(e,String(s))}));const s=t.toString(),i=s?`/v3/token?${s}`:"/v3/token";return(yield this.fetchJson(i,{method:"GET"})).token}))}}e.AssemblyAI=class{constructor(e){e.baseUrl=e.baseUrl||"https://api.assemblyai.com",e.baseUrl&&e.baseUrl.endsWith("/")&&(e.baseUrl=e.baseUrl.slice(0,-1)),this.files=new S(e),this.transcripts=new g(e,this.files),this.lemur=new o(e),this.realtime=new b(e),this.streaming=new O(Object.assign(Object.assign({},e),{baseUrl:e.streamingBaseUrl||"https://streaming.assemblyai.com"}))}},e.FileService=S,e.LemurService=o,e.RealtimeService=class extends y{},e.RealtimeServiceFactory=class extends b{},e.RealtimeTranscriber=y,e.RealtimeTranscriberFactory=b,e.StreamingTranscriber=T,e.TranscriptService=g}));
|
package/dist/browser.mjs
CHANGED
|
@@ -15,7 +15,7 @@ if (typeof navigator !== "undefined" && navigator.userAgent) {
|
|
|
15
15
|
defaultUserAgentString += navigator.userAgent;
|
|
16
16
|
}
|
|
17
17
|
const defaultUserAgent = {
|
|
18
|
-
sdk: { name: "JavaScript", version: "4.
|
|
18
|
+
sdk: { name: "JavaScript", version: "4.13.0-beta.1" },
|
|
19
19
|
};
|
|
20
20
|
if (typeof process !== "undefined") {
|
|
21
21
|
if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
|
|
@@ -210,9 +210,48 @@ const RealtimeErrorMessages = {
|
|
|
210
210
|
class RealtimeError extends Error {
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
const StreamingErrorType = {
|
|
214
|
+
BadSampleRate: 4000,
|
|
215
|
+
AuthFailed: 4001,
|
|
216
|
+
InsufficientFunds: 4002,
|
|
217
|
+
FreeTierUser: 4003,
|
|
218
|
+
NonexistentSessionId: 4004,
|
|
219
|
+
SessionExpired: 4008,
|
|
220
|
+
ClosedSession: 4010,
|
|
221
|
+
RateLimited: 4029,
|
|
222
|
+
UniqueSessionViolation: 4030,
|
|
223
|
+
SessionTimeout: 4031,
|
|
224
|
+
AudioTooShort: 4032,
|
|
225
|
+
AudioTooLong: 4033,
|
|
226
|
+
AudioTooSmallToTranscode: 4034,
|
|
227
|
+
BadSchema: 4101,
|
|
228
|
+
TooManyStreams: 4102,
|
|
229
|
+
Reconnected: 4103,
|
|
230
|
+
};
|
|
231
|
+
const StreamingErrorMessages = {
|
|
232
|
+
[StreamingErrorType.BadSampleRate]: "Sample rate must be a positive integer",
|
|
233
|
+
[StreamingErrorType.AuthFailed]: "Not Authorized",
|
|
234
|
+
[StreamingErrorType.InsufficientFunds]: "Insufficient funds",
|
|
235
|
+
[StreamingErrorType.FreeTierUser]: "This feature is paid-only and requires you to add a credit card. Please visit https://app.assemblyai.com/ to add a credit card to your account.",
|
|
236
|
+
[StreamingErrorType.NonexistentSessionId]: "Session ID does not exist",
|
|
237
|
+
[StreamingErrorType.SessionExpired]: "Session has expired",
|
|
238
|
+
[StreamingErrorType.ClosedSession]: "Session is closed",
|
|
239
|
+
[StreamingErrorType.RateLimited]: "Rate limited",
|
|
240
|
+
[StreamingErrorType.UniqueSessionViolation]: "Unique session violation",
|
|
241
|
+
[StreamingErrorType.SessionTimeout]: "Session Timeout",
|
|
242
|
+
[StreamingErrorType.AudioTooShort]: "Audio too short",
|
|
243
|
+
[StreamingErrorType.AudioTooLong]: "Audio too long",
|
|
244
|
+
[StreamingErrorType.AudioTooSmallToTranscode]: "Audio too small to transcode",
|
|
245
|
+
[StreamingErrorType.BadSchema]: "Bad schema",
|
|
246
|
+
[StreamingErrorType.TooManyStreams]: "Too many streams",
|
|
247
|
+
[StreamingErrorType.Reconnected]: "This session has been reconnected. This WebSocket is no longer valid.",
|
|
248
|
+
};
|
|
249
|
+
class StreamingError extends Error {
|
|
250
|
+
}
|
|
251
|
+
|
|
213
252
|
const defaultRealtimeUrl = "wss://api.assemblyai.com/v2/realtime/ws";
|
|
214
253
|
const forceEndOfUtteranceMessage = `{"force_end_utterance":true}`;
|
|
215
|
-
const terminateSessionMessage = `{"terminate_session":true}`;
|
|
254
|
+
const terminateSessionMessage$1 = `{"terminate_session":true}`;
|
|
216
255
|
/**
|
|
217
256
|
* RealtimeTranscriber connects to the Streaming Speech-to-Text API and lets you transcribe audio in real-time.
|
|
218
257
|
*/
|
|
@@ -405,11 +444,11 @@ Learn more at https://github.com/AssemblyAI/assemblyai-node-sdk/blob/main/docs/c
|
|
|
405
444
|
const sessionTerminatedPromise = new Promise((resolve) => {
|
|
406
445
|
this.sessionTerminatedResolve = resolve;
|
|
407
446
|
});
|
|
408
|
-
this.socket.send(terminateSessionMessage);
|
|
447
|
+
this.socket.send(terminateSessionMessage$1);
|
|
409
448
|
await sessionTerminatedPromise;
|
|
410
449
|
}
|
|
411
450
|
else {
|
|
412
|
-
this.socket.send(terminateSessionMessage);
|
|
451
|
+
this.socket.send(terminateSessionMessage$1);
|
|
413
452
|
}
|
|
414
453
|
}
|
|
415
454
|
if (this.socket?.removeAllListeners)
|
|
@@ -746,7 +785,166 @@ function dataUrlToBlob(dataUrl) {
|
|
|
746
785
|
return new Blob([u8arr], { type: mime });
|
|
747
786
|
}
|
|
748
787
|
|
|
788
|
+
const defaultStreamingUrl$1 = "wss://streaming.assemblyai.com/v3/ws";
|
|
789
|
+
const terminateSessionMessage = `{"type":"Terminate"}`;
|
|
790
|
+
class StreamingTranscriber {
|
|
791
|
+
constructor(params) {
|
|
792
|
+
this.listeners = {};
|
|
793
|
+
this.params = {
|
|
794
|
+
...params,
|
|
795
|
+
websocketBaseUrl: params.websocketBaseUrl || defaultStreamingUrl$1,
|
|
796
|
+
};
|
|
797
|
+
if ("token" in params && params.token)
|
|
798
|
+
this.token = params.token;
|
|
799
|
+
if ("apiKey" in params && params.apiKey)
|
|
800
|
+
this.apiKey = params.apiKey;
|
|
801
|
+
if (!(this.token || this.apiKey)) {
|
|
802
|
+
throw new Error("API key or temporary token is required.");
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
connectionUrl() {
|
|
806
|
+
const url = new URL(this.params.websocketBaseUrl ?? "");
|
|
807
|
+
if (url.protocol !== "wss:") {
|
|
808
|
+
throw new Error("Invalid protocol, must be wss");
|
|
809
|
+
}
|
|
810
|
+
const searchParams = new URLSearchParams();
|
|
811
|
+
searchParams.set("sample_rate", this.params.sampleRate.toString());
|
|
812
|
+
if (this.params.wordFinalizationMaxWaitTime) {
|
|
813
|
+
searchParams.set("word_finalization_max_wait_time", this.params.wordFinalizationMaxWaitTime.toString());
|
|
814
|
+
}
|
|
815
|
+
if (this.params.endOfTurnConfidenceThreshold) {
|
|
816
|
+
searchParams.set("end_of_turn_confidence_threshold", this.params.endOfTurnConfidenceThreshold.toString());
|
|
817
|
+
}
|
|
818
|
+
if (this.params.minEndOfTurnSilenceWhenConfident) {
|
|
819
|
+
searchParams.set("min_end_of_turn_silence_when_confident", this.params.minEndOfTurnSilenceWhenConfident.toString());
|
|
820
|
+
}
|
|
821
|
+
if (this.params.maxTurnSilence) {
|
|
822
|
+
searchParams.set("max_turn_silence", this.params.maxTurnSilence.toString());
|
|
823
|
+
}
|
|
824
|
+
if (this.params.formattedFinals) {
|
|
825
|
+
searchParams.set("formatted_finals", this.params.formattedFinals.toString());
|
|
826
|
+
}
|
|
827
|
+
url.search = searchParams.toString();
|
|
828
|
+
return url;
|
|
829
|
+
}
|
|
830
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
831
|
+
on(event, listener) {
|
|
832
|
+
this.listeners[event] = listener;
|
|
833
|
+
}
|
|
834
|
+
connect() {
|
|
835
|
+
return new Promise((resolve) => {
|
|
836
|
+
if (this.socket) {
|
|
837
|
+
throw new Error("Already connected");
|
|
838
|
+
}
|
|
839
|
+
const url = this.connectionUrl();
|
|
840
|
+
this.socket = factory(url.toString(), {
|
|
841
|
+
headers: { Authorization: this.token || this.apiKey },
|
|
842
|
+
});
|
|
843
|
+
this.socket.binaryType = "arraybuffer";
|
|
844
|
+
this.socket.onopen = () => { };
|
|
845
|
+
this.socket.onclose = ({ code, reason }) => {
|
|
846
|
+
if (!reason) {
|
|
847
|
+
if (code in StreamingErrorMessages) {
|
|
848
|
+
reason = StreamingErrorMessages[code];
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
this.listeners.close?.(code, reason);
|
|
852
|
+
};
|
|
853
|
+
this.socket.onerror = (event) => {
|
|
854
|
+
if (event.error)
|
|
855
|
+
this.listeners.error?.(event.error);
|
|
856
|
+
else
|
|
857
|
+
this.listeners.error?.(new Error(event.message));
|
|
858
|
+
};
|
|
859
|
+
this.socket.onmessage = ({ data }) => {
|
|
860
|
+
const message = JSON.parse(data.toString());
|
|
861
|
+
if ("error" in message) {
|
|
862
|
+
this.listeners.error?.(new StreamingError(message.error));
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
switch (message.type) {
|
|
866
|
+
case "Begin": {
|
|
867
|
+
resolve(message);
|
|
868
|
+
this.listeners.open?.(message);
|
|
869
|
+
break;
|
|
870
|
+
}
|
|
871
|
+
case "Turn": {
|
|
872
|
+
this.listeners.turn?.(message);
|
|
873
|
+
break;
|
|
874
|
+
}
|
|
875
|
+
case "Termination": {
|
|
876
|
+
this.sessionTerminatedResolve?.();
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
};
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
stream() {
|
|
884
|
+
return new WritableStream({
|
|
885
|
+
write: (chunk) => {
|
|
886
|
+
this.sendAudio(chunk);
|
|
887
|
+
},
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
sendAudio(audio) {
|
|
891
|
+
this.send(audio);
|
|
892
|
+
}
|
|
893
|
+
send(data) {
|
|
894
|
+
if (!this.socket || this.socket.readyState !== this.socket.OPEN) {
|
|
895
|
+
throw new Error("Socket is not open for communication");
|
|
896
|
+
}
|
|
897
|
+
this.socket.send(data);
|
|
898
|
+
}
|
|
899
|
+
async close(waitForSessionTermination = true) {
|
|
900
|
+
if (this.socket) {
|
|
901
|
+
if (this.socket.readyState === this.socket.OPEN) {
|
|
902
|
+
if (waitForSessionTermination) {
|
|
903
|
+
const sessionTerminatedPromise = new Promise((resolve) => {
|
|
904
|
+
this.sessionTerminatedResolve = resolve;
|
|
905
|
+
});
|
|
906
|
+
this.socket.send(terminateSessionMessage);
|
|
907
|
+
await sessionTerminatedPromise;
|
|
908
|
+
}
|
|
909
|
+
else {
|
|
910
|
+
this.socket.send(terminateSessionMessage);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
if (this.socket?.removeAllListeners)
|
|
914
|
+
this.socket.removeAllListeners();
|
|
915
|
+
this.socket.close();
|
|
916
|
+
}
|
|
917
|
+
this.listeners = {};
|
|
918
|
+
this.socket = undefined;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
class StreamingTranscriberFactory extends BaseService {
|
|
923
|
+
constructor(params) {
|
|
924
|
+
super(params);
|
|
925
|
+
}
|
|
926
|
+
transcriber(params) {
|
|
927
|
+
return new StreamingTranscriber(params);
|
|
928
|
+
}
|
|
929
|
+
async createTemporaryToken(params) {
|
|
930
|
+
const searchParams = new URLSearchParams();
|
|
931
|
+
// Add each param to the search params
|
|
932
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
933
|
+
if (value !== undefined && value !== null) {
|
|
934
|
+
searchParams.append(key, String(value));
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
const queryString = searchParams.toString();
|
|
938
|
+
const url = queryString ? `/v3/token?${queryString}` : "/v3/token";
|
|
939
|
+
const data = await this.fetchJson(url, {
|
|
940
|
+
method: "GET",
|
|
941
|
+
});
|
|
942
|
+
return data.token;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
749
946
|
const defaultBaseUrl = "https://api.assemblyai.com";
|
|
947
|
+
const defaultStreamingUrl = "https://streaming.assemblyai.com";
|
|
750
948
|
class AssemblyAI {
|
|
751
949
|
/**
|
|
752
950
|
* Create a new AssemblyAI client.
|
|
@@ -761,7 +959,11 @@ class AssemblyAI {
|
|
|
761
959
|
this.transcripts = new TranscriptService(params, this.files);
|
|
762
960
|
this.lemur = new LemurService(params);
|
|
763
961
|
this.realtime = new RealtimeTranscriberFactory(params);
|
|
962
|
+
this.streaming = new StreamingTranscriberFactory({
|
|
963
|
+
...params,
|
|
964
|
+
baseUrl: params.streamingBaseUrl || defaultStreamingUrl,
|
|
965
|
+
});
|
|
764
966
|
}
|
|
765
967
|
}
|
|
766
968
|
|
|
767
|
-
export { AssemblyAI, FileService, LemurService, RealtimeService, RealtimeServiceFactory, RealtimeTranscriber, RealtimeTranscriberFactory, TranscriptService };
|
|
969
|
+
export { AssemblyAI, FileService, LemurService, RealtimeService, RealtimeServiceFactory, RealtimeTranscriber, RealtimeTranscriberFactory, StreamingTranscriber, TranscriptService };
|