assemblyai 4.3.4 → 4.4.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/CHANGELOG.md +23 -1
- package/README.md +1 -0
- package/dist/assemblyai.umd.js +21 -2
- package/dist/assemblyai.umd.min.js +1 -1
- package/dist/bun.mjs +19 -0
- package/dist/deno.mjs +19 -0
- package/dist/index.cjs +21 -2
- package/dist/index.mjs +21 -2
- package/dist/node.cjs +19 -0
- package/dist/node.mjs +19 -0
- package/dist/services/realtime/service.d.ts +3 -1
- package/dist/types/asyncapi.generated.d.ts +35 -2
- package/dist/types/openapi.generated.d.ts +4 -0
- package/dist/types/realtime/index.d.ts +29 -2
- package/package.json +8 -4
- package/src/services/realtime/service.ts +21 -0
- package/src/services/transcripts/index.ts +13 -0
- package/src/types/asyncapi.generated.ts +36 -0
- package/src/types/openapi.generated.ts +4 -0
- package/src/types/realtime/index.ts +29 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.4.1] - 2024-04-16
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Deprecate `enableExtraSessionInformation` parameter in `CreateRealtimeTranscriberParams` type
|
|
8
|
+
|
|
9
|
+
## [4.4.0] - 2024-04-12
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Add `disablePartialTranscripts` parameter to `CreateRealtimeTranscriberParams`
|
|
14
|
+
- Add `enableExtraSessionInformation` parameter to `CreateRealtimeTranscriberParams`
|
|
15
|
+
- Add `session_information` event to `RealtimeTranscriber.on()`
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- ⚠️ Deprecate `conformer-2` literal for `TranscriptParams.speech_model` property
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Add missing `status` property to `AutoHighlightsResult`
|
|
24
|
+
|
|
3
25
|
## [4.3.4] - 2024-04-02
|
|
4
26
|
|
|
5
27
|
### Added
|
|
@@ -7,7 +29,7 @@
|
|
|
7
29
|
- `SpeechModel.Best` enum
|
|
8
30
|
- `TranscriptListItem.error` property
|
|
9
31
|
|
|
10
|
-
###
|
|
32
|
+
### Changed
|
|
11
33
|
|
|
12
34
|
- Make `PageDetails.prev_url` nullable
|
|
13
35
|
- Rename Realtime to Streaming inside code documentation
|
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ It is written primarily for Node.js in TypeScript with all types exported, but a
|
|
|
19
19
|
## Documentation
|
|
20
20
|
|
|
21
21
|
Visit the [AssemblyAI documentation](https://www.assemblyai.com/docs) for step-by-step instructions and a lot more details about our AI models and API.
|
|
22
|
+
Explore the [SDK API reference](https://assemblyai.github.io/assemblyai-node-sdk/) for more details on the SDK types, functions, and classes.
|
|
22
23
|
|
|
23
24
|
## Quickstart
|
|
24
25
|
|
package/dist/assemblyai.umd.js
CHANGED
|
@@ -206,6 +206,7 @@
|
|
|
206
206
|
this.wordBoost = params.wordBoost;
|
|
207
207
|
this.encoding = params.encoding;
|
|
208
208
|
this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
|
|
209
|
+
this.disablePartialTranscripts = params.disablePartialTranscripts;
|
|
209
210
|
if ("token" in params && params.token)
|
|
210
211
|
this.token = params.token;
|
|
211
212
|
if ("apiKey" in params && params.apiKey)
|
|
@@ -230,6 +231,10 @@
|
|
|
230
231
|
if (this.encoding) {
|
|
231
232
|
searchParams.set("encoding", this.encoding);
|
|
232
233
|
}
|
|
234
|
+
searchParams.set("enable_extra_session_information", "true");
|
|
235
|
+
if (this.disablePartialTranscripts) {
|
|
236
|
+
searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
|
|
237
|
+
}
|
|
233
238
|
url.search = searchParams.toString();
|
|
234
239
|
return url;
|
|
235
240
|
}
|
|
@@ -276,7 +281,7 @@
|
|
|
276
281
|
(_d = (_c = this.listeners).error) === null || _d === void 0 ? void 0 : _d.call(_c, new Error(event.message));
|
|
277
282
|
};
|
|
278
283
|
this.socket.onmessage = ({ data }) => {
|
|
279
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
284
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
280
285
|
const message = JSON.parse(data.toString());
|
|
281
286
|
if ("error" in message) {
|
|
282
287
|
(_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, new RealtimeError(message.error));
|
|
@@ -306,8 +311,12 @@
|
|
|
306
311
|
(_m = (_l = this.listeners)["transcript.final"]) === null || _m === void 0 ? void 0 : _m.call(_l, message);
|
|
307
312
|
break;
|
|
308
313
|
}
|
|
314
|
+
case "SessionInformation": {
|
|
315
|
+
(_p = (_o = this.listeners).session_information) === null || _p === void 0 ? void 0 : _p.call(_o, message);
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
309
318
|
case "SessionTerminated": {
|
|
310
|
-
(
|
|
319
|
+
(_q = this.sessionTerminatedResolve) === null || _q === void 0 ? void 0 : _q.call(this);
|
|
311
320
|
break;
|
|
312
321
|
}
|
|
313
322
|
}
|
|
@@ -433,6 +442,7 @@
|
|
|
433
442
|
*/
|
|
434
443
|
transcribe(params, options) {
|
|
435
444
|
return __awaiter(this, void 0, void 0, function* () {
|
|
445
|
+
deprecateConformer2(params);
|
|
436
446
|
const transcript = yield this.submit(params);
|
|
437
447
|
return yield this.waitUntilReady(transcript.id, options);
|
|
438
448
|
});
|
|
@@ -444,6 +454,7 @@
|
|
|
444
454
|
*/
|
|
445
455
|
submit(params) {
|
|
446
456
|
return __awaiter(this, void 0, void 0, function* () {
|
|
457
|
+
deprecateConformer2(params);
|
|
447
458
|
let audioUrl;
|
|
448
459
|
let transcriptParams = undefined;
|
|
449
460
|
if ("audio" in params) {
|
|
@@ -485,6 +496,7 @@
|
|
|
485
496
|
create(params, options) {
|
|
486
497
|
return __awaiter(this, void 0, void 0, function* () {
|
|
487
498
|
var _a;
|
|
499
|
+
deprecateConformer2(params);
|
|
488
500
|
const path = getPath(params.audio_url);
|
|
489
501
|
if (path !== null) {
|
|
490
502
|
const uploadUrl = yield this.files.upload(path);
|
|
@@ -628,6 +640,13 @@
|
|
|
628
640
|
return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
|
|
629
641
|
}
|
|
630
642
|
}
|
|
643
|
+
function deprecateConformer2(params) {
|
|
644
|
+
if (!params)
|
|
645
|
+
return;
|
|
646
|
+
if (params.speech_model === "conformer-2") {
|
|
647
|
+
console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.");
|
|
648
|
+
}
|
|
649
|
+
}
|
|
631
650
|
|
|
632
651
|
const readFile = function (
|
|
633
652
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -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{c(i.next(e))}catch(e){o(e)}}function a(e){try{c(i.throw(e))}catch(e){o(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(r,a)}c((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),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=null;"undefined"!=typeof WebSocket?o=WebSocket:"undefined"!=typeof MozWebSocket?o=MozWebSocket:"undefined"!=typeof global?o=global.WebSocket||global.MozWebSocket:"undefined"!=typeof window?o=window.WebSocket||window.MozWebSocket:"undefined"!=typeof self&&(o=self.WebSocket||self.MozWebSocket);var r,a=o;!function(e){e[e.BadSampleRate=4e3]="BadSampleRate",e[e.AuthFailed=4001]="AuthFailed",e[e.InsufficientFundsOrFreeAccount=4002]="InsufficientFundsOrFreeAccount",e[e.NonexistentSessionId=4004]="NonexistentSessionId",e[e.SessionExpired=4008]="SessionExpired",e[e.ClosedSession=4010]="ClosedSession",e[e.RateLimited=4029]="RateLimited",e[e.UniqueSessionViolation=4030]="UniqueSessionViolation",e[e.SessionTimeout=4031]="SessionTimeout",e[e.AudioTooShort=4032]="AudioTooShort",e[e.AudioTooLong=4033]="AudioTooLong",e[e.BadJson=4100]="BadJson",e[e.BadSchema=4101]="BadSchema",e[e.TooManyStreams=4102]="TooManyStreams",e[e.Reconnected=4103]="Reconnected",e[e.ReconnectAttemptsExhausted=1013]="ReconnectAttemptsExhausted"}(r||(r={}));const c={[r.BadSampleRate]:"Sample rate must be a positive integer",[r.AuthFailed]:"Not Authorized",[r.InsufficientFundsOrFreeAccount]:"Insufficient funds or you are using a free account. This feature is paid-only and requires you to add a credit card. Please visit https://assemblyai.com/dashboard/ to add a credit card to your account.",[r.NonexistentSessionId]:"Session ID does not exist",[r.SessionExpired]:"Session has expired",[r.ClosedSession]:"Session is closed",[r.RateLimited]:"Rate limited",[r.UniqueSessionViolation]:"Unique session violation",[r.SessionTimeout]:"Session Timeout",[r.AudioTooShort]:"Audio too short",[r.AudioTooLong]:"Audio too long",[r.BadJson]:"Bad JSON",[r.BadSchema]:"Bad schema",[r.TooManyStreams]:"Too many streams",[r.Reconnected]:"Reconnected",[r.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class l extends Error{}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,"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.")}connectionUrl(){const e=new URL(this.realtimeUrl);if("wss:"!==e.protocol)throw new Error("Invalid protocol, must be wss");const t=new URLSearchParams;return this.token&&t.set("token",this.token),t.set("sample_rate",this.sampleRate.toString()),this.wordBoost&&this.wordBoost.length>0&&t.set("word_boost",JSON.stringify(this.wordBoost)),this.encoding&&t.set("encoding",this.encoding),e.search=t.toString(),e}on(e,t){this.listeners[e]=t}connect(){return new Promise((e=>{if(this.socket)throw new Error("Already connected");const t=this.connectionUrl();this.token?this.socket=new a(t.toString()):this.socket=new a(t.toString(),{headers:{Authorization:this.apiKey}}),this.socket.binaryType="arraybuffer",this.socket.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 r&&(t=c[e]),null===(i=(s=this.listeners).close)||void 0===i||i.call(s,e,t)},this.socket.onerror=e=>{var t,s,i,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,c,d,h,u,f,p,m;const y=JSON.parse(t.toString());if("error"in y)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new l(y.error));else switch(y.message_type){case"SessionBegins":{const t={sessionId:y.session_id,expiresAt:new Date(y.expires_at)};e(t),null===(o=(n=this.listeners).open)||void 0===o||o.call(n,t);break}case"PartialTranscript":y.created=new Date(y.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,y),null===(d=(c=this.listeners)["transcript.partial"])||void 0===d||d.call(c,y);break;case"FinalTranscript":y.created=new Date(y.created),null===(u=(h=this.listeners).transcript)||void 0===u||u.call(h,y),null===(p=(f=this.listeners)["transcript.final"])||void 0===p||p.call(f,y);break;case"SessionTerminated":null===(m=this.sessionTerminatedResolve)||void 0===m||m.call(this)}}}))}sendAudio(e){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!==a.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return t(this,arguments,void 0,(function*(e=!0){if(this.socket){if(this.socket.readyState===a.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(d),yield e}else this.socket.send(d);"removeAllListeners"in this.socket&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class u extends s{constructor(e){super(e),this.rtFactoryParams=e}createService(e){return this.transcriber(e)}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.rtFactoryParams.apiKey),new h(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 f(e){return e.startsWith("http")||e.startsWith("https")?null:e.startsWith("file://")?e.substring(7):e.startsWith("file:")?e.substring(5):e}class p extends s{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){const t=yield this.submit(e);return yield this.waitUntilReady(t.id,s)}))}submit(e){return t(this,void 0,void 0,(function*(){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=f(i);t=null!==e?yield this.files.upload(e):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=f(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`)}}class m extends s{upload(e){return t(this,void 0,void 0,(function*(){let s;s="string"==typeof e?yield function(e){return t(this,void 0,void 0,(function*(){throw new Error("Interacting with the file system is not supported in this environment.")}))}():e;return(yield this.fetchJson("/v2/upload",{method:"POST",body:s,headers:{"Content-Type":"application/octet-stream"},duplex:"half"})).upload_url}))}}e.AssemblyAI=class{constructor(e){e.baseUrl=e.baseUrl||"https://api.assemblyai.com",e.baseUrl&&e.baseUrl.endsWith("/")&&(e.baseUrl=e.baseUrl.slice(0,-1)),this.files=new m(e),this.transcripts=new p(e,this.files),this.lemur=new i(e),this.realtime=new u(e)}},e.FileService=m,e.LemurService=i,e.RealtimeService=class extends h{},e.RealtimeServiceFactory=class extends u{},e.RealtimeTranscriber=h,e.RealtimeTranscriberFactory=u,e.TranscriptService=p}));
|
|
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{c(i.next(e))}catch(e){o(e)}}function a(e){try{c(i.throw(e))}catch(e){o(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(r,a)}c((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),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=null;"undefined"!=typeof WebSocket?o=WebSocket:"undefined"!=typeof MozWebSocket?o=MozWebSocket:"undefined"!=typeof global?o=global.WebSocket||global.MozWebSocket:"undefined"!=typeof window?o=window.WebSocket||window.MozWebSocket:"undefined"!=typeof self&&(o=self.WebSocket||self.MozWebSocket);var r,a=o;!function(e){e[e.BadSampleRate=4e3]="BadSampleRate",e[e.AuthFailed=4001]="AuthFailed",e[e.InsufficientFundsOrFreeAccount=4002]="InsufficientFundsOrFreeAccount",e[e.NonexistentSessionId=4004]="NonexistentSessionId",e[e.SessionExpired=4008]="SessionExpired",e[e.ClosedSession=4010]="ClosedSession",e[e.RateLimited=4029]="RateLimited",e[e.UniqueSessionViolation=4030]="UniqueSessionViolation",e[e.SessionTimeout=4031]="SessionTimeout",e[e.AudioTooShort=4032]="AudioTooShort",e[e.AudioTooLong=4033]="AudioTooLong",e[e.BadJson=4100]="BadJson",e[e.BadSchema=4101]="BadSchema",e[e.TooManyStreams=4102]="TooManyStreams",e[e.Reconnected=4103]="Reconnected",e[e.ReconnectAttemptsExhausted=1013]="ReconnectAttemptsExhausted"}(r||(r={}));const c={[r.BadSampleRate]:"Sample rate must be a positive integer",[r.AuthFailed]:"Not Authorized",[r.InsufficientFundsOrFreeAccount]:"Insufficient funds or you are using a free account. This feature is paid-only and requires you to add a credit card. Please visit https://assemblyai.com/dashboard/ to add a credit card to your account.",[r.NonexistentSessionId]:"Session ID does not exist",[r.SessionExpired]:"Session has expired",[r.ClosedSession]:"Session is closed",[r.RateLimited]:"Rate limited",[r.UniqueSessionViolation]:"Unique session violation",[r.SessionTimeout]:"Session Timeout",[r.AudioTooShort]:"Audio too short",[r.AudioTooLong]:"Audio too long",[r.BadJson]:"Bad JSON",[r.BadSchema]:"Bad schema",[r.TooManyStreams]:"Too many streams",[r.Reconnected]:"Reconnected",[r.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class l extends Error{}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=new a(t.toString()):this.socket=new a(t.toString(),{headers:{Authorization:this.apiKey}}),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{void 0!==this.endUtteranceSilenceThreshold&&null!==this.endUtteranceSilenceThreshold&&this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold)},this.socket.onclose=({code:e,reason:t})=>{var s,i;t||e in r&&(t=c[e]),null===(i=(s=this.listeners).close)||void 0===i||i.call(s,e,t)},this.socket.onerror=e=>{var t,s,i,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,c,d,h,u,f,p,m,y,S;const v=JSON.parse(t.toString());if("error"in v)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new l(v.error));else switch(v.message_type){case"SessionBegins":{const t={sessionId:v.session_id,expiresAt:new Date(v.expires_at)};e(t),null===(o=(n=this.listeners).open)||void 0===o||o.call(n,t);break}case"PartialTranscript":v.created=new Date(v.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,v),null===(d=(c=this.listeners)["transcript.partial"])||void 0===d||d.call(c,v);break;case"FinalTranscript":v.created=new Date(v.created),null===(u=(h=this.listeners).transcript)||void 0===u||u.call(h,v),null===(p=(f=this.listeners)["transcript.final"])||void 0===p||p.call(f,v);break;case"SessionInformation":null===(y=(m=this.listeners).session_information)||void 0===y||y.call(m,v);break;case"SessionTerminated":null===(S=this.sessionTerminatedResolve)||void 0===S||S.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!==a.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return t(this,arguments,void 0,(function*(e=!0){if(this.socket){if(this.socket.readyState===a.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(d),yield e}else this.socket.send(d);"removeAllListeners"in this.socket&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class u extends s{constructor(e){super(e),this.rtFactoryParams=e}createService(e){return this.transcriber(e)}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.rtFactoryParams.apiKey),new h(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 f(e){return e.startsWith("http")||e.startsWith("https")?null:e.startsWith("file://")?e.substring(7):e.startsWith("file:")?e.substring(5):e}class p extends s{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){m(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(m(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=f(i);t=null!==e?yield this.files.upload(e):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;m(e);const i=f(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 m(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 y extends s{upload(e){return t(this,void 0,void 0,(function*(){let s;s="string"==typeof e?yield function(e){return t(this,void 0,void 0,(function*(){throw new Error("Interacting with the file system is not supported in this environment.")}))}():e;return(yield this.fetchJson("/v2/upload",{method:"POST",body:s,headers:{"Content-Type":"application/octet-stream"},duplex:"half"})).upload_url}))}}e.AssemblyAI=class{constructor(e){e.baseUrl=e.baseUrl||"https://api.assemblyai.com",e.baseUrl&&e.baseUrl.endsWith("/")&&(e.baseUrl=e.baseUrl.slice(0,-1)),this.files=new y(e),this.transcripts=new p(e,this.files),this.lemur=new i(e),this.realtime=new u(e)}},e.FileService=y,e.LemurService=i,e.RealtimeService=class extends h{},e.RealtimeServiceFactory=class extends u{},e.RealtimeTranscriber=h,e.RealtimeTranscriberFactory=u,e.TranscriptService=p}));
|
package/dist/bun.mjs
CHANGED
|
@@ -140,6 +140,7 @@ class RealtimeTranscriber {
|
|
|
140
140
|
this.wordBoost = params.wordBoost;
|
|
141
141
|
this.encoding = params.encoding;
|
|
142
142
|
this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
|
|
143
|
+
this.disablePartialTranscripts = params.disablePartialTranscripts;
|
|
143
144
|
if ("token" in params && params.token)
|
|
144
145
|
this.token = params.token;
|
|
145
146
|
if ("apiKey" in params && params.apiKey)
|
|
@@ -164,6 +165,10 @@ class RealtimeTranscriber {
|
|
|
164
165
|
if (this.encoding) {
|
|
165
166
|
searchParams.set("encoding", this.encoding);
|
|
166
167
|
}
|
|
168
|
+
searchParams.set("enable_extra_session_information", "true");
|
|
169
|
+
if (this.disablePartialTranscripts) {
|
|
170
|
+
searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
|
|
171
|
+
}
|
|
167
172
|
url.search = searchParams.toString();
|
|
168
173
|
return url;
|
|
169
174
|
}
|
|
@@ -237,6 +242,10 @@ class RealtimeTranscriber {
|
|
|
237
242
|
this.listeners["transcript.final"]?.(message);
|
|
238
243
|
break;
|
|
239
244
|
}
|
|
245
|
+
case "SessionInformation": {
|
|
246
|
+
this.listeners.session_information?.(message);
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
240
249
|
case "SessionTerminated": {
|
|
241
250
|
this.sessionTerminatedResolve?.();
|
|
242
251
|
break;
|
|
@@ -359,6 +368,7 @@ class TranscriptService extends BaseService {
|
|
|
359
368
|
* @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
|
|
360
369
|
*/
|
|
361
370
|
async transcribe(params, options) {
|
|
371
|
+
deprecateConformer2(params);
|
|
362
372
|
const transcript = await this.submit(params);
|
|
363
373
|
return await this.waitUntilReady(transcript.id, options);
|
|
364
374
|
}
|
|
@@ -368,6 +378,7 @@ class TranscriptService extends BaseService {
|
|
|
368
378
|
* @returns A promise that resolves to the queued transcript.
|
|
369
379
|
*/
|
|
370
380
|
async submit(params) {
|
|
381
|
+
deprecateConformer2(params);
|
|
371
382
|
let audioUrl;
|
|
372
383
|
let transcriptParams = undefined;
|
|
373
384
|
if ("audio" in params) {
|
|
@@ -406,6 +417,7 @@ class TranscriptService extends BaseService {
|
|
|
406
417
|
* @deprecated Use `transcribe` instead to transcribe a audio file that includes polling, or `submit` to transcribe a audio file without polling.
|
|
407
418
|
*/
|
|
408
419
|
async create(params, options) {
|
|
420
|
+
deprecateConformer2(params);
|
|
409
421
|
const path = getPath(params.audio_url);
|
|
410
422
|
if (path !== null) {
|
|
411
423
|
const uploadUrl = await this.files.upload(path);
|
|
@@ -538,6 +550,13 @@ class TranscriptService extends BaseService {
|
|
|
538
550
|
return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
|
|
539
551
|
}
|
|
540
552
|
}
|
|
553
|
+
function deprecateConformer2(params) {
|
|
554
|
+
if (!params)
|
|
555
|
+
return;
|
|
556
|
+
if (params.speech_model === "conformer-2") {
|
|
557
|
+
console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.");
|
|
558
|
+
}
|
|
559
|
+
}
|
|
541
560
|
|
|
542
561
|
const readFile = async (path) => Bun.file(path).stream();
|
|
543
562
|
|
package/dist/deno.mjs
CHANGED
|
@@ -140,6 +140,7 @@ class RealtimeTranscriber {
|
|
|
140
140
|
this.wordBoost = params.wordBoost;
|
|
141
141
|
this.encoding = params.encoding;
|
|
142
142
|
this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
|
|
143
|
+
this.disablePartialTranscripts = params.disablePartialTranscripts;
|
|
143
144
|
if ("token" in params && params.token)
|
|
144
145
|
this.token = params.token;
|
|
145
146
|
if ("apiKey" in params && params.apiKey)
|
|
@@ -164,6 +165,10 @@ class RealtimeTranscriber {
|
|
|
164
165
|
if (this.encoding) {
|
|
165
166
|
searchParams.set("encoding", this.encoding);
|
|
166
167
|
}
|
|
168
|
+
searchParams.set("enable_extra_session_information", "true");
|
|
169
|
+
if (this.disablePartialTranscripts) {
|
|
170
|
+
searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
|
|
171
|
+
}
|
|
167
172
|
url.search = searchParams.toString();
|
|
168
173
|
return url;
|
|
169
174
|
}
|
|
@@ -237,6 +242,10 @@ class RealtimeTranscriber {
|
|
|
237
242
|
this.listeners["transcript.final"]?.(message);
|
|
238
243
|
break;
|
|
239
244
|
}
|
|
245
|
+
case "SessionInformation": {
|
|
246
|
+
this.listeners.session_information?.(message);
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
240
249
|
case "SessionTerminated": {
|
|
241
250
|
this.sessionTerminatedResolve?.();
|
|
242
251
|
break;
|
|
@@ -359,6 +368,7 @@ class TranscriptService extends BaseService {
|
|
|
359
368
|
* @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
|
|
360
369
|
*/
|
|
361
370
|
async transcribe(params, options) {
|
|
371
|
+
deprecateConformer2(params);
|
|
362
372
|
const transcript = await this.submit(params);
|
|
363
373
|
return await this.waitUntilReady(transcript.id, options);
|
|
364
374
|
}
|
|
@@ -368,6 +378,7 @@ class TranscriptService extends BaseService {
|
|
|
368
378
|
* @returns A promise that resolves to the queued transcript.
|
|
369
379
|
*/
|
|
370
380
|
async submit(params) {
|
|
381
|
+
deprecateConformer2(params);
|
|
371
382
|
let audioUrl;
|
|
372
383
|
let transcriptParams = undefined;
|
|
373
384
|
if ("audio" in params) {
|
|
@@ -406,6 +417,7 @@ class TranscriptService extends BaseService {
|
|
|
406
417
|
* @deprecated Use `transcribe` instead to transcribe a audio file that includes polling, or `submit` to transcribe a audio file without polling.
|
|
407
418
|
*/
|
|
408
419
|
async create(params, options) {
|
|
420
|
+
deprecateConformer2(params);
|
|
409
421
|
const path = getPath(params.audio_url);
|
|
410
422
|
if (path !== null) {
|
|
411
423
|
const uploadUrl = await this.files.upload(path);
|
|
@@ -538,6 +550,13 @@ class TranscriptService extends BaseService {
|
|
|
538
550
|
return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
|
|
539
551
|
}
|
|
540
552
|
}
|
|
553
|
+
function deprecateConformer2(params) {
|
|
554
|
+
if (!params)
|
|
555
|
+
return;
|
|
556
|
+
if (params.speech_model === "conformer-2") {
|
|
557
|
+
console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.");
|
|
558
|
+
}
|
|
559
|
+
}
|
|
541
560
|
|
|
542
561
|
const readFile = async (path) => (await Deno.open(path)).readable;
|
|
543
562
|
|
package/dist/index.cjs
CHANGED
|
@@ -188,6 +188,7 @@ class RealtimeTranscriber {
|
|
|
188
188
|
this.wordBoost = params.wordBoost;
|
|
189
189
|
this.encoding = params.encoding;
|
|
190
190
|
this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
|
|
191
|
+
this.disablePartialTranscripts = params.disablePartialTranscripts;
|
|
191
192
|
if ("token" in params && params.token)
|
|
192
193
|
this.token = params.token;
|
|
193
194
|
if ("apiKey" in params && params.apiKey)
|
|
@@ -212,6 +213,10 @@ class RealtimeTranscriber {
|
|
|
212
213
|
if (this.encoding) {
|
|
213
214
|
searchParams.set("encoding", this.encoding);
|
|
214
215
|
}
|
|
216
|
+
searchParams.set("enable_extra_session_information", "true");
|
|
217
|
+
if (this.disablePartialTranscripts) {
|
|
218
|
+
searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
|
|
219
|
+
}
|
|
215
220
|
url.search = searchParams.toString();
|
|
216
221
|
return url;
|
|
217
222
|
}
|
|
@@ -258,7 +263,7 @@ class RealtimeTranscriber {
|
|
|
258
263
|
(_d = (_c = this.listeners).error) === null || _d === void 0 ? void 0 : _d.call(_c, new Error(event.message));
|
|
259
264
|
};
|
|
260
265
|
this.socket.onmessage = ({ data }) => {
|
|
261
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
266
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
262
267
|
const message = JSON.parse(data.toString());
|
|
263
268
|
if ("error" in message) {
|
|
264
269
|
(_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, new RealtimeError(message.error));
|
|
@@ -288,8 +293,12 @@ class RealtimeTranscriber {
|
|
|
288
293
|
(_m = (_l = this.listeners)["transcript.final"]) === null || _m === void 0 ? void 0 : _m.call(_l, message);
|
|
289
294
|
break;
|
|
290
295
|
}
|
|
296
|
+
case "SessionInformation": {
|
|
297
|
+
(_p = (_o = this.listeners).session_information) === null || _p === void 0 ? void 0 : _p.call(_o, message);
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
291
300
|
case "SessionTerminated": {
|
|
292
|
-
(
|
|
301
|
+
(_q = this.sessionTerminatedResolve) === null || _q === void 0 ? void 0 : _q.call(this);
|
|
293
302
|
break;
|
|
294
303
|
}
|
|
295
304
|
}
|
|
@@ -415,6 +424,7 @@ class TranscriptService extends BaseService {
|
|
|
415
424
|
*/
|
|
416
425
|
transcribe(params, options) {
|
|
417
426
|
return __awaiter(this, void 0, void 0, function* () {
|
|
427
|
+
deprecateConformer2(params);
|
|
418
428
|
const transcript = yield this.submit(params);
|
|
419
429
|
return yield this.waitUntilReady(transcript.id, options);
|
|
420
430
|
});
|
|
@@ -426,6 +436,7 @@ class TranscriptService extends BaseService {
|
|
|
426
436
|
*/
|
|
427
437
|
submit(params) {
|
|
428
438
|
return __awaiter(this, void 0, void 0, function* () {
|
|
439
|
+
deprecateConformer2(params);
|
|
429
440
|
let audioUrl;
|
|
430
441
|
let transcriptParams = undefined;
|
|
431
442
|
if ("audio" in params) {
|
|
@@ -467,6 +478,7 @@ class TranscriptService extends BaseService {
|
|
|
467
478
|
create(params, options) {
|
|
468
479
|
return __awaiter(this, void 0, void 0, function* () {
|
|
469
480
|
var _a;
|
|
481
|
+
deprecateConformer2(params);
|
|
470
482
|
const path = getPath(params.audio_url);
|
|
471
483
|
if (path !== null) {
|
|
472
484
|
const uploadUrl = yield this.files.upload(path);
|
|
@@ -610,6 +622,13 @@ class TranscriptService extends BaseService {
|
|
|
610
622
|
return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
|
|
611
623
|
}
|
|
612
624
|
}
|
|
625
|
+
function deprecateConformer2(params) {
|
|
626
|
+
if (!params)
|
|
627
|
+
return;
|
|
628
|
+
if (params.speech_model === "conformer-2") {
|
|
629
|
+
console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.");
|
|
630
|
+
}
|
|
631
|
+
}
|
|
613
632
|
|
|
614
633
|
const readFile = function (
|
|
615
634
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
package/dist/index.mjs
CHANGED
|
@@ -186,6 +186,7 @@ class RealtimeTranscriber {
|
|
|
186
186
|
this.wordBoost = params.wordBoost;
|
|
187
187
|
this.encoding = params.encoding;
|
|
188
188
|
this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
|
|
189
|
+
this.disablePartialTranscripts = params.disablePartialTranscripts;
|
|
189
190
|
if ("token" in params && params.token)
|
|
190
191
|
this.token = params.token;
|
|
191
192
|
if ("apiKey" in params && params.apiKey)
|
|
@@ -210,6 +211,10 @@ class RealtimeTranscriber {
|
|
|
210
211
|
if (this.encoding) {
|
|
211
212
|
searchParams.set("encoding", this.encoding);
|
|
212
213
|
}
|
|
214
|
+
searchParams.set("enable_extra_session_information", "true");
|
|
215
|
+
if (this.disablePartialTranscripts) {
|
|
216
|
+
searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
|
|
217
|
+
}
|
|
213
218
|
url.search = searchParams.toString();
|
|
214
219
|
return url;
|
|
215
220
|
}
|
|
@@ -256,7 +261,7 @@ class RealtimeTranscriber {
|
|
|
256
261
|
(_d = (_c = this.listeners).error) === null || _d === void 0 ? void 0 : _d.call(_c, new Error(event.message));
|
|
257
262
|
};
|
|
258
263
|
this.socket.onmessage = ({ data }) => {
|
|
259
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
264
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
260
265
|
const message = JSON.parse(data.toString());
|
|
261
266
|
if ("error" in message) {
|
|
262
267
|
(_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, new RealtimeError(message.error));
|
|
@@ -286,8 +291,12 @@ class RealtimeTranscriber {
|
|
|
286
291
|
(_m = (_l = this.listeners)["transcript.final"]) === null || _m === void 0 ? void 0 : _m.call(_l, message);
|
|
287
292
|
break;
|
|
288
293
|
}
|
|
294
|
+
case "SessionInformation": {
|
|
295
|
+
(_p = (_o = this.listeners).session_information) === null || _p === void 0 ? void 0 : _p.call(_o, message);
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
289
298
|
case "SessionTerminated": {
|
|
290
|
-
(
|
|
299
|
+
(_q = this.sessionTerminatedResolve) === null || _q === void 0 ? void 0 : _q.call(this);
|
|
291
300
|
break;
|
|
292
301
|
}
|
|
293
302
|
}
|
|
@@ -413,6 +422,7 @@ class TranscriptService extends BaseService {
|
|
|
413
422
|
*/
|
|
414
423
|
transcribe(params, options) {
|
|
415
424
|
return __awaiter(this, void 0, void 0, function* () {
|
|
425
|
+
deprecateConformer2(params);
|
|
416
426
|
const transcript = yield this.submit(params);
|
|
417
427
|
return yield this.waitUntilReady(transcript.id, options);
|
|
418
428
|
});
|
|
@@ -424,6 +434,7 @@ class TranscriptService extends BaseService {
|
|
|
424
434
|
*/
|
|
425
435
|
submit(params) {
|
|
426
436
|
return __awaiter(this, void 0, void 0, function* () {
|
|
437
|
+
deprecateConformer2(params);
|
|
427
438
|
let audioUrl;
|
|
428
439
|
let transcriptParams = undefined;
|
|
429
440
|
if ("audio" in params) {
|
|
@@ -465,6 +476,7 @@ class TranscriptService extends BaseService {
|
|
|
465
476
|
create(params, options) {
|
|
466
477
|
return __awaiter(this, void 0, void 0, function* () {
|
|
467
478
|
var _a;
|
|
479
|
+
deprecateConformer2(params);
|
|
468
480
|
const path = getPath(params.audio_url);
|
|
469
481
|
if (path !== null) {
|
|
470
482
|
const uploadUrl = yield this.files.upload(path);
|
|
@@ -608,6 +620,13 @@ class TranscriptService extends BaseService {
|
|
|
608
620
|
return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
|
|
609
621
|
}
|
|
610
622
|
}
|
|
623
|
+
function deprecateConformer2(params) {
|
|
624
|
+
if (!params)
|
|
625
|
+
return;
|
|
626
|
+
if (params.speech_model === "conformer-2") {
|
|
627
|
+
console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.");
|
|
628
|
+
}
|
|
629
|
+
}
|
|
611
630
|
|
|
612
631
|
const readFile = function (
|
|
613
632
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
package/dist/node.cjs
CHANGED
|
@@ -139,6 +139,7 @@ class RealtimeTranscriber {
|
|
|
139
139
|
this.wordBoost = params.wordBoost;
|
|
140
140
|
this.encoding = params.encoding;
|
|
141
141
|
this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
|
|
142
|
+
this.disablePartialTranscripts = params.disablePartialTranscripts;
|
|
142
143
|
if ("token" in params && params.token)
|
|
143
144
|
this.token = params.token;
|
|
144
145
|
if ("apiKey" in params && params.apiKey)
|
|
@@ -163,6 +164,10 @@ class RealtimeTranscriber {
|
|
|
163
164
|
if (this.encoding) {
|
|
164
165
|
searchParams.set("encoding", this.encoding);
|
|
165
166
|
}
|
|
167
|
+
searchParams.set("enable_extra_session_information", "true");
|
|
168
|
+
if (this.disablePartialTranscripts) {
|
|
169
|
+
searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
|
|
170
|
+
}
|
|
166
171
|
url.search = searchParams.toString();
|
|
167
172
|
return url;
|
|
168
173
|
}
|
|
@@ -236,6 +241,10 @@ class RealtimeTranscriber {
|
|
|
236
241
|
this.listeners["transcript.final"]?.(message);
|
|
237
242
|
break;
|
|
238
243
|
}
|
|
244
|
+
case "SessionInformation": {
|
|
245
|
+
this.listeners.session_information?.(message);
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
239
248
|
case "SessionTerminated": {
|
|
240
249
|
this.sessionTerminatedResolve?.();
|
|
241
250
|
break;
|
|
@@ -358,6 +367,7 @@ class TranscriptService extends BaseService {
|
|
|
358
367
|
* @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
|
|
359
368
|
*/
|
|
360
369
|
async transcribe(params, options) {
|
|
370
|
+
deprecateConformer2(params);
|
|
361
371
|
const transcript = await this.submit(params);
|
|
362
372
|
return await this.waitUntilReady(transcript.id, options);
|
|
363
373
|
}
|
|
@@ -367,6 +377,7 @@ class TranscriptService extends BaseService {
|
|
|
367
377
|
* @returns A promise that resolves to the queued transcript.
|
|
368
378
|
*/
|
|
369
379
|
async submit(params) {
|
|
380
|
+
deprecateConformer2(params);
|
|
370
381
|
let audioUrl;
|
|
371
382
|
let transcriptParams = undefined;
|
|
372
383
|
if ("audio" in params) {
|
|
@@ -405,6 +416,7 @@ class TranscriptService extends BaseService {
|
|
|
405
416
|
* @deprecated Use `transcribe` instead to transcribe a audio file that includes polling, or `submit` to transcribe a audio file without polling.
|
|
406
417
|
*/
|
|
407
418
|
async create(params, options) {
|
|
419
|
+
deprecateConformer2(params);
|
|
408
420
|
const path = getPath(params.audio_url);
|
|
409
421
|
if (path !== null) {
|
|
410
422
|
const uploadUrl = await this.files.upload(path);
|
|
@@ -537,6 +549,13 @@ class TranscriptService extends BaseService {
|
|
|
537
549
|
return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
|
|
538
550
|
}
|
|
539
551
|
}
|
|
552
|
+
function deprecateConformer2(params) {
|
|
553
|
+
if (!params)
|
|
554
|
+
return;
|
|
555
|
+
if (params.speech_model === "conformer-2") {
|
|
556
|
+
console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.");
|
|
557
|
+
}
|
|
558
|
+
}
|
|
540
559
|
|
|
541
560
|
const readFile = async (path) => stream.Readable.toWeb(fs.createReadStream(path));
|
|
542
561
|
|
package/dist/node.mjs
CHANGED
|
@@ -137,6 +137,7 @@ class RealtimeTranscriber {
|
|
|
137
137
|
this.wordBoost = params.wordBoost;
|
|
138
138
|
this.encoding = params.encoding;
|
|
139
139
|
this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
|
|
140
|
+
this.disablePartialTranscripts = params.disablePartialTranscripts;
|
|
140
141
|
if ("token" in params && params.token)
|
|
141
142
|
this.token = params.token;
|
|
142
143
|
if ("apiKey" in params && params.apiKey)
|
|
@@ -161,6 +162,10 @@ class RealtimeTranscriber {
|
|
|
161
162
|
if (this.encoding) {
|
|
162
163
|
searchParams.set("encoding", this.encoding);
|
|
163
164
|
}
|
|
165
|
+
searchParams.set("enable_extra_session_information", "true");
|
|
166
|
+
if (this.disablePartialTranscripts) {
|
|
167
|
+
searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
|
|
168
|
+
}
|
|
164
169
|
url.search = searchParams.toString();
|
|
165
170
|
return url;
|
|
166
171
|
}
|
|
@@ -234,6 +239,10 @@ class RealtimeTranscriber {
|
|
|
234
239
|
this.listeners["transcript.final"]?.(message);
|
|
235
240
|
break;
|
|
236
241
|
}
|
|
242
|
+
case "SessionInformation": {
|
|
243
|
+
this.listeners.session_information?.(message);
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
237
246
|
case "SessionTerminated": {
|
|
238
247
|
this.sessionTerminatedResolve?.();
|
|
239
248
|
break;
|
|
@@ -356,6 +365,7 @@ class TranscriptService extends BaseService {
|
|
|
356
365
|
* @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
|
|
357
366
|
*/
|
|
358
367
|
async transcribe(params, options) {
|
|
368
|
+
deprecateConformer2(params);
|
|
359
369
|
const transcript = await this.submit(params);
|
|
360
370
|
return await this.waitUntilReady(transcript.id, options);
|
|
361
371
|
}
|
|
@@ -365,6 +375,7 @@ class TranscriptService extends BaseService {
|
|
|
365
375
|
* @returns A promise that resolves to the queued transcript.
|
|
366
376
|
*/
|
|
367
377
|
async submit(params) {
|
|
378
|
+
deprecateConformer2(params);
|
|
368
379
|
let audioUrl;
|
|
369
380
|
let transcriptParams = undefined;
|
|
370
381
|
if ("audio" in params) {
|
|
@@ -403,6 +414,7 @@ class TranscriptService extends BaseService {
|
|
|
403
414
|
* @deprecated Use `transcribe` instead to transcribe a audio file that includes polling, or `submit` to transcribe a audio file without polling.
|
|
404
415
|
*/
|
|
405
416
|
async create(params, options) {
|
|
417
|
+
deprecateConformer2(params);
|
|
406
418
|
const path = getPath(params.audio_url);
|
|
407
419
|
if (path !== null) {
|
|
408
420
|
const uploadUrl = await this.files.upload(path);
|
|
@@ -535,6 +547,13 @@ class TranscriptService extends BaseService {
|
|
|
535
547
|
return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
|
|
536
548
|
}
|
|
537
549
|
}
|
|
550
|
+
function deprecateConformer2(params) {
|
|
551
|
+
if (!params)
|
|
552
|
+
return;
|
|
553
|
+
if (params.speech_model === "conformer-2") {
|
|
554
|
+
console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.");
|
|
555
|
+
}
|
|
556
|
+
}
|
|
538
557
|
|
|
539
558
|
const readFile = async (path) => Readable.toWeb(createReadStream(path));
|
|
540
559
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RealtimeTranscriberParams, RealtimeTranscript, PartialTranscript, FinalTranscript, SessionBeginsEventData, AudioData } from "../..";
|
|
1
|
+
import { RealtimeTranscriberParams, RealtimeTranscript, PartialTranscript, FinalTranscript, SessionBeginsEventData, AudioData, SessionInformation } from "../..";
|
|
2
2
|
export declare class RealtimeTranscriber {
|
|
3
3
|
private realtimeUrl;
|
|
4
4
|
private sampleRate;
|
|
@@ -7,6 +7,7 @@ export declare class RealtimeTranscriber {
|
|
|
7
7
|
private apiKey?;
|
|
8
8
|
private token?;
|
|
9
9
|
private endUtteranceSilenceThreshold?;
|
|
10
|
+
private disablePartialTranscripts?;
|
|
10
11
|
private socket?;
|
|
11
12
|
private listeners;
|
|
12
13
|
private sessionTerminatedResolve?;
|
|
@@ -16,6 +17,7 @@ export declare class RealtimeTranscriber {
|
|
|
16
17
|
on(event: "transcript", listener: (transcript: RealtimeTranscript) => void): void;
|
|
17
18
|
on(event: "transcript.partial", listener: (transcript: PartialTranscript) => void): void;
|
|
18
19
|
on(event: "transcript.final", listener: (transcript: FinalTranscript) => void): void;
|
|
20
|
+
on(event: "session_information", listener: (info: SessionInformation) => void): void;
|
|
19
21
|
on(event: "error", listener: (error: Error) => void): void;
|
|
20
22
|
on(event: "close", listener: (code: number, reason: string) => void): void;
|
|
21
23
|
connect(): Promise<SessionBeginsEventData>;
|
|
@@ -16,6 +16,9 @@ export type ConfigureEndUtteranceSilenceThreshold = {
|
|
|
16
16
|
*/
|
|
17
17
|
end_utterance_silence_threshold: number;
|
|
18
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Transcript text at the end of an utterance with punctuation and casing.
|
|
21
|
+
*/
|
|
19
22
|
export type FinalTranscript = RealtimeBaseTranscript & {
|
|
20
23
|
/**
|
|
21
24
|
* Describes the type of message
|
|
@@ -39,7 +42,10 @@ export type ForceEndUtterance = {
|
|
|
39
42
|
*/
|
|
40
43
|
force_end_utterance: boolean;
|
|
41
44
|
};
|
|
42
|
-
export type MessageType = "SessionBegins" | "PartialTranscript" | "FinalTranscript" | "SessionTerminated";
|
|
45
|
+
export type MessageType = "SessionBegins" | "PartialTranscript" | "FinalTranscript" | "SessionInformation" | "SessionTerminated";
|
|
46
|
+
/**
|
|
47
|
+
* As you send audio data to the API, the API immediately starts responding with Partial Transcript results.
|
|
48
|
+
*/
|
|
43
49
|
export type PartialTranscript = RealtimeBaseTranscript & {
|
|
44
50
|
/**
|
|
45
51
|
* Describes the type of message
|
|
@@ -79,12 +85,18 @@ export type RealtimeBaseTranscript = {
|
|
|
79
85
|
*/
|
|
80
86
|
words: Word[];
|
|
81
87
|
};
|
|
88
|
+
/**
|
|
89
|
+
* Error message
|
|
90
|
+
*/
|
|
82
91
|
export type RealtimeError = {
|
|
83
92
|
error: string;
|
|
84
93
|
};
|
|
85
|
-
export type RealtimeMessage = SessionBegins | PartialTranscript | FinalTranscript | SessionTerminated | RealtimeError;
|
|
94
|
+
export type RealtimeMessage = SessionBegins | PartialTranscript | FinalTranscript | SessionInformation | SessionTerminated | RealtimeError;
|
|
86
95
|
export type RealtimeTranscript = PartialTranscript | FinalTranscript;
|
|
87
96
|
export type RealtimeTranscriptType = "PartialTranscript" | "FinalTranscript";
|
|
97
|
+
/**
|
|
98
|
+
* Session start
|
|
99
|
+
*/
|
|
88
100
|
export type SessionBegins = RealtimeBaseMessage & {
|
|
89
101
|
/**
|
|
90
102
|
* Timestamp when this session will expire
|
|
@@ -99,12 +111,33 @@ export type SessionBegins = RealtimeBaseMessage & {
|
|
|
99
111
|
*/
|
|
100
112
|
session_id: string;
|
|
101
113
|
};
|
|
114
|
+
/**
|
|
115
|
+
* Information about the session
|
|
116
|
+
* Information about the session that is concluding.
|
|
117
|
+
* This message is sent at the end of the session, before the SessionTerminated message.
|
|
118
|
+
*/
|
|
119
|
+
export type SessionInformation = RealtimeBaseMessage & {
|
|
120
|
+
/**
|
|
121
|
+
* The total duration of the audio in seconds
|
|
122
|
+
*/
|
|
123
|
+
audio_duration_seconds: number;
|
|
124
|
+
/**
|
|
125
|
+
* Describes the type of the message
|
|
126
|
+
*/
|
|
127
|
+
message_type: "SessionInformation";
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Session terminated
|
|
131
|
+
*/
|
|
102
132
|
export type SessionTerminated = RealtimeBaseMessage & {
|
|
103
133
|
/**
|
|
104
134
|
* Describes the type of the message
|
|
105
135
|
*/
|
|
106
136
|
message_type: "SessionTerminated";
|
|
107
137
|
};
|
|
138
|
+
/**
|
|
139
|
+
* Terminate session
|
|
140
|
+
*/
|
|
108
141
|
export type TerminateSession = {
|
|
109
142
|
/**
|
|
110
143
|
* Set to true to end your streaming session forever
|
|
@@ -258,6 +258,10 @@ export type AutoHighlightsResult = {
|
|
|
258
258
|
* A temporally-sequential array of Key Phrases
|
|
259
259
|
*/
|
|
260
260
|
results: AutoHighlightResult[];
|
|
261
|
+
/**
|
|
262
|
+
* The status of the Key Phrases model. Either success, or unavailable in the rare case that the model failed.
|
|
263
|
+
*/
|
|
264
|
+
status: AudioIntelligenceModelStatus;
|
|
261
265
|
};
|
|
262
266
|
/**
|
|
263
267
|
* Chapter of the audio file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AudioEncoding, FinalTranscript, PartialTranscript, RealtimeTranscript, RealtimeTranscriptType } from "../asyncapi.generated";
|
|
1
|
+
import { AudioEncoding, FinalTranscript, PartialTranscript, RealtimeTranscript, RealtimeTranscriptType, SessionInformation } from "../asyncapi.generated";
|
|
2
2
|
type CreateRealtimeTranscriberParams = {
|
|
3
3
|
/**
|
|
4
4
|
* The WebSocket URL that the RealtimeTranscriber connects to
|
|
@@ -20,6 +20,19 @@ type CreateRealtimeTranscriberParams = {
|
|
|
20
20
|
* The duration of the end utterance silence threshold in milliseconds
|
|
21
21
|
*/
|
|
22
22
|
endUtteranceSilenceThreshold?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Disable partial transcripts.
|
|
25
|
+
* Set to `true` to not receive partial transcripts. Defaults to `false`.
|
|
26
|
+
* @defaultValue false
|
|
27
|
+
*/
|
|
28
|
+
disablePartialTranscripts?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Enable extra session information.
|
|
31
|
+
* Set to `true` to receive the `session_information` message before the session ends. Defaults to `false`.
|
|
32
|
+
* @defaultValue true
|
|
33
|
+
* @deprecated This parameter is now ignored and will be removed. Session information will always be sent.
|
|
34
|
+
*/
|
|
35
|
+
enableExtraSessionInformation?: boolean;
|
|
23
36
|
} & ({
|
|
24
37
|
/**
|
|
25
38
|
* The API key used to authenticate the RealtimeTranscriber
|
|
@@ -57,6 +70,19 @@ type RealtimeTranscriberParams = {
|
|
|
57
70
|
* The duration of the end utterance silence threshold in milliseconds
|
|
58
71
|
*/
|
|
59
72
|
endUtteranceSilenceThreshold?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Disable partial transcripts.
|
|
75
|
+
* Set to `true` to not receive partial transcripts. Defaults to `false`.
|
|
76
|
+
* @defaultValue false
|
|
77
|
+
*/
|
|
78
|
+
disablePartialTranscripts?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Enable extra session information.
|
|
81
|
+
* Set to `true` to receive the `session_information` message before the session ends. Defaults to `false`.
|
|
82
|
+
* @defaultValue true
|
|
83
|
+
* @deprecated This parameter is now ignored and will be removed. Session information will always be sent.
|
|
84
|
+
*/
|
|
85
|
+
enableExtraSessionInformation?: boolean;
|
|
60
86
|
} & ({
|
|
61
87
|
/**
|
|
62
88
|
* The API key used to authenticate the RealtimeTranscriber.
|
|
@@ -73,7 +99,7 @@ type RealtimeTranscriberParams = {
|
|
|
73
99
|
* @deprecated Use RealtimeTranscriberParams instead
|
|
74
100
|
*/
|
|
75
101
|
type RealtimeServiceParams = RealtimeTranscriberParams;
|
|
76
|
-
type RealtimeEvents = "open" | "close" | "transcript" | "transcript.partial" | "transcript.final" | "error";
|
|
102
|
+
type RealtimeEvents = "open" | "close" | "transcript" | "transcript.partial" | "transcript.final" | "session_information" | "error";
|
|
77
103
|
type SessionBeginsEventData = {
|
|
78
104
|
sessionId: string;
|
|
79
105
|
expiresAt: Date;
|
|
@@ -84,6 +110,7 @@ type RealtimeListeners = {
|
|
|
84
110
|
transcript?: (transcript: RealtimeTranscript) => void;
|
|
85
111
|
"transcript.partial"?: (transcript: PartialTranscript) => void;
|
|
86
112
|
"transcript.final"?: (transcript: FinalTranscript) => void;
|
|
113
|
+
session_information?: (info: SessionInformation) => void;
|
|
87
114
|
error?: (error: Error) => void;
|
|
88
115
|
};
|
|
89
116
|
type RealtimeTokenParams = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "assemblyai",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.1",
|
|
4
4
|
"description": "The AssemblyAI JavaScript SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription, as well as the latest LeMUR models.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18"
|
|
@@ -69,9 +69,12 @@
|
|
|
69
69
|
"build": "pnpm clean && pnpm rollup -c",
|
|
70
70
|
"clean": "rimraf dist/* && rimraf temp/* && rimraf temp-docs/*",
|
|
71
71
|
"lint": "eslint -c .eslintrc.json '{src,tests}/**/*.{js,ts}' && publint && tsc --noEmit -p tsconfig.json",
|
|
72
|
-
"test": "
|
|
72
|
+
"test": "pnpm run test:unit && pnpm run test:integration",
|
|
73
|
+
"test:unit": "jest --config jest.unit.config.js",
|
|
74
|
+
"test:integration": "jest --config jest.integration.config.js --testTimeout 360000",
|
|
73
75
|
"format": "prettier '**/*' --write",
|
|
74
|
-
"generate
|
|
76
|
+
"generate:types": "tsx ./scripts/generate-types.ts && prettier 'src/types/*.generated.ts' --write",
|
|
77
|
+
"generate:reference": "typedoc",
|
|
75
78
|
"copybara:dry-run": "./copybara.sh dry_run --init-history",
|
|
76
79
|
"copybara:pr": "./copybara.sh sync_out --init-history"
|
|
77
80
|
},
|
|
@@ -125,7 +128,8 @@
|
|
|
125
128
|
"ts-jest": "^29.1.2",
|
|
126
129
|
"tslib": "^2.5.3",
|
|
127
130
|
"typescript": "^5.4.2",
|
|
128
|
-
"typedoc": "^0.25.12"
|
|
131
|
+
"typedoc": "^0.25.12",
|
|
132
|
+
"typedoc-plugin-extras": "^3.0.0"
|
|
129
133
|
},
|
|
130
134
|
"dependencies": {
|
|
131
135
|
"ws": "^8.16.0"
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
SessionBeginsEventData,
|
|
13
13
|
AudioEncoding,
|
|
14
14
|
AudioData,
|
|
15
|
+
SessionInformation,
|
|
15
16
|
} from "../..";
|
|
16
17
|
import {
|
|
17
18
|
RealtimeError,
|
|
@@ -49,6 +50,8 @@ export class RealtimeTranscriber {
|
|
|
49
50
|
private apiKey?: string;
|
|
50
51
|
private token?: string;
|
|
51
52
|
private endUtteranceSilenceThreshold?: number;
|
|
53
|
+
private disablePartialTranscripts?: boolean;
|
|
54
|
+
|
|
52
55
|
private socket?: WebSocket;
|
|
53
56
|
private listeners: RealtimeListeners = {};
|
|
54
57
|
private sessionTerminatedResolve?: () => void;
|
|
@@ -59,6 +62,7 @@ export class RealtimeTranscriber {
|
|
|
59
62
|
this.wordBoost = params.wordBoost;
|
|
60
63
|
this.encoding = params.encoding;
|
|
61
64
|
this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
|
|
65
|
+
this.disablePartialTranscripts = params.disablePartialTranscripts;
|
|
62
66
|
if ("token" in params && params.token) this.token = params.token;
|
|
63
67
|
if ("apiKey" in params && params.apiKey) this.apiKey = params.apiKey;
|
|
64
68
|
|
|
@@ -85,6 +89,15 @@ export class RealtimeTranscriber {
|
|
|
85
89
|
if (this.encoding) {
|
|
86
90
|
searchParams.set("encoding", this.encoding);
|
|
87
91
|
}
|
|
92
|
+
|
|
93
|
+
searchParams.set("enable_extra_session_information", "true");
|
|
94
|
+
|
|
95
|
+
if (this.disablePartialTranscripts) {
|
|
96
|
+
searchParams.set(
|
|
97
|
+
"disable_partial_transcripts",
|
|
98
|
+
this.disablePartialTranscripts.toString(),
|
|
99
|
+
);
|
|
100
|
+
}
|
|
88
101
|
url.search = searchParams.toString();
|
|
89
102
|
|
|
90
103
|
return url;
|
|
@@ -103,6 +116,10 @@ export class RealtimeTranscriber {
|
|
|
103
116
|
event: "transcript.final",
|
|
104
117
|
listener: (transcript: FinalTranscript) => void,
|
|
105
118
|
): void;
|
|
119
|
+
on(
|
|
120
|
+
event: "session_information",
|
|
121
|
+
listener: (info: SessionInformation) => void,
|
|
122
|
+
): void;
|
|
106
123
|
on(event: "error", listener: (error: Error) => void): void;
|
|
107
124
|
on(event: "close", listener: (code: number, reason: string) => void): void;
|
|
108
125
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -183,6 +200,10 @@ export class RealtimeTranscriber {
|
|
|
183
200
|
this.listeners["transcript.final"]?.(message);
|
|
184
201
|
break;
|
|
185
202
|
}
|
|
203
|
+
case "SessionInformation": {
|
|
204
|
+
this.listeners.session_information?.(message);
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
186
207
|
case "SessionTerminated": {
|
|
187
208
|
this.sessionTerminatedResolve?.();
|
|
188
209
|
break;
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
TranscribeParams,
|
|
16
16
|
TranscribeOptions,
|
|
17
17
|
SubmitParams,
|
|
18
|
+
SpeechModel,
|
|
18
19
|
} from "../..";
|
|
19
20
|
import { FileService } from "../files";
|
|
20
21
|
import { getPath } from "../../utils/path";
|
|
@@ -37,6 +38,7 @@ export class TranscriptService extends BaseService {
|
|
|
37
38
|
params: TranscribeParams,
|
|
38
39
|
options?: TranscribeOptions,
|
|
39
40
|
): Promise<Transcript> {
|
|
41
|
+
deprecateConformer2(params);
|
|
40
42
|
const transcript = await this.submit(params);
|
|
41
43
|
return await this.waitUntilReady(transcript.id, options);
|
|
42
44
|
}
|
|
@@ -47,6 +49,7 @@ export class TranscriptService extends BaseService {
|
|
|
47
49
|
* @returns A promise that resolves to the queued transcript.
|
|
48
50
|
*/
|
|
49
51
|
async submit(params: SubmitParams): Promise<Transcript> {
|
|
52
|
+
deprecateConformer2(params);
|
|
50
53
|
let audioUrl;
|
|
51
54
|
let transcriptParams: TranscriptParams | undefined = undefined;
|
|
52
55
|
if ("audio" in params) {
|
|
@@ -87,6 +90,7 @@ export class TranscriptService extends BaseService {
|
|
|
87
90
|
params: TranscriptParams,
|
|
88
91
|
options?: CreateTranscriptOptions,
|
|
89
92
|
): Promise<Transcript> {
|
|
93
|
+
deprecateConformer2(params);
|
|
90
94
|
const path = getPath(params.audio_url);
|
|
91
95
|
if (path !== null) {
|
|
92
96
|
const uploadUrl = await this.files.upload(path);
|
|
@@ -246,3 +250,12 @@ export class TranscriptService extends BaseService {
|
|
|
246
250
|
);
|
|
247
251
|
}
|
|
248
252
|
}
|
|
253
|
+
|
|
254
|
+
function deprecateConformer2(params: { speech_model?: SpeechModel | null }) {
|
|
255
|
+
if (!params) return;
|
|
256
|
+
if (params.speech_model === "conformer-2") {
|
|
257
|
+
console.warn(
|
|
258
|
+
"The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.",
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
@@ -37,6 +37,9 @@ export type ConfigureEndUtteranceSilenceThreshold = {
|
|
|
37
37
|
end_utterance_silence_threshold: number;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Transcript text at the end of an utterance with punctuation and casing.
|
|
42
|
+
*/
|
|
40
43
|
export type FinalTranscript = RealtimeBaseTranscript & {
|
|
41
44
|
/**
|
|
42
45
|
* Describes the type of message
|
|
@@ -66,8 +69,12 @@ export type MessageType =
|
|
|
66
69
|
| "SessionBegins"
|
|
67
70
|
| "PartialTranscript"
|
|
68
71
|
| "FinalTranscript"
|
|
72
|
+
| "SessionInformation"
|
|
69
73
|
| "SessionTerminated";
|
|
70
74
|
|
|
75
|
+
/**
|
|
76
|
+
* As you send audio data to the API, the API immediately starts responding with Partial Transcript results.
|
|
77
|
+
*/
|
|
71
78
|
export type PartialTranscript = RealtimeBaseTranscript & {
|
|
72
79
|
/**
|
|
73
80
|
* Describes the type of message
|
|
@@ -110,6 +117,9 @@ export type RealtimeBaseTranscript = {
|
|
|
110
117
|
words: Word[];
|
|
111
118
|
};
|
|
112
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Error message
|
|
122
|
+
*/
|
|
113
123
|
export type RealtimeError = {
|
|
114
124
|
error: string;
|
|
115
125
|
};
|
|
@@ -118,6 +128,7 @@ export type RealtimeMessage =
|
|
|
118
128
|
| SessionBegins
|
|
119
129
|
| PartialTranscript
|
|
120
130
|
| FinalTranscript
|
|
131
|
+
| SessionInformation
|
|
121
132
|
| SessionTerminated
|
|
122
133
|
| RealtimeError;
|
|
123
134
|
|
|
@@ -125,6 +136,9 @@ export type RealtimeTranscript = PartialTranscript | FinalTranscript;
|
|
|
125
136
|
|
|
126
137
|
export type RealtimeTranscriptType = "PartialTranscript" | "FinalTranscript";
|
|
127
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Session start
|
|
141
|
+
*/
|
|
128
142
|
export type SessionBegins = RealtimeBaseMessage & {
|
|
129
143
|
/**
|
|
130
144
|
* Timestamp when this session will expire
|
|
@@ -140,6 +154,25 @@ export type SessionBegins = RealtimeBaseMessage & {
|
|
|
140
154
|
session_id: string;
|
|
141
155
|
};
|
|
142
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Information about the session
|
|
159
|
+
* Information about the session that is concluding.
|
|
160
|
+
* This message is sent at the end of the session, before the SessionTerminated message.
|
|
161
|
+
*/
|
|
162
|
+
export type SessionInformation = RealtimeBaseMessage & {
|
|
163
|
+
/**
|
|
164
|
+
* The total duration of the audio in seconds
|
|
165
|
+
*/
|
|
166
|
+
audio_duration_seconds: number;
|
|
167
|
+
/**
|
|
168
|
+
* Describes the type of the message
|
|
169
|
+
*/
|
|
170
|
+
message_type: "SessionInformation";
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Session terminated
|
|
175
|
+
*/
|
|
143
176
|
export type SessionTerminated = RealtimeBaseMessage & {
|
|
144
177
|
/**
|
|
145
178
|
* Describes the type of the message
|
|
@@ -147,6 +180,9 @@ export type SessionTerminated = RealtimeBaseMessage & {
|
|
|
147
180
|
message_type: "SessionTerminated";
|
|
148
181
|
};
|
|
149
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Terminate session
|
|
185
|
+
*/
|
|
150
186
|
export type TerminateSession = {
|
|
151
187
|
/**
|
|
152
188
|
* Set to true to end your streaming session forever
|
|
@@ -271,6 +271,10 @@ export type AutoHighlightsResult = {
|
|
|
271
271
|
* A temporally-sequential array of Key Phrases
|
|
272
272
|
*/
|
|
273
273
|
results: AutoHighlightResult[];
|
|
274
|
+
/**
|
|
275
|
+
* The status of the Key Phrases model. Either success, or unavailable in the rare case that the model failed.
|
|
276
|
+
*/
|
|
277
|
+
status: AudioIntelligenceModelStatus;
|
|
274
278
|
};
|
|
275
279
|
|
|
276
280
|
/**
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
PartialTranscript,
|
|
5
5
|
RealtimeTranscript,
|
|
6
6
|
RealtimeTranscriptType,
|
|
7
|
+
SessionInformation,
|
|
7
8
|
} from "../asyncapi.generated";
|
|
8
9
|
|
|
9
10
|
type CreateRealtimeTranscriberParams = {
|
|
@@ -27,6 +28,19 @@ type CreateRealtimeTranscriberParams = {
|
|
|
27
28
|
* The duration of the end utterance silence threshold in milliseconds
|
|
28
29
|
*/
|
|
29
30
|
endUtteranceSilenceThreshold?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Disable partial transcripts.
|
|
33
|
+
* Set to `true` to not receive partial transcripts. Defaults to `false`.
|
|
34
|
+
* @defaultValue false
|
|
35
|
+
*/
|
|
36
|
+
disablePartialTranscripts?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Enable extra session information.
|
|
39
|
+
* Set to `true` to receive the `session_information` message before the session ends. Defaults to `false`.
|
|
40
|
+
* @defaultValue true
|
|
41
|
+
* @deprecated This parameter is now ignored and will be removed. Session information will always be sent.
|
|
42
|
+
*/
|
|
43
|
+
enableExtraSessionInformation?: boolean;
|
|
30
44
|
} & (
|
|
31
45
|
| {
|
|
32
46
|
/**
|
|
@@ -69,6 +83,19 @@ type RealtimeTranscriberParams = {
|
|
|
69
83
|
* The duration of the end utterance silence threshold in milliseconds
|
|
70
84
|
*/
|
|
71
85
|
endUtteranceSilenceThreshold?: number;
|
|
86
|
+
/**
|
|
87
|
+
* Disable partial transcripts.
|
|
88
|
+
* Set to `true` to not receive partial transcripts. Defaults to `false`.
|
|
89
|
+
* @defaultValue false
|
|
90
|
+
*/
|
|
91
|
+
disablePartialTranscripts?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Enable extra session information.
|
|
94
|
+
* Set to `true` to receive the `session_information` message before the session ends. Defaults to `false`.
|
|
95
|
+
* @defaultValue true
|
|
96
|
+
* @deprecated This parameter is now ignored and will be removed. Session information will always be sent.
|
|
97
|
+
*/
|
|
98
|
+
enableExtraSessionInformation?: boolean;
|
|
72
99
|
} & (
|
|
73
100
|
| {
|
|
74
101
|
/**
|
|
@@ -96,6 +123,7 @@ type RealtimeEvents =
|
|
|
96
123
|
| "transcript"
|
|
97
124
|
| "transcript.partial"
|
|
98
125
|
| "transcript.final"
|
|
126
|
+
| "session_information"
|
|
99
127
|
| "error";
|
|
100
128
|
|
|
101
129
|
type SessionBeginsEventData = {
|
|
@@ -109,6 +137,7 @@ type RealtimeListeners = {
|
|
|
109
137
|
transcript?: (transcript: RealtimeTranscript) => void;
|
|
110
138
|
"transcript.partial"?: (transcript: PartialTranscript) => void;
|
|
111
139
|
"transcript.final"?: (transcript: FinalTranscript) => void;
|
|
140
|
+
session_information?: (info: SessionInformation) => void;
|
|
112
141
|
error?: (error: Error) => void;
|
|
113
142
|
};
|
|
114
143
|
|