@deepgram/sdk 5.4.0 → 5.5.0

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.
Files changed (87) hide show
  1. package/dist/browser/index.global.js +474 -18
  2. package/dist/cjs/BaseClient.d.ts +3 -0
  3. package/dist/cjs/BaseClient.js +20 -2
  4. package/dist/cjs/CustomClient.d.ts +75 -6
  5. package/dist/cjs/CustomClient.js +421 -15
  6. package/dist/cjs/api/errors/BadRequestError.js +1 -1
  7. package/dist/cjs/api/resources/agent/resources/v1/types/AgentV1SettingsAgentListenProvider.d.ts +7 -3
  8. package/dist/cjs/api/resources/agent/resources/v1/types/AgentV1SettingsAgentListenProvider.js +1 -7
  9. package/dist/cjs/api/resources/listen/resources/v1/client/Client.d.ts +1 -0
  10. package/dist/cjs/api/resources/listen/resources/v1/client/Client.js +2 -1
  11. package/dist/cjs/api/resources/listen/resources/v1/resources/media/client/requests/ListenV1RequestUrl.d.ts +2 -2
  12. package/dist/cjs/api/resources/listen/resources/v1/resources/media/client/requests/MediaTranscribeRequestOctetStream.d.ts +2 -2
  13. package/dist/cjs/api/resources/listen/resources/v1/types/DiarizeModel.d.ts +5 -0
  14. package/dist/cjs/api/{types/CreateKeyV1RequestOne.js → resources/listen/resources/v1/types/DiarizeModel.js} +5 -0
  15. package/dist/cjs/api/resources/listen/resources/v1/types/index.d.ts +1 -0
  16. package/dist/cjs/api/resources/listen/resources/v1/types/index.js +1 -0
  17. package/dist/cjs/api/resources/listen/resources/v2/client/Client.d.ts +1 -0
  18. package/dist/cjs/api/resources/listen/resources/v2/client/Client.js +2 -1
  19. package/dist/cjs/api/resources/listen/resources/v2/types/ListenV2CloseStream.d.ts +2 -1
  20. package/dist/cjs/api/resources/listen/resources/v2/types/ListenV2CloseStream.js +5 -1
  21. package/dist/cjs/api/resources/listen/resources/v2/types/ListenV2TurnInfo.d.ts +4 -0
  22. package/dist/cjs/api/types/DeepgramListenProviderV2.d.ts +7 -1
  23. package/dist/cjs/api/types/ListenV1Diarize.d.ts +1 -1
  24. package/dist/cjs/api/types/ListenV1Diarize.js +1 -1
  25. package/dist/cjs/api/types/ListenV2ProfanityFilter.d.ts +6 -0
  26. package/dist/cjs/api/types/ListenV2ProfanityFilter.js +9 -0
  27. package/dist/cjs/api/types/index.d.ts +1 -0
  28. package/dist/cjs/api/types/index.js +1 -0
  29. package/dist/cjs/auth/HeaderAuthProvider.js +2 -1
  30. package/dist/cjs/core/auth/AuthProvider.d.ts +1 -0
  31. package/dist/cjs/core/auth/AuthProvider.js +7 -0
  32. package/dist/cjs/core/auth/index.d.ts +1 -1
  33. package/dist/cjs/core/auth/index.js +3 -1
  34. package/dist/cjs/core/fetcher/getResponseBody.js +11 -0
  35. package/dist/cjs/core/fetcher/requestWithRetries.js +4 -1
  36. package/dist/cjs/core/fetcher/signals.js +9 -1
  37. package/dist/cjs/errors/DeepgramError.js +1 -1
  38. package/dist/cjs/errors/DeepgramTimeoutError.js +1 -1
  39. package/dist/cjs/index.d.ts +2 -0
  40. package/dist/cjs/index.js +1 -0
  41. package/dist/cjs/version.d.ts +1 -1
  42. package/dist/cjs/version.js +1 -1
  43. package/dist/esm/BaseClient.d.mts +3 -0
  44. package/dist/esm/BaseClient.mjs +20 -2
  45. package/dist/esm/CustomClient.d.mts +75 -6
  46. package/dist/esm/CustomClient.mjs +421 -15
  47. package/dist/esm/api/errors/BadRequestError.mjs +1 -1
  48. package/dist/esm/api/resources/agent/resources/v1/types/AgentV1SettingsAgentListenProvider.d.mts +7 -3
  49. package/dist/esm/api/resources/agent/resources/v1/types/AgentV1SettingsAgentListenProvider.mjs +1 -7
  50. package/dist/esm/api/resources/listen/resources/v1/client/Client.d.mts +1 -0
  51. package/dist/esm/api/resources/listen/resources/v1/client/Client.mjs +2 -1
  52. package/dist/esm/api/resources/listen/resources/v1/resources/media/client/requests/ListenV1RequestUrl.d.mts +2 -2
  53. package/dist/esm/api/resources/listen/resources/v1/resources/media/client/requests/MediaTranscribeRequestOctetStream.d.mts +2 -2
  54. package/dist/esm/api/resources/listen/resources/v1/types/DiarizeModel.d.mts +5 -0
  55. package/dist/esm/api/resources/listen/resources/v1/types/DiarizeModel.mjs +5 -0
  56. package/dist/esm/api/resources/listen/resources/v1/types/index.d.mts +1 -0
  57. package/dist/esm/api/resources/listen/resources/v1/types/index.mjs +1 -0
  58. package/dist/esm/api/resources/listen/resources/v2/client/Client.d.mts +1 -0
  59. package/dist/esm/api/resources/listen/resources/v2/client/Client.mjs +2 -1
  60. package/dist/esm/api/resources/listen/resources/v2/types/ListenV2CloseStream.d.mts +2 -1
  61. package/dist/esm/api/resources/listen/resources/v2/types/ListenV2CloseStream.mjs +5 -1
  62. package/dist/esm/api/resources/listen/resources/v2/types/ListenV2TurnInfo.d.mts +4 -0
  63. package/dist/esm/api/types/DeepgramListenProviderV2.d.mts +7 -1
  64. package/dist/esm/api/types/ListenV1Diarize.d.mts +1 -1
  65. package/dist/esm/api/types/ListenV1Diarize.mjs +1 -1
  66. package/dist/esm/api/types/ListenV2ProfanityFilter.d.mts +6 -0
  67. package/dist/esm/api/types/ListenV2ProfanityFilter.mjs +6 -0
  68. package/dist/esm/api/types/index.d.mts +1 -0
  69. package/dist/esm/api/types/index.mjs +1 -0
  70. package/dist/esm/auth/HeaderAuthProvider.mjs +2 -1
  71. package/dist/esm/core/auth/AuthProvider.d.mts +1 -0
  72. package/dist/esm/core/auth/AuthProvider.mjs +6 -1
  73. package/dist/esm/core/auth/index.d.mts +1 -1
  74. package/dist/esm/core/auth/index.mjs +1 -0
  75. package/dist/esm/core/fetcher/getResponseBody.mjs +11 -0
  76. package/dist/esm/core/fetcher/requestWithRetries.mjs +4 -1
  77. package/dist/esm/core/fetcher/signals.mjs +9 -1
  78. package/dist/esm/errors/DeepgramError.mjs +1 -1
  79. package/dist/esm/errors/DeepgramTimeoutError.mjs +1 -1
  80. package/dist/esm/index.d.mts +2 -0
  81. package/dist/esm/index.mjs +1 -0
  82. package/dist/esm/version.d.mts +1 -1
  83. package/dist/esm/version.mjs +1 -1
  84. package/package.json +1 -1
  85. package/dist/cjs/api/types/CreateKeyV1RequestOne.d.ts +0 -1
  86. package/dist/esm/api/types/CreateKeyV1RequestOne.d.mts +0 -1
  87. package/dist/esm/api/types/CreateKeyV1RequestOne.mjs +0 -2
