@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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sarvam-speech.d.ts","sourceRoot":"","sources":["../../src/services/sarvam-speech.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC;IACxC,QAAQ,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC;IAC7B,aAAa,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;CACtE;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC;CACjC;AAmHD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAQhB;IAEd,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,aAAa,CAA2C;IAChE,OAAO,CAAC,gBAAgB,CAAoC;IAE5D,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,mBAAmB,CAAa;gBAE5B,MAAM,GAAE,kBAAuB;IAUrC,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC;IA+KhB,OAAO,CAAC,SAAS;IAWX,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAiE9B,KAAK,CACT,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,GACtD,OAAO,CAAC,IAAI,CAAC;IAqGhB,YAAY,IAAI,IAAI;IAuBd,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,OAAO,CAAC,mBAAmB;CAc5B"}
@@ -0,0 +1,418 @@
1
+ const DEFAULT_TTS_URL = "/api/speech/sarvam";
2
+ const DEFAULT_STT_URL = "/api/speech/sarvam-stt";
3
+ const DEFAULT_STT_MODEL = "saaras:v3";
4
+ const DEFAULT_TTS_MODEL = "bulbul:v3";
5
+ const DEFAULT_SPEAKER = "manan";
6
+ const DEFAULT_STT_SAMPLE_RATE = 16000;
7
+ function toBase64(bytes) {
8
+ let binary = "";
9
+ const chunkSize = 0x8000;
10
+ for (let i = 0; i < bytes.length; i += chunkSize) {
11
+ binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
12
+ }
13
+ return btoa(binary);
14
+ }
15
+ function downsampleTo16BitMono(input, inputRate, outputRate) {
16
+ if (outputRate === inputRate) {
17
+ const pcm = new Int16Array(input.length);
18
+ for (let i = 0; i < input.length; i++) {
19
+ const clamped = Math.max(-1, Math.min(1, input[i]));
20
+ pcm[i] = clamped < 0 ? clamped * 0x8000 : clamped * 0x7fff;
21
+ }
22
+ return pcm;
23
+ }
24
+ const ratio = inputRate / outputRate;
25
+ const outputLength = Math.max(1, Math.floor(input.length / ratio));
26
+ const pcm = new Int16Array(outputLength);
27
+ let outputIndex = 0;
28
+ let inputIndex = 0;
29
+ while (outputIndex < outputLength) {
30
+ const nextInputIndex = Math.floor((outputIndex + 1) * ratio);
31
+ let accum = 0;
32
+ let count = 0;
33
+ for (let i = inputIndex; i < nextInputIndex && i < input.length; i++) {
34
+ accum += input[i];
35
+ count++;
36
+ }
37
+ const sample = count > 0 ? accum / count : 0;
38
+ const clamped = Math.max(-1, Math.min(1, sample));
39
+ pcm[outputIndex] = clamped < 0 ? clamped * 0x8000 : clamped * 0x7fff;
40
+ outputIndex++;
41
+ inputIndex = nextInputIndex;
42
+ }
43
+ return pcm;
44
+ }
45
+ function encodeWav(pcm, sampleRate) {
46
+ const bytesPerSample = 2;
47
+ const numChannels = 1;
48
+ const dataSize = pcm.length * bytesPerSample;
49
+ const buffer = new ArrayBuffer(44 + dataSize);
50
+ const view = new DataView(buffer);
51
+ const writeString = (offset, value) => {
52
+ for (let i = 0; i < value.length; i++) {
53
+ view.setUint8(offset + i, value.charCodeAt(i));
54
+ }
55
+ };
56
+ writeString(0, "RIFF");
57
+ view.setUint32(4, 36 + dataSize, true);
58
+ writeString(8, "WAVE");
59
+ writeString(12, "fmt ");
60
+ view.setUint32(16, 16, true);
61
+ view.setUint16(20, 1, true);
62
+ view.setUint16(22, numChannels, true);
63
+ view.setUint32(24, sampleRate, true);
64
+ view.setUint32(28, sampleRate * numChannels * bytesPerSample, true);
65
+ view.setUint16(32, numChannels * bytesPerSample, true);
66
+ view.setUint16(34, 16, true);
67
+ writeString(36, "data");
68
+ view.setUint32(40, dataSize, true);
69
+ let offset = 44;
70
+ for (let i = 0; i < pcm.length; i++) {
71
+ view.setInt16(offset, pcm[i], true);
72
+ offset += 2;
73
+ }
74
+ return new Uint8Array(buffer);
75
+ }
76
+ function resolveWsUrl(path) {
77
+ if (/^wss?:\/\//i.test(path)) {
78
+ return path;
79
+ }
80
+ if (typeof window === "undefined") {
81
+ return path;
82
+ }
83
+ const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
84
+ return `${protocol}//${window.location.host}${path}`;
85
+ }
86
+ export class SarvamSpeechService {
87
+ constructor(config = {}) {
88
+ this.sttSocket = null;
89
+ this.sttContext = null;
90
+ this.sttMediaStream = null;
91
+ this.sttSourceNode = null;
92
+ this.sttProcessorNode = null;
93
+ this.audioElement = null;
94
+ this.currentBlobUrl = null;
95
+ this.speechGeneration = 0;
96
+ this.listeningGeneration = 0;
97
+ this.ttsUrl = config.ttsUrl ?? DEFAULT_TTS_URL;
98
+ this.sttUrl = config.sttUrl ?? DEFAULT_STT_URL;
99
+ this.sttModel = config.sttModel ?? DEFAULT_STT_MODEL;
100
+ this.ttsModel = config.ttsModel ?? DEFAULT_TTS_MODEL;
101
+ this.speaker = config.speaker ?? DEFAULT_SPEAKER;
102
+ this.sttSampleRate = config.sttSampleRate ?? DEFAULT_STT_SAMPLE_RATE;
103
+ this.ttsSampleRate = config.ttsSampleRate;
104
+ }
105
+ async startListening(language, handlers) {
106
+ if (typeof navigator === "undefined" || !navigator.mediaDevices) {
107
+ throw new Error("navigator.mediaDevices is unavailable for Sarvam STT");
108
+ }
109
+ if (this.sttSocket || this.sttMediaStream) {
110
+ await this.stopListening();
111
+ }
112
+ const generation = ++this.listeningGeneration;
113
+ const isCurrentSession = () => generation === this.listeningGeneration && this.sttSocket !== null;
114
+ const query = new URLSearchParams({
115
+ "language-code": language,
116
+ model: this.sttModel,
117
+ sample_rate: String(this.sttSampleRate),
118
+ input_audio_codec: "wav",
119
+ high_vad_sensitivity: "true",
120
+ vad_signals: "true",
121
+ flush_signal: "true",
122
+ });
123
+ const socket = new WebSocket(`${resolveWsUrl(this.sttUrl)}?${query.toString()}`);
124
+ this.sttSocket = socket;
125
+ socket.onmessage = (event) => {
126
+ if (!isCurrentSession()) {
127
+ return;
128
+ }
129
+ let message;
130
+ try {
131
+ message = JSON.parse(event.data);
132
+ }
133
+ catch {
134
+ return;
135
+ }
136
+ if (!message || typeof message !== "object") {
137
+ return;
138
+ }
139
+ switch (message.type) {
140
+ case "events": {
141
+ const signalType = message.data?.signal_type;
142
+ if (signalType === "START_SPEECH") {
143
+ handlers.onSpeechStart?.();
144
+ }
145
+ else if (signalType === "END_SPEECH") {
146
+ this.sendFlush(socket);
147
+ handlers.onSpeechEnd?.();
148
+ }
149
+ break;
150
+ }
151
+ case "data": {
152
+ const transcript = typeof message.data?.transcript === "string"
153
+ ? message.data.transcript.trim()
154
+ : "";
155
+ if (!transcript) {
156
+ return;
157
+ }
158
+ handlers.onPartial?.(transcript);
159
+ handlers.onFinal?.(transcript);
160
+ break;
161
+ }
162
+ case "transcript": {
163
+ const transcript = typeof message.text === "string" ? message.text.trim() : "";
164
+ if (!transcript) {
165
+ return;
166
+ }
167
+ handlers.onPartial?.(transcript);
168
+ handlers.onFinal?.(transcript);
169
+ break;
170
+ }
171
+ case "error": {
172
+ const errorMessage = typeof message.data?.error === "string"
173
+ ? message.data.error
174
+ : "Sarvam STT error";
175
+ handlers.onError?.(new Error(errorMessage));
176
+ break;
177
+ }
178
+ default:
179
+ break;
180
+ }
181
+ };
182
+ socket.onerror = () => {
183
+ if (!isCurrentSession()) {
184
+ return;
185
+ }
186
+ handlers.onError?.(new Error("Sarvam STT socket error"));
187
+ };
188
+ await new Promise((resolve, reject) => {
189
+ socket.addEventListener("open", () => resolve(), { once: true });
190
+ socket.addEventListener("error", () => reject(new Error("Failed to connect to Sarvam STT relay")), { once: true });
191
+ });
192
+ if (!isCurrentSession()) {
193
+ return;
194
+ }
195
+ const mediaStream = await navigator.mediaDevices.getUserMedia({
196
+ audio: true,
197
+ });
198
+ const audioContext = new AudioContext();
199
+ const sourceNode = audioContext.createMediaStreamSource(mediaStream);
200
+ const processorNode = audioContext.createScriptProcessor(4096, 1, 1);
201
+ sourceNode.connect(processorNode);
202
+ processorNode.connect(audioContext.destination);
203
+ processorNode.onaudioprocess = (event) => {
204
+ if (!isCurrentSession()) {
205
+ return;
206
+ }
207
+ if (handlers.shouldSendAudio && !handlers.shouldSendAudio()) {
208
+ return;
209
+ }
210
+ if (socket.readyState !== WebSocket.OPEN) {
211
+ return;
212
+ }
213
+ const floatSamples = event.inputBuffer.getChannelData(0);
214
+ if (!floatSamples || floatSamples.length === 0) {
215
+ return;
216
+ }
217
+ try {
218
+ const pcm = downsampleTo16BitMono(floatSamples, audioContext.sampleRate, this.sttSampleRate);
219
+ const wav = encodeWav(pcm, this.sttSampleRate);
220
+ const audioBase64 = toBase64(wav);
221
+ socket.send(JSON.stringify({
222
+ audio: {
223
+ data: audioBase64,
224
+ sample_rate: this.sttSampleRate,
225
+ encoding: "audio/wav",
226
+ },
227
+ }));
228
+ }
229
+ catch (error) {
230
+ handlers.onError?.(error instanceof Error
231
+ ? error
232
+ : new Error(`Failed to stream audio: ${String(error)}`));
233
+ }
234
+ };
235
+ this.sttContext = audioContext;
236
+ this.sttMediaStream = mediaStream;
237
+ this.sttSourceNode = sourceNode;
238
+ this.sttProcessorNode = processorNode;
239
+ }
240
+ sendFlush(socket) {
241
+ if (socket.readyState !== WebSocket.OPEN) {
242
+ return;
243
+ }
244
+ try {
245
+ socket.send(JSON.stringify({ type: "flush" }));
246
+ }
247
+ catch {
248
+ }
249
+ }
250
+ async stopListening() {
251
+ this.listeningGeneration++;
252
+ const socket = this.sttSocket;
253
+ this.sttSocket = null;
254
+ const processorNode = this.sttProcessorNode;
255
+ const sourceNode = this.sttSourceNode;
256
+ const audioContext = this.sttContext;
257
+ const mediaStream = this.sttMediaStream;
258
+ this.sttProcessorNode = null;
259
+ this.sttSourceNode = null;
260
+ this.sttContext = null;
261
+ this.sttMediaStream = null;
262
+ if (processorNode) {
263
+ try {
264
+ processorNode.disconnect();
265
+ }
266
+ catch {
267
+ }
268
+ processorNode.onaudioprocess = null;
269
+ }
270
+ if (sourceNode) {
271
+ try {
272
+ sourceNode.disconnect();
273
+ }
274
+ catch {
275
+ }
276
+ }
277
+ if (mediaStream) {
278
+ for (const track of mediaStream.getTracks()) {
279
+ try {
280
+ track.stop();
281
+ }
282
+ catch {
283
+ }
284
+ }
285
+ }
286
+ if (audioContext) {
287
+ try {
288
+ await audioContext.close();
289
+ }
290
+ catch {
291
+ }
292
+ }
293
+ if (socket) {
294
+ this.sendFlush(socket);
295
+ try {
296
+ socket.onmessage = null;
297
+ socket.onerror = null;
298
+ socket.onclose = null;
299
+ socket.close();
300
+ }
301
+ catch {
302
+ }
303
+ }
304
+ }
305
+ async speak(text, opts) {
306
+ if (!text || !text.trim()) {
307
+ return;
308
+ }
309
+ this.stopSpeaking();
310
+ const generation = ++this.speechGeneration;
311
+ const language = opts?.language ?? "en-IN";
312
+ const body = {
313
+ text,
314
+ target_language_code: language,
315
+ model: this.ttsModel,
316
+ speaker: this.speaker,
317
+ output_audio_codec: "wav",
318
+ };
319
+ if (this.ttsSampleRate) {
320
+ body.speech_sample_rate = String(this.ttsSampleRate);
321
+ }
322
+ const response = await fetch(this.ttsUrl, {
323
+ method: "POST",
324
+ headers: {
325
+ "Content-Type": "application/json",
326
+ },
327
+ body: JSON.stringify(body),
328
+ });
329
+ if (!response.ok) {
330
+ const errorText = await response.text().catch(() => "");
331
+ throw new Error(`Sarvam TTS failed: ${response.status} ${response.statusText}${errorText ? ` - ${errorText}` : ""}`);
332
+ }
333
+ const payload = (await response.json());
334
+ const audioBase64 = Array.isArray(payload.audios) && payload.audios.length > 0
335
+ ? payload.audios[0]
336
+ : typeof payload.audio === "string"
337
+ ? payload.audio
338
+ : null;
339
+ if (!audioBase64) {
340
+ throw new Error("Sarvam TTS response does not contain audio data");
341
+ }
342
+ const binaryString = atob(audioBase64);
343
+ const bytes = new Uint8Array(binaryString.length);
344
+ for (let i = 0; i < binaryString.length; i++) {
345
+ bytes[i] = binaryString.charCodeAt(i);
346
+ }
347
+ if (generation !== this.speechGeneration) {
348
+ return;
349
+ }
350
+ const blob = new Blob([bytes], { type: "audio/wav" });
351
+ const blobUrl = URL.createObjectURL(blob);
352
+ if (generation !== this.speechGeneration) {
353
+ URL.revokeObjectURL(blobUrl);
354
+ return;
355
+ }
356
+ this.currentBlobUrl = blobUrl;
357
+ const audio = new Audio(blobUrl);
358
+ this.audioElement = audio;
359
+ await new Promise((resolve, reject) => {
360
+ audio.onended = () => {
361
+ this.cleanupAudioElement(audio, blobUrl);
362
+ resolve();
363
+ };
364
+ audio.onerror = () => {
365
+ this.cleanupAudioElement(audio, blobUrl);
366
+ reject(new Error("Sarvam TTS playback failed"));
367
+ };
368
+ audio
369
+ .play()
370
+ .then(() => {
371
+ if (generation === this.speechGeneration) {
372
+ opts?.onAudioStart?.();
373
+ }
374
+ })
375
+ .catch((error) => {
376
+ this.cleanupAudioElement(audio, blobUrl);
377
+ reject(error instanceof Error ? error : new Error(String(error)));
378
+ });
379
+ });
380
+ }
381
+ stopSpeaking() {
382
+ this.speechGeneration++;
383
+ if (this.audioElement) {
384
+ try {
385
+ this.audioElement.pause();
386
+ this.audioElement.src = "";
387
+ }
388
+ catch {
389
+ }
390
+ this.audioElement = null;
391
+ }
392
+ if (this.currentBlobUrl) {
393
+ try {
394
+ URL.revokeObjectURL(this.currentBlobUrl);
395
+ }
396
+ catch {
397
+ }
398
+ this.currentBlobUrl = null;
399
+ }
400
+ }
401
+ async dispose() {
402
+ await this.stopListening();
403
+ this.stopSpeaking();
404
+ }
405
+ cleanupAudioElement(audio, blobUrl) {
406
+ if (this.audioElement === audio) {
407
+ this.audioElement = null;
408
+ }
409
+ if (this.currentBlobUrl === blobUrl) {
410
+ try {
411
+ URL.revokeObjectURL(blobUrl);
412
+ }
413
+ catch {
414
+ }
415
+ this.currentBlobUrl = null;
416
+ }
417
+ }
418
+ }
@@ -1,10 +1,13 @@
1
- import type { NavigationAction, ActionResult } from "../types.js";
1
+ import type { NavigationAction, ActionResult, SpeechProvider } from "../types.js";
2
2
  import type { AzureSpeechService } from "./azure-speech.js";
3
3
  import type { BedrockService } from "./bedrock.js";
4
+ import type { SarvamSpeechService } from "./sarvam-speech.js";
4
5
  interface VoiceFeedbackConfig {
5
6
  enabled?: boolean;
6
7
  language?: string;
7
- azureSpeechService: AzureSpeechService;
8
+ speechProvider?: SpeechProvider;
9
+ azureSpeechService?: AzureSpeechService;
10
+ sarvamSpeechService?: SarvamSpeechService;
8
11
  bedrockService: BedrockService;
9
12
  }
10
13
  interface FeedbackContext {
@@ -21,7 +24,9 @@ interface FeedbackContext {
21
24
  export declare class VoiceFeedbackService {
22
25
  private enabled;
23
26
  private language;
27
+ private speechProvider;
24
28
  private azureSpeechService;
29
+ private sarvamSpeechService;
25
30
  private bedrockService;
26
31
  private synthesizer;
27
32
  private isSpeaking;
@@ -1 +1 @@
1
- {"version":3,"file":"voice-feedback.d.ts","sourceRoot":"","sources":["../../src/services/voice-feedback.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,UAAU,mBAAmB;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,UAAU,CAAkB;gBAExB,MAAM,EAAE,mBAAmB;IAiBvC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAclC,SAAS,IAAI,OAAO;IAOpB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;YAQrB,qBAAqB;IAmCnC,OAAO,CAAC,mBAAmB;YAsBb,uBAAuB;IAsCrC,OAAO,CAAC,oBAAoB;IA4C5B,OAAO,CAAC,kBAAkB;YAgCZ,KAAK;IA0EnB,OAAO,CAAC,YAAY;IAkBd,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAoFxD,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxD,mBAAmB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,GAAG,UAAU,GAC7B,OAAO,CAAC,IAAI,CAAC;IAwBhB,OAAO,CAAC,kBAAkB;IAwF1B,OAAO,IAAI,IAAI;CAOhB"}
1
+ {"version":3,"file":"voice-feedback.d.ts","sourceRoot":"","sources":["../../src/services/voice-feedback.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9D,UAAU,mBAAmB;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,mBAAmB,CAA6B;IACxD,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,UAAU,CAAkB;gBAExB,MAAM,EAAE,mBAAmB;IA2BvC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAclC,SAAS,IAAI,OAAO;IAOpB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;YAQrB,qBAAqB;IA2CnC,OAAO,CAAC,mBAAmB;YAsBb,uBAAuB;IAwCrC,OAAO,CAAC,oBAAoB;IA4C5B,OAAO,CAAC,kBAAkB;YAuCZ,KAAK;IAyFnB,OAAO,CAAC,YAAY;IAwBd,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAoFxD,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxD,mBAAmB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,GAAG,UAAU,GAC7B,OAAO,CAAC,IAAI,CAAC;IAwBhB,OAAO,CAAC,kBAAkB;IAwF1B,OAAO,IAAI,IAAI;CAWhB"}
@@ -1,12 +1,22 @@
1
1
  import * as sdk from "microsoft-cognitiveservices-speech-sdk";
2
+ import { formatActionLabel } from "../actions.js";
3
+ import { resolveTtsLanguage } from "../languages.js";
2
4
  export class VoiceFeedbackService {
3
5
  constructor(config) {
4
6
  this.synthesizer = null;
5
7
  this.isSpeaking = false;
6
8
  this.enabled = config.enabled ?? true;
7
9
  this.language = config.language || "en-IN";
8
- this.azureSpeechService = config.azureSpeechService;
10
+ this.speechProvider = config.speechProvider ?? "sarvam";
11
+ this.azureSpeechService = config.azureSpeechService ?? null;
12
+ this.sarvamSpeechService = config.sarvamSpeechService ?? null;
9
13
  this.bedrockService = config.bedrockService;
14
+ if (this.speechProvider === "azure" && !this.azureSpeechService) {
15
+ throw new Error("Azure speech service is required for azure provider");
16
+ }
17
+ if (this.speechProvider === "sarvam" && !this.sarvamSpeechService) {
18
+ throw new Error("Sarvam speech service is required for sarvam provider");
19
+ }
10
20
  console.log("[VoiceFeedback] Service initialized - enabled:", this.enabled, "language:", this.language);
11
21
  }
12
22
  setEnabled(enabled) {
@@ -24,12 +34,18 @@ export class VoiceFeedbackService {
24
34
  console.log("[VoiceFeedback] Language changed to:", language);
25
35
  }
26
36
  async initializeSynthesizer() {
37
+ if (this.speechProvider === "sarvam") {
38
+ return;
39
+ }
27
40
  if (this.synthesizer) {
28
41
  console.log("[VoiceFeedback] Synthesizer already initialized");
29
42
  return;
30
43
  }
31
44
  console.log("[VoiceFeedback] Initializing synthesizer...");
32
45
  try {
46
+ if (!this.azureSpeechService) {
47
+ throw new Error("Azure speech service not configured");
48
+ }
33
49
  const tokenResponse = await this.azureSpeechService.fetchToken();
34
50
  const speechConfig = sdk.SpeechConfig.fromAuthorizationToken(tokenResponse.token, tokenResponse.region);
35
51
  const voiceName = this.getVoiceForLanguage(this.language);
@@ -65,7 +81,7 @@ export class VoiceFeedbackService {
65
81
  const prompt = this.buildPromptForAction(action, actionResult, transcript, elementInfo);
66
82
  console.log("[VoiceFeedback] Requesting AI message generation...");
67
83
  try {
68
- const response = await this.bedrockService.generateFeedbackMessage(prompt, this.language);
84
+ const response = await this.bedrockService.generateFeedbackMessage(prompt, resolveTtsLanguage(this.language));
69
85
  console.log("[VoiceFeedback] AI generated message:", response);
70
86
  return response;
71
87
  }
@@ -118,10 +134,15 @@ export class VoiceFeedbackService {
118
134
  if (elementInfo?.label) {
119
135
  return elementInfo.label;
120
136
  }
121
- return `${actionResult.info.elementTag}`;
137
+ return formatActionLabel(action);
138
+ }
139
+ if (action === "search_content") {
140
+ const query = typeof actionResult?.info?.query === "string"
141
+ ? actionResult.info.query
142
+ : undefined;
143
+ return query ? `Searching for ${query}` : formatActionLabel(action);
122
144
  }
123
- const actionLabel = action.replace(/_/g, " ");
124
- return actionLabel;
145
+ return formatActionLabel(action);
125
146
  }
126
147
  async speak(message) {
127
148
  if (!this.enabled || !message) {
@@ -130,6 +151,17 @@ export class VoiceFeedbackService {
130
151
  }
131
152
  console.log("[VoiceFeedback] Attempting to speak:", message);
132
153
  try {
154
+ if (this.speechProvider === "sarvam") {
155
+ if (!this.sarvamSpeechService) {
156
+ throw new Error("Sarvam speech service not configured");
157
+ }
158
+ this.isSpeaking = true;
159
+ await this.sarvamSpeechService.speak(message, {
160
+ language: resolveTtsLanguage(this.language),
161
+ });
162
+ this.isSpeaking = false;
163
+ return;
164
+ }
133
165
  await this.initializeSynthesizer();
134
166
  if (!this.synthesizer) {
135
167
  console.warn("[VoiceFeedback] Synthesizer not available after initialization");
@@ -171,6 +203,11 @@ export class VoiceFeedbackService {
171
203
  }
172
204
  }
173
205
  stopSpeaking() {
206
+ if (this.speechProvider === "sarvam") {
207
+ this.sarvamSpeechService?.stopSpeaking();
208
+ this.isSpeaking = false;
209
+ return;
210
+ }
174
211
  if (this.synthesizer && this.isSpeaking) {
175
212
  try {
176
213
  this.synthesizer.close();
@@ -324,6 +361,9 @@ export class VoiceFeedbackService {
324
361
  }
325
362
  dispose() {
326
363
  this.stopSpeaking();
364
+ if (this.speechProvider === "sarvam") {
365
+ return;
366
+ }
327
367
  if (this.synthesizer) {
328
368
  this.synthesizer.close();
329
369
  this.synthesizer = null;
package/dist/types.d.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  export type CoreNavigationAction = "zoom_in" | "zoom_out" | "scroll_up" | "scroll_down" | "scroll_left" | "scroll_right" | "page_up" | "page_down" | "scroll_top" | "scroll_bottom" | "go_back" | "go_forward" | "reload_page" | "print_page" | "copy_url" | "open_menu" | "close_menu" | "focus_search" | "toggle_fullscreen" | "exit_fullscreen" | "play_media" | "pause_media" | "mute_media" | "unmute_media" | "search_content" | "stop" | "quit" | "tab_next" | "tab_back" | "focus_next" | "focus_previous" | "click" | "enter" | "submit" | "activate" | "move_left" | "move_right" | "move_up" | "move_down" | "move_beginning" | "move_end" | "select_all" | "select_line" | "type_text" | "cut" | "copy" | "paste" | "clear" | "unknown";
2
2
  export type NavigationAction = CoreNavigationAction | `navigate_${string}`;
3
3
  export type ButtonPlacement = "bottom-right" | "bottom-left" | "top-right" | "top-left" | "center-right" | "center-left";
4
+ export type SpeechProvider = "sarvam" | "azure";
4
5
  export interface UIConfig {
5
6
  showDefaultButton?: boolean;
6
7
  customButtonSelector?: string;
7
8
  buttonPlacement?: ButtonPlacement;
8
9
  }
9
10
  export interface NavigationConfig {
11
+ speechProvider?: SpeechProvider;
10
12
  aws?: {
11
13
  bedrockEndpoint?: string;
12
14
  embeddingEndpoint?: string;
@@ -21,6 +23,15 @@ export interface NavigationConfig {
21
23
  subscriptionKey?: string;
22
24
  region?: string;
23
25
  };
26
+ sarvam?: {
27
+ ttsUrl?: string;
28
+ sttUrl?: string;
29
+ sttModel?: "saaras:v3" | "saarika:v2.5";
30
+ ttsModel?: "bulbul:v3" | "bulbul:v2";
31
+ speaker?: string;
32
+ sttSampleRate?: 8000 | 16000;
33
+ ttsSampleRate?: 8000 | 16000 | 22050 | 24000 | 32000 | 44100 | 48000;
34
+ };
24
35
  language?: string;
25
36
  voiceFeedback?: {
26
37
  enabled?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myscheme/voice-navigation-sdk",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Voice navigation SDK using Azure Speech and AWS Bedrock",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -30,10 +30,12 @@
30
30
  "@azure/core-auth": "^1.10.0",
31
31
  "@opensearch-project/opensearch": "^2.12.0",
32
32
  "dotenv": "^17.3.1",
33
- "microsoft-cognitiveservices-speech-sdk": "^1.47.0"
33
+ "microsoft-cognitiveservices-speech-sdk": "^1.47.0",
34
+ "ws": "^8.16.0"
34
35
  },
35
36
  "devDependencies": {
36
37
  "@types/node": "^20.17.10",
38
+ "@types/ws": "^8.5.13",
37
39
  "typescript": "^5.7.2"
38
40
  },
39
41
  "keywords": [