@glassly/engine 0.3.2-beta.572 → 0.3.2-beta.602

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 (151) hide show
  1. package/README.md +1 -1
  2. package/build/engine.d.ts +15 -1
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +7 -3
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/dev.d.ts +2 -2
  7. package/build/facades/dev.d.ts.map +1 -1
  8. package/build/facades/dev.js +2 -2
  9. package/build/facades/dev.js.map +1 -1
  10. package/build/facades/glasses.d.ts +20 -0
  11. package/build/facades/glasses.d.ts.map +1 -1
  12. package/build/facades/glasses.js +21 -0
  13. package/build/facades/glasses.js.map +1 -1
  14. package/build/facades/pairing.js +1 -1
  15. package/build/facades/pairing.js.map +1 -1
  16. package/build/facades/reports.js +2 -2
  17. package/build/facades/reports.js.map +1 -1
  18. package/build/facades/session.d.ts +1 -1
  19. package/build/facades/session.js +2 -2
  20. package/build/facades/session.js.map +1 -1
  21. package/build/generated/releaseMetadata.js +3 -3
  22. package/build/generated/releaseMetadata.js.map +1 -1
  23. package/build/index.d.ts +3 -1
  24. package/build/index.d.ts.map +1 -1
  25. package/build/index.js +3 -1
  26. package/build/index.js.map +1 -1
  27. package/build/runtime/bootstrap.d.ts +2 -2
  28. package/build/runtime/bootstrap.d.ts.map +1 -1
  29. package/build/runtime/bootstrap.js.map +1 -1
  30. package/build/services/CloudAudioSubscriptionSync.d.ts +2 -2
  31. package/build/services/CloudAudioSubscriptionSync.js +2 -2
  32. package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
  33. package/build/services/CloudClientService.d.ts +2 -2
  34. package/build/services/CloudClientService.d.ts.map +1 -1
  35. package/build/services/CloudClientService.js +4 -4
  36. package/build/services/CloudClientService.js.map +1 -1
  37. package/build/services/CloudTranscriptE2EMetrics.d.ts +2 -2
  38. package/build/services/CloudTranscriptE2EMetrics.d.ts.map +1 -1
  39. package/build/services/CloudTranscriptE2EMetrics.js +3 -3
  40. package/build/services/CloudTranscriptE2EMetrics.js.map +1 -1
  41. package/build/services/DeviceEventRouter.d.ts.map +1 -1
  42. package/build/services/DeviceEventRouter.js +5 -0
  43. package/build/services/DeviceEventRouter.js.map +1 -1
  44. package/build/services/GestureDotsService.d.ts +9 -9
  45. package/build/services/GestureDotsService.d.ts.map +1 -1
  46. package/build/services/GestureDotsService.js +75 -50
  47. package/build/services/GestureDotsService.js.map +1 -1
  48. package/build/services/GlassesTouchInput.d.ts +1 -1
  49. package/build/services/GlassesTouchInput.d.ts.map +1 -1
  50. package/build/services/GlassesTouchInput.js +7 -4
  51. package/build/services/GlassesTouchInput.js.map +1 -1
  52. package/build/services/LocalMiniappRuntime.d.ts +1 -1
  53. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  54. package/build/services/LocalMiniappRuntime.js +32 -8
  55. package/build/services/LocalMiniappRuntime.js.map +1 -1
  56. package/build/services/LocalSttFallbackCoordinator.d.ts +5 -2
  57. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  58. package/build/services/LocalSttFallbackCoordinator.js +7 -3
  59. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  60. package/build/services/PhonePhotoCoordinator.d.ts +1 -1
  61. package/build/services/PhonePhotoCoordinator.js +4 -4
  62. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  63. package/build/services/PhoneStreamCoordinator.d.ts +1 -1
  64. package/build/services/PhoneStreamCoordinator.js +1 -1
  65. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  66. package/build/services/SupportProfileSync.d.ts +1 -1
  67. package/build/services/SupportProfileSync.js +2 -2
  68. package/build/services/SupportProfileSync.js.map +1 -1
  69. package/build/services/TranscriptionRouting.d.ts +6 -1
  70. package/build/services/TranscriptionRouting.d.ts.map +1 -1
  71. package/build/services/TranscriptionRouting.js +7 -3
  72. package/build/services/TranscriptionRouting.js.map +1 -1
  73. package/build/services/cloudStreamApi.d.ts +2 -2
  74. package/build/services/cloudStreamApi.js +2 -2
  75. package/build/services/cloudStreamApi.js.map +1 -1
  76. package/build/services/gestureDotGlyphs.d.ts +1 -1
  77. package/build/services/gestureDotGlyphs.d.ts.map +1 -1
  78. package/build/services/gestureDotGlyphs.js +5 -0
  79. package/build/services/gestureDotGlyphs.js.map +1 -1
  80. package/build/services/neuralBand/MetaAuth.d.ts +31 -0
  81. package/build/services/neuralBand/MetaAuth.d.ts.map +1 -0
  82. package/build/services/neuralBand/MetaAuth.js +161 -0
  83. package/build/services/neuralBand/MetaAuth.js.map +1 -0
  84. package/build/services/neuralBand/NeuralBandInput.d.ts +50 -0
  85. package/build/services/neuralBand/NeuralBandInput.d.ts.map +1 -0
  86. package/build/services/neuralBand/NeuralBandInput.js +114 -0
  87. package/build/services/neuralBand/NeuralBandInput.js.map +1 -0
  88. package/build/services/neuralBand/NeuralBandSettingsSync.d.ts +3 -0
  89. package/build/services/neuralBand/NeuralBandSettingsSync.d.ts.map +1 -0
  90. package/build/services/neuralBand/NeuralBandSettingsSync.js +52 -0
  91. package/build/services/neuralBand/NeuralBandSettingsSync.js.map +1 -0
  92. package/build/services/neuralBand/sha256.d.ts +7 -0
  93. package/build/services/neuralBand/sha256.d.ts.map +1 -0
  94. package/build/services/neuralBand/sha256.js +68 -0
  95. package/build/services/neuralBand/sha256.js.map +1 -0
  96. package/build/services/settingsBridge.d.ts +12 -4
  97. package/build/services/settingsBridge.d.ts.map +1 -1
  98. package/build/services/settingsBridge.js +13 -4
  99. package/build/services/settingsBridge.js.map +1 -1
  100. package/build/services/soniox/SonioxRealtimeClient.d.ts +2 -2
  101. package/build/services/soniox/SonioxRealtimeClient.js +2 -2
  102. package/build/services/soniox/SonioxRealtimeClient.js.map +1 -1
  103. package/build/services/soniox/SonioxTokenAssembler.d.ts +1 -1
  104. package/build/services/soniox/SonioxTokenAssembler.js +1 -1
  105. package/build/services/soniox/SonioxTokenAssembler.js.map +1 -1
  106. package/build/stores/cloudClientStatus.js +1 -1
  107. package/build/stores/cloudClientStatus.js.map +1 -1
  108. package/build/stores/settings.d.ts.map +1 -1
  109. package/build/stores/settings.js +25 -7
  110. package/build/stores/settings.js.map +1 -1
  111. package/build/types/enums.d.ts +2 -1
  112. package/build/types/enums.d.ts.map +1 -1
  113. package/build/types/enums.js +1 -0
  114. package/build/types/enums.js.map +1 -1
  115. package/build/utils/cloudClient/cloudSecureStore.js +2 -2
  116. package/build/utils/cloudClient/cloudSecureStore.js.map +1 -1
  117. package/package.json +7 -7
  118. package/src/engine.ts +7 -3
  119. package/src/facades/dev.ts +2 -2
  120. package/src/facades/glasses.ts +27 -0
  121. package/src/facades/pairing.ts +1 -1
  122. package/src/facades/reports.ts +2 -2
  123. package/src/facades/session.ts +2 -2
  124. package/src/generated/releaseMetadata.ts +3 -3
  125. package/src/index.ts +15 -1
  126. package/src/runtime/bootstrap.ts +2 -2
  127. package/src/services/CloudAudioSubscriptionSync.ts +2 -2
  128. package/src/services/CloudClientService.ts +4 -4
  129. package/src/services/CloudTranscriptE2EMetrics.ts +3 -3
  130. package/src/services/DeviceEventRouter.ts +5 -0
  131. package/src/services/GestureDotsService.ts +72 -49
  132. package/src/services/GlassesTouchInput.ts +13 -5
  133. package/src/services/LocalMiniappRuntime.ts +52 -24
  134. package/src/services/LocalSttFallbackCoordinator.ts +18 -4
  135. package/src/services/PhonePhotoCoordinator.ts +4 -4
  136. package/src/services/PhoneStreamCoordinator.ts +1 -1
  137. package/src/services/SupportProfileSync.ts +2 -2
  138. package/src/services/TranscriptionRouting.ts +12 -4
  139. package/src/services/cloudStreamApi.ts +3 -3
  140. package/src/services/gestureDotGlyphs.ts +6 -1
  141. package/src/services/neuralBand/MetaAuth.ts +192 -0
  142. package/src/services/neuralBand/NeuralBandInput.ts +148 -0
  143. package/src/services/neuralBand/NeuralBandSettingsSync.ts +63 -0
  144. package/src/services/neuralBand/sha256.ts +70 -0
  145. package/src/services/settingsBridge.ts +15 -4
  146. package/src/services/soniox/SonioxRealtimeClient.ts +2 -2
  147. package/src/services/soniox/SonioxTokenAssembler.ts +1 -1
  148. package/src/stores/cloudClientStatus.ts +1 -1
  149. package/src/stores/settings.ts +25 -7
  150. package/src/types/enums.ts +1 -0
  151. package/src/utils/cloudClient/cloudSecureStore.ts +2 -2
