@myscheme/voice-navigation-sdk 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,6 +41,7 @@ export declare class MicrophoneHandler {
41
41
  getAggregatedText(): string;
42
42
  scheduleSilenceCheck(callbacks?: NavigationCallbacks): void;
43
43
  rescheduleSilenceCheck(): void;
44
+ private verifyRecognizerHealth;
44
45
  private startHealthCheck;
45
46
  private stopHealthCheck;
46
47
  private recoverFromStalledRecognizer;
@@ -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;gBAE1B,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;IAgB9B,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;IA4IrE,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;WAwCzB,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,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;gBAE1B,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;IAoJrE,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;WAwCzB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;CAYvD"}
@@ -179,13 +179,28 @@ export class MicrophoneHandler {
179
179
  }
180
180
  console.log("[MicrophoneHandler] Rescheduling silence check");
181
181
  this.scheduleSilenceCheck(this.activeCallbacks);
182
+ this.verifyRecognizerHealth();
183
+ }
184
+ verifyRecognizerHealth() {
185
+ if (!this.isRecording || !this.recognizer) {
186
+ return;
187
+ }
188
+ const now = Date.now();
189
+ const timeSinceLastRecognition = now - this.lastRecognitionTime;
190
+ if (timeSinceLastRecognition > 15000) {
191
+ console.warn("[MicrophoneHandler] Recognizer may be stalled - last event was", timeSinceLastRecognition / 1000, "seconds ago. Triggering recovery.");
192
+ void this.recoverFromStalledRecognizer();
193
+ }
194
+ else {
195
+ console.log("[MicrophoneHandler] Recognizer health OK - last event", (timeSinceLastRecognition / 1000).toFixed(1), "seconds ago");
196
+ }
182
197
  }
