voice-router-dev 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +138 -4
- package/dist/index.d.mts +9269 -7817
- package/dist/index.d.ts +9269 -7817
- package/dist/index.js +536 -302
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +529 -302
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -43,9 +43,16 @@ __export(src_exports, {
|
|
|
43
43
|
GladiaAdapter: () => GladiaAdapter,
|
|
44
44
|
GladiaTypes: () => schema_exports,
|
|
45
45
|
GladiaWebhookHandler: () => GladiaWebhookHandler,
|
|
46
|
+
ListenV1EncodingParameter: () => ListenV1EncodingParameter,
|
|
46
47
|
OpenAIWhisperAdapter: () => OpenAIWhisperAdapter,
|
|
48
|
+
SpeakV1ContainerParameter: () => SpeakV1ContainerParameter,
|
|
49
|
+
SpeakV1EncodingParameter: () => SpeakV1EncodingParameter,
|
|
50
|
+
SpeakV1SampleRateParameter: () => SpeakV1SampleRateParameter,
|
|
47
51
|
SpeechmaticsAdapter: () => SpeechmaticsAdapter,
|
|
48
52
|
SpeechmaticsWebhookHandler: () => SpeechmaticsWebhookHandler,
|
|
53
|
+
StreamingSupportedBitDepthEnum: () => StreamingSupportedBitDepthEnum,
|
|
54
|
+
StreamingSupportedEncodingEnum: () => StreamingSupportedEncodingEnum,
|
|
55
|
+
StreamingSupportedSampleRateEnum: () => StreamingSupportedSampleRateEnum,
|
|
49
56
|
VoiceRouter: () => VoiceRouter,
|
|
50
57
|
WebhookRouter: () => WebhookRouter,
|
|
51
58
|
createAssemblyAIAdapter: () => createAssemblyAIAdapter,
|
|
@@ -268,24 +275,165 @@ function createVoiceRouter(config, adapters) {
|
|
|
268
275
|
return router;
|
|
269
276
|
}
|
|
270
277
|
|
|
278
|
+
// src/generated/deepgram/schema/listenV1EncodingParameter.ts
|
|
279
|
+
var ListenV1EncodingParameter = {
|
|
280
|
+
linear16: "linear16",
|
|
281
|
+
flac: "flac",
|
|
282
|
+
mulaw: "mulaw",
|
|
283
|
+
opus: "opus",
|
|
284
|
+
speex: "speex",
|
|
285
|
+
g729: "g729"
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
// src/generated/deepgram/schema/speakV1EncodingParameter.ts
|
|
289
|
+
var SpeakV1EncodingParameter = {
|
|
290
|
+
linear16: "linear16",
|
|
291
|
+
aac: "aac",
|
|
292
|
+
opus: "opus",
|
|
293
|
+
mp3: "mp3",
|
|
294
|
+
flac: "flac",
|
|
295
|
+
mulaw: "mulaw",
|
|
296
|
+
alaw: "alaw"
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// src/generated/deepgram/schema/speakV1ContainerParameter.ts
|
|
300
|
+
var SpeakV1ContainerParameter = {
|
|
301
|
+
none: "none",
|
|
302
|
+
wav: "wav",
|
|
303
|
+
ogg: "ogg"
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
// src/generated/deepgram/schema/speakV1SampleRateParameter.ts
|
|
307
|
+
var SpeakV1SampleRateParameter = {
|
|
308
|
+
NUMBER_16000: 16e3,
|
|
309
|
+
NUMBER_24000: 24e3,
|
|
310
|
+
NUMBER_32000: 32e3,
|
|
311
|
+
NUMBER_48000: 48e3,
|
|
312
|
+
null: null,
|
|
313
|
+
NUMBER_8000: 8e3,
|
|
314
|
+
NUMBER_22050: 22050
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// src/generated/gladia/schema/streamingSupportedEncodingEnum.ts
|
|
318
|
+
var StreamingSupportedEncodingEnum = {
|
|
319
|
+
"wav/pcm": "wav/pcm",
|
|
320
|
+
"wav/alaw": "wav/alaw",
|
|
321
|
+
"wav/ulaw": "wav/ulaw"
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
// src/generated/gladia/schema/streamingSupportedSampleRateEnum.ts
|
|
325
|
+
var StreamingSupportedSampleRateEnum = {
|
|
326
|
+
NUMBER_8000: 8e3,
|
|
327
|
+
NUMBER_16000: 16e3,
|
|
328
|
+
NUMBER_32000: 32e3,
|
|
329
|
+
NUMBER_44100: 44100,
|
|
330
|
+
NUMBER_48000: 48e3
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
// src/generated/gladia/schema/streamingSupportedBitDepthEnum.ts
|
|
334
|
+
var StreamingSupportedBitDepthEnum = {
|
|
335
|
+
NUMBER_8: 8,
|
|
336
|
+
NUMBER_16: 16,
|
|
337
|
+
NUMBER_24: 24,
|
|
338
|
+
NUMBER_32: 32
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
// src/constants/defaults.ts
|
|
342
|
+
var DEFAULT_TIMEOUTS = {
|
|
343
|
+
/** Standard HTTP request timeout for API calls (60 seconds) */
|
|
344
|
+
HTTP_REQUEST: 6e4,
|
|
345
|
+
/** Audio processing timeout for long audio files (120 seconds) */
|
|
346
|
+
AUDIO_PROCESSING: 12e4,
|
|
347
|
+
/** WebSocket connection establishment timeout (10 seconds) */
|
|
348
|
+
WS_CONNECTION: 1e4,
|
|
349
|
+
/** WebSocket graceful close timeout (5 seconds) */
|
|
350
|
+
WS_CLOSE: 5e3
|
|
351
|
+
};
|
|
352
|
+
var DEFAULT_POLLING = {
|
|
353
|
+
/** Maximum number of polling attempts before timing out */
|
|
354
|
+
MAX_ATTEMPTS: 60,
|
|
355
|
+
/** Standard interval between polling attempts (2 seconds) */
|
|
356
|
+
INTERVAL_MS: 2e3,
|
|
357
|
+
/** Slower interval for long-running jobs (3 seconds) */
|
|
358
|
+
SLOW_INTERVAL_MS: 3e3
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// src/utils/errors.ts
|
|
362
|
+
var ERROR_CODES = {
|
|
363
|
+
/** Failed to parse API response or WebSocket message */
|
|
364
|
+
PARSE_ERROR: "PARSE_ERROR",
|
|
365
|
+
/** WebSocket connection error */
|
|
366
|
+
WEBSOCKET_ERROR: "WEBSOCKET_ERROR",
|
|
367
|
+
/** Async transcription job did not complete within timeout */
|
|
368
|
+
POLLING_TIMEOUT: "POLLING_TIMEOUT",
|
|
369
|
+
/** Transcription processing failed on provider side */
|
|
370
|
+
TRANSCRIPTION_ERROR: "TRANSCRIPTION_ERROR",
|
|
371
|
+
/** Connection attempt timed out */
|
|
372
|
+
CONNECTION_TIMEOUT: "CONNECTION_TIMEOUT",
|
|
373
|
+
/** Invalid input provided to API */
|
|
374
|
+
INVALID_INPUT: "INVALID_INPUT",
|
|
375
|
+
/** Requested operation not supported by provider */
|
|
376
|
+
NOT_SUPPORTED: "NOT_SUPPORTED",
|
|
377
|
+
/** No transcription results available */
|
|
378
|
+
NO_RESULTS: "NO_RESULTS",
|
|
379
|
+
/** Unspecified or unknown error */
|
|
380
|
+
UNKNOWN_ERROR: "UNKNOWN_ERROR"
|
|
381
|
+
};
|
|
382
|
+
var ERROR_MESSAGES = {
|
|
383
|
+
PARSE_ERROR: "Failed to parse response data",
|
|
384
|
+
WEBSOCKET_ERROR: "WebSocket connection error",
|
|
385
|
+
POLLING_TIMEOUT: "Transcription did not complete within timeout period",
|
|
386
|
+
TRANSCRIPTION_ERROR: "Transcription processing failed",
|
|
387
|
+
CONNECTION_TIMEOUT: "Connection attempt timed out",
|
|
388
|
+
INVALID_INPUT: "Invalid input provided",
|
|
389
|
+
NOT_SUPPORTED: "Operation not supported by this provider",
|
|
390
|
+
NO_RESULTS: "No transcription results available",
|
|
391
|
+
UNKNOWN_ERROR: "An unknown error occurred"
|
|
392
|
+
};
|
|
393
|
+
function createError(code, customMessage, details) {
|
|
394
|
+
return {
|
|
395
|
+
code,
|
|
396
|
+
message: customMessage || ERROR_MESSAGES[code],
|
|
397
|
+
details
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
|
|
271
401
|
// src/adapters/base-adapter.ts
|
|
272
402
|
var BaseAdapter = class {
|
|
273
403
|
initialize(config) {
|
|
274
404
|
this.config = config;
|
|
275
405
|
}
|
|
276
406
|
/**
|
|
277
|
-
* Helper method to create error responses
|
|
407
|
+
* Helper method to create error responses with stack traces
|
|
408
|
+
*
|
|
409
|
+
* @param error - Error object or unknown error
|
|
410
|
+
* @param statusCode - Optional HTTP status code
|
|
411
|
+
* @param code - Optional error code (defaults to extracted or UNKNOWN_ERROR)
|
|
278
412
|
*/
|
|
279
|
-
createErrorResponse(error, statusCode) {
|
|
413
|
+
createErrorResponse(error, statusCode, code) {
|
|
280
414
|
const err = error;
|
|
415
|
+
const httpStatus = statusCode || err.statusCode || err.response?.status;
|
|
416
|
+
const httpStatusText = err.response?.statusText;
|
|
417
|
+
const responseData = err.response?.data;
|
|
281
418
|
return {
|
|
282
419
|
success: false,
|
|
283
420
|
provider: this.name,
|
|
284
421
|
error: {
|
|
285
|
-
code: err.code ||
|
|
422
|
+
code: code || err.code || ERROR_CODES.UNKNOWN_ERROR,
|
|
286
423
|
message: err.message || "An unknown error occurred",
|
|
287
|
-
statusCode:
|
|
288
|
-
details:
|
|
424
|
+
statusCode: httpStatus,
|
|
425
|
+
details: {
|
|
426
|
+
// Include full error object
|
|
427
|
+
error,
|
|
428
|
+
// Include stack trace if available
|
|
429
|
+
stack: err.stack,
|
|
430
|
+
// Include HTTP response details
|
|
431
|
+
httpStatus,
|
|
432
|
+
httpStatusText,
|
|
433
|
+
responseData,
|
|
434
|
+
// Include provider name for debugging
|
|
435
|
+
provider: this.name
|
|
436
|
+
}
|
|
289
437
|
}
|
|
290
438
|
};
|
|
291
439
|
}
|
|
@@ -300,6 +448,64 @@ var BaseAdapter = class {
|
|
|
300
448
|
throw new Error(`API key is required for ${this.name} provider`);
|
|
301
449
|
}
|
|
302
450
|
}
|
|
451
|
+
/**
|
|
452
|
+
* Build axios config for generated API client functions
|
|
453
|
+
*
|
|
454
|
+
* @param authHeaderName - Header name for API key (e.g., "Authorization", "x-gladia-key")
|
|
455
|
+
* @param authHeaderValue - Optional function to format auth header value (defaults to raw API key)
|
|
456
|
+
* @returns Axios config object
|
|
457
|
+
*/
|
|
458
|
+
getAxiosConfig(authHeaderName = "Authorization", authHeaderValue) {
|
|
459
|
+
this.validateConfig();
|
|
460
|
+
const authValue = authHeaderValue ? authHeaderValue(this.config.apiKey) : this.config.apiKey;
|
|
461
|
+
return {
|
|
462
|
+
baseURL: this.config.baseUrl || this.baseUrl,
|
|
463
|
+
timeout: this.config.timeout || DEFAULT_TIMEOUTS.HTTP_REQUEST,
|
|
464
|
+
headers: {
|
|
465
|
+
[authHeaderName]: authValue,
|
|
466
|
+
"Content-Type": "application/json",
|
|
467
|
+
...this.config.headers
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Generic polling helper for async transcription jobs
|
|
473
|
+
*
|
|
474
|
+
* Polls getTranscript() until job completes or times out.
|
|
475
|
+
*
|
|
476
|
+
* @param transcriptId - Job/transcript ID to poll
|
|
477
|
+
* @param options - Polling configuration
|
|
478
|
+
* @returns Final transcription result
|
|
479
|
+
*/
|
|
480
|
+
async pollForCompletion(transcriptId, options) {
|
|
481
|
+
const { maxAttempts = DEFAULT_POLLING.MAX_ATTEMPTS, intervalMs = DEFAULT_POLLING.INTERVAL_MS } = options || {};
|
|
482
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
483
|
+
const result = await this.getTranscript(transcriptId);
|
|
484
|
+
if (!result.success) {
|
|
485
|
+
return result;
|
|
486
|
+
}
|
|
487
|
+
const status = result.data?.status;
|
|
488
|
+
if (status === "completed") {
|
|
489
|
+
return result;
|
|
490
|
+
}
|
|
491
|
+
if (status === "error") {
|
|
492
|
+
return this.createErrorResponse(
|
|
493
|
+
new Error("Transcription failed"),
|
|
494
|
+
void 0,
|
|
495
|
+
ERROR_CODES.TRANSCRIPTION_ERROR
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
success: false,
|
|
502
|
+
provider: this.name,
|
|
503
|
+
error: {
|
|
504
|
+
code: ERROR_CODES.POLLING_TIMEOUT,
|
|
505
|
+
message: `Transcription did not complete after ${maxAttempts} attempts`
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
303
509
|
};
|
|
304
510
|
|
|
305
511
|
// src/adapters/gladia-adapter.ts
|
|
@@ -346,6 +552,143 @@ function mapEncodingToProvider(unifiedEncoding, provider) {
|
|
|
346
552
|
return providerEncoding;
|
|
347
553
|
}
|
|
348
554
|
|
|
555
|
+
// src/utils/websocket-helpers.ts
|
|
556
|
+
function waitForWebSocketOpen(ws, timeoutMs = DEFAULT_TIMEOUTS.WS_CONNECTION) {
|
|
557
|
+
return new Promise((resolve, reject) => {
|
|
558
|
+
const timeout = setTimeout(() => {
|
|
559
|
+
reject(new Error("WebSocket connection timeout"));
|
|
560
|
+
}, timeoutMs);
|
|
561
|
+
ws.once("open", () => {
|
|
562
|
+
clearTimeout(timeout);
|
|
563
|
+
resolve();
|
|
564
|
+
});
|
|
565
|
+
ws.once("error", (error) => {
|
|
566
|
+
clearTimeout(timeout);
|
|
567
|
+
reject(error);
|
|
568
|
+
});
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
function closeWebSocket(ws, timeoutMs = DEFAULT_TIMEOUTS.WS_CLOSE) {
|
|
572
|
+
return new Promise((resolve) => {
|
|
573
|
+
const timeout = setTimeout(() => {
|
|
574
|
+
ws.terminate();
|
|
575
|
+
resolve();
|
|
576
|
+
}, timeoutMs);
|
|
577
|
+
ws.close();
|
|
578
|
+
ws.once("close", () => {
|
|
579
|
+
clearTimeout(timeout);
|
|
580
|
+
resolve();
|
|
581
|
+
});
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
function setupWebSocketHandlers(ws, callbacks, setSessionStatus) {
|
|
585
|
+
ws.on("open", () => {
|
|
586
|
+
setSessionStatus("open");
|
|
587
|
+
callbacks?.onOpen?.();
|
|
588
|
+
});
|
|
589
|
+
ws.on("error", (error) => {
|
|
590
|
+
callbacks?.onError?.(createError(ERROR_CODES.WEBSOCKET_ERROR, error.message, error));
|
|
591
|
+
});
|
|
592
|
+
ws.on("close", (code, reason) => {
|
|
593
|
+
setSessionStatus("closed");
|
|
594
|
+
callbacks?.onClose?.(code, reason.toString());
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
function validateSessionForAudio(sessionStatus, wsReadyState, WebSocketOpen) {
|
|
598
|
+
if (sessionStatus !== "open") {
|
|
599
|
+
throw new Error(`Cannot send audio: session is ${sessionStatus}`);
|
|
600
|
+
}
|
|
601
|
+
if (wsReadyState !== WebSocketOpen) {
|
|
602
|
+
throw new Error("WebSocket is not open");
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// src/utils/validation.ts
|
|
607
|
+
function validateEnumValue(value, enumType, fieldName, provider) {
|
|
608
|
+
const validValues = Object.values(enumType);
|
|
609
|
+
const isValid = validValues.some((v) => v === value);
|
|
610
|
+
if (!isValid) {
|
|
611
|
+
throw new Error(
|
|
612
|
+
`${provider} does not support ${fieldName} '${value}'. Supported values (from OpenAPI spec): ${validValues.join(", ")}`
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
return value;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// src/utils/transcription-helpers.ts
|
|
619
|
+
function extractSpeakersFromUtterances(utterances, getSpeakerId, formatLabel) {
|
|
620
|
+
if (!utterances || utterances.length === 0) {
|
|
621
|
+
return void 0;
|
|
622
|
+
}
|
|
623
|
+
const speakerSet = /* @__PURE__ */ new Set();
|
|
624
|
+
utterances.forEach((utterance) => {
|
|
625
|
+
const speakerId = getSpeakerId(utterance);
|
|
626
|
+
if (speakerId !== void 0) {
|
|
627
|
+
speakerSet.add(String(speakerId));
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
if (speakerSet.size === 0) {
|
|
631
|
+
return void 0;
|
|
632
|
+
}
|
|
633
|
+
return Array.from(speakerSet).map((speakerId) => ({
|
|
634
|
+
id: speakerId,
|
|
635
|
+
label: formatLabel ? formatLabel(speakerId) : `Speaker ${speakerId}`
|
|
636
|
+
}));
|
|
637
|
+
}
|
|
638
|
+
function extractWords(words, mapper) {
|
|
639
|
+
if (!words || words.length === 0) {
|
|
640
|
+
return void 0;
|
|
641
|
+
}
|
|
642
|
+
const normalizedWords = words.map(mapper);
|
|
643
|
+
return normalizedWords.length > 0 ? normalizedWords : void 0;
|
|
644
|
+
}
|
|
645
|
+
var STATUS_MAPPINGS = {
|
|
646
|
+
gladia: {
|
|
647
|
+
queued: "queued",
|
|
648
|
+
processing: "processing",
|
|
649
|
+
done: "completed",
|
|
650
|
+
error: "error"
|
|
651
|
+
},
|
|
652
|
+
assemblyai: {
|
|
653
|
+
queued: "queued",
|
|
654
|
+
processing: "processing",
|
|
655
|
+
completed: "completed",
|
|
656
|
+
error: "error"
|
|
657
|
+
},
|
|
658
|
+
deepgram: {
|
|
659
|
+
queued: "queued",
|
|
660
|
+
processing: "processing",
|
|
661
|
+
completed: "completed",
|
|
662
|
+
error: "error"
|
|
663
|
+
},
|
|
664
|
+
azure: {
|
|
665
|
+
succeeded: "completed",
|
|
666
|
+
running: "processing",
|
|
667
|
+
notstarted: "queued",
|
|
668
|
+
failed: "error"
|
|
669
|
+
},
|
|
670
|
+
speechmatics: {
|
|
671
|
+
running: "processing",
|
|
672
|
+
done: "completed",
|
|
673
|
+
rejected: "error",
|
|
674
|
+
expired: "error"
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
function normalizeStatus(providerStatus, provider, defaultStatus = "queued") {
|
|
678
|
+
if (!providerStatus) return defaultStatus;
|
|
679
|
+
const mapping = STATUS_MAPPINGS[provider];
|
|
680
|
+
const statusKey = providerStatus.toString().toLowerCase();
|
|
681
|
+
if (statusKey in mapping) {
|
|
682
|
+
return mapping[statusKey];
|
|
683
|
+
}
|
|
684
|
+
for (const [key, value] of Object.entries(mapping)) {
|
|
685
|
+
if (statusKey.includes(key)) {
|
|
686
|
+
return value;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return defaultStatus;
|
|
690
|
+
}
|
|
691
|
+
|
|
349
692
|
// src/generated/gladia/api/gladiaControlAPI.ts
|
|
350
693
|
var import_axios = __toESM(require("axios"));
|
|
351
694
|
|
|
@@ -882,21 +1225,6 @@ var StreamingResponseStatus = {
|
|
|
882
1225
|
error: "error"
|
|
883
1226
|
};
|
|
884
1227
|
|
|
885
|
-
// src/generated/gladia/schema/streamingSupportedBitDepthEnum.ts
|
|
886
|
-
var StreamingSupportedBitDepthEnum = {
|
|
887
|
-
NUMBER_8: 8,
|
|
888
|
-
NUMBER_16: 16,
|
|
889
|
-
NUMBER_24: 24,
|
|
890
|
-
NUMBER_32: 32
|
|
891
|
-
};
|
|
892
|
-
|
|
893
|
-
// src/generated/gladia/schema/streamingSupportedEncodingEnum.ts
|
|
894
|
-
var StreamingSupportedEncodingEnum = {
|
|
895
|
-
"wav/pcm": "wav/pcm",
|
|
896
|
-
"wav/alaw": "wav/alaw",
|
|
897
|
-
"wav/ulaw": "wav/ulaw"
|
|
898
|
-
};
|
|
899
|
-
|
|
900
1228
|
// src/generated/gladia/schema/streamingSupportedModels.ts
|
|
901
1229
|
var StreamingSupportedModels = {
|
|
902
1230
|
"solaria-1": "solaria-1"
|
|
@@ -908,15 +1236,6 @@ var StreamingSupportedRegions = {
|
|
|
908
1236
|
"eu-west": "eu-west"
|
|
909
1237
|
};
|
|
910
1238
|
|
|
911
|
-
// src/generated/gladia/schema/streamingSupportedSampleRateEnum.ts
|
|
912
|
-
var StreamingSupportedSampleRateEnum = {
|
|
913
|
-
NUMBER_8000: 8e3,
|
|
914
|
-
NUMBER_16000: 16e3,
|
|
915
|
-
NUMBER_32000: 32e3,
|
|
916
|
-
NUMBER_44100: 44100,
|
|
917
|
-
NUMBER_48000: 48e3
|
|
918
|
-
};
|
|
919
|
-
|
|
920
1239
|
// src/generated/gladia/schema/subtitlesFormatEnum.ts
|
|
921
1240
|
var SubtitlesFormatEnum = {
|
|
922
1241
|
srt: "srt",
|
|
@@ -1466,21 +1785,10 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1466
1785
|
}
|
|
1467
1786
|
/**
|
|
1468
1787
|
* Get axios config for generated API client functions
|
|
1469
|
-
* Configures headers and base URL
|
|
1788
|
+
* Configures headers and base URL using Gladia's x-gladia-key header
|
|
1470
1789
|
*/
|
|
1471
1790
|
getAxiosConfig() {
|
|
1472
|
-
|
|
1473
|
-
throw new Error("Adapter not initialized. Call initialize() first.");
|
|
1474
|
-
}
|
|
1475
|
-
return {
|
|
1476
|
-
baseURL: this.config.baseUrl || this.baseUrl,
|
|
1477
|
-
timeout: this.config.timeout || 6e4,
|
|
1478
|
-
headers: {
|
|
1479
|
-
"x-gladia-key": this.config.apiKey,
|
|
1480
|
-
"Content-Type": "application/json",
|
|
1481
|
-
...this.config.headers
|
|
1482
|
-
}
|
|
1483
|
-
};
|
|
1791
|
+
return super.getAxiosConfig("x-gladia-key");
|
|
1484
1792
|
}
|
|
1485
1793
|
/**
|
|
1486
1794
|
* Submit audio for transcription
|
|
@@ -1647,29 +1955,13 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1647
1955
|
* Normalize Gladia response to unified format
|
|
1648
1956
|
*/
|
|
1649
1957
|
normalizeResponse(response) {
|
|
1650
|
-
|
|
1651
|
-
switch (response.status) {
|
|
1652
|
-
case "queued":
|
|
1653
|
-
status = "queued";
|
|
1654
|
-
break;
|
|
1655
|
-
case "processing":
|
|
1656
|
-
status = "processing";
|
|
1657
|
-
break;
|
|
1658
|
-
case "done":
|
|
1659
|
-
status = "completed";
|
|
1660
|
-
break;
|
|
1661
|
-
case "error":
|
|
1662
|
-
status = "error";
|
|
1663
|
-
break;
|
|
1664
|
-
default:
|
|
1665
|
-
status = "queued";
|
|
1666
|
-
}
|
|
1958
|
+
const status = normalizeStatus(response.status, "gladia");
|
|
1667
1959
|
if (response.status === "error") {
|
|
1668
1960
|
return {
|
|
1669
1961
|
success: false,
|
|
1670
1962
|
provider: this.name,
|
|
1671
1963
|
error: {
|
|
1672
|
-
code: response.error_code?.toString() ||
|
|
1964
|
+
code: response.error_code?.toString() || ERROR_CODES.TRANSCRIPTION_ERROR,
|
|
1673
1965
|
message: "Transcription failed",
|
|
1674
1966
|
statusCode: response.error_code || void 0
|
|
1675
1967
|
},
|
|
@@ -1709,22 +2001,11 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1709
2001
|
* Extract speaker information from Gladia response
|
|
1710
2002
|
*/
|
|
1711
2003
|
extractSpeakers(transcription) {
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
if (utterance.speaker !== void 0) {
|
|
1718
|
-
speakerSet.add(utterance.speaker);
|
|
1719
|
-
}
|
|
1720
|
-
});
|
|
1721
|
-
if (speakerSet.size === 0) {
|
|
1722
|
-
return void 0;
|
|
1723
|
-
}
|
|
1724
|
-
return Array.from(speakerSet).map((speakerId) => ({
|
|
1725
|
-
id: speakerId.toString(),
|
|
1726
|
-
label: `Speaker ${speakerId}`
|
|
1727
|
-
}));
|
|
2004
|
+
return extractSpeakersFromUtterances(
|
|
2005
|
+
transcription?.utterances,
|
|
2006
|
+
(utterance) => utterance.speaker,
|
|
2007
|
+
(id) => `Speaker ${id}`
|
|
2008
|
+
);
|
|
1728
2009
|
}
|
|
1729
2010
|
/**
|
|
1730
2011
|
* Extract word timestamps from Gladia response
|
|
@@ -1735,14 +2016,17 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1735
2016
|
}
|
|
1736
2017
|
const allWords = transcription.utterances.flatMap(
|
|
1737
2018
|
(utterance) => utterance.words.map((word) => ({
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
end: word.end,
|
|
1741
|
-
confidence: word.confidence,
|
|
1742
|
-
speaker: utterance.speaker?.toString()
|
|
2019
|
+
word,
|
|
2020
|
+
speaker: utterance.speaker
|
|
1743
2021
|
}))
|
|
1744
2022
|
);
|
|
1745
|
-
return allWords
|
|
2023
|
+
return extractWords(allWords, (item) => ({
|
|
2024
|
+
text: item.word.word,
|
|
2025
|
+
start: item.word.start,
|
|
2026
|
+
end: item.word.end,
|
|
2027
|
+
confidence: item.word.confidence,
|
|
2028
|
+
speaker: item.speaker?.toString()
|
|
2029
|
+
}));
|
|
1746
2030
|
}
|
|
1747
2031
|
/**
|
|
1748
2032
|
* Extract utterances from Gladia response
|
|
@@ -1768,38 +2052,6 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1768
2052
|
/**
|
|
1769
2053
|
* Poll for transcription completion
|
|
1770
2054
|
*/
|
|
1771
|
-
async pollForCompletion(jobId, maxAttempts = 60, intervalMs = 2e3) {
|
|
1772
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
1773
|
-
const result = await this.getTranscript(jobId);
|
|
1774
|
-
if (!result.success) {
|
|
1775
|
-
return result;
|
|
1776
|
-
}
|
|
1777
|
-
const status = result.data?.status;
|
|
1778
|
-
if (status === "completed") {
|
|
1779
|
-
return result;
|
|
1780
|
-
}
|
|
1781
|
-
if (status === "error") {
|
|
1782
|
-
return {
|
|
1783
|
-
success: false,
|
|
1784
|
-
provider: this.name,
|
|
1785
|
-
error: {
|
|
1786
|
-
code: "TRANSCRIPTION_ERROR",
|
|
1787
|
-
message: "Transcription failed"
|
|
1788
|
-
},
|
|
1789
|
-
raw: result.raw
|
|
1790
|
-
};
|
|
1791
|
-
}
|
|
1792
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
1793
|
-
}
|
|
1794
|
-
return {
|
|
1795
|
-
success: false,
|
|
1796
|
-
provider: this.name,
|
|
1797
|
-
error: {
|
|
1798
|
-
code: "POLLING_TIMEOUT",
|
|
1799
|
-
message: `Transcription did not complete after ${maxAttempts} attempts`
|
|
1800
|
-
}
|
|
1801
|
-
};
|
|
1802
|
-
}
|
|
1803
2055
|
/**
|
|
1804
2056
|
* Stream audio for real-time transcription
|
|
1805
2057
|
*
|
|
@@ -1843,14 +2095,12 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1843
2095
|
this.validateConfig();
|
|
1844
2096
|
let validatedSampleRate;
|
|
1845
2097
|
if (options?.sampleRate) {
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
}
|
|
1853
|
-
validatedSampleRate = options.sampleRate;
|
|
2098
|
+
validatedSampleRate = validateEnumValue(
|
|
2099
|
+
options.sampleRate,
|
|
2100
|
+
StreamingSupportedSampleRateEnum,
|
|
2101
|
+
"sample rate",
|
|
2102
|
+
"Gladia"
|
|
2103
|
+
);
|
|
1854
2104
|
}
|
|
1855
2105
|
const streamingRequest = {
|
|
1856
2106
|
encoding: options?.encoding ? mapEncodingToProvider(options.encoding, "gladia") : void 0,
|
|
@@ -1872,9 +2122,8 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1872
2122
|
const { id, url: wsUrl } = initResponse.data;
|
|
1873
2123
|
const ws = new import_ws.default(wsUrl);
|
|
1874
2124
|
let sessionStatus = "connecting";
|
|
1875
|
-
ws
|
|
1876
|
-
sessionStatus =
|
|
1877
|
-
callbacks?.onOpen?.();
|
|
2125
|
+
setupWebSocketHandlers(ws, callbacks, (status) => {
|
|
2126
|
+
sessionStatus = status;
|
|
1878
2127
|
});
|
|
1879
2128
|
ws.on("message", (data) => {
|
|
1880
2129
|
try {
|
|
@@ -1919,48 +2168,20 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1919
2168
|
}
|
|
1920
2169
|
} catch (error) {
|
|
1921
2170
|
callbacks?.onError?.({
|
|
1922
|
-
code:
|
|
2171
|
+
code: ERROR_CODES.PARSE_ERROR,
|
|
1923
2172
|
message: "Failed to parse WebSocket message",
|
|
1924
2173
|
details: error
|
|
1925
2174
|
});
|
|
1926
2175
|
}
|
|
1927
2176
|
});
|
|
1928
|
-
|
|
1929
|
-
callbacks?.onError?.({
|
|
1930
|
-
code: "WEBSOCKET_ERROR",
|
|
1931
|
-
message: error.message,
|
|
1932
|
-
details: error
|
|
1933
|
-
});
|
|
1934
|
-
});
|
|
1935
|
-
ws.on("close", (code, reason) => {
|
|
1936
|
-
sessionStatus = "closed";
|
|
1937
|
-
callbacks?.onClose?.(code, reason.toString());
|
|
1938
|
-
});
|
|
1939
|
-
await new Promise((resolve, reject) => {
|
|
1940
|
-
const timeout = setTimeout(() => {
|
|
1941
|
-
reject(new Error("WebSocket connection timeout"));
|
|
1942
|
-
}, 1e4);
|
|
1943
|
-
ws.once("open", () => {
|
|
1944
|
-
clearTimeout(timeout);
|
|
1945
|
-
resolve();
|
|
1946
|
-
});
|
|
1947
|
-
ws.once("error", (error) => {
|
|
1948
|
-
clearTimeout(timeout);
|
|
1949
|
-
reject(error);
|
|
1950
|
-
});
|
|
1951
|
-
});
|
|
2177
|
+
await waitForWebSocketOpen(ws);
|
|
1952
2178
|
return {
|
|
1953
2179
|
id,
|
|
1954
2180
|
provider: this.name,
|
|
1955
2181
|
createdAt: /* @__PURE__ */ new Date(),
|
|
1956
2182
|
getStatus: () => sessionStatus,
|
|
1957
2183
|
sendAudio: async (chunk) => {
|
|
1958
|
-
|
|
1959
|
-
throw new Error(`Cannot send audio: session is ${sessionStatus}`);
|
|
1960
|
-
}
|
|
1961
|
-
if (ws.readyState !== import_ws.default.OPEN) {
|
|
1962
|
-
throw new Error("WebSocket is not open");
|
|
1963
|
-
}
|
|
2184
|
+
validateSessionForAudio(sessionStatus, ws.readyState, import_ws.default.OPEN);
|
|
1964
2185
|
ws.send(chunk.data);
|
|
1965
2186
|
if (chunk.isLast) {
|
|
1966
2187
|
ws.send(
|
|
@@ -1982,18 +2203,8 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1982
2203
|
})
|
|
1983
2204
|
);
|
|
1984
2205
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
ws.terminate();
|
|
1988
|
-
resolve();
|
|
1989
|
-
}, 5e3);
|
|
1990
|
-
ws.close();
|
|
1991
|
-
ws.once("close", () => {
|
|
1992
|
-
clearTimeout(timeout);
|
|
1993
|
-
sessionStatus = "closed";
|
|
1994
|
-
resolve();
|
|
1995
|
-
});
|
|
1996
|
-
});
|
|
2206
|
+
await closeWebSocket(ws);
|
|
2207
|
+
sessionStatus = "closed";
|
|
1997
2208
|
}
|
|
1998
2209
|
};
|
|
1999
2210
|
}
|
|
@@ -2327,9 +2538,6 @@ var createTranscript = (transcriptParams, options) => {
|
|
|
2327
2538
|
var getTranscript = (transcriptId, options) => {
|
|
2328
2539
|
return import_axios2.default.get(`/v2/transcript/${transcriptId}`, options);
|
|
2329
2540
|
};
|
|
2330
|
-
var createTemporaryToken = (createRealtimeTemporaryTokenParams, options) => {
|
|
2331
|
-
return import_axios2.default.post("/v2/realtime/token", createRealtimeTemporaryTokenParams, options);
|
|
2332
|
-
};
|
|
2333
2541
|
|
|
2334
2542
|
// src/adapters/assemblyai-adapter.ts
|
|
2335
2543
|
var AssemblyAIAdapter = class extends BaseAdapter {
|
|
@@ -2347,26 +2555,17 @@ var AssemblyAIAdapter = class extends BaseAdapter {
|
|
|
2347
2555
|
entityDetection: true,
|
|
2348
2556
|
piiRedaction: true
|
|
2349
2557
|
};
|
|
2350
|
-
this.baseUrl = "https://api.assemblyai.com
|
|
2351
|
-
|
|
2558
|
+
this.baseUrl = "https://api.assemblyai.com";
|
|
2559
|
+
// Generated functions already include /v2 path
|
|
2560
|
+
this.wsBaseUrl = "wss://streaming.assemblyai.com/v3/ws";
|
|
2352
2561
|
}
|
|
2562
|
+
// v3 Universal Streaming endpoint
|
|
2353
2563
|
/**
|
|
2354
2564
|
* Get axios config for generated API client functions
|
|
2355
|
-
* Configures headers and base URL
|
|
2565
|
+
* Configures headers and base URL using authorization header
|
|
2356
2566
|
*/
|
|
2357
2567
|
getAxiosConfig() {
|
|
2358
|
-
|
|
2359
|
-
throw new Error("Adapter not initialized. Call initialize() first.");
|
|
2360
|
-
}
|
|
2361
|
-
return {
|
|
2362
|
-
baseURL: this.config.baseUrl || this.baseUrl,
|
|
2363
|
-
timeout: this.config.timeout || 6e4,
|
|
2364
|
-
headers: {
|
|
2365
|
-
authorization: this.config.apiKey,
|
|
2366
|
-
"Content-Type": "application/json",
|
|
2367
|
-
...this.config.headers
|
|
2368
|
-
}
|
|
2369
|
-
};
|
|
2568
|
+
return super.getAxiosConfig("authorization");
|
|
2370
2569
|
}
|
|
2371
2570
|
/**
|
|
2372
2571
|
* Submit audio for transcription
|
|
@@ -2644,41 +2843,6 @@ var AssemblyAIAdapter = class extends BaseAdapter {
|
|
|
2644
2843
|
}))
|
|
2645
2844
|
}));
|
|
2646
2845
|
}
|
|
2647
|
-
/**
|
|
2648
|
-
* Poll for transcription completion
|
|
2649
|
-
*/
|
|
2650
|
-
async pollForCompletion(transcriptId, maxAttempts = 60, intervalMs = 3e3) {
|
|
2651
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
2652
|
-
const result = await this.getTranscript(transcriptId);
|
|
2653
|
-
if (!result.success) {
|
|
2654
|
-
return result;
|
|
2655
|
-
}
|
|
2656
|
-
const status = result.data?.status;
|
|
2657
|
-
if (status === "completed") {
|
|
2658
|
-
return result;
|
|
2659
|
-
}
|
|
2660
|
-
if (status === "error") {
|
|
2661
|
-
return {
|
|
2662
|
-
success: false,
|
|
2663
|
-
provider: this.name,
|
|
2664
|
-
error: {
|
|
2665
|
-
code: "TRANSCRIPTION_ERROR",
|
|
2666
|
-
message: "Transcription failed"
|
|
2667
|
-
},
|
|
2668
|
-
raw: result.raw
|
|
2669
|
-
};
|
|
2670
|
-
}
|
|
2671
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
2672
|
-
}
|
|
2673
|
-
return {
|
|
2674
|
-
success: false,
|
|
2675
|
-
provider: this.name,
|
|
2676
|
-
error: {
|
|
2677
|
-
code: "POLLING_TIMEOUT",
|
|
2678
|
-
message: `Transcription did not complete after ${maxAttempts} attempts`
|
|
2679
|
-
}
|
|
2680
|
-
};
|
|
2681
|
-
}
|
|
2682
2846
|
/**
|
|
2683
2847
|
* Stream audio for real-time transcription
|
|
2684
2848
|
*
|
|
@@ -2719,14 +2883,17 @@ var AssemblyAIAdapter = class extends BaseAdapter {
|
|
|
2719
2883
|
*/
|
|
2720
2884
|
async transcribeStream(options, callbacks) {
|
|
2721
2885
|
this.validateConfig();
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
const
|
|
2728
|
-
const
|
|
2729
|
-
|
|
2886
|
+
if (!this.config?.apiKey) {
|
|
2887
|
+
throw new Error("API key is required for streaming");
|
|
2888
|
+
}
|
|
2889
|
+
const sampleRate = options?.sampleRate || 16e3;
|
|
2890
|
+
const encoding = options?.encoding || "pcm_s16le";
|
|
2891
|
+
const wsUrl = `${this.wsBaseUrl}?sample_rate=${sampleRate}&encoding=${encoding}`;
|
|
2892
|
+
const ws = new import_ws2.default(wsUrl, {
|
|
2893
|
+
headers: {
|
|
2894
|
+
Authorization: this.config.apiKey
|
|
2895
|
+
}
|
|
2896
|
+
});
|
|
2730
2897
|
let sessionStatus = "connecting";
|
|
2731
2898
|
const sessionId = `assemblyai-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
2732
2899
|
ws.on("open", () => {
|
|
@@ -2736,41 +2903,42 @@ var AssemblyAIAdapter = class extends BaseAdapter {
|
|
|
2736
2903
|
ws.on("message", (data) => {
|
|
2737
2904
|
try {
|
|
2738
2905
|
const message = JSON.parse(data.toString());
|
|
2739
|
-
if (
|
|
2906
|
+
if ("error" in message) {
|
|
2907
|
+
callbacks?.onError?.({
|
|
2908
|
+
code: "API_ERROR",
|
|
2909
|
+
message: message.error
|
|
2910
|
+
});
|
|
2911
|
+
return;
|
|
2912
|
+
}
|
|
2913
|
+
if (message.type === "Begin") {
|
|
2914
|
+
const beginMsg = message;
|
|
2740
2915
|
callbacks?.onMetadata?.({
|
|
2741
|
-
sessionId:
|
|
2742
|
-
expiresAt:
|
|
2916
|
+
sessionId: beginMsg.id,
|
|
2917
|
+
expiresAt: new Date(beginMsg.expires_at).toISOString()
|
|
2743
2918
|
});
|
|
2744
|
-
} else if (message.
|
|
2919
|
+
} else if (message.type === "Turn") {
|
|
2920
|
+
const turnMsg = message;
|
|
2745
2921
|
callbacks?.onTranscript?.({
|
|
2746
2922
|
type: "transcript",
|
|
2747
|
-
text:
|
|
2748
|
-
isFinal:
|
|
2749
|
-
confidence:
|
|
2750
|
-
words:
|
|
2923
|
+
text: turnMsg.transcript,
|
|
2924
|
+
isFinal: turnMsg.end_of_turn,
|
|
2925
|
+
confidence: turnMsg.end_of_turn_confidence,
|
|
2926
|
+
words: turnMsg.words.map((word) => ({
|
|
2751
2927
|
text: word.text,
|
|
2752
2928
|
start: word.start / 1e3,
|
|
2929
|
+
// Convert ms to seconds
|
|
2753
2930
|
end: word.end / 1e3,
|
|
2754
2931
|
confidence: word.confidence
|
|
2755
2932
|
})),
|
|
2756
|
-
data:
|
|
2933
|
+
data: turnMsg
|
|
2757
2934
|
});
|
|
2758
|
-
} else if (message.
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
words: message.words.map((word) => ({
|
|
2765
|
-
text: word.text,
|
|
2766
|
-
start: word.start / 1e3,
|
|
2767
|
-
end: word.end / 1e3,
|
|
2768
|
-
confidence: word.confidence
|
|
2769
|
-
})),
|
|
2770
|
-
data: message
|
|
2935
|
+
} else if (message.type === "Termination") {
|
|
2936
|
+
const termMsg = message;
|
|
2937
|
+
callbacks?.onMetadata?.({
|
|
2938
|
+
terminated: true,
|
|
2939
|
+
audioDurationSeconds: termMsg.audio_duration_seconds,
|
|
2940
|
+
sessionDurationSeconds: termMsg.session_duration_seconds
|
|
2771
2941
|
});
|
|
2772
|
-
} else if (message.message_type === "SessionTerminated") {
|
|
2773
|
-
callbacks?.onMetadata?.({ terminated: true });
|
|
2774
2942
|
}
|
|
2775
2943
|
} catch (error) {
|
|
2776
2944
|
callbacks?.onError?.({
|
|
@@ -3320,7 +3488,24 @@ function createDeepgramAdapter(config) {
|
|
|
3320
3488
|
}
|
|
3321
3489
|
|
|
3322
3490
|
// src/adapters/azure-stt-adapter.ts
|
|
3491
|
+
var import_axios5 = __toESM(require("axios"));
|
|
3492
|
+
|
|
3493
|
+
// src/generated/azure/api/speechServicesAPIV31.ts
|
|
3323
3494
|
var import_axios4 = __toESM(require("axios"));
|
|
3495
|
+
var transcriptionsCreate = (transcription, options) => {
|
|
3496
|
+
return import_axios4.default.post("/transcriptions", transcription, options);
|
|
3497
|
+
};
|
|
3498
|
+
var transcriptionsGet = (id, options) => {
|
|
3499
|
+
return import_axios4.default.get(`/transcriptions/${id}`, options);
|
|
3500
|
+
};
|
|
3501
|
+
var transcriptionsListFiles = (id, params, options) => {
|
|
3502
|
+
return import_axios4.default.get(`/transcriptions/${id}/files`, {
|
|
3503
|
+
...options,
|
|
3504
|
+
params: { ...params, ...options?.params }
|
|
3505
|
+
});
|
|
3506
|
+
};
|
|
3507
|
+
|
|
3508
|
+
// src/adapters/azure-stt-adapter.ts
|
|
3324
3509
|
var AzureSTTAdapter = class extends BaseAdapter {
|
|
3325
3510
|
constructor() {
|
|
3326
3511
|
super(...arguments);
|
|
@@ -3337,20 +3522,20 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3337
3522
|
entityDetection: false,
|
|
3338
3523
|
piiRedaction: false
|
|
3339
3524
|
};
|
|
3525
|
+
this.baseUrl = "https://eastus.api.cognitive.microsoft.com/speechtotext/v3.1";
|
|
3340
3526
|
}
|
|
3527
|
+
// Default, overridden in initialize()
|
|
3341
3528
|
initialize(config) {
|
|
3342
3529
|
super.initialize(config);
|
|
3343
3530
|
this.region = config.region || "eastus";
|
|
3344
3531
|
this.baseUrl = config.baseUrl || `https://${this.region}.api.cognitive.microsoft.com/speechtotext/v3.1`;
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
}
|
|
3353
|
-
});
|
|
3532
|
+
}
|
|
3533
|
+
/**
|
|
3534
|
+
* Get axios config for generated API client functions
|
|
3535
|
+
* Configures headers and base URL using Azure subscription key
|
|
3536
|
+
*/
|
|
3537
|
+
getAxiosConfig() {
|
|
3538
|
+
return super.getAxiosConfig("Ocp-Apim-Subscription-Key");
|
|
3354
3539
|
}
|
|
3355
3540
|
/**
|
|
3356
3541
|
* Submit audio for transcription
|
|
@@ -3382,9 +3567,9 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3382
3567
|
contentUrls: [audio.url],
|
|
3383
3568
|
properties: this.buildTranscriptionProperties(options)
|
|
3384
3569
|
};
|
|
3385
|
-
const response = await
|
|
3386
|
-
|
|
3387
|
-
|
|
3570
|
+
const response = await transcriptionsCreate(
|
|
3571
|
+
transcriptionRequest,
|
|
3572
|
+
this.getAxiosConfig()
|
|
3388
3573
|
);
|
|
3389
3574
|
const transcription = response.data;
|
|
3390
3575
|
return {
|
|
@@ -3415,9 +3600,7 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3415
3600
|
async getTranscript(transcriptId) {
|
|
3416
3601
|
this.validateConfig();
|
|
3417
3602
|
try {
|
|
3418
|
-
const statusResponse = await this.
|
|
3419
|
-
`/transcriptions/${transcriptId}`
|
|
3420
|
-
);
|
|
3603
|
+
const statusResponse = await transcriptionsGet(transcriptId, this.getAxiosConfig());
|
|
3421
3604
|
const transcription = statusResponse.data;
|
|
3422
3605
|
const status = this.normalizeStatus(transcription.status);
|
|
3423
3606
|
if (status !== "completed") {
|
|
@@ -3445,7 +3628,11 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3445
3628
|
raw: transcription
|
|
3446
3629
|
};
|
|
3447
3630
|
}
|
|
3448
|
-
const filesResponse = await
|
|
3631
|
+
const filesResponse = await transcriptionsListFiles(
|
|
3632
|
+
transcriptId,
|
|
3633
|
+
void 0,
|
|
3634
|
+
this.getAxiosConfig()
|
|
3635
|
+
);
|
|
3449
3636
|
const files = filesResponse.data?.values || [];
|
|
3450
3637
|
const resultFile = files.find((file) => file.kind === "Transcription");
|
|
3451
3638
|
if (!resultFile?.links?.contentUrl) {
|
|
@@ -3459,7 +3646,7 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3459
3646
|
raw: transcription
|
|
3460
3647
|
};
|
|
3461
3648
|
}
|
|
3462
|
-
const contentResponse = await
|
|
3649
|
+
const contentResponse = await import_axios5.default.get(resultFile.links.contentUrl);
|
|
3463
3650
|
const transcriptionData = contentResponse.data;
|
|
3464
3651
|
return this.normalizeResponse(transcription, transcriptionData);
|
|
3465
3652
|
} catch (error) {
|
|
@@ -3558,7 +3745,57 @@ function createAzureSTTAdapter(config) {
|
|
|
3558
3745
|
}
|
|
3559
3746
|
|
|
3560
3747
|
// src/adapters/openai-whisper-adapter.ts
|
|
3561
|
-
var
|
|
3748
|
+
var import_axios7 = __toESM(require("axios"));
|
|
3749
|
+
|
|
3750
|
+
// src/generated/openai/api/openAIAPI.ts
|
|
3751
|
+
var import_axios6 = __toESM(require("axios"));
|
|
3752
|
+
var createTranscription = (createTranscriptionRequest, options) => {
|
|
3753
|
+
const formData = new FormData();
|
|
3754
|
+
formData.append("file", createTranscriptionRequest.file);
|
|
3755
|
+
formData.append("model", createTranscriptionRequest.model);
|
|
3756
|
+
if (createTranscriptionRequest.language !== void 0) {
|
|
3757
|
+
formData.append("language", createTranscriptionRequest.language);
|
|
3758
|
+
}
|
|
3759
|
+
if (createTranscriptionRequest.prompt !== void 0) {
|
|
3760
|
+
formData.append("prompt", createTranscriptionRequest.prompt);
|
|
3761
|
+
}
|
|
3762
|
+
if (createTranscriptionRequest.response_format !== void 0) {
|
|
3763
|
+
formData.append("response_format", createTranscriptionRequest.response_format);
|
|
3764
|
+
}
|
|
3765
|
+
if (createTranscriptionRequest.temperature !== void 0) {
|
|
3766
|
+
formData.append("temperature", createTranscriptionRequest.temperature.toString());
|
|
3767
|
+
}
|
|
3768
|
+
if (createTranscriptionRequest.include !== void 0) {
|
|
3769
|
+
createTranscriptionRequest.include.forEach((value) => formData.append("include", value));
|
|
3770
|
+
}
|
|
3771
|
+
if (createTranscriptionRequest.timestamp_granularities !== void 0) {
|
|
3772
|
+
createTranscriptionRequest.timestamp_granularities.forEach(
|
|
3773
|
+
(value) => formData.append("timestamp_granularities", value)
|
|
3774
|
+
);
|
|
3775
|
+
}
|
|
3776
|
+
if (createTranscriptionRequest.stream !== void 0 && createTranscriptionRequest.stream !== null) {
|
|
3777
|
+
formData.append("stream", createTranscriptionRequest.stream.toString());
|
|
3778
|
+
}
|
|
3779
|
+
if (createTranscriptionRequest.chunking_strategy !== void 0 && createTranscriptionRequest.chunking_strategy !== null) {
|
|
3780
|
+
formData.append(
|
|
3781
|
+
"chunking_strategy",
|
|
3782
|
+
typeof createTranscriptionRequest.chunking_strategy === "object" ? JSON.stringify(createTranscriptionRequest.chunking_strategy) : createTranscriptionRequest.chunking_strategy
|
|
3783
|
+
);
|
|
3784
|
+
}
|
|
3785
|
+
if (createTranscriptionRequest.known_speaker_names !== void 0) {
|
|
3786
|
+
createTranscriptionRequest.known_speaker_names.forEach(
|
|
3787
|
+
(value) => formData.append("known_speaker_names", value)
|
|
3788
|
+
);
|
|
3789
|
+
}
|
|
3790
|
+
if (createTranscriptionRequest.known_speaker_references !== void 0) {
|
|
3791
|
+
createTranscriptionRequest.known_speaker_references.forEach(
|
|
3792
|
+
(value) => formData.append("known_speaker_references", value)
|
|
3793
|
+
);
|
|
3794
|
+
}
|
|
3795
|
+
return import_axios6.default.post("/audio/transcriptions", formData, options);
|
|
3796
|
+
};
|
|
3797
|
+
|
|
3798
|
+
// src/adapters/openai-whisper-adapter.ts
|
|
3562
3799
|
var OpenAIWhisperAdapter = class extends BaseAdapter {
|
|
3563
3800
|
constructor() {
|
|
3564
3801
|
super(...arguments);
|
|
@@ -3580,19 +3817,12 @@ var OpenAIWhisperAdapter = class extends BaseAdapter {
|
|
|
3580
3817
|
};
|
|
3581
3818
|
this.baseUrl = "https://api.openai.com/v1";
|
|
3582
3819
|
}
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
// 2 minutes default (audio processing can take time)
|
|
3590
|
-
headers: {
|
|
3591
|
-
Authorization: `Bearer ${config.apiKey}`,
|
|
3592
|
-
"Content-Type": "multipart/form-data",
|
|
3593
|
-
...config.headers
|
|
3594
|
-
}
|
|
3595
|
-
});
|
|
3820
|
+
/**
|
|
3821
|
+
* Get axios config for generated API client functions
|
|
3822
|
+
* Configures headers and base URL using Bearer token authorization
|
|
3823
|
+
*/
|
|
3824
|
+
getAxiosConfig() {
|
|
3825
|
+
return super.getAxiosConfig("Authorization", (apiKey) => `Bearer ${apiKey}`);
|
|
3596
3826
|
}
|
|
3597
3827
|
/**
|
|
3598
3828
|
* Submit audio for transcription
|
|
@@ -3614,7 +3844,7 @@ var OpenAIWhisperAdapter = class extends BaseAdapter {
|
|
|
3614
3844
|
let audioData;
|
|
3615
3845
|
let fileName = "audio.mp3";
|
|
3616
3846
|
if (audio.type === "url") {
|
|
3617
|
-
const response2 = await
|
|
3847
|
+
const response2 = await import_axios7.default.get(audio.url, {
|
|
3618
3848
|
responseType: "arraybuffer"
|
|
3619
3849
|
});
|
|
3620
3850
|
audioData = Buffer.from(response2.data);
|
|
@@ -3639,40 +3869,37 @@ var OpenAIWhisperAdapter = class extends BaseAdapter {
|
|
|
3639
3869
|
const model = this.selectModel(options);
|
|
3640
3870
|
const isDiarization = model === "gpt-4o-transcribe-diarize";
|
|
3641
3871
|
const needsWords = options?.wordTimestamps === true;
|
|
3642
|
-
const
|
|
3872
|
+
const request = {
|
|
3643
3873
|
file: audioData,
|
|
3874
|
+
// Generated type expects Blob
|
|
3644
3875
|
model
|
|
3645
3876
|
};
|
|
3646
3877
|
if (options?.language) {
|
|
3647
|
-
|
|
3878
|
+
request.language = options.language;
|
|
3648
3879
|
}
|
|
3649
3880
|
if (options?.metadata?.prompt) {
|
|
3650
|
-
|
|
3881
|
+
request.prompt = options.metadata.prompt;
|
|
3651
3882
|
}
|
|
3652
3883
|
if (options?.metadata?.temperature !== void 0) {
|
|
3653
|
-
|
|
3884
|
+
request.temperature = options.metadata.temperature;
|
|
3654
3885
|
}
|
|
3655
3886
|
if (isDiarization) {
|
|
3656
|
-
|
|
3887
|
+
request.response_format = "diarized_json";
|
|
3657
3888
|
if (options?.metadata?.knownSpeakerNames) {
|
|
3658
|
-
|
|
3889
|
+
request.known_speaker_names = options.metadata.knownSpeakerNames;
|
|
3659
3890
|
}
|
|
3660
3891
|
if (options?.metadata?.knownSpeakerReferences) {
|
|
3661
|
-
|
|
3892
|
+
request.known_speaker_references = options.metadata.knownSpeakerReferences;
|
|
3662
3893
|
}
|
|
3663
3894
|
} else if (needsWords || options?.diarization) {
|
|
3664
|
-
|
|
3895
|
+
request.response_format = "verbose_json";
|
|
3665
3896
|
if (needsWords) {
|
|
3666
|
-
|
|
3897
|
+
request.timestamp_granularities = ["word", "segment"];
|
|
3667
3898
|
}
|
|
3668
3899
|
} else {
|
|
3669
|
-
|
|
3900
|
+
request.response_format = "json";
|
|
3670
3901
|
}
|
|
3671
|
-
const response = await this.
|
|
3672
|
-
headers: {
|
|
3673
|
-
"Content-Type": "multipart/form-data"
|
|
3674
|
-
}
|
|
3675
|
-
});
|
|
3902
|
+
const response = await createTranscription(request, this.getAxiosConfig());
|
|
3676
3903
|
return this.normalizeResponse(response.data, model, isDiarization);
|
|
3677
3904
|
} catch (error) {
|
|
3678
3905
|
return this.createErrorResponse(error);
|
|
@@ -3793,7 +4020,7 @@ function createOpenAIWhisperAdapter(config) {
|
|
|
3793
4020
|
}
|
|
3794
4021
|
|
|
3795
4022
|
// src/adapters/speechmatics-adapter.ts
|
|
3796
|
-
var
|
|
4023
|
+
var import_axios8 = __toESM(require("axios"));
|
|
3797
4024
|
var SpeechmaticsAdapter = class extends BaseAdapter {
|
|
3798
4025
|
constructor() {
|
|
3799
4026
|
super(...arguments);
|
|
@@ -3815,7 +4042,7 @@ var SpeechmaticsAdapter = class extends BaseAdapter {
|
|
|
3815
4042
|
initialize(config) {
|
|
3816
4043
|
super.initialize(config);
|
|
3817
4044
|
this.baseUrl = config.baseUrl || this.baseUrl;
|
|
3818
|
-
this.client =
|
|
4045
|
+
this.client = import_axios8.default.create({
|
|
3819
4046
|
baseURL: this.baseUrl,
|
|
3820
4047
|
timeout: config.timeout || 12e4,
|
|
3821
4048
|
headers: {
|
|
@@ -4951,9 +5178,16 @@ function createWebhookRouter() {
|
|
|
4951
5178
|
GladiaAdapter,
|
|
4952
5179
|
GladiaTypes,
|
|
4953
5180
|
GladiaWebhookHandler,
|
|
5181
|
+
ListenV1EncodingParameter,
|
|
4954
5182
|
OpenAIWhisperAdapter,
|
|
5183
|
+
SpeakV1ContainerParameter,
|
|
5184
|
+
SpeakV1EncodingParameter,
|
|
5185
|
+
SpeakV1SampleRateParameter,
|
|
4955
5186
|
SpeechmaticsAdapter,
|
|
4956
5187
|
SpeechmaticsWebhookHandler,
|
|
5188
|
+
StreamingSupportedBitDepthEnum,
|
|
5189
|
+
StreamingSupportedEncodingEnum,
|
|
5190
|
+
StreamingSupportedSampleRateEnum,
|
|
4957
5191
|
VoiceRouter,
|
|
4958
5192
|
WebhookRouter,
|
|
4959
5193
|
createAssemblyAIAdapter,
|