@myscheme/voice-navigation-sdk 0.1.9 → 0.1.10

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 (48) hide show
  1. package/README.md +130 -17
  2. package/dist/actions.d.ts +1 -0
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +51 -1
  5. package/dist/index.d.ts +38 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +158 -1
  8. package/dist/languages.d.ts +17 -0
  9. package/dist/languages.d.ts.map +1 -0
  10. package/dist/languages.js +86 -0
  11. package/dist/microphone-handler.d.ts +8 -2
  12. package/dist/microphone-handler.d.ts.map +1 -1
  13. package/dist/microphone-handler.js +89 -2
  14. package/dist/navigation-controller.d.ts +2 -0
  15. package/dist/navigation-controller.d.ts.map +1 -1
  16. package/dist/navigation-controller.js +58 -22
  17. package/dist/server/azure-speech-handler.d.ts +3 -2
  18. package/dist/server/azure-speech-handler.d.ts.map +1 -1
  19. package/dist/server/azure-speech-handler.js +26 -2
  20. package/dist/server/bedrock-embedding-handler.d.ts +2 -1
  21. package/dist/server/bedrock-embedding-handler.d.ts.map +1 -1
  22. package/dist/server/bedrock-embedding-handler.js +73 -19
  23. package/dist/server/bedrock-handler.d.ts +2 -1
  24. package/dist/server/bedrock-handler.d.ts.map +1 -1
  25. package/dist/server/bedrock-handler.js +124 -19
  26. package/dist/server/index.d.ts +5 -0
  27. package/dist/server/index.d.ts.map +1 -1
  28. package/dist/server/index.js +3 -0
  29. package/dist/server/opensearch-env-handler.d.ts +2 -1
  30. package/dist/server/opensearch-env-handler.d.ts.map +1 -1
  31. package/dist/server/opensearch-env-handler.js +23 -53
  32. package/dist/server/sarvam-stt-relay.d.ts +8 -0
  33. package/dist/server/sarvam-stt-relay.d.ts.map +1 -0
  34. package/dist/server/sarvam-stt-relay.js +111 -0
  35. package/dist/server/security.d.ts +26 -0
  36. package/dist/server/security.d.ts.map +1 -0
  37. package/dist/server/security.js +89 -0
  38. package/dist/services/bedrock.d.ts.map +1 -1
  39. package/dist/services/bedrock.js +13 -0
  40. package/dist/services/sarvam-speech.d.ts +47 -0
  41. package/dist/services/sarvam-speech.d.ts.map +1 -0
  42. package/dist/services/sarvam-speech.js +418 -0
  43. package/dist/services/voice-feedback.d.ts +7 -2
  44. package/dist/services/voice-feedback.d.ts.map +1 -1
  45. package/dist/services/voice-feedback.js +45 -5
  46. package/dist/types.d.ts +11 -0
  47. package/dist/types.d.ts.map +1 -1
  48. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"microphone-handler.d.ts","sourceRoot":"","sources":["../src/microphone-handler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,GAAG,MAAM,wCAAwC,CAAC;AAC9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,UAAU,gBAAgB;IACxB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,mBAAmB,CAAgB;IAC3C,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,8BAA8B,CAEtB;IAChB,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,uBAAuB,CAAkB;gBAErC,MAAM,EAAE,gBAAgB;IAUpC,uBAAuB,IAAI,OAAO;IAIlC,uBAAuB,IAAI,OAAO;IAO5B,kBAAkB,IAAI,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAoB1D,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBzC,kBAAkB,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAwDzD,2BAA2B,IAAI,OAAO,CAAC,OAAO,CAAC;IA2BrD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAYnC,wBAAwB,IAAI,IAAI;IAO1B,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBnC,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBzC,iBAAiB,IAAI,IAAI;IAUzB,iBAAiB,IAAI,MAAM;IAO3B,oBAAoB,CAAC,SAAS,GAAE,mBAAwB,GAAG,IAAI;IAiB/D,sBAAsB,IAAI,IAAI;IAmB9B,OAAO,CAAC,sBAAsB;IA4B9B,OAAO,CAAC,gBAAgB;IAyBxB,OAAO,CAAC,eAAe;YAUT,4BAA4B;IAoCpC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiBpE,iBAAiB,IAAI,IAAI;IAqCnB,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAmBjD,cAAc,CAAC,SAAS,GAAE,mBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;IA6JrE,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;WA6CzB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;CAYvD"}
