@elizaos/app-core 2.0.0-beta.3 → 2.0.11-beta.6

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