@@ -44,7 +44,7 @@ import overlayPages from "./pages/OverlayPages";
44
44
  import dashboardOpenTrace from "./debug/DashboardOpenTrace";
45
45
  import { isAppForegrounded, isPhoneActive, onAppForegroundChange, onPhoneActivityChange } from "./PhoneActivity";
46
46
  import { installedNotificationApps } from "./PhoneNotificationsSync";
47
- import { DERIVED_SETTINGS_KEYS, SETTINGS_BRIDGE_KEYS, isDerivedSettingsKey, ringBatteryFrom, selectSettingsBridgeKeys, validateSettingsSet, } from "./settingsBridge";
47
+ import { DERIVED_SETTINGS_KEYS, SETTINGS_BRIDGE_KEYS, input2dFrom, isDerivedSettingsKey, ringBatteryFrom, selectSettingsBridgeKeys, validateSettingsSet, } from "./settingsBridge";
48
48
  import { mayUsePermission } from "./miniappPermissions";
49
49
  import { activeDashboard, addDashboardApp, displayViewsFor, isDashboardApp, isOverlayApp, onOverlayAppsChange, removeDashboardApp, setOverlayViewer, } from "./pages/overlayApps";
50
50
  import { pagesEligible } from "./pages/pageEligibility";
@@ -63,7 +63,7 @@ import { phonePhotoCoordinator } from "./PhonePhotoCoordinator";
63
63
  import { phoneStreamCoordinator } from "./PhoneStreamCoordinator";
