@elizaos/app-core 2.0.0-beta.3 → 2.0.3-beta.3

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 (1466) hide show
  1. package/agent-bridge.d.ts +27 -0
  2. package/agent-bridge.d.ts.map +1 -0
  3. package/agent-bridge.js +26 -0
  4. package/api/__tests__/sandbox-test-helpers.js +1 -1
  5. package/api/auth/audit.d.ts +1 -1
  6. package/api/auth/audit.js +1 -1
  7. package/api/auth/auth-context.d.ts +1 -1
  8. package/api/auth/auth-context.js +1 -1
  9. package/api/auth/bootstrap-token.d.ts +1 -1
  10. package/api/auth/bootstrap-token.js +2 -2
  11. package/api/auth/index.d.ts +9 -10
  12. package/api/auth/index.d.ts.map +1 -1
  13. package/api/auth/index.js +9 -10
  14. package/api/auth/passwords.js +2 -2
  15. package/api/auth/sensitive-rate-limit.d.ts +1 -4
  16. package/api/auth/sensitive-rate-limit.d.ts.map +1 -1
  17. package/api/auth/sensitive-rate-limit.js +6 -6
  18. package/api/auth/sessions.d.ts +1 -1
  19. package/api/auth/sessions.js +2 -2
  20. package/api/auth-bootstrap-routes.d.ts +7 -14
  21. package/api/auth-bootstrap-routes.d.ts.map +1 -1
  22. package/api/auth-bootstrap-routes.js +14 -27
  23. package/api/auth-pairing-routes.d.ts +17 -0
  24. package/api/auth-pairing-routes.d.ts.map +1 -0
  25. package/api/auth-pairing-routes.js +299 -0
  26. package/api/auth-session-routes.d.ts +2 -2
  27. package/api/auth-session-routes.d.ts.map +1 -1
  28. package/api/auth-session-routes.js +36 -15
  29. package/api/auth.d.ts +13 -20
  30. package/api/auth.d.ts.map +1 -1
  31. package/api/auth.js +32 -27
  32. package/api/automations-compat-routes.d.ts +1 -1
  33. package/api/automations-compat-routes.d.ts.map +1 -1
  34. package/api/automations-compat-routes.js +5 -5
  35. package/api/background-tasks-routes.d.ts +4 -0
  36. package/api/background-tasks-routes.d.ts.map +1 -0
  37. package/api/background-tasks-routes.js +63 -0
  38. package/api/catalog-routes.d.ts +1 -1
  39. package/api/catalog-routes.js +3 -3
  40. package/api/cloud-pair-route.d.ts +26 -0
  41. package/api/cloud-pair-route.d.ts.map +1 -0
  42. package/api/cloud-pair-route.js +222 -0
  43. package/api/cloud-voice-routes.d.ts +52 -0
  44. package/api/cloud-voice-routes.d.ts.map +1 -0
  45. package/api/cloud-voice-routes.js +50 -0
  46. package/api/compat-route-shared.d.ts +14 -7
  47. package/api/compat-route-shared.d.ts.map +1 -1
  48. package/api/compat-route-shared.js +27 -188
  49. package/api/credential-resolver.d.ts +2 -2
  50. package/api/credential-resolver.d.ts.map +1 -1
  51. package/api/credential-resolver.js +8 -2
  52. package/api/database-rows-compat-routes.d.ts +1 -1
  53. package/api/database-rows-compat-routes.d.ts.map +1 -1
  54. package/api/database-rows-compat-routes.js +69 -31
  55. package/api/dev-boot-history.d.ts +26 -0
  56. package/api/dev-boot-history.d.ts.map +1 -0
  57. package/api/dev-boot-history.js +69 -0
  58. package/api/dev-compat-routes.d.ts +6 -1
  59. package/api/dev-compat-routes.d.ts.map +1 -1
  60. package/api/dev-compat-routes.js +127 -4
  61. package/api/dev-console-log.d.ts +2 -2
  62. package/api/dev-console-log.d.ts.map +1 -1
  63. package/api/dev-console-log.js +8 -5
  64. package/api/dev-route-catalog.d.ts +58 -0
  65. package/api/dev-route-catalog.d.ts.map +1 -0
  66. package/api/dev-route-catalog.js +477 -0
  67. package/api/dev-stack.d.ts.map +1 -1
  68. package/api/dev-stack.js +6 -9
  69. package/api/drop-status-compat-route.d.ts +3 -0
  70. package/api/drop-status-compat-route.d.ts.map +1 -0
  71. package/api/drop-status-compat-route.js +12 -0
  72. package/api/first-run-routes.d.ts +4 -0
  73. package/api/first-run-routes.d.ts.map +1 -0
  74. package/api/first-run-routes.js +208 -0
  75. package/api/first-run-tts-route.d.ts +19 -0
  76. package/api/first-run-tts-route.d.ts.map +1 -0
  77. package/api/first-run-tts-route.js +59 -0
  78. package/api/internal-routes.d.ts +23 -0
  79. package/api/internal-routes.d.ts.map +1 -0
  80. package/api/internal-routes.js +203 -0
  81. package/api/ios-local-agent-transport.d.ts +36 -0
  82. package/api/ios-local-agent-transport.d.ts.map +1 -0
  83. package/api/ios-local-agent-transport.js +566 -0
  84. package/api/onboarding-voice-lines.d.ts +23 -0
  85. package/api/onboarding-voice-lines.d.ts.map +1 -0
  86. package/api/onboarding-voice-lines.js +8 -0
  87. package/api/perf-instrument.d.ts +43 -0
  88. package/api/perf-instrument.d.ts.map +1 -0
  89. package/api/perf-instrument.js +113 -0
  90. package/api/response.d.ts.map +1 -1
  91. package/api/response.js +14 -14
  92. package/api/runtime-mode-routes.d.ts +1 -1
  93. package/api/runtime-mode-routes.d.ts.map +1 -1
  94. package/api/runtime-mode-routes.js +2 -2
  95. package/api/secrets-inventory-routes.js +2 -2
  96. package/api/secrets-manager-routes.d.ts +1 -1
  97. package/api/secrets-manager-routes.d.ts.map +1 -1
  98. package/api/secrets-manager-routes.js +9 -10
  99. package/api/sensitive-request-routes.d.ts +2 -2
  100. package/api/sensitive-request-routes.js +5 -5
  101. package/api/server-config-filter.d.ts.map +1 -1
  102. package/api/server-config-filter.js +0 -1
  103. package/api/server-cors.d.ts.map +1 -1
  104. package/api/server-cors.js +13 -2
  105. package/api/server-first-run-helpers.d.ts +26 -0
  106. package/api/server-first-run-helpers.d.ts.map +1 -0
  107. package/api/server-first-run-helpers.js +268 -0
  108. package/api/server-security.js +1 -1
  109. package/api/server-startup.d.ts.map +1 -1
  110. package/api/server-startup.js +3 -4
  111. package/api/server-wallet-trade.js +1 -1
  112. package/api/server.d.ts +11 -11
  113. package/api/server.d.ts.map +1 -1
  114. package/api/server.js +227 -139
  115. package/api/setup-contract.d.ts +63 -0
  116. package/api/setup-contract.d.ts.map +1 -0
  117. package/api/setup-contract.js +39 -0
  118. package/api/training-benchmarks.d.ts +97 -0
  119. package/api/training-benchmarks.d.ts.map +1 -0
  120. package/api/training-benchmarks.js +329 -0
  121. package/api/workbench-compat-routes.d.ts +1 -1
  122. package/api/workbench-compat-routes.js +2 -2
  123. package/benchmark/cerebras-autowire.d.ts +28 -0
  124. package/benchmark/cerebras-autowire.d.ts.map +1 -0
  125. package/benchmark/cerebras-autowire.js +62 -0
  126. package/benchmark/lifeops-bench-handler.d.ts +36 -0
  127. package/benchmark/lifeops-bench-handler.d.ts.map +1 -1
  128. package/benchmark/lifeops-bench-handler.js +63 -1
  129. package/benchmark/lifeops-fake-backend.d.ts +39 -0
  130. package/benchmark/lifeops-fake-backend.d.ts.map +1 -1
  131. package/benchmark/lifeops-fake-backend.js +993 -21
  132. package/benchmark/mock-plugin.d.ts.map +1 -1
  133. package/benchmark/mock-plugin.js +0 -24
  134. package/benchmark/plugin.d.ts +2 -1
  135. package/benchmark/plugin.d.ts.map +1 -1
  136. package/benchmark/plugin.js +989 -68
  137. package/benchmark/replay-capture.d.ts +2 -2
  138. package/benchmark/replay-capture.d.ts.map +1 -1
  139. package/benchmark/replay-capture.js +3 -3
  140. package/benchmark/server-utils.d.ts +164 -11
  141. package/benchmark/server-utils.d.ts.map +1 -1
  142. package/benchmark/server-utils.js +625 -62
  143. package/benchmark/server.d.ts.map +1 -1
  144. package/benchmark/server.js +1962 -118
  145. package/boot-profile.d.ts +3 -0
  146. package/boot-profile.d.ts.map +1 -0
  147. package/boot-profile.js +30 -0
  148. package/browser.d.ts +23 -1
  149. package/browser.d.ts.map +1 -1
  150. package/browser.js +20 -1
  151. package/cli/argv.js +1 -1
  152. package/cli/banner.js +1 -1
  153. package/cli/command-format.js +2 -2
  154. package/cli/doctor/checks.d.ts.map +1 -1
  155. package/cli/doctor/checks.js +6 -6
  156. package/cli/plugins-cli.d.ts.map +1 -1
  157. package/cli/plugins-cli.js +82 -32
  158. package/cli/profile.d.ts.map +1 -1
  159. package/cli/profile.js +5 -4
  160. package/cli/program/build-program.js +4 -4
  161. package/cli/program/command-registry.d.ts.map +1 -1
  162. package/cli/program/command-registry.js +13 -11
  163. package/cli/program/help.js +5 -5
  164. package/cli/program/preaction.js +5 -5
  165. package/cli/program/register.auth.d.ts +27 -1
  166. package/cli/program/register.auth.d.ts.map +1 -1
  167. package/cli/program/register.auth.js +193 -12
  168. package/cli/program/register.capability-router.d.ts +29 -0
  169. package/cli/program/register.capability-router.d.ts.map +1 -0
  170. package/cli/program/register.capability-router.js +568 -0
  171. package/cli/program/register.config.js +1 -1
  172. package/cli/program/register.configure.d.ts.map +1 -1
  173. package/cli/program/register.configure.js +1 -1
  174. package/cli/program/register.dashboard.d.ts.map +1 -1
  175. package/cli/program/register.dashboard.js +17 -8
  176. package/cli/program/register.db.d.ts.map +1 -1
  177. package/cli/program/register.db.js +3 -4
  178. package/cli/program/register.doctor.js +7 -7
  179. package/cli/program/register.setup.d.ts.map +1 -1
  180. package/cli/program/register.setup.js +14 -10
  181. package/cli/program/register.start.d.ts.map +1 -1
  182. package/cli/program/register.start.js +5 -3
  183. package/cli/program/register.subclis.js +3 -3
  184. package/cli/program/register.update.d.ts +6 -0
  185. package/cli/program/register.update.d.ts.map +1 -1
  186. package/cli/program/register.update.js +58 -6
  187. package/cli/program.d.ts +1 -1
  188. package/cli/program.js +1 -1
  189. package/cli/run-main.js +4 -4
  190. package/config/app-config.d.ts +2 -0
  191. package/config/app-config.d.ts.map +1 -0
  192. package/config/app-config.js +1 -0
  193. package/connectors/capacitor-jsc.d.ts.map +1 -1
  194. package/connectors/capacitor-jsc.js +16 -10
  195. package/connectors/capacitor-quickjs.d.ts.map +1 -1
  196. package/connectors/capacitor-quickjs.js +18 -13
  197. package/connectors/capacitor-sqlite.d.ts.map +1 -1
  198. package/connectors/capacitor-sqlite.js +27 -12
  199. package/dispatch/approval-queue.d.ts +37 -0
  200. package/dispatch/approval-queue.d.ts.map +1 -0
  201. package/dispatch/approval-queue.js +25 -0
  202. package/dispatch/channel-registry.d.ts +30 -0
  203. package/dispatch/channel-registry.d.ts.map +1 -0
  204. package/dispatch/channel-registry.js +22 -0
  205. package/dispatch/connector-registry.d.ts +39 -0
  206. package/dispatch/connector-registry.d.ts.map +1 -0
  207. package/dispatch/connector-registry.js +24 -0
  208. package/dispatch/index.d.ts +14 -0
  209. package/dispatch/index.d.ts.map +1 -0
  210. package/dispatch/index.js +13 -0
  211. package/dispatch/send-policy.d.ts +36 -0
  212. package/dispatch/send-policy.d.ts.map +1 -0
  213. package/dispatch/send-policy.js +16 -0
  214. package/entry.js +28 -11
  215. package/first-run/first-run-config.d.ts +55 -0
  216. package/first-run/first-run-config.d.ts.map +1 -0
  217. package/first-run/first-run-config.js +178 -0
  218. package/first-run/runtime-target.d.ts +4 -0
  219. package/first-run/runtime-target.d.ts.map +1 -0
  220. package/first-run/runtime-target.js +13 -0
  221. package/index.d.ts +46 -34
  222. package/index.d.ts.map +1 -1
  223. package/index.js +53 -33
  224. package/package.json +166 -51
  225. package/packaging/PUBLISHING_GUIDE.md +20 -20
  226. package/packaging/debian/apt-repo-config/README.md +18 -0
  227. package/packaging/debian/apt-repo-config/conf/distributions +11 -0
  228. package/packaging/flatpak/README.md +26 -16
  229. package/packaging/flatpak/ai.elizaos.App.metainfo.xml +17 -12
  230. package/packaging/flatpak/ai.elizaos.App.store.yml +5 -5
  231. package/packaging/flatpak/ai.elizaos.App.yml +10 -24
  232. package/packaging/flatpak/elizaos-app-wrapper.store.sh +2 -2
  233. package/packaging/flatpak/generate-sources.sh +74 -0
  234. package/packaging/flatpak/node-sources.json +7930 -0
  235. package/packaging/inno/build-inno.ps1 +34 -9
  236. package/packaging/msix/AppxManifest.store.xml +1 -1
  237. package/packaging/msix/README.md +39 -19
  238. package/packaging/msix/build-msix.ps1 +44 -14
  239. package/packaging/snap/snapcraft.yaml +22 -21
  240. package/packaging/test-packaging.sh +2 -2
  241. package/permissions/types.d.ts +1 -1
  242. package/permissions/types.js +1 -1
  243. package/platform/elizaos-agent-browser-stub.d.ts +143 -0
  244. package/platform/elizaos-agent-browser-stub.d.ts.map +1 -0
  245. package/platform/elizaos-agent-browser-stub.js +157 -0
  246. package/platform/elizaos-plugin-elizacloud-browser-stub.d.ts +34 -0
  247. package/platform/elizaos-plugin-elizacloud-browser-stub.d.ts.map +1 -0
  248. package/platform/elizaos-plugin-elizacloud-browser-stub.js +51 -0
  249. package/platform/empty-node-module.d.ts +148 -0
  250. package/platform/empty-node-module.d.ts.map +1 -1
  251. package/platform/empty-node-module.js +140 -3
  252. package/platform/ios-runtime-backends.d.ts +83 -0
  253. package/platform/ios-runtime-backends.d.ts.map +1 -0
  254. package/platform/ios-runtime-backends.js +133 -0
  255. package/platform/ios-runtime-bridge.d.ts +15 -0
  256. package/platform/ios-runtime-bridge.d.ts.map +1 -0
  257. package/platform/ios-runtime-bridge.js +526 -0
  258. package/platform/native-library-policy.d.ts +23 -0
  259. package/platform/native-library-policy.d.ts.map +1 -0
  260. package/platform/native-library-policy.js +112 -0
  261. package/platform/native-plugin-entrypoints.d.ts +19 -0
  262. package/platform/native-plugin-entrypoints.d.ts.map +1 -0
  263. package/platform/native-plugin-entrypoints.js +29 -0
  264. package/platforms/android/README.md +68 -10
  265. package/platforms/android/app/build.gradle +291 -3
  266. package/platforms/android/app/capacitor.build.gradle +18 -1
  267. package/platforms/android/app/proguard-rules.pro +17 -2
  268. package/platforms/android/app/src/androidTest/java/ai/elizaos/app/ElizaOsInstrumentedTest.java +1 -1
  269. package/platforms/android/app/src/main/AndroidManifest.xml +335 -18
  270. package/platforms/android/app/src/main/assets/runners/eliza-tasks.js +177 -0
  271. package/platforms/android/app/src/main/elizavoice-jni/CMakeLists.txt +100 -0
  272. package/platforms/android/app/src/main/elizavoice-jni/elizavoice-jni.cpp +1629 -0
  273. package/platforms/android/app/src/main/java/ai/elizaos/app/AgentPlugin.java +111 -171
  274. package/platforms/android/app/src/main/java/ai/elizaos/app/AndroidVirtualizationBridge.java +284 -0
  275. package/platforms/android/app/src/main/java/ai/elizaos/app/BatteryOptimizationPlugin.java +95 -0
  276. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAccessibilityService.java +55 -0
  277. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAgentService.java +1283 -141
  278. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAndroidSystemBridge.java +83 -0
  279. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAssistActivity.java +50 -1
  280. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBionicInferenceServer.java +740 -0
  281. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBootReceiver.java +90 -8
  282. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBrowserActivity.java +2 -2
  283. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaCalendarActivity.java +1 -1
  284. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaCameraActivity.java +1 -1
  285. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaClockActivity.java +2 -2
  286. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaContactsActivity.java +1 -1
  287. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaDialActivity.java +1 -1
  288. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaInCallService.java +1 -1
  289. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaMmsReceiver.java +1 -1
  290. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaNativeBridge.java +22 -0
  291. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaNotificationListenerService.java +45 -0
  292. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaQuickActionsWidgetProvider.java +68 -0
  293. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaShareActivity.java +132 -0
  294. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsComposeActivity.java +1 -1
  295. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsGatewayService.java +268 -0
  296. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsReceiver.java +12 -1
  297. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaTasksWorker.java +194 -0
  298. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoiceCaptureService.java +198 -0
  299. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoiceNative.java +255 -0
  300. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoicePlugin.java +505 -0
  301. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoiceTileService.java +39 -0
  302. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaWorkScheduler.java +60 -0
  303. package/platforms/android/app/src/main/java/ai/elizaos/app/GatewayConnectionService.java +53 -19
  304. package/platforms/android/app/src/main/java/ai/elizaos/app/MainActivity.java +160 -33
  305. package/platforms/android/app/src/main/java/ai/elizaos/app/ResourceProbePlugin.java +169 -0
  306. package/platforms/android/app/src/main/java/ai/elizaos/app/VoiceCapturePlugin.java +119 -0
  307. package/platforms/android/app/src/main/res/drawable/eliza_widget_background.xml +10 -0
  308. package/platforms/android/app/src/main/res/drawable/eliza_widget_button_background.xml +13 -0
  309. package/platforms/android/app/src/main/res/drawable/splash.png +0 -0
  310. package/platforms/android/app/src/main/res/drawable-land-hdpi/splash.png +0 -0
  311. package/platforms/android/app/src/main/res/drawable-land-mdpi/splash.png +0 -0
  312. package/platforms/android/app/src/main/res/drawable-land-xhdpi/splash.png +0 -0
  313. package/platforms/android/app/src/main/res/drawable-land-xxhdpi/splash.png +0 -0
  314. package/platforms/android/app/src/main/res/drawable-land-xxxhdpi/splash.png +0 -0
  315. package/platforms/android/app/src/main/res/drawable-port-hdpi/splash.png +0 -0
  316. package/platforms/android/app/src/main/res/drawable-port-mdpi/splash.png +0 -0
  317. package/platforms/android/app/src/main/res/drawable-port-xhdpi/splash.png +0 -0
  318. package/platforms/android/app/src/main/res/drawable-port-xxhdpi/splash.png +0 -0
  319. package/platforms/android/app/src/main/res/drawable-port-xxxhdpi/splash.png +0 -0
  320. package/platforms/android/app/src/main/res/layout/eliza_quick_actions_widget.xml +86 -0
  321. package/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +2 -1
  322. package/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +2 -1
  323. package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  324. package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  325. package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png +0 -0
  326. package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  327. package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  328. package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  329. package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png +0 -0
  330. package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  331. package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  332. package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  333. package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png +0 -0
  334. package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  335. package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  336. package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  337. package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png +0 -0
  338. package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  339. package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  340. package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  341. package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png +0 -0
  342. package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  343. package/platforms/android/app/src/main/res/values/android_app_actions.xml +48 -0
  344. package/platforms/android/app/src/main/res/values/colors.xml +12 -0
  345. package/platforms/android/app/src/main/res/values/ic_launcher_background.xml +2 -2
  346. package/platforms/android/app/src/main/res/values/strings.xml +2 -2
  347. package/platforms/android/app/src/main/res/values/styles.xml +28 -1
  348. package/platforms/android/app/src/main/res/xml/eliza_accessibility_service.xml +9 -0
  349. package/platforms/android/app/src/main/res/xml/eliza_quick_actions_widget.xml +13 -0
  350. package/platforms/android/app/src/main/res/xml/shortcuts.xml +121 -0
  351. package/platforms/android/build.gradle +2 -2
  352. package/platforms/android/capacitor-cordova-android-plugins/build.gradle +9 -3
  353. package/platforms/android/capacitor-cordova-android-plugins/cordova.variables.gradle +6 -2
  354. package/platforms/android/capacitor-cordova-android-plugins/src/main/AndroidManifest.xml +7 -2
  355. package/platforms/android/capacitor-cordova-android-plugins/src/main/java/.gitkeep +0 -1
  356. package/platforms/android/capacitor.settings.gradle +66 -16
  357. package/platforms/android/gradle.properties +1 -0
  358. package/platforms/android/update-manifest/generate-manifest.mjs +97 -0
  359. package/platforms/android/update-manifest/schema.json +26 -0
  360. package/platforms/apple-store-entitlements.reviewed.json +155 -0
  361. package/platforms/electrobun/.generated/brand-config.json +3 -2
  362. package/platforms/electrobun/LICENSE +21 -0
  363. package/platforms/electrobun/README.md +15 -1
  364. package/platforms/electrobun/assets/appIcon.icns +0 -0
  365. package/platforms/electrobun/assets/appIcon.ico +0 -0
  366. package/platforms/electrobun/assets/appIcon.iconset/icon_128x128.png +0 -0
  367. package/platforms/electrobun/assets/appIcon.iconset/icon_128x128@2x.png +0 -0
  368. package/platforms/electrobun/assets/appIcon.iconset/icon_16x16.png +0 -0
  369. package/platforms/electrobun/assets/appIcon.iconset/icon_16x16@2x.png +0 -0
  370. package/platforms/electrobun/assets/appIcon.iconset/icon_256x256.png +0 -0
  371. package/platforms/electrobun/assets/appIcon.iconset/icon_256x256@2x.png +0 -0
  372. package/platforms/electrobun/assets/appIcon.iconset/icon_32x32.png +0 -0
  373. package/platforms/electrobun/assets/appIcon.iconset/icon_32x32@2x.png +0 -0
  374. package/platforms/electrobun/assets/appIcon.iconset/icon_512x512.png +0 -0
  375. package/platforms/electrobun/assets/brand-config.json +6 -6
  376. package/platforms/electrobun/biome.json +9 -9
  377. package/platforms/electrobun/docs/capability-collapse-matrix.json +318 -0
  378. package/platforms/electrobun/docs/capability-collapse-matrix.md +129 -0
  379. package/platforms/electrobun/docs/capability-routing.md +86 -0
  380. package/platforms/electrobun/docs/database-boot-policy.md +90 -0
  381. package/platforms/electrobun/docs/riscv64-port.md +175 -0
  382. package/platforms/electrobun/docs/startup-first-run-cleanup.md +18 -0
  383. package/platforms/electrobun/docs/trace-first-annotations.md +52 -0
  384. package/platforms/electrobun/docs/ui-boundary-audit.json +580 -0
  385. package/platforms/electrobun/docs/ui-boundary-audit.md +257 -0
  386. package/platforms/electrobun/electrobun.config.ts +591 -364
  387. package/platforms/electrobun/entitlements/JUSTIFICATIONS.md +141 -0
  388. package/platforms/electrobun/entitlements/README.md +34 -6
  389. package/platforms/electrobun/entitlements/mas-bun.entitlements +15 -0
  390. package/platforms/electrobun/entitlements/mas.entitlements +6 -4
  391. package/platforms/electrobun/native/macos/window-effects.mm +1526 -0
  392. package/platforms/electrobun/package.json +21 -13
  393. package/platforms/electrobun/remotes/fs/README.md +70 -0
  394. package/platforms/electrobun/remotes/fs/electrobun.config.ts +38 -0
  395. package/platforms/electrobun/remotes/fs/package.json +12 -0
  396. package/platforms/electrobun/remotes/fs/plugin.json +25 -0
  397. package/platforms/electrobun/remotes/fs/src/bun/errors.ts +57 -0
  398. package/platforms/electrobun/remotes/fs/src/bun/file-limits.ts +50 -0
  399. package/platforms/electrobun/remotes/fs/src/bun/fs-service.ts +389 -0
  400. package/platforms/electrobun/remotes/fs/src/bun/path-guard.ts +270 -0
  401. package/platforms/electrobun/remotes/fs/src/bun/protocol.ts +149 -0
  402. package/platforms/electrobun/remotes/fs/src/bun/worker.ts +174 -0
  403. package/platforms/electrobun/remotes/fs/src/dev/phase5-smoke.ts +171 -0
  404. package/platforms/electrobun/remotes/fs/src/web/index.html +8 -0
  405. package/platforms/electrobun/remotes/git/README.md +75 -0
  406. package/platforms/electrobun/remotes/git/electrobun.config.ts +44 -0
  407. package/platforms/electrobun/remotes/git/package.json +12 -0
  408. package/platforms/electrobun/remotes/git/plugin.json +31 -0
  409. package/platforms/electrobun/remotes/git/src/bun/errors.ts +69 -0
  410. package/platforms/electrobun/remotes/git/src/bun/git-command.ts +156 -0
  411. package/platforms/electrobun/remotes/git/src/bun/git-service.ts +446 -0
  412. package/platforms/electrobun/remotes/git/src/bun/operation-history.ts +124 -0
  413. package/platforms/electrobun/remotes/git/src/bun/protocol.ts +252 -0
  414. package/platforms/electrobun/remotes/git/src/bun/worker.ts +316 -0
  415. package/platforms/electrobun/remotes/git/src/dev/phase7-smoke.ts +141 -0
  416. package/platforms/electrobun/remotes/git/src/web/index.html +8 -0
  417. package/platforms/electrobun/remotes/local-model/README.md +138 -0
  418. package/platforms/electrobun/remotes/local-model/electrobun.config.ts +46 -0
  419. package/platforms/electrobun/remotes/local-model/package.json +12 -0
  420. package/platforms/electrobun/remotes/local-model/plugin.json +33 -0
  421. package/platforms/electrobun/remotes/local-model/src/bun/download-state.ts +115 -0
  422. package/platforms/electrobun/remotes/local-model/src/bun/eliza1-catalog.ts +405 -0
  423. package/platforms/electrobun/remotes/local-model/src/bun/errors.ts +74 -0
  424. package/platforms/electrobun/remotes/local-model/src/bun/hf-eliza1-client.ts +169 -0
  425. package/platforms/electrobun/remotes/local-model/src/bun/local-inference-api-client.ts +245 -0
  426. package/platforms/electrobun/remotes/local-model/src/bun/model-service.ts +490 -0
  427. package/platforms/electrobun/remotes/local-model/src/bun/protocol.ts +301 -0
  428. package/platforms/electrobun/remotes/local-model/src/bun/worker.ts +248 -0
  429. package/platforms/electrobun/remotes/local-model/src/dev/phase8-smoke.ts +116 -0
  430. package/platforms/electrobun/remotes/local-model/src/web/index.html +13 -0
  431. package/platforms/electrobun/remotes/pty/README.md +65 -0
  432. package/platforms/electrobun/remotes/pty/electrobun.config.ts +47 -0
  433. package/platforms/electrobun/remotes/pty/package.json +12 -0
  434. package/platforms/electrobun/remotes/pty/plugin.json +34 -0
  435. package/platforms/electrobun/remotes/pty/src/bun/errors.ts +57 -0
  436. package/platforms/electrobun/remotes/pty/src/bun/output-buffer.ts +127 -0
  437. package/platforms/electrobun/remotes/pty/src/bun/protocol.ts +192 -0
  438. package/platforms/electrobun/remotes/pty/src/bun/pty-service.ts +562 -0
  439. package/platforms/electrobun/remotes/pty/src/bun/worker.ts +218 -0
  440. package/platforms/electrobun/remotes/pty/src/dev/phase6-smoke.ts +127 -0
  441. package/platforms/electrobun/remotes/pty/src/web/index.html +8 -0
  442. package/platforms/electrobun/remotes/runtime/README.md +370 -0
  443. package/platforms/electrobun/remotes/runtime/electrobun.config.ts +48 -0
  444. package/platforms/electrobun/remotes/runtime/package.json +14 -0
  445. package/platforms/electrobun/remotes/runtime/plugin.json +30 -0
  446. package/platforms/electrobun/remotes/runtime/src/bun/api-client.ts +620 -0
  447. package/platforms/electrobun/remotes/runtime/src/bun/errors.ts +45 -0
  448. package/platforms/electrobun/remotes/runtime/src/bun/log-buffer.ts +33 -0
  449. package/platforms/electrobun/remotes/runtime/src/bun/protocol.ts +366 -0
  450. package/platforms/electrobun/remotes/runtime/src/bun/route-discovery.ts +419 -0
  451. package/platforms/electrobun/remotes/runtime/src/bun/runtime-manager.ts +423 -0
  452. package/platforms/electrobun/remotes/runtime/src/bun/sse-parser.ts +99 -0
  453. package/platforms/electrobun/remotes/runtime/src/bun/stream-manager.ts +887 -0
  454. package/platforms/electrobun/remotes/runtime/src/bun/worker.ts +1231 -0
  455. package/platforms/electrobun/remotes/runtime/src/dev/phase1-smoke.ts +34 -0
  456. package/platforms/electrobun/remotes/runtime/src/dev/phase2-smoke.ts +91 -0
  457. package/platforms/electrobun/remotes/runtime/src/dev/phase3-smoke.ts +137 -0
  458. package/platforms/electrobun/remotes/runtime/src/web/index.css +187 -0
  459. package/platforms/electrobun/remotes/runtime/src/web/index.html +76 -0
  460. package/platforms/electrobun/remotes/runtime/src/web/index.ts +192 -0
  461. package/platforms/electrobun/remotes/surface/README.md +201 -0
  462. package/platforms/electrobun/remotes/surface/electrobun.config.ts +38 -0
  463. package/platforms/electrobun/remotes/surface/package.json +12 -0
  464. package/platforms/electrobun/remotes/surface/plugin.json +28 -0
  465. package/platforms/electrobun/remotes/surface/src/bun/worker.ts +132 -0
  466. package/platforms/electrobun/remotes/surface/src/dev/phase4-smoke.ts +566 -0
  467. package/platforms/electrobun/remotes/surface/src/protocol/event-types.ts +84 -0
  468. package/platforms/electrobun/remotes/surface/src/protocol/runtime-client.ts +673 -0
  469. package/platforms/electrobun/remotes/surface/src/web/app.ts +595 -0
  470. package/platforms/electrobun/remotes/surface/src/web/index.css +460 -0
  471. package/platforms/electrobun/remotes/surface/src/web/index.html +466 -0
  472. package/platforms/electrobun/remotes/surface/src/web/index.ts +5 -0
  473. package/platforms/electrobun/remotes/surface/src/web/render.ts +455 -0
  474. package/platforms/electrobun/remotes/surface/src/web/state.ts +427 -0
  475. package/platforms/electrobun/scripts/build-macos-effects.sh +4 -0
  476. package/platforms/electrobun/scripts/ensure-build-folder.ts +28 -0
  477. package/platforms/electrobun/scripts/local-adhoc-sign-macos.ts +159 -159
  478. package/platforms/electrobun/scripts/postwrap-diagnostics.ts +424 -339
  479. package/platforms/electrobun/scripts/postwrap-sign-runtime-macos.ts +302 -271
  480. package/platforms/electrobun/scripts/smoke-test-windows.ps1 +17 -16
  481. package/platforms/electrobun/scripts/smoke-test.sh +5 -7
  482. package/platforms/electrobun/scripts/sync-web-assets.mjs +13 -13
  483. package/platforms/electrobun/scripts/verify-rpc-handlers.ts +109 -110
  484. package/platforms/electrobun/scripts/verify-windows-installer-proof.ps1 +3 -8
  485. package/platforms/electrobun/src/__stubs__/bun-ffi.ts +31 -31
  486. package/platforms/electrobun/src/__stubs__/electrobun-bun.ts +1 -1
  487. package/platforms/electrobun/src/agent-ready-state.ts +8 -8
  488. package/platforms/electrobun/src/agent-reset-from-main.test.ts +162 -0
  489. package/platforms/electrobun/src/agent-reset-from-main.ts +62 -62
  490. package/platforms/electrobun/src/agent-status-rpc.test.ts +95 -0
  491. package/platforms/electrobun/src/agent-status-rpc.ts +156 -0
  492. package/platforms/electrobun/src/api-base.test.ts +247 -0
  493. package/platforms/electrobun/src/api-base.ts +202 -93
  494. package/platforms/electrobun/src/application-menu-action-registry.ts +9 -9
  495. package/platforms/electrobun/src/application-menu.ts +341 -348
  496. package/platforms/electrobun/src/background-notice.ts +36 -36
  497. package/platforms/electrobun/src/boot-progress.test.ts +188 -0
  498. package/platforms/electrobun/src/boot-progress.ts +111 -0
  499. package/platforms/electrobun/src/brand-config.test.ts +39 -0
  500. package/platforms/electrobun/src/brand-config.ts +141 -129
  501. package/platforms/electrobun/src/bridge/browser-tabs-renderer-registry.ts +28 -28
  502. package/platforms/electrobun/src/bridge/electrobun-boot-config.ts +42 -0
  503. package/platforms/electrobun/src/bridge/electrobun-crypto-ready.ts +120 -0
  504. package/platforms/electrobun/src/bridge/electrobun-direct-rpc.ts +342 -357
  505. package/platforms/electrobun/src/bridge/electrobun-stub.ts +13 -13
  506. package/platforms/electrobun/src/browser-workspace-bridge-server.ts +285 -243
  507. package/platforms/electrobun/src/cloud-auth-window.ts +136 -136
  508. package/platforms/electrobun/src/cloud-disconnect-from-main.ts +90 -90
  509. package/platforms/electrobun/src/config-and-auth-rpc.test.ts +256 -0
  510. package/platforms/electrobun/src/config-and-auth-rpc.ts +302 -0
  511. package/platforms/electrobun/src/conversations-and-character-rpc.test.ts +185 -0
  512. package/platforms/electrobun/src/conversations-and-character-rpc.ts +131 -0
  513. package/platforms/electrobun/src/dashboard-rpc.test.ts +200 -0
  514. package/platforms/electrobun/src/dashboard-rpc.ts +344 -0
  515. package/platforms/electrobun/src/database/database-lock.ts +141 -0
  516. package/platforms/electrobun/src/database/database-mode.ts +149 -0
  517. package/platforms/electrobun/src/database/database-recovery.ts +72 -0
  518. package/platforms/electrobun/src/database/database-snapshot.ts +190 -0
  519. package/platforms/electrobun/src/database/database.test.ts +196 -0
  520. package/platforms/electrobun/src/database/index.ts +5 -0
  521. package/platforms/electrobun/src/database/pglite-paths.ts +100 -0
  522. package/platforms/electrobun/src/desktop-deep-link-events.test.ts +30 -0
  523. package/platforms/electrobun/src/desktop-deep-link-events.ts +17 -0
  524. package/platforms/electrobun/src/desktop-http-request.test.ts +102 -73
  525. package/platforms/electrobun/src/desktop-http-request.ts +97 -85
  526. package/platforms/electrobun/src/desktop-pill-config.test.ts +27 -0
  527. package/platforms/electrobun/src/desktop-pill-config.ts +40 -0
  528. package/platforms/electrobun/src/desktop-test-bridge-server.ts +232 -204
  529. package/platforms/electrobun/src/desktop-tray-config.test.ts +87 -0
  530. package/platforms/electrobun/src/desktop-tray-config.ts +84 -0
  531. package/platforms/electrobun/src/devtools-layout.ts +41 -41
  532. package/platforms/electrobun/src/diagnostic-format.test.ts +71 -0
  533. package/platforms/electrobun/src/diagnostic-format.ts +75 -36
  534. package/platforms/electrobun/src/dynamic-view-rpc-schema.test.ts +37 -0
  535. package/platforms/electrobun/src/dynamic-views/README.md +44 -0
  536. package/platforms/electrobun/src/dynamic-views/demo/agent-run-trace.html +135 -0
  537. package/platforms/electrobun/src/dynamic-views/errors.ts +29 -0
  538. package/platforms/electrobun/src/dynamic-views/host.test.ts +353 -0
  539. package/platforms/electrobun/src/dynamic-views/host.ts +332 -0
  540. package/platforms/electrobun/src/dynamic-views/index.ts +57 -0
  541. package/platforms/electrobun/src/dynamic-views/kiosk-canvas.ts +89 -0
  542. package/platforms/electrobun/src/dynamic-views/registry.test.ts +139 -0
  543. package/platforms/electrobun/src/dynamic-views/registry.ts +196 -0
  544. package/platforms/electrobun/src/dynamic-views/session-manager.test.ts +355 -0
  545. package/platforms/electrobun/src/dynamic-views/session-manager.ts +348 -0
  546. package/platforms/electrobun/src/dynamic-views/types.ts +105 -0
  547. package/platforms/electrobun/src/electrobun-boot-config.test.ts +50 -0
  548. package/platforms/electrobun/src/electrobun-config.test.ts +62 -0
  549. package/platforms/electrobun/src/electrobun-crypto-ready.test.ts +65 -0
  550. package/platforms/electrobun/src/electrobun-window-options.ts +25 -0
  551. package/platforms/electrobun/src/extension-rpc.test.ts +88 -0
  552. package/platforms/electrobun/src/extension-rpc.ts +102 -0
  553. package/platforms/electrobun/src/fatal-shutdown.test.ts +12 -16
  554. package/platforms/electrobun/src/fatal-shutdown.ts +1 -1
  555. package/platforms/electrobun/src/first-party-remotes.test.ts +169 -0
  556. package/platforms/electrobun/src/first-party-remotes.ts +297 -0
  557. package/platforms/electrobun/src/first-run-rpc.test.ts +192 -0
  558. package/platforms/electrobun/src/first-run-rpc.ts +146 -0
  559. package/platforms/electrobun/src/floating-chat-window.ts +181 -181
  560. package/platforms/electrobun/src/inbox-rpc.test.ts +123 -0
  561. package/platforms/electrobun/src/inbox-rpc.ts +158 -0
  562. package/platforms/electrobun/src/index.ts +2608 -2098
  563. package/platforms/electrobun/src/kiosk-mode.ts +50 -0
  564. package/platforms/electrobun/src/launch/index.ts +4 -0
  565. package/platforms/electrobun/src/launch/launch-dynamic-view.ts +37 -0
  566. package/platforms/electrobun/src/launch/launch-orchestrator.test.ts +224 -0
  567. package/platforms/electrobun/src/launch/launch-orchestrator.ts +456 -0
  568. package/platforms/electrobun/src/launch/launch-store.test.ts +97 -0
  569. package/platforms/electrobun/src/launch/launch-store.ts +134 -0
  570. package/platforms/electrobun/src/launch/types.ts +103 -0
  571. package/platforms/electrobun/src/launch/views/launch-diagnostics.html +205 -0
  572. package/platforms/electrobun/src/lifecycle/agent-ready-publish.test.ts +50 -0
  573. package/platforms/electrobun/src/lifecycle/agent-ready-publish.ts +27 -0
  574. package/platforms/electrobun/src/lifecycle/api-base-owner.test.ts +83 -0
  575. package/platforms/electrobun/src/lifecycle/api-base-owner.ts +63 -31
  576. package/platforms/electrobun/src/lifecycle/desktop-session-prime.ts +44 -44
  577. package/platforms/electrobun/src/logger.ts +14 -14
  578. package/platforms/electrobun/src/main-window-runtime.ts +83 -83
  579. package/platforms/electrobun/src/main-window-session.test.ts +109 -0
  580. package/platforms/electrobun/src/main-window-session.ts +87 -51
  581. package/platforms/electrobun/src/menu-reset-from-main.ts +158 -158
  582. package/platforms/electrobun/src/native/agent-env.test.ts +52 -0
  583. package/platforms/electrobun/src/native/agent-runtime-layout.test.ts +42 -0
  584. package/platforms/electrobun/src/native/agent-state-dir.test.ts +91 -0
  585. package/platforms/electrobun/src/native/agent.ts +2133 -1682
  586. package/platforms/electrobun/src/native/auth-bridge.test.ts +67 -0
  587. package/platforms/electrobun/src/native/auth-bridge.ts +464 -360
  588. package/platforms/electrobun/src/native/browser-workspace.ts +723 -471
  589. package/platforms/electrobun/src/native/camera.ts +50 -50
  590. package/platforms/electrobun/src/native/canvas.ts +444 -445
  591. package/platforms/electrobun/src/native/credentials.ts +678 -616
  592. package/platforms/electrobun/src/native/desktop-window.test.ts +416 -0
  593. package/platforms/electrobun/src/native/desktop.ts +2200 -2156
  594. package/platforms/electrobun/src/native/editor-bridge.ts +201 -201
  595. package/platforms/electrobun/src/native/file-watcher.ts +154 -154
  596. package/platforms/electrobun/src/native/gateway.ts +179 -180
  597. package/platforms/electrobun/src/native/gpu-window.ts +256 -256
  598. package/platforms/electrobun/src/native/index.ts +82 -74
  599. package/platforms/electrobun/src/native/location.test.ts +44 -0
  600. package/platforms/electrobun/src/native/location.ts +90 -80
  601. package/platforms/electrobun/src/native/loopback-port.ts +60 -60
  602. package/platforms/electrobun/src/native/mac-window-effects.ts +166 -104
  603. package/platforms/electrobun/src/native/music-player.ts +38 -38
  604. package/platforms/electrobun/src/native/permissions-shared.ts +249 -150
  605. package/platforms/electrobun/src/native/permissions.ts +301 -208
  606. package/platforms/electrobun/src/native/power-state.ts +129 -129
  607. package/platforms/electrobun/src/native/remote-plugin-host.test.ts +1394 -0
  608. package/platforms/electrobun/src/native/remote-plugin-host.ts +1541 -0
  609. package/platforms/electrobun/src/native/screencapture.ts +667 -573
  610. package/platforms/electrobun/src/native/steward.ts +207 -204
  611. package/platforms/electrobun/src/native/swabble.ts +68 -324
  612. package/platforms/electrobun/src/native/talkmode.ts +253 -422
  613. package/platforms/electrobun/src/native/webgpu-browser-support.test.ts +18 -0
  614. package/platforms/electrobun/src/native/webgpu-browser-support.ts +165 -147
  615. package/platforms/electrobun/src/native-onboarding.ts +270 -0
  616. package/platforms/electrobun/src/onboarding-overlay-window.ts +141 -0
  617. package/platforms/electrobun/src/persisted-deployment.ts +91 -0
  618. package/platforms/electrobun/src/pill-window.test.ts +91 -0
  619. package/platforms/electrobun/src/pill-window.ts +99 -0
  620. package/platforms/electrobun/src/preload-validation.ts +44 -44
  621. package/platforms/electrobun/src/preload.js +1 -1
  622. package/platforms/electrobun/src/print-electrobun-dev-settings-banner.ts +120 -120
  623. package/platforms/electrobun/src/renderer-api-proxy.test.ts +73 -0
  624. package/platforms/electrobun/src/renderer-api-proxy.ts +86 -0
  625. package/platforms/electrobun/src/renderer-static.test.ts +53 -0
  626. package/platforms/electrobun/src/renderer-static.ts +144 -57
  627. package/platforms/electrobun/src/rpc-handler-slices.ts +121 -0
  628. package/platforms/electrobun/src/rpc-handlers.test.ts +267 -0
  629. package/platforms/electrobun/src/rpc-handlers.ts +1306 -913
  630. package/platforms/electrobun/src/rpc-parse-utils.ts +57 -0
  631. package/platforms/electrobun/src/rpc-port-resolver.test.ts +45 -0
  632. package/platforms/electrobun/src/rpc-port-resolver.ts +31 -0
  633. package/platforms/electrobun/src/rpc-schema.ts +2556 -1619
  634. package/platforms/electrobun/src/runtime-layout.ts +105 -105
  635. package/platforms/electrobun/src/runtime-permissions.ts +95 -95
  636. package/platforms/electrobun/src/runtime-rpc.test.ts +126 -0
  637. package/platforms/electrobun/src/runtime-rpc.ts +237 -0
  638. package/platforms/electrobun/src/screenshot-dev-server.ts +87 -87
  639. package/platforms/electrobun/src/settings-mutations-rpc.test.ts +193 -0
  640. package/platforms/electrobun/src/settings-mutations-rpc.ts +220 -0
  641. package/platforms/electrobun/src/startup-trace.ts +274 -270
  642. package/platforms/electrobun/src/subscription-rpc.test.ts +89 -0
  643. package/platforms/electrobun/src/subscription-rpc.ts +192 -0
  644. package/platforms/electrobun/src/surface-windows.test.ts +355 -0
  645. package/platforms/electrobun/src/surface-windows.ts +410 -410
  646. package/platforms/electrobun/src/trace/README.md +73 -0
  647. package/platforms/electrobun/src/trace/errors.ts +21 -0
  648. package/platforms/electrobun/src/trace/index.ts +40 -0
  649. package/platforms/electrobun/src/trace/trace-dynamic-view.ts +40 -0
  650. package/platforms/electrobun/src/trace/trace-host-requests.ts +473 -0
  651. package/platforms/electrobun/src/trace/trace-service.test.ts +186 -0
  652. package/platforms/electrobun/src/trace/trace-service.ts +324 -0
  653. package/platforms/electrobun/src/trace/trace-store.test.ts +141 -0
  654. package/platforms/electrobun/src/trace/trace-store.ts +551 -0
  655. package/platforms/electrobun/src/trace/types.ts +250 -0
  656. package/platforms/electrobun/src/trace/views/agent-run-trace.html +311 -0
  657. package/platforms/electrobun/src/types/web-speech.d.ts +28 -28
  658. package/platforms/electrobun/src/types.ts +5 -5
  659. package/platforms/electrobun/src/update-availability.test.ts +72 -0
  660. package/platforms/electrobun/src/update-availability.ts +90 -0
  661. package/platforms/electrobun/src/update-rpc.test.ts +83 -0
  662. package/platforms/electrobun/src/update-rpc.ts +123 -0
  663. package/platforms/electrobun/src/voice/README.md +184 -0
  664. package/platforms/electrobun/src/voice/errors.ts +42 -0
  665. package/platforms/electrobun/src/voice/index.ts +78 -0
  666. package/platforms/electrobun/src/voice/types.ts +316 -0
  667. package/platforms/electrobun/src/voice/voice-host-requests.ts +259 -0
  668. package/platforms/electrobun/src/voice/voice-latency-budget.test.ts +66 -0
  669. package/platforms/electrobun/src/voice/voice-latency-budget.ts +243 -0
  670. package/platforms/electrobun/src/voice/voice-live-validation.test.ts +357 -0
  671. package/platforms/electrobun/src/voice/voice-live-validation.ts +838 -0
  672. package/platforms/electrobun/src/voice/voice-pipeline.ts +250 -0
  673. package/platforms/electrobun/src/voice/voice-playback-adapter.ts +31 -0
  674. package/platforms/electrobun/src/voice/voice-runtime-adapter.test.ts +213 -0
  675. package/platforms/electrobun/src/voice/voice-runtime-adapter.ts +687 -0
  676. package/platforms/electrobun/src/voice/voice-service.test.ts +587 -0
  677. package/platforms/electrobun/src/voice/voice-service.ts +1067 -0
  678. package/platforms/electrobun/src/voice/voice-stream-coordinator.test.ts +115 -0
  679. package/platforms/electrobun/src/voice/voice-stream-coordinator.ts +270 -0
  680. package/platforms/electrobun/src/voice/voice-trace.ts +97 -0
  681. package/platforms/electrobun/src/voice/voice-tts-chunker.test.ts +91 -0
  682. package/platforms/electrobun/src/voice/voice-tts-chunker.ts +194 -0
  683. package/platforms/electrobun/src/windows-cef-profile.ts +88 -88
  684. package/platforms/electrobun/tsconfig.json +88 -12
  685. package/platforms/electrobun/update-channels.json +22 -0
  686. package/platforms/electrobun/vitest.electrobun.config.ts +72 -42
  687. package/platforms/ios/App/App/App.entitlements +4 -0
  688. package/platforms/ios/App/App/AppDelegate.swift +80 -18
  689. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ios-marketing-1024.png +0 -0
  690. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-20x20@1x.png +0 -0
  691. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-20x20@2x.png +0 -0
  692. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-29x29@1x.png +0 -0
  693. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-29x29@2x.png +0 -0
  694. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-40x40@1x.png +0 -0
  695. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-40x40@2x.png +0 -0
  696. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-76x76@1x.png +0 -0
  697. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-76x76@2x.png +0 -0
  698. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-83_5x83_5@2x.png +0 -0
  699. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-20x20@2x.png +0 -0
  700. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-20x20@3x.png +0 -0
  701. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-29x29@2x.png +0 -0
  702. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-29x29@3x.png +0 -0
  703. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-40x40@2x.png +0 -0
  704. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-40x40@3x.png +0 -0
  705. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-60x60@2x.png +0 -0
  706. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-60x60@3x.png +0 -0
  707. package/platforms/ios/App/App/Base.lproj/LaunchScreen.storyboard +4 -9
  708. package/platforms/ios/App/App/ComputerUseBridge.swift +589 -0
  709. package/platforms/ios/App/App/DeviceActivityMonitorExtension/DeviceActivityMonitorExtension.entitlements +12 -0
  710. package/platforms/ios/App/App/DeviceActivityMonitorExtension/DeviceActivityMonitorExtension.swift +34 -0
  711. package/platforms/ios/App/App/DeviceActivityMonitorExtension/Info.plist +29 -0
  712. package/platforms/ios/App/App/DeviceActivityReportExtension/DeviceActivityReportExtension.entitlements +12 -0
  713. package/platforms/ios/App/App/DeviceActivityReportExtension/DeviceActivityReportExtension.swift +53 -0
  714. package/platforms/ios/App/App/DeviceActivityReportExtension/Info.plist +27 -0
  715. package/platforms/ios/App/App/ElizaAppIntents.swift +183 -0
  716. package/platforms/ios/App/App/ElizaIntentPlugin.swift +342 -5
  717. package/platforms/ios/App/App/Info.plist +17 -1
  718. package/platforms/ios/App/App/runners/eliza-tasks.js +177 -0
  719. package/platforms/ios/App/App.xcodeproj/project.pbxproj +262 -6
  720. package/platforms/ios/App/BroadcastExtension/SampleHandler.swift +100 -0
  721. package/platforms/ios/App/Podfile +5 -0
  722. package/platforms/ios/App/Podfile.lock +83 -59
  723. package/register-runtime-hooks.js +11 -5
  724. package/registry/index.d.ts +1 -5
  725. package/registry/index.d.ts.map +1 -1
  726. package/registry/index.js +10 -68
  727. package/runtime/android-avf-microdroid-bridge.d.ts +29 -0
  728. package/runtime/android-avf-microdroid-bridge.d.ts.map +1 -0
  729. package/runtime/android-avf-microdroid-bridge.js +149 -0
  730. package/runtime/api-dev-settings-banner.d.ts.map +1 -1
  731. package/runtime/api-dev-settings-banner.js +5 -13
  732. package/runtime/app-core-runtime-hooks.d.ts +21 -0
  733. package/runtime/app-core-runtime-hooks.d.ts.map +1 -0
  734. package/runtime/app-core-runtime-hooks.js +10 -0
  735. package/runtime/autonomy-policy.d.ts +2 -0
  736. package/runtime/autonomy-policy.d.ts.map +1 -0
  737. package/runtime/autonomy-policy.js +4 -0
  738. package/runtime/bundled-fused-lib.d.ts +36 -0
  739. package/runtime/bundled-fused-lib.d.ts.map +1 -0
  740. package/runtime/bundled-fused-lib.js +77 -0
  741. package/runtime/channel-plugin-map.d.ts +1 -5
  742. package/runtime/channel-plugin-map.d.ts.map +1 -1
  743. package/runtime/channel-plugin-map.js +11 -31
  744. package/runtime/desktop/AppWindowRenderer.d.ts +17 -0
  745. package/runtime/desktop/AppWindowRenderer.d.ts.map +1 -0
  746. package/runtime/desktop/AppWindowRenderer.js +360 -0
  747. package/runtime/desktop/DesktopSurfaceNavigationRuntime.d.ts +2 -0
  748. package/runtime/desktop/DesktopSurfaceNavigationRuntime.d.ts.map +1 -0
  749. package/runtime/desktop/DesktopSurfaceNavigationRuntime.js +41 -0
  750. package/runtime/desktop/DesktopTrayRuntime.d.ts +2 -0
  751. package/runtime/desktop/DesktopTrayRuntime.d.ts.map +1 -0
  752. package/runtime/desktop/DesktopTrayRuntime.js +174 -0
  753. package/runtime/desktop/DetachedShellRoot.d.ts +10 -0
  754. package/runtime/desktop/DetachedShellRoot.d.ts.map +1 -0
  755. package/runtime/desktop/DetachedShellRoot.js +111 -0
  756. package/runtime/desktop/index.d.ts +6 -0
  757. package/runtime/desktop/index.d.ts.map +1 -0
  758. package/runtime/desktop/index.js +5 -0
  759. package/runtime/desktop/tray-menu.d.ts +20 -0
  760. package/runtime/desktop/tray-menu.d.ts.map +1 -0
  761. package/runtime/desktop/tray-menu.js +143 -0
  762. package/runtime/dev-server.d.ts +1 -1
  763. package/runtime/dev-server.d.ts.map +1 -1
  764. package/runtime/dev-server.js +104 -19
  765. package/runtime/eliza.d.ts +75 -1
  766. package/runtime/eliza.d.ts.map +1 -1
  767. package/runtime/eliza.js +606 -122
  768. package/runtime/ensure-text-to-speech-handler.d.ts.map +1 -1
  769. package/runtime/ensure-text-to-speech-handler.js +10 -3
  770. package/runtime/mobile-safe-runtime.d.ts +181 -2
  771. package/runtime/mobile-safe-runtime.d.ts.map +1 -1
  772. package/runtime/mobile-safe-runtime.js +1019 -12
  773. package/runtime/mode/remote-forwarder.d.ts.map +1 -1
  774. package/runtime/mode/remote-forwarder.js +2 -2
  775. package/runtime/mode/route-mode-guard.d.ts +2 -3
  776. package/runtime/mode/route-mode-guard.d.ts.map +1 -1
  777. package/runtime/mode/route-mode-guard.js +4 -5
  778. package/runtime/mode/route-mode-matrix.d.ts +1 -1
  779. package/runtime/mode/route-mode-matrix.d.ts.map +1 -1
  780. package/runtime/mode/route-mode-matrix.js +14 -1
  781. package/runtime/mode/runtime-mode.d.ts +1 -1
  782. package/runtime/mode/runtime-mode.js +1 -1
  783. package/runtime/runtime-bootstrap-policy.d.ts.map +1 -1
  784. package/runtime/runtime-bootstrap-policy.js +14 -2
  785. package/runtime/telegram-standalone-handler.d.ts.map +1 -1
  786. package/runtime/telegram-standalone-handler.js +10 -9
  787. package/runtime/tts-cache-wiring.d.ts +29 -0
  788. package/runtime/tts-cache-wiring.d.ts.map +1 -0
  789. package/runtime/tts-cache-wiring.js +114 -0
  790. package/runtime/voice-warmup.d.ts +66 -0
  791. package/runtime/voice-warmup.d.ts.map +1 -0
  792. package/runtime/voice-warmup.js +101 -0
  793. package/scripts/android-sms-gateway-template.test.mjs +1014 -0
  794. package/scripts/aosp/README.md +29 -16
  795. package/scripts/aosp/compile-libllama-zig-pin.test.mjs +147 -0
  796. package/scripts/aosp/compile-libllama.mjs +1750 -267
  797. package/scripts/aosp/compile-libllama.test.mjs +133 -0
  798. package/scripts/aosp/compile-shim.mjs +68 -19
  799. package/scripts/aosp/deploy-pixel.mjs +405 -0
  800. package/scripts/aosp/lib/load-variant-config.mjs +3 -3
  801. package/scripts/aosp/llama-cpp-patches/README.md +8 -8
  802. package/scripts/aosp/llama-cpp-patches/apply-patches.mjs +23 -6
  803. package/scripts/aosp/llama-cpp-patches/polarquant/README.md +37 -0
  804. package/scripts/aosp/llama-cpp-patches/qjl/README.md +37 -0
  805. package/scripts/aosp/seccomp-shim/sigsys-handler-arm64.c +169 -0
  806. package/scripts/aosp/seccomp-shim/sigsys-handler-riscv64.c +217 -0
  807. package/scripts/aosp/smoke-cuttlefish.mjs +34 -4
  808. package/scripts/aosp/stage-default-models.mjs +59 -35
  809. package/scripts/aosp/stage-default-models.test.mjs +23 -0
  810. package/scripts/aosp/variant-config-schema.ts +2 -2
  811. package/scripts/assert-required-bundled-packages.test.ts +555 -0
  812. package/scripts/audit-apple-store-sandbox.mjs +146 -0
  813. package/scripts/audit-live-test-surface.mjs +5 -2
  814. package/scripts/build-capacitor-app.mjs +21 -0
  815. package/scripts/build-flatpak.mjs +5 -5
  816. package/scripts/build-helpers/arm64-simd.mjs +72 -0
  817. package/scripts/build-helpers/omnivoice-merged.mjs +87 -0
  818. package/scripts/build-helpers/verify-fused-symbols.mjs +600 -0
  819. package/scripts/build-helpers/verify-fused-symbols.test.mjs +0 -0
  820. package/scripts/build-image.sh +1 -1
  821. package/scripts/build-llama-cpp-mtp.mjs +488 -0
  822. package/scripts/build-native-plugins.mjs +230 -18
  823. package/scripts/build-patched-electrobun-cli.mjs +68 -10
  824. package/scripts/build-win.mjs +1 -1
  825. package/scripts/bun-riscv64/Dockerfile +418 -0
  826. package/scripts/bun-riscv64/README.md +316 -0
  827. package/scripts/bun-riscv64/build.sh +469 -0
  828. package/scripts/bun-riscv64/bun-patches/0001-config-add-riscv64-arch.patch +74 -0
  829. package/scripts/bun-riscv64/bun-patches/0002-flags-add-riscv64-march-mabi.patch +16 -0
  830. package/scripts/bun-riscv64/bun-patches/0003-zig-add-riscv64-target-triple-and-cpu.patch +26 -0
  831. package/scripts/bun-riscv64/bun-patches/0004-webkit-force-local-mode-on-riscv64.patch +33 -0
  832. package/scripts/bun-riscv64/bun-patches/0005-tinycc-disable-on-riscv64.patch +16 -0
  833. package/scripts/bun-riscv64/bun-patches/0006-build-add-riscv64-cli-validation.patch +15 -0
  834. package/scripts/bun-riscv64/bun-patches/0007-deps-per-dep-riscv64-checks.patch +24 -0
  835. package/scripts/bun-riscv64/bun-patches/0008-source-stabilize-riscv64-musl-build.patch +226 -0
  836. package/scripts/bun-riscv64/bun-patches/0009-disable-wasm-streaming-hooks-for-c-loop.patch +162 -0
  837. package/scripts/bun-riscv64/bun-patches/0010-disable-inspector-profiler-for-riscv64-c-loop.patch +80 -0
  838. package/scripts/bun-riscv64/bun-patches/0011-process-arch-add-riscv64.patch +23 -0
  839. package/scripts/bun-riscv64/bun-patches/0012-cpu-features-add-riscv64-fallback.patch +13 -0
  840. package/scripts/bun-riscv64/bun-patches/0013-disable-console-inspector-hooks-for-riscv64-c-loop.patch +43 -0
  841. package/scripts/bun-riscv64/bun-patches/0014-disable-custom-inspector-dispatchers-on-riscv64.patch +127 -0
  842. package/scripts/bun-riscv64/bun-patches/0015-disable-jsc-profiler-builtins-on-riscv64.patch +75 -0
  843. package/scripts/bun-riscv64/bun-patches/0016-node-vm-disable-jit-cached-data-on-riscv64-c-loop.patch +96 -0
  844. package/scripts/bun-riscv64/bun-patches/0017-disable-performance-domjit-signature-on-riscv64-c-loop.patch +34 -0
  845. package/scripts/bun-riscv64/bun-patches/0018-fix-serialized-script-identifier-big-endian-path.patch +19 -0
  846. package/scripts/bun-riscv64/bun-patches/0019-add-wtf-timer-fire-bridge-for-c-loop.patch +24 -0
  847. package/scripts/bun-riscv64/bun-patches/0020-run-riscv64-smoke-test-under-qemu.patch +13 -0
  848. package/scripts/bun-riscv64/bun-patches/0021-fix-riscv64-linux-open-flags.patch +25 -0
  849. package/scripts/bun-riscv64/bun-patches/0022-zlib-riscv64-generic-kernels.patch +25 -0
  850. package/scripts/bun-riscv64/bun-patches/README.md +127 -0
  851. package/scripts/bun-riscv64/bun-version.json +202 -0
  852. package/scripts/bun-riscv64/run-build.sh +162 -0
  853. package/scripts/bun-riscv64/rust-core/0001-riscv64-rust-core-port.patch +868 -0
  854. package/scripts/bun-riscv64/rust-core/0002-second-wave-riscv64-source-gaps.patch +130 -0
  855. package/scripts/bun-riscv64/rust-core/0003-third-wave-riscv64-crash-handler-gaps.patch +78 -0
  856. package/scripts/bun-riscv64/rust-core/0004-rust-target-cpu-riscv64.patch +39 -0
  857. package/scripts/bun-riscv64/rust-core/0005-fifth-wave-riscv64-source-gaps.patch +96 -0
  858. package/scripts/bun-riscv64/rust-core/0006-cpp-wasm-and-inspector-guards-riscv64.patch +91 -0
  859. package/scripts/bun-riscv64/rust-core/0007-bun-alloc-max-align-t-riscv64.patch +36 -0
  860. package/scripts/bun-riscv64/rust-core/0008-workspace-lints-warn-not-deny-riscv64.patch +75 -0
  861. package/scripts/bun-riscv64/rust-core/0009-zigglobalobject-wasm-streaming-guards-riscv64.patch +109 -0
  862. package/scripts/bun-riscv64/rust-core/0010-tcc-externs-stub-on-riscv64.patch +62 -0
  863. package/scripts/bun-riscv64/rust-core/0011-clippy-ptr-cast-lints-warn-riscv64.patch +61 -0
  864. package/scripts/bun-riscv64/rust-core/README.md +80 -0
  865. package/scripts/bun-riscv64/rust-core/webkit-patches/0003-disable-dfg-ftl-on-riscv64.patch +60 -0
  866. package/scripts/bun-riscv64/rust-core/webkit-patches/0004-riscv64-do-not-force-wasm-in-c-loop.patch +31 -0
  867. package/scripts/bun-riscv64/rust-core/webkit-patches/0005-domjit-effect-allow-no-dfg-c-loop.patch +40 -0
  868. package/scripts/bun-riscv64/rust-core/webkit-patches/0006-disable-usewasm-when-webassembly-compiled-out.patch +33 -0
  869. package/scripts/bun-riscv64/rust-core/webkit-patches/0007-restore-dropped-includes-and-llint-fwd-decl.patch +31 -0
  870. package/scripts/bun-riscv64/validate.sh +264 -0
  871. package/scripts/bun-riscv64/webkit-patches/0001-cherry-pick-llint-riscv64.recipe +155 -0
  872. package/scripts/bun-riscv64/webkit-patches/0002-cherry-pick-baseline-jit-riscv64.recipe +40 -0
  873. package/scripts/bun-riscv64/webkit-patches/0003-disable-dfg-ftl-on-riscv64.patch +60 -0
  874. package/scripts/bun-riscv64/webkit-patches/0004-riscv64-do-not-force-wasm-in-c-loop.patch +31 -0
  875. package/scripts/bun-riscv64/webkit-patches/0005-domjit-effect-allow-no-dfg-c-loop.patch +40 -0
  876. package/scripts/bun-riscv64/webkit-patches/0006-disable-usewasm-when-webassembly-compiled-out.patch +33 -0
  877. package/scripts/bun-riscv64/webkit-patches/0007-restore-dropped-includes-and-llint-fwd-decl.patch +72 -0
  878. package/scripts/bun-riscv64/webkit-patches/README.md +146 -0
  879. package/scripts/check-homepage-public-readiness.mjs +353 -0
  880. package/scripts/check-homepage-release-data.mjs +110 -0
  881. package/scripts/check-i18n.mjs +1 -1
  882. package/scripts/check-real-local-chat.ts +147 -0
  883. package/scripts/check-real-local-provisioning.ts +104 -0
  884. package/scripts/check-real-local-reset.ts +249 -0
  885. package/scripts/check-sms-gateway-completion-audit.mjs +428 -0
  886. package/scripts/check-sms-gateway-readiness.mjs +266 -0
  887. package/scripts/clean-repo.mjs +5 -5
  888. package/scripts/codesign-mas.mjs +222 -16
  889. package/scripts/collect-docker-runtime-deps.mjs +229 -0
  890. package/scripts/continue-sms-gateway-work.mjs +121 -0
  891. package/scripts/copy-runtime-node-modules.ts +1050 -195
  892. package/scripts/deploy-cloud-api-production-gateway.mjs +52 -0
  893. package/scripts/desktop-build.mjs +965 -98
  894. package/scripts/dev-platform.mjs +346 -102
  895. package/scripts/dev-startup-smoke.mjs +248 -0
  896. package/scripts/dev-ui.mjs +418 -176
  897. package/scripts/disable-local-eliza-workspace.mjs +35 -0
  898. package/scripts/docker-ci-smoke.sh +465 -96
  899. package/scripts/docker-entrypoint.sh +62 -1
  900. package/scripts/docker-entrypoint.test.ts +283 -0
  901. package/scripts/ensure-avatars.mjs +2 -2
  902. package/scripts/ensure-electrobun-core.mjs +1 -1
  903. package/scripts/ensure-generated-core-proto-js.mjs +1 -1
  904. package/scripts/ensure-type-package-aliases.mjs +62 -5
  905. package/scripts/ensure-vision-deps.mjs +20 -1
  906. package/scripts/entry.ts +1 -1
  907. package/scripts/ffi-stub/Makefile +64 -0
  908. package/scripts/ffi-stub/README.md +391 -0
  909. package/scripts/ffi-stub/asr-ffi-smoke.ts +139 -0
  910. package/scripts/ffi-stub/ffi-stub.c +539 -0
  911. package/scripts/ffi-stub/ffi.h +538 -0
  912. package/scripts/ffi-stub/libelizainference_stub.so +0 -0
  913. package/scripts/ffi-stub/tts-stream-ffi-smoke.ts +349 -0
  914. package/scripts/generate-first-run-voicelines.mjs +194 -0
  915. package/scripts/generate-plugin-index.js +4 -3
  916. package/scripts/generate-static-asset-manifest.mjs +1 -1
  917. package/scripts/i18n-dynamic-keys.json +5 -5
  918. package/scripts/init-submodules.mjs +2 -2
  919. package/scripts/install-android-sms-gateway.md +177 -0
  920. package/scripts/install-android-sms-gateway.mjs +1088 -0
  921. package/scripts/ios-xcframework/README.md +74 -72
  922. package/scripts/ios-xcframework/build-xcframework.mjs +204 -43
  923. package/scripts/ios-xcframework/run-physical-device-smoke.mjs +1943 -0
  924. package/scripts/ios-xcframework/runtime-symbol-shim.c +450 -0
  925. package/scripts/kernel-patches/cpu-polar-kernels.mjs +441 -0
  926. package/scripts/kernel-patches/cpu-simd-kernels.mjs +253 -0
  927. package/scripts/kernel-patches/cpu-thread-parallelism.mjs +368 -0
  928. package/scripts/kernel-patches/cuda-kernels.mjs +117 -0
  929. package/scripts/kernel-patches/metal-kernels.mjs +1698 -109
  930. package/scripts/kernel-patches/server-omnivoice-route.mjs +718 -0
  931. package/scripts/kernel-patches/server-structured-output.mjs +279 -0
  932. package/scripts/kernel-patches/vulkan-dispatch-log.mjs +166 -0
  933. package/scripts/kernel-patches/vulkan-dispatch-log.test.mjs +50 -0
  934. package/scripts/kernel-patches/vulkan-dispatch-patches/01-vulkan-shaders-gen.patch +30 -16
  935. package/scripts/kernel-patches/vulkan-dispatch-patches/02-ggml-vulkan-pipelines.patch +75 -30
  936. package/scripts/kernel-patches/vulkan-kernels.mjs +800 -49
  937. package/scripts/lib/agent-source-watcher.mjs +173 -0
  938. package/scripts/lib/agent-source-watcher.test.mjs +184 -0
  939. package/scripts/lib/api-supervisor.mjs +78 -9
  940. package/scripts/lib/api-supervisor.test.mjs +121 -0
  941. package/scripts/lib/app-dir.mjs +2 -16
  942. package/scripts/lib/apple-entitlement-audit.mjs +655 -0
  943. package/scripts/lib/apple-entitlement-audit.test.mjs +144 -0
  944. package/scripts/lib/artifact-staleness.d.mts +33 -0
  945. package/scripts/lib/artifact-staleness.mjs +122 -0
  946. package/scripts/lib/artifact-staleness.test.mts +98 -0
  947. package/scripts/lib/bun-version-guard.mjs +13 -13
  948. package/scripts/lib/capacitor-plugin-build-needed.mjs +4 -3
  949. package/scripts/lib/capacitor-plugin-names.mjs +30 -14
  950. package/scripts/lib/desktop-preflight.mjs +9 -5
  951. package/scripts/lib/desktop-startup-embedding-warmup-policy.mjs +51 -0
  952. package/scripts/lib/desktop-startup-embedding-warmup-policy.test.mjs +55 -0
  953. package/scripts/lib/duet-bridge.d.mts +63 -0
  954. package/scripts/lib/duet-bridge.mjs +193 -0
  955. package/scripts/lib/ios-plist-url-scheme.mjs +80 -0
  956. package/scripts/lib/mobile-build-decisions.mjs +97 -0
  957. package/scripts/lib/node-path-env.mjs +4 -2
  958. package/scripts/lib/orchestrator-desktop-dev-banner.mjs +12 -3
  959. package/scripts/lib/patch-bun-exports.mjs +90 -27
  960. package/scripts/lib/patch-bun-exports.test.mjs +79 -0
  961. package/scripts/lib/renderer-build-action.mjs +35 -0
  962. package/scripts/lib/renderer-build-action.test.mjs +70 -0
  963. package/scripts/lib/renderer-build-manifest.d.mts +65 -0
  964. package/scripts/lib/renderer-build-manifest.mjs +257 -0
  965. package/scripts/lib/renderer-build-manifest.test.mts +277 -0
  966. package/scripts/lib/stage-android-agent.mjs +757 -99
  967. package/scripts/lib/sync-eliza-env-aliases.mjs +3 -25
  968. package/scripts/lib/ui-smoke-stub-decision.mjs +33 -0
  969. package/scripts/lib/ui-smoke-stub-decision.test.mjs +46 -0
  970. package/scripts/lib/verify-ondevice-artifact.d.mts +16 -0
  971. package/scripts/lib/verify-ondevice-artifact.mjs +61 -0
  972. package/scripts/lib/verify-ondevice-artifact.test.mts +98 -0
  973. package/scripts/lib/vite-renderer-dist-stale.mjs +5 -0
  974. package/scripts/lib/voice-latency-report.mjs +154 -0
  975. package/scripts/lib/websocket-pending-queue.ts +92 -0
  976. package/scripts/lifeops-prompt-benchmark.ts +21 -12
  977. package/scripts/link-docker-local-app-packages.mjs +109 -36
  978. package/scripts/local-stt-bench.ts +192 -0
  979. package/scripts/maintain-cloud-api-production-gateway.mjs +54 -0
  980. package/scripts/mas-smoke.mjs +459 -0
  981. package/scripts/mas-smoke.test.mjs +220 -0
  982. package/scripts/mobile-auth-simulator-smoke.mjs +0 -1
  983. package/scripts/normalize-eliza-capture.ts +97 -0
  984. package/scripts/omnivoice-fuse/prepare.mjs +2543 -23
  985. package/scripts/pack-upstreams.mjs +65 -5
  986. package/scripts/package-electrobun-linux.mjs +303 -0
  987. package/scripts/patch-deps.mjs +5 -3
  988. package/scripts/patches/llama-asr-word-timestamps.patch +218 -0
  989. package/scripts/playwright-ui-live-stack.ts +588 -157
  990. package/scripts/playwright-ui-smoke-api-stub.mjs +3495 -111
  991. package/scripts/pre-review-local.mjs +2 -2
  992. package/scripts/prepare-ios-cocoapods.sh +41 -3
  993. package/scripts/release-check.ts +180 -84
  994. package/scripts/relink-workspace-packages-to-dist.mjs +21 -4
  995. package/scripts/rt.mjs +16 -1
  996. package/scripts/run-biome-check.mjs +1 -1
  997. package/scripts/run-coding-agent-e2e.mjs +3 -3
  998. package/scripts/run-eliza-app-core-script.mjs +34 -0
  999. package/scripts/run-local-plugin-live-smoke.mjs +66 -2
  1000. package/scripts/run-mobile-build-android-app-actions.test.mjs +426 -0
  1001. package/scripts/run-mobile-build-brand-separation.test.mts +33 -0
  1002. package/scripts/run-mobile-build-ios-engine-gate.test.mjs +85 -0
  1003. package/scripts/run-mobile-build-mtp-staleness.test.mts +198 -0
  1004. package/scripts/run-mobile-build.mjs +5082 -610
  1005. package/scripts/run-node-runtime.mjs +184 -7
  1006. package/scripts/run-node-runtime.test.mjs +167 -0
  1007. package/scripts/run-node-tsx.mjs +80 -33
  1008. package/scripts/run-node.mjs +41 -1
  1009. package/scripts/run-production-build.mjs +34 -27
  1010. package/scripts/run-release-check.mjs +19 -0
  1011. package/scripts/run-release-contract-suite.mjs +107 -14
  1012. package/scripts/run-ui-smoke-playwright-suite.mjs +0 -2
  1013. package/scripts/runtime-package-manifest.ts +21 -3
  1014. package/scripts/serve-real-local-agent.ts +72 -0
  1015. package/scripts/setup-upstreams.mjs +42 -1
  1016. package/scripts/sms-gateway-status.mjs +194 -0
  1017. package/scripts/stage-android-agent.test.mjs +97 -0
  1018. package/scripts/stage-desktop-fused-lib.mjs +453 -0
  1019. package/scripts/stage-elizavoice-lib.mjs +363 -0
  1020. package/scripts/startup-integration-script-drift.test.ts +82 -4
  1021. package/scripts/streaming-pipeline-bench.ts +543 -0
  1022. package/scripts/sync-homepage-porkbun-dns.mjs +262 -0
  1023. package/scripts/test-sms-gateway-software.mjs +100 -0
  1024. package/scripts/type-audit.mjs +1 -1
  1025. package/scripts/validate-bluebubbles-outbound.mjs +293 -0
  1026. package/scripts/validate-cdn-assets.mjs +15 -7
  1027. package/scripts/validate-regression-matrix.mjs +109 -8
  1028. package/scripts/verify-android-sms-gateway-e2e.mjs +362 -0
  1029. package/scripts/verify-bluebubbles-gateway-e2e.mjs +191 -0
  1030. package/scripts/verify-bluebubbles-inbound-readiness.mjs +88 -0
  1031. package/scripts/verify-cloud-api-production-deploy.mjs +87 -0
  1032. package/scripts/verify-cloud-sms-onboarding-flow.mjs +336 -0
  1033. package/scripts/verify-ondevice-artifact.mjs +111 -0
  1034. package/scripts/voice/freeze-voice.mjs +521 -0
  1035. package/scripts/voice-attribution-smoke.ts +644 -0
  1036. package/scripts/voice-create-profile.mjs +379 -0
  1037. package/scripts/voice-duet.mjs +1355 -0
  1038. package/scripts/voice-e2e-hardware.ts +877 -0
  1039. package/scripts/voice-interactive.mjs +1721 -0
  1040. package/scripts/voice-latency-report.mjs +96 -0
  1041. package/scripts/voice-latency-report.test.ts +176 -0
  1042. package/scripts/voice-preset/build-default-voice-preset.mjs +249 -0
  1043. package/scripts/voice-preset/build-onboarding-voice.mjs +281 -0
  1044. package/scripts/watch-sms-gateway-readiness.mjs +303 -0
  1045. package/scripts/write-homepage-release-data.mjs +458 -26
  1046. package/security/agent-vault-id.d.ts +2 -2
  1047. package/security/agent-vault-id.js +1 -1
  1048. package/security/hydrate-wallet-keys-from-platform-store.d.ts.map +1 -1
  1049. package/security/hydrate-wallet-keys-from-platform-store.js +23 -14
  1050. package/security/platform-secure-store-node.d.ts +3 -3
  1051. package/security/platform-secure-store-node.js +3 -3
  1052. package/security/wallet-os-store-actions.d.ts +0 -9
  1053. package/security/wallet-os-store-actions.d.ts.map +1 -1
  1054. package/security/wallet-os-store-actions.js +3 -10
  1055. package/services/account-pool.d.ts +23 -14
  1056. package/services/account-pool.d.ts.map +1 -1
  1057. package/services/account-pool.js +86 -24
  1058. package/services/account-usage.d.ts.map +1 -1
  1059. package/services/account-usage.js +2 -5
  1060. package/services/ambient-audio/consent.d.ts +9 -0
  1061. package/services/ambient-audio/consent.d.ts.map +1 -0
  1062. package/services/ambient-audio/consent.js +28 -0
  1063. package/services/ambient-audio/index.d.ts +7 -0
  1064. package/services/ambient-audio/index.d.ts.map +1 -0
  1065. package/services/ambient-audio/index.js +4 -0
  1066. package/services/ambient-audio/replay-buffer.d.ts +14 -0
  1067. package/services/ambient-audio/replay-buffer.d.ts.map +1 -0
  1068. package/services/ambient-audio/replay-buffer.js +66 -0
  1069. package/services/ambient-audio/response-gate.d.ts +3 -0
  1070. package/services/ambient-audio/response-gate.d.ts.map +1 -0
  1071. package/services/ambient-audio/response-gate.js +33 -0
  1072. package/services/ambient-audio/service.d.ts +22 -0
  1073. package/services/ambient-audio/service.d.ts.map +1 -0
  1074. package/services/ambient-audio/service.js +47 -0
  1075. package/services/ambient-audio/types.d.ts +42 -0
  1076. package/services/ambient-audio/types.d.ts.map +1 -0
  1077. package/services/app-updates/update-policy.d.ts +64 -0
  1078. package/services/app-updates/update-policy.d.ts.map +1 -0
  1079. package/services/app-updates/update-policy.js +228 -0
  1080. package/services/auth-store.d.ts +37 -1
  1081. package/services/auth-store.d.ts.map +1 -1
  1082. package/services/auth-store.js +59 -26
  1083. package/services/cloud-jwks-store.d.ts +3 -3
  1084. package/services/cloud-jwks-store.d.ts.map +1 -1
  1085. package/services/cloud-jwks-store.js +5 -8
  1086. package/services/coding-account-bridge.d.ts +71 -0
  1087. package/services/coding-account-bridge.d.ts.map +1 -0
  1088. package/services/coding-account-bridge.js +267 -0
  1089. package/services/connector-target-catalog.d.ts +11 -4
  1090. package/services/connector-target-catalog.d.ts.map +1 -1
  1091. package/services/connector-target-catalog.js +7 -4
  1092. package/services/credential-tunnel-service.d.ts +66 -0
  1093. package/services/credential-tunnel-service.d.ts.map +1 -0
  1094. package/services/credential-tunnel-service.js +227 -0
  1095. package/services/github-credentials.d.ts +1 -1
  1096. package/services/github-credentials.js +1 -1
  1097. package/services/inference-abort.d.ts +47 -0
  1098. package/services/inference-abort.d.ts.map +1 -0
  1099. package/services/inference-abort.js +76 -0
  1100. package/services/persistence.d.ts +2 -3
  1101. package/services/persistence.d.ts.map +1 -1
  1102. package/services/persistence.js +2 -3
  1103. package/services/phrase-chunked-tts.d.ts +136 -0
  1104. package/services/phrase-chunked-tts.d.ts.map +1 -0
  1105. package/services/phrase-chunked-tts.js +208 -0
  1106. package/services/sandbox-registry.d.ts +78 -0
  1107. package/services/sandbox-registry.d.ts.map +1 -0
  1108. package/services/sandbox-registry.js +323 -0
  1109. package/services/secrets-manager-installer.d.ts +8 -1
  1110. package/services/secrets-manager-installer.d.ts.map +1 -1
  1111. package/services/secrets-manager-installer.js +27 -2
  1112. package/services/sensitive-requests/cloud-link-adapter.d.ts +15 -0
  1113. package/services/sensitive-requests/cloud-link-adapter.d.ts.map +1 -0
  1114. package/services/sensitive-requests/cloud-link-adapter.js +73 -0
  1115. package/services/sensitive-requests/index.d.ts +27 -0
  1116. package/services/sensitive-requests/index.d.ts.map +1 -0
  1117. package/services/sensitive-requests/index.js +51 -0
  1118. package/services/sensitive-requests/instruct-dm-only-adapter.d.ts +14 -0
  1119. package/services/sensitive-requests/instruct-dm-only-adapter.d.ts.map +1 -0
  1120. package/services/sensitive-requests/instruct-dm-only-adapter.js +22 -0
  1121. package/services/sensitive-requests/owner-app-inline-adapter.d.ts +3 -0
  1122. package/services/sensitive-requests/owner-app-inline-adapter.d.ts.map +1 -0
  1123. package/services/sensitive-requests/owner-app-inline-adapter.js +146 -0
  1124. package/services/sensitive-requests/owner-app-oauth-adapter.d.ts +3 -0
  1125. package/services/sensitive-requests/owner-app-oauth-adapter.d.ts.map +1 -0
  1126. package/services/sensitive-requests/owner-app-oauth-adapter.js +156 -0
  1127. package/services/sensitive-requests/public-link-adapter.d.ts +14 -0
  1128. package/services/sensitive-requests/public-link-adapter.d.ts.map +1 -0
  1129. package/services/sensitive-requests/public-link-adapter.js +86 -0
  1130. package/services/sensitive-requests/tunnel-link-adapter.d.ts +17 -0
  1131. package/services/sensitive-requests/tunnel-link-adapter.d.ts.map +1 -0
  1132. package/services/sensitive-requests/tunnel-link-adapter.js +38 -0
  1133. package/services/steward-credentials.d.ts +1 -1
  1134. package/services/steward-credentials.d.ts.map +1 -1
  1135. package/services/steward-credentials.js +10 -6
  1136. package/services/steward-sidecar/health-check.d.ts.map +1 -1
  1137. package/services/steward-sidecar/health-check.js +4 -3
  1138. package/services/steward-sidecar/process-management.d.ts +1 -1
  1139. package/services/steward-sidecar/process-management.d.ts.map +1 -1
  1140. package/services/steward-sidecar/process-management.js +9 -3
  1141. package/services/steward-sidecar/types.d.ts +1 -1
  1142. package/services/steward-sidecar/types.d.ts.map +1 -1
  1143. package/services/steward-sidecar/wallet-setup.d.ts +1 -1
  1144. package/services/steward-sidecar/wallet-setup.d.ts.map +1 -1
  1145. package/services/steward-sidecar/wallet-setup.js +8 -7
  1146. package/services/steward-sidecar.d.ts +5 -5
  1147. package/services/steward-sidecar.d.ts.map +1 -1
  1148. package/services/steward-sidecar.js +27 -19
  1149. package/services/task-host-capabilities.d.ts +60 -0
  1150. package/services/task-host-capabilities.d.ts.map +1 -0
  1151. package/services/task-host-capabilities.js +122 -0
  1152. package/services/tool-call-cache/index.d.ts +2 -2
  1153. package/services/tool-call-cache/index.d.ts.map +1 -1
  1154. package/services/tool-call-cache/index.js +1 -1
  1155. package/services/trigger-event-bridge.js +1 -1
  1156. package/services/tunnel-to-mobile/index.d.ts +2 -0
  1157. package/services/tunnel-to-mobile/index.d.ts.map +1 -0
  1158. package/services/tunnel-to-mobile/index.js +1 -0
  1159. package/services/tunnel-to-mobile/tunnel-to-mobile-client.d.ts +105 -0
  1160. package/services/tunnel-to-mobile/tunnel-to-mobile-client.d.ts.map +1 -0
  1161. package/services/tunnel-to-mobile/tunnel-to-mobile-client.js +190 -0
  1162. package/services/vault-bootstrap.d.ts.map +1 -1
  1163. package/services/vault-bootstrap.js +52 -21
  1164. package/services/vault-mirror.d.ts +1 -1
  1165. package/services/vault-mirror.d.ts.map +1 -1
  1166. package/services/vault-mirror.js +29 -6
  1167. package/services/voice-profiles/diarization-pipeline.d.ts +6 -0
  1168. package/services/voice-profiles/diarization-pipeline.d.ts.map +1 -0
  1169. package/services/voice-profiles/diarization-pipeline.js +20 -0
  1170. package/services/voice-profiles/index.d.ts +12 -0
  1171. package/services/voice-profiles/index.d.ts.map +1 -0
  1172. package/services/voice-profiles/index.js +5 -0
  1173. package/services/voice-profiles/nickname-evaluator.d.ts +14 -0
  1174. package/services/voice-profiles/nickname-evaluator.d.ts.map +1 -0
  1175. package/services/voice-profiles/nickname-evaluator.js +46 -0
  1176. package/services/voice-profiles/owner-confidence.d.ts +10 -0
  1177. package/services/voice-profiles/owner-confidence.d.ts.map +1 -0
  1178. package/services/voice-profiles/owner-confidence.js +38 -0
  1179. package/services/voice-profiles/private-challenge.d.ts +20 -0
  1180. package/services/voice-profiles/private-challenge.d.ts.map +1 -0
  1181. package/services/voice-profiles/private-challenge.js +44 -0
  1182. package/services/voice-profiles/store.d.ts +21 -0
  1183. package/services/voice-profiles/store.d.ts.map +1 -0
  1184. package/services/voice-profiles/store.js +50 -0
  1185. package/services/voice-profiles/types.d.ts +38 -0
  1186. package/services/voice-profiles/types.d.ts.map +1 -0
  1187. package/services/voice-profiles/types.js +1 -0
  1188. package/styles/electrobun-mac-window-drag.css +4 -4
  1189. package/test/helpers/__tests__/live-agent-test.smoke.test.ts +43 -70
  1190. package/test/helpers/browser-mocks.ts +2 -2
  1191. package/test/helpers/conditional-tests.ts +2 -2
  1192. package/test/helpers/live-agent-test.ts +537 -551
  1193. package/test/helpers/live-provider.test.ts +95 -5
  1194. package/test/helpers/live-provider.ts +234 -56
  1195. package/test/helpers/live-runtime-server.ts +4 -4
  1196. package/test/helpers/pglite-runtime.ts +1 -1
  1197. package/test/helpers/real-runtime.ts +72 -20
  1198. package/test/helpers/trajectory-harness.ts +11 -7
  1199. package/test/scripts/start-eliza-live.ts +9 -0
  1200. package/test/scripts/test-parallel.mjs +1 -1
  1201. package/test/scripts/test-root-unit.mjs +6 -7
  1202. package/test/scripts/websocket-pending-queue.test.ts +119 -0
  1203. package/test-support/test-helpers.d.ts +0 -33
  1204. package/test-support/test-helpers.d.ts.map +1 -1
  1205. package/test-support/test-helpers.js +81 -189
  1206. package/ui-compat.d.ts +14 -2
  1207. package/ui-compat.d.ts.map +1 -1
  1208. package/ui-compat.js +23 -3
  1209. package/api/auth-pairing-compat-routes.d.ts +0 -17
  1210. package/api/auth-pairing-compat-routes.d.ts.map +0 -1
  1211. package/api/auth-pairing-compat-routes.js +0 -301
  1212. package/api/local-inference-compat-routes.d.ts +0 -16
  1213. package/api/local-inference-compat-routes.d.ts.map +0 -1
  1214. package/api/local-inference-compat-routes.js +0 -617
  1215. package/api/onboarding-compat-routes.d.ts +0 -4
  1216. package/api/onboarding-compat-routes.d.ts.map +0 -1
  1217. package/api/onboarding-compat-routes.js +0 -207
  1218. package/api/plugins-compat-routes.d.ts +0 -103
  1219. package/api/plugins-compat-routes.d.ts.map +0 -1
  1220. package/api/plugins-compat-routes.js +0 -1181
  1221. package/api/server-onboarding-compat.d.ts +0 -31
  1222. package/api/server-onboarding-compat.d.ts.map +0 -1
  1223. package/api/server-onboarding-compat.js +0 -283
  1224. package/benchmark/cua-routes.d.ts +0 -10
  1225. package/benchmark/cua-routes.d.ts.map +0 -1
  1226. package/benchmark/cua-routes.js +0 -179
  1227. package/benchmark/mock-plugin-base.d.ts +0 -9
  1228. package/benchmark/mock-plugin-base.d.ts.map +0 -1
  1229. package/benchmark/mock-plugin-base.js +0 -325
  1230. package/cli/parse-duration.d.ts +0 -5
  1231. package/cli/parse-duration.d.ts.map +0 -1
  1232. package/cli/parse-duration.js +0 -27
  1233. package/patches/llama-cpp-capacitor@0.1.5.patch +0 -2387
  1234. package/platform/agent-browser-stub.d.ts +0 -27
  1235. package/platform/agent-browser-stub.d.ts.map +0 -1
  1236. package/platform/agent-browser-stub.js +0 -16
  1237. package/platforms/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +0 -26
  1238. package/platforms/android/app/src/main/res/drawable/ic_launcher_background.xml +0 -170
  1239. package/platforms/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -34
  1240. package/platforms/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +0 -18
  1241. package/platforms/electrobun/assets/appIcon.iconset/icon_512x512@2x.png +0 -0
  1242. package/platforms/electrobun/assets/appIcon.png +0 -0
  1243. package/platforms/electrobun/scripts/build-whisper-universal.sh +0 -137
  1244. package/platforms/electrobun/scripts/build-whisper.sh +0 -95
  1245. package/platforms/electrobun/scripts/ensure-whisper-model.sh +0 -93
  1246. package/platforms/electrobun/src/libMacWindowEffects.dylib +0 -0
  1247. package/platforms/electrobun/src/native/whisper.ts +0 -280
  1248. package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png +0 -0
  1249. package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png +0 -0
  1250. package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png +0 -0
  1251. package/registry/generate-apps.d.ts +0 -2
  1252. package/registry/generate-apps.d.ts.map +0 -1
  1253. package/registry/generate-apps.js +0 -338
  1254. package/registry/generate.d.ts +0 -2
  1255. package/registry/generate.d.ts.map +0 -1
  1256. package/registry/generate.js +0 -506
  1257. package/registry/loader.d.ts +0 -27
  1258. package/registry/loader.d.ts.map +0 -1
  1259. package/registry/loader.js +0 -111
  1260. package/registry/schema.d.ts +0 -989
  1261. package/registry/schema.d.ts.map +0 -1
  1262. package/registry/schema.js +0 -264
  1263. package/runtime/embedding-manager-support.d.ts +0 -77
  1264. package/runtime/embedding-manager-support.d.ts.map +0 -1
  1265. package/runtime/embedding-manager-support.js +0 -309
  1266. package/runtime/embedding-presets.d.ts +0 -5
  1267. package/runtime/embedding-presets.d.ts.map +0 -1
  1268. package/runtime/embedding-presets.js +0 -47
  1269. package/runtime/embedding-warmup-policy.d.ts +0 -13
  1270. package/runtime/embedding-warmup-policy.d.ts.map +0 -1
  1271. package/runtime/embedding-warmup-policy.js +0 -33
  1272. package/runtime/ensure-local-inference-handler.d.ts +0 -25
  1273. package/runtime/ensure-local-inference-handler.d.ts.map +0 -1
  1274. package/runtime/ensure-local-inference-handler.js +0 -389
  1275. package/runtime/mobile-local-inference-gate.d.ts +0 -21
  1276. package/runtime/mobile-local-inference-gate.d.ts.map +0 -1
  1277. package/runtime/mobile-local-inference-gate.js +0 -24
  1278. package/scripts/aosp/avd-test.mjs +0 -403
  1279. package/scripts/aosp/boot-validate.mjs +0 -536
  1280. package/scripts/aosp/build-aosp.mjs +0 -448
  1281. package/scripts/aosp/build-bootanimation.mjs +0 -178
  1282. package/scripts/aosp/capture-screens.mjs +0 -325
  1283. package/scripts/aosp/e2e-validate.mjs +0 -225
  1284. package/scripts/aosp/lint-init-rc.mjs +0 -258
  1285. package/scripts/aosp/llama-shim/eliza_llama_shim.c +0 -276
  1286. package/scripts/aosp/sim.mjs +0 -277
  1287. package/scripts/aosp/sync-to-aosp.mjs +0 -134
  1288. package/scripts/aosp/validate.mjs +0 -1273
  1289. package/scripts/build-llama-cpp-dflash.mjs +0 -1866
  1290. package/scripts/generate-onboarding-voicelines.mjs +0 -194
  1291. package/scripts/generated/static-asset-manifest.json +0 -4
  1292. package/scripts/normalize-parallax-capture.ts +0 -97
  1293. package/scripts/omnivoice-fuse/Makefile +0 -44
  1294. package/scripts/omnivoice-fuse/README.md +0 -266
  1295. package/scripts/omnivoice-fuse/cmake-graft.mjs +0 -180
  1296. package/scripts/omnivoice-fuse/ffi-stub.c +0 -222
  1297. package/scripts/omnivoice-fuse/ffi.h +0 -158
  1298. package/scripts/omnivoice-fuse/libelizainference_stub.dylib +0 -0
  1299. package/scripts/omnivoice-fuse/verify-symbols.mjs +0 -138
  1300. package/security/cloud-secret-store.d.ts +0 -34
  1301. package/security/cloud-secret-store.d.ts.map +0 -1
  1302. package/security/cloud-secret-store.js +0 -65
  1303. package/security/export-guard.d.ts +0 -34
  1304. package/security/export-guard.d.ts.map +0 -1
  1305. package/security/export-guard.js +0 -127
  1306. package/services/local-inference/__stress__/cache-stress-helpers.d.ts +0 -76
  1307. package/services/local-inference/__stress__/cache-stress-helpers.d.ts.map +0 -1
  1308. package/services/local-inference/__stress__/cache-stress-helpers.js +0 -238
  1309. package/services/local-inference/active-model.d.ts +0 -180
  1310. package/services/local-inference/active-model.d.ts.map +0 -1
  1311. package/services/local-inference/active-model.js +0 -362
  1312. package/services/local-inference/assignments.d.ts +0 -58
  1313. package/services/local-inference/assignments.d.ts.map +0 -1
  1314. package/services/local-inference/assignments.js +0 -179
  1315. package/services/local-inference/backend.d.ts +0 -200
  1316. package/services/local-inference/backend.d.ts.map +0 -1
  1317. package/services/local-inference/backend.js +0 -242
  1318. package/services/local-inference/bundled-models.d.ts +0 -34
  1319. package/services/local-inference/bundled-models.d.ts.map +0 -1
  1320. package/services/local-inference/bundled-models.js +0 -104
  1321. package/services/local-inference/cache-bridge.d.ts +0 -184
  1322. package/services/local-inference/cache-bridge.d.ts.map +0 -1
  1323. package/services/local-inference/cache-bridge.js +0 -333
  1324. package/services/local-inference/catalog.d.ts +0 -57
  1325. package/services/local-inference/catalog.d.ts.map +0 -1
  1326. package/services/local-inference/catalog.js +0 -262
  1327. package/services/local-inference/conversation-registry.d.ts +0 -122
  1328. package/services/local-inference/conversation-registry.d.ts.map +0 -1
  1329. package/services/local-inference/conversation-registry.js +0 -182
  1330. package/services/local-inference/device-bridge.d.ts +0 -139
  1331. package/services/local-inference/device-bridge.d.ts.map +0 -1
  1332. package/services/local-inference/device-bridge.js +0 -774
  1333. package/services/local-inference/dflash-doctor.d.ts +0 -27
  1334. package/services/local-inference/dflash-doctor.d.ts.map +0 -1
  1335. package/services/local-inference/dflash-doctor.js +0 -149
  1336. package/services/local-inference/dflash-server.d.ts +0 -248
  1337. package/services/local-inference/dflash-server.d.ts.map +0 -1
  1338. package/services/local-inference/dflash-server.js +0 -1076
  1339. package/services/local-inference/downloader.d.ts +0 -48
  1340. package/services/local-inference/downloader.d.ts.map +0 -1
  1341. package/services/local-inference/downloader.js +0 -688
  1342. package/services/local-inference/engine.d.ts +0 -282
  1343. package/services/local-inference/engine.d.ts.map +0 -1
  1344. package/services/local-inference/engine.js +0 -743
  1345. package/services/local-inference/external-scanner.d.ts +0 -17
  1346. package/services/local-inference/external-scanner.d.ts.map +0 -1
  1347. package/services/local-inference/external-scanner.js +0 -261
  1348. package/services/local-inference/handler-registry.d.ts +0 -72
  1349. package/services/local-inference/handler-registry.d.ts.map +0 -1
  1350. package/services/local-inference/handler-registry.js +0 -159
  1351. package/services/local-inference/hardware.d.ts +0 -26
  1352. package/services/local-inference/hardware.d.ts.map +0 -1
  1353. package/services/local-inference/hardware.js +0 -139
  1354. package/services/local-inference/hf-search.d.ts +0 -19
  1355. package/services/local-inference/hf-search.d.ts.map +0 -1
  1356. package/services/local-inference/hf-search.js +0 -169
  1357. package/services/local-inference/index.d.ts +0 -10
  1358. package/services/local-inference/index.d.ts.map +0 -1
  1359. package/services/local-inference/index.js +0 -7
  1360. package/services/local-inference/llama-server-metrics.d.ts +0 -108
  1361. package/services/local-inference/llama-server-metrics.d.ts.map +0 -1
  1362. package/services/local-inference/llama-server-metrics.js +0 -175
  1363. package/services/local-inference/manifest/index.d.ts +0 -4
  1364. package/services/local-inference/manifest/index.d.ts.map +0 -1
  1365. package/services/local-inference/manifest/index.js +0 -5
  1366. package/services/local-inference/manifest/schema.d.ts +0 -419
  1367. package/services/local-inference/manifest/schema.d.ts.map +0 -1
  1368. package/services/local-inference/manifest/schema.js +0 -227
  1369. package/services/local-inference/manifest/types.d.ts +0 -23
  1370. package/services/local-inference/manifest/types.d.ts.map +0 -1
  1371. package/services/local-inference/manifest/types.js +0 -5
  1372. package/services/local-inference/manifest/validator.d.ts +0 -43
  1373. package/services/local-inference/manifest/validator.d.ts.map +0 -1
  1374. package/services/local-inference/manifest/validator.js +0 -187
  1375. package/services/local-inference/paths.d.ts +0 -8
  1376. package/services/local-inference/paths.d.ts.map +0 -1
  1377. package/services/local-inference/paths.js +0 -7
  1378. package/services/local-inference/providers.d.ts +0 -61
  1379. package/services/local-inference/providers.d.ts.map +0 -1
  1380. package/services/local-inference/providers.js +0 -334
  1381. package/services/local-inference/ram-budget.d.ts +0 -57
  1382. package/services/local-inference/ram-budget.d.ts.map +0 -1
  1383. package/services/local-inference/ram-budget.js +0 -107
  1384. package/services/local-inference/readiness.d.ts +0 -9
  1385. package/services/local-inference/readiness.d.ts.map +0 -1
  1386. package/services/local-inference/readiness.js +0 -153
  1387. package/services/local-inference/recommendation.d.ts +0 -62
  1388. package/services/local-inference/recommendation.d.ts.map +0 -1
  1389. package/services/local-inference/recommendation.js +0 -309
  1390. package/services/local-inference/registry.d.ts +0 -35
  1391. package/services/local-inference/registry.d.ts.map +0 -1
  1392. package/services/local-inference/registry.js +0 -117
  1393. package/services/local-inference/router-handler.d.ts +0 -51
  1394. package/services/local-inference/router-handler.d.ts.map +0 -1
  1395. package/services/local-inference/router-handler.js +0 -165
  1396. package/services/local-inference/routing-policy.d.ts +0 -55
  1397. package/services/local-inference/routing-policy.d.ts.map +0 -1
  1398. package/services/local-inference/routing-policy.js +0 -195
  1399. package/services/local-inference/routing-preferences.d.ts +0 -8
  1400. package/services/local-inference/routing-preferences.d.ts.map +0 -1
  1401. package/services/local-inference/routing-preferences.js +0 -7
  1402. package/services/local-inference/service.d.ts +0 -88
  1403. package/services/local-inference/service.d.ts.map +0 -1
  1404. package/services/local-inference/service.js +0 -210
  1405. package/services/local-inference/session-pool.d.ts +0 -72
  1406. package/services/local-inference/session-pool.d.ts.map +0 -1
  1407. package/services/local-inference/session-pool.js +0 -125
  1408. package/services/local-inference/types.d.ts +0 -309
  1409. package/services/local-inference/types.d.ts.map +0 -1
  1410. package/services/local-inference/types.js +0 -23
  1411. package/services/local-inference/verify.d.ts +0 -8
  1412. package/services/local-inference/verify.d.ts.map +0 -1
  1413. package/services/local-inference/verify.js +0 -7
  1414. package/services/local-inference/voice/barge-in.d.ts +0 -15
  1415. package/services/local-inference/voice/barge-in.d.ts.map +0 -1
  1416. package/services/local-inference/voice/barge-in.js +0 -20
  1417. package/services/local-inference/voice/engine-bridge.d.ts +0 -256
  1418. package/services/local-inference/voice/engine-bridge.d.ts.map +0 -1
  1419. package/services/local-inference/voice/engine-bridge.js +0 -398
  1420. package/services/local-inference/voice/ffi-bindings.d.ts +0 -114
  1421. package/services/local-inference/voice/ffi-bindings.d.ts.map +0 -1
  1422. package/services/local-inference/voice/ffi-bindings.js +0 -281
  1423. package/services/local-inference/voice/index.d.ts +0 -51
  1424. package/services/local-inference/voice/index.d.ts.map +0 -1
  1425. package/services/local-inference/voice/index.js +0 -50
  1426. package/services/local-inference/voice/lifecycle.d.ts +0 -135
  1427. package/services/local-inference/voice/lifecycle.d.ts.map +0 -1
  1428. package/services/local-inference/voice/lifecycle.js +0 -189
  1429. package/services/local-inference/voice/phoneme-tokenizer.d.ts +0 -58
  1430. package/services/local-inference/voice/phoneme-tokenizer.d.ts.map +0 -1
  1431. package/services/local-inference/voice/phoneme-tokenizer.js +0 -53
  1432. package/services/local-inference/voice/phrase-cache.d.ts +0 -24
  1433. package/services/local-inference/voice/phrase-cache.d.ts.map +0 -1
  1434. package/services/local-inference/voice/phrase-cache.js +0 -32
  1435. package/services/local-inference/voice/phrase-chunker.d.ts +0 -20
  1436. package/services/local-inference/voice/phrase-chunker.d.ts.map +0 -1
  1437. package/services/local-inference/voice/phrase-chunker.js +0 -85
  1438. package/services/local-inference/voice/ring-buffer.d.ts +0 -40
  1439. package/services/local-inference/voice/ring-buffer.d.ts.map +0 -1
  1440. package/services/local-inference/voice/ring-buffer.js +0 -85
  1441. package/services/local-inference/voice/rollback-queue.d.ts +0 -24
  1442. package/services/local-inference/voice/rollback-queue.d.ts.map +0 -1
  1443. package/services/local-inference/voice/rollback-queue.js +0 -49
  1444. package/services/local-inference/voice/scheduler.d.ts +0 -47
  1445. package/services/local-inference/voice/scheduler.d.ts.map +0 -1
  1446. package/services/local-inference/voice/scheduler.js +0 -123
  1447. package/services/local-inference/voice/shared-resources.d.ts +0 -119
  1448. package/services/local-inference/voice/shared-resources.d.ts.map +0 -1
  1449. package/services/local-inference/voice/shared-resources.js +0 -83
  1450. package/services/local-inference/voice/speaker-preset-cache.d.ts +0 -28
  1451. package/services/local-inference/voice/speaker-preset-cache.d.ts.map +0 -1
  1452. package/services/local-inference/voice/speaker-preset-cache.js +0 -44
  1453. package/services/local-inference/voice/types.d.ts +0 -80
  1454. package/services/local-inference/voice/types.d.ts.map +0 -1
  1455. package/services/local-inference/voice/voice-preset-format.d.ts +0 -56
  1456. package/services/local-inference/voice/voice-preset-format.d.ts.map +0 -1
  1457. package/services/local-inference/voice/voice-preset-format.js +0 -184
  1458. package/services/plugin-installer.d.ts +0 -22
  1459. package/services/plugin-installer.d.ts.map +0 -1
  1460. package/services/plugin-installer.js +0 -41
  1461. package/test/helpers/i18n.ts +0 -5
  1462. package/test/helpers/loopback.ts +0 -33
  1463. package/test/helpers/react-test.ts +0 -40
  1464. package/test/helpers/skip-without.ts +0 -53
  1465. package/test/scripts/task-agent-live-smoke.ts +0 -1335
  1466. /package/services/{local-inference/voice → ambient-audio}/types.js +0 -0
