voice-router-dev 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +496 -222
- package/dist/index.d.ts +496 -222
- package/dist/index.js +422 -275
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +422 -275
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -144,39 +144,7 @@ var VoiceRouter = class {
|
|
|
144
144
|
const adapter = this.getAdapter(provider);
|
|
145
145
|
return adapter.getTranscript(transcriptId);
|
|
146
146
|
}
|
|
147
|
-
|
|
148
|
-
* Stream audio for real-time transcription
|
|
149
|
-
* Only works with providers that support streaming
|
|
150
|
-
*
|
|
151
|
-
* @param options - Streaming options including provider selection
|
|
152
|
-
* @param callbacks - Event callbacks for transcription results
|
|
153
|
-
* @returns Promise that resolves with a StreamingSession
|
|
154
|
-
*
|
|
155
|
-
* @example
|
|
156
|
-
* ```typescript
|
|
157
|
-
* import { VoiceRouter } from '@meeting-baas/sdk';
|
|
158
|
-
*
|
|
159
|
-
* const router = new VoiceRouter();
|
|
160
|
-
* router.initialize({
|
|
161
|
-
* gladia: { apiKey: process.env.GLADIA_KEY },
|
|
162
|
-
* deepgram: { apiKey: process.env.DEEPGRAM_KEY }
|
|
163
|
-
* });
|
|
164
|
-
*
|
|
165
|
-
* const session = await router.transcribeStream({
|
|
166
|
-
* provider: 'deepgram',
|
|
167
|
-
* encoding: 'linear16',
|
|
168
|
-
* sampleRate: 16000,
|
|
169
|
-
* language: 'en'
|
|
170
|
-
* }, {
|
|
171
|
-
* onTranscript: (event) => console.log(event.text),
|
|
172
|
-
* onError: (error) => console.error(error)
|
|
173
|
-
* });
|
|
174
|
-
*
|
|
175
|
-
* // Send audio chunks
|
|
176
|
-
* await session.sendAudio({ data: audioBuffer });
|
|
177
|
-
* await session.close();
|
|
178
|
-
* ```
|
|
179
|
-
*/
|
|
147
|
+
// Implementation
|
|
180
148
|
async transcribeStream(options, callbacks) {
|
|
181
149
|
const provider = this.selectProvider(options?.provider);
|
|
182
150
|
const adapter = this.getAdapter(provider);
|
|
@@ -242,24 +210,102 @@ function createVoiceRouter(config, adapters) {
|
|
|
242
210
|
return router;
|
|
243
211
|
}
|
|
244
212
|
|
|
213
|
+
// src/constants/defaults.ts
|
|
214
|
+
var DEFAULT_TIMEOUTS = {
|
|
215
|
+
/** Standard HTTP request timeout for API calls (60 seconds) */
|
|
216
|
+
HTTP_REQUEST: 6e4,
|
|
217
|
+
/** Audio processing timeout for long audio files (120 seconds) */
|
|
218
|
+
AUDIO_PROCESSING: 12e4,
|
|
219
|
+
/** WebSocket connection establishment timeout (10 seconds) */
|
|
220
|
+
WS_CONNECTION: 1e4,
|
|
221
|
+
/** WebSocket graceful close timeout (5 seconds) */
|
|
222
|
+
WS_CLOSE: 5e3
|
|
223
|
+
};
|
|
224
|
+
var DEFAULT_POLLING = {
|
|
225
|
+
/** Maximum number of polling attempts before timing out */
|
|
226
|
+
MAX_ATTEMPTS: 60,
|
|
227
|
+
/** Standard interval between polling attempts (2 seconds) */
|
|
228
|
+
INTERVAL_MS: 2e3,
|
|
229
|
+
/** Slower interval for long-running jobs (3 seconds) */
|
|
230
|
+
SLOW_INTERVAL_MS: 3e3
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// src/utils/errors.ts
|
|
234
|
+
var ERROR_CODES = {
|
|
235
|
+
/** Failed to parse API response or WebSocket message */
|
|
236
|
+
PARSE_ERROR: "PARSE_ERROR",
|
|
237
|
+
/** WebSocket connection error */
|
|
238
|
+
WEBSOCKET_ERROR: "WEBSOCKET_ERROR",
|
|
239
|
+
/** Async transcription job did not complete within timeout */
|
|
240
|
+
POLLING_TIMEOUT: "POLLING_TIMEOUT",
|
|
241
|
+
/** Transcription processing failed on provider side */
|
|
242
|
+
TRANSCRIPTION_ERROR: "TRANSCRIPTION_ERROR",
|
|
243
|
+
/** Connection attempt timed out */
|
|
244
|
+
CONNECTION_TIMEOUT: "CONNECTION_TIMEOUT",
|
|
245
|
+
/** Invalid input provided to API */
|
|
246
|
+
INVALID_INPUT: "INVALID_INPUT",
|
|
247
|
+
/** Requested operation not supported by provider */
|
|
248
|
+
NOT_SUPPORTED: "NOT_SUPPORTED",
|
|
249
|
+
/** No transcription results available */
|
|
250
|
+
NO_RESULTS: "NO_RESULTS",
|
|
251
|
+
/** Unspecified or unknown error */
|
|
252
|
+
UNKNOWN_ERROR: "UNKNOWN_ERROR"
|
|
253
|
+
};
|
|
254
|
+
var ERROR_MESSAGES = {
|
|
255
|
+
PARSE_ERROR: "Failed to parse response data",
|
|
256
|
+
WEBSOCKET_ERROR: "WebSocket connection error",
|
|
257
|
+
POLLING_TIMEOUT: "Transcription did not complete within timeout period",
|
|
258
|
+
TRANSCRIPTION_ERROR: "Transcription processing failed",
|
|
259
|
+
CONNECTION_TIMEOUT: "Connection attempt timed out",
|
|
260
|
+
INVALID_INPUT: "Invalid input provided",
|
|
261
|
+
NOT_SUPPORTED: "Operation not supported by this provider",
|
|
262
|
+
NO_RESULTS: "No transcription results available",
|
|
263
|
+
UNKNOWN_ERROR: "An unknown error occurred"
|
|
264
|
+
};
|
|
265
|
+
function createError(code, customMessage, details) {
|
|
266
|
+
return {
|
|
267
|
+
code,
|
|
268
|
+
message: customMessage || ERROR_MESSAGES[code],
|
|
269
|
+
details
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
245
273
|
// src/adapters/base-adapter.ts
|
|
246
274
|
var BaseAdapter = class {
|
|
247
275
|
initialize(config) {
|
|
248
276
|
this.config = config;
|
|
249
277
|
}
|
|
250
278
|
/**
|
|
251
|
-
* Helper method to create error responses
|
|
279
|
+
* Helper method to create error responses with stack traces
|
|
280
|
+
*
|
|
281
|
+
* @param error - Error object or unknown error
|
|
282
|
+
* @param statusCode - Optional HTTP status code
|
|
283
|
+
* @param code - Optional error code (defaults to extracted or UNKNOWN_ERROR)
|
|
252
284
|
*/
|
|
253
|
-
createErrorResponse(error, statusCode) {
|
|
285
|
+
createErrorResponse(error, statusCode, code) {
|
|
254
286
|
const err = error;
|
|
287
|
+
const httpStatus = statusCode || err.statusCode || err.response?.status;
|
|
288
|
+
const httpStatusText = err.response?.statusText;
|
|
289
|
+
const responseData = err.response?.data;
|
|
255
290
|
return {
|
|
256
291
|
success: false,
|
|
257
292
|
provider: this.name,
|
|
258
293
|
error: {
|
|
259
|
-
code: err.code ||
|
|
294
|
+
code: code || err.code || ERROR_CODES.UNKNOWN_ERROR,
|
|
260
295
|
message: err.message || "An unknown error occurred",
|
|
261
|
-
statusCode:
|
|
262
|
-
details:
|
|
296
|
+
statusCode: httpStatus,
|
|
297
|
+
details: {
|
|
298
|
+
// Include full error object
|
|
299
|
+
error,
|
|
300
|
+
// Include stack trace if available
|
|
301
|
+
stack: err.stack,
|
|
302
|
+
// Include HTTP response details
|
|
303
|
+
httpStatus,
|
|
304
|
+
httpStatusText,
|
|
305
|
+
responseData,
|
|
306
|
+
// Include provider name for debugging
|
|
307
|
+
provider: this.name
|
|
308
|
+
}
|
|
263
309
|
}
|
|
264
310
|
};
|
|
265
311
|
}
|
|
@@ -274,6 +320,64 @@ var BaseAdapter = class {
|
|
|
274
320
|
throw new Error(`API key is required for ${this.name} provider`);
|
|
275
321
|
}
|
|
276
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* Build axios config for generated API client functions
|
|
325
|
+
*
|
|
326
|
+
* @param authHeaderName - Header name for API key (e.g., "Authorization", "x-gladia-key")
|
|
327
|
+
* @param authHeaderValue - Optional function to format auth header value (defaults to raw API key)
|
|
328
|
+
* @returns Axios config object
|
|
329
|
+
*/
|
|
330
|
+
getAxiosConfig(authHeaderName = "Authorization", authHeaderValue) {
|
|
331
|
+
this.validateConfig();
|
|
332
|
+
const authValue = authHeaderValue ? authHeaderValue(this.config.apiKey) : this.config.apiKey;
|
|
333
|
+
return {
|
|
334
|
+
baseURL: this.config.baseUrl || this.baseUrl,
|
|
335
|
+
timeout: this.config.timeout || DEFAULT_TIMEOUTS.HTTP_REQUEST,
|
|
336
|
+
headers: {
|
|
337
|
+
[authHeaderName]: authValue,
|
|
338
|
+
"Content-Type": "application/json",
|
|
339
|
+
...this.config.headers
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Generic polling helper for async transcription jobs
|
|
345
|
+
*
|
|
346
|
+
* Polls getTranscript() until job completes or times out.
|
|
347
|
+
*
|
|
348
|
+
* @param transcriptId - Job/transcript ID to poll
|
|
349
|
+
* @param options - Polling configuration
|
|
350
|
+
* @returns Final transcription result
|
|
351
|
+
*/
|
|
352
|
+
async pollForCompletion(transcriptId, options) {
|
|
353
|
+
const { maxAttempts = DEFAULT_POLLING.MAX_ATTEMPTS, intervalMs = DEFAULT_POLLING.INTERVAL_MS } = options || {};
|
|
354
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
355
|
+
const result = await this.getTranscript(transcriptId);
|
|
356
|
+
if (!result.success) {
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
const status = result.data?.status;
|
|
360
|
+
if (status === "completed") {
|
|
361
|
+
return result;
|
|
362
|
+
}
|
|
363
|
+
if (status === "error") {
|
|
364
|
+
return this.createErrorResponse(
|
|
365
|
+
new Error("Transcription failed"),
|
|
366
|
+
void 0,
|
|
367
|
+
ERROR_CODES.TRANSCRIPTION_ERROR
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
success: false,
|
|
374
|
+
provider: this.name,
|
|
375
|
+
error: {
|
|
376
|
+
code: ERROR_CODES.POLLING_TIMEOUT,
|
|
377
|
+
message: `Transcription did not complete after ${maxAttempts} attempts`
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
277
381
|
};
|
|
278
382
|
|
|
279
383
|
// src/adapters/gladia-adapter.ts
|
|
@@ -320,6 +424,143 @@ function mapEncodingToProvider(unifiedEncoding, provider) {
|
|
|
320
424
|
return providerEncoding;
|
|
321
425
|
}
|
|
322
426
|
|
|
427
|
+
// src/utils/websocket-helpers.ts
|
|
428
|
+
function waitForWebSocketOpen(ws, timeoutMs = DEFAULT_TIMEOUTS.WS_CONNECTION) {
|
|
429
|
+
return new Promise((resolve, reject) => {
|
|
430
|
+
const timeout = setTimeout(() => {
|
|
431
|
+
reject(new Error("WebSocket connection timeout"));
|
|
432
|
+
}, timeoutMs);
|
|
433
|
+
ws.once("open", () => {
|
|
434
|
+
clearTimeout(timeout);
|
|
435
|
+
resolve();
|
|
436
|
+
});
|
|
437
|
+
ws.once("error", (error) => {
|
|
438
|
+
clearTimeout(timeout);
|
|
439
|
+
reject(error);
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
function closeWebSocket(ws, timeoutMs = DEFAULT_TIMEOUTS.WS_CLOSE) {
|
|
444
|
+
return new Promise((resolve) => {
|
|
445
|
+
const timeout = setTimeout(() => {
|
|
446
|
+
ws.terminate();
|
|
447
|
+
resolve();
|
|
448
|
+
}, timeoutMs);
|
|
449
|
+
ws.close();
|
|
450
|
+
ws.once("close", () => {
|
|
451
|
+
clearTimeout(timeout);
|
|
452
|
+
resolve();
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
function setupWebSocketHandlers(ws, callbacks, setSessionStatus) {
|
|
457
|
+
ws.on("open", () => {
|
|
458
|
+
setSessionStatus("open");
|
|
459
|
+
callbacks?.onOpen?.();
|
|
460
|
+
});
|
|
461
|
+
ws.on("error", (error) => {
|
|
462
|
+
callbacks?.onError?.(createError(ERROR_CODES.WEBSOCKET_ERROR, error.message, error));
|
|
463
|
+
});
|
|
464
|
+
ws.on("close", (code, reason) => {
|
|
465
|
+
setSessionStatus("closed");
|
|
466
|
+
callbacks?.onClose?.(code, reason.toString());
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
function validateSessionForAudio(sessionStatus, wsReadyState, WebSocketOpen) {
|
|
470
|
+
if (sessionStatus !== "open") {
|
|
471
|
+
throw new Error(`Cannot send audio: session is ${sessionStatus}`);
|
|
472
|
+
}
|
|
473
|
+
if (wsReadyState !== WebSocketOpen) {
|
|
474
|
+
throw new Error("WebSocket is not open");
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// src/utils/validation.ts
|
|
479
|
+
function validateEnumValue(value, enumType, fieldName, provider) {
|
|
480
|
+
const validValues = Object.values(enumType);
|
|
481
|
+
const isValid = validValues.some((v) => v === value);
|
|
482
|
+
if (!isValid) {
|
|
483
|
+
throw new Error(
|
|
484
|
+
`${provider} does not support ${fieldName} '${value}'. Supported values (from OpenAPI spec): ${validValues.join(", ")}`
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
return value;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// src/utils/transcription-helpers.ts
|
|
491
|
+
function extractSpeakersFromUtterances(utterances, getSpeakerId, formatLabel) {
|
|
492
|
+
if (!utterances || utterances.length === 0) {
|
|
493
|
+
return void 0;
|
|
494
|
+
}
|
|
495
|
+
const speakerSet = /* @__PURE__ */ new Set();
|
|
496
|
+
utterances.forEach((utterance) => {
|
|
497
|
+
const speakerId = getSpeakerId(utterance);
|
|
498
|
+
if (speakerId !== void 0) {
|
|
499
|
+
speakerSet.add(String(speakerId));
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
if (speakerSet.size === 0) {
|
|
503
|
+
return void 0;
|
|
504
|
+
}
|
|
505
|
+
return Array.from(speakerSet).map((speakerId) => ({
|
|
506
|
+
id: speakerId,
|
|
507
|
+
label: formatLabel ? formatLabel(speakerId) : `Speaker ${speakerId}`
|
|
508
|
+
}));
|
|
509
|
+
}
|
|
510
|
+
function extractWords(words, mapper) {
|
|
511
|
+
if (!words || words.length === 0) {
|
|
512
|
+
return void 0;
|
|
513
|
+
}
|
|
514
|
+
const normalizedWords = words.map(mapper);
|
|
515
|
+
return normalizedWords.length > 0 ? normalizedWords : void 0;
|
|
516
|
+
}
|
|
517
|
+
var STATUS_MAPPINGS = {
|
|
518
|
+
gladia: {
|
|
519
|
+
queued: "queued",
|
|
520
|
+
processing: "processing",
|
|
521
|
+
done: "completed",
|
|
522
|
+
error: "error"
|
|
523
|
+
},
|
|
524
|
+
assemblyai: {
|
|
525
|
+
queued: "queued",
|
|
526
|
+
processing: "processing",
|
|
527
|
+
completed: "completed",
|
|
528
|
+
error: "error"
|
|
529
|
+
},
|
|
530
|
+
deepgram: {
|
|
531
|
+
queued: "queued",
|
|
532
|
+
processing: "processing",
|
|
533
|
+
completed: "completed",
|
|
534
|
+
error: "error"
|
|
535
|
+
},
|
|
536
|
+
azure: {
|
|
537
|
+
succeeded: "completed",
|
|
538
|
+
running: "processing",
|
|
539
|
+
notstarted: "queued",
|
|
540
|
+
failed: "error"
|
|
541
|
+
},
|
|
542
|
+
speechmatics: {
|
|
543
|
+
running: "processing",
|
|
544
|
+
done: "completed",
|
|
545
|
+
rejected: "error",
|
|
546
|
+
expired: "error"
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
function normalizeStatus(providerStatus, provider, defaultStatus = "queued") {
|
|
550
|
+
if (!providerStatus) return defaultStatus;
|
|
551
|
+
const mapping = STATUS_MAPPINGS[provider];
|
|
552
|
+
const statusKey = providerStatus.toString().toLowerCase();
|
|
553
|
+
if (statusKey in mapping) {
|
|
554
|
+
return mapping[statusKey];
|
|
555
|
+
}
|
|
556
|
+
for (const [key, value] of Object.entries(mapping)) {
|
|
557
|
+
if (statusKey.includes(key)) {
|
|
558
|
+
return value;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return defaultStatus;
|
|
562
|
+
}
|
|
563
|
+
|
|
323
564
|
// src/generated/gladia/api/gladiaControlAPI.ts
|
|
324
565
|
import axios from "axios";
|
|
325
566
|
|
|
@@ -1440,21 +1681,10 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1440
1681
|
}
|
|
1441
1682
|
/**
|
|
1442
1683
|
* Get axios config for generated API client functions
|
|
1443
|
-
* Configures headers and base URL
|
|
1684
|
+
* Configures headers and base URL using Gladia's x-gladia-key header
|
|
1444
1685
|
*/
|
|
1445
1686
|
getAxiosConfig() {
|
|
1446
|
-
|
|
1447
|
-
throw new Error("Adapter not initialized. Call initialize() first.");
|
|
1448
|
-
}
|
|
1449
|
-
return {
|
|
1450
|
-
baseURL: this.config.baseUrl || this.baseUrl,
|
|
1451
|
-
timeout: this.config.timeout || 6e4,
|
|
1452
|
-
headers: {
|
|
1453
|
-
"x-gladia-key": this.config.apiKey,
|
|
1454
|
-
"Content-Type": "application/json",
|
|
1455
|
-
...this.config.headers
|
|
1456
|
-
}
|
|
1457
|
-
};
|
|
1687
|
+
return super.getAxiosConfig("x-gladia-key");
|
|
1458
1688
|
}
|
|
1459
1689
|
/**
|
|
1460
1690
|
* Submit audio for transcription
|
|
@@ -1621,29 +1851,13 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1621
1851
|
* Normalize Gladia response to unified format
|
|
1622
1852
|
*/
|
|
1623
1853
|
normalizeResponse(response) {
|
|
1624
|
-
|
|
1625
|
-
switch (response.status) {
|
|
1626
|
-
case "queued":
|
|
1627
|
-
status = "queued";
|
|
1628
|
-
break;
|
|
1629
|
-
case "processing":
|
|
1630
|
-
status = "processing";
|
|
1631
|
-
break;
|
|
1632
|
-
case "done":
|
|
1633
|
-
status = "completed";
|
|
1634
|
-
break;
|
|
1635
|
-
case "error":
|
|
1636
|
-
status = "error";
|
|
1637
|
-
break;
|
|
1638
|
-
default:
|
|
1639
|
-
status = "queued";
|
|
1640
|
-
}
|
|
1854
|
+
const status = normalizeStatus(response.status, "gladia");
|
|
1641
1855
|
if (response.status === "error") {
|
|
1642
1856
|
return {
|
|
1643
1857
|
success: false,
|
|
1644
1858
|
provider: this.name,
|
|
1645
1859
|
error: {
|
|
1646
|
-
code: response.error_code?.toString() ||
|
|
1860
|
+
code: response.error_code?.toString() || ERROR_CODES.TRANSCRIPTION_ERROR,
|
|
1647
1861
|
message: "Transcription failed",
|
|
1648
1862
|
statusCode: response.error_code || void 0
|
|
1649
1863
|
},
|
|
@@ -1683,22 +1897,11 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1683
1897
|
* Extract speaker information from Gladia response
|
|
1684
1898
|
*/
|
|
1685
1899
|
extractSpeakers(transcription) {
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
if (utterance.speaker !== void 0) {
|
|
1692
|
-
speakerSet.add(utterance.speaker);
|
|
1693
|
-
}
|
|
1694
|
-
});
|
|
1695
|
-
if (speakerSet.size === 0) {
|
|
1696
|
-
return void 0;
|
|
1697
|
-
}
|
|
1698
|
-
return Array.from(speakerSet).map((speakerId) => ({
|
|
1699
|
-
id: speakerId.toString(),
|
|
1700
|
-
label: `Speaker ${speakerId}`
|
|
1701
|
-
}));
|
|
1900
|
+
return extractSpeakersFromUtterances(
|
|
1901
|
+
transcription?.utterances,
|
|
1902
|
+
(utterance) => utterance.speaker,
|
|
1903
|
+
(id) => `Speaker ${id}`
|
|
1904
|
+
);
|
|
1702
1905
|
}
|
|
1703
1906
|
/**
|
|
1704
1907
|
* Extract word timestamps from Gladia response
|
|
@@ -1709,14 +1912,17 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1709
1912
|
}
|
|
1710
1913
|
const allWords = transcription.utterances.flatMap(
|
|
1711
1914
|
(utterance) => utterance.words.map((word) => ({
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
end: word.end,
|
|
1715
|
-
confidence: word.confidence,
|
|
1716
|
-
speaker: utterance.speaker?.toString()
|
|
1915
|
+
word,
|
|
1916
|
+
speaker: utterance.speaker
|
|
1717
1917
|
}))
|
|
1718
1918
|
);
|
|
1719
|
-
return allWords
|
|
1919
|
+
return extractWords(allWords, (item) => ({
|
|
1920
|
+
text: item.word.word,
|
|
1921
|
+
start: item.word.start,
|
|
1922
|
+
end: item.word.end,
|
|
1923
|
+
confidence: item.word.confidence,
|
|
1924
|
+
speaker: item.speaker?.toString()
|
|
1925
|
+
}));
|
|
1720
1926
|
}
|
|
1721
1927
|
/**
|
|
1722
1928
|
* Extract utterances from Gladia response
|
|
@@ -1742,38 +1948,6 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1742
1948
|
/**
|
|
1743
1949
|
* Poll for transcription completion
|
|
1744
1950
|
*/
|
|
1745
|
-
async pollForCompletion(jobId, maxAttempts = 60, intervalMs = 2e3) {
|
|
1746
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
1747
|
-
const result = await this.getTranscript(jobId);
|
|
1748
|
-
if (!result.success) {
|
|
1749
|
-
return result;
|
|
1750
|
-
}
|
|
1751
|
-
const status = result.data?.status;
|
|
1752
|
-
if (status === "completed") {
|
|
1753
|
-
return result;
|
|
1754
|
-
}
|
|
1755
|
-
if (status === "error") {
|
|
1756
|
-
return {
|
|
1757
|
-
success: false,
|
|
1758
|
-
provider: this.name,
|
|
1759
|
-
error: {
|
|
1760
|
-
code: "TRANSCRIPTION_ERROR",
|
|
1761
|
-
message: "Transcription failed"
|
|
1762
|
-
},
|
|
1763
|
-
raw: result.raw
|
|
1764
|
-
};
|
|
1765
|
-
}
|
|
1766
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
1767
|
-
}
|
|
1768
|
-
return {
|
|
1769
|
-
success: false,
|
|
1770
|
-
provider: this.name,
|
|
1771
|
-
error: {
|
|
1772
|
-
code: "POLLING_TIMEOUT",
|
|
1773
|
-
message: `Transcription did not complete after ${maxAttempts} attempts`
|
|
1774
|
-
}
|
|
1775
|
-
};
|
|
1776
|
-
}
|
|
1777
1951
|
/**
|
|
1778
1952
|
* Stream audio for real-time transcription
|
|
1779
1953
|
*
|
|
@@ -1817,14 +1991,12 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1817
1991
|
this.validateConfig();
|
|
1818
1992
|
let validatedSampleRate;
|
|
1819
1993
|
if (options?.sampleRate) {
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
}
|
|
1827
|
-
validatedSampleRate = options.sampleRate;
|
|
1994
|
+
validatedSampleRate = validateEnumValue(
|
|
1995
|
+
options.sampleRate,
|
|
1996
|
+
StreamingSupportedSampleRateEnum,
|
|
1997
|
+
"sample rate",
|
|
1998
|
+
"Gladia"
|
|
1999
|
+
);
|
|
1828
2000
|
}
|
|
1829
2001
|
const streamingRequest = {
|
|
1830
2002
|
encoding: options?.encoding ? mapEncodingToProvider(options.encoding, "gladia") : void 0,
|
|
@@ -1846,9 +2018,8 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1846
2018
|
const { id, url: wsUrl } = initResponse.data;
|
|
1847
2019
|
const ws = new WebSocket(wsUrl);
|
|
1848
2020
|
let sessionStatus = "connecting";
|
|
1849
|
-
ws
|
|
1850
|
-
sessionStatus =
|
|
1851
|
-
callbacks?.onOpen?.();
|
|
2021
|
+
setupWebSocketHandlers(ws, callbacks, (status) => {
|
|
2022
|
+
sessionStatus = status;
|
|
1852
2023
|
});
|
|
1853
2024
|
ws.on("message", (data) => {
|
|
1854
2025
|
try {
|
|
@@ -1893,48 +2064,20 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1893
2064
|
}
|
|
1894
2065
|
} catch (error) {
|
|
1895
2066
|
callbacks?.onError?.({
|
|
1896
|
-
code:
|
|
2067
|
+
code: ERROR_CODES.PARSE_ERROR,
|
|
1897
2068
|
message: "Failed to parse WebSocket message",
|
|
1898
2069
|
details: error
|
|
1899
2070
|
});
|
|
1900
2071
|
}
|
|
1901
2072
|
});
|
|
1902
|
-
|
|
1903
|
-
callbacks?.onError?.({
|
|
1904
|
-
code: "WEBSOCKET_ERROR",
|
|
1905
|
-
message: error.message,
|
|
1906
|
-
details: error
|
|
1907
|
-
});
|
|
1908
|
-
});
|
|
1909
|
-
ws.on("close", (code, reason) => {
|
|
1910
|
-
sessionStatus = "closed";
|
|
1911
|
-
callbacks?.onClose?.(code, reason.toString());
|
|
1912
|
-
});
|
|
1913
|
-
await new Promise((resolve, reject) => {
|
|
1914
|
-
const timeout = setTimeout(() => {
|
|
1915
|
-
reject(new Error("WebSocket connection timeout"));
|
|
1916
|
-
}, 1e4);
|
|
1917
|
-
ws.once("open", () => {
|
|
1918
|
-
clearTimeout(timeout);
|
|
1919
|
-
resolve();
|
|
1920
|
-
});
|
|
1921
|
-
ws.once("error", (error) => {
|
|
1922
|
-
clearTimeout(timeout);
|
|
1923
|
-
reject(error);
|
|
1924
|
-
});
|
|
1925
|
-
});
|
|
2073
|
+
await waitForWebSocketOpen(ws);
|
|
1926
2074
|
return {
|
|
1927
2075
|
id,
|
|
1928
2076
|
provider: this.name,
|
|
1929
2077
|
createdAt: /* @__PURE__ */ new Date(),
|
|
1930
2078
|
getStatus: () => sessionStatus,
|
|
1931
2079
|
sendAudio: async (chunk) => {
|
|
1932
|
-
|
|
1933
|
-
throw new Error(`Cannot send audio: session is ${sessionStatus}`);
|
|
1934
|
-
}
|
|
1935
|
-
if (ws.readyState !== WebSocket.OPEN) {
|
|
1936
|
-
throw new Error("WebSocket is not open");
|
|
1937
|
-
}
|
|
2080
|
+
validateSessionForAudio(sessionStatus, ws.readyState, WebSocket.OPEN);
|
|
1938
2081
|
ws.send(chunk.data);
|
|
1939
2082
|
if (chunk.isLast) {
|
|
1940
2083
|
ws.send(
|
|
@@ -1956,18 +2099,8 @@ var GladiaAdapter = class extends BaseAdapter {
|
|
|
1956
2099
|
})
|
|
1957
2100
|
);
|
|
1958
2101
|
}
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
ws.terminate();
|
|
1962
|
-
resolve();
|
|
1963
|
-
}, 5e3);
|
|
1964
|
-
ws.close();
|
|
1965
|
-
ws.once("close", () => {
|
|
1966
|
-
clearTimeout(timeout);
|
|
1967
|
-
sessionStatus = "closed";
|
|
1968
|
-
resolve();
|
|
1969
|
-
});
|
|
1970
|
-
});
|
|
2102
|
+
await closeWebSocket(ws);
|
|
2103
|
+
sessionStatus = "closed";
|
|
1971
2104
|
}
|
|
1972
2105
|
};
|
|
1973
2106
|
}
|
|
@@ -2321,26 +2454,16 @@ var AssemblyAIAdapter = class extends BaseAdapter {
|
|
|
2321
2454
|
entityDetection: true,
|
|
2322
2455
|
piiRedaction: true
|
|
2323
2456
|
};
|
|
2324
|
-
this.baseUrl = "https://api.assemblyai.com
|
|
2457
|
+
this.baseUrl = "https://api.assemblyai.com";
|
|
2458
|
+
// Generated functions already include /v2 path
|
|
2325
2459
|
this.wsBaseUrl = "wss://api.assemblyai.com/v2/realtime/ws";
|
|
2326
2460
|
}
|
|
2327
2461
|
/**
|
|
2328
2462
|
* Get axios config for generated API client functions
|
|
2329
|
-
* Configures headers and base URL
|
|
2463
|
+
* Configures headers and base URL using authorization header
|
|
2330
2464
|
*/
|
|
2331
2465
|
getAxiosConfig() {
|
|
2332
|
-
|
|
2333
|
-
throw new Error("Adapter not initialized. Call initialize() first.");
|
|
2334
|
-
}
|
|
2335
|
-
return {
|
|
2336
|
-
baseURL: this.config.baseUrl || this.baseUrl,
|
|
2337
|
-
timeout: this.config.timeout || 6e4,
|
|
2338
|
-
headers: {
|
|
2339
|
-
authorization: this.config.apiKey,
|
|
2340
|
-
"Content-Type": "application/json",
|
|
2341
|
-
...this.config.headers
|
|
2342
|
-
}
|
|
2343
|
-
};
|
|
2466
|
+
return super.getAxiosConfig("authorization");
|
|
2344
2467
|
}
|
|
2345
2468
|
/**
|
|
2346
2469
|
* Submit audio for transcription
|
|
@@ -2618,41 +2741,6 @@ var AssemblyAIAdapter = class extends BaseAdapter {
|
|
|
2618
2741
|
}))
|
|
2619
2742
|
}));
|
|
2620
2743
|
}
|
|
2621
|
-
/**
|
|
2622
|
-
* Poll for transcription completion
|
|
2623
|
-
*/
|
|
2624
|
-
async pollForCompletion(transcriptId, maxAttempts = 60, intervalMs = 3e3) {
|
|
2625
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
2626
|
-
const result = await this.getTranscript(transcriptId);
|
|
2627
|
-
if (!result.success) {
|
|
2628
|
-
return result;
|
|
2629
|
-
}
|
|
2630
|
-
const status = result.data?.status;
|
|
2631
|
-
if (status === "completed") {
|
|
2632
|
-
return result;
|
|
2633
|
-
}
|
|
2634
|
-
if (status === "error") {
|
|
2635
|
-
return {
|
|
2636
|
-
success: false,
|
|
2637
|
-
provider: this.name,
|
|
2638
|
-
error: {
|
|
2639
|
-
code: "TRANSCRIPTION_ERROR",
|
|
2640
|
-
message: "Transcription failed"
|
|
2641
|
-
},
|
|
2642
|
-
raw: result.raw
|
|
2643
|
-
};
|
|
2644
|
-
}
|
|
2645
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
2646
|
-
}
|
|
2647
|
-
return {
|
|
2648
|
-
success: false,
|
|
2649
|
-
provider: this.name,
|
|
2650
|
-
error: {
|
|
2651
|
-
code: "POLLING_TIMEOUT",
|
|
2652
|
-
message: `Transcription did not complete after ${maxAttempts} attempts`
|
|
2653
|
-
}
|
|
2654
|
-
};
|
|
2655
|
-
}
|
|
2656
2744
|
/**
|
|
2657
2745
|
* Stream audio for real-time transcription
|
|
2658
2746
|
*
|
|
@@ -3294,7 +3382,24 @@ function createDeepgramAdapter(config) {
|
|
|
3294
3382
|
}
|
|
3295
3383
|
|
|
3296
3384
|
// src/adapters/azure-stt-adapter.ts
|
|
3385
|
+
import axios5 from "axios";
|
|
3386
|
+
|
|
3387
|
+
// src/generated/azure/api/speechServicesAPIV31.ts
|
|
3297
3388
|
import axios4 from "axios";
|
|
3389
|
+
var transcriptionsCreate = (transcription, options) => {
|
|
3390
|
+
return axios4.post("/transcriptions", transcription, options);
|
|
3391
|
+
};
|
|
3392
|
+
var transcriptionsGet = (id, options) => {
|
|
3393
|
+
return axios4.get(`/transcriptions/${id}`, options);
|
|
3394
|
+
};
|
|
3395
|
+
var transcriptionsListFiles = (id, params, options) => {
|
|
3396
|
+
return axios4.get(`/transcriptions/${id}/files`, {
|
|
3397
|
+
...options,
|
|
3398
|
+
params: { ...params, ...options?.params }
|
|
3399
|
+
});
|
|
3400
|
+
};
|
|
3401
|
+
|
|
3402
|
+
// src/adapters/azure-stt-adapter.ts
|
|
3298
3403
|
var AzureSTTAdapter = class extends BaseAdapter {
|
|
3299
3404
|
constructor() {
|
|
3300
3405
|
super(...arguments);
|
|
@@ -3311,20 +3416,20 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3311
3416
|
entityDetection: false,
|
|
3312
3417
|
piiRedaction: false
|
|
3313
3418
|
};
|
|
3419
|
+
this.baseUrl = "https://eastus.api.cognitive.microsoft.com/speechtotext/v3.1";
|
|
3314
3420
|
}
|
|
3421
|
+
// Default, overridden in initialize()
|
|
3315
3422
|
initialize(config) {
|
|
3316
3423
|
super.initialize(config);
|
|
3317
3424
|
this.region = config.region || "eastus";
|
|
3318
3425
|
this.baseUrl = config.baseUrl || `https://${this.region}.api.cognitive.microsoft.com/speechtotext/v3.1`;
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
}
|
|
3327
|
-
});
|
|
3426
|
+
}
|
|
3427
|
+
/**
|
|
3428
|
+
* Get axios config for generated API client functions
|
|
3429
|
+
* Configures headers and base URL using Azure subscription key
|
|
3430
|
+
*/
|
|
3431
|
+
getAxiosConfig() {
|
|
3432
|
+
return super.getAxiosConfig("Ocp-Apim-Subscription-Key");
|
|
3328
3433
|
}
|
|
3329
3434
|
/**
|
|
3330
3435
|
* Submit audio for transcription
|
|
@@ -3356,9 +3461,9 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3356
3461
|
contentUrls: [audio.url],
|
|
3357
3462
|
properties: this.buildTranscriptionProperties(options)
|
|
3358
3463
|
};
|
|
3359
|
-
const response = await
|
|
3360
|
-
|
|
3361
|
-
|
|
3464
|
+
const response = await transcriptionsCreate(
|
|
3465
|
+
transcriptionRequest,
|
|
3466
|
+
this.getAxiosConfig()
|
|
3362
3467
|
);
|
|
3363
3468
|
const transcription = response.data;
|
|
3364
3469
|
return {
|
|
@@ -3389,9 +3494,7 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3389
3494
|
async getTranscript(transcriptId) {
|
|
3390
3495
|
this.validateConfig();
|
|
3391
3496
|
try {
|
|
3392
|
-
const statusResponse = await this.
|
|
3393
|
-
`/transcriptions/${transcriptId}`
|
|
3394
|
-
);
|
|
3497
|
+
const statusResponse = await transcriptionsGet(transcriptId, this.getAxiosConfig());
|
|
3395
3498
|
const transcription = statusResponse.data;
|
|
3396
3499
|
const status = this.normalizeStatus(transcription.status);
|
|
3397
3500
|
if (status !== "completed") {
|
|
@@ -3419,7 +3522,11 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3419
3522
|
raw: transcription
|
|
3420
3523
|
};
|
|
3421
3524
|
}
|
|
3422
|
-
const filesResponse = await
|
|
3525
|
+
const filesResponse = await transcriptionsListFiles(
|
|
3526
|
+
transcriptId,
|
|
3527
|
+
void 0,
|
|
3528
|
+
this.getAxiosConfig()
|
|
3529
|
+
);
|
|
3423
3530
|
const files = filesResponse.data?.values || [];
|
|
3424
3531
|
const resultFile = files.find((file) => file.kind === "Transcription");
|
|
3425
3532
|
if (!resultFile?.links?.contentUrl) {
|
|
@@ -3433,7 +3540,7 @@ var AzureSTTAdapter = class extends BaseAdapter {
|
|
|
3433
3540
|
raw: transcription
|
|
3434
3541
|
};
|
|
3435
3542
|
}
|
|
3436
|
-
const contentResponse = await
|
|
3543
|
+
const contentResponse = await axios5.get(resultFile.links.contentUrl);
|
|
3437
3544
|
const transcriptionData = contentResponse.data;
|
|
3438
3545
|
return this.normalizeResponse(transcription, transcriptionData);
|
|
3439
3546
|
} catch (error) {
|
|
@@ -3532,7 +3639,57 @@ function createAzureSTTAdapter(config) {
|
|
|
3532
3639
|
}
|
|
3533
3640
|
|
|
3534
3641
|
// src/adapters/openai-whisper-adapter.ts
|
|
3535
|
-
import
|
|
3642
|
+
import axios7 from "axios";
|
|
3643
|
+
|
|
3644
|
+
// src/generated/openai/api/openAIAPI.ts
|
|
3645
|
+
import axios6 from "axios";
|
|
3646
|
+
var createTranscription = (createTranscriptionRequest, options) => {
|
|
3647
|
+
const formData = new FormData();
|
|
3648
|
+
formData.append("file", createTranscriptionRequest.file);
|
|
3649
|
+
formData.append("model", createTranscriptionRequest.model);
|
|
3650
|
+
if (createTranscriptionRequest.language !== void 0) {
|
|
3651
|
+
formData.append("language", createTranscriptionRequest.language);
|
|
3652
|
+
}
|
|
3653
|
+
if (createTranscriptionRequest.prompt !== void 0) {
|
|
3654
|
+
formData.append("prompt", createTranscriptionRequest.prompt);
|
|
3655
|
+
}
|
|
3656
|
+
if (createTranscriptionRequest.response_format !== void 0) {
|
|
3657
|
+
formData.append("response_format", createTranscriptionRequest.response_format);
|
|
3658
|
+
}
|
|
3659
|
+
if (createTranscriptionRequest.temperature !== void 0) {
|
|
3660
|
+
formData.append("temperature", createTranscriptionRequest.temperature.toString());
|
|
3661
|
+
}
|
|
3662
|
+
if (createTranscriptionRequest.include !== void 0) {
|
|
3663
|
+
createTranscriptionRequest.include.forEach((value) => formData.append("include", value));
|
|
3664
|
+
}
|
|
3665
|
+
if (createTranscriptionRequest.timestamp_granularities !== void 0) {
|
|
3666
|
+
createTranscriptionRequest.timestamp_granularities.forEach(
|
|
3667
|
+
(value) => formData.append("timestamp_granularities", value)
|
|
3668
|
+
);
|
|
3669
|
+
}
|
|
3670
|
+
if (createTranscriptionRequest.stream !== void 0 && createTranscriptionRequest.stream !== null) {
|
|
3671
|
+
formData.append("stream", createTranscriptionRequest.stream.toString());
|
|
3672
|
+
}
|
|
3673
|
+
if (createTranscriptionRequest.chunking_strategy !== void 0 && createTranscriptionRequest.chunking_strategy !== null) {
|
|
3674
|
+
formData.append(
|
|
3675
|
+
"chunking_strategy",
|
|
3676
|
+
typeof createTranscriptionRequest.chunking_strategy === "object" ? JSON.stringify(createTranscriptionRequest.chunking_strategy) : createTranscriptionRequest.chunking_strategy
|
|
3677
|
+
);
|
|
3678
|
+
}
|
|
3679
|
+
if (createTranscriptionRequest.known_speaker_names !== void 0) {
|
|
3680
|
+
createTranscriptionRequest.known_speaker_names.forEach(
|
|
3681
|
+
(value) => formData.append("known_speaker_names", value)
|
|
3682
|
+
);
|
|
3683
|
+
}
|
|
3684
|
+
if (createTranscriptionRequest.known_speaker_references !== void 0) {
|
|
3685
|
+
createTranscriptionRequest.known_speaker_references.forEach(
|
|
3686
|
+
(value) => formData.append("known_speaker_references", value)
|
|
3687
|
+
);
|
|
3688
|
+
}
|
|
3689
|
+
return axios6.post("/audio/transcriptions", formData, options);
|
|
3690
|
+
};
|
|
3691
|
+
|
|
3692
|
+
// src/adapters/openai-whisper-adapter.ts
|
|
3536
3693
|
var OpenAIWhisperAdapter = class extends BaseAdapter {
|
|
3537
3694
|
constructor() {
|
|
3538
3695
|
super(...arguments);
|
|
@@ -3554,19 +3711,12 @@ var OpenAIWhisperAdapter = class extends BaseAdapter {
|
|
|
3554
3711
|
};
|
|
3555
3712
|
this.baseUrl = "https://api.openai.com/v1";
|
|
3556
3713
|
}
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
// 2 minutes default (audio processing can take time)
|
|
3564
|
-
headers: {
|
|
3565
|
-
Authorization: `Bearer ${config.apiKey}`,
|
|
3566
|
-
"Content-Type": "multipart/form-data",
|
|
3567
|
-
...config.headers
|
|
3568
|
-
}
|
|
3569
|
-
});
|
|
3714
|
+
/**
|
|
3715
|
+
* Get axios config for generated API client functions
|
|
3716
|
+
* Configures headers and base URL using Bearer token authorization
|
|
3717
|
+
*/
|
|
3718
|
+
getAxiosConfig() {
|
|
3719
|
+
return super.getAxiosConfig("Authorization", (apiKey) => `Bearer ${apiKey}`);
|
|
3570
3720
|
}
|
|
3571
3721
|
/**
|
|
3572
3722
|
* Submit audio for transcription
|
|
@@ -3588,7 +3738,7 @@ var OpenAIWhisperAdapter = class extends BaseAdapter {
|
|
|
3588
3738
|
let audioData;
|
|
3589
3739
|
let fileName = "audio.mp3";
|
|
3590
3740
|
if (audio.type === "url") {
|
|
3591
|
-
const response2 = await
|
|
3741
|
+
const response2 = await axios7.get(audio.url, {
|
|
3592
3742
|
responseType: "arraybuffer"
|
|
3593
3743
|
});
|
|
3594
3744
|
audioData = Buffer.from(response2.data);
|
|
@@ -3613,40 +3763,37 @@ var OpenAIWhisperAdapter = class extends BaseAdapter {
|
|
|
3613
3763
|
const model = this.selectModel(options);
|
|
3614
3764
|
const isDiarization = model === "gpt-4o-transcribe-diarize";
|
|
3615
3765
|
const needsWords = options?.wordTimestamps === true;
|
|
3616
|
-
const
|
|
3766
|
+
const request = {
|
|
3617
3767
|
file: audioData,
|
|
3768
|
+
// Generated type expects Blob
|
|
3618
3769
|
model
|
|
3619
3770
|
};
|
|
3620
3771
|
if (options?.language) {
|
|
3621
|
-
|
|
3772
|
+
request.language = options.language;
|
|
3622
3773
|
}
|
|
3623
3774
|
if (options?.metadata?.prompt) {
|
|
3624
|
-
|
|
3775
|
+
request.prompt = options.metadata.prompt;
|
|
3625
3776
|
}
|
|
3626
3777
|
if (options?.metadata?.temperature !== void 0) {
|
|
3627
|
-
|
|
3778
|
+
request.temperature = options.metadata.temperature;
|
|
3628
3779
|
}
|
|
3629
3780
|
if (isDiarization) {
|
|
3630
|
-
|
|
3781
|
+
request.response_format = "diarized_json";
|
|
3631
3782
|
if (options?.metadata?.knownSpeakerNames) {
|
|
3632
|
-
|
|
3783
|
+
request.known_speaker_names = options.metadata.knownSpeakerNames;
|
|
3633
3784
|
}
|
|
3634
3785
|
if (options?.metadata?.knownSpeakerReferences) {
|
|
3635
|
-
|
|
3786
|
+
request.known_speaker_references = options.metadata.knownSpeakerReferences;
|
|
3636
3787
|
}
|
|
3637
3788
|
} else if (needsWords || options?.diarization) {
|
|
3638
|
-
|
|
3789
|
+
request.response_format = "verbose_json";
|
|
3639
3790
|
if (needsWords) {
|
|
3640
|
-
|
|
3791
|
+
request.timestamp_granularities = ["word", "segment"];
|
|
3641
3792
|
}
|
|
3642
3793
|
} else {
|
|
3643
|
-
|
|
3794
|
+
request.response_format = "json";
|
|
3644
3795
|
}
|
|
3645
|
-
const response = await this.
|
|
3646
|
-
headers: {
|
|
3647
|
-
"Content-Type": "multipart/form-data"
|
|
3648
|
-
}
|
|
3649
|
-
});
|
|
3796
|
+
const response = await createTranscription(request, this.getAxiosConfig());
|
|
3650
3797
|
return this.normalizeResponse(response.data, model, isDiarization);
|
|
3651
3798
|
} catch (error) {
|
|
3652
3799
|
return this.createErrorResponse(error);
|
|
@@ -3767,7 +3914,7 @@ function createOpenAIWhisperAdapter(config) {
|
|
|
3767
3914
|
}
|
|
3768
3915
|
|
|
3769
3916
|
// src/adapters/speechmatics-adapter.ts
|
|
3770
|
-
import
|
|
3917
|
+
import axios8 from "axios";
|
|
3771
3918
|
var SpeechmaticsAdapter = class extends BaseAdapter {
|
|
3772
3919
|
constructor() {
|
|
3773
3920
|
super(...arguments);
|
|
@@ -3789,7 +3936,7 @@ var SpeechmaticsAdapter = class extends BaseAdapter {
|
|
|
3789
3936
|
initialize(config) {
|
|
3790
3937
|
super.initialize(config);
|
|
3791
3938
|
this.baseUrl = config.baseUrl || this.baseUrl;
|
|
3792
|
-
this.client =
|
|
3939
|
+
this.client = axios8.create({
|
|
3793
3940
|
baseURL: this.baseUrl,
|
|
3794
3941
|
timeout: config.timeout || 12e4,
|
|
3795
3942
|
headers: {
|