64
64
  import { phoneVideoCoordinator } from "./PhoneVideoCoordinator";
65
65
  import { runSentenceTtsPipeline } from "./SentenceTtsPipeline";
66
- import { summarizeTranscriptionRoutes, transcriptionDeliveryRoute } from "./TranscriptionRouting";
66
+ import { summarizeTranscriptionRoutes, transcriptionDeliveryRoute, } from "./TranscriptionRouting";
67
67
  import { prepareTtsSentences } from "./TtsTextSanitizer";
68
68
  import { handleWifiAdbRequest } from "./WifiAdbRequest";
69
69
  import { cloudClientService, setBlobNamespaceMigrator } from "./CloudClientService";
@@ -152,7 +152,7 @@ const MINIAPP_AUTH_REFRESH_MIN_DELAY_MS = 5_000;
152
152
  // (e.g. the cloud client had not finished its first-boot Core token exchange
153
153
  // when the miniapp connected). Exponential from base, capped, so a transient
154
154
  // not-yet-connected client self-heals within seconds instead of needing a full
155
- // manual Cloud V2 reconnect.
155
+ // manual Cloud reconnect.
156
156
  const MINIAPP_AUTH_RETRY_BASE_MS = 1_000;
157
157
  const MINIAPP_AUTH_RETRY_MAX_MS = 15_000;
