voice-router-dev 0.8.2 → 0.8.3

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.js CHANGED
@@ -234,6 +234,9 @@ __export(src_exports, {
234
234
  transcriptionsGet: () => transcriptionsGet,
235
235
  transcriptionsList: () => transcriptionsList,
236
236
  transcriptionsListFiles: () => transcriptionsListFiles,
237
+ webHooksCreate: () => webHooksCreate,
238
+ webHooksDelete: () => webHooksDelete,
239
+ webHooksList: () => webHooksList,
237
240
  zodToFieldConfigs: () => zodToFieldConfigs
238
241
  });
239
242
  module.exports = __toCommonJS(src_exports);
@@ -2922,6 +2925,12 @@ var ERROR_CODES = {
2922
2925
  CONNECTION_TIMEOUT: "CONNECTION_TIMEOUT",
2923
2926
  /** Invalid input provided to API */
2924
2927
  INVALID_INPUT: "INVALID_INPUT",
2928
+ /** Authentication failed (invalid or missing API key) */
2929
+ AUTHENTICATION_ERROR: "AUTHENTICATION_ERROR",
2930
+ /** Rate limit exceeded */
2931
+ RATE_LIMIT: "RATE_LIMIT",
2932
+ /** Provider server error (5xx) */
2933
+ SERVER_ERROR: "SERVER_ERROR",
2925
2934
  /** Requested operation not supported by provider */
2926
2935
  NOT_SUPPORTED: "NOT_SUPPORTED",
2927
2936
  /** No transcription results available */
@@ -2936,6 +2945,9 @@ var ERROR_MESSAGES = {
2936
2945
  TRANSCRIPTION_ERROR: "Transcription processing failed",
2937
2946
  CONNECTION_TIMEOUT: "Connection attempt timed out",
2938
2947
  INVALID_INPUT: "Invalid input provided",
2948
+ AUTHENTICATION_ERROR: "Authentication failed (invalid or missing API key)",
2949
+ RATE_LIMIT: "Rate limit exceeded",
2950
+ SERVER_ERROR: "Provider server error",
2939
2951
  NOT_SUPPORTED: "Operation not supported by this provider",
2940
2952
  NO_RESULTS: "No transcription results available",
2941
2953
  UNKNOWN_ERROR: "An unknown error occurred"
@@ -2947,6 +2959,36 @@ function createError(code, customMessage, details) {
2947
2959
  details
2948
2960
  };
2949
2961
  }
2962
+ function httpStatusToErrorCode(status) {
2963
+ switch (status) {
2964
+ case 400:
2965
+ case 404:
2966
+ case 422:
2967
+ return ERROR_CODES.INVALID_INPUT;
2968
+ case 401:
2969
+ case 403:
2970
+ return ERROR_CODES.AUTHENTICATION_ERROR;
2971
+ case 408:
2972
+ return ERROR_CODES.CONNECTION_TIMEOUT;
2973
+ case 429:
2974
+ return ERROR_CODES.RATE_LIMIT;
2975
+ default:
2976
+ if (status >= 500) return ERROR_CODES.SERVER_ERROR;
2977
+ return ERROR_CODES.UNKNOWN_ERROR;
2978
+ }
2979
+ }
2980
+ function extractProviderMessage(data) {
2981
+ if (!data || typeof data !== "object") {
2982
+ return typeof data === "string" ? data : void 0;
2983
+ }
2984
+ const d = data;
2985
+ if (d.error && typeof d.error === "object" && d.error.message) return String(d.error.message);
2986
+ if (typeof d.error === "string") return d.error;
2987
+ if (d.detail && typeof d.detail === "object" && d.detail.message) return String(d.detail.message);
2988
+ if (typeof d.message === "string") return d.message;
2989
+ if (typeof d.err_msg === "string") return d.err_msg;
2990
+ return void 0;
2991
+ }
2950
2992
 
2951
2993
  // src/adapters/base-adapter.ts
2952
2994
  var BaseAdapter = class {
@@ -2965,12 +3007,15 @@ var BaseAdapter = class {
2965
3007
  const httpStatus = statusCode || err.statusCode || err.response?.status;
2966
3008
  const httpStatusText = err.response?.statusText;
2967
3009
  const responseData = err.response?.data;
3010
+ const errorCode = code || (httpStatus ? httpStatusToErrorCode(httpStatus) : void 0) || ERROR_CODES.UNKNOWN_ERROR;
3011
+ const providerMessage = extractProviderMessage(responseData);
3012
+ const message = providerMessage || err.message || "An unknown error occurred";
2968
3013
  return {
2969
3014
  success: false,
2970
3015
  provider: this.name,
2971
3016
  error: {
2972
- code: code || err.code || ERROR_CODES.UNKNOWN_ERROR,
2973
- message: err.message || "An unknown error occurred",
3017
+ code: errorCode,
3018
+ message,
2974
3019
  statusCode: httpStatus,
2975
3020
  details: {
2976
3021
  // Include full error object
@@ -5611,14 +5656,61 @@ var AssemblyAIAdapter = class extends BaseAdapter {
5611
5656
  this.wsBaseUrl = "wss://streaming.assemblyai.com/v3/ws";
5612
5657
  }
5613
5658
  // v3 Universal Streaming endpoint
5659
+ /**
5660
+ * Get regional hosts for AssemblyAI
5661
+ *
5662
+ * @param region - Regional endpoint identifier
5663
+ * @returns Object with api and streaming hosts
5664
+ */
5665
+ getRegionalHosts(region) {
5666
+ if (region === "eu") {
5667
+ return { api: "api.eu.assemblyai.com", streaming: "streaming.eu.assemblyai.com" };
5668
+ }
5669
+ return { api: "api.assemblyai.com", streaming: "streaming.assemblyai.com" };
5670
+ }
5614
5671
  initialize(config) {
5615
5672
  super.initialize(config);
5616
- if (config.wsBaseUrl) {
5617
- this.wsBaseUrl = config.wsBaseUrl;
5618
- } else if (config.baseUrl) {
5619
- this.wsBaseUrl = `${this.deriveWsUrl(config.baseUrl)}/v3/ws`;
5673
+ const hosts = this.getRegionalHosts(config.region);
5674
+ this.baseUrl = config.baseUrl || `https://${hosts.api}`;
5675
+ this.wsBaseUrl = config.wsBaseUrl || (config.baseUrl ? `${this.deriveWsUrl(config.baseUrl)}/v3/ws` : `wss://${hosts.streaming}/v3/ws`);
5676
+ }
5677
+ /**
5678
+ * Change the regional endpoint dynamically
5679
+ *
5680
+ * Useful for switching between US and EU endpoints without reinitializing.
5681
+ * Affects both REST API and WebSocket streaming endpoints.
5682
+ *
5683
+ * @param region - New regional endpoint to use (`us` or `eu`)
5684
+ *
5685
+ * @example Switch to EU region
5686
+ * ```typescript
5687
+ * import { AssemblyAIRegion } from 'voice-router-dev/constants'
5688
+ *
5689
+ * adapter.setRegion(AssemblyAIRegion.eu)
5690
+ * await adapter.transcribe(audio) // Uses EU endpoint
5691
+ * ```
5692
+ */
5693
+ setRegion(region) {
5694
+ this.validateConfig();
5695
+ if (!this.config.baseUrl) {
5696
+ const hosts = this.getRegionalHosts(region);
5697
+ this.baseUrl = `https://${hosts.api}`;
5698
+ if (!this.config.wsBaseUrl) {
5699
+ this.wsBaseUrl = `wss://${hosts.streaming}/v3/ws`;
5700
+ }
5620
5701
  }
5621
5702
  }
5703
+ /**
5704
+ * Get the current regional endpoints being used
5705
+ *
5706
+ * @returns Object with current API and WebSocket URLs
5707
+ */
5708
+ getRegion() {
5709
+ return {
5710
+ api: this.baseUrl,
5711
+ websocket: this.wsBaseUrl
5712
+ };
5713
+ }
5622
5714
  /**
5623
5715
  * Get axios config for generated API client functions
5624
5716
  * Configures headers and base URL using authorization header
@@ -7676,6 +7768,18 @@ var transcriptionsListFiles = (id, params, options) => {
7676
7768
  params: { ...params, ...options?.params }
7677
7769
  });
7678
7770
  };
7771
+ var webHooksList = (params, options) => {
7772
+ return import_axios4.default.get(`/webhooks`, {
7773
+ ...options,
7774
+ params: { ...params, ...options?.params }
7775
+ });
7776
+ };
7777
+ var webHooksCreate = (webHook, options) => {
7778
+ return import_axios4.default.post(`/webhooks`, webHook, options);
7779
+ };
7780
+ var webHooksDelete = (id, options) => {
7781
+ return import_axios4.default.delete(`/webhooks/${id}`, options);
7782
+ };
7679
7783
 
7680
7784
  // src/adapters/azure-stt-adapter.ts
7681
7785
  var AzureSTTAdapter = class extends BaseAdapter {
@@ -7748,19 +7852,8 @@ var AzureSTTAdapter = class extends BaseAdapter {
7748
7852
  this.getAxiosConfig()
7749
7853
  );
7750
7854
  const transcription = response.data;
7751
- return {
7752
- success: true,
7753
- provider: this.name,
7754
- data: {
7755
- id: transcription.self?.split("/").pop() || "",
7756
- text: "",
7757
- // Will be populated after polling
7758
- status: this.normalizeStatus(transcription.status),
7759
- language: transcription.locale,
7760
- createdAt: transcription.createdDateTime
7761
- },
7762
- raw: transcription
7763
- };
7855
+ const transcriptId = transcription.self?.split("/").pop() || "";
7856
+ return await this.pollForCompletion(transcriptId);
7764
7857
  } catch (error) {
7765
7858
  return this.createErrorResponse(error);
7766
7859
  }
@@ -7918,6 +8011,50 @@ var AzureSTTAdapter = class extends BaseAdapter {
7918
8011
  };
7919
8012
  }
7920
8013
  }
8014
+ /**
8015
+ * Register a subscription-wide webhook for transcription events
8016
+ *
8017
+ * Azure webhooks are subscription-wide (not per-transcription).
8018
+ * Call this once during setup to receive callbacks for all transcription events.
8019
+ * The webhook URL will receive POST requests for transcription lifecycle events.
8020
+ *
8021
+ * @param url - The webhook URL to receive events
8022
+ * @param options - Optional: event filters and display name
8023
+ * @returns Created webhook object
8024
+ */
8025
+ async registerWebhook(url, options) {
8026
+ this.validateConfig();
8027
+ const webhook = {
8028
+ webUrl: url,
8029
+ displayName: options?.displayName || "SDK Webhook",
8030
+ events: options?.events || {
8031
+ transcriptionCreation: true,
8032
+ transcriptionProcessing: true,
8033
+ transcriptionCompletion: true
8034
+ }
8035
+ };
8036
+ const response = await webHooksCreate(webhook, this.getAxiosConfig());
8037
+ return response.data;
8038
+ }
8039
+ /**
8040
+ * Unregister a subscription-wide webhook by ID
8041
+ *
8042
+ * @param webhookId - The webhook ID to delete
8043
+ */
8044
+ async unregisterWebhook(webhookId) {
8045
+ this.validateConfig();
8046
+ await webHooksDelete(webhookId, this.getAxiosConfig());
8047
+ }
8048
+ /**
8049
+ * List all registered webhooks for the subscription
8050
+ *
8051
+ * @returns Array of registered webhooks
8052
+ */
8053
+ async listWebhooks() {
8054
+ this.validateConfig();
8055
+ const response = await webHooksList(void 0, this.getAxiosConfig());
8056
+ return [...response.data.values || []];
8057
+ }
7921
8058
  /**
7922
8059
  * Map unified status to Azure status format using generated enum
7923
8060
  */
@@ -8674,6 +8811,20 @@ function createOpenAIWhisperAdapter(config) {
8674
8811
  // src/adapters/speechmatics-adapter.ts
8675
8812
  var import_axios8 = __toESM(require("axios"));
8676
8813
 
8814
+ // src/generated/speechmatics/schema/notificationConfigContentsItem.ts
8815
+ var NotificationConfigContentsItem = {
8816
+ jobinfo: "jobinfo",
8817
+ transcript: "transcript",
8818
+ "transcriptjson-v2": "transcript.json-v2",
8819
+ transcripttxt: "transcript.txt",
8820
+ transcriptsrt: "transcript.srt",
8821
+ alignment: "alignment",
8822
+ alignmentword_start_and_end: "alignment.word_start_and_end",
8823
+ alignmentone_per_line: "alignment.one_per_line",
8824
+ data: "data",
8825
+ text: "text"
8826
+ };
8827
+
8677
8828
  // src/generated/speechmatics/schema/transcriptionConfigDiarization.ts
8678
8829
  var TranscriptionConfigDiarization = {
8679
8830
  none: "none",
@@ -8830,6 +8981,14 @@ var SpeechmaticsAdapter = class extends BaseAdapter {
8830
8981
  content: word
8831
8982
  }));
8832
8983
  }
8984
+ if (options?.webhookUrl) {
8985
+ jobConfig.notification_config = [
8986
+ {
8987
+ url: options.webhookUrl,
8988
+ contents: [NotificationConfigContentsItem.transcript]
8989
+ }
8990
+ ];
8991
+ }
8833
8992
  let requestBody;
8834
8993
  let headers = {};
8835
8994
  if (audio.type === "url") {
@@ -8855,16 +9014,20 @@ var SpeechmaticsAdapter = class extends BaseAdapter {
8855
9014
  };
8856
9015
  }
8857
9016
  const response = await this.client.post("/jobs", requestBody, { headers });
8858
- return {
8859
- success: true,
8860
- provider: this.name,
8861
- data: {
8862
- id: response.data.id,
8863
- text: "",
8864
- status: "queued"
8865
- },
8866
- raw: response.data
8867
- };
9017
+ const jobId = response.data.id;
9018
+ if (options?.webhookUrl) {
9019
+ return {
9020
+ success: true,
9021
+ provider: this.name,
9022
+ data: {
9023
+ id: jobId,
9024
+ text: "",
9025
+ status: "queued"
9026
+ },
9027
+ raw: response.data
9028
+ };
9029
+ }
9030
+ return await this.pollForCompletion(jobId);
8868
9031
  } catch (error) {
8869
9032
  return this.createErrorResponse(error);
8870
9033
  }
@@ -32165,7 +32328,7 @@ var createRealtimeClientSecretBody = import_zod6.z.object({
32165
32328
  format: import_zod6.z.discriminatedUnion("type", [
32166
32329
  import_zod6.z.object({
32167
32330
  type: import_zod6.z.enum(["audio/pcm"]).describe("The audio format. Always `audio/pcm`."),
32168
- rate: import_zod6.z.literal(24e3).optional().describe("The sample rate of the audio. Always `24000`.")
32331
+ rate: import_zod6.z.literal(24e3).describe("The sample rate of the audio. Always `24000`.")
32169
32332
  }).describe("The PCM audio format. Only a 24kHz sample rate is supported."),
32170
32333
  import_zod6.z.object({
32171
32334
  type: import_zod6.z.enum(["audio/pcmu"]).describe("The audio format. Always `audio/pcmu`.")
@@ -32264,7 +32427,7 @@ var createRealtimeClientSecretBody = import_zod6.z.object({
32264
32427
  format: import_zod6.z.discriminatedUnion("type", [
32265
32428
  import_zod6.z.object({
32266
32429
  type: import_zod6.z.enum(["audio/pcm"]).describe("The audio format. Always `audio/pcm`."),
32267
- rate: import_zod6.z.literal(24e3).optional().describe("The sample rate of the audio. Always `24000`.")
32430
+ rate: import_zod6.z.literal(24e3).describe("The sample rate of the audio. Always `24000`.")
32268
32431
  }).describe("The PCM audio format. Only a 24kHz sample rate is supported."),
32269
32432
  import_zod6.z.object({
32270
32433
  type: import_zod6.z.enum(["audio/pcmu"]).describe("The audio format. Always `audio/pcmu`.")
@@ -32474,7 +32637,7 @@ var createRealtimeClientSecretBody = import_zod6.z.object({
32474
32637
  format: import_zod6.z.discriminatedUnion("type", [
32475
32638
  import_zod6.z.object({
32476
32639
  type: import_zod6.z.enum(["audio/pcm"]).describe("The audio format. Always `audio/pcm`."),
32477
- rate: import_zod6.z.literal(24e3).optional().describe("The sample rate of the audio. Always `24000`.")
32640
+ rate: import_zod6.z.literal(24e3).describe("The sample rate of the audio. Always `24000`.")
32478
32641
  }).describe("The PCM audio format. Only a 24kHz sample rate is supported."),
32479
32642
  import_zod6.z.object({
32480
32643
  type: import_zod6.z.enum(["audio/pcmu"]).describe("The audio format. Always `audio/pcmu`.")
@@ -32644,7 +32807,7 @@ var createRealtimeClientSecretResponse = import_zod6.z.object({
32644
32807
  format: import_zod6.z.discriminatedUnion("type", [
32645
32808
  import_zod6.z.object({
32646
32809
  type: import_zod6.z.enum(["audio/pcm"]).describe("The audio format. Always `audio/pcm`."),
32647
- rate: import_zod6.z.literal(24e3).optional().describe("The sample rate of the audio. Always `24000`.")
32810
+ rate: import_zod6.z.literal(24e3).describe("The sample rate of the audio. Always `24000`.")
32648
32811
  }).describe("The PCM audio format. Only a 24kHz sample rate is supported."),
32649
32812
  import_zod6.z.object({
32650
32813
  type: import_zod6.z.enum(["audio/pcmu"]).describe("The audio format. Always `audio/pcmu`.")
@@ -32743,7 +32906,7 @@ var createRealtimeClientSecretResponse = import_zod6.z.object({
32743
32906
  format: import_zod6.z.discriminatedUnion("type", [
32744
32907
  import_zod6.z.object({
32745
32908
  type: import_zod6.z.enum(["audio/pcm"]).describe("The audio format. Always `audio/pcm`."),
32746
- rate: import_zod6.z.literal(24e3).optional().describe("The sample rate of the audio. Always `24000`.")
32909
+ rate: import_zod6.z.literal(24e3).describe("The sample rate of the audio. Always `24000`.")
32747
32910
  }).describe("The PCM audio format. Only a 24kHz sample rate is supported."),
32748
32911
  import_zod6.z.object({
32749
32912
  type: import_zod6.z.enum(["audio/pcmu"]).describe("The audio format. Always `audio/pcmu`.")
@@ -32962,7 +33125,7 @@ var createRealtimeClientSecretResponse = import_zod6.z.object({
32962
33125
  format: import_zod6.z.discriminatedUnion("type", [
32963
33126
  import_zod6.z.object({
32964
33127
  type: import_zod6.z.enum(["audio/pcm"]).describe("The audio format. Always `audio/pcm`."),
32965
- rate: import_zod6.z.literal(24e3).optional().describe("The sample rate of the audio. Always `24000`.")
33128
+ rate: import_zod6.z.literal(24e3).describe("The sample rate of the audio. Always `24000`.")
32966
33129
  }).describe("The PCM audio format. Only a 24kHz sample rate is supported."),
32967
33130
  import_zod6.z.object({
32968
33131
  type: import_zod6.z.enum(["audio/pcmu"]).describe("The audio format. Always `audio/pcmu`.")
@@ -33191,7 +33354,7 @@ var createRealtimeSessionResponse = import_zod6.z.object({
33191
33354
  format: import_zod6.z.discriminatedUnion("type", [
33192
33355
  import_zod6.z.object({
33193
33356
  type: import_zod6.z.enum(["audio/pcm"]).describe("The audio format. Always `audio/pcm`."),
33194
- rate: import_zod6.z.literal(24e3).optional().describe("The sample rate of the audio. Always `24000`.")
33357
+ rate: import_zod6.z.literal(24e3).describe("The sample rate of the audio. Always `24000`.")
33195
33358
  }).describe("The PCM audio format. Only a 24kHz sample rate is supported."),
33196
33359
  import_zod6.z.object({
33197
33360
  type: import_zod6.z.enum(["audio/pcmu"]).describe("The audio format. Always `audio/pcmu`.")
@@ -33235,7 +33398,7 @@ var createRealtimeSessionResponse = import_zod6.z.object({
33235
33398
  format: import_zod6.z.discriminatedUnion("type", [
33236
33399
  import_zod6.z.object({
33237
33400
  type: import_zod6.z.enum(["audio/pcm"]).describe("The audio format. Always `audio/pcm`."),
33238
- rate: import_zod6.z.literal(24e3).optional().describe("The sample rate of the audio. Always `24000`.")
33401
+ rate: import_zod6.z.literal(24e3).describe("The sample rate of the audio. Always `24000`.")
33239
33402
  }).describe("The PCM audio format. Only a 24kHz sample rate is supported."),
33240
33403
  import_zod6.z.object({
33241
33404
  type: import_zod6.z.enum(["audio/pcmu"]).describe("The audio format. Always `audio/pcmu`.")
@@ -38333,20 +38496,6 @@ var LanguagePackInfoWritingDirection = {
38333
38496
  "right-to-left": "right-to-left"
38334
38497
  };
38335
38498
 
38336
- // src/generated/speechmatics/schema/notificationConfigContentsItem.ts
38337
- var NotificationConfigContentsItem = {
38338
- jobinfo: "jobinfo",
38339
- transcript: "transcript",
38340
- "transcriptjson-v2": "transcript.json-v2",
38341
- transcripttxt: "transcript.txt",
38342
- transcriptsrt: "transcript.srt",
38343
- alignment: "alignment",
38344
- alignmentword_start_and_end: "alignment.word_start_and_end",
38345
- alignmentone_per_line: "alignment.one_per_line",
38346
- data: "data",
38347
- text: "text"
38348
- };
38349
-
38350
38499
  // src/generated/speechmatics/schema/notificationConfigMethod.ts
38351
38500
  var NotificationConfigMethod = {
38352
38501
  post: "post",
@@ -40279,6 +40428,9 @@ var deleteTranscriptByIdResponse = import_zod13.z.any();
40279
40428
  transcriptionsGet,
40280
40429
  transcriptionsList,
40281
40430
  transcriptionsListFiles,
40431
+ webHooksCreate,
40432
+ webHooksDelete,
40433
+ webHooksList,
40282
40434
  zodToFieldConfigs
40283
40435
  });
40284
40436
  //# sourceMappingURL=index.js.map