@@ -23,6 +23,7 @@ import { V1Socket as SpeakV1Socket } from "./api/resources/speak/resources/v1/cl
23
23
  import { mergeHeaders } from "./core/headers.mjs";
24
24
  import { fromJson } from "./core/json.mjs";
25
25
  import * as core from "./core/index.mjs";
26
+ import * as websocketEvents from "./core/websocket/events.mjs";
26
27
  import * as environments from "./environments.mjs";
27
28
  import { RUNTIME } from "./core/runtime/index.mjs";
28
29
  // Default WebSocket connection timeout in milliseconds
@@ -32,6 +33,7 @@ const DEFAULT_CONNECTION_TIMEOUT_MS = 10000;
32
33
  const WEBSOCKET_OPTION_KEYS = new Set([
33
34
  "Authorization",
34
35
  "headers",
36
+ "protocols",
35
37
  "debug",
36
38
  "reconnectAttempts",
37
39
  "connectionTimeoutInSeconds",
@@ -151,18 +153,21 @@ class AccessTokenAuthProviderWrapper {
151
153
  });
152
154
  }
153
155
  }
154
- /**
155
- * Custom wrapper around DeepgramClient that ensures the custom websocket implementation
156
- * from ws.ts is always used, even if the auto-generated code changes.
157
- */
158
156
  export class CustomDeepgramClient extends DeepgramClient {
159
157
  constructor(options = {}) {
158
+ var _a;
160
159
  // Generate a UUID for the session ID
161
160
  const sessionId = generateUUID();
162
161
  // Add the session ID to headers so it's included in all REST requests
163
- const optionsWithSessionId = Object.assign(Object.assign({}, options), { headers: Object.assign(Object.assign({}, options.headers), { "x-deepgram-session-id": sessionId }) });
162
+ // Auto-disable wrapper-level reconnect when a custom transportFactory
163
+ // is in use: those transports own their retry lifecycle, and stacking
164
+ // a second retry layer on top causes storm-on-storm under burst load.
165
+ // Callers can still opt back in by explicitly passing reconnect: true.
166
+ const reconnect = (_a = options.reconnect) !== null && _a !== void 0 ? _a : options.transportFactory == null;
167
+ const optionsWithSessionId = Object.assign(Object.assign({}, options), { reconnect, headers: Object.assign(Object.assign({}, options.headers), { "x-deepgram-session-id": sessionId }) });
164
168
  super(optionsWithSessionId);
165
169
  this._sessionId = sessionId;
170
+ this._reconnect = reconnect;
166
171
  // Always wrap the auth provider to add "Token " prefix to API keys
167
172
  // The auto-generated HeaderAuthProvider doesn't add the prefix
168
173
  this._options.authProvider = new ApiKeyAuthProviderWrapper(this._options.authProvider);
@@ -178,6 +183,16 @@ export class CustomDeepgramClient extends DeepgramClient {
178
183
  get sessionId() {
179
184
  return this._sessionId;
180
185
  }
186
+ /**
187
+ * Whether the SDK will retry streaming connections at the wrapper level
188
+ * after a transport-side failure. Returns `false` when a `transportFactory`
189
+ * was supplied without an explicit `reconnect: true` override, signalling
190
+ * that the custom transport is expected to manage its own reconnect
191
+ * lifecycle.
192
+ */
193
+ get reconnect() {
194
+ return this._reconnect;
195
+ }
181
196
  /**
182
197
  * Override the agent getter to return a wrapped client that ensures
183
198
  * the custom websocket implementation is used.
@@ -291,12 +306,364 @@ function buildQueryParams(args) {
291
306
  }
292
307
  return result;
293
308
  }
309
+ function normalizeProtocols(protocols) {
310
+ if (protocols == null) {
311
+ return [];
312
+ }
313
+ return Array.isArray(protocols) ? protocols : [protocols];
314
+ }
315
+ function stringifyHeaders(headers) {
316
+ const result = {};
317
+ for (const [key, value] of Object.entries(headers)) {
318
+ result[key] = String(value);
319
+ }
320
+ return result;
321
+ }
322
+ function buildWebSocketUrl(url, queryParams) {
323
+ const queryString = core.url.toQueryString(queryParams, { arrayFormat: "repeat" });
324
+ return queryString ? `${url}?${queryString}` : url;
325
+ }
326
+ function getTransportFactory(options) {
327
+ return options.transportFactory;
328
+ }
329
+ function getReconnect(options) {
330
+ return options.reconnect !== false;
331
+ }
332
+ class TransportWebSocketAdapter {
333
+ constructor(args) {
334
+ this._listeners = {
335
+ error: [],
336
+ message: [],
337
+ open: [],
338
+ close: [],
339
+ };
340
+ this._retryCount = -1;
341
+ this._shouldReconnect = true;
342
+ this._connectLock = false;
343
+ this._binaryType = "blob";
344
+ this._closeCalled = false;
345
+ this._messageQueue = [];
346
+ this.CONNECTING = ReconnectingWebSocket.CONNECTING;
347
+ this.OPEN = ReconnectingWebSocket.OPEN;
348
+ this.CLOSING = ReconnectingWebSocket.CLOSING;
349
+ this.CLOSED = ReconnectingWebSocket.CLOSED;
350
+ this.onclose = null;
351
+ this.onerror = null;
352
+ this.onmessage = null;
353
+ this.onopen = null;
354
+ this._handleAbort = () => {
355
+ if (this._closeCalled) {
356
+ return;
357
+ }
358
+ this._debug("abort signal fired");
359
+ this._closeCalled = true;
360
+ this._shouldReconnect = false;
361
+ this._clearConnectTimeout();
362
+ const transport = this._transport;
363
+ this._transport = undefined;
364
+ this._setTransportHandle(undefined);
365
+ if (transport) {
366
+ void transport.close(1000, "aborted");
367
+ }
368
+ this._readyState = ReconnectingWebSocket.ReadyState.CLOSED;
369
+ this._emitClose(1000, "aborted");
370
+ };
371
+ this._factory = args.factory;
372
+ this._request = args.request;
373
+ this._reconnect = args.reconnect !== false;
374
+ this._readyState = args.startClosed
375
+ ? ReconnectingWebSocket.ReadyState.CLOSED
376
+ : ReconnectingWebSocket.ReadyState.CONNECTING;
377
+ if (this._request.abortSignal) {
378
+ this._request.abortSignal.addEventListener("abort", this._handleAbort, { once: true });
379
+ }
380
+ if (!args.startClosed) {
381
+ void this._connect();
382
+ }
383
+ }
384
+ get binaryType() {
385
+ return this._binaryType;
386
+ }
387
+ set binaryType(value) {
388
+ this._binaryType = value;
389
+ }
390
+ get retryCount() {
391
+ return Math.max(this._retryCount, 0);
392
+ }
393
+ get bufferedAmount() {
394
+ return this._messageQueue.reduce((acc, message) => {
395
+ if (typeof message === "string") {
396
+ return acc + message.length;
397
+ }
398
+ if (message instanceof Blob) {
399
+ return acc + message.size;
400
+ }
401
+ return acc + message.byteLength;
402
+ }, 0);
403
+ }
404
+ get extensions() {
405
+ return "";
406
+ }
407
+ get protocol() {
408
+ var _a;
409
+ return (_a = this._request.protocols[0]) !== null && _a !== void 0 ? _a : "";
410
+ }
411
+ get readyState() {
412
+ return this._readyState;
413
+ }
414
+ get url() {
415
+ return this._request.url;
416
+ }
417
+ close(code = 1000, reason) {
418
+ this._closeCalled = true;
419
+ this._shouldReconnect = false;
420
+ this._clearConnectTimeout();
421
+ this._readyState = ReconnectingWebSocket.ReadyState.CLOSING;
422
+ const transport = this._transport;
423
+ this._transport = undefined;
424
+ this._setTransportHandle(undefined);
425
+ if (!transport) {
426
+ this._readyState = ReconnectingWebSocket.ReadyState.CLOSED;
427
+ return;
428
+ }
429
+ void transport.close(code, reason);
430
+ this._readyState = ReconnectingWebSocket.ReadyState.CLOSED;
431
+ }
432
+ reconnect(code, reason) {
433
+ this._shouldReconnect = true;
434
+ this._closeCalled = false;
435
+ this._retryCount = -1;
436
+ this._readyState = ReconnectingWebSocket.ReadyState.CONNECTING;
437
+ const transport = this._transport;
438
+ this._transport = undefined;
439
+ this._setTransportHandle(undefined);
440
+ if (transport) {
441
+ void transport.close(code, reason);
442
+ }
443
+ void this._connect();
444
+ }
445
+ send(data) {
446
+ var _a;
447
+ if ((_a = this._transport) === null || _a === void 0 ? void 0 : _a.isOpen()) {
448
+ void this._transport.send(data);
449
+ return;
450
+ }
451
+ this._messageQueue.push(data);
452
+ }
453
+ addEventListener(type, listener) {
454
+ if (this._listeners[type]) {
455
+ this._listeners[type].push(listener);
456
+ }
457
+ }
458
+ dispatchEvent(event) {
459
+ const listeners = this._listeners[event.type];
460
+ if (listeners) {
461
+ for (const listener of listeners) {
462
+ this._callEventListener(event, listener);
463
+ }
464
+ }
465
+ return true;
466
+ }
467
+ removeEventListener(type, listener) {
468
+ if (this._listeners[type]) {
469
+ this._listeners[type] = this._listeners[type].filter((registered) => registered !== listener);
470
+ }
471
+ }
472
+ _debug(...args) {
473
+ if (this._request.debug) {
474
+ // biome-ignore lint/suspicious/noConsole: transport debug logging mirrors websocket debug logging
475
+ console.log.apply(console, ["DG-TRANSPORT>", ...args]);
476
+ }
477
+ }
478
+ _connect() {
479
+ return __awaiter(this, void 0, void 0, function* () {
480
+ var _a, _b;
481
+ if (this._connectLock || !this._shouldReconnect || ((_a = this._request.abortSignal) === null || _a === void 0 ? void 0 : _a.aborted)) {
482
+ return;
483
+ }
484
+ // When wrapper-level reconnect is disabled, allow only the initial
485
+ // attempt (_retryCount starts at -1 and increments to 0 on first
486
+ // _connect). Any subsequent re-entry from _handleError must short out
487
+ // so the transport's own retry logic is the single source of truth.
488
+ if (!this._reconnect && this._retryCount >= 0) {
489
+ this._debug("reconnect disabled, skipping retry");
490
+ return;
491
+ }
492
+ if (this._retryCount >= this._request.reconnectAttempts) {
493
+ this._debug("max retries reached", this._retryCount, ">=", this._request.reconnectAttempts);
494
+ return;
495
+ }
496
+ this._connectLock = true;
497
+ this._retryCount++;
498
+ this._readyState = ReconnectingWebSocket.ReadyState.CONNECTING;
499
+ this._clearConnectTimeout();
500
+ try {
501
+ const transport = yield this._factory(this._request.url, this._request.headers, this._request);
502
+ if (this._closeCalled || ((_b = this._request.abortSignal) === null || _b === void 0 ? void 0 : _b.aborted)) {
503
+ this._connectLock = false;
504
+ yield transport.close(1000, "aborted");
505
+ return;
506
+ }
507
+ this._transport = transport;
508
+ this._setTransportHandle(transport);
509
+ this._bindTransport(transport);
510
+ this._armConnectTimeout();
511
+ this._connectLock = false;
512
+ if (transport.isOpen()) {
513
+ this._handleOpen(transport);
514
+ }
515
+ }
516
+ catch (error) {
517
+ this._connectLock = false;
518
+ this._handleError(error instanceof Error ? error : new Error(String(error)));
519
+ }
520
+ });
521
+ }
522
+ _bindTransport(transport) {
523
+ transport.onOpen(() => {
524
+ if (this._transport !== transport) {
525
+ return;
526
+ }
527
+ this._handleOpen(transport);
528
+ });
529
+ transport.onMessage((message) => {
530
+ if (this._transport !== transport) {
531
+ return;
532
+ }
533
+ this._handleMessage(message);
534
+ });
535
+ transport.onError((error) => {
536
+ if (this._transport !== transport) {
537
+ return;
538
+ }
539
+ this._handleError(error);
540
+ });
541
+ transport.onClose((event) => {
542
+ var _a, _b;
543
+ if (this._transport !== transport) {
544
+ return;
545
+ }
546
+ this._handleClose((_a = event.code) !== null && _a !== void 0 ? _a : 1000, (_b = event.reason) !== null && _b !== void 0 ? _b : "");
547
+ });
548
+ }
549
+ _armConnectTimeout() {
550
+ const timeoutMs = this._request.connectionTimeoutInSeconds != null
551
+ ? this._request.connectionTimeoutInSeconds * 1000
552
+ : DEFAULT_CONNECTION_TIMEOUT_MS;
553
+ this._connectTimeout = setTimeout(() => {
554
+ this._handleError(new Error("TIMEOUT"));
555
+ }, timeoutMs);
556
+ }
557
+ _clearConnectTimeout() {
558
+ if (this._connectTimeout != null) {
559
+ clearTimeout(this._connectTimeout);
560
+ this._connectTimeout = undefined;
561
+ }
562
+ }
563
+ _handleOpen(transport) {
564
+ if (this._transport !== transport || this._readyState === ReconnectingWebSocket.ReadyState.OPEN) {
565
+ return;
566
+ }
567
+ this._debug("open event");
568
+ this._clearConnectTimeout();
569
+ this._readyState = ReconnectingWebSocket.ReadyState.OPEN;
570
+ const queued = [...this._messageQueue];
571
+ this._messageQueue = [];
572
+ for (const message of queued) {
573
+ void transport.send(message);
574
+ }
575
+ const event = new websocketEvents.Event("open", this);
576
+ if (this.onopen) {
577
+ this.onopen(event);
578
+ }
579
+ this._listeners.open.forEach((listener) => this._callEventListener(event, listener));
580
+ }
581
+ _handleMessage(message) {
582
+ const event = { type: "message", data: message, target: this };
583
+ if (this.onmessage) {
584
+ this.onmessage(event);
585
+ }
586
+ this._listeners.message.forEach((listener) => this._callEventListener(event, listener));
587
+ }
588
+ _handleError(error) {
589
+ this._debug("error event", error.message);
590
+ this._clearConnectTimeout();
591
+ this._readyState = ReconnectingWebSocket.ReadyState.CLOSED;
592
+ const event = new websocketEvents.ErrorEvent(error, this);
593
+ if (this.onerror) {
594
+ this.onerror(event);
595
+ }
596
+ this._listeners.error.forEach((listener) => this._callEventListener(event, listener));
597
+ const transport = this._transport;
598
+ this._transport = undefined;
599
+ this._setTransportHandle(undefined);
600
+ if (transport) {
601
+ void transport.close(1011, error.message);
602
+ }
603
+ if (this._shouldReconnect && !this._closeCalled) {
604
+ void this._connect();
605
+ }
606
+ }
607
+ _handleClose(code, reason) {
608
+ this._debug("close event", code, reason);
609
+ this._clearConnectTimeout();
610
+ this._transport = undefined;
611
+ this._readyState = ReconnectingWebSocket.ReadyState.CLOSED;
612
+ this._setTransportHandle(undefined);
613
+ if (code === 1000) {
614
+ this._shouldReconnect = false;
615
+ }
616
+ this._emitClose(code, reason);
617
+ if (this._shouldReconnect && !this._closeCalled) {
618
+ void this._connect();
619
+ }
620
+ }
621
+ _emitClose(code, reason) {
622
+ const event = new websocketEvents.CloseEvent(code, reason, this);
623
+ if (this.onclose) {
624
+ this.onclose(event);
625
+ }
626
+ this._listeners.close.forEach((listener) => this._callEventListener(event, listener));
627
+ }
628
+ _setTransportHandle(transport) {
629
+ if (!transport) {
630
+ this._ws = undefined;
631
+ return;
632
+ }
633
+ this._ws = {
634
+ OPEN: this.OPEN,
635
+ get readyState() {
636
+ return transport.isOpen()
637
+ ? ReconnectingWebSocket.ReadyState.OPEN
638
+ : ReconnectingWebSocket.ReadyState.CLOSED;
639
+ },
640
+ ping: transport.ping
641
+ ? (data) => {
642
+ var _a;
643
+ void ((_a = transport.ping) === null || _a === void 0 ? void 0 : _a.call(transport, data));
644
+ }
645
+ : undefined,
646
+ };
647
+ }
648
+ _callEventListener(event, listener) {
649
+ if (typeof listener === "object" && listener && "handleEvent" in listener) {
650
+ listener.handleEvent(event);
651
+ }
652
+ else {
653
+ listener(event);
654
+ }
655
+ }
656
+ }
657
+ TransportWebSocketAdapter.CONNECTING = ReconnectingWebSocket.CONNECTING;
658
+ TransportWebSocketAdapter.OPEN = ReconnectingWebSocket.OPEN;
659
+ TransportWebSocketAdapter.CLOSING = ReconnectingWebSocket.CLOSING;
660
+ TransportWebSocketAdapter.CLOSED = ReconnectingWebSocket.CLOSED;
294
661
  /**
295
662
  * Helper function to get WebSocket class and handle headers/protocols based on runtime.
296
663
  * In Node.js, use the 'ws' library which supports headers.
297
664
  * In browser, use Sec-WebSocket-Protocol for authentication since headers aren't supported.
298
665
  */
299
- function getWebSocketOptions(headers) {
666
+ function getWebSocketOptions(headers, requestedProtocols) {
300
667
  const options = {};
301
668
  // Check if we're in a browser environment (browser or web-worker)
302
669
  const isBrowser = RUNTIME.type === "browser" || RUNTIME.type === "web-worker";
@@ -306,6 +673,9 @@ function getWebSocketOptions(headers) {
306
673
  if (RUNTIME.type === "node" && NodeWebSocket) {
307
674
  options.WebSocket = NodeWebSocket;
308
675
  options.headers = headers;
676
+ if (requestedProtocols.length > 0) {
677
+ options.protocols = requestedProtocols;
678
+ }
309
679
  }
310
680
  else if (isBrowser) {
311
681
  // In browser, native WebSocket doesn't support custom headers
@@ -319,7 +689,7 @@ function getWebSocketOptions(headers) {
319
689
  delete browserHeaders["X-Deepgram-Session-Id"];
320
690
  options.headers = browserHeaders;
321
691
  // Build protocols array for browser WebSocket
322
- const protocols = [];
692
+ const protocols = [...requestedProtocols];
323
693
  // If we have an Authorization header, extract the token and format as protocols
324
694
  // Deepgram expects:
325
695
  // - For API keys: Sec-WebSocket-Protocol: token,API_KEY_GOES_HERE
@@ -352,6 +722,9 @@ function getWebSocketOptions(headers) {
352
722
  else {
353
723
  // Fallback for other environments
354
724
  options.headers = headers;
725
+ if (requestedProtocols.length > 0) {
726
+ options.protocols = requestedProtocols;
727
+ }
355
728
  }
356
729
  return options;
357
730
  }
@@ -428,7 +801,7 @@ function resetSocketConnectionState(socket) {
428
801
  * This reduces duplication across all Wrapped*Client classes.
429
802
  */
430
803
  function createWebSocketConnection(_a) {
431
- return __awaiter(this, arguments, void 0, function* ({ options, urlPath, environmentKey, queryParams, headers, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal, }) {
804
+ return __awaiter(this, arguments, void 0, function* ({ options, urlPath, environmentKey, queryParams, protocols, service, headers, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal, }) {
432
805
  var _b, _c, _d, _e, _f, _g;
433
806
  // Ensure ws is loaded for Node.js environments (no-op after first call)
434
807
  yield loadNodeWebSocket();
@@ -438,13 +811,38 @@ function createWebSocketConnection(_a) {
438
811
  const mergedHeaders = mergeHeaders((_c = options.headers) !== null && _c !== void 0 ? _c : {}, (_d = authRequest === null || authRequest === void 0 ? void 0 : authRequest.headers) !== null && _d !== void 0 ? _d : {}, headers);
439
812
  // Resolve any Suppliers in headers to actual values
440
813
  const _headers = yield resolveHeaders(mergedHeaders);
441
- // Get WebSocket options with proper header handling
442
- const wsOptions = getWebSocketOptions(_headers);
814
+ const normalizedProtocols = normalizeProtocols(protocols);
443
815
  // Get the appropriate base URL for the environment
444
816
  const baseUrl = (_e = (yield core.Supplier.get(options.baseUrl))) !== null && _e !== void 0 ? _e : ((_f = (yield core.Supplier.get(options.environment))) !== null && _f !== void 0 ? _f : environments.DeepgramEnvironment.Production)[environmentKey];
817
+ const url = core.url.join(baseUrl, urlPath);
818
+ const fullUrl = buildWebSocketUrl(url, queryParams);
819
+ const transportFactory = getTransportFactory(options);
820
+ const reconnect = getReconnect(options);
821
+ if (transportFactory) {
822
+ const request = {
823
+ url: fullUrl,
824
+ headers: stringifyHeaders(_headers),
825
+ protocols: normalizedProtocols,
826
+ path: urlPath,
827
+ service,
828
+ queryParams,
829
+ debug: debug !== null && debug !== void 0 ? debug : false,
830
+ reconnectAttempts: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
831
+ connectionTimeoutInSeconds,
832
+ abortSignal,
833
+ };
834
+ return new TransportWebSocketAdapter({
835
+ factory: transportFactory,
836
+ request,
837
+ startClosed: true,
838
+ reconnect,
839
+ });
840
+ }
841
+ // Get WebSocket options with proper header handling
842
+ const wsOptions = getWebSocketOptions(_headers, normalizedProtocols);
445
843
  // Create and return the ReconnectingWebSocket
446
844
  return new ReconnectingWebSocket({
447
- url: core.url.join(baseUrl, urlPath),
845
+ url,
448
846
  protocols: (_g = wsOptions.protocols) !== null && _g !== void 0 ? _g : [],
449
847
  queryParameters: queryParams,
450
848
  headers: wsOptions.headers,
@@ -470,12 +868,14 @@ function createWebSocketConnection(_a) {
470
868
  class WrappedAgentV1Client extends AgentV1Client {
471
869
  connect() {
472
870
  return __awaiter(this, arguments, void 0, function* (args = {}) {
473
- const { headers, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal } = args;
871
+ const { headers, protocols, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal } = args;
474
872
  const socket = yield createWebSocketConnection({
475
873
  options: this._options,
476
874
  urlPath: "/v1/agent/converse",
477
875
  environmentKey: "agent",
478
876
  queryParams: buildQueryParams(args),
877
+ protocols,
878
+ service: "agent.v1",
479
879
  headers,
480
880
  debug,
481
881
  reconnectAttempts,
@@ -547,12 +947,14 @@ class WrappedAgentV1Socket extends AgentV1Socket {
547
947
  class WrappedListenV1Client extends ListenV1Client {
548
948
  connect(args) {
549
949
  return __awaiter(this, void 0, void 0, function* () {
550
- const { headers, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal } = args;
950
+ const { headers, protocols, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal } = args;
551
951
  const socket = yield createWebSocketConnection({
552
952
  options: this._options,
553
953
  urlPath: "/v1/listen",
554
954
  environmentKey: "production",
555
955
  queryParams: buildQueryParams(args),
956
+ protocols,
957
+ service: "listen.v1",
556
958
  headers,
557
959
  debug,
558
960
  reconnectAttempts,
@@ -623,12 +1025,14 @@ class WrappedListenV1Socket extends ListenV1Socket {
623
1025
  class WrappedListenV2Client extends ListenV2Client {
624
1026
  connect(args) {
625
1027
  return __awaiter(this, void 0, void 0, function* () {
626
- const { headers, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal } = args;
1028
+ const { headers, protocols, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal } = args;
627
1029
  const socket = yield createWebSocketConnection({
628
1030
  options: this._options,
629
1031
  urlPath: "/v2/listen",
630
1032
  environmentKey: "production",
631
1033
  queryParams: buildQueryParams(args),
1034
+ protocols,
1035
+ service: "listen.v2",
632
1036
  headers,
633
1037
  debug,
634
1038
  reconnectAttempts,
@@ -730,12 +1134,14 @@ class WrappedListenV2Socket extends ListenV2Socket {
730
1134
  class WrappedSpeakV1Client extends SpeakV1Client {
731
1135
  connect(args) {
732
1136
  return __awaiter(this, void 0, void 0, function* () {
733
- const { headers, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal } = args;
1137
+ const { headers, protocols, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal } = args;
734
1138
  const socket = yield createWebSocketConnection({
735
1139
  options: this._options,
736
1140
  urlPath: "/v1/speak",
737
1141
  environmentKey: "production",
738
1142
  queryParams: buildQueryParams(args),
1143
+ protocols,
1144
+ service: "speak.v1",
739
1145
  headers,
740
1146
  debug,
741
1147
  reconnectAttempts,
@@ -12,6 +12,6 @@ export class BadRequestError extends errors.DeepgramError {
12
12
  if (Error.captureStackTrace) {
13
13
  Error.captureStackTrace(this, this.constructor);
14
14
  }
15
- this.name = this.constructor.name;
15
+ this.name = "BadRequestError";
16
16
  }
17
17
  }
@@ -1,6 +1,10 @@
1
1
  import type * as Deepgram from "../../../../../index.mjs";
2
- export type AgentV1SettingsAgentListenProvider = Deepgram.agent.AgentV1SettingsAgentContextListenProvider;
2
+ export type AgentV1SettingsAgentListenProvider = Deepgram.agent.AgentV1SettingsAgentListenProvider.V1 | Deepgram.agent.AgentV1SettingsAgentListenProvider.V2;
3
3
  export declare namespace AgentV1SettingsAgentListenProvider {
4
- type V1 = Deepgram.agent.AgentV1SettingsAgentContextListenProvider.V1;
5
- type V2 = Deepgram.agent.AgentV1SettingsAgentContextListenProvider.V2;
4
+ interface V1 extends Deepgram.DeepgramListenProviderV1 {
5
+ version: "v1";
6
+ }
7
+ interface V2 extends Deepgram.DeepgramListenProviderV2 {
8
+ version: "v2";
9
+ }
6
10
  }
@@ -1,8 +1,2 @@
1
- // Backward-compat alias for the type renamed by the 2026-05-06 regen to
2
- // `AgentV1SettingsAgentContextListenProvider`. The new V2 only adds an optional
3
- // `language_hint` field, so this alias is purely additive: every literal that
4
- // satisfied the old V2 still satisfies the new V2, and pinned-name callers
5
- // (`const p: AgentV1SettingsAgentListenProvider = ...`) keep compiling without
6
- // a cast. See AGENTS.md for the patch rationale; regression coverage in
7
- // tests/unit/compat-aliases.test.ts.
1
+ // This file was auto-generated by Fern from our API Definition.
8
2
  export {};
@@ -11,6 +11,7 @@ export declare namespace V1Client {
11
11
  channels?: Deepgram.ListenV1Channels | undefined;
12
12
  detect_entities?: Deepgram.ListenV1DetectEntities;
13
13
  diarize?: Deepgram.ListenV1Diarize;
14
+ diarize_model?: Deepgram.listen.DiarizeModel;
14
15
  dictation?: Deepgram.ListenV1Dictation;
15
16
  encoding?: Deepgram.ListenV1Encoding;
16
17
  endpointing?: Deepgram.ListenV1Endpointing | undefined;
@@ -26,13 +26,14 @@ export class V1Client {
26
26
  connect(args) {
27
27
  return __awaiter(this, void 0, void 0, function* () {
28
28
  var _a, _b, _c;
29
- const { callback, callback_method: callbackMethod, channels, detect_entities: detectEntities, diarize, dictation, encoding, endpointing, extra, interim_results: interimResults, keyterm, keywords, language, mip_opt_out: mipOptOut, model, multichannel, numerals, profanity_filter: profanityFilter, punctuate, redact, replace, sample_rate: sampleRate, search, smart_format: smartFormat, tag, utterance_end_ms: utteranceEndMs, vad_events: vadEvents, version, protocols, queryParams, headers, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal, } = args;
29
+ const { callback, callback_method: callbackMethod, channels, detect_entities: detectEntities, diarize, diarize_model: diarizeModel, dictation, encoding, endpointing, extra, interim_results: interimResults, keyterm, keywords, language, mip_opt_out: mipOptOut, model, multichannel, numerals, profanity_filter: profanityFilter, punctuate, redact, replace, sample_rate: sampleRate, search, smart_format: smartFormat, tag, utterance_end_ms: utteranceEndMs, vad_events: vadEvents, version, protocols, queryParams, headers, debug, reconnectAttempts, connectionTimeoutInSeconds, abortSignal, } = args;
30
30
  const _queryParams = {
31
31
  callback: callback != null ? (typeof callback === "string" ? callback : toJson(callback)) : undefined,
32
32
  callback_method: callbackMethod != null ? callbackMethod : undefined,
33
33
  channels: channels != null ? (typeof channels === "string" ? channels : toJson(channels)) : undefined,
34
34
  detect_entities: detectEntities != null ? detectEntities : undefined,
35
35
  diarize: diarize != null ? diarize : undefined,
36
+ diarize_model: diarizeModel != null ? diarizeModel : undefined,
36
37
  dictation: dictation != null ? dictation : undefined,
37
38
  encoding: encoding != null ? encoding : undefined,
38
39
  endpointing: endpointing != null ? (typeof endpointing === "string" ? endpointing : toJson(endpointing)) : undefined,
@@ -71,9 +71,9 @@ export interface ListenV1RequestUrl {
71
71
  detect_entities?: boolean;
72
72
  /** Identifies the dominant language spoken in submitted audio */
73
73
  detect_language?: boolean;
74
- /** Recognize speaker changes. Each word in the transcript will be assigned a speaker number starting at 0 */
74
+ /** Deprecated: use `diarize_model` instead. Recognize speaker changes. Each word in the transcript will be assigned a speaker number starting at 0. */
75
75
  diarize?: boolean;
76
- /** Select and enable a specific batch diarization model version. If specifying this parameter, you should not set the deprecated `diarize=true` parameter. Not accepted on streaming requests. */
76
+ /** Select and enable a specific diarization model version. Specifying this parameter enables diarization and selects the model — you do not need to also set the deprecated `diarize=true` parameter. For batch, supported values are `latest` (currently v2), `v1`, and `v2`. For streaming, supported values are `latest` (currently v1) and `v1`; `v2` returns a validation error on streaming requests. */
77
77
  diarize_model?: Deepgram.listen.v1.MediaTranscribeRequestDiarizeModel;
78
78
  /** Dictation mode for controlling formatting with dictated speech */
79
79
  dictation?: boolean;
@@ -32,9 +32,9 @@ export interface MediaTranscribeRequestOctetStream {
32
32
  detect_entities?: boolean;
33
33
  /** Identifies the dominant language spoken in submitted audio */
34
34
  detect_language?: boolean;
35
- /** Recognize speaker changes. Each word in the transcript will be assigned a speaker number starting at 0 */
35
+ /** Deprecated: use `diarize_model` instead. Recognize speaker changes. Each word in the transcript will be assigned a speaker number starting at 0. */
36
36
  diarize?: boolean;
37
- /** Select and enable a specific batch diarization model version. If specifying this parameter, you should not set the deprecated `diarize=true` parameter. Not accepted on streaming requests. */
37
+ /** Select and enable a specific diarization model version. Specifying this parameter enables diarization and selects the model — you do not need to also set the deprecated `diarize=true` parameter. For batch, supported values are `latest` (currently v2), `v1`, and `v2`. For streaming, supported values are `latest` (currently v1) and `v1`; `v2` returns a validation error on streaming requests. */
38
38
  diarize_model?: Deepgram.listen.v1.MediaTranscribeRequestDiarizeModel;
39
39
  /** Dictation mode for controlling formatting with dictated speech */
40
40
  dictation?: boolean;
@@ -0,0 +1,5 @@
1
+ export declare const DiarizeModel: {
2
+ readonly Latest: "latest";
3
+ readonly V1: "v1";
4
+ };
5
+ export type DiarizeModel = (typeof DiarizeModel)[keyof typeof DiarizeModel] | string;
@@ -0,0 +1,5 @@
1
+ // This file was auto-generated by Fern from our API Definition.
2
+ export const DiarizeModel = {
3
+ Latest: "latest",
4
+ V1: "v1",
5
+ };
@@ -1,3 +1,4 @@
1
+ export * from "./DiarizeModel.mjs";
1
2
  export * from "./ListenV1CloseStream.mjs";
2
3
  export * from "./ListenV1Finalize.mjs";
3
4
  export * from "./ListenV1KeepAlive.mjs";