158
158
  const FOREGROUND_LIVENESS_PROBE_TIMEOUT_MS = 2_500;
@@ -835,6 +835,7 @@ class LocalMiniappRuntime {
835
835
  subscriptions: new Set(),
836
836
  forceLocalTranscriptionStreams: new Set(),
837
837
  cloudTranscriptionStreams: new Set(),
838
+ noFallbackTranscriptionStreams: new Set(),
838
839
  sendMessage: sendFn,
839
840
  lastPongAt: Date.now(),
840
841
  unansweredPingRounds: 0,
@@ -1538,7 +1539,7 @@ class LocalMiniappRuntime {
1538
1539
  // right after app start. CONNECT_ACK already went out without auth; keep
1539
1540
  // trying to mint (and re-drive on cloud-connect) so the app authenticates
1540
1541
  // to its backend on its own, instead of staying dead until a full manual
1541
- // Cloud V2 reconnect re-runs the whole handshake.
1542
+ // Cloud reconnect re-runs the whole handshake.
1542
1543
  this.deliverInitialMiniappAuth(packageName, authPromise, 0);
1543
1544
  }
1544
1545
  this.sendCloudStatusToMiniapp(packageName);
@@ -1688,7 +1689,7 @@ class LocalMiniappRuntime {
1688
1689
  * When the cloud client (re)connects, immediately re-attempt the initial mint
1689
1690
  * for any handshook app still missing its token, instead of waiting out the
1690
1691
  * backoff. This is what turns "scan a dev app before the cloud is ready" from
1691
- * "dead until you manually reconnect Cloud V2" into "authenticates on its own
1692
+ * "dead until you manually reconnect Cloud" into "authenticates on its own
1692
1693
  * the instant the connection comes up".
1693
1694
  */
1694
1695
  redriveMiniappAuthDelivery() {
@@ -1798,6 +1799,7 @@ class LocalMiniappRuntime {
1798
1799
  let requestedLocationRate = null;
1799
1800
  const forceLocalTranscriptionStreams = new Set();
1800
1801
  const cloudTranscriptionStreams = new Set();
1802
+ const noFallbackTranscriptionStreams = new Set();
1801
1803
  const streams = rawStreams?.map((s) => {
1802
1804
  if (typeof s === "object" && s !== null) {
1803
1805
  if (s.stream === "location_stream") {
@@ -1811,6 +1813,8 @@ class LocalMiniappRuntime {
1811
1813
  }
1812
1814
  if (isSpeechTextStream(s.stream) && (s.forceLocal !== true || s.includeCloud === true)) {
1813
1815
  cloudTranscriptionStreams.add(s.stream);
1816
+ if (s.localFallback === false)
1817
+ noFallbackTranscriptionStreams.add(s.stream);
1814
1818
  }
1815
1819
  return s.stream;
1816
1820
  }
@@ -1875,6 +1879,7 @@ class LocalMiniappRuntime {
1875
1879
  app.subscriptions = new Set(streams);
1876
1880
  app.forceLocalTranscriptionStreams = new Set([...forceLocalTranscriptionStreams].filter((stream) => app.subscriptions.has(stream)));
1877
1881
  app.cloudTranscriptionStreams = new Set([...cloudTranscriptionStreams].filter((stream) => app.subscriptions.has(stream)));
1882
+ app.noFallbackTranscriptionStreams = new Set([...noFallbackTranscriptionStreams].filter((stream) => app.subscriptions.has(stream)));
1878
1883
  this.replaceStreamSubscribers(packageName, previousSubscriptions, app.subscriptions);
1879
1884
  // The overlay app presents phone notifications on the glasses while it
1880
1885
  // listens to them; recorded for every dashboard so the role can move.
@@ -2212,6 +2217,10 @@ class LocalMiniappRuntime {
2212
2217
  return localDisplayManager.foregroundAppOnScreen();
2213
2218
  case "ring_battery":
2214
2219
  return ringBatteryFrom(useGlassesStore.getState());
2220
+ case "input_2d": {
2221
+ const controller = useSettingsStore.getState().getSetting(SETTINGS.default_controller.key);
2222
+ return input2dFrom(useGlassesStore.getState(), controller);
2223
+ }
2215
2224
  }
2216
2225
  }
2217
2226
  handleSettingsGet(packageName, payload, requestId) {
@@ -2298,6 +2307,7 @@ class LocalMiniappRuntime {
2298
2307
  useAppStatusStore.subscribe(pushDerived);
2299
2308
  onOverlayAppsChange(pushDerived);
2300
2309
  useGlassesStore.subscribe((s) => `${s.ringConnected}:${s.ringBatteryLevel}:${s.controllerConnected}:${s.controllerBatteryLevel}`, pushDerived);
2310
+ useSettingsStore.subscribe((s) => s.getSetting(SETTINGS.default_controller.key), pushDerived);
2301
2311
  }
2302
2312
  /**
2303
2313
  * Native nav UI feed (display.sendNativeNav*). Gated on the device's nav
@@ -4245,6 +4255,7 @@ class LocalMiniappRuntime {
4245
4255
  const previousSubscriptions = app.subscriptions;
4246
4256
  app.subscriptions = new Set(streams);
4247
4257
  app.forceLocalTranscriptionStreams.clear();
4258
+ app.noFallbackTranscriptionStreams.clear();
4248
4259
  app.cloudTranscriptionStreams = new Set(streams.filter(isSpeechTextStream));
4249
4260
  this.replaceStreamSubscribers(packageName, previousSubscriptions, app.subscriptions);
4250
4261
  this.recomputeMicRequirements();
@@ -4310,6 +4321,7 @@ class LocalMiniappRuntime {
4310
4321
  let transcriptionLang = null;
4311
4322
  let forceLocalTranscriptionLang = null;
4312
4323
  let hasForceLocalTranscription = false;
4324
+ let hasFallbackTranscription = false;
4313
4325
  const localTranslations = [];
4314
4326
  for (const [stream, subscribers] of this.activeStreamSubscribers()) {
4315
4327
  if (subscribers.size === 0)
@@ -4340,6 +4352,8 @@ class LocalMiniappRuntime {
4340
4352
  if (forceLocalTranscriptionLang === null)
4341
4353
  forceLocalTranscriptionLang = language;
4342
4354
  }
4355
+ if (routes.hasFallbackSubscriber)
4356
+ hasFallbackTranscription = true;
4343
4357
  if (routes.hasCloudSubscriber)
4344
4358
  cloudStreams.add(stream);
4345
4359
  }
@@ -4351,7 +4365,7 @@ class LocalMiniappRuntime {
4351
4365
  localTranslationService.setSubscriptions(translatesLocally);
4352
4366
  const hasForceLocalTranslation = translatesLocally.some((sub) => sub.forceLocal);
4353
4367
  const localSourceLang = translatesLocally.length > 0 ? sttModelManager.getBcp47ForLanguage() : null;
4354
- localSttFallbackCoordinator.onSubscriptionChange(transcriptionLang !== null || localSourceLang !== null, forceLocalTranscriptionLang ?? transcriptionLang ?? localSourceLang, hasForceLocalTranscription || hasForceLocalTranslation);
4368
+ localSttFallbackCoordinator.onSubscriptionChange(transcriptionLang !== null || localSourceLang !== null, forceLocalTranscriptionLang ?? transcriptionLang ?? localSourceLang, hasForceLocalTranscription || hasForceLocalTranslation, hasFallbackTranscription || localSourceLang !== null);
4355
4369
  // Mirror the same set as typed AudioSubscription[]. When Soniox-direct is
4356
4370
  // enabled (user API key set), the DIRECT service serves the whole set and
4357
4371
  // the cloud gets an EMPTY one — pushed as a real PUT, not skipped, so
@@ -4500,12 +4514,15 @@ class LocalMiniappRuntime {
4500
4514
  return;
4501
4515
  if (!q.blocked) {
4502
4516
  this.lastSttQuotaNoticeAt = 0;
4503
- void localSttFallbackCoordinator.onSttQuotaBlockedChange(false);
4517
+ void localSttFallbackCoordinator.onSttQuotaBlockedChange(false).then(() => this.broadcastCloudStatus());
4504
4518
  this.onQuotaRestored?.("transcription");
4505
4519
  return;
4506
4520
  }
4507
4521
  console.warn(`${LOG_TAG}: cloud transcription blocked by plan quota`);
4508
4522
  void localSttFallbackCoordinator.onSttQuotaBlockedChange(true).then(() => {
4523
+ // Miniapps learn of the block through the status snapshot; the lens
4524
+ // notice below is for the wearer.
4525
+ this.broadcastCloudStatus();
4509
4526
  const localSttActive = localSttFallbackCoordinator.isActive();
4510
4527
  const now = Date.now();
4511
4528
  if (now - this.lastSttQuotaNoticeAt >= STT_QUOTA_NOTICE_DEBOUNCE_MS) {
@@ -4721,6 +4738,7 @@ class LocalMiniappRuntime {
4721
4738
  return {
4722
4739
  status: base.status,
4723
4740
  audioTransport: fallbackActive || sonioxDegraded ? "offline" : base.audioTransport,
4741
+ quotaBlocked: localSttFallbackCoordinator.isSttQuotaBlocked() ? ["transcription"] : [],
4724
4742
  };
4725
4743
  }
4726
4744
  broadcastCloudStatus() {
@@ -4967,6 +4985,7 @@ class LocalMiniappRuntime {
4967
4985
  return {
4968
4986
  cloud: app?.cloudTranscriptionStreams.has(stream) === true,
4969
4987
  forceLocal: app?.forceLocalTranscriptionStreams.has(stream) === true,
4988
+ localFallback: app?.noFallbackTranscriptionStreams.has(stream) !== true,
4970
4989
  };
4971
4990
  }
4972
4991
  appTranslationRoutesForEvent(packageName, patterns) {
@@ -4979,10 +4998,15 @@ class LocalMiniappRuntime {
4979
4998
  appTranscriptionRoutesForEvent(packageName, stream) {
4980
4999
  const app = this.connectedApps.get(packageName);
4981
5000
  const autoStream = `${MiniappStreamType.TRANSCRIPTION}:auto`;
5001
+ const cloudExact = app?.cloudTranscriptionStreams.has(stream) === true;
5002
+ const cloudAuto = app?.cloudTranscriptionStreams.has(autoStream) === true;
4982
5003
  return {
4983
- cloud: app?.cloudTranscriptionStreams.has(stream) === true || app?.cloudTranscriptionStreams.has(autoStream) === true,
5004
+ cloud: cloudExact || cloudAuto,
4984
5005
  forceLocal: app?.forceLocalTranscriptionStreams.has(stream) === true ||
4985
5006
  app?.forceLocalTranscriptionStreams.has(autoStream) === true,
5007
+ // Fallback stays accepted while any matching default subscription takes it.
5008
+ localFallback: (cloudExact && app?.noFallbackTranscriptionStreams.has(stream) !== true) ||
5009
+ (cloudAuto && app?.noFallbackTranscriptionStreams.has(autoStream) !== true),
4986
5010
  };
4987
5011
  }
4988
5012
  /**