@glassly/engine 0.4.0 → 0.4.1-beta.1138

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 (230) hide show
  1. package/build/engine.d.ts +3 -1
  2. package/build/engine.d.ts.map +1 -1
  3. package/build/engine.js +6 -4
  4. package/build/engine.js.map +1 -1
  5. package/build/facades/display.d.ts +1 -1
  6. package/build/facades/display.d.ts.map +1 -1
  7. package/build/facades/display.js +1 -1
  8. package/build/facades/display.js.map +1 -1
  9. package/build/facades/glasses.js +1 -1
  10. package/build/facades/glasses.js.map +1 -1
  11. package/build/facades/permissions.d.ts.map +1 -1
  12. package/build/facades/permissions.js +0 -2
  13. package/build/facades/permissions.js.map +1 -1
  14. package/build/facades/phoneNotifications.d.ts +7 -0
  15. package/build/facades/phoneNotifications.d.ts.map +1 -1
  16. package/build/facades/phoneNotifications.js +6 -0
  17. package/build/facades/phoneNotifications.js.map +1 -1
  18. package/build/facades/providerKeys.d.ts +1 -1
  19. package/build/facades/providerKeys.js +1 -1
  20. package/build/facades/providerKeys.js.map +1 -1
  21. package/build/facades/reports.d.ts +15 -0
  22. package/build/facades/reports.d.ts.map +1 -1
  23. package/build/facades/reports.js +37 -0
  24. package/build/facades/reports.js.map +1 -1
  25. package/build/facades/settings.js +1 -1
  26. package/build/facades/settings.js.map +1 -1
  27. package/build/generated/releaseMetadata.js +4 -4
  28. package/build/generated/releaseMetadata.js.map +1 -1
  29. package/build/index.d.ts +2 -1
  30. package/build/index.d.ts.map +1 -1
  31. package/build/index.js +1 -1
  32. package/build/index.js.map +1 -1
  33. package/build/react/useMentraLiveOta.d.ts.map +1 -1
  34. package/build/react/useMentraLiveOta.js.map +1 -1
  35. package/build/runtime/config.d.ts.map +1 -1
  36. package/build/runtime/config.js.map +1 -1
  37. package/build/services/AiTierResolution.d.ts +1 -1
  38. package/build/services/AiTierResolution.d.ts.map +1 -1
  39. package/build/services/AiTierResolution.js.map +1 -1
  40. package/build/services/AppRegistry.d.ts +12 -1
  41. package/build/services/AppRegistry.d.ts.map +1 -1
  42. package/build/services/AppRegistry.js +33 -0
  43. package/build/services/AppRegistry.js.map +1 -1
  44. package/build/services/AutomaticReportResult.d.ts.map +1 -1
  45. package/build/services/AutomaticReportResult.js.map +1 -1
  46. package/build/services/CloudClientService.d.ts +7 -5
  47. package/build/services/CloudClientService.d.ts.map +1 -1
  48. package/build/services/CloudClientService.js +17 -14
  49. package/build/services/CloudClientService.js.map +1 -1
  50. package/build/services/DisplayProcessor.d.ts.map +1 -1
  51. package/build/services/DisplayProcessor.js +2 -1
  52. package/build/services/DisplayProcessor.js.map +1 -1
  53. package/build/services/GestureDotsService.js +1 -1
  54. package/build/services/GestureDotsService.js.map +1 -1
  55. package/build/services/HotspotOtaTransport.d.ts.map +1 -1
  56. package/build/services/HotspotOtaTransport.js +0 -1
  57. package/build/services/HotspotOtaTransport.js.map +1 -1
  58. package/build/services/JSRouter.js +2 -2
  59. package/build/services/JSRouter.js.map +1 -1
  60. package/build/services/LocalLlmModelManager.d.ts.map +1 -1
  61. package/build/services/LocalLlmModelManager.js +4 -3
  62. package/build/services/LocalLlmModelManager.js.map +1 -1
  63. package/build/services/LocalLlmProvider.d.ts.map +1 -1
  64. package/build/services/LocalLlmProvider.js +5 -6
  65. package/build/services/LocalLlmProvider.js.map +1 -1
  66. package/build/services/LocalMiniappRuntime.d.ts +10 -3
  67. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  68. package/build/services/LocalMiniappRuntime.js +142 -30
  69. package/build/services/LocalMiniappRuntime.js.map +1 -1
  70. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  71. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  72. package/build/services/NativeNavigationService.d.ts.map +1 -1
  73. package/build/services/NativeNavigationService.js.map +1 -1
  74. package/build/services/NavigationHandlers.d.ts +1 -1
  75. package/build/services/NavigationHandlers.js +2 -2
  76. package/build/services/NavigationHandlers.js.map +1 -1
  77. package/build/services/NavigationService.d.ts +2 -2
  78. package/build/services/NavigationService.d.ts.map +1 -1
  79. package/build/services/NavigationService.js +11 -11
  80. package/build/services/NavigationService.js.map +1 -1
  81. package/build/services/PairingIdentity.d.ts.map +1 -1
  82. package/build/services/PairingIdentity.js.map +1 -1
  83. package/build/services/PhoneCalendarService.d.ts.map +1 -1
  84. package/build/services/PhoneCalendarService.js.map +1 -1
  85. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  86. package/build/services/PhoneNotificationsSync.js +2 -1
  87. package/build/services/PhoneNotificationsSync.js.map +1 -1
  88. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  89. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  90. package/build/services/ProviderKeyValidation.d.ts +1 -1
  91. package/build/services/ProviderKeyValidation.js +1 -1
  92. package/build/services/ProviderKeyValidation.js.map +1 -1
  93. package/build/services/STTModelManager.d.ts.map +1 -1
  94. package/build/services/STTModelManager.js +1 -6
  95. package/build/services/STTModelManager.js.map +1 -1
  96. package/build/services/SupportProfileSync.d.ts.map +1 -1
  97. package/build/services/SupportProfileSync.js +3 -0
  98. package/build/services/SupportProfileSync.js.map +1 -1
  99. package/build/services/TranscriptionRouting.d.ts +3 -0
  100. package/build/services/TranscriptionRouting.d.ts.map +1 -1
  101. package/build/services/TranscriptionRouting.js +14 -0
  102. package/build/services/TranscriptionRouting.js.map +1 -1
  103. package/build/services/UIRouter.d.ts.map +1 -1
  104. package/build/services/UIRouter.js.map +1 -1
  105. package/build/services/controllers.d.ts.map +1 -1
  106. package/build/services/controllers.js +1 -0
  107. package/build/services/controllers.js.map +1 -1
  108. package/build/services/effectiveCapabilities.js +3 -2
  109. package/build/services/effectiveCapabilities.js.map +1 -1
  110. package/build/services/gestureDotGlyphs.d.ts.map +1 -1
  111. package/build/services/gestureDotGlyphs.js.map +1 -1
  112. package/build/services/manifestActions.d.ts.map +1 -1
  113. package/build/services/manifestActions.js.map +1 -1
  114. package/build/services/neuralBand/MetaAuth.d.ts +1 -0
  115. package/build/services/neuralBand/MetaAuth.d.ts.map +1 -1
  116. package/build/services/neuralBand/MetaAuth.js +36 -8
  117. package/build/services/neuralBand/MetaAuth.js.map +1 -1
  118. package/build/services/notificationAppPayload.d.ts +14 -0
  119. package/build/services/notificationAppPayload.d.ts.map +1 -0
  120. package/build/services/notificationAppPayload.js +15 -0
  121. package/build/services/notificationAppPayload.js.map +1 -0
  122. package/build/services/notifications/miniappNotifications.d.ts +31 -0
  123. package/build/services/notifications/miniappNotifications.d.ts.map +1 -0
  124. package/build/services/notifications/miniappNotifications.js +24 -0
  125. package/build/services/notifications/miniappNotifications.js.map +1 -0
  126. package/build/services/pages/pageEligibility.d.ts +1 -2
  127. package/build/services/pages/pageEligibility.d.ts.map +1 -1
  128. package/build/services/pages/pageEligibility.js +4 -2
  129. package/build/services/pages/pageEligibility.js.map +1 -1
  130. package/build/services/settingsBridge.d.ts.map +1 -1
  131. package/build/services/settingsBridge.js +0 -2
  132. package/build/services/settingsBridge.js.map +1 -1
  133. package/build/services/uiShim.d.ts.map +1 -1
  134. package/build/services/uiShim.js +14 -0
  135. package/build/services/uiShim.js.map +1 -1
  136. package/build/stores/appVisibility.d.ts.map +1 -1
  137. package/build/stores/appVisibility.js.map +1 -1
  138. package/build/stores/gallerySync.d.ts.map +1 -1
  139. package/build/stores/gallerySync.js.map +1 -1
  140. package/build/stores/glasses.d.ts.map +1 -1
  141. package/build/stores/glasses.js +1 -0
  142. package/build/stores/glasses.js.map +1 -1
  143. package/build/stores/settings.d.ts.map +1 -1
  144. package/build/stores/settings.js +27 -28
  145. package/build/stores/settings.js.map +1 -1
  146. package/build/types/capabilities/even-realities-g1.d.ts.map +1 -1
  147. package/build/types/capabilities/even-realities-g1.js +4 -0
  148. package/build/types/capabilities/even-realities-g1.js.map +1 -1
  149. package/build/types/capabilities/nimo.d.ts.map +1 -1
  150. package/build/types/capabilities/nimo.js +21 -7
  151. package/build/types/capabilities/nimo.js.map +1 -1
  152. package/build/types/enums.d.ts +2 -1
  153. package/build/types/enums.d.ts.map +1 -1
  154. package/build/types/enums.js +1 -0
  155. package/build/types/enums.js.map +1 -1
  156. package/build/utils/display/index.d.ts +1 -0
  157. package/build/utils/display/index.d.ts.map +1 -1
  158. package/build/utils/display/index.js +2 -2
  159. package/build/utils/display/index.js.map +1 -1
  160. package/build/utils/display/profiles/index.d.ts +1 -0
  161. package/build/utils/display/profiles/index.d.ts.map +1 -1
  162. package/build/utils/display/profiles/index.js +1 -0
  163. package/build/utils/display/profiles/index.js.map +1 -1
  164. package/build/utils/display/profiles/nimo.d.ts +2 -0
  165. package/build/utils/display/profiles/nimo.d.ts.map +1 -0
  166. package/build/utils/display/profiles/nimo.js +3 -0
  167. package/build/utils/display/profiles/nimo.js.map +1 -0
  168. package/build/utils/display/scene/svgPath.js.map +1 -1
  169. package/build/utils/memory/search.d.ts.map +1 -1
  170. package/build/utils/memory/search.js +17 -7
  171. package/build/utils/memory/search.js.map +1 -1
  172. package/package.json +15 -15
  173. package/src/engine.ts +9 -7
  174. package/src/facades/display.ts +1 -1
  175. package/src/facades/glasses.ts +1 -1
  176. package/src/facades/permissions.ts +0 -2
  177. package/src/facades/phoneNotifications.ts +10 -0
  178. package/src/facades/providerKeys.ts +1 -1
  179. package/src/facades/reports.ts +41 -0
  180. package/src/facades/settings.ts +1 -1
  181. package/src/generated/releaseMetadata.ts +4 -4
  182. package/src/index.ts +2 -0
  183. package/src/react/useMentraLiveOta.ts +1 -4
  184. package/src/runtime/config.ts +1 -6
  185. package/src/services/AiTierResolution.ts +1 -1
  186. package/src/services/AppRegistry.ts +38 -1
  187. package/src/services/AutomaticReportResult.ts +1 -3
  188. package/src/services/CloudClientService.ts +17 -11
  189. package/src/services/DisplayProcessor.ts +2 -0
  190. package/src/services/GestureDotsService.ts +1 -1
  191. package/src/services/HotspotOtaTransport.ts +1 -5
  192. package/src/services/JSRouter.ts +2 -2
  193. package/src/services/LocalLlmModelManager.ts +4 -3
  194. package/src/services/LocalLlmProvider.ts +6 -7
  195. package/src/services/LocalMiniappRuntime.ts +170 -40
  196. package/src/services/LocalSttFallbackCoordinator.ts +1 -5
  197. package/src/services/NativeNavigationService.ts +1 -2
  198. package/src/services/NavigationHandlers.ts +2 -2
  199. package/src/services/NavigationService.ts +12 -11
  200. package/src/services/PairingIdentity.ts +1 -3
  201. package/src/services/PhoneCalendarService.ts +1 -3
  202. package/src/services/PhoneNotificationsSync.ts +2 -1
  203. package/src/services/PhoneStreamCoordinator.ts +1 -2
  204. package/src/services/ProviderKeyValidation.ts +1 -1
  205. package/src/services/STTModelManager.ts +1 -6
  206. package/src/services/SupportProfileSync.ts +2 -0
  207. package/src/services/TranscriptionRouting.ts +18 -0
  208. package/src/services/UIRouter.ts +3 -9
  209. package/src/services/controllers.ts +1 -0
  210. package/src/services/effectiveCapabilities.ts +3 -2
  211. package/src/services/gestureDotGlyphs.ts +10 -5
  212. package/src/services/manifestActions.ts +2 -1
  213. package/src/services/neuralBand/MetaAuth.ts +37 -8
  214. package/src/services/notificationAppPayload.ts +15 -0
  215. package/src/services/notifications/miniappNotifications.ts +53 -0
  216. package/src/services/pages/pageEligibility.ts +3 -2
  217. package/src/services/settingsBridge.ts +1 -4
  218. package/src/services/uiShim.ts +14 -0
  219. package/src/stores/appVisibility.ts +2 -5
  220. package/src/stores/gallerySync.ts +1 -7
  221. package/src/stores/glasses.ts +1 -0
  222. package/src/stores/settings.ts +27 -28
  223. package/src/types/capabilities/even-realities-g1.ts +5 -0
  224. package/src/types/capabilities/nimo.ts +23 -7
  225. package/src/types/enums.ts +1 -0
  226. package/src/utils/display/index.ts +2 -2
  227. package/src/utils/display/profiles/index.ts +2 -0
  228. package/src/utils/display/profiles/nimo.ts +2 -0
  229. package/src/utils/display/scene/svgPath.ts +1 -1
  230. package/src/utils/memory/search.ts +17 -7