1
+ {"version":3,"file":"microphone-handler.d.ts","sourceRoot":"","sources":["../src/microphone-handler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,GAAG,MAAM,wCAAwC,CAAC;AAC9D,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,UAAU,gBAAgB;IACxB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,mBAAmB,CAA6B;IACxD,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,mBAAmB,CAAgB;IAC3C,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,8BAA8B,CAEtB;IAChB,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,uBAAuB,CAAkB;gBAErC,MAAM,EAAE,gBAAgB;IAqBpC,uBAAuB,IAAI,OAAO;IAIlC,uBAAuB,IAAI,OAAO;IAO5B,kBAAkB,IAAI,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAoB1D,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBzC,kBAAkB,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAwDzD,2BAA2B,IAAI,OAAO,CAAC,OAAO,CAAC;IA2BrD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAYnC,wBAAwB,IAAI,IAAI;IAO1B,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAoBnC,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBzC,iBAAiB,IAAI,IAAI;IAUzB,iBAAiB,IAAI,MAAM;IAO3B,oBAAoB,CAAC,SAAS,GAAE,mBAAwB,GAAG,IAAI;IAiB/D,sBAAsB,IAAI,IAAI;IAmB9B,OAAO,CAAC,sBAAsB;IA4B9B,OAAO,CAAC,gBAAgB;IAyBxB,OAAO,CAAC,eAAe;YAUT,4BAA4B;IAwCpC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiBpE,iBAAiB,IAAI,IAAI;IAiDnB,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAmBjD,cAAc,CAAC,SAAS,GAAE,mBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;YA8J7D,oBAAoB;IAqD5B,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;WAgEzB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;CAYvD"}
@@ -15,7 +15,15 @@ export class MicrophoneHandler {
15
15
  this.recognitionHealthCheckInterval = null;
16
16
  this.isRecovering = false;
17
17
  this.isStoppingIntentionally = false;
18
- this.azureSpeechService = config.azureSpeechService;
18
+ this.speechProvider = config.speechProvider ?? "sarvam";
19
+ this.azureSpeechService = config.azureSpeechService ?? null;
20
+ this.sarvamSpeechService = config.sarvamSpeechService ?? null;
21
+ if (this.speechProvider === "azure" && !this.azureSpeechService) {
22
+ throw new Error("Azure speech service is required for azure provider");
23
+ }
24
+ if (this.speechProvider === "sarvam" && !this.sarvamSpeechService) {
25
+ throw new Error("Sarvam speech service is required for sarvam provider");
26
+ }
19
27
  this.bedrockService = config.bedrockService;
20
28
  this.language = config.language || "en-IN";
21
29
  this.silenceTimeout = config.silenceTimeout || 2000;
@@ -127,6 +135,9 @@ export class MicrophoneHandler {
127
135
  this.transcriptionBuffer = [];
128
136
  }
129
137
  async fetchAzureToken() {
138
+ if (!this.azureSpeechService) {
139
+ throw new Error("Azure speech service is not configured");
140
+ }
130
141
  try {
131
142
  const response = await this.azureSpeechService.fetchToken();
132
143
  this.token = response.token;
@@ -174,7 +185,7 @@ export class MicrophoneHandler {
174
185
  console.warn("[MicrophoneHandler] Cannot reschedule - not recording");
175
186
  return;
176
187
  }
177
- if (!this.recognizer) {
188
+ if (this.speechProvider === "azure" && !this.recognizer) {
178
189
  console.error("[MicrophoneHandler] Cannot reschedule - no recognizer");
179
190
  return;
180
191
  }
@@ -220,6 +231,9 @@ export class MicrophoneHandler {
220
231
  }
221
232
  this.isRecovering = true;
222
233
  console.log("[MicrophoneHandler] Attempting to recover from stalled recognizer");
234
+ if (this.speechProvider === "sarvam" && this.sarvamSpeechService) {
235
+ await this.sarvamSpeechService.stopListening();
236
+ }
223
237
  this.disposeRecognizer();
224
238
  this.isRecording = false;
225
239
  await new Promise((resolve) => setTimeout(resolve, 500));
@@ -254,6 +268,14 @@ export class MicrophoneHandler {
254
268
  }
255
269
  disposeRecognizer() {
256
270
  this.stopHealthCheck();
271
+ if (this.speechProvider === "sarvam") {
272
+ if (this.sarvamSpeechService) {
273
+ void this.sarvamSpeechService.stopListening().catch((error) => {
274
+ console.error("[MicrophoneHandler] Error stopping Sarvam STT:", error);
275
+ });
276
+ }
277
+ return;
278
+ }
257
279
  if (this.recognizer) {
258
280
  try {
259
281
  this.recognizer.stopContinuousRecognitionAsync(() => {
@@ -308,6 +330,9 @@ export class MicrophoneHandler {
308
330
  return false;
309
331
  }
310
332
  }
333
+ if (this.speechProvider === "sarvam") {
334
+ return this.startSarvamRecording(callbacks);
335
+ }
311
336
  const sdkReady = await this.ensureSpeechSdk();
312
337
  if (!sdkReady) {
313
338
  if (callbacks.onError) {
@@ -398,10 +423,72 @@ export class MicrophoneHandler {
398
423
  });
399
424
  return true;
400
425
  }
426
+ async startSarvamRecording(callbacks) {
427
+ if (!this.sarvamSpeechService) {
428
+ callbacks.onError?.(new Error("Sarvam speech service not configured"));
429
+ return false;
430
+ }
431
+ this.resetTranscriptionBuffer();
432
+ try {
433
+ await this.sarvamSpeechService.startListening(this.language, {
434
+ shouldSendAudio: () => this.isRecording,
435
+ onPartial: (text) => {
436
+ this.lastRecognitionTime = Date.now();
437
+ this.activeCallbacks.onPartial?.(text);
438
+ },
439
+ onFinal: (text) => {
440
+ this.lastRecognitionTime = Date.now();
441
+ this.transcriptionBuffer.push(text);
442
+ this.activeCallbacks.onSegment?.(text, {});
443
+ this.scheduleSilenceCheck(this.activeCallbacks);
444
+ },
445
+ onSpeechStart: () => {
446
+ this.lastRecognitionTime = Date.now();
447
+ },
448
+ onSpeechEnd: () => {
449
+ this.lastRecognitionTime = Date.now();
450
+ this.scheduleSilenceCheck(this.activeCallbacks);
451
+ },
452
+ onError: (error) => {
453
+ this.isRecording = false;
454
+ this.stopHealthCheck();
455
+ this.activeCallbacks.onError?.(error);
456
+ },
457
+ });
458
+ this.isRecording = true;
459
+ this.audioContextUnlocked = true;
460
+ this.lastRecognitionTime = Date.now();
461
+ this.startHealthCheck();
462
+ this.scheduleSilenceCheck(this.activeCallbacks);
463
+ return true;
464
+ }
465
+ catch (error) {
466
+ this.isRecording = false;
467
+ callbacks.onError?.(error);
468
+ return false;
469
+ }
470
+ }
401
471
  async stopRecording() {
402
472
  this.clearSilenceTimer();
403
473
  this.stopHealthCheck();
404
474
  this.isStoppingIntentionally = true;
475
+ if (this.speechProvider === "sarvam") {
476
+ if (!this.isRecording || !this.sarvamSpeechService) {
477
+ console.warn("[MicrophoneHandler] Not currently recording");
478
+ this.isStoppingIntentionally = false;
479
+ return this.getAggregatedText();
480
+ }
481
+ try {
482
+ await this.sarvamSpeechService.stopListening();
483
+ }
484
+ catch (error) {
485
+ console.error("[MicrophoneHandler] Error stopping Sarvam STT:", error);
486
+ }
487
+ this.isRecording = false;
488
+ this.isStoppingIntentionally = false;
489
+ const finalText = this.getAggregatedText();
490
+ return finalText;
491
+ }
405
492
  if (!this.isRecording || !this.recognizer) {
406
493
  console.warn("[MicrophoneHandler] Not currently recording");
407
494
  this.isStoppingIntentionally = false;
@@ -1,8 +1,10 @@
1
1
  import type { NavigationConfig } from "./types.js";
2
2
  export declare class VoiceNavigationController {
3
3
  private config;
4
+ private speechProvider;
4
5
  private microphoneHandler;
5
6
  private azureSpeechService;
7
+ private sarvamSpeechService;
6
8
  private bedrockService;
7
9
  private voiceFeedbackService;
8
10
  private pageRegistry;
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-controller.d.ts","sourceRoot":"","sources":["../src/navigation-controller.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAMjB,MAAM,YAAY,CAAC;AA4DpB,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,qBAAqB,CAAkB;IAC/C,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,+BAA+B,CAAkB;IACzD,OAAO,CAAC,wBAAwB,CAA6B;IAC7D,OAAO,CAAC,mBAAmB,CAAoC;IAC/D,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,wBAAwB,CAA6B;gBAEjD,MAAM,EAAE,gBAAgB;YA0JtB,iBAAiB;IAiD/B,OAAO,CAAC,eAAe;IAoBhB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAepC,oBAAoB,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;YAOtD,eAAe;IAmE7B,OAAO,CAAC,kBAAkB;YASZ,eAAe;IA8BhB,KAAK,CAChB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAO,GACzC,OAAO,CAAC,IAAI,CAAC;IAuFH,IAAI,CACf,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,OAAO,CAAC,IAAI,CAAC;IAqEhB,OAAO,CAAC,mBAAmB;IAoD3B,OAAO,CAAC,qBAAqB;IA4C7B,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;YAWP,aAAa;YAOb,wBAAwB;IA2CtC,OAAO,CAAC,WAAW;YAuBL,iBAAiB;YAwBjB,iBAAiB;IA6RxB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQnC,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOxC,sBAAsB,IAAI,OAAO;YAO1B,qBAAqB;YAgFrB,yBAAyB;IAmMvC,OAAO,CAAC,oBAAoB;IAqD5B,OAAO,CAAC,yBAAyB;IAoCjC,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,4BAA4B;IAiB7B,OAAO,IAAI,IAAI;IAgBtB,OAAO,CAAC,kBAAkB;IA8B1B,OAAO,CAAC,kBAAkB;IAwD1B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,uBAAuB;IAqD/B,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,wBAAwB;CAmBjC"}
1
+ {"version":3,"file":"navigation-controller.d.ts","sourceRoot":"","sources":["../src/navigation-controller.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAOjB,MAAM,YAAY,CAAC;AA8DpB,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,mBAAmB,CAA6B;IACxD,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,qBAAqB,CAAkB;IAC/C,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,+BAA+B,CAAkB;IACzD,OAAO,CAAC,wBAAwB,CAA6B;IAC7D,OAAO,CAAC,mBAAmB,CAAoC;IAC/D,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,wBAAwB,CAA6B;gBAEjD,MAAM,EAAE,gBAAgB;YAgMtB,iBAAiB;IAoD/B,OAAO,CAAC,eAAe;IAoBhB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAepC,oBAAoB,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;YAOtD,eAAe;IAmE7B,OAAO,CAAC,kBAAkB;YASZ,eAAe;IA8BhB,KAAK,CAChB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAO,GACzC,OAAO,CAAC,IAAI,CAAC;IAuFH,IAAI,CACf,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,OAAO,CAAC,IAAI,CAAC;IAqEhB,OAAO,CAAC,mBAAmB;IAoD3B,OAAO,CAAC,qBAAqB;IA4C7B,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;YAWP,aAAa;YAOb,wBAAwB;IA2CtC,OAAO,CAAC,WAAW;YAuBL,iBAAiB;YAwBjB,iBAAiB;IA6RxB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IASnC,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOxC,sBAAsB,IAAI,OAAO;YAO1B,qBAAqB;YAgFrB,yBAAyB;IAmMvC,OAAO,CAAC,oBAAoB;IAqD5B,OAAO,CAAC,yBAAyB;IAoCjC,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,4BAA4B;IAiB7B,OAAO,IAAI,IAAI;IAgBtB,OAAO,CAAC,kBAAkB;IA8B1B,OAAO,CAAC,kBAAkB;IAwD1B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,uBAAuB;IAqD/B,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,wBAAwB;CAmBjC"}
@@ -1,9 +1,11 @@
1
1
  import { MicrophoneHandler } from "./microphone-handler.js";
2
2
  import { AzureSpeechService } from "./services/azure-speech.js";
3
3
  import { BedrockService } from "./services/bedrock.js";
4
+ import { SarvamSpeechService } from "./services/sarvam-speech.js";
4
5
  import { PageRegistry } from "./services/page-registry.js";
5
6
  import { VoiceFeedbackService } from "./services/voice-feedback.js";
6
7
  import { loadNavigationPages } from "./services/xml-parser.js";
8
+ import { normalizeLanguageCode } from "./languages.js";
7
9
  import { VectorSearchService, } from "./services/vector-search.js";
8
10
  import { performAgentAction, formatActionLabel, extractAgentAction, setPageRegistry, } from "./actions.js";
9
11
  import { createFloatingControl, attachToCustomButton, setState, updateStatus, updateTranscript, updateActionIndicator, showError, emitEvent, } from "./ui.js";
@@ -45,17 +47,28 @@ export class VoiceNavigationController {
45
47
  this.config = {
46
48
  ...config,
47
49
  opensearch: openSearchConfig,
50
+ speechProvider: config.speechProvider ?? "sarvam",
48
51
  };
52
+ this.speechProvider = this.config.speechProvider ?? "sarvam";
49
53
  console.log("[Voice Navigation Controller] Constructor called with UI config:", this.config.ui);
50
- const hasAzureEndpoint = !!this.config.azure?.tokenEndpoint;
51
- const hasAzureCredentials = !!(this.config.azure?.subscriptionKey && this.config.azure?.region);
52
- if (!this.config.azure) {
53
- this.config.azure = { tokenEndpoint: "/api/speech/token" };
54
- console.log("[VoiceNavigation] Auto-configured Azure endpoint: /api/speech/token");
54
+ if (this.speechProvider === "azure") {
55
+ const hasAzureEndpoint = !!this.config.azure?.tokenEndpoint;
56
+ const hasAzureCredentials = !!(this.config.azure?.subscriptionKey && this.config.azure?.region);
57
+ if (!this.config.azure) {
58
+ this.config.azure = { tokenEndpoint: "/api/speech/token" };
59
+ console.log("[VoiceNavigation] Auto-configured Azure endpoint: /api/speech/token");
60
+ }
61
+ else if (!hasAzureEndpoint && !hasAzureCredentials) {
62
+ this.config.azure.tokenEndpoint = "/api/speech/token";
63
+ console.log("[VoiceNavigation] Auto-configured Azure endpoint: /api/speech/token");
64
+ }
55
65
  }
56
- else if (!hasAzureEndpoint && !hasAzureCredentials) {
57
- this.config.azure.tokenEndpoint = "/api/speech/token";
58
- console.log("[VoiceNavigation] Auto-configured Azure endpoint: /api/speech/token");
66
+ if (this.speechProvider === "sarvam") {
67
+ this.config.sarvam = {
68
+ ...(this.config.sarvam ?? {}),
69
+ ttsUrl: this.config.sarvam?.ttsUrl ?? "/api/speech/sarvam",
70
+ sttUrl: this.config.sarvam?.sttUrl ?? "/api/speech/sarvam-stt",
71
+ };
59
72
  }
60
73
  const hasAwsEndpoint = !!this.config.aws?.bedrockEndpoint;
61
74
  const hasAwsCredentials = !!(this.config.aws?.accessKeyId &&
@@ -80,11 +93,29 @@ export class VoiceNavigationController {
80
93
  openSearchConfig.suggestEndpoint = "/api/opensearch/suggest";
81
94
  console.log("[VoiceNavigation] Auto-configured OpenSearch endpoints: /api/opensearch/search, /api/opensearch/suggest");
82
95
  }
83
- this.azureSpeechService = new AzureSpeechService({
84
- tokenEndpoint: this.config.azure.tokenEndpoint,
85
- subscriptionKey: this.config.azure.subscriptionKey,
86
- region: this.config.azure.region,
87
- });
96
+ this.azureSpeechService = null;
97
+ this.sarvamSpeechService = null;
98
+ if (this.speechProvider === "azure") {
99
+ if (!this.config.azure) {
100
+ throw new Error("Azure configuration is required for azure provider");
101
+ }
102
+ this.azureSpeechService = new AzureSpeechService({
103
+ tokenEndpoint: this.config.azure.tokenEndpoint,
104
+ subscriptionKey: this.config.azure.subscriptionKey,
105
+ region: this.config.azure.region,
106
+ });
107
+ }
108
+ else {
109
+ this.sarvamSpeechService = new SarvamSpeechService({
110
+ ttsUrl: this.config.sarvam?.ttsUrl,
111
+ sttUrl: this.config.sarvam?.sttUrl,
112
+ sttModel: this.config.sarvam?.sttModel,
113
+ ttsModel: this.config.sarvam?.ttsModel,
114
+ speaker: this.config.sarvam?.speaker,
115
+ sttSampleRate: this.config.sarvam?.sttSampleRate,
116
+ ttsSampleRate: this.config.sarvam?.ttsSampleRate,
117
+ });
118
+ }
88
119
  this.bedrockService = new BedrockService({
89
120
  bedrockEndpoint: this.config.aws.bedrockEndpoint,
90
121
  embeddingEndpoint: this.config.aws.embeddingEndpoint,
@@ -99,16 +130,20 @@ export class VoiceNavigationController {
99
130
  this.pageRegistry = new PageRegistry([]);
100
131
  this.pagesInitialized = this.initializePages();
101
132
  this.microphoneHandler = new MicrophoneHandler({
102
- azureSpeechService: this.azureSpeechService,
133
+ speechProvider: this.speechProvider,
134
+ azureSpeechService: this.azureSpeechService ?? undefined,
135
+ sarvamSpeechService: this.sarvamSpeechService ?? undefined,
103
136
  bedrockService: this.bedrockService,
104
- language: this.config.language || "en-IN",
137
+ language: normalizeLanguageCode(this.config.language),
105
138
  });
106
139
  const voiceFeedbackEnabled = this.config.voiceFeedback?.enabled !== false;
107
140
  console.log("[VoiceNavigation] Initializing voice feedback service - enabled:", voiceFeedbackEnabled);
108
141
  this.voiceFeedbackService = new VoiceFeedbackService({
109
142
  enabled: voiceFeedbackEnabled,
110
- language: this.config.language || "en-IN",
111
- azureSpeechService: this.azureSpeechService,
143
+ language: normalizeLanguageCode(this.config.language),
144
+ speechProvider: this.speechProvider,
145
+ azureSpeechService: this.azureSpeechService ?? undefined,
146
+ sarvamSpeechService: this.sarvamSpeechService ?? undefined,
112
147
  bedrockService: this.bedrockService,
113
148
  });
114
149
  console.log("[VoiceNavigation] Voice feedback service initialized successfully");
@@ -143,7 +178,7 @@ export class VoiceNavigationController {
143
178
  customButtonSelector,
144
179
  buttonPlacement,
145
180
  });
146
- if (!showDefaultButton && customButtonSelector) {
181
+ if (customButtonSelector) {
147
182
  console.log(`[Voice Navigation] Attempting to use custom button: ${customButtonSelector}`);
148
183
  try {
149
184
  this.ui = await attachToCustomButton(customButtonSelector);
@@ -151,11 +186,11 @@ export class VoiceNavigationController {
151
186
  }
152
187
  catch (error) {
153
188
  console.error("Failed to attach to custom button:", error);
154
- console.warn("Falling back to default button due to custom button error");
189
+ console.warn("Falling back to default button - custom button selector was not found in the DOM");
155
190
  this.ui = createFloatingControl(buttonPlacement);
156
191
  }
157
192
  }
158
- else if (!showDefaultButton && !customButtonSelector) {
193
+ else if (!showDefaultButton) {
159
194
  console.warn("showDefaultButton is false but no customButtonSelector provided. Creating default button.");
160
195
  this.ui = createFloatingControl(buttonPlacement);
161
196
  }
@@ -719,8 +754,9 @@ export class VoiceNavigationController {
719
754
  });
720
755
  }
721
756
  setLanguage(language) {
722
- this.microphoneHandler.setLanguage(language);
723
- this.voiceFeedbackService.setLanguage(language);
757
+ const normalized = normalizeLanguageCode(language);
758
+ this.microphoneHandler.setLanguage(normalized);
759
+ this.voiceFeedbackService.setLanguage(normalized);
724
760
  }
725
761
  setVoiceFeedback(enabled) {
726
762
  this.voiceFeedbackService.setEnabled(enabled);
@@ -1,4 +1,5 @@
1
- type NextApiRequest = {
1
+ import { type GateRequestLike } from "./security.js";
2
+ type NextApiRequest = GateRequestLike & {
2
3
  method?: string;
3
4
  body?: unknown;
4
5
  };
@@ -8,6 +9,6 @@ type NextApiResponse = {
8
9
  setHeader: (name: string, value: string | string[]) => void;
9
10
  };
10
11
  export declare function azureSpeechTokenHandler(req: NextApiRequest, res: NextApiResponse): Promise<void>;
11
- export declare function POST(_request: Request): Promise<Response>;
12
+ export declare function POST(request: Request): Promise<Response>;
12
13
  export {};
13
14
  //# sourceMappingURL=azure-speech-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"azure-speech-handler.d.ts","sourceRoot":"","sources":["../../src/server/azure-speech-handler.ts"],"names":[],"mappings":"AAwBA,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7D,CAAC;AA6EF,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAMD,wBAAsB,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmB/D"}
1
+ {"version":3,"file":"azure-speech-handler.d.ts","sourceRoot":"","sources":["../../src/server/azure-speech-handler.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAGnE,KAAK,cAAc,GAAG,eAAe,GAAG;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7D,CAAC;AA6EF,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC,CAgCf;AAMD,wBAAsB,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqC9D"}
@@ -1,3 +1,4 @@
1
+ import { evaluateGate } from "./security.js";
1
2
  async function getAzureSpeechToken() {
2
3
  const key = process.env.AZURE_SPEECH_KEY;
3
4
  const region = process.env.AZURE_SPEECH_REGION;
@@ -49,6 +50,12 @@ export async function azureSpeechTokenHandler(req, res) {
49
50
  res.status(405).json({ error: "Method not allowed" });
50
51
  return;
51
52
  }
53
+ const gate = evaluateGate(req, { maxRequests: 20, windowMs: 60 * 1000, bucket: "aztoken" });
54
+ if (!gate.ok) {
55
+ res.setHeader("Cache-Control", "no-store, no-cache, max-age=0, must-revalidate");
56
+ res.status(gate.status ?? 403).json({ error: gate.error });
57
+ return;
58
+ }
52
59
  const result = await getAzureSpeechToken();
53
60
  res.setHeader("Cache-Control", "no-store, no-cache, max-age=0, must-revalidate");
54
61
  if (result.success && result.data) {
@@ -58,12 +65,29 @@ export async function azureSpeechTokenHandler(req, res) {
58
65
  res.status(result.statusCode).json(result.error);
59
66
  }
60
67
  }
61
- export async function POST(_request) {
62
- const result = await getAzureSpeechToken();
68
+ export async function POST(request) {
63
69
  const headers = {
64
70
  "Content-Type": "application/json",
65
71
  "Cache-Control": "no-store, no-cache, max-age=0, must-revalidate",
66
72
  };
73
+ const gateReq = {
74
+ method: request.method,
75
+ headers: {
76
+ origin: request.headers.get("origin") ?? undefined,
77
+ referer: request.headers.get("referer") ?? undefined,
78
+ host: request.headers.get("host") ?? undefined,
79
+ "x-forwarded-for": request.headers.get("x-forwarded-for") ?? undefined,
80
+ "x-real-ip": request.headers.get("x-real-ip") ?? undefined,
81
+ },
82
+ };
83
+ const gate = evaluateGate(gateReq, { maxRequests: 20, windowMs: 60 * 1000, bucket: "aztoken" });
84
+ if (!gate.ok) {
85
+ return new Response(JSON.stringify({ error: gate.error }), {
86
+ status: gate.status ?? 403,
87
+ headers,
88
+ });
89
+ }
90
+ const result = await getAzureSpeechToken();
67
91
  if (result.success && result.data) {
68
92
  return new Response(JSON.stringify(result.data), {
69
93
  status: result.statusCode,
@@ -1,4 +1,5 @@
1
- type NextApiRequest = {
1
+ import { type GateRequestLike } from "./security.js";
2
+ type NextApiRequest = GateRequestLike & {
2
3
  method?: string;
3
4
  body?: {
4
5
  text?: string | string[];
@@ -1 +1 @@
1
- {"version":3,"file":"bedrock-embedding-handler.d.ts","sourceRoot":"","sources":["../../src/server/bedrock-embedding-handler.ts"],"names":[],"mappings":"AA4BA,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7D,CAAC;AA0MF,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAMD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,CAAC,CAkCnB"}
1
+ {"version":3,"file":"bedrock-embedding-handler.d.ts","sourceRoot":"","sources":["../../src/server/bedrock-embedding-handler.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEnE,KAAK,cAAc,GAAG,eAAe,GAAG;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7D,CAAC;AA0OF,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAMD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,CAAC,CAsDnB"}
@@ -1,4 +1,29 @@
1
1
  import crypto from "crypto";
2
+ import { evaluateGate } from "./security.js";
3
+ const MAX_EMBEDDING_TEXTS = 16;
4
+ const MAX_EMBEDDING_TEXT_CHARS = 2000;
5
+ const ALLOWED_INPUT_TYPES = new Set([
6
+ "search_query",
7
+ "search_document",
8
+ "classification",
9
+ "clustering",
10
+ ]);
11
+ function sanitizeEmbeddingInput(text, inputType) {
12
+ const rawTexts = Array.isArray(text) ? text : text != null ? [text] : [];
13
+ const texts = [];
14
+ for (const entry of rawTexts.slice(0, MAX_EMBEDDING_TEXTS)) {
15
+ if (typeof entry === "string" && entry.trim().length > 0) {
16
+ texts.push(entry.slice(0, MAX_EMBEDDING_TEXT_CHARS));
17
+ }
18
+ }
19
+ if (texts.length === 0) {
20
+ return { ok: false };
21
+ }
22
+ const resolvedType = typeof inputType === "string" && ALLOWED_INPUT_TYPES.has(inputType)
23
+ ? inputType
24
+ : "search_query";
25
+ return { ok: true, texts, inputType: resolvedType };
26
+ }
2
27
  function sign(key, msg) {
3
28
  return crypto.createHmac("sha256", key).update(msg, "utf8").digest();
4
29
  }
@@ -141,43 +166,72 @@ export async function bedrockEmbeddingHandler(req, res) {
141
166
  res.status(405).json({ error: "Method not allowed" });
142
167
  return;
143
168
  }
144
- const { text, inputType = "search_query" } = req.body || {};
145
- const result = await generateBedrockEmbedding(text, inputType);
169
+ const gate = evaluateGate(req, { maxRequests: 30, windowMs: 60 * 1000, bucket: "embed" });
170
+ if (!gate.ok) {
171
+ res.status(gate.status ?? 403).json({ error: gate.error });
172
+ return;
173
+ }
174
+ const { text, inputType } = req.body || {};
175
+ const sanitized = sanitizeEmbeddingInput(text, inputType);
176
+ if (!sanitized.ok) {
177
+ res.status(400).json({ error: "Invalid text parameter" });
178
+ return;
179
+ }
180
+ const result = await generateBedrockEmbedding(sanitized.texts, sanitized.inputType);
146
181
  if (result.success && result.data) {
147
182
  res.status(result.statusCode).json(result.data);
148
183
  }
149
184
  else {
150
- res.status(result.statusCode).json(result.error);
185
+ res
186
+ .status(result.statusCode >= 500 ? 502 : result.statusCode)
187
+ .json({ error: "Embedding request failed" });
151
188
  }
152
189
  }
153
190
  export async function BedrockEmbeddingPOST(request) {
191
+ const headers = { "Content-Type": "application/json" };
192
+ const gateReq = {
193
+ method: request.method,
194
+ headers: {
195
+ origin: request.headers.get("origin") ?? undefined,
196
+ referer: request.headers.get("referer") ?? undefined,
197
+ host: request.headers.get("host") ?? undefined,
198
+ "x-forwarded-for": request.headers.get("x-forwarded-for") ?? undefined,
199
+ "x-real-ip": request.headers.get("x-real-ip") ?? undefined,
200
+ },
201
+ };
202
+ const gate = evaluateGate(gateReq, { maxRequests: 30, windowMs: 60 * 1000, bucket: "embed" });
203
+ if (!gate.ok) {
204
+ return new Response(JSON.stringify({ error: gate.error }), {
205
+ status: gate.status ?? 403,
206
+ headers,
207
+ });
208
+ }
154
209
  try {
155
210
  const body = await request.json();
156
- const { text, inputType = "search_query" } = body || {};
157
- const result = await generateBedrockEmbedding(text, inputType);
158
- const headers = {
159
- "Content-Type": "application/json",
160
- };
161
- if (result.success && result.data) {
162
- return new Response(JSON.stringify(result.data), {
163
- status: result.statusCode,
211
+ const { text, inputType } = body || {};
212
+ const sanitized = sanitizeEmbeddingInput(text, inputType);
213
+ if (!sanitized.ok) {
214
+ return new Response(JSON.stringify({ error: "Invalid text parameter" }), {
215
+ status: 400,
164
216
  headers,
165
217
  });
166
218
  }
167
- else {
168
- return new Response(JSON.stringify(result.error), {
219
+ const result = await generateBedrockEmbedding(sanitized.texts, sanitized.inputType);
220
+ if (result.success && result.data) {
221
+ return new Response(JSON.stringify(result.data), {
169
222
  status: result.statusCode,
170
223
  headers,
171
224
  });
172
225
  }
226
+ return new Response(JSON.stringify({ error: "Embedding request failed" }), {
227
+ status: result.statusCode >= 500 ? 502 : result.statusCode,
228
+ headers,
229
+ });
173
230
  }
174
- catch (error) {
175
- return new Response(JSON.stringify({
176
- error: "Invalid request",
177
- message: error instanceof Error ? error.message : "Unknown error",
178
- }), {
231
+ catch {
232
+ return new Response(JSON.stringify({ error: "Invalid request" }), {
179
233
  status: 400,
180
- headers: { "Content-Type": "application/json" },
234
+ headers,
181
235
  });
182
236
  }
183
237
  }
@@ -1,4 +1,5 @@
1
- type NextApiRequest = {
1
+ import { type GateRequestLike } from "./security.js";
2
+ type NextApiRequest = GateRequestLike & {
2
3
  method?: string;
3
4
  body?: {
4
5
  body?: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"bedrock-handler.d.ts","sourceRoot":"","sources":["../../src/server/bedrock-handler.ts"],"names":[],"mappings":"AA4BA,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACH,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7D,CAAC;AAqLF,wBAAsB,cAAc,CAClC,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC,CAkBf;AAMD,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkCrE"}
1
+ {"version":3,"file":"bedrock-handler.d.ts","sourceRoot":"","sources":["../../src/server/bedrock-handler.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEnE,KAAK,cAAc,GAAG,eAAe,GAAG;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACH,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7D,CAAC;AAyRF,wBAAsB,cAAc,CAClC,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAMD,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmDrE"}