@@ -16,7 +16,10 @@ import android.util.Log;
16
16
 
17
17
  import androidx.core.app.NotificationCompat;
18
18
 
19
- import ByteArrayOutputStream;
19
+ import ai.elizaos.app.BuildConfig;
20
+ import ai.elizaos.app.R;
21
+
22
+ import java.io.ByteArrayOutputStream;
20
23
  import java.io.File;
21
24
  import java.io.FileOutputStream;
22
25
  import java.io.IOException;
@@ -24,12 +27,18 @@ import java.io.InputStream;
24
27
  import java.io.OutputStream;
25
28
  import java.nio.charset.StandardCharsets;
26
29
  import java.net.HttpURLConnection;
30
+ import java.net.InetSocketAddress;
31
+ import java.net.Socket;
27
32
  import java.net.URL;
28
33
  import java.util.ArrayList;
29
34
  import java.util.LinkedHashMap;
30
35
  import java.util.List;
36
+ import java.util.Locale;
31
37
  import java.util.Map;
32
38
 
39
+ import org.json.JSONException;
40
+ import org.json.JSONObject;
41
+
33
42
  /**
34
43
  * Foreground service that owns the local Eliza agent process on Android.
35
44
  *
@@ -53,10 +62,10 @@ public class ElizaAgentService extends Service {
53
62
  private static final int NOTIFICATION_ID = 2;
54
63
 
55
64
  // Intent actions
56
- public static final String ACTION_START = "ai.elizaos.app.action.START_AGENT";
57
- public static final String ACTION_STOP = "ai.elizaos.app.action.STOP_AGENT";
58
- public static final String ACTION_RESTART = "ai.elizaos.app.action.RESTART_AGENT";
59
- public static final String ACTION_UPDATE_STATUS = "ai.elizaos.app.action.UPDATE_AGENT_STATUS";
65
+ public static final String ACTION_START = "app.eliza.action.START_AGENT";
66
+ public static final String ACTION_STOP = "app.eliza.action.STOP_AGENT";
67
+ public static final String ACTION_RESTART = "app.eliza.action.RESTART_AGENT";
68
+ public static final String ACTION_UPDATE_STATUS = "app.eliza.action.UPDATE_AGENT_STATUS";
60
69
 
61
70
  // Extras
62
71
  private static final String EXTRA_STATUS = "status";
@@ -87,9 +96,28 @@ public class ElizaAgentService extends Service {
87
96
  private static final int AGENT_PORT = 31337;
88
97
  private static final String HEALTH_URL = "http://127.0.0.1:" + AGENT_PORT + "/api/health";
89
98
 
99
+ /**
100
+ * Abstract-namespace AF_UNIX socket the in-process bionic GPU inference
101
+ * server ({@link ElizaBionicInferenceServer}) binds, and the musl agent's
102
+ * BionicHostLoader connects to. Abstract namespace (no filesystem path)
103
+ * avoids SELinux file-label issues under the priv_app domain. The musl
104
+ * agent reaches it as {@code Bun.connect({unix:"\0" + name})}.
105
+ */
106
+ static final String BIONIC_INFERENCE_SOCKET_NAME = "eliza_bionic_infer_v1";
107
+ private static final String LOCAL_AGENT_BASE_URL = "http://127.0.0.1:" + AGENT_PORT;
108
+ private static final int LOCAL_REQUEST_DEFAULT_TIMEOUT_MS = 10_000;
109
+ private static final int LOCAL_REQUEST_MAX_TIMEOUT_MS = 600_000;
110
+ // Read-timeout budget applied to slow on-device inference routes (ASR / TTS
111
+ // / transcription / chat generation) when the caller doesn't pin its own —
112
+ // matches LOCAL_REQUEST_MAX_TIMEOUT_MS and the agent's chat-generation
113
+ // budget so a cold model load never trips a spurious local_agent_unavailable.
114
+ private static final int LOCAL_INFERENCE_REQUEST_TIMEOUT_MS = 600_000;
115
+ private static final int LOCAL_REQUEST_MAX_BODY_BYTES = 10 * 1024 * 1024;
116
+ private static final int LOCAL_REQUEST_MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
117
+
90
118
  // The on-device boot path is heavy: PGlite extension extraction +
91
119
  // plugin resolution + libllama dlopen + first-time model load can
92
- // exceed 240 s on a cold cuttlefish x86_64 image. The chat path is
120
+ // exceed several minutes on a cold cuttlefish x86_64 image. The chat path is
93
121
  // even heavier: a single planner-produced prompt at ~12k tokens,
94
122
  // chunked through llama_decode on emulated CPU, can run 15–30 min
95
123
  // wall-clock for a single chat turn (multiple model invocations:
@@ -102,7 +130,7 @@ public class ElizaAgentService extends Service {
102
130
  // event loop yet), we DO NOT count a strike — the process is doing
103
131
  // exactly what it should be doing, just synchronously inside a
104
132
  // native call. We only count strikes when the process is actually
105
- // dead OR returns 5xx from /api/health (a real crash signal).
133
+ // dead OR returns non-2xx / non-ready health (a real crash signal).
106
134
  // Strikes accumulate when the process is dead, which forces a
107
135
  // restart via the existing scheduleRestart() path.
108
136
  //
@@ -116,16 +144,29 @@ public class ElizaAgentService extends Service {
116
144
  private static final long WATCHDOG_INTERVAL_MS = 600_000L;
117
145
  private static final int HEALTH_FAIL_STRIKES = 3;
118
146
  private static final long HEALTH_TIMEOUT_MS = 30_000L;
147
+ // Keep this aligned with packages/app/scripts/mobile-local-chat-smoke.mjs:
148
+ // ANDROID_HEALTH_ATTEMPTS (240) × 2000 ms = 480 s.
149
+ private static final long STARTUP_HEALTH_GRACE_MS = 480_000L;
150
+ private static final long STARTUP_HEALTH_POLL_MS = 5_000L;
119
151
  private static final int MAX_RESTART_ATTEMPTS = 5;
120
152
  private static final long PROCESS_TERMINATE_GRACE_MS = 5_000L;
153
+ // How long after a detached launch we treat a not-yet-listening agent as
154
+ // "still cold-booting" and refuse to relaunch it (the boot — plugin
155
+ // resolution + first model load — runs ~60-90s on an emulated CPU). Past
156
+ // this the boot is considered failed and a relaunch is allowed.
157
+ private static final long AGENT_BOOT_GRACE_MS = 120_000L;
121
158
 
122
159
  private final Object processLock = new Object();
123
160
  private Process agentProcess;
124
161
  private Thread stdoutPump;
125
162
  private Thread stderrPump;
126
163
  private WatchdogThread watchdog;
164
+ /** In-process bionic GPU inference host; non-null only when delegating. */
165
+ private volatile ElizaBionicInferenceServer bionicInferenceServer;
127
166
  private Thread startWorker;
128
167
  private volatile boolean shuttingDown;
168
+ private volatile boolean detachedAgentMode;
169
+ private volatile long detachedLaunchStartedAtMs;
129
170
  private int restartAttempts;
130
171
  private String currentStatus = "starting";
131
172
 
@@ -136,12 +177,424 @@ public class ElizaAgentService extends Service {
136
177
  // include `Authorization: Bearer <token>`. The agent enforces the
137
178
  // token via ELIZA_REQUIRE_LOCAL_AUTH=1.
138
179
  private static volatile String currentLocalAgentToken;
180
+ private static volatile String currentTerminalRunToken;
139
181
 
140
182
  /** Called by the Capacitor agent plugin Android binding. */
141
183
  public static String localAgentToken() {
142
184
  return currentLocalAgentToken;
143
185
  }
144
186
 
187
+ /**
188
+ * Cross-process token recovery. The token is a per-process static, but the
189
+ * bun agent is a DETACHED process that outlives the app process that started
190
+ * it — so a freshly-launched WebView process (e.g. after a boot autostart)
191
+ * sees a null static even though a healthy agent is running, which dead-ends
192
+ * the dashboard at the pairing screen. Fall back to the recovery file that
193
+ * {@link #writeLocalAgentTokenFile} persists, and cache it for this process.
194
+ */
195
+ public static String localAgentToken(Context context) {
196
+ String token = currentLocalAgentToken;
197
+ if (token != null && !token.trim().isEmpty()) {
198
+ return token;
199
+ }
200
+ if (context == null) {
201
+ return token;
202
+ }
203
+ String fromFile = readLocalAgentTokenFile(context);
204
+ if (fromFile != null && !fromFile.trim().isEmpty()) {
205
+ currentLocalAgentToken = fromFile.trim();
206
+ return currentLocalAgentToken;
207
+ }
208
+ return token;
209
+ }
210
+
211
+ private static String readLocalAgentTokenFile(Context context) {
212
+ File file = new File(new File(context.getFilesDir(), "auth"), "local-agent-token");
213
+ if (!file.isFile()) {
214
+ return null;
215
+ }
216
+ try (java.io.FileInputStream in = new java.io.FileInputStream(file)) {
217
+ java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
218
+ byte[] buf = new byte[256];
219
+ int n;
220
+ while ((n = in.read(buf)) != -1) {
221
+ bos.write(buf, 0, n);
222
+ }
223
+ return new String(bos.toByteArray(), java.nio.charset.StandardCharsets.UTF_8).trim();
224
+ } catch (IOException error) {
225
+ Log.w(TAG, "Unable to read local-agent token file: " + error.getMessage());
226
+ return null;
227
+ }
228
+ }
229
+
230
+ /** Called by trusted in-app code that needs to route shell requests. */
231
+ public static String terminalRunToken() {
232
+ return currentTerminalRunToken;
233
+ }
234
+
235
+ /**
236
+ * Shared in-process request surface for Android native plugins and workers.
237
+ *
238
+ * The current Android agent still serves routes from the Bun child process
239
+ * over loopback, but callers should route through this method instead of
240
+ * opening their own sockets. That keeps auth, header filtering, body caps,
241
+ * and future Binder/stdio replacement behind one app-owned boundary.
242
+ */
243
+ /**
244
+ * Routes whose on-device handler does a synchronous, multi-second (cold
245
+ * model load) or open-ended (token-by-token generation) llama call before
246
+ * the HTTP response completes — they need the long inference read-timeout
247
+ * budget, not the 10s default used for ordinary CRUD API calls.
248
+ */
249
+ private static boolean isLongRunningInferencePath(String path) {
250
+ if (path == null) return false;
251
+ String p = path.toLowerCase(Locale.US);
252
+ return p.contains("/asr")
253
+ || p.contains("/tts")
254
+ || p.contains("/transcription")
255
+ || p.contains("/speech")
256
+ || p.contains("/local-inference")
257
+ || p.contains("/messages/stream")
258
+ || p.contains("/messages")
259
+ || p.contains("/greeting")
260
+ || p.contains("/voice");
261
+ }
262
+
263
+ public static String requestLocalAgent(String requestJson) throws IOException, JSONException {
264
+ JSONObject request = requestJson == null || requestJson.trim().isEmpty()
265
+ ? new JSONObject()
266
+ : new JSONObject(requestJson);
267
+ String path = request.optString("path", "").trim();
268
+ if (!isSafeLocalAgentPath(path)) {
269
+ throw new IllegalArgumentException("Local agent request requires a path that starts with /");
270
+ }
271
+ String method = request.optString("method", "GET")
272
+ .trim()
273
+ .toUpperCase(Locale.US);
274
+ if (!method.matches("^[A-Z]{1,16}$")) {
275
+ throw new IllegalArgumentException("Unsupported HTTP method");
276
+ }
277
+ int timeoutMs = request.optInt("timeoutMs", LOCAL_REQUEST_DEFAULT_TIMEOUT_MS);
278
+ // On-device inference is inherently slow: a cold model load alone — the
279
+ // ~1 GB ASR GGUF, the OmniVoice TTS GGUFs, or evicting + reloading the
280
+ // chat model — is a multi-second synchronous llama load before the agent
281
+ // emits a single byte, and transcription/synthesis/generation on
282
+ // emulated or low-end CPU runs well past 10 s. The WebView transport
283
+ // sends its generic 10 s fetch timeout for these calls too, which aborts
284
+ // them mid-decode and surfaces "Local agent request failed" /
285
+ // local_agent_unavailable, failing the whole voice turn (and every route
286
+ // that touches inference). FLOOR inference/voice routes at the inference
287
+ // budget — raise a too-short caller timeout, never lower a longer one.
288
+ if (isLongRunningInferencePath(path)) {
289
+ timeoutMs = Math.max(timeoutMs, LOCAL_INFERENCE_REQUEST_TIMEOUT_MS);
290
+ }
291
+ timeoutMs = Math.max(1_000, Math.min(timeoutMs, LOCAL_REQUEST_MAX_TIMEOUT_MS));
292
+ JSONObject headers = request.optJSONObject("headers");
293
+ Object rawBody = request.opt("body");
294
+ String body = rawBody == null || rawBody == JSONObject.NULL ? null : rawBody.toString();
295
+
296
+ return performLocalAgentRequest(
297
+ method,
298
+ path,
299
+ headers == null ? new JSONObject() : headers,
300
+ body,
301
+ timeoutMs,
302
+ currentLocalAgentToken
303
+ ).toString();
304
+ }
305
+
306
+ /**
307
+ * Streaming variant of {@link #requestLocalAgent}. Where that buffers the
308
+ * whole loopback response into one JSON string (so an SSE body's token
309
+ * frames arrive all at once and the chat reply never streams on mobile),
310
+ * this opens the same request and reads the response InputStream
311
+ * INCREMENTALLY, pushing each fragment to {@code onEvent} as a small JSON
312
+ * envelope the AgentPlugin maps to Capacitor events:
313
+ * {"type":"response","status":..,"statusText":..,"headers":{..}} (once, first)
314
+ * {"type":"chunk","dataBase64":".."} (per read)
315
+ * {"type":"complete"} or {"type":"complete","error":".."} (terminal)
316
+ *
317
+ * Single attempt by design: a connect failure emits a terminal error event
318
+ * and the WebView falls back to the buffered {@link #requestLocalAgent}
319
+ * (which carries the cold-load connect retry), so non-idempotent POSTs are
320
+ * never replayed here. Runs on the caller's thread (AgentPlugin spawns one).
321
+ */
322
+ public static void requestLocalAgentStream(String requestJson, java.util.function.Consumer<String> onEvent) {
323
+ try {
324
+ JSONObject request = requestJson == null || requestJson.trim().isEmpty()
325
+ ? new JSONObject()
326
+ : new JSONObject(requestJson);
327
+ String path = request.optString("path", "").trim();
328
+ if (!isSafeLocalAgentPath(path)) {
329
+ throw new IllegalArgumentException("Local agent request requires a path that starts with /");
330
+ }
331
+ String method = request.optString("method", "GET").trim().toUpperCase(Locale.US);
332
+ if (!method.matches("^[A-Z]{1,16}$")) {
333
+ throw new IllegalArgumentException("Unsupported HTTP method");
334
+ }
335
+ int timeoutMs = request.optInt("timeoutMs", LOCAL_REQUEST_DEFAULT_TIMEOUT_MS);
336
+ if (isLongRunningInferencePath(path)) {
337
+ timeoutMs = Math.max(timeoutMs, LOCAL_INFERENCE_REQUEST_TIMEOUT_MS);
338
+ }
339
+ timeoutMs = Math.max(1_000, Math.min(timeoutMs, LOCAL_REQUEST_MAX_TIMEOUT_MS));
340
+ JSONObject headers = request.optJSONObject("headers");
341
+ if (headers == null) headers = new JSONObject();
342
+ Object rawBody = request.opt("body");
343
+ String body = rawBody == null || rawBody == JSONObject.NULL ? null : rawBody.toString();
344
+ streamLocalAgentRequest(method, path, headers, body, timeoutMs, currentLocalAgentToken, onEvent);
345
+ } catch (Exception error) {
346
+ emitStreamComplete(onEvent, error.getMessage() == null ? "Local agent stream failed" : error.getMessage());
347
+ }
348
+ }
349
+
350
+ private static void streamLocalAgentRequest(
351
+ String method,
352
+ String path,
353
+ JSONObject headers,
354
+ String body,
355
+ int timeoutMs,
356
+ String token,
357
+ java.util.function.Consumer<String> onEvent
358
+ ) throws IOException, JSONException {
359
+ byte[] bodyBytes = body == null ? null : body.getBytes(StandardCharsets.UTF_8);
360
+ if (bodyBytes != null && bodyBytes.length > LOCAL_REQUEST_MAX_BODY_BYTES) {
361
+ throw new IOException("Request body is too large");
362
+ }
363
+
364
+ HttpURLConnection conn = null;
365
+ try {
366
+ URL url = new URL(LOCAL_AGENT_BASE_URL + path);
367
+ conn = (HttpURLConnection) url.openConnection();
368
+ conn.setRequestMethod(method);
369
+ conn.setConnectTimeout(timeoutMs);
370
+ conn.setReadTimeout(timeoutMs);
371
+ conn.setInstanceFollowRedirects(false);
372
+ conn.setUseCaches(false);
373
+ applyLocalAgentHeaders(conn, headers);
374
+ if (token != null && !token.trim().isEmpty() && !hasHeader(headers, "authorization")) {
375
+ conn.setRequestProperty("Authorization", "Bearer " + token.trim());
376
+ }
377
+ if (bodyBytes != null && !"GET".equals(method) && !"HEAD".equals(method)) {
378
+ if (!hasHeader(headers, "content-type")) {
379
+ conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
380
+ }
381
+ conn.setDoOutput(true);
382
+ try (OutputStream out = conn.getOutputStream()) {
383
+ out.write(bodyBytes);
384
+ out.flush();
385
+ }
386
+ }
387
+
388
+ int status = conn.getResponseCode();
389
+ JSONObject responseHeaders = new JSONObject();
390
+ for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
391
+ String key = entry.getKey();
392
+ List<String> values = entry.getValue();
393
+ if (key == null || values == null || values.isEmpty()) continue;
394
+ responseHeaders.put(key.toLowerCase(Locale.US), String.join(", ", values));
395
+ }
396
+ onEvent.accept(new JSONObject()
397
+ .put("type", "response")
398
+ .put("status", status)
399
+ .put("statusText", conn.getResponseMessage() == null ? "" : conn.getResponseMessage())
400
+ .put("headers", responseHeaders)
401
+ .toString());
402
+
403
+ // Read the body as it arrives. The agent flushes each SSE frame, so a
404
+ // blocking read returns per-frame rather than waiting for the whole
405
+ // body — that is exactly the incremental delivery the WebView needs.
406
+ InputStream stream = status >= 400 ? conn.getErrorStream() : conn.getInputStream();
407
+ if (stream != null) {
408
+ byte[] buffer = new byte[8192];
409
+ int read;
410
+ while ((read = stream.read(buffer)) != -1) {
411
+ if (read == 0) continue;
412
+ String dataBase64 = android.util.Base64.encodeToString(
413
+ java.util.Arrays.copyOf(buffer, read), android.util.Base64.NO_WRAP);
414
+ onEvent.accept(new JSONObject()
415
+ .put("type", "chunk")
416
+ .put("dataBase64", dataBase64)
417
+ .toString());
418
+ }
419
+ }
420
+ emitStreamComplete(onEvent, null);
421
+ } finally {
422
+ if (conn != null) conn.disconnect();
423
+ }
424
+ }
425
+
426
+ private static void emitStreamComplete(java.util.function.Consumer<String> onEvent, String error) {
427
+ try {
428
+ JSONObject complete = new JSONObject().put("type", "complete");
429
+ if (error != null) complete.put("error", error);
430
+ onEvent.accept(complete.toString());
431
+ } catch (JSONException ignored) {
432
+ // A complete event with no error is the worst case if JSON fails.
433
+ onEvent.accept("{\"type\":\"complete\"}");
434
+ }
435
+ }
436
+
437
+ private static boolean isSafeLocalAgentPath(String path) {
438
+ return path != null
439
+ && path.startsWith("/")
440
+ && !path.startsWith("//")
441
+ && !path.contains("://");
442
+ }
443
+
444
+ private static JSONObject performLocalAgentRequest(
445
+ String method,
446
+ String path,
447
+ JSONObject headers,
448
+ String body,
449
+ int timeoutMs,
450
+ String token
451
+ ) throws IOException, JSONException {
452
+ // The on-device agent is single-threaded: while bun is inside a long
453
+ // synchronous FFI call (a cold ASR/TTS model load, or a llama_decode for
454
+ // a chat reply) its HTTP listener briefly stops accepting connections, so
455
+ // a concurrent request — e.g. createConversation right after a voice
456
+ // transcription — can hit "connection refused". The request bytes were
457
+ // never sent, so it is safe to back off and re-dial rather than surface a
458
+ // spurious local_agent_unavailable that fails the whole voice turn. Only
459
+ // connection-establishment failures are retried; a read timeout (request
460
+ // already sent) propagates so non-idempotent POSTs are never replayed.
461
+ // The window must outlast the longest event-loop stall: after a voice
462
+ // transcription the agent evicts + cold-reloads the chat model (a
463
+ // synchronous ~10-15 s llama load on phone CPU) before generating the
464
+ // reply, during which the HTTP listener refuses connections.
465
+ final int connectRetries = 15;
466
+ IOException lastConnectError = null;
467
+ for (int attempt = 0; attempt <= connectRetries; attempt++) {
468
+ try {
469
+ return performLocalAgentRequestOnce(
470
+ method, path, headers, body, timeoutMs, token);
471
+ } catch (java.net.ConnectException connectError) {
472
+ lastConnectError = connectError;
473
+ } catch (java.net.SocketTimeoutException timeoutError) {
474
+ // Distinguish connect-timeout (never sent → retry) from
475
+ // read-timeout (sent → must not replay). HttpURLConnection
476
+ // surfaces both as SocketTimeoutException; the connect phase
477
+ // message contains "connect".
478
+ String msg = timeoutError.getMessage();
479
+ if (msg != null && msg.toLowerCase(Locale.US).contains("connect")) {
480
+ lastConnectError = timeoutError;
481
+ } else {
482
+ throw timeoutError;
483
+ }
484
+ }
485
+ if (attempt < connectRetries) {
486
+ try {
487
+ Thread.sleep(250L * (attempt + 1));
488
+ } catch (InterruptedException interrupted) {
489
+ Thread.currentThread().interrupt();
490
+ throw lastConnectError;
491
+ }
492
+ }
493
+ }
494
+ throw lastConnectError != null
495
+ ? lastConnectError
496
+ : new IOException("local agent unreachable");
497
+ }
498
+
499
+ private static JSONObject performLocalAgentRequestOnce(
500
+ String method,
501
+ String path,
502
+ JSONObject headers,
503
+ String body,
504
+ int timeoutMs,
505
+ String token
506
+ ) throws IOException, JSONException {
507
+ byte[] bodyBytes = body == null ? null : body.getBytes(StandardCharsets.UTF_8);
508
+ if (bodyBytes != null && bodyBytes.length > LOCAL_REQUEST_MAX_BODY_BYTES) {
509
+ throw new IOException("Request body is too large");
510
+ }
511
+
512
+ HttpURLConnection conn = null;
513
+ try {
514
+ URL url = new URL(LOCAL_AGENT_BASE_URL + path);
515
+ conn = (HttpURLConnection) url.openConnection();
516
+ conn.setRequestMethod(method);
517
+ conn.setConnectTimeout(timeoutMs);
518
+ conn.setReadTimeout(timeoutMs);
519
+ conn.setInstanceFollowRedirects(false);
520
+ conn.setUseCaches(false);
521
+ applyLocalAgentHeaders(conn, headers);
522
+ if (token != null && !token.trim().isEmpty() && !hasHeader(headers, "authorization")) {
523
+ conn.setRequestProperty("Authorization", "Bearer " + token.trim());
524
+ }
525
+ if (bodyBytes != null && !"GET".equals(method) && !"HEAD".equals(method)) {
526
+ if (!hasHeader(headers, "content-type")) {
527
+ conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
528
+ }
529
+ conn.setDoOutput(true);
530
+ try (OutputStream out = conn.getOutputStream()) {
531
+ out.write(bodyBytes);
532
+ out.flush();
533
+ }
534
+ }
535
+
536
+ int status = conn.getResponseCode();
537
+ InputStream stream = status >= 400 ? conn.getErrorStream() : conn.getInputStream();
538
+ // Read the raw response bytes so binary payloads (e.g. local TTS WAV
539
+ // audio, images) survive the bridge intact. `body` is a best-effort
540
+ // UTF-8 view for text callers; `bodyBase64` carries the lossless raw
541
+ // bytes that binary callers decode — encoding the bytes as a UTF-8
542
+ // String first (the old path) replaced every non-UTF-8 byte with
543
+ // U+FFFD, corrupting WAV/PNG payloads beyond recovery.
544
+ byte[] responseBytes = readResponseBytes(stream, LOCAL_REQUEST_MAX_RESPONSE_BYTES);
545
+ String responseBody = new String(responseBytes, StandardCharsets.UTF_8);
546
+ JSONObject responseHeaders = new JSONObject();
547
+ for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
548
+ String key = entry.getKey();
549
+ List<String> values = entry.getValue();
550
+ if (key == null || values == null || values.isEmpty()) continue;
551
+ responseHeaders.put(key.toLowerCase(Locale.US), String.join(", ", values));
552
+ }
553
+ return new JSONObject()
554
+ .put("status", status)
555
+ .put("statusText", conn.getResponseMessage() == null ? "" : conn.getResponseMessage())
556
+ .put("headers", responseHeaders)
557
+ .put("body", responseBody)
558
+ .put(
559
+ "bodyBase64",
560
+ android.util.Base64.encodeToString(responseBytes, android.util.Base64.NO_WRAP)
561
+ )
562
+ .put("bodyEncoding", "base64");
563
+ } finally {
564
+ if (conn != null) conn.disconnect();
565
+ }
566
+ }
567
+
568
+ private static void applyLocalAgentHeaders(HttpURLConnection conn, JSONObject headers) {
569
+ if (headers == null) return;
570
+ java.util.Iterator<String> keys = headers.keys();
571
+ while (keys.hasNext()) {
572
+ String key = keys.next();
573
+ if (isBlockedForwardedHeader(key)) continue;
574
+ Object value = headers.opt(key);
575
+ if (value == null || value == JSONObject.NULL) continue;
576
+ String stringValue = value.toString();
577
+ if (!stringValue.trim().isEmpty()) {
578
+ conn.setRequestProperty(key, stringValue);
579
+ }
580
+ }
581
+ }
582
+
583
+ private static boolean hasHeader(JSONObject headers, String expected) {
584
+ if (headers == null) return false;
585
+ java.util.Iterator<String> keys = headers.keys();
586
+ while (keys.hasNext()) {
587
+ if (expected.equalsIgnoreCase(keys.next())) return true;
588
+ }
589
+ return false;
590
+ }
591
+
592
+ private static boolean isBlockedForwardedHeader(String key) {
593
+ return "host".equalsIgnoreCase(key)
594
+ || "connection".equalsIgnoreCase(key)
595
+ || "content-length".equalsIgnoreCase(key);
596
+ }
597
+
145
598
  // ── Lifecycle ────────────────────────────────────────────────────────
146
599
 
147
600
  @Override
@@ -201,6 +654,10 @@ public class ElizaAgentService extends Service {
201
654
  watchdog.interrupt();
202
655
  watchdog = null;
203
656
  }
657
+ if (bionicInferenceServer != null) {
658
+ bionicInferenceServer.stop();
659
+ bionicInferenceServer = null;
660
+ }
204
661
  stopAgentProcess();
205
662
  NotificationManager mgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
206
663
  if (mgr != null) {
@@ -226,7 +683,11 @@ public class ElizaAgentService extends Service {
226
683
  String[] supported = Build.SUPPORTED_ABIS;
227
684
  if (supported != null) {
228
685
  for (String abi : supported) {
229
- if ("arm64-v8a".equals(abi) || "x86_64".equals(abi)) return abi;
686
+ if (
687
+ "arm64-v8a".equals(abi) ||
688
+ "x86_64".equals(abi) ||
689
+ "riscv64".equals(abi)
690
+ ) return abi;
230
691
  }
231
692
  if (supported.length > 0) return supported[0];
232
693
  }
@@ -316,6 +777,10 @@ public class ElizaAgentService extends Service {
316
777
  if (initDbWasm.exists()) initDbWasm.delete();
317
778
  File pgData = new File(root, "pglite.data");
318
779
  if (pgData.exists()) pgData.delete();
780
+ File ortWasmLoader = new File(root, "ort-wasm-simd-threaded.mjs");
781
+ if (ortWasmLoader.exists()) ortWasmLoader.delete();
782
+ File ortWasmBinary = new File(root, "ort-wasm-simd-threaded.wasm");
783
+ if (ortWasmBinary.exists()) ortWasmBinary.delete();
319
784
  File vec = new File(getFilesDir(), "vector.tar.gz");
320
785
  if (vec.exists()) vec.delete();
321
786
  File fuzzy = new File(getFilesDir(), "fuzzystrmatch.tar.gz");
@@ -359,6 +824,13 @@ public class ElizaAgentService extends Service {
359
824
  copyAssetIfPresent(assets, "agent/pglite.wasm", new File(root, "pglite.wasm"));
360
825
  copyAssetIfPresent(assets, "agent/initdb.wasm", new File(root, "initdb.wasm"));
361
826
  copyAssetIfPresent(assets, "agent/pglite.data", new File(root, "pglite.data"));
827
+ // Legacy ONNX Runtime Web sidecars used by the removed Android Kokoro
828
+ // TTS path. Current AOSP TTS uses fused OmniVoice, so fresh bundles do
829
+ // not ship these files; keep extraction best-effort for older APKs.
830
+ copyAssetIfPresent(assets, "agent/ort-wasm-simd-threaded.mjs",
831
+ new File(root, "ort-wasm-simd-threaded.mjs"));
832
+ copyAssetIfPresent(assets, "agent/ort-wasm-simd-threaded.wasm",
833
+ new File(root, "ort-wasm-simd-threaded.wasm"));
362
834
  // aapt2 not only strips `.gz` from `*.tar.gz` asset names, it also
363
835
  // DECOMPRESSES them into raw tar bytes. PGlite's loader does
364
836
  // `new URL("../X.tar.gz", ...)` then pipes the bytes through
@@ -394,6 +866,8 @@ public class ElizaAgentService extends Service {
394
866
 
395
867
  File bun = new File(abiDir, BUN_BINARY);
396
868
  if (bun.exists()) bun.setExecutable(true, false);
869
+ File llamaServer = new File(abiDir, "llama-server");
870
+ if (llamaServer.exists()) llamaServer.setExecutable(true, false);
397
871
  File launch = new File(root, AGENT_LAUNCH_SCRIPT);
398
872
  if (launch.exists()) launch.setExecutable(true, false);
399
873
  for (String name : abiFiles) {
@@ -511,6 +985,7 @@ public class ElizaAgentService extends Service {
511
985
  private String packagedMuslLoaderName(String abi) {
512
986
  if ("arm64-v8a".equals(abi)) return "libeliza_ld_musl_aarch64.so";
513
987
  if ("x86_64".equals(abi)) return "libeliza_ld_musl_x86_64.so";
988
+ if ("riscv64".equals(abi)) return "libeliza_ld_musl_riscv64.so";
514
989
  return null;
515
990
  }
516
991
 
@@ -590,10 +1065,8 @@ public class ElizaAgentService extends Service {
590
1065
 
591
1066
  /**
592
1067
  * Like copyAssetIfMissing, but silently no-ops when the source asset is
593
- * absent. Used for PGlite + plugin-manifest payload that Phase D
594
- * generates only when the real agent bundle is built; with the spike
595
- * placeholder bundle the assets are simply not present and the agent
596
- * runs without them.
1068
+ * absent. Used for optional PGlite + plugin-manifest payloads; minimal
1069
+ * mobile bundles can run without those embedded database extensions.
597
1070
  */
598
1071
  private void copyAssetIfPresent(AssetManager assets, String assetPath, File target) throws IOException {
599
1072
  try (InputStream probe = assets.open(assetPath)) {
@@ -642,11 +1115,65 @@ public class ElizaAgentService extends Service {
642
1115
 
643
1116
  // ── Process lifecycle ────────────────────────────────────────────────
644
1117
 
1118
+ /**
1119
+ * Start the in-process bionic inference host whenever the fused native lib
1120
+ * AND a local voice bundle (kokoro) are present — independent of the LLM
1121
+ * runtime mode and of whether the agent process spawns fresh or adopts a
1122
+ * surviving one.
1123
+ *
1124
+ * <p>Previously the host was started ONLY inside {@link #startAgentProcess()}'s
1125
+ * fresh-spawn {@code delegateToBionicHost} block, so after a process restart
1126
+ * that adopts a surviving agent (or when the agent runs cloud-routed) the
1127
+ * host never bound its abstract UDS, and {@code TalkMode}'s local Kokoro TTS
1128
+ * silently fell back to the system (Google) TTS. The voice host serves Kokoro
1129
+ * from {@code libelizainference} + the staged bundle and needs no LLM, so its
1130
+ * lifecycle is decoupled from agent inference here.
1131
+ *
1132
+ * <p>{@link ElizaBionicInferenceServer#start()} is idempotent and never throws
1133
+ * (it logs + returns on lib-load / socket-bind failure), so this is purely
1134
+ * additive: worst case the host stays down and TalkMode falls back to system
1135
+ * TTS exactly as before — it cannot affect agent startup.
1136
+ */
1137
+ private synchronized void ensureBionicVoiceHost() {
1138
+ if (bionicInferenceServer != null) {
1139
+ return;
1140
+ }
1141
+ File fusedLib = new File(nativeLibraryDir(), "libelizainference.so");
1142
+ if (!fusedLib.isFile()) {
1143
+ return;
1144
+ }
1145
+ File kokoroVoice = new File(getFilesDir(), "eliza-1/bundle/tts/kokoro");
1146
+ if (!kokoroVoice.isDirectory()) {
1147
+ return;
1148
+ }
1149
+ try {
1150
+ String defaultBundleDir =
1151
+ new File(getFilesDir(), "eliza-1/bundle").getAbsolutePath();
1152
+ ElizaBionicInferenceServer host =
1153
+ new ElizaBionicInferenceServer(BIONIC_INFERENCE_SOCKET_NAME, defaultBundleDir);
1154
+ host.start();
1155
+ bionicInferenceServer = host;
1156
+ Log.i(TAG, "ensureBionicVoiceHost: local voice host started"
1157
+ + " (kokoro bundle present, independent of LLM mode)");
1158
+ } catch (Throwable t) {
1159
+ Log.w(TAG, "ensureBionicVoiceHost: could not start local voice host", t);
1160
+ }
1161
+ }
1162
+
645
1163
  private void requestAgentStart(boolean restartFirst) {
1164
+ // Bring up the local-voice (Kokoro TTS) bionic host on every service
1165
+ // start, before the agent-already-running guards below — so it binds
1166
+ // even when the agent is adopted rather than freshly spawned.
1167
+ ensureBionicVoiceHost();
646
1168
  synchronized (processLock) {
647
1169
  if (!restartFirst && agentProcess != null && agentProcess.isAlive()) {
648
1170
  return;
649
1171
  }
1172
+ if (!restartFirst
1173
+ && detachedAgentMode
1174
+ && ("starting".equals(currentStatus) || "running".equals(currentStatus))) {
1175
+ return;
1176
+ }
650
1177
  if (startWorker != null && startWorker.isAlive()) {
651
1178
  return;
652
1179
  }
@@ -674,6 +1201,47 @@ public class ElizaAgentService extends Service {
674
1201
  return;
675
1202
  }
676
1203
 
1204
+ // Detached agents outlive the service/app process that launched
1205
+ // them. If a prior instance's agent is still bound to the loopback
1206
+ // port, ADOPT it instead of relaunching: launch.sh pkills any
1207
+ // running bun before forking a fresh one, so a needless relaunch
1208
+ // tears the live HTTP listener down for tens of seconds and the
1209
+ // WebView's /api/auth/me startup probe fails with "Backend
1210
+ // Unreachable". That is the emulator e2e churn — the Activity/FGS
1211
+ // gets recreated mid-run and onStartCommand → startAgentProcess
1212
+ // would relaunch a perfectly healthy agent. Gate on the raw TCP
1213
+ // listener (not /api/health), so a bun that is alive but busy
1214
+ // mid-llama_decode — when an HTTP probe would time out — is still
1215
+ // recognised as running and left alone.
1216
+ if (detachedAgentMode && isLoopbackAgentListening()) {
1217
+ if (!"running".equals(currentStatus)) {
1218
+ currentStatus = "running";
1219
+ updateNotification();
1220
+ }
1221
+ Log.i(TAG, "Detached agent already listening on port " + AGENT_PORT
1222
+ + "; adopting it (no relaunch).");
1223
+ return;
1224
+ }
1225
+
1226
+ // The agent may have been launched moments ago and still be in its
1227
+ // (slow) cold boot — plugin resolution + first model load can take
1228
+ // 60-90s on an emulated CPU before bun binds the port. During that
1229
+ // window isLoopbackAgentListening() is false, so without this guard a
1230
+ // recreated Activity/FGS (onStartCommand fires repeatedly as the e2e
1231
+ // foregrounds/navigates) would relaunch.sh-pkill the booting bun and
1232
+ // restart the whole boot — an endless churn that never reaches ready.
1233
+ // If we launched within the boot grace window, assume it is still
1234
+ // coming up and leave it alone rather than kill + restart it.
1235
+ if (detachedAgentMode
1236
+ && detachedLaunchStartedAtMs > 0
1237
+ && (System.currentTimeMillis() - detachedLaunchStartedAtMs)
1238
+ < AGENT_BOOT_GRACE_MS) {
1239
+ Log.i(TAG, "Detached agent still in cold boot (launched "
1240
+ + (System.currentTimeMillis() - detachedLaunchStartedAtMs)
1241
+ + "ms ago); not relaunching.");
1242
+ return;
1243
+ }
1244
+
677
1245
  String abi = resolveRuntimeAbi();
678
1246
  try {
679
1247
  extractAssetsIfNeeded(abi);
@@ -687,6 +1255,7 @@ public class ElizaAgentService extends Service {
687
1255
  File root = agentRoot();
688
1256
  File abiDir = agentAbiDir(abi);
689
1257
  File bundle = new File(root, AGENT_BUNDLE_NAME);
1258
+ File launchScript = new File(root, AGENT_LAUNCH_SCRIPT);
690
1259
  File bun = new File(abiDir, BUN_BINARY);
691
1260
  String loaderName = findMuslLoader(abiDir);
692
1261
 
@@ -702,6 +1271,12 @@ public class ElizaAgentService extends Service {
702
1271
  updateNotification();
703
1272
  return;
704
1273
  }
1274
+ if (!launchScript.exists()) {
1275
+ Log.e(TAG, "Agent launch script missing at " + launchScript);
1276
+ currentStatus = "missing-launcher";
1277
+ updateNotification();
1278
+ return;
1279
+ }
705
1280
  if (loaderName == null) {
706
1281
  Log.e(TAG, "musl loader missing under " + abiDir);
707
1282
  currentStatus = "missing-loader";
@@ -723,21 +1298,25 @@ public class ElizaAgentService extends Service {
723
1298
  // Android. ELIZA_REQUIRE_LOCAL_AUTH on the server side flips
724
1299
  // that heuristic off so every request needs the bearer token.
725
1300
  String token = generateLocalAgentToken();
1301
+ String terminalToken = generateLocalAgentToken();
726
1302
  currentLocalAgentToken = token;
1303
+ currentTerminalRunToken = terminalToken;
727
1304
  try {
728
1305
  writeLocalAgentTokenFile(token);
729
1306
  } catch (IOException error) {
730
1307
  Log.w(TAG, "Failed to persist local-agent token file: " + error.getMessage());
731
1308
  }
732
1309
 
733
- // Invocation:
734
- // LD_LIBRARY_PATH=<agent/{abi}> PORT=31337 ELIZA_*=…
735
- // ELIZA_API_TOKEN=<token>
736
- // agent/{abi}/ld-musl-…so.1 agent/{abi}/bun agent/agent-bundle.js
1310
+ // Invocation goes through launch.sh instead of keeping bun as a
1311
+ // Java child process. Android has repeatedly killed the direct
1312
+ // child path after ~30-50 s with SIGTRAP-like exit 133 while the
1313
+ // same runtime stays alive when it is session-detached. The
1314
+ // service still owns auth, env, foreground lifetime, and health
1315
+ // supervision; launch.sh only performs the setsid double-fork and
1316
+ // writes raw Bun stdio to agent/agent.log.
737
1317
  List<String> command = new ArrayList<>();
738
- command.add(loader.getAbsolutePath());
739
- command.add(bun.getAbsolutePath());
740
- command.add(bundle.getAbsolutePath());
1318
+ command.add("/system/bin/sh");
1319
+ command.add(launchScript.getAbsolutePath());
741
1320
 
742
1321
  ProcessBuilder pb = new ProcessBuilder(command);
743
1322
  pb.directory(root);
@@ -747,8 +1326,38 @@ public class ElizaAgentService extends Service {
747
1326
  "LD_LIBRARY_PATH",
748
1327
  nativeLibraryDir().getAbsolutePath() + ":" + abiDir.getAbsolutePath()
749
1328
  );
1329
+ // Native voice libs (Silero VAD + WeSpeaker/pyannote voice classifier)
1330
+ // ship as jniLibs and extract into nativeLibraryDir. The on-device bun
1331
+ // agent's bun:ffi loaders (vad-ggml.ts / encoder-ggml.ts /
1332
+ // diarizer-ggml.ts) honor these env overrides; without them they fall
1333
+ // back to the repo-local CMake build dirs, which do not exist on a
1334
+ // packaged install, so live diarization would report library-missing.
1335
+ // Only export when the .so actually shipped, so a stale env never
1336
+ // points the loader at a missing path.
1337
+ File sileroVadLib = new File(nativeLibraryDir(), "libsilero_vad.so");
1338
+ File voiceClassifierLib = new File(nativeLibraryDir(), "libvoice_classifier.so");
1339
+ if (sileroVadLib.isFile() && !env.containsKey("ELIZA_SILERO_VAD_LIB")) {
1340
+ agentEnv.put("ELIZA_SILERO_VAD_LIB", sileroVadLib.getAbsolutePath());
1341
+ Log.i(TAG, "libsilero_vad.so present; exporting ELIZA_SILERO_VAD_LIB="
1342
+ + sileroVadLib.getAbsolutePath());
1343
+ }
1344
+ if (voiceClassifierLib.isFile() && !env.containsKey("ELIZA_VOICE_CLASSIFIER_LIB")) {
1345
+ agentEnv.put("ELIZA_VOICE_CLASSIFIER_LIB", voiceClassifierLib.getAbsolutePath());
1346
+ Log.i(TAG, "libvoice_classifier.so present; exporting ELIZA_VOICE_CLASSIFIER_LIB="
1347
+ + voiceClassifierLib.getAbsolutePath());
1348
+ }
1349
+ agentEnv.put("AGENT_ROOT", root.getAbsolutePath());
1350
+ agentEnv.put("RUNTIME_DIR", abiDir.getAbsolutePath());
1351
+ agentEnv.put("DEVICE_DIR", abiDir.getAbsolutePath());
1352
+ agentEnv.put("LD_NAME", loaderName);
1353
+ agentEnv.put("LD_PATH", loader.getAbsolutePath());
1354
+ agentEnv.put("BUN_PATH", bun.getAbsolutePath());
1355
+ agentEnv.put("AGENT_BUNDLE", AGENT_BUNDLE_NAME);
1356
+ agentEnv.put("AGENT_BUNDLE_PATH", bundle.getAbsolutePath());
1357
+ agentEnv.put("LOG_FILE", new File(root, AGENT_LOG_NAME).getAbsolutePath());
750
1358
  agentEnv.put("PORT", String.valueOf(AGENT_PORT));
751
1359
  agentEnv.put("ELIZA_API_PORT", String.valueOf(AGENT_PORT));
1360
+ agentEnv.put("ELIZA_API_BIND", "127.0.0.1");
752
1361
  // The agent's runtime-env resolver reads ELIZA_PORT / ELIZA_UI_PORT
753
1362
  // (defaulting to 2138) before falling back to PORT. Without
754
1363
  // these the agent binds 2138 even though the service advertises
@@ -759,25 +1368,274 @@ public class ElizaAgentService extends Service {
759
1368
  agentEnv.put("ELIZA_UI_PORT", String.valueOf(AGENT_PORT));
760
1369
  agentEnv.put("ELIZA_STATE_DIR", agentStateDir().getAbsolutePath());
761
1370
  agentEnv.put("ELIZA_PLATFORM", "android");
1371
+ agentEnv.put("ELIZA_MOBILE_PLATFORM", "android");
1372
+ agentEnv.put("ELIZA_RUNTIME_MODE", "local-yolo");
1373
+ agentEnv.put("AGENT_COMMAND", "android-bridge");
762
1374
  agentEnv.put("ELIZA_DISABLE_DIRECT_RUN", "1");
763
- // Android loopback is shared across apps. Require the per-boot
764
- // bearer token; the Capacitor Agent plugin exposes it to the
765
- // WebView before local-agent API calls are retried.
766
- agentEnv.put("ELIZA_REQUIRE_LOCAL_AUTH", "1");
1375
+ // Local passwordless mode: the on-device agent trusts its own
1376
+ // loopback so the single device owner never hits a login/pairing
1377
+ // gate. The per-boot bearer-token guard (ELIZA_REQUIRE_LOCAL_AUTH=1)
1378
+ // is intentionally OFF — the WebView cannot reliably present that
1379
+ // token at cold start, which otherwise dead-ends the dashboard at
1380
+ // 401 ("Connecting to backend…" forever). Tradeoff: other apps on
1381
+ // THIS device can reach 127.0.0.1:31337. The token is still minted
1382
+ // and exposed via the Agent plugin for callers that opt to use it.
1383
+ agentEnv.put("ELIZA_REQUIRE_LOCAL_AUTH", "0");
767
1384
  agentEnv.put("ELIZA_API_TOKEN", token);
1385
+ agentEnv.put("ELIZA_TERMINAL_RUN_TOKEN", terminalToken);
768
1386
  // The Capacitor APK always hosts @elizaos/capacitor-llama in the
769
1387
  // WebView, so the runtime should always be ready to broker
770
1388
  // inference over the device-bridge WSS at /api/local-inference/
771
1389
  // device-bridge. The WebView dials it over loopback once the
772
1390
  // user picks the local runtime mode in onboarding.
773
1391
  agentEnv.put("ELIZA_DEVICE_BRIDGE_ENABLED", "1");
774
- // AOSP builds ship libllama.so under agent/{abi}/ and load it
775
- // directly into the bun process via bun:ffi (see
776
- // eliza/packages/agent/src/runtime/aosp-llama-adapter.ts). The
777
- // gradle BuildConfig.AOSP_BUILD field is wired by sub-task 2B;
778
- // the Capacitor APK keeps its DeviceBridge loopback path.
779
- if (BuildConfig.AOSP_BUILD) {
1392
+ agentEnv.put("ELIZA_DEVICE_PAIRING_TOKEN", token);
1393
+ // CPU-only inference on a stock-Android Capacitor APK runs the
1394
+ // same on-device chat path as the AOSP variant — Snapdragon
1395
+ // 4 Gen 1 / Tensor G1 class hardware lands at 3–7 tok/s and a
1396
+ // ~4.5 k-token system prompt + 256-token reply needs the
1397
+ // same 600 s native/chat budget the bridge uses by default.
1398
+ // The upstream gate that previously bumped these (under
1399
+ // `BuildConfig.AOSP_BUILD && isBrandedDevice()` further down)
1400
+ // only fires for branded AOSP builds; stock-Android sideloads
1401
+ // get the defaults and time out on every first turn with
1402
+ // "Chat generation failed with no streamed text
1403
+ // (err=Chat generation timed out after 180000ms)". Set the
1404
+ // same 10 min budget here unconditionally so both build
1405
+ // types finish their cold first turn.
1406
+ if (!env.containsKey("ELIZA_CHAT_GENERATION_TIMEOUT_MS")) {
1407
+ agentEnv.put("ELIZA_CHAT_GENERATION_TIMEOUT_MS", "600000");
1408
+ }
1409
+ if (!env.containsKey("ELIZA_DEVICE_GENERATE_TIMEOUT_MS")) {
1410
+ agentEnv.put("ELIZA_DEVICE_GENERATE_TIMEOUT_MS", "600000");
1411
+ }
1412
+ // The mobile bridge ships the bge embedding GGUF disabled
1413
+ // by default (`ELIZA_LOCAL_EMBEDDING_ENABLED!="1"`) because
1414
+ // mmapping it alongside the chat GGUF would OOM a 4 GB
1415
+ // Moto G Play class device. With the embedding handler
1416
+ // returning the zero vector for every call, the chat-
1417
+ // augmentation document-retrieval branch never lands a
1418
+ // match above `CHAT_DOCUMENTS_THRESHOLD`, and its LLM-
1419
+ // driven query recovery fallback wastes one full
1420
+ // generate-text round-trip per turn (~60–90 s on this
1421
+ // hardware) producing queries that themselves match
1422
+ // nothing. Skip the whole augmentation path when the
1423
+ // embedding handler is in the disabled state.
1424
+ if (!env.containsKey("ELIZA_DOCUMENT_AUGMENTATION_DISABLED")
1425
+ && !"1".equals(env.get("ELIZA_LOCAL_EMBEDDING_ENABLED"))) {
1426
+ agentEnv.put("ELIZA_DOCUMENT_AUGMENTATION_DISABLED", "1");
1427
+ }
1428
+ // Skip the auto-download of recommended GGUF models that
1429
+ // mobile-device-bridge-bootstrap kicks off at registration
1430
+ // time. On Android the bun process cannot reach the network
1431
+ // without specific SELinux carve-outs and the download fail
1432
+ // cascades into a mid-init crash with no stderr captured
1433
+ // (agent.log empty, no exit code). The WebView side handles
1434
+ // model selection + persistence; the bun process only needs
1435
+ // the bridge handlers registered, not pre-warmed.
1436
+ agentEnv.put("ELIZA_DISABLE_MODEL_AUTO_DOWNLOAD", "1");
1437
+ // Native bun:ffi inference path. When the APK bundles the eliza
1438
+ // llama.cpp fork's fused native lib under agent/{abi}/
1439
+ // (libelizainference.so), opt the bun process into loading it
1440
+ // directly via bun:ffi — see
1441
+ // eliza/plugins/plugin-aosp-local-inference/src/aosp-local-inference-bootstrap.ts
1442
+ // (tryBuildAospFusedTextLoader) and aosp-llama-paths.ts
1443
+ // (isAospEnabled reads ELIZA_LOCAL_LLAMA).
1444
+ // This is required, not optional: the eliza-1 model tiers are
1445
+ // Gemma-4-arch GGUFs (TurboQuant-quantized; stock f16/q8_0 KV — the
1446
+ // legacy QJL/PolarQuant/TBQ KV kernels are retired post-#9033), and
1447
+ // the stock llama-cpp-capacitor JNI lib cannot load those GGUFs at
1448
+ // all (`context->loadModel() returned false`). The fused
1449
+ // libelizainference.so carries the kernels + Gemma arch and is
1450
+ // the SOLE text/voice native library the bun agent loads.
1451
+ //
1452
+ // This was previously gated on `BuildConfig.AOSP_BUILD &&
1453
+ // isBrandedDevice()`. That gate's sole rationale was the
1454
+ // aosp loader's first-run model auto-download crashing a
1455
+ // network-restricted bun process — but that download is already
1456
+ // suppressed unconditionally above
1457
+ // (ELIZA_DISABLE_MODEL_AUTO_DOWNLOAD=1), and the loader itself
1458
+ // self-gates + defensively no-ops when the lib is absent or
1459
+ // incompatible. Presence of the bundled fused lib is therefore
1460
+ // the correct, sufficient signal for both build types.
1461
+ //
1462
+ // libelizainference.so is the lib actually dlopen'd at runtime;
1463
+ // libllama.so is kept as a legacy OR-condition so the gate still
1464
+ // activates on any APK that predates the fused-lib cutover (where
1465
+ // only libllama.so + shim were staged). Once libllama.so stops
1466
+ // being built the fused lib alone trips the gate.
1467
+ File abiFusedInference = new File(abiDir, "libelizainference.so");
1468
+ File abiLibllama = new File(abiDir, "libllama.so");
1469
+ File abiLlamaShim = new File(abiDir, "libeliza-llama-shim.so");
1470
+ File abiGgmlVulkan = new File(abiDir, "libggml-vulkan.so");
1471
+ boolean fusedInferenceBundled = abiFusedInference.isFile();
1472
+ boolean legacyLibllamaBundled = abiLibllama.isFile() && abiLlamaShim.isFile();
1473
+ boolean nativeLlamaBundled = fusedInferenceBundled || legacyLibllamaBundled;
1474
+ boolean brandedAospBuild = BuildConfig.AOSP_BUILD && isBrandedDevice();
1475
+ // When the dynamic-Vulkan fused lib is staged (libelizainference.so +
1476
+ // libggml-vulkan.so), the GPU is only reachable from THIS bionic app
1477
+ // process — the musl agent's ld can't load libvulkan's HIDL closure
1478
+ // (project_android_gpu_vulkan_wall). So instead of pointing the musl
1479
+ // agent at the bun:ffi AOSP loader (ELIZA_LOCAL_LLAMA=1 → the wall),
1480
+ // delegate inference over an abstract-namespace UDS to the in-process
1481
+ // ElizaBionicInferenceServer, which runs libelizainference on the Mali
1482
+ // GPU. The musl agent never tries to load the native lib itself.
1483
+ boolean delegateToBionicHost = fusedInferenceBundled && abiGgmlVulkan.isFile();
1484
+ if (delegateToBionicHost) {
1485
+ agentEnv.put("ELIZA_BIONIC_HOST_DELEGATED", "1");
1486
+ agentEnv.put("ELIZA_BIONIC_INFERENCE_SOCK", BIONIC_INFERENCE_SOCKET_NAME);
1487
+ // The bionic host reloads the model per call (the fork's Vulkan
1488
+ // backend corrupts shared GPU weights on reuse), so even a
1489
+ // token-capped post-turn reflection runs ~40-60s — past the
1490
+ // 30s default post-delivery side-effect timeout. That reflection
1491
+ // is non-blocking background work (the reply is already
1492
+ // delivered), so give it room to finish and persist instead of
1493
+ // logging a spurious timeout every turn. Don't clobber an
1494
+ // explicit operator override.
1495
+ if (!agentEnv.containsKey("ELIZA_POST_DELIVERY_SIDE_EFFECT_TIMEOUT_MS")) {
1496
+ agentEnv.put("ELIZA_POST_DELIVERY_SIDE_EFFECT_TIMEOUT_MS", "120000");
1497
+ }
1498
+ Log.i(TAG, "agent/" + abiDir.getName()
1499
+ + "/libggml-vulkan.so present; delegating inference to the in-process"
1500
+ + " bionic Vulkan host over UDS \"" + BIONIC_INFERENCE_SOCKET_NAME
1501
+ + "\" (NOT taking the musl bun:ffi AOSP path)");
1502
+ // Stand up the in-process GPU inference server BEFORE the agent
1503
+ // spawns so the abstract socket is already bound when the agent's
1504
+ // BionicHostLoader first connects. Idempotent across restarts.
1505
+ if (bionicInferenceServer == null) {
1506
+ String defaultBundleDir =
1507
+ new File(getFilesDir(), "eliza-1/bundle").getAbsolutePath();
1508
+ bionicInferenceServer =
1509
+ new ElizaBionicInferenceServer(BIONIC_INFERENCE_SOCKET_NAME, defaultBundleDir);
1510
+ }
1511
+ bionicInferenceServer.start();
1512
+ }
1513
+ if (!delegateToBionicHost && nativeLlamaBundled
1514
+ && !env.containsKey("ELIZA_LOCAL_LLAMA")) {
1515
+ agentEnv.put("ELIZA_LOCAL_LLAMA", "1");
1516
+ String bundledLib = fusedInferenceBundled
1517
+ ? "libelizainference.so"
1518
+ : "libllama.so + shim (legacy)";
1519
+ Log.i(TAG, "agent/" + abiDir.getName()
1520
+ + "/" + bundledLib + " present; enabling native bun:ffi inference (ELIZA_LOCAL_LLAMA=1)");
1521
+ }
1522
+ if (nativeLlamaBundled) {
1523
+ // When the Vulkan ggml backend (libggml-vulkan.so) is bundled —
1524
+ // i.e. the arm64 GPU build — offload the model to the GPU. The
1525
+ // aosp loader pins n_gpu_layers=0 by default, so without
1526
+ // this a Vulkan-capable build still runs entirely on CPU. CPU-
1527
+ // only builds (riscv64, or arm64 without the Vulkan backend) ship
1528
+ // no libggml-vulkan.so, so they correctly stay on CPU.
1529
+ // Skipped when delegating: the GPU offload happens in the bionic
1530
+ // host, not the musl bun:ffi path (which can't reach Vulkan).
1531
+ if (!delegateToBionicHost
1532
+ && abiGgmlVulkan.isFile()
1533
+ && !env.containsKey("ELIZA_AOSP_LLAMA_USE_GPU")
1534
+ && !env.containsKey("ELIZA_LLAMA_N_GPU_LAYERS")) {
1535
+ agentEnv.put("ELIZA_AOSP_LLAMA_USE_GPU", "true");
1536
+ Log.i(TAG, "agent/" + abiDir.getName()
1537
+ + "/libggml-vulkan.so present; offloading inference to GPU (ELIZA_AOSP_LLAMA_USE_GPU=true)");
1538
+ }
1539
+ if (!env.containsKey("ELIZA_MOBILE_LOCAL_DIRECT_REPLY")) {
1540
+ agentEnv.put("ELIZA_MOBILE_LOCAL_DIRECT_REPLY", "1");
1541
+ }
1542
+ if (!env.containsKey("ELIZA_KOKORO_PREWARM")) {
1543
+ agentEnv.put("ELIZA_KOKORO_PREWARM", "1");
1544
+ }
1545
+ if (!env.containsKey("ELIZA_KOKORO_PREWARM_DELAY_MS")) {
1546
+ // Kokoro's first on-device ORT/WASM synthesis can be
1547
+ // CPU-bound for tens of seconds. Keep the warmup opt-in,
1548
+ // but schedule it well after the local HTTP server should
1549
+ // be listening so app readiness is not blocked by audio
1550
+ // cache priming.
1551
+ agentEnv.put("ELIZA_KOKORO_PREWARM_DELAY_MS", "60000");
1552
+ }
1553
+ // MTP (multi-token / speculative decode) is compiled into the
1554
+ // single fused libelizainference.so (the eliza_mtp::Engine over
1555
+ // common/speculative.cpp, exported as eliza_inference_llm_mtp_supported).
1556
+ // It is controlled in-process by ELIZA_BIONIC_MTP and the FFI
1557
+ // capability probe — NOT by a separate speculative-shim .so (that
1558
+ // shim is retired and never staged). No env wiring needed here.
1559
+ if (BuildConfig.DEBUG && !env.containsKey("ELIZA_AOSP_LLAMA_DEBUG_LOG")) {
1560
+ File debugLog = new File(agentStateDir(), "aosp-llama-debug.log");
1561
+ agentEnv.put("ELIZA_AOSP_LLAMA_DEBUG_LOG", debugLog.getAbsolutePath());
1562
+ }
1563
+ // Mobile llama.cpp defaults for the in-process fork loader.
1564
+ // The adapter has safe fallbacks, but Java is the only layer
1565
+ // that can reliably read the Android CPU count before bun's
1566
+ // seccomp-limited runtime starts. Keep these tied to the
1567
+ // bundled fork libs, not to full-AOSP branding: the regular
1568
+ // debug APK uses the same bun:ffi path when those libs ship.
1569
+ //
1570
+ // The Eliza-1 native context is 128k. The regular debug APK
1571
+ // runs the model in-process on phone CPU, so default to a
1572
+ // small interactive context and let the adapter keep the tail
1573
+ // of oversized prompts. Full branded AOSP builds keep the
1574
+ // larger 16k context used by CVD/system smoke tests. This
1575
+ // keeps the debug APK's first message-handler prefill bounded
1576
+ // on Pixel-class devices instead of pinning bun behind a
1577
+ // multi-minute FFI call before it can answer health checks or
1578
+ // honor aborts.
1579
+ if (!env.containsKey("ELIZA_LLAMA_N_CTX")) {
1580
+ agentEnv.put("ELIZA_LLAMA_N_CTX", brandedAospBuild ? "16384" : "4096");
1581
+ }
1582
+
1583
+ if (!env.containsKey("ELIZA_LLAMA_THREADS")) {
1584
+ int cores = Runtime.getRuntime().availableProcessors();
1585
+ if (cores < 1) cores = 1;
1586
+ agentEnv.put("ELIZA_LLAMA_THREADS", String.valueOf(cores));
1587
+ }
1588
+
1589
+ // Keep decode chunks bounded for stock APK runs while avoiding
1590
+ // unnecessary multi-chunk prompt prefill. Pixel validation on
1591
+ // eliza-1-0_8b showed 256-token chunks reduce native prefill
1592
+ // time versus the older 64-token default, without blocking
1593
+ // health/startup probes because the HTTP server binds after
1594
+ // model prewarm. Branded AOSP keeps the historical 512-token
1595
+ // chunk size for its longer smoke budget.
1596
+ if (!env.containsKey("ELIZA_LLAMA_N_BATCH")) {
1597
+ agentEnv.put("ELIZA_LLAMA_N_BATCH", brandedAospBuild ? "512" : "256");
1598
+ }
1599
+ if (!env.containsKey("ELIZA_LLAMA_N_UBATCH")) {
1600
+ agentEnv.put("ELIZA_LLAMA_N_UBATCH", brandedAospBuild ? "512" : "256");
1601
+ }
1602
+
1603
+ // Stage-1 RESPONSE_HANDLER is an internal structured planning
1604
+ // call, not the user's requested chat completion budget. On the
1605
+ // debug APK's in-process phone-CPU path, leaving it at the
1606
+ // core default (1024) lets an unconstrained or malformed local
1607
+ // decode run for minutes before the trajectory can record the
1608
+ // first stage. The AOSP adapter now honors the Stage-1 GBNF
1609
+ // grammar, so 384 tokens is ample for the HANDLE_RESPONSE
1610
+ // envelope while still bounding failure cases tightly. Full
1611
+ // branded AOSP keeps the core default unless explicitly set.
1612
+ if (!brandedAospBuild && !env.containsKey("RESPONSE_HANDLER_MAX_TOKENS")) {
1613
+ agentEnv.put("RESPONSE_HANDLER_MAX_TOKENS", "384");
1614
+ }
1615
+ // Bound every native llama generation on debug APKs, not only
1616
+ // Stage-1. Some downstream TEXT_LARGE calls request 8192
1617
+ // tokens while the debug APK uses n_ctx=4096; without this cap
1618
+ // the adapter must reserve the whole context for output and
1619
+ // drops the prompt to a single token.
1620
+ if (!brandedAospBuild && !env.containsKey("ELIZA_LLAMA_MAX_OUTPUT_TOKENS")) {
1621
+ agentEnv.put("ELIZA_LLAMA_MAX_OUTPUT_TOKENS", "384");
1622
+ }
1623
+ }
1624
+ if (BuildConfig.AOSP_BUILD && isBrandedDevice()) {
1625
+ agentEnv.put("ELIZA_AOSP_BUILD", "1");
780
1626
  agentEnv.put("ELIZA_LOCAL_LLAMA", "1");
1627
+ // Branded AOSP unconditionally opts the bun agent into native
1628
+ // inference. If neither the fused libelizainference.so nor the
1629
+ // legacy libllama.so + shim shipped in this APK, that opt-in
1630
+ // cannot be honored — the bun agent's fused loader will fail at
1631
+ // its first TEXT_* call. Surface the broken pipeline LOUDLY here
1632
+ // (Commandment 8: no silent fallback) rather than letting the
1633
+ // failure first appear minutes later mid-inference.
1634
+ if (!nativeLlamaBundled) {
1635
+ Log.e(TAG, "agent/" + abiDir.getName()
1636
+ + ": branded AOSP set ELIZA_LOCAL_LLAMA=1 but no native inference lib is bundled "
1637
+ + "(libelizainference.so absent, libllama.so + shim absent); local inference WILL fail.");
1638
+ }
781
1639
  // CPU-only inference of a 12k-token prompt on cuttlefish
782
1640
  // x86_64 / Eliza-1 lands well past the 180 s default
783
1641
  // chat-generation timeout (chat-routes.ts). On cvd a
@@ -791,52 +1649,52 @@ public class ElizaAgentService extends Service {
791
1649
  // (Tensor / Adreno) finishes in seconds, so this only
792
1650
  // matters for AOSP cvd runs.
793
1651
  agentEnv.put("ELIZA_CHAT_GENERATION_TIMEOUT_MS", "3600000");
794
-
795
- // Eliza-1 native context is 128k. We pin to 16k
796
- // because 16k easily fits the planner's ~12k-token
797
- // prompts plus output reserve. KV-cache for 16k ctx on
798
- // 1B-Q4_K_M / fp16 KV is ~512 MB (16384 cells × 16 layers
799
- // × (256 MiB K + 256 MiB V) per llama.cpp's sched_reserve),
800
- // which alongside the ~770 MB weights and ~290 MB compute
801
- // buffer puts the model alone close to 1.6 GB. cvd has 4
802
- // GB total RAM with ~640 MB free at agent start, and bun's
803
- // heap routinely peaks at 1.5–2.0 GB during long planner
804
- // cycles — the combined footprint hits OOM-killer
805
- // territory and bun panics with a SIGSEGV mid-request.
806
- // Override via env on real-device builds when ctx vs RAM
807
- // trade-offs change.
808
- if (!env.containsKey("ELIZA_LLAMA_N_CTX")) {
809
- agentEnv.put("ELIZA_LLAMA_N_CTX", "16384");
810
- }
811
-
812
- // Pin n_threads to the actual CPU count. The default of
813
- // 0 in the adapter (and llama.cpp's auto-detect path)
814
- // frequently returns 1 on Android because Android's
815
- // seccomp filter blocks sched_getaffinity for app
816
- // domains and llama.cpp's /proc/cpuinfo parse misses
817
- // the core count on cvd. Cuttlefish x86_64 has 4 vCPUs;
818
- // most real phones have 6–8 big.LITTLE cores. Read
819
- // from the JVM at startup and pass through so the FFI
820
- // side doesn't need to call any blocked syscall.
821
- if (!env.containsKey("ELIZA_LLAMA_THREADS")) {
822
- int cores = Runtime.getRuntime().availableProcessors();
823
- if (cores < 1) cores = 1;
824
- agentEnv.put("ELIZA_LLAMA_THREADS", String.valueOf(cores));
825
- }
826
-
827
- // Smaller decode chunks → more event-loop yield points
828
- // during prompt prefill. 2048 holds bun inside a single
829
- // llama_decode call for ~30 s on cvd CPU; the watchdog
830
- // probe sits on a closed listener queue that whole
831
- // time. 512-token chunks land each call in ~6–8 s, so
832
- // the 30 s probe timeout has a realistic chance to
833
- // wake the listener between chunks.
834
- if (!env.containsKey("ELIZA_LLAMA_N_BATCH")) {
835
- agentEnv.put("ELIZA_LLAMA_N_BATCH", "512");
836
- }
1652
+ // Device bridge is unused on AOSP (ELIZA_LOCAL_LLAMA=1 routes
1653
+ // inference through the fused libelizainference.so loader
1654
+ // instead). Set the same 1h budget explicitly so the intent is clear and
1655
+ // operator overrides above are not inadvertently in effect.
1656
+ agentEnv.put("ELIZA_DEVICE_GENERATE_TIMEOUT_MS", "3600000");
1657
+
1658
+ // Native llama.cpp ctx/thread/batch defaults are applied above
1659
+ // whenever the fork libs are bundled. Full AOSP only needs
1660
+ // its longer timeout budget here.
837
1661
  }
838
1662
  agentEnv.put("HOME", getFilesDir().getAbsolutePath());
839
- agentEnv.put("TMPDIR", getCacheDir().getAbsolutePath());
1663
+ if (!env.containsKey("TMPDIR")) {
1664
+ agentEnv.put("TMPDIR", getCacheDir().getAbsolutePath());
1665
+ }
1666
+ agentEnv.put("SHELL", "/system/bin/sh");
1667
+ agentEnv.put("CODING_TOOLS_SHELL", "/system/bin/sh");
1668
+ agentEnv.put("SHELL_ALLOWED_DIRECTORY", agentStateDir().getAbsolutePath());
1669
+ agentEnv.put("CODING_TOOLS_WORKSPACE_ROOTS", agentStateDir().getAbsolutePath());
1670
+ String inheritedPath = env.get("PATH");
1671
+ StringBuilder pathBuilder = new StringBuilder();
1672
+ pathBuilder.append(abiDir.getAbsolutePath()).append("/bin");
1673
+ pathBuilder.append(":").append(abiDir.getAbsolutePath());
1674
+ pathBuilder.append(":").append(new File(root, "tools/bin").getAbsolutePath());
1675
+ pathBuilder.append(":").append(new File(root, "bin").getAbsolutePath());
1676
+ pathBuilder.append(":/system/bin:/system/xbin:/vendor/bin:/apex/com.android.runtime/bin");
1677
+ if (inheritedPath != null && !inheritedPath.trim().isEmpty()) {
1678
+ pathBuilder.append(":").append(inheritedPath);
1679
+ }
1680
+ agentEnv.put("PATH", pathBuilder.toString());
1681
+
1682
+ // ── No-terminal env hints for bun's stdio probe ───────────────
1683
+ // Untrusted-app SELinux policy denies `ioctl(TIOCGWINSZ)` on
1684
+ // both app_data_file and the Java-pipe fifo with `permissive=0`.
1685
+ // Bun's stdio init calls `ioctl(stdout, TIOCGWINSZ)` to detect
1686
+ // terminal width; on EACCES it has historically returned mid-
1687
+ // init without writing any diagnostic, leaving agent.log empty
1688
+ // and the watchdog probing a non-existent listener. The env
1689
+ // hints below put bun on its non-terminal path so it does not
1690
+ // bother probing — TERM=dumb gates the terminfo lookups,
1691
+ // NO_COLOR=1 + FORCE_COLOR=0 disable the ANSI emitter, and
1692
+ // CI=1 routes through bun's CI-mode logger (no progress bars,
1693
+ // no spinners, no width detection).
1694
+ agentEnv.put("TERM", "dumb");
1695
+ agentEnv.put("NO_COLOR", "1");
1696
+ agentEnv.put("FORCE_COLOR", "0");
1697
+ agentEnv.put("CI", "1");
840
1698
 
841
1699
  // ── Android seccomp compatibility (SIGSYS / code 159 fix) ──────
842
1700
  //
@@ -935,13 +1793,16 @@ public class ElizaAgentService extends Service {
935
1793
  // - On AOSP cvd we want a deterministic agent binary, not
936
1794
  // one that mutates its prompts mid-smoke.
937
1795
  //
938
- // Hard-disable both the bootstrap and the trajectory ingest
939
- // path so the agent never spins up a training round on-device.
940
- // Trajectories are still useful for live chat context, but
941
- // this disables PERSISTENCE the optimizer has no input data
942
- // and no-ops at boot.
1796
+ // Hard-disable the bootstrap so the agent never spins up a
1797
+ // training round on-device. Keep trajectory persistence available
1798
+ // in debug APKs: Android local-llama bringup depends on the
1799
+ // per-turn trace files as the ground-truth failure record. Release
1800
+ // builds keep the historical opt-out unless an operator overrides
1801
+ // the env explicitly.
943
1802
  agentEnv.put("ELIZA_DISABLE_AUTO_BOOTSTRAP", "1");
944
- agentEnv.put("ELIZA_DISABLE_TRAJECTORY_LOGGING", "1");
1803
+ if (!env.containsKey("ELIZA_DISABLE_TRAJECTORY_LOGGING")) {
1804
+ agentEnv.put("ELIZA_DISABLE_TRAJECTORY_LOGGING", BuildConfig.DEBUG ? "0" : "1");
1805
+ }
945
1806
 
946
1807
  // ── Vault passphrase ──────────────────────────────────────
947
1808
  // The runtime's vault-bootstrap mirrors process.env secrets
@@ -988,13 +1849,46 @@ public class ElizaAgentService extends Service {
988
1849
 
989
1850
  env.putAll(agentEnv);
990
1851
 
991
- // Merge stderr into stdout so a single pump captures both streams
992
- // and one failure mode — bun crashing mid-write before the buffered
993
- // stderr line is flushed can't lose the diagnostic. The previous
994
- // BufferedReader.readLine() pump silently dropped any partial line
995
- // that wasn't terminated with a newline, which is exactly what
996
- // happens when a panic interrupts a Logger call mid-string.
1852
+ // ── Stdio redirection (TIOCGWINSZ SELinux workaround) ─────────
1853
+ // On Android `untrusted_app`, SELinux denies
1854
+ // `ioctl(fd, TIOCGWINSZ)` (cmd 0x5413) on every non-tty class
1855
+ // accessible to the app with `permissive=0`:
1856
+ // - `pipe:[...]` (Java ProcessBuilder PIPE) fifo_file ioctl
1857
+ // - `/data/data/<pkg>/files/agent/agent.log` app_data_file ioctl
1858
+ // The denial returns EACCES; bun's stdio init (or musl's
1859
+ // `__init_libc` terminal-width probe) treats the EACCES as a
1860
+ // hard failure and exits within ~100ms before any line is
1861
+ // flushed, leaving agent.log at 0 bytes and the watchdog
1862
+ // probing nothing. The one fd class that *does* allow ioctl
1863
+ // for untrusted_app is `null_device:chr_file` (rw_file_perms
1864
+ // grants ioctl, no xperm whitelist restriction). Verified
1865
+ // empirically: same ProcessBuilder spawn from `runas_app`
1866
+ // context (more permissive) reaches `/api/health 200`;
1867
+ // identical spawn from `untrusted_app` (service context)
1868
+ // dies silently on the file ioctl.
1869
+ //
1870
+ // Workaround: redirect all three fds to /dev/null so every
1871
+ // TIOCGWINSZ returns ENOTTY (kernel-level, no SELinux check
1872
+ // needed). We sacrifice stdout/stderr capture for liveness;
1873
+ // the agent runtime still writes structured logs to
1874
+ // `<stateDir>/logs/agent.log` via its own pino transport,
1875
+ // and Android's logcat captures every line emitted via
1876
+ // `Log.i(TAG, …)` from the Java side. For local debug
1877
+ // sessions that need raw bun stdio, set `ELIZA_LOG_STDOUT=1`
1878
+ // in the parent service env — that opts into the legacy
1879
+ // file-redirect path (which only works on rooted devices
1880
+ // or via `adb shell run-as`).
1881
+ File devNull = new File("/dev/null");
1882
+ pb.redirectInput(ProcessBuilder.Redirect.from(devNull));
997
1883
  pb.redirectErrorStream(true);
1884
+ if ("1".equals(env.get("ELIZA_LOG_STDOUT"))) {
1885
+ File logFile = new File(root, AGENT_LOG_NAME);
1886
+ try { logFile.createNewFile(); } catch (IOException ignored) {}
1887
+ pb.redirectOutput(ProcessBuilder.Redirect.appendTo(logFile));
1888
+ Log.i(TAG, "Agent stdout/stderr capture enabled at " + logFile.getAbsolutePath());
1889
+ } else {
1890
+ pb.redirectOutput(ProcessBuilder.Redirect.to(devNull));
1891
+ }
998
1892
 
999
1893
  Process started;
1000
1894
  try {
@@ -1008,14 +1902,60 @@ public class ElizaAgentService extends Service {
1008
1902
  }
1009
1903
 
1010
1904
  agentProcess = started;
1011
- File logFile = new File(root, AGENT_LOG_NAME);
1012
- stdoutPump = startStreamPump(started.getInputStream(), logFile, "out");
1013
- // stderrPump intentionally nullredirectErrorStream(true) merges
1014
- // both streams into getInputStream() so one pump captures everything.
1905
+ detachedAgentMode = true;
1906
+ detachedLaunchStartedAtMs = System.currentTimeMillis();
1907
+ // stdoutPump/stderrPump no longer needed bun writes straight
1908
+ // to agent.log on disk via the OS-level redirect above.
1909
+ stdoutPump = null;
1015
1910
  stderrPump = null;
1016
- currentStatus = "running";
1911
+ currentStatus = "starting";
1017
1912
  updateNotification();
1018
- Log.i(TAG, "Agent process started (pid=" + safePid(started) + ").");
1913
+ final long startedAtMs = System.currentTimeMillis();
1914
+ final long launchStartedAtMs = detachedLaunchStartedAtMs;
1915
+ final long pidForLog = safePid(started);
1916
+ Log.i(TAG, "Agent launcher started (pid=" + pidForLog + ").");
1917
+ // Immediate-exit watcher: bun on `untrusted_app` has been
1918
+ // observed dying within ~50ms with no stderr / no tombstone /
1919
+ // no audit hint past the standard musl init probe denials.
1920
+ // The 10-minute watchdog tick is far too slow to surface a
1921
+ // useful exit code. This thread blocks on `process.waitFor()`
1922
+ // and logs the exit value the moment the kernel reaps the
1923
+ // child, then hands off to the existing watchdog restart
1924
+ // path via scheduleRestart().
1925
+ final Process watched = started;
1926
+ Thread exitWatcher = new Thread(() -> {
1927
+ int code;
1928
+ try {
1929
+ code = watched.waitFor();
1930
+ } catch (InterruptedException ex) {
1931
+ Thread.currentThread().interrupt();
1932
+ return;
1933
+ }
1934
+ long aliveMs = System.currentTimeMillis() - startedAtMs;
1935
+ if (detachedAgentMode && code == 0) {
1936
+ Log.i(TAG, "Agent launcher exited after detached start (pid="
1937
+ + pidForLog + " alive=" + aliveMs + "ms).");
1938
+ } else {
1939
+ Log.w(TAG, "Agent process exited early (pid=" + pidForLog
1940
+ + " code=" + code + " alive=" + aliveMs + "ms).");
1941
+ }
1942
+ boolean stillThisProcess;
1943
+ synchronized (processLock) {
1944
+ stillThisProcess = (agentProcess == watched);
1945
+ if (stillThisProcess) {
1946
+ agentProcess = null;
1947
+ }
1948
+ }
1949
+ if (stillThisProcess && !shuttingDown && detachedAgentMode && code == 0) {
1950
+ startDetachedStartupProbe(launchStartedAtMs);
1951
+ return;
1952
+ }
1953
+ if (stillThisProcess && !shuttingDown) {
1954
+ scheduleRestart();
1955
+ }
1956
+ }, "ElizaAgent-exit-watcher");
1957
+ exitWatcher.setDaemon(true);
1958
+ exitWatcher.start();
1019
1959
  }
1020
1960
  }
1021
1961
 
@@ -1023,6 +1963,7 @@ public class ElizaAgentService extends Service {
1023
1963
  Process toStop;
1024
1964
  Thread outPump;
1025
1965
  Thread errPump;
1966
+ boolean wasDetached;
1026
1967
  synchronized (processLock) {
1027
1968
  toStop = agentProcess;
1028
1969
  outPump = stdoutPump;
@@ -1030,6 +1971,14 @@ public class ElizaAgentService extends Service {
1030
1971
  agentProcess = null;
1031
1972
  stdoutPump = null;
1032
1973
  stderrPump = null;
1974
+ wasDetached = detachedAgentMode;
1975
+ detachedAgentMode = false;
1976
+ detachedLaunchStartedAtMs = 0L;
1977
+ currentLocalAgentToken = null;
1978
+ currentTerminalRunToken = null;
1979
+ }
1980
+ if (wasDetached) {
1981
+ stopDetachedAgentProcess();
1033
1982
  }
1034
1983
  if (toStop == null) {
1035
1984
  return;
@@ -1053,6 +2002,38 @@ public class ElizaAgentService extends Service {
1053
2002
  if (errPump != null) errPump.interrupt();
1054
2003
  }
1055
2004
 
2005
+ private void stopDetachedAgentProcess() {
2006
+ String abi = resolveRuntimeAbi();
2007
+ File abiDir = agentAbiDir(abi);
2008
+ File bun = preferPackagedExecutable(new File(abiDir, BUN_BINARY), "libeliza_bun.so");
2009
+ File bundle = new File(agentRoot(), AGENT_BUNDLE_NAME);
2010
+ String killCommand = "pkill -f " + shellQuote(bun.getAbsolutePath())
2011
+ + " 2>/dev/null || true; pkill -f "
2012
+ + shellQuote(bundle.getAbsolutePath()) + " 2>/dev/null || true";
2013
+ try {
2014
+ Process killer = new ProcessBuilder("/system/bin/sh", "-c", killCommand)
2015
+ .redirectInput(ProcessBuilder.Redirect.from(new File("/dev/null")))
2016
+ .redirectOutput(ProcessBuilder.Redirect.to(new File("/dev/null")))
2017
+ .redirectError(ProcessBuilder.Redirect.to(new File("/dev/null")))
2018
+ .start();
2019
+ long deadline = System.currentTimeMillis() + PROCESS_TERMINATE_GRACE_MS;
2020
+ while (killer.isAlive() && System.currentTimeMillis() < deadline) {
2021
+ Thread.sleep(100);
2022
+ }
2023
+ if (killer.isAlive()) {
2024
+ killer.destroyForcibly();
2025
+ }
2026
+ } catch (IOException error) {
2027
+ Log.w(TAG, "Failed to stop detached agent process: " + error.getMessage());
2028
+ } catch (InterruptedException error) {
2029
+ Thread.currentThread().interrupt();
2030
+ }
2031
+ }
2032
+
2033
+ private static String shellQuote(String value) {
2034
+ return "'" + value.replace("'", "'\\''") + "'";
2035
+ }
2036
+
1056
2037
  private static final java.security.SecureRandom TOKEN_RNG = new java.security.SecureRandom();
1057
2038
 
1058
2039
  private static String generateLocalAgentToken() {
@@ -1160,6 +2141,163 @@ public class ElizaAgentService extends Service {
1160
2141
  return t;
1161
2142
  }
1162
2143
 
2144
+ private void startDetachedStartupProbe(final long launchStartedAtMs) {
2145
+ Thread probe = new Thread(() -> {
2146
+ long deadline = launchStartedAtMs + STARTUP_HEALTH_GRACE_MS;
2147
+ while (!shuttingDown && System.currentTimeMillis() < deadline) {
2148
+ ProbeResult result = probeHealth();
2149
+ if (result == ProbeResult.OK) {
2150
+ restartAttempts = 0;
2151
+ synchronized (processLock) {
2152
+ if (!detachedAgentMode || detachedLaunchStartedAtMs != launchStartedAtMs) {
2153
+ return;
2154
+ }
2155
+ currentStatus = "running";
2156
+ }
2157
+ updateNotification();
2158
+ Log.i(TAG, "Detached agent health check passed.");
2159
+ return;
2160
+ }
2161
+ try {
2162
+ Thread.sleep(STARTUP_HEALTH_POLL_MS);
2163
+ } catch (InterruptedException error) {
2164
+ Thread.currentThread().interrupt();
2165
+ return;
2166
+ }
2167
+ }
2168
+ boolean stillCurrent;
2169
+ synchronized (processLock) {
2170
+ stillCurrent = detachedAgentMode && detachedLaunchStartedAtMs == launchStartedAtMs;
2171
+ }
2172
+ if (stillCurrent && !shuttingDown) {
2173
+ Log.w(TAG, "Detached agent did not become healthy within "
2174
+ + STARTUP_HEALTH_GRACE_MS + "ms. Scheduling restart.");
2175
+ scheduleRestart();
2176
+ }
2177
+ }, "ElizaAgent-detached-startup-probe");
2178
+ probe.setDaemon(true);
2179
+ probe.start();
2180
+ }
2181
+
2182
+ /**
2183
+ * Quick liveness probe for an already-running detached agent: can a TCP
2184
+ * connection be opened to the loopback agent port? Unlike {@link
2185
+ * #probeHealth()} this only completes the socket handshake, so it returns
2186
+ * true even while bun is busy inside a synchronous native call
2187
+ * (mid-llama_decode) and the HTTP layer is unresponsive — precisely the
2188
+ * state we must NOT mistake for a dead agent and relaunch over. Used by
2189
+ * {@link #startAgentProcess()} to adopt a surviving detached agent instead
2190
+ * of killing + restarting it when the service/Activity is recreated.
2191
+ */
2192
+ private boolean isLoopbackAgentListening() {
2193
+ try (Socket socket = new Socket()) {
2194
+ socket.connect(new InetSocketAddress("127.0.0.1", AGENT_PORT), 2000);
2195
+ return true;
2196
+ } catch (IOException ignored) {
2197
+ return false;
2198
+ }
2199
+ }
2200
+
2201
+ private ProbeResult probeHealth() {
2202
+ HttpURLConnection conn = null;
2203
+ try {
2204
+ URL url = new URL(HEALTH_URL);
2205
+ conn = (HttpURLConnection) url.openConnection();
2206
+ conn.setConnectTimeout((int) HEALTH_TIMEOUT_MS);
2207
+ conn.setReadTimeout((int) HEALTH_TIMEOUT_MS);
2208
+ conn.setRequestMethod("GET");
2209
+ String token = currentLocalAgentToken;
2210
+ if (token != null && !token.trim().isEmpty()) {
2211
+ conn.setRequestProperty("Authorization", "Bearer " + token.trim());
2212
+ }
2213
+ int status = conn.getResponseCode();
2214
+ if (status >= 200 && status < 300) {
2215
+ String body = readResponseBody(conn);
2216
+ if (!isReadyHealthBody(body)) {
2217
+ Log.w(TAG, "Agent health endpoint responded before ready: " + compactForLog(body));
2218
+ return ProbeResult.DEAD;
2219
+ }
2220
+ return ProbeResult.OK;
2221
+ }
2222
+ // Non-2xx: agent process is up but not healthy/authenticated.
2223
+ // Treat as DEAD so strikes accumulate — this is a crash or
2224
+ // readiness signal, not a busy signal.
2225
+ return ProbeResult.DEAD;
2226
+ } catch (IOException error) {
2227
+ // HTTP request failed (timeout / connect refused / read
2228
+ // interrupt). If the direct child process is still alive the
2229
+ // most likely cause is bun synchronously inside a native FFI
2230
+ // call. Detached mode has no live Java child to inspect, so a
2231
+ // closed port is treated as DEAD and the startup probe/watchdog
2232
+ // owns retry timing.
2233
+ Process current;
2234
+ synchronized (processLock) {
2235
+ current = agentProcess;
2236
+ }
2237
+ if (current != null && current.isAlive()) {
2238
+ return ProbeResult.BUSY;
2239
+ }
2240
+ return ProbeResult.DEAD;
2241
+ } finally {
2242
+ if (conn != null) conn.disconnect();
2243
+ }
2244
+ }
2245
+
2246
+ private static String readResponseBody(HttpURLConnection conn) throws IOException {
2247
+ try (InputStream in = conn.getInputStream()) {
2248
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
2249
+ byte[] buf = new byte[4096];
2250
+ int n;
2251
+ while ((n = in.read(buf)) >= 0) {
2252
+ out.write(buf, 0, n);
2253
+ }
2254
+ return out.toString(StandardCharsets.UTF_8.name());
2255
+ }
2256
+ }
2257
+
2258
+ private static String readResponseBody(InputStream in, int maxBytes) throws IOException {
2259
+ return new String(readResponseBytes(in, maxBytes), StandardCharsets.UTF_8);
2260
+ }
2261
+
2262
+ private static byte[] readResponseBytes(InputStream in, int maxBytes) throws IOException {
2263
+ if (in == null) return new byte[0];
2264
+ try (InputStream input = in) {
2265
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
2266
+ byte[] buf = new byte[8192];
2267
+ int total = 0;
2268
+ int n;
2269
+ while ((n = input.read(buf)) >= 0) {
2270
+ total += n;
2271
+ if (total > maxBytes) {
2272
+ throw new IOException("Response body is too large");
2273
+ }
2274
+ out.write(buf, 0, n);
2275
+ }
2276
+ return out.toByteArray();
2277
+ }
2278
+ }
2279
+
2280
+ private static boolean isReadyHealthBody(String body) {
2281
+ if (body == null || body.trim().isEmpty()) return false;
2282
+ try {
2283
+ JSONObject json = new JSONObject(body);
2284
+ if (!json.optBoolean("ready", false)) return false;
2285
+ String runtime = json.optString("runtime", "");
2286
+ if (!runtime.isEmpty() && !"ok".equals(runtime)) return false;
2287
+ String agentState = json.optString("agentState", "");
2288
+ return agentState.isEmpty() || "running".equals(agentState);
2289
+ } catch (JSONException error) {
2290
+ return false;
2291
+ }
2292
+ }
2293
+
2294
+ private static String compactForLog(String value) {
2295
+ if (value == null) return "";
2296
+ String compact = value.replaceAll("\\s+", " ").trim();
2297
+ if (compact.length() <= 240) return compact;
2298
+ return compact.substring(0, 240) + "…";
2299
+ }
2300
+
1163
2301
  private void scheduleRestart() {
1164
2302
  if (shuttingDown) return;
1165
2303
  if (restartAttempts >= MAX_RESTART_ATTEMPTS) {
@@ -1216,7 +2354,28 @@ public class ElizaAgentService extends Service {
1216
2354
  current = agentProcess;
1217
2355
  }
1218
2356
  if (current == null) {
1219
- // Service is up but no process — caller must explicitly start.
2357
+ if (detachedAgentMode) {
2358
+ ProbeResult probe = probeHealth();
2359
+ if (probe == ProbeResult.OK) {
2360
+ if (unhealthyTicks > 0) {
2361
+ Log.i(TAG, "Detached agent health restored.");
2362
+ }
2363
+ unhealthyTicks = 0;
2364
+ restartAttempts = 0;
2365
+ if (!"running".equals(currentStatus)) {
2366
+ currentStatus = "running";
2367
+ updateNotification();
2368
+ }
2369
+ } else if (probe == ProbeResult.DEAD) {
2370
+ unhealthyTicks++;
2371
+ Log.w(TAG, "Detached agent health probe failed ("
2372
+ + unhealthyTicks + " consecutive).");
2373
+ if (unhealthyTicks >= HEALTH_FAIL_STRIKES) {
2374
+ unhealthyTicks = 0;
2375
+ scheduleRestart();
2376
+ }
2377
+ }
2378
+ }
1220
2379
  continue;
1221
2380
  }
1222
2381
  if (!current.isAlive()) {
@@ -1261,7 +2420,7 @@ public class ElizaAgentService extends Service {
1261
2420
  Log.i(TAG, "Agent HTTP probe timed out but process is alive — likely mid-decode. No strike.");
1262
2421
  } else {
1263
2422
  // ProbeResult.DEAD: process is dead, OR /api/health
1264
- // returned 5xx (a real crash signal). Only here do we
2423
+ // did not return 2xx with ready=true. Only here do we
1265
2424
  // accumulate strikes toward a force-restart.
1266
2425
  unhealthyTicks++;
1267
2426
  Log.w(TAG, "Agent health probe failed (" + unhealthyTicks + " consecutive).");
@@ -1275,44 +2434,6 @@ public class ElizaAgentService extends Service {
1275
2434
  }
1276
2435
  }
1277
2436
 
1278
- private ProbeResult probeHealth() {
1279
- HttpURLConnection conn = null;
1280
- try {
1281
- URL url = new URL(HEALTH_URL);
1282
- conn = (HttpURLConnection) url.openConnection();
1283
- conn.setConnectTimeout((int) HEALTH_TIMEOUT_MS);
1284
- conn.setReadTimeout((int) HEALTH_TIMEOUT_MS);
1285
- conn.setRequestMethod("GET");
1286
- int status = conn.getResponseCode();
1287
- if (status >= 200 && status < 500) {
1288
- return ProbeResult.OK;
1289
- }
1290
- // 5xx: agent process is up but reported a server error.
1291
- // Treat as DEAD so strikes accumulate — a 5xx on
1292
- // /api/health is a crash signal, not a busy signal.
1293
- return ProbeResult.DEAD;
1294
- } catch (IOException error) {
1295
- // HTTP request failed (timeout / connect refused / read
1296
- // interrupt). If the agent process is still alive the
1297
- // most likely cause is bun synchronously inside a native
1298
- // FFI call (long llama_decode on a multi-thousand-token
1299
- // prompt). The event loop will resume when the FFI call
1300
- // returns. If the process IS dead, scheduleRestart()
1301
- // already fired from the outer loop on the
1302
- // !current.isAlive() path on the previous tick — a
1303
- // strike here would be redundant.
1304
- Process current;
1305
- synchronized (processLock) {
1306
- current = agentProcess;
1307
- }
1308
- if (current != null && current.isAlive()) {
1309
- return ProbeResult.BUSY;
1310
- }
1311
- return ProbeResult.DEAD;
1312
- } finally {
1313
- if (conn != null) conn.disconnect();
1314
- }
1315
- }
1316
2437
  }
1317
2438
 
1318
2439
  /**
@@ -1323,8 +2444,9 @@ public class ElizaAgentService extends Service {
1323
2444
  * HEALTH_TIMEOUT_MS. Typically means bun is synchronously
1324
2445
  * inside a native FFI call (llama_decode on a long prompt).
1325
2446
  * No strike.
1326
- * DEAD → process is dead, OR the HTTP server returned 5xx, OR a
1327
- * hard connection failure (port closed). Count a strike.
2447
+ * DEAD → process is dead, OR the HTTP server did not return 2xx
2448
+ * with ready=true, OR a hard connection failure (port
2449
+ * closed). Count a strike.
1328
2450
  */
1329
2451
  private enum ProbeResult {
1330
2452
  OK,
@@ -1430,7 +2552,7 @@ public class ElizaAgentService extends Service {
1430
2552
  /**
1431
2553
  * Storage key for the persisted mobile runtime mode. Must match
1432
2554
  * MOBILE_RUNTIME_MODE_STORAGE_KEY in
1433
- * eliza/packages/app-core/src/onboarding/mobile-runtime-mode.ts.
2555
+ * eliza/packages/app-core/src/first-run/mobile-runtime-mode.ts.
1434
2556
  */
1435
2557
  private static final String RUNTIME_MODE_KEY = "eliza:mobile-runtime-mode";
1436
2558
 
@@ -1448,17 +2570,37 @@ public class ElizaAgentService extends Service {
1448
2570
  if (isBrandedDevice()) {
1449
2571
  return true;
1450
2572
  }
2573
+ // This APK is the on-device local-agent sideload build (the cloud
2574
+ // thin-client is a separate build). Autostart the agent unless the
2575
+ // user has explicitly chosen a cloud runtime mode. A fresh install
2576
+ // has no persisted mode yet (the renderer writes it only after the
2577
+ // WebView boots), so default to autostart instead of stranding the
2578
+ // dashboard with no agent to connect to.
1451
2579
  String mode = readRuntimeMode(context);
1452
- return "local".equals(mode);
2580
+ return !"cloud".equals(mode);
2581
+ }
2582
+
2583
+ /**
2584
+ * True once the user (or the device image) has actually committed to
2585
+ * running the on-device agent — a branded device, or a stock phone whose
2586
+ * runtime mode has been explicitly persisted by the onboarding picker.
2587
+ *
2588
+ * Distinct from {@link #shouldAutoStart}: a fresh stock install has no
2589
+ * persisted mode yet, so the agent still auto-starts (so the dashboard has
2590
+ * something to talk to) but the user has chosen nothing. We use this to
2591
+ * avoid cold-asking for notification consent during first-run onboarding —
2592
+ * iOS-style, we ask only after there is a committed reason (the foreground
2593
+ * service still runs without the grant; its notification is just
2594
+ * suppressed until later granted).
2595
+ */
2596
+ public static boolean hasCommittedRuntimeChoice(Context context) {
2597
+ return isBrandedDevice() || readRuntimeMode(context) != null;
1453
2598
  }
1454
2599
 
1455
2600
  private static boolean isBrandedDevice() {
1456
- if (!readSystemProperty("ro.elizaos.product").isEmpty()) return true;
1457
- // White-label forks set ro.<brand>os.product (e.g. ro.miladyos.product).
1458
- // We can't enumerate every fork's namespace from native code, so
1459
- // probe the most common ones used by current forks. Forks that
1460
- // need a different sysprop should override shouldAutoStart locally.
1461
- return !readSystemProperty("ro.miladyos.product").isEmpty();
2601
+ // AOSP / ElizaOS images set ro.elizaos.product. White-label forks
2602
+ // that use a different sysprop should override shouldAutoStart locally.
2603
+ return !readSystemProperty("ro.elizaos.product").isEmpty();
1462
2604
  }
1463
2605
 
1464
2606
  private static String readRuntimeMode(Context context) {