@@ -165,12 +165,12 @@ class LocalLlmProvider {
165
165
  BgTimer.clearTimeout(deadline);
166
166
  }
167
167
  const elapsedMs = Date.now() - startedAt;
168
- console.log(`${LOG_TAG}: ${model.modelId} prompt=${generated.stats.numPromptTokens} out=${generated.stats.numGeneratedTokens} tokens in ${elapsedMs} ms`);
168
+ console.log(`${LOG_TAG}: ${model.modelId} prompt=${generated.stats.prefill.numTokens} out=${generated.stats.numTokens} tokens in ${elapsedMs} ms`);
169
169
  const seed = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`;
170
170
  const completion = finalizeLocalResult({
171
171
  text: generated.text,
172
- promptTokens: generated.stats.numPromptTokens,
173
- generatedTokens: generated.stats.numGeneratedTokens,
172
+ promptTokens: generated.stats.prefill.numTokens,
173
+ generatedTokens: generated.stats.numTokens,
174
174
  maxNewTokens,
175
175
  }, { jsonMode, toolsOffered: Boolean(tools), makeToolCallId: (index) => `local_${seed}_${index}` });
176
176
  return { ...completion, modelId: model.modelId };
@@ -212,11 +212,10 @@ class LocalLlmProvider {
212
212
  const tokenizerConfig = rne.llm.parseTokenizerConfig(JSON.parse(await RNFS.readFile(paths.tokenizerConfig, "utf8")));
213
213
  const template = new Template(tokenizerConfig.chatTemplate);
214
214
  const startedAt = Date.now();
215
- const createRunner = rne.wrapAsync(rne.llm.createLLMRunner);
216
- const runner = await createRunner(paths.model, paths.tokenizer, []);
215
+ const runner = await rne.llm.createLLMRunner(paths.model, paths.tokenizer, []);
217
216
  let tokenizer;
218
217
  try {
219
- const maxSeqLen = runner.getKVCacheState().maxSeqLen;
218
+ const maxSeqLen = runner.getKVCacheState().maxContextLen;
220
219
  if (!Number.isInteger(maxSeqLen) || maxSeqLen <= CONTEXT_MARGIN_TOKENS + 16) {
221
220
  throw new Error(`On-device model ${modelId} reported an invalid context size: ${maxSeqLen}`);
222
221
  }
@@ -1 +1 @@
1
- {"version":3,"file":"LocalLlmProvider.js","sourceRoot":"","sources":["../../src/services/LocalLlmProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * LocalLlmProvider — session.ai.complete served by the phone itself: an\n * ExecuTorch runner (react-native-executorch) over the Qwen3 export that\n * LocalLlmModelManager downloaded. Stateless per request like the vendor\n * providers: every call renders the whole conversation through the model's\n * chat template, resets the KV cache, and generates on ExecuTorch's worklet\n * thread so the JS thread stays free.\n *\n * The runner is loaded on the first request and kept resident while calls\n * keep coming (loading a 1–3 GB model is seconds, not milliseconds); it is\n * dropped after an idle period and whenever the selected model changes.\n * Requests are serialized — one model, one KV cache.\n *\n * react-native-executorch is imported lazily so the engine module graph\n * loads without the native runtime (bun tests, hosts without the dependency).\n */\nimport * as RNFS from \"@dr.pogodin/react-native-fs\"\nimport {Template} from \"@huggingface/jinja\"\n\nimport type {LlmCompleteRequest} from \"@glassly/cloud-protocol/llm\"\nimport {BgTimer} from \"../utils/timers\"\nimport localLlmModelManager, {type LocalLlmModelId} from \"./LocalLlmModelManager\"\nimport {\n buildTemplateMessages,\n finalizeLocalResult,\n fitPromptToContext,\n toTemplateTools,\n type LocalCompletion,\n} from \"./LocalLlmPrompt\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\n\ntype Rne = typeof import(\"react-native-executorch\")\n// The runner API lives on the `llm` namespace; derive its types from there so\n// the import stays a type-only reference (no native module at load time).\ntype Tokenizer = ReturnType<Rne[\"nlp\"][\"loadTokenizer\"]>\ntype LLMRunner = ReturnType<Rne[\"llm\"][\"createLLMRunner\"]>\ntype LLMGenerationStats = ReturnType<LLMRunner[\"generate\"]>\ntype LLMGenerationConfig = NonNullable<Parameters<LLMRunner[\"generate\"]>[1]>\n\nconst LOG_TAG = \"LOCAL_LLM\"\n\n/** Drop the resident model after this long without a request. */\nconst IDLE_UNLOAD_MS = 5 * 60_000\n/** Hard stop on one generation — the SDK request times out at 120 s anyway. */\nconst GENERATION_DEADLINE_MS = 100_000\n// One generating, one waiting. Assist's proactive insights re-request every\n// time the SDK's 60 s timeout fires while a slow on-device run is still going,\n// and an unbounded queue kept the phone generating for callers that had\n// already given up (one reporter saw 472 s runs and 15 s touch latency).\nconst MAX_PENDING_REQUESTS = 2\n// Under the SDK's 60 s request timeout: a request that waited longer has no caller.\nconst QUEUE_WAIT_LIMIT_MS = 55_000\nconst DEFAULT_MAX_NEW_TOKENS = 512\nconst MAX_NEW_TOKENS_CEILING = 1_024\n/** Reserve space for runner-added BOS/EOS tokens and context boundary bookkeeping. */\nconst CONTEXT_MARGIN_TOKENS = 96\n\ninterface LoadedModel {\n modelId: LocalLlmModelId\n runner: LLMRunner\n tokenizer: Tokenizer\n countTokens: (tokenizer: Tokenizer, prompt: string) => Promise<number>\n template: Template\n stopTokens: string[]\n maxSeqLen: number\n generate: (\n runner: LLMRunner,\n prompt: string,\n config: LLMGenerationConfig,\n stopTokens: string[],\n ) => Promise<{text: string; stats: LLMGenerationStats}>\n}\n\nexport interface LocalLlmCompleteResult extends LocalCompletion {\n modelId: LocalLlmModelId\n}\n\n/**\n * Runs on ExecuTorch's worklet runtime: `runner.generate` blocks its thread\n * until EOS, `maxNewTokens`, or `runner.stop()` from the JS thread.\n */\nfunction generateWorklet(\n runner: LLMRunner,\n prompt: string,\n config: LLMGenerationConfig,\n stopTokens: string[],\n): {text: string; stats: LLMGenerationStats} {\n \"worklet\"\n let text = \"\"\n const stats = runner.generate(prompt, config, (token: string) => {\n if (stopTokens.includes(token)) return\n text += token\n })\n return {text, stats}\n}\n\nfunction countTokensWorklet(tokenizer: Tokenizer, prompt: string): number {\n \"worklet\"\n return tokenizer.encode(prompt).length\n}\n\nclass LocalLlmProvider {\n private static instance: LocalLlmProvider\n\n private loaded: LoadedModel | null = null\n private loading: Promise<LoadedModel> | null = null\n private queue: Promise<unknown> = Promise.resolve()\n private pendingCount = 0\n private idleTimer: number | null = null\n private rne: Rne | null = null\n\n private constructor() {\n // A different model picked in Settings invalidates the resident runner.\n useSettingsStore.subscribe(\n (state) => state.settings[SETTINGS.local_llm_model.key],\n () => {\n void this.unload()\n },\n )\n }\n\n static getInstance(): LocalLlmProvider {\n if (!LocalLlmProvider.instance) LocalLlmProvider.instance = new LocalLlmProvider()\n return LocalLlmProvider.instance\n }\n\n /** Whether a runner is resident right now (diagnostics; not a readiness check). */\n isLoaded(): boolean {\n return this.loaded !== null\n }\n\n loadedModelId(): LocalLlmModelId | null {\n return this.loaded?.modelId ?? null\n }\n\n /** Serve one neutral completion on-device. Throws when the model is missing or generation fails. */\n complete(request: LlmCompleteRequest): Promise<LocalLlmCompleteResult> {\n if (this.pendingCount >= MAX_PENDING_REQUESTS) {\n return Promise.reject(\n new Error(`The on-device model is busy (${this.pendingCount} requests pending); try again shortly.`),\n )\n }\n this.pendingCount += 1\n const queuedAt = Date.now()\n const run = this.queue.then(() => {\n const waitedMs = Date.now() - queuedAt\n if (waitedMs > QUEUE_WAIT_LIMIT_MS) {\n throw new Error(`The on-device model was busy for ${Math.round(waitedMs / 1000)} s; request dropped.`)\n }\n return this.completeInner(request)\n })\n this.queue = run.catch(() => undefined)\n return run.finally(() => {\n this.pendingCount -= 1\n })\n }\n\n /** Release the resident runner (idle, model switch, memory pressure). Safe to call repeatedly. */\n async unload(): Promise<void> {\n this.clearIdleTimer()\n // Never dispose under a running generation: let the queue drain first.\n await this.queue\n const pending = this.loading\n if (pending) {\n try {\n await pending\n } catch {\n // A failed load left nothing to release.\n }\n }\n this.releaseRunner()\n }\n\n /** Synchronous dispose; callers guarantee no generation is in flight. */\n private releaseRunner(): void {\n const loaded = this.loaded\n this.loaded = null\n if (!loaded) return\n try {\n loaded.runner.dispose()\n } catch (error) {\n console.warn(`${LOG_TAG}: runner dispose failed:`, error)\n } finally {\n loaded.tokenizer.dispose()\n }\n }\n\n private async completeInner(request: LlmCompleteRequest): Promise<LocalLlmCompleteResult> {\n this.clearIdleTimer()\n // Loading and the first generation are where memory peaks; if the OS kills\n // the app in between, the marker keeps the next launch from looping on it.\n const selectedId = localLlmModelManager.selectedModelId()\n const coldModelId = this.loaded?.modelId === selectedId ? null : selectedId\n if (coldModelId) localLlmModelManager.beginColdLoad(coldModelId)\n try {\n const model = await this.ensureLoaded()\n const jsonMode = request.jsonMode === true\n const tools = toTemplateTools(request.tools)\n\n const maxNewTokens = Math.max(\n 16,\n Math.min(request.maxTokens ?? DEFAULT_MAX_NEW_TOKENS, MAX_NEW_TOKENS_CEILING, Math.floor(model.maxSeqLen / 4)),\n )\n const promptBudget = model.maxSeqLen - maxNewTokens - CONTEXT_MARGIN_TOKENS\n const {prompt, promptTokens, truncated} = await fitPromptToContext(\n buildTemplateMessages({...request, jsonMode}),\n promptBudget,\n (messages) => model.template.render({messages, tools, add_generation_prompt: true, enable_thinking: false}),\n (text) => model.countTokens(model.tokenizer, text),\n )\n console.log(\n `${LOG_TAG}: ${model.modelId} prompt=${promptTokens} budget=${promptBudget} context=${model.maxSeqLen} maxNewTokens=${maxNewTokens} truncated=${truncated}`,\n )\n\n model.runner.reset(0)\n const deadline = BgTimer.setTimeout(() => {\n console.warn(`${LOG_TAG}: generation deadline hit, stopping`)\n model.runner.stop()\n }, GENERATION_DEADLINE_MS)\n let generated: {text: string; stats: LLMGenerationStats}\n const startedAt = Date.now()\n try {\n generated = await model.generate(\n model.runner,\n prompt,\n {maxNewTokens, temperature: request.temperature ?? 0.7},\n model.stopTokens,\n )\n } catch (error) {\n console.warn(\n `${LOG_TAG}: generation failed: model=${model.modelId} prompt=${promptTokens} context=${model.maxSeqLen} maxNewTokens=${maxNewTokens}`,\n error,\n )\n throw error\n } finally {\n BgTimer.clearTimeout(deadline)\n }\n\n const elapsedMs = Date.now() - startedAt\n console.log(\n `${LOG_TAG}: ${model.modelId} prompt=${generated.stats.numPromptTokens} out=${generated.stats.numGeneratedTokens} tokens in ${elapsedMs} ms`,\n )\n\n const seed = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`\n const completion = finalizeLocalResult(\n {\n text: generated.text,\n promptTokens: generated.stats.numPromptTokens,\n generatedTokens: generated.stats.numGeneratedTokens,\n maxNewTokens,\n },\n {jsonMode, toolsOffered: Boolean(tools), makeToolCallId: (index) => `local_${seed}_${index}`},\n )\n return {...completion, modelId: model.modelId}\n } finally {\n if (coldModelId) localLlmModelManager.endColdLoad()\n this.armIdleTimer()\n }\n }\n\n private async ensureLoaded(): Promise<LoadedModel> {\n const modelId = localLlmModelManager.selectedModelId()\n if (this.loaded?.modelId === modelId) return this.loaded\n if (this.loading) return this.loading\n\n this.loading = this.load(modelId)\n .then((model) => {\n this.loaded = model\n return model\n })\n .finally(() => {\n this.loading = null\n })\n return this.loading\n }\n\n private async load(modelId: LocalLlmModelId): Promise<LoadedModel> {\n // Runs inside the request queue, so nothing is generating; unload() would\n // wait on that same queue.\n this.releaseRunner()\n const unusable = localLlmModelManager.unusableReason(modelId)\n if (unusable) throw new Error(unusable)\n if (!(await localLlmModelManager.isModelAvailable(modelId))) {\n throw new Error(`on-device model ${modelId} is not downloaded`)\n }\n const rne = await this.runtime()\n const paths = localLlmModelManager.paths(modelId)\n\n const tokenizerConfig = rne.llm.parseTokenizerConfig(JSON.parse(await RNFS.readFile(paths.tokenizerConfig, \"utf8\")))\n const template = new Template(tokenizerConfig.chatTemplate)\n\n const startedAt = Date.now()\n const createRunner = rne.wrapAsync(rne.llm.createLLMRunner)\n const runner = await createRunner(paths.model, paths.tokenizer, [])\n let tokenizer: Tokenizer | undefined\n try {\n const maxSeqLen = runner.getKVCacheState().maxSeqLen\n if (!Number.isInteger(maxSeqLen) || maxSeqLen <= CONTEXT_MARGIN_TOKENS + 16) {\n throw new Error(`On-device model ${modelId} reported an invalid context size: ${maxSeqLen}`)\n }\n tokenizer = await rne.wrapAsync(rne.nlp.loadTokenizer)(paths.tokenizer)\n console.log(`${LOG_TAG}: loaded ${modelId} (context ${maxSeqLen}) in ${Date.now() - startedAt} ms`)\n return {\n modelId,\n runner,\n tokenizer,\n countTokens: rne.wrapAsync(countTokensWorklet),\n template,\n stopTokens: [...tokenizerConfig.stopTokens],\n maxSeqLen,\n generate: rne.wrapAsync(generateWorklet),\n }\n } catch (error) {\n tokenizer?.dispose()\n runner.dispose()\n throw error\n }\n }\n\n private async runtime(): Promise<Rne> {\n if (this.rne) return this.rne\n const rne: Rne = await import(\"react-native-executorch\")\n // Software Mansion's anonymous download analytics; the host has its own telemetry.\n rne.setTelemetryEnabled(false)\n this.rne = rne\n return rne\n }\n\n private armIdleTimer(): void {\n this.clearIdleTimer()\n this.idleTimer = BgTimer.setTimeout(() => {\n this.idleTimer = null\n console.log(`${LOG_TAG}: idle, unloading ${this.loaded?.modelId ?? \"nothing\"}`)\n void this.unload()\n }, IDLE_UNLOAD_MS)\n }\n\n private clearIdleTimer(): void {\n if (this.idleTimer) {\n BgTimer.clearTimeout(this.idleTimer)\n this.idleTimer = null\n }\n }\n}\n\nconst localLlmProvider = LocalLlmProvider.getInstance()\nexport {LocalLlmProvider}\nexport default localLlmProvider\n"]}
1
+ {"version":3,"file":"LocalLlmProvider.js","sourceRoot":"","sources":["../../src/services/LocalLlmProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * LocalLlmProvider — session.ai.complete served by the phone itself: an\n * ExecuTorch runner (react-native-executorch) over the Qwen3 export that\n * LocalLlmModelManager downloaded. Stateless per request like the vendor\n * providers: every call renders the whole conversation through the model's\n * chat template, resets the KV cache, and generates on ExecuTorch's worklet\n * thread so the JS thread stays free.\n *\n * The runner is loaded on the first request and kept resident while calls\n * keep coming (loading a 1–3 GB model is seconds, not milliseconds); it is\n * dropped after an idle period and whenever the selected model changes.\n * Requests are serialized — one model, one KV cache.\n *\n * react-native-executorch is imported lazily so the engine module graph\n * loads without the native runtime (bun tests, hosts without the dependency).\n */\nimport * as RNFS from \"@dr.pogodin/react-native-fs\"\nimport {Template} from \"@huggingface/jinja\"\n\nimport type {LlmCompleteRequest} from \"@glassly/cloud-protocol/llm\"\nimport {BgTimer} from \"../utils/timers\"\nimport localLlmModelManager, {type LocalLlmModelId} from \"./LocalLlmModelManager\"\nimport {\n buildTemplateMessages,\n finalizeLocalResult,\n fitPromptToContext,\n toTemplateTools,\n type LocalCompletion,\n} from \"./LocalLlmPrompt\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\n\ntype Rne = typeof import(\"react-native-executorch\")\n// The runner API lives on the `llm` namespace; derive its types from there so\n// the import stays a type-only reference (no native module at load time).\ntype Tokenizer = ReturnType<Rne[\"nlp\"][\"loadTokenizer\"]>\ntype LLMRunner = Awaited<ReturnType<Rne[\"llm\"][\"createLLMRunner\"]>>\ntype LLMGenerationStats = ReturnType<LLMRunner[\"generate\"]>\ntype LLMGenerationConfig = NonNullable<Parameters<LLMRunner[\"generate\"]>[1]>\n\nconst LOG_TAG = \"LOCAL_LLM\"\n\n/** Drop the resident model after this long without a request. */\nconst IDLE_UNLOAD_MS = 5 * 60_000\n/** Hard stop on one generation — the SDK request times out at 120 s anyway. */\nconst GENERATION_DEADLINE_MS = 100_000\n// One generating, one waiting. Assist's proactive insights re-request every\n// time the SDK's 60 s timeout fires while a slow on-device run is still going,\n// and an unbounded queue kept the phone generating for callers that had\n// already given up (one reporter saw 472 s runs and 15 s touch latency).\nconst MAX_PENDING_REQUESTS = 2\n// Under the SDK's 60 s request timeout: a request that waited longer has no caller.\nconst QUEUE_WAIT_LIMIT_MS = 55_000\nconst DEFAULT_MAX_NEW_TOKENS = 512\nconst MAX_NEW_TOKENS_CEILING = 1_024\n/** Reserve space for runner-added BOS/EOS tokens and context boundary bookkeeping. */\nconst CONTEXT_MARGIN_TOKENS = 96\n\ninterface LoadedModel {\n modelId: LocalLlmModelId\n runner: LLMRunner\n tokenizer: Tokenizer\n countTokens: (tokenizer: Tokenizer, prompt: string) => Promise<number>\n template: Template\n stopTokens: string[]\n maxSeqLen: number\n generate: (\n runner: LLMRunner,\n prompt: string,\n config: LLMGenerationConfig,\n stopTokens: string[],\n ) => Promise<{text: string; stats: LLMGenerationStats}>\n}\n\nexport interface LocalLlmCompleteResult extends LocalCompletion {\n modelId: LocalLlmModelId\n}\n\n/**\n * Runs on ExecuTorch's worklet runtime: `runner.generate` blocks its thread\n * until EOS, `maxNewTokens`, or `runner.stop()` from the JS thread.\n */\nfunction generateWorklet(\n runner: LLMRunner,\n prompt: string,\n config: LLMGenerationConfig,\n stopTokens: string[],\n): {text: string; stats: LLMGenerationStats} {\n \"worklet\"\n let text = \"\"\n const stats = runner.generate(prompt, config, (token: string) => {\n if (stopTokens.includes(token)) return\n text += token\n })\n return {text, stats}\n}\n\nfunction countTokensWorklet(tokenizer: Tokenizer, prompt: string): number {\n \"worklet\"\n return tokenizer.encode(prompt).length\n}\n\nclass LocalLlmProvider {\n private static instance: LocalLlmProvider\n\n private loaded: LoadedModel | null = null\n private loading: Promise<LoadedModel> | null = null\n private queue: Promise<unknown> = Promise.resolve()\n private pendingCount = 0\n private idleTimer: number | null = null\n private rne: Rne | null = null\n\n private constructor() {\n // A different model picked in Settings invalidates the resident runner.\n useSettingsStore.subscribe(\n (state) => state.settings[SETTINGS.local_llm_model.key],\n () => {\n void this.unload()\n },\n )\n }\n\n static getInstance(): LocalLlmProvider {\n if (!LocalLlmProvider.instance) LocalLlmProvider.instance = new LocalLlmProvider()\n return LocalLlmProvider.instance\n }\n\n /** Whether a runner is resident right now (diagnostics; not a readiness check). */\n isLoaded(): boolean {\n return this.loaded !== null\n }\n\n loadedModelId(): LocalLlmModelId | null {\n return this.loaded?.modelId ?? null\n }\n\n /** Serve one neutral completion on-device. Throws when the model is missing or generation fails. */\n complete(request: LlmCompleteRequest): Promise<LocalLlmCompleteResult> {\n if (this.pendingCount >= MAX_PENDING_REQUESTS) {\n return Promise.reject(\n new Error(`The on-device model is busy (${this.pendingCount} requests pending); try again shortly.`),\n )\n }\n this.pendingCount += 1\n const queuedAt = Date.now()\n const run = this.queue.then(() => {\n const waitedMs = Date.now() - queuedAt\n if (waitedMs > QUEUE_WAIT_LIMIT_MS) {\n throw new Error(`The on-device model was busy for ${Math.round(waitedMs / 1000)} s; request dropped.`)\n }\n return this.completeInner(request)\n })\n this.queue = run.catch(() => undefined)\n return run.finally(() => {\n this.pendingCount -= 1\n })\n }\n\n /** Release the resident runner (idle, model switch, memory pressure). Safe to call repeatedly. */\n async unload(): Promise<void> {\n this.clearIdleTimer()\n // Never dispose under a running generation: let the queue drain first.\n await this.queue\n const pending = this.loading\n if (pending) {\n try {\n await pending\n } catch {\n // A failed load left nothing to release.\n }\n }\n this.releaseRunner()\n }\n\n /** Synchronous dispose; callers guarantee no generation is in flight. */\n private releaseRunner(): void {\n const loaded = this.loaded\n this.loaded = null\n if (!loaded) return\n try {\n loaded.runner.dispose()\n } catch (error) {\n console.warn(`${LOG_TAG}: runner dispose failed:`, error)\n } finally {\n loaded.tokenizer.dispose()\n }\n }\n\n private async completeInner(request: LlmCompleteRequest): Promise<LocalLlmCompleteResult> {\n this.clearIdleTimer()\n // Loading and the first generation are where memory peaks; if the OS kills\n // the app in between, the marker keeps the next launch from looping on it.\n const selectedId = localLlmModelManager.selectedModelId()\n const coldModelId = this.loaded?.modelId === selectedId ? null : selectedId\n if (coldModelId) localLlmModelManager.beginColdLoad(coldModelId)\n try {\n const model = await this.ensureLoaded()\n const jsonMode = request.jsonMode === true\n const tools = toTemplateTools(request.tools)\n\n const maxNewTokens = Math.max(\n 16,\n Math.min(request.maxTokens ?? DEFAULT_MAX_NEW_TOKENS, MAX_NEW_TOKENS_CEILING, Math.floor(model.maxSeqLen / 4)),\n )\n const promptBudget = model.maxSeqLen - maxNewTokens - CONTEXT_MARGIN_TOKENS\n const {prompt, promptTokens, truncated} = await fitPromptToContext(\n buildTemplateMessages({...request, jsonMode}),\n promptBudget,\n (messages) => model.template.render({messages, tools, add_generation_prompt: true, enable_thinking: false}),\n (text) => model.countTokens(model.tokenizer, text),\n )\n console.log(\n `${LOG_TAG}: ${model.modelId} prompt=${promptTokens} budget=${promptBudget} context=${model.maxSeqLen} maxNewTokens=${maxNewTokens} truncated=${truncated}`,\n )\n\n model.runner.reset(0)\n const deadline = BgTimer.setTimeout(() => {\n console.warn(`${LOG_TAG}: generation deadline hit, stopping`)\n model.runner.stop()\n }, GENERATION_DEADLINE_MS)\n let generated: {text: string; stats: LLMGenerationStats}\n const startedAt = Date.now()\n try {\n generated = await model.generate(\n model.runner,\n prompt,\n {maxNewTokens, temperature: request.temperature ?? 0.7},\n model.stopTokens,\n )\n } catch (error) {\n console.warn(\n `${LOG_TAG}: generation failed: model=${model.modelId} prompt=${promptTokens} context=${model.maxSeqLen} maxNewTokens=${maxNewTokens}`,\n error,\n )\n throw error\n } finally {\n BgTimer.clearTimeout(deadline)\n }\n\n const elapsedMs = Date.now() - startedAt\n console.log(\n `${LOG_TAG}: ${model.modelId} prompt=${generated.stats.prefill.numTokens} out=${generated.stats.numTokens} tokens in ${elapsedMs} ms`,\n )\n\n const seed = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`\n const completion = finalizeLocalResult(\n {\n text: generated.text,\n promptTokens: generated.stats.prefill.numTokens,\n generatedTokens: generated.stats.numTokens,\n maxNewTokens,\n },\n {jsonMode, toolsOffered: Boolean(tools), makeToolCallId: (index) => `local_${seed}_${index}`},\n )\n return {...completion, modelId: model.modelId}\n } finally {\n if (coldModelId) localLlmModelManager.endColdLoad()\n this.armIdleTimer()\n }\n }\n\n private async ensureLoaded(): Promise<LoadedModel> {\n const modelId = localLlmModelManager.selectedModelId()\n if (this.loaded?.modelId === modelId) return this.loaded\n if (this.loading) return this.loading\n\n this.loading = this.load(modelId)\n .then((model) => {\n this.loaded = model\n return model\n })\n .finally(() => {\n this.loading = null\n })\n return this.loading\n }\n\n private async load(modelId: LocalLlmModelId): Promise<LoadedModel> {\n // Runs inside the request queue, so nothing is generating; unload() would\n // wait on that same queue.\n this.releaseRunner()\n const unusable = localLlmModelManager.unusableReason(modelId)\n if (unusable) throw new Error(unusable)\n if (!(await localLlmModelManager.isModelAvailable(modelId))) {\n throw new Error(`on-device model ${modelId} is not downloaded`)\n }\n const rne = await this.runtime()\n const paths = localLlmModelManager.paths(modelId)\n\n const tokenizerConfig = rne.llm.parseTokenizerConfig(JSON.parse(await RNFS.readFile(paths.tokenizerConfig, \"utf8\")))\n const template = new Template(tokenizerConfig.chatTemplate)\n\n const startedAt = Date.now()\n const runner = await rne.llm.createLLMRunner(paths.model, paths.tokenizer, [])\n let tokenizer: Tokenizer | undefined\n try {\n const maxSeqLen = runner.getKVCacheState().maxContextLen\n if (!Number.isInteger(maxSeqLen) || maxSeqLen <= CONTEXT_MARGIN_TOKENS + 16) {\n throw new Error(`On-device model ${modelId} reported an invalid context size: ${maxSeqLen}`)\n }\n tokenizer = await rne.wrapAsync(rne.nlp.loadTokenizer)(paths.tokenizer)\n console.log(`${LOG_TAG}: loaded ${modelId} (context ${maxSeqLen}) in ${Date.now() - startedAt} ms`)\n return {\n modelId,\n runner,\n tokenizer,\n countTokens: rne.wrapAsync(countTokensWorklet),\n template,\n stopTokens: [...tokenizerConfig.stopTokens],\n maxSeqLen,\n generate: rne.wrapAsync(generateWorklet),\n }\n } catch (error) {\n tokenizer?.dispose()\n runner.dispose()\n throw error\n }\n }\n\n private async runtime(): Promise<Rne> {\n if (this.rne) return this.rne\n const rne: Rne = await import(\"react-native-executorch\")\n // Software Mansion's anonymous download analytics; the host has its own telemetry.\n rne.setTelemetryEnabled(false)\n this.rne = rne\n return rne\n }\n\n private armIdleTimer(): void {\n this.clearIdleTimer()\n this.idleTimer = BgTimer.setTimeout(() => {\n this.idleTimer = null\n console.log(`${LOG_TAG}: idle, unloading ${this.loaded?.modelId ?? \"nothing\"}`)\n void this.unload()\n }, IDLE_UNLOAD_MS)\n }\n\n private clearIdleTimer(): void {\n if (this.idleTimer) {\n BgTimer.clearTimeout(this.idleTimer)\n this.idleTimer = null\n }\n }\n}\n\nconst localLlmProvider = LocalLlmProvider.getInstance()\nexport {LocalLlmProvider}\nexport default localLlmProvider\n"]}
@@ -9,6 +9,7 @@
9
9
  * management (connect/disconnect/ping).
10
10
  */
11
11
  import type { MiniappLaunchSource } from "@glassly/miniapp";
12
+ import type { TranscriptionData } from "@glassly/cloud-protocol";
12
13
  import { type MiniappRuntimeDiagnosticSnapshot } from "../utils/miniappDiagnostics";
13
14
  export interface InstalledMiniappManifest {
14
15
  packageName?: string;
@@ -327,6 +328,8 @@ declare class LocalMiniappRuntime {
327
328
  private handleSettingsGet;
328
329
  private handleSettingsSet;
329
330
  private handleNotificationAppsList;
331
+ private handleNotificationPost;
332
+ private handleNotificationDismiss;
330
333
  /**
331
334
  * Push bridged settings as they change: stored keys from the store, the
332
335
  * derived keys whenever their inputs move (phone activity, the display,
@@ -466,7 +469,7 @@ declare class LocalMiniappRuntime {
466
469
  * The request names a TIER; this handler resolves it to a provider+model
467
470
  * (Settings > AI Models dropdowns, or auto from saved keys) and then picks
468
471
  * one of two transport paths, decided by whether the user saved a key for
469
- * the resolved provider (Settings > API Keys) — the phone is where both
472
+ * the resolved provider (Settings > Privacy > API Keys) — the phone is where both
470
473
  * settings live, so this is the only place the choice can be made:
471
474
  *
472
475
  * - User key saved → the phone calls the vendor DIRECTLY via
@@ -655,7 +658,7 @@ declare class LocalMiniappRuntime {
655
658
  */
656
659
  private ensurePauseWired;
657
660
  private broadcastPauseState;
658
- /** Host user preferences miniapps follow by default (Settings > Appearance). */
661
+ /** Host user preferences miniapps follow by default: the metric toggle and the phone's own clock format. */
659
662
  private currentPreferences;
660
663
  private ensurePreferencesWired;
661
664
  private currentCloudStatus;
@@ -669,7 +672,9 @@ declare class LocalMiniappRuntime {
669
672
  */
670
673
  forwardEvent(streamType: string, data: unknown, transcriptionSource?: TranscriptionEventSource,
671
674
  /** Deliver to this subscriber alone (the designated dashboard app's gestures while it shows). */
672
- only?: string): void;
675
+ only?: string,
676
+ /** Producing cloud/direct subscription; auto results also serve matching language listeners. */
677
+ transcriptionSubscription?: TranscriptionData["subscription"]): void;
673
678
  /**
674
679
  * Persist a final utterance into the shared memory timeline when the user
675
680
  * has "remember conversations" on (Settings > Memory).
@@ -732,6 +737,7 @@ declare class LocalMiniappRuntime {
732
737
  /** Project a host ClientApp into the SDK's MiniappInfo shape (JSON over the wire). */
733
738
  private buildMiniappInfo;
734
739
  private miniappIcons;
740
+ private notificationSeq;
735
741
  private handleMiniappsList;
736
742
  private handleMiniappsStart;
737
743
  /**
@@ -787,6 +793,7 @@ declare class LocalMiniappRuntime {
787
793
  private handleWidgetUpdate;
788
794
  /** A miniapp disconnected: as a host its placements go, as a provider its boxes are forgotten and its frames kept. */
789
795
  private onWidgetPartyGone;
796
+ releaseWidgetHost(hostPackageName: string): void;
790
797
  /** True iff `value` serializes larger than the action payload cap. */
791
798
  private actionPayloadTooLarge;
792
799
  /** Floored at 6s: a freshly-woken target buffers an undelivered ACTION_CALL for 5s (HANDLER_WAIT_MS in @glassly/miniapp's actions module) + 1s for the reply. Keep in sync. */
@@ -1 +1 @@
1
- {"version":3,"file":"LocalMiniappRuntime.d.ts","sourceRoot":"","sources":["../../src/services/LocalMiniappRuntime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LocalMiniappRuntime.d.ts","sourceRoot":"","sources":["../../src/services/LocalMiniappRuntime.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ import { AppState, Linking } from "react-native";
13
13
  import { logBuffer } from "../utils/devLogging";
14
14
  import { collectDisplayDiagnostics } from "./DisplayDiagnostics";
15
15
  import Share from "react-native-share";
16
+ import { uses24HourClock } from "react-native-localize";
16
17
  import * as Battery from "expo-battery";
17
18
  import * as Clipboard from "expo-clipboard";
18
19
  import { File, Paths } from "expo-file-system";
@@ -48,6 +49,7 @@ import overlayPages from "./pages/OverlayPages";
48
49
  import dashboardOpenTrace from "./debug/DashboardOpenTrace";
49
50
  import { isAppForegrounded, isPhoneActive, onAppForegroundChange, onPhoneActivityChange } from "./PhoneActivity";
50
51
  import { installedNotificationApps } from "./PhoneNotificationsSync";
52
+ import { emitMiniappNotification, MINIAPP_NOTIFICATION_CONTENT_MAX, MINIAPP_NOTIFICATION_ID_MAX, MINIAPP_NOTIFICATION_TITLE_MAX, miniappNotificationId, } from "./notifications/miniappNotifications";
51
53
  import { MiniappIcons } from "./MiniappIcons";
52
54
  import { pairedControllersFrom, readyControllersKey } from "./controllers";
53
55
  import { DERIVED_SETTINGS_KEYS, SETTINGS_BRIDGE_KEYS, controllersSettingFrom, isDerivedSettingsKey, selectSettingsBridgeKeys, validateSettingsSet, } from "./settingsBridge";
@@ -72,7 +74,7 @@ import { phonePhotoCoordinator } from "./PhonePhotoCoordinator";
72
74
  import { phoneStreamCoordinator } from "./PhoneStreamCoordinator";
73
75
  import { phoneVideoCoordinator } from "./PhoneVideoCoordinator";
74
76
  import { runSentenceTtsPipeline } from "./SentenceTtsPipeline";
75
- import { summarizeTranscriptionRoutes, transcriptionDeliveryRoute, } from "./TranscriptionRouting";
77
+ import { matchesTranscriptionSubscription, summarizeTranscriptionRoutes, transcriptionDeliveryRoute, } from "./TranscriptionRouting";
76
78
  import { prepareTtsSentences } from "./TtsTextSanitizer";
77
79
  import { handleWifiAdbRequest } from "./WifiAdbRequest";
78
80
  import { cloudClientService, setBlobNamespaceMigrator } from "./CloudClientService";
@@ -250,7 +252,7 @@ const PERMISSION_TYPE_TO_CANONICAL = {
250
252
  HOST_WIDGETS: "hostWidgets",
251
253
  };
252
254
  /**
253
- * User API keys (Settings > API Keys) a miniapp may read via
255
+ * User API keys (Settings > Privacy > API Keys) a miniapp may read via
254
256
  * session.keys.get(), mapped provider → settings-store key. Explicit
255
257
  * allowlist: the Soniox key is deliberately absent — it gates the
256
258
  * phone→Soniox direct transcription path and is not exposed to miniapps.
@@ -291,8 +293,8 @@ function directLlmProvider(name) {
291
293
  directLlmProviders.set(name, built);
292
294
  return built;
293
295
  }
294
- const QUOTA_EXCEEDED_MESSAGE = "AI credits are used up. Get more in Settings > Membership, or add your own API key in Settings > API Keys.";
295
- /** The user's saved key (Settings > API Keys) for an LLM provider, "" if none. */
296
+ const QUOTA_EXCEEDED_MESSAGE = "AI credits are used up. Get more in Settings > Membership, or add your own API key in Settings > Privacy > API Keys.";
297
+ /** The user's saved key (Settings > Privacy > API Keys) for an LLM provider, "" if none. */
296
298
  function userLlmKey(provider) {
297
299
  const raw = useSettingsStore.getState().getSetting(MINIAPP_READABLE_API_KEYS[provider]);
298
300
  return typeof raw === "string" ? raw.trim() : "";
@@ -1234,6 +1236,12 @@ class LocalMiniappRuntime {
1234
1236
  case MiniappRequestType.NOTIFICATION_APPS_LIST:
1235
1237
  void this.handleNotificationAppsList(packageName, requestId);
1236
1238
  break;
1239
+ case MiniappRequestType.NOTIFICATION_POST:
1240
+ this.handleNotificationPost(packageName, payload, requestId);
1241
+ break;
1242
+ case MiniappRequestType.NOTIFICATION_DISMISS:
1243
+ this.handleNotificationDismiss(packageName, payload, requestId);
1244
+ break;
1237
1245
  case MiniappRequestType.NATIVE_NAV:
1238
1246
  this.handleNativeNav(packageName, payload, requestId);
1239
1247
  break;
@@ -2397,7 +2405,13 @@ class LocalMiniappRuntime {
2397
2405
  return;
2398
2406
  }
2399
2407
  try {
2400
- this.sendResult(packageName, requestId, true, await installedNotificationApps());
2408
+ const posters = this.interopApps().filter((app) => app.packageName && app.permissions?.some((permission) => permission.type === "POST_NOTIFICATIONS"));
2409
+ const miniapps = await Promise.all(posters.map(async (app) => ({
2410
+ packageName: app.packageName,
2411
+ appName: app.name || app.packageName,
2412
+ icon: (await this.miniappIcons.read(app)) ?? null,
2413
+ })));
2414
+ this.sendResult(packageName, requestId, true, [...(await installedNotificationApps()), ...miniapps]);
2401
2415
  }
2402
2416
  catch (err) {
2403
2417
  this.sendResult(packageName, requestId, false, undefined, {
@@ -2406,6 +2420,58 @@ class LocalMiniappRuntime {
2406
2420
  });
2407
2421
  }
2408
2422
  }
2423
+ handleNotificationPost(packageName, payload, requestId) {
2424
+ if (!this.requirePermission(packageName, requestId, "POST_NOTIFICATIONS", "to post notifications"))
2425
+ return;
2426
+ const title = typeof payload.title === "string" ? payload.title.slice(0, MINIAPP_NOTIFICATION_TITLE_MAX) : "";
2427
+ const content = typeof payload.content === "string" ? payload.content.slice(0, MINIAPP_NOTIFICATION_CONTENT_MAX) : "";
2428
+ if (!title.trim() && !content.trim()) {
2429
+ this.sendResult(packageName, requestId, false, undefined, {
2430
+ code: MiniappErrorCode.INVALID_ARGUMENT,
2431
+ message: "A notification needs a title or content",
2432
+ });
2433
+ return;
2434
+ }
2435
+ if (payload.id !== undefined && (typeof payload.id !== "string" || !payload.id.trim())) {
2436
+ this.sendResult(packageName, requestId, false, undefined, {
2437
+ code: MiniappErrorCode.INVALID_ARGUMENT,
2438
+ message: "A notification id must be a non-empty string",
2439
+ });
2440
+ return;
2441
+ }
2442
+ const id = typeof payload.id === "string"
2443
+ ? payload.id.trim().slice(0, MINIAPP_NOTIFICATION_ID_MAX)
2444
+ : `${Date.now().toString(36)}-${++this.notificationSeq}`;
2445
+ const app = this.interopApps().find((candidate) => candidate.packageName === packageName);
2446
+ emitMiniappNotification({
2447
+ type: "posted",
2448
+ notificationId: miniappNotificationId(packageName, id),
2449
+ source: packageName,
2450
+ app: app?.name || packageName,
2451
+ title,
2452
+ content,
2453
+ timestamp: Date.now(),
2454
+ });
2455
+ this.sendResult(packageName, requestId, true, { id });
2456
+ }
2457
+ handleNotificationDismiss(packageName, payload, requestId) {
2458
+ if (!this.requirePermission(packageName, requestId, "POST_NOTIFICATIONS", "to dismiss notifications"))
2459
+ return;
2460
+ if (typeof payload.id !== "string" || !payload.id.trim()) {
2461
+ this.sendResult(packageName, requestId, false, undefined, {
2462
+ code: MiniappErrorCode.INVALID_ARGUMENT,
2463
+ message: "dismiss needs the id post() returned",
2464
+ });
2465
+ return;
2466
+ }
2467
+ emitMiniappNotification({
2468
+ type: "dismissed",
2469
+ notificationId: miniappNotificationId(packageName, payload.id.trim().slice(0, MINIAPP_NOTIFICATION_ID_MAX)),
2470
+ source: packageName,
2471
+ timestamp: Date.now(),
2472
+ });
2473
+ this.sendResult(packageName, requestId, true);
2474
+ }
2409
2475
  /**
2410
2476
  * Push bridged settings as they change: stored keys from the store, the
2411
2477
  * derived keys whenever their inputs move (phone activity, the display,
@@ -3603,7 +3669,7 @@ class LocalMiniappRuntime {
3603
3669
  }
3604
3670
  }
3605
3671
  // ---------------------------------------------------------------------------
3606
- // User API keys (Settings > API Keys)
3672
+ // User API keys (Settings > Privacy > API Keys)
3607
3673
  // ---------------------------------------------------------------------------
3608
3674
  /**
3609
3675
  * Serve session.keys.get(provider): read a user-supplied provider API key
@@ -3660,7 +3726,7 @@ class LocalMiniappRuntime {
3660
3726
  * The request names a TIER; this handler resolves it to a provider+model
3661
3727
  * (Settings > AI Models dropdowns, or auto from saved keys) and then picks
3662
3728
  * one of two transport paths, decided by whether the user saved a key for
3663
- * the resolved provider (Settings > API Keys) — the phone is where both
3729
+ * the resolved provider (Settings > Privacy > API Keys) — the phone is where both
3664
3730
  * settings live, so this is the only place the choice can be made:
3665
3731
  *
3666
3732
  * - User key saved → the phone calls the vendor DIRECTLY via
@@ -3874,7 +3940,7 @@ class LocalMiniappRuntime {
3874
3940
  this.onQuotaExceeded?.("llm");
3875
3941
  this.sendResult(packageName, requestId, false, undefined, {
3876
3942
  code: MiniappErrorCode.QUOTA_EXCEEDED,
3877
- message: "AI credits are used up. Get more in Settings > Membership, or add your own API key in Settings > API Keys.",
3943
+ message: "AI credits are used up. Get more in Settings > Membership, or add your own API key in Settings > Privacy > API Keys.",
3878
3944
  });
3879
3945
  return;
3880
3946
  }
@@ -4670,6 +4736,9 @@ class LocalMiniappRuntime {
4670
4736
  */
4671
4737
  buildCloudAudioSubscriptions(cloudStreams) {
4672
4738
  const subs = [];
4739
+ // One auto recognizer serves every transcription listener. Explicit-language
4740
+ // listeners are filtered at delivery; translations still need their own jobs.
4741
+ const hasAutoTranscription = cloudStreams.has("transcription:auto");
4673
4742
  // Union of every connected app's TRANSCRIPTION_CONFIG hints. Hints only
4674
4743
  // apply to the auto-mode TRANSCRIPTION subscription (the wire schema has
4675
4744
  // no hints field on specific-language sources — the language IS the hint
@@ -4679,6 +4748,8 @@ class LocalMiniappRuntime {
4679
4748
  for (const stream of cloudStreams) {
4680
4749
  if (stream.startsWith("transcription:")) {
4681
4750
  const lang = stream.substring("transcription:".length);
4751
+ if (hasAutoTranscription && lang !== "auto")
4752
+ continue;
4682
4753
  const source = langSource(lang);
4683
4754
  subs.push({
4684
4755
  kind: "transcription",
@@ -4803,6 +4874,11 @@ class LocalMiniappRuntime {
4803
4874
  this.onQuotaRestored?.("llm");
4804
4875
  }
4805
4876
  handleTranscriptionData(d) {
4877
+ const expectsAuto = [...(this.streamSubscribers.get("transcription:auto") ?? [])].some((packageName) => this.appTranscriptionRoutesForSubscription(packageName, "transcription:auto").cloud);
4878
+ // Subscription replacement is asynchronous. Ignore late results from the
4879
+ // old pipeline while switching between auto and language-specific jobs.
4880
+ if ((d.subscription.language.mode === "auto") !== expectsAuto)
4881
+ return;
4806
4882
  const receivedAt = Date.now();
4807
4883
  if (TRANSCRIPT_TIMING_TELEMETRY) {
4808
4884
  console.log(`${LOG_TAG}: transcript recv t=${receivedAt} provider=${d.provider} final=${d.isFinal} lang=${d.resolvedLanguage} text="${d.text.slice(0, 48)}"`);
@@ -4833,7 +4909,7 @@ class LocalMiniappRuntime {
4833
4909
  provider: d.provider,
4834
4910
  confidence: d.confidence,
4835
4911
  __hostReceivedAt: receivedAt,
4836
- }, "cloud");
4912
+ }, "cloud", undefined, d.subscription);
4837
4913
  }
4838
4914
  handleTranslationData(d) {
4839
4915
  this.forwardEvent(`translation:${d.source.language}:${d.target.language}`, {
@@ -4911,7 +4987,7 @@ class LocalMiniappRuntime {
4911
4987
  const broadcast = () => this.broadcastCapabilities();
4912
4988
  // Connection, model and firmware also decide the dashboard view's eligibility;
4913
4989
  // connected controllers add their input surfaces to `button`.
4914
- useGlassesStore.subscribe((s) => `${s.sceneCanvasWidth ?? 0}x${s.sceneCanvasHeight ?? 0}:${s.sceneVector === true}:${s.firmwareVersion}:${s.connection.state}:${s.deviceModel}:${readyControllersKey(s.controllers)}`, broadcast);
4990
+ useGlassesStore.subscribe((s) => `${s.sceneCanvasWidth ?? 0}x${s.sceneCanvasHeight ?? 0}:${s.sceneVector === true}:${s.sceneStereo === true}:${s.firmwareVersion}:${s.connection.state}:${s.deviceModel}:${readyControllersKey(s.controllers)}`, broadcast);
4915
4991
  // The debug knob flips hasNativeNavigation on custom firmware.
4916
4992
  useSettingsStore.subscribe((s) => s.getSetting(SETTINGS.cfw_native_navigation.key), broadcast);
4917
4993
  // The dashboard master switch flips the dashboard view.
@@ -4966,23 +5042,34 @@ class LocalMiniappRuntime {
4966
5042
  });
4967
5043
  }
4968
5044
  }
4969
- /** Host user preferences miniapps follow by default (Settings > Appearance). */
5045
+ /** Host user preferences miniapps follow by default: the metric toggle and the phone's own clock format. */
4970
5046
  currentPreferences() {
4971
5047
  const settings = useSettingsStore.getState();
4972
5048
  return {
4973
5049
  unitSystem: settings.getSetting(SETTINGS.metric_system.key) === true ? "metric" : "imperial",
4974
- twelveHourTime: settings.getSetting(SETTINGS.twelve_hour_time.key) === true,
5050
+ twelveHourTime: !uses24HourClock(),
4975
5051
  };
4976
5052
  }
4977
5053
  ensurePreferencesWired() {
4978
5054
  if (this.preferencesWired)
4979
5055
  return;
4980
5056
  this.preferencesWired = true;
4981
- useSettingsStore.subscribe((s) => `${s.getSetting(SETTINGS.metric_system.key) === true}:${s.getSetting(SETTINGS.twelve_hour_time.key) === true}`, () => {
5057
+ let sent = JSON.stringify(this.currentPreferences());
5058
+ const pushIfChanged = () => {
4982
5059
  const preferences = this.currentPreferences();
5060
+ const key = JSON.stringify(preferences);
5061
+ if (key === sent)
5062
+ return;
5063
+ sent = key;
4983
5064
  for (const packageName of this.handshookApps) {
4984
5065
  this.sendToMiniapp(packageName, { type: MiniappResponseType.PREFERENCES_UPDATE, preferences });
4985
5066
  }
5067
+ };
5068
+ useSettingsStore.subscribe((s) => s.getSetting(SETTINGS.metric_system.key) === true, pushIfChanged);
5069
+ // The clock format is an OS setting, so it can only have changed while the app was in the background.
5070
+ AppState.addEventListener("change", (state) => {
5071
+ if (state === "active")
5072
+ pushIfChanged();
4986
5073
  });
4987
5074
  }
4988
5075
  currentCloudStatus() {
@@ -5022,7 +5109,9 @@ class LocalMiniappRuntime {
5022
5109
  */
5023
5110
  forwardEvent(streamType, data, transcriptionSource,
5024
5111
  /** Deliver to this subscriber alone (the designated dashboard app's gestures while it shows). */
5025
- only) {
5112
+ only,
5113
+ /** Producing cloud/direct subscription; auto results also serve matching language listeners. */
5114
+ transcriptionSubscription) {
5026
5115
  // Paused miniapps (glasses disconnected) hear no streams. The resume push
5027
5116
  // lands before the reconnect's own glasses_connection event, so nothing
5028
5117
  // a resumed app needs is lost here.
@@ -5035,16 +5124,19 @@ class LocalMiniappRuntime {
5035
5124
  markTranscriptSourceRecent("local");
5036
5125
  // Translate cloud event names to miniapp protocol stream types
5037
5126
  const normalizedStream = this.normalizeStreamType(streamType);
5127
+ const transcriptionStreams = transcriptionSource === "cloud" && transcriptionSubscription
5128
+ ? [...this.streamSubscribers.keys()].filter((stream) => matchesTranscriptionSubscription(stream, normalizedStream, transcriptionSubscription))
5129
+ : undefined;
5038
5130
  // Passive memory capture happens HERE, before subscriber fan-out, so the
5039
5131
  // timeline reflects what was said around the user regardless of which
5040
5132
  // miniapps happen to be running or subscribed. (This used to live in the
5041
5133
  // Assistant miniapp, which paid an IPC round-trip per line and only
5042
5134
  // recorded while it was open.)
5043
5135
  this.captureTranscriptToMemory(normalizedStream, data);
5044
- // Collect all subscribers: exact match, plus wildcard matches for streams
5045
- // that carry a language tag. A miniapp subscribed to "transcription:auto"
5046
- // should receive any "transcription:<lang>" event (the detected language
5047
- // is conveyed in the event data, not the stream key).
5136
+ // Auto cloud/direct results serve auto listeners and listeners requesting
5137
+ // the detected language. Specific jobs serve only their own subscription.
5138
+ // Local/legacy events have no producing subscription and retain wildcard
5139
+ // matching so one on-device recognizer can serve auto and explicit listeners.
5048
5140
  //
5049
5141
  // Translation streams support cloud v3's wildcard patterns. Incoming
5050
5142
  // events are keyed `translation:<source>:<target>` and we match against
@@ -5056,12 +5148,14 @@ class LocalMiniappRuntime {
5056
5148
  // translation:auto — back-compat alias for *:*
5057
5149
  const matchedSubs = new Set();
5058
5150
  let translationPatterns = [];
5059
- const exact = this.streamSubscribers.get(normalizedStream);
5060
- if (exact)
5061
- for (const p of exact)
5062
- matchedSubs.add(p);
5151
+ for (const stream of transcriptionStreams ?? [normalizedStream]) {
5152
+ const exact = this.streamSubscribers.get(stream);
5153
+ if (exact)
5154
+ for (const p of exact)
5155
+ matchedSubs.add(p);
5156
+ }
5063
5157
  if (normalizedStream.startsWith("transcription:")) {
5064
- const autoSubs = this.streamSubscribers.get("transcription:auto");
5158
+ const autoSubs = transcriptionStreams ? undefined : this.streamSubscribers.get("transcription:auto");
5065
5159
  if (autoSubs)
5066
5160
  for (const p of autoSubs)
5067
5161
  matchedSubs.add(p);
@@ -5147,8 +5241,16 @@ class LocalMiniappRuntime {
5147
5241
  if (normalizedStream === MiniappStreamType.TOUCH_EVENT && miniappWidgetMode.isWidgetOnly(packageName))
5148
5242
  continue;
5149
5243
  let transcriptionRoute;
5244
+ let outboundStream = normalizedStream;
5150
5245
  if (normalizedStream.startsWith("transcription:") && transcriptionSource) {
5151
- const routes = this.appTranscriptionRoutesForEvent(packageName, normalizedStream);
5246
+ const cloudStreams = transcriptionStreams?.filter((stream) => this.appTranscriptionRoutesForSubscription(packageName, stream).cloud);
5247
+ const routes = cloudStreams
5248
+ ? { cloud: cloudStreams.length > 0, forceLocal: false }
5249
+ : this.appTranscriptionRoutesForEvent(packageName, normalizedStream);
5250
+ // Existing miniapp bundles dispatch explicit listeners by their BCP-47
5251
+ // subscription key, while providers detect bare codes (es vs es-ES).
5252
+ // Send one envelope per app, even when it also subscribes to auto.
5253
+ outboundStream = cloudStreams?.find((stream) => stream !== "transcription:auto") ?? normalizedStream;
5152
5254
  transcriptionRoute =
5153
5255
  transcriptionDeliveryRoute(transcriptionSource, routes, this.transcriptionPrimaryUp()) ?? undefined;
5154
5256
  if (!transcriptionRoute)
@@ -5176,7 +5278,7 @@ class LocalMiniappRuntime {
5176
5278
  }
5177
5279
  this.sendToMiniapp(packageName, {
5178
5280
  type: MiniappResponseType.EVENT,
5179
- streamType: normalizedStream,
5281
+ streamType: outboundStream,
5180
5282
  data: outboundData,
5181
5283
  ...(transcriptionRoute ? { transcriptionRoute } : {}),
5182
5284
  });
@@ -5443,6 +5545,7 @@ class LocalMiniappRuntime {
5443
5545
  };
5444
5546
  }
5445
5547
  miniappIcons = new MiniappIcons();
5548
+ notificationSeq = 0;
5446
5549
  async handleMiniappsList(packageName, payload, requestId) {
5447
5550
  if (!this.requireMiniappsPermission(packageName, requestId, "list"))
5448
5551
  return;
@@ -5714,7 +5817,12 @@ class LocalMiniappRuntime {
5714
5817
  // and an unplace racing it cannot stop the provider early. A provider the
5715
5818
  // store already runs (a wearer's launch still spawning, say) stays a
5716
5819
  // normal run; the registry alone lags that launch.
5717
- this.widgetPlacements = placeWidget(this.widgetPlacements, { hostPackageName, providerPackageName: provider, widgetId, box });
5820
+ this.widgetPlacements = placeWidget(this.widgetPlacements, {
5821
+ hostPackageName,
5822
+ providerPackageName: provider,
5823
+ widgetId,
5824
+ box,
5825
+ });
5718
5826
  miniappWidgetMode.setPlaced(provider, true);
5719
5827
  if (!app.running && !miniappRunningRegistry.has(provider))
5720
5828
  miniappWidgetMode.setWidgetOnly(provider, true);
@@ -5751,7 +5859,8 @@ class LocalMiniappRuntime {
5751
5859
  this.sendResult(hostPackageName, requestId, true);
5752
5860
  if (!had)
5753
5861
  return;
5754
- if (this.connectedApps.has(provider) && widgetHostsOf(this.widgetPlacements, provider, target.widgetId).length === 0) {
5862
+ if (this.connectedApps.has(provider) &&
5863
+ widgetHostsOf(this.widgetPlacements, provider, target.widgetId).length === 0) {
5755
5864
  this.sendWidgetCall(provider, target.widgetId, { kind: "box", box: null });
5756
5865
  }
5757
5866
  await this.settleWidgetProvider(provider);
@@ -5906,8 +6015,7 @@ class LocalMiniappRuntime {
5906
6015
  }
5907
6016
  /** A miniapp disconnected: as a host its placements go, as a provider its boxes are forgotten and its frames kept. */
5908
6017
  onWidgetPartyGone(packageName) {
5909
- const providersBefore = placedProviders(this.widgetPlacements);
5910
- this.widgetPlacements = dropWidgetHost(this.widgetPlacements, packageName);
6018
+ this.releaseWidgetHost(packageName);
5911
6019
  this.widgetPlacements = dropWidgetProvider(this.widgetPlacements, packageName);
5912
6020
  miniappWidgetMode.setPlaced(packageName, false);
5913
6021
  miniappWidgetMode.setWidgetOnly(packageName, false);
@@ -5923,8 +6031,12 @@ class LocalMiniappRuntime {
5923
6031
  });
5924
6032
  }
5925
6033
  }
6034
+ }
6035
+ releaseWidgetHost(hostPackageName) {
6036
+ const providersBefore = placedProviders(this.widgetPlacements);
6037
+ this.widgetPlacements = dropWidgetHost(this.widgetPlacements, hostPackageName);
5926
6038
  for (const provider of providersBefore) {
5927
- if (provider !== packageName)
6039
+ if (provider !== hostPackageName)
5928
6040
  void this.settleWidgetProvider(provider);
5929
6041
  }
5930
6042
  }