183
198
  startHealthCheck() {
184
199
  this.stopHealthCheck();
185
200
  this.recognitionHealthCheckInterval = setInterval(() => {
186
201
  const now = Date.now();
187
202
  const timeSinceLastRecognition = now - this.lastRecognitionTime;
188
- if (this.isRecording && timeSinceLastRecognition > 60000) {
203
+ if (this.isRecording && timeSinceLastRecognition > 30000) {
189
204
  console.warn("[MicrophoneHandler] Recognizer appears stalled. Last recognition:", timeSinceLastRecognition / 1000, "seconds ago");
190
205
  this.recoverFromStalledRecognizer();
191
206
  }
@@ -341,6 +356,7 @@ export class MicrophoneHandler {
341
356
  }
342
357
  }
343
358
  else if (e.result.reason === sdk.ResultReason.NoMatch) {
359
+ this.lastRecognitionTime = Date.now();
344
360
  console.log("[MicrophoneHandler] No speech recognized (NoMatch)");
345
361
  }
346
362
  };
@@ -353,9 +369,12 @@ export class MicrophoneHandler {
353
369
  }
354
370
  };
355
371
  this.recognizer.sessionStopped = (_s, _e) => {
356
- console.log("[MicrophoneHandler] Session stopped");
372
+ console.log("[MicrophoneHandler] Session stopped unexpectedly by SDK");
357
373
  this.isRecording = false;
358
374
  this.stopHealthCheck();
375
+ if (this.activeCallbacks.onError) {
376
+ this.activeCallbacks.onError(new Error("Speech recognition session stopped unexpectedly"));
377
+ }
359
378
  };
360
379
  this.recognizer.startContinuousRecognitionAsync(() => {
361
380
  console.log("[MicrophoneHandler] Continuous recognition started");
@@ -16,6 +16,7 @@ export declare class VoiceNavigationController {
16
16
  private vectorSearchService;
17
17
  private pagesInitialized;
18
18
  private uiInitialized;
19
+ private isSyncingButtonState;
19
20
  constructor(config: NavigationConfig);
20
21
  private initializeUIAsync;
21
22
  private shouldAutoStart;
@@ -29,7 +30,10 @@ export declare class VoiceNavigationController {
29
30
  start(options?: {
30
31
  reason?: "auto" | "user";
31
32
  }): Promise<void>;
32
- stop(): Promise<void>;
33
+ stop(options?: {
34
+ triggeredByUser?: boolean;
35
+ }): Promise<void>;
36
+ private syncCustomButtonState;
33
37
  private handlePartial;
34
38
  private handleSegment;
35
39
  private handleSilence;
@@ -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;gBAEzB,MAAM,EAAE,gBAAgB;YAqJtB,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;IAwBhB,KAAK,CAChB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAO,GACzC,OAAO,CAAC,IAAI,CAAC;IAmFH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiClC,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;YAWP,aAAa;YAOb,wBAAwB;IA2CtC,OAAO,CAAC,WAAW;YAoBL,iBAAiB;YAwBjB,iBAAiB;IAoRxB,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;IAkD/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,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;gBAElC,MAAM,EAAE,gBAAgB;YAqJtB,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;IAsFH,IAAI,CACf,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,OAAO,CAAC,IAAI,CAAC;IAoDhB,OAAO,CAAC,qBAAqB;IAwB7B,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;YAWP,aAAa;YAOb,wBAAwB;IA2CtC,OAAO,CAAC,WAAW;YAuBL,iBAAiB;YAwBjB,iBAAiB;IAoRxB,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"}
@@ -38,6 +38,7 @@ export class VoiceNavigationController {
38
38
  this.autoStartPendingUserInteraction = false;
39
39
  this.removeAutoStartListeners = null;
40
40
  this.vectorSearchService = null;
41
+ this.isSyncingButtonState = false;
41
42
  const openSearchConfig = resolveOpenSearchConfig(config);
42
43
  this.config = {
43
44
  ...config,
@@ -235,13 +236,17 @@ export class VoiceNavigationController {
235
236
  });
236
237
  }
237
238
  async toggleRecording() {
239
+ if (this.isSyncingButtonState) {
240
+ console.log("[VoiceNavigation] Skipping toggle - syncing button state");
241
+ return;
242
+ }
238
243
  if (!this.ui || !this.ui.root) {
239
244
  console.warn("UI not initialized, cannot toggle recording");
240
245
  return;
241
246
  }
242
247
  const currentState = this.ui.root.dataset.state;
243
248
  if (currentState === "listening" || currentState === "thinking") {
244
- await this.stop();
249
+ await this.stop({ triggeredByUser: true });
245
250
  return;
246
251
  }
247
252
  if (currentState === "loading") {
@@ -286,7 +291,9 @@ export class VoiceNavigationController {
286
291
  }
287
292
  catch (error) {
288
293
  setState(this.ui, "idle");
289
- updateStatus(this.ui, "Tap to enable voice navigation");
294
+ if (!this.ui.isCustomButton) {
295
+ updateStatus(this.ui, "Tap to enable voice navigation");
296
+ }
290
297
  return;
291
298
  }
292
299
  }
@@ -318,7 +325,8 @@ export class VoiceNavigationController {
318
325
  emitEvent("error", { error });
319
326
  }
320
327
  }
321
- async stop() {
328
+ async stop(options = {}) {
329
+ const triggeredByUser = options.triggeredByUser ?? false;
322
330
  if (!this.ui || !this.ui.root) {
323
331
  console.warn("UI not initialized, cannot stop");
324
332
  return;
@@ -335,12 +343,38 @@ export class VoiceNavigationController {
335
343
  setState(this.ui, "idle");
336
344
  emitEvent("state-change", { state: "idle" });
337
345
  updateTranscript(this.ui, "");
346
+ if (!triggeredByUser && this.ui.isCustomButton) {
347
+ console.log("[VoiceNavigation] Programmatically clicking custom button to sync external UI state");
348
+ this.syncCustomButtonState();
349
+ }
338
350
  }
339
351
  catch (error) {
340
352
  console.error("Failed to stop recording:", error);
341
353
  showError(this.ui, error);
342
354
  setState(this.ui, "error");
343
355
  emitEvent("error", { error });
356
+ if (!triggeredByUser && this.ui.isCustomButton) {
357
+ console.log("[VoiceNavigation] Programmatically clicking custom button after error");
358
+ this.syncCustomButtonState();
359
+ }
360
+ }
361
+ }
362
+ syncCustomButtonState() {
363
+ if (!this.ui.isCustomButton) {
364
+ return;
365
+ }
366
+ try {
367
+ this.isSyncingButtonState = true;
368
+ this.ui.button.click();
369
+ console.log("[VoiceNavigation] Custom button clicked to sync external UI state");
370
+ }
371
+ catch (error) {
372
+ console.error("[VoiceNavigation] Failed to click custom button:", error);
373
+ }
374
+ finally {
375
+ setTimeout(() => {
376
+ this.isSyncingButtonState = false;
377
+ }, 100);
344
378
  }
345
379
  }
346
380
  handlePartial(text) {
@@ -397,7 +431,9 @@ export class VoiceNavigationController {
397
431
  this.isPermissionRelatedError(error)) {
398
432
  setState(this.ui, "idle");
399
433
  this.handleAutoStartFallback("auto");
400
- updateStatus(this.ui, "Tap to start voice control");
434
+ if (!this.ui.isCustomButton) {
435
+ updateStatus(this.ui, "Tap to start voice control");
436
+ }
401
437
  return;
402
438
  }
403
439
  showError(this.ui, error);
@@ -1045,7 +1081,9 @@ export class VoiceNavigationController {
1045
1081
  window.removeEventListener(event, resume);
1046
1082
  });
1047
1083
  };
1048
- updateStatus(this.ui, "Tap to enable voice navigation");
1084
+ if (!this.ui.isCustomButton) {
1085
+ updateStatus(this.ui, "Tap to enable voice navigation");
1086
+ }
1049
1087
  }
1050
1088
  clearAutoStartFallback() {
1051
1089
  if (this.removeAutoStartListeners) {
@@ -1 +1 @@
1
- {"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/services/bedrock.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAE5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAyCD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,aAAa;IA6CjC,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAO7C,OAAO,CAAC,iBAAiB;IA+BnB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAWtD,qBAAqB;YA2ErB,mBAAmB;IAyEjC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc;IAO9C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAWlC,iBAAiB;YAkFjB,eAAe;IAwFvB,uBAAuB,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;YA0BJ,wBAAwB;YAwExB,sBAAsB;CA+DrC"}
1
+ {"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/services/bedrock.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAE5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAqDD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,aAAa;IA6CjC,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAO7C,OAAO,CAAC,iBAAiB;IA+BnB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAWtD,qBAAqB;YA2ErB,mBAAmB;IAyEjC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc;IAO9C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAWlC,iBAAiB;YAkFjB,eAAe;IAwFvB,uBAAuB,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;YA0BJ,wBAAwB;YAwExB,sBAAsB;CA+DrC"}
@@ -33,7 +33,19 @@ EXAMPLES:
33
33
  MATCHING RULES FOR PAGE NAVIGATION:
34
34
  - Match user's words to page names and keywords
35
35
  - Choose the navigate_ action that best matches
36
- - If user says "go to X" or "open X" or "show me X", find the page with that name or keyword`;
36
+ - If user says "go to X" or "open X" or "show me X", find the page with that name or keyword
37
+
38
+ SPECIAL PRIORITY RULES FOR STATES AND MINISTRIES:
39
+ - If user mentions a state/UT name (like "Assam", "Delhi", "Tamil Nadu", "Maharashtra"), ALWAYS use the state navigation action (navigate_state_*)
40
+ - If user mentions a ministry name or ministry keywords (like "education", "health", "agriculture"), ALWAYS use the ministry navigation action (navigate_ministry_*)
41
+ - User does NOT need to say "state of" or "ministry of" - the name alone is enough
42
+ - Examples:
43
+ * "go to Assam" → {"action": "navigate_state_assam"}
44
+ * "open Delhi" → {"action": "navigate_state_delhi"}
45
+ * "show Kerala" → {"action": "navigate_state_kerala"}
46
+ * "go to education" → {"action": "navigate_ministry_education"}
47
+ * "open health ministry" → {"action": "navigate_ministry_health"}
48
+ * "ministry of agriculture" → {"action": "navigate_ministry_agriculture"}`;
37
49
  const DEFAULT_EMBEDDING_MODEL_ID = "cohere.embed-multilingual-v3";
38
50
  export class BedrockService {
39
51
  constructor(config) {
package/dist/ui.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAuC/E,eAAO,MAAM,2BAA2B,GACtC,YAAW,eAAgC,KAC1C,IAqHF,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAChC,YAAW,eAAgC,KAC1C,UAgEF,CAAC;AA+EF,eAAO,MAAM,oBAAoB,GAC/B,gBAAgB,MAAM,KACrB,OAAO,CAAC,UAAU,CAuEpB,CAAC;AAKF,eAAO,MAAM,YAAY,GAAI,IAAI,UAAU,EAAE,MAAM,MAAM,KAAG,IAE3D,CAAC;AAKF,eAAO,MAAM,QAAQ,GAAI,IAAI,UAAU,EAAE,OAAO,eAAe,KAAG,IAgDjE,CAAC;AAKF,eAAO,MAAM,gBAAgB,GAAI,IAAI,UAAU,EAAE,MAAM,MAAM,KAAG,IAE/D,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAChC,IAAI,UAAU,EACd,YAAY,MAAM,EAClB,WAAW,OAAO,EAClB,OAAM,GAAQ,KACb,IAkBF,CAAC;AAKF,eAAO,MAAM,SAAS,GAAI,IAAI,UAAU,EAAE,OAAO,KAAK,KAAG,IAGxD,CAAC;AAKF,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,SAAQ,GAAQ,KAAG,IAU1D,CAAC"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAuC/E,eAAO,MAAM,2BAA2B,GACtC,YAAW,eAAgC,KAC1C,IAkIF,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAChC,YAAW,eAAgC,KAC1C,UAgEF,CAAC;AA+EF,eAAO,MAAM,oBAAoB,GAC/B,gBAAgB,MAAM,KACrB,OAAO,CAAC,UAAU,CAuEpB,CAAC;AAKF,eAAO,MAAM,YAAY,GAAI,IAAI,UAAU,EAAE,MAAM,MAAM,KAAG,IAE3D,CAAC;AAKF,eAAO,MAAM,QAAQ,GAAI,IAAI,UAAU,EAAE,OAAO,eAAe,KAAG,IA0DjE,CAAC;AAKF,eAAO,MAAM,gBAAgB,GAAI,IAAI,UAAU,EAAE,MAAM,MAAM,KAAG,IAE/D,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAChC,IAAI,UAAU,EACd,YAAY,MAAM,EAClB,WAAW,OAAO,EAClB,OAAM,GAAQ,KACb,IAkBF,CAAC;AAKF,eAAO,MAAM,SAAS,GAAI,IAAI,UAAU,EAAE,OAAO,KAAK,KAAG,IAGxD,CAAC;AAKF,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,SAAQ,GAAQ,KAAG,IAU1D,CAAC"}
package/dist/ui.js CHANGED
@@ -85,6 +85,10 @@ export const injectFloatingControlStyles = (placement = "bottom-right") => {
85
85
  color: #bae6fd;
86
86
  }
87
87
 
88
+ .navigate-control__status:empty {
89
+ display: none;
90
+ }
91
+
88
92
  .navigate-control__transcript {
89
93
  font-size: 0.95rem;
90
94
  line-height: 1.4;
@@ -123,6 +127,15 @@ export const injectFloatingControlStyles = (placement = "bottom-right") => {
123
127
  background: #7c3aed;
124
128
  }
125
129
 
130
+ .navigate-control--hidden {
131
+ display: none !important;
132
+ visibility: hidden !important;
133
+ }
134
+
135
+ .navigate-control--hidden .navigate-control__panel {
136
+ display: none !important;
137
+ }
138
+
126
139
  @media (max-width: 640px) {
127
140
  .navigate-control {
128
141
  ${mobilePlacementStyles}
@@ -238,13 +251,12 @@ export const attachToCustomButton = async (buttonSelector) => {
238
251
  if (!root) {
239
252
  root = document.createElement("div");
240
253
  root.id = "navigate-control-panel";
241
- root.className = "navigate-control";
242
- root.style.display = "none";
254
+ root.className = "navigate-control navigate-control--hidden";
243
255
  }
244
256
  root.dataset.state = root.dataset.state || "idle";
245
257
  root.innerHTML = `
246
258
  <div class="navigate-control__panel">
247
- <div class="navigate-control__status">Tap your button to start voice control</div>
259
+ <div class="navigate-control__status"></div>
248
260
  <div class="navigate-control__transcript" role="status" aria-live="polite"></div>
249
261
  <div class="navigate-control__action" aria-live="polite"></div>
250
262
  </div>
@@ -264,6 +276,7 @@ export const attachToCustomButton = async (buttonSelector) => {
264
276
  });
265
277
  }
266
278
  customButton.setAttribute("aria-pressed", "false");
279
+ customButton.dataset.voiceState = "idle";
267
280
  if (!customButton.getAttribute("aria-label")) {
268
281
  customButton.setAttribute("aria-label", "Start voice control");
269
282
  }
@@ -282,6 +295,7 @@ export const updateStatus = (ui, text) => {
282
295
  };
283
296
  export const setState = (ui, state) => {
284
297
  ui.root.dataset.state = state;
298
+ ui.button.dataset.voiceState = state;
285
299
  const updateLabel = (text) => {
286
300
  if (ui.label) {
287
301
  ui.label.textContent = text;
@@ -292,9 +306,14 @@ export const setState = (ui, state) => {
292
306
  updateLabel("Start");
293
307
  ui.button.setAttribute("aria-pressed", "false");
294
308
  ui.button.setAttribute("aria-label", "Start voice control");
295
- updateStatus(ui, ui.isCustomButton
296
- ? "Tap your button to start voice control"
297
- : "Tap to start voice control");
309
+ if (ui.isCustomButton) {
310
+ updateStatus(ui, "");
311
+ updateTranscript(ui, "");
312
+ ui.action.textContent = "";
313
+ }
314
+ else {
315
+ updateStatus(ui, "Tap to start voice control");
316
+ }
298
317
  break;
299
318
  case "loading":
300
319
  updateLabel("Loading...");
@@ -314,11 +333,17 @@ export const setState = (ui, state) => {
314
333
  break;
315
334
  case "error":
316
335
  updateLabel("Error");
336
+ ui.button.setAttribute("aria-pressed", "false");
317
337
  ui.button.setAttribute("aria-label", "Error occurred");
318
338
  break;
319
339
  }
320
340
  if (ui.isCustomButton) {
321
- ui.root.style.display = state === "idle" ? "none" : "flex";
341
+ if (state === "idle" || state === "error") {
342
+ ui.root.classList.add("navigate-control--hidden");
343
+ }
344
+ else {
345
+ ui.root.classList.remove("navigate-control--hidden");
346
+ }
322
347
  }
323
348
  };
324
349
  export const updateTranscript = (ui, text) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myscheme/voice-navigation-sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Voice navigation SDK using Azure Speech and AWS Bedrock",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",