@elizaos/app-core 2.0.0-beta.2 → 2.0.11-beta.5
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.
- package/agent-bridge.d.ts +27 -0
- package/agent-bridge.d.ts.map +1 -0
- package/agent-bridge.js +26 -0
- package/api/__tests__/sandbox-test-helpers.js +1 -1
- package/api/auth/audit.js +1 -1
- package/api/auth/auth-context.js +1 -1
- package/api/auth/bootstrap-token.js +2 -2
- package/api/auth/index.d.ts +9 -10
- package/api/auth/index.d.ts.map +1 -1
- package/api/auth/index.js +9 -10
- package/api/auth/passwords.js +2 -2
- package/api/auth/sensitive-rate-limit.d.ts +1 -4
- package/api/auth/sensitive-rate-limit.d.ts.map +1 -1
- package/api/auth/sensitive-rate-limit.js +6 -6
- package/api/auth/sessions.js +2 -2
- package/api/auth-bootstrap-routes.d.ts +6 -13
- package/api/auth-bootstrap-routes.d.ts.map +1 -1
- package/api/auth-bootstrap-routes.js +14 -27
- package/api/auth-pairing-routes.d.ts +17 -0
- package/api/auth-pairing-routes.d.ts.map +1 -0
- package/api/auth-pairing-routes.js +300 -0
- package/api/auth-session-routes.d.ts.map +1 -1
- package/api/auth-session-routes.js +36 -15
- package/api/auth.d.ts +12 -19
- package/api/auth.d.ts.map +1 -1
- package/api/auth.js +32 -27
- package/api/automations-compat-routes.d.ts.map +1 -1
- package/api/automations-compat-routes.js +5 -5
- package/api/background-tasks-routes.d.ts +4 -0
- package/api/background-tasks-routes.d.ts.map +1 -0
- package/api/background-tasks-routes.js +63 -0
- package/api/catalog-routes.js +3 -3
- package/api/cloud-pair-route.d.ts +26 -0
- package/api/cloud-pair-route.d.ts.map +1 -0
- package/api/cloud-pair-route.js +222 -0
- package/api/cloud-voice-routes.d.ts +52 -0
- package/api/cloud-voice-routes.d.ts.map +1 -0
- package/api/cloud-voice-routes.js +50 -0
- package/api/compat-route-shared.d.ts +2 -2
- package/api/compat-route-shared.d.ts.map +1 -1
- package/api/compat-route-shared.js +11 -7
- package/api/credential-resolver.d.ts +2 -2
- package/api/credential-resolver.d.ts.map +1 -1
- package/api/credential-resolver.js +8 -2
- package/api/database-rows-compat-routes.d.ts.map +1 -1
- package/api/database-rows-compat-routes.js +69 -31
- package/api/dev-boot-history.d.ts +26 -0
- package/api/dev-boot-history.d.ts.map +1 -0
- package/api/dev-boot-history.js +69 -0
- package/api/dev-compat-routes.d.ts +5 -0
- package/api/dev-compat-routes.d.ts.map +1 -1
- package/api/dev-compat-routes.js +127 -4
- package/api/dev-console-log.d.ts +2 -2
- package/api/dev-console-log.d.ts.map +1 -1
- package/api/dev-console-log.js +8 -5
- package/api/dev-route-catalog.d.ts +58 -0
- package/api/dev-route-catalog.d.ts.map +1 -0
- package/api/dev-route-catalog.js +447 -0
- package/api/dev-stack.d.ts.map +1 -1
- package/api/dev-stack.js +6 -9
- package/api/first-run-routes.d.ts +4 -0
- package/api/first-run-routes.d.ts.map +1 -0
- package/api/first-run-routes.js +208 -0
- package/api/first-run-tts-route.d.ts +19 -0
- package/api/first-run-tts-route.d.ts.map +1 -0
- package/api/first-run-tts-route.js +59 -0
- package/api/internal-routes.d.ts +23 -0
- package/api/internal-routes.d.ts.map +1 -0
- package/api/internal-routes.js +203 -0
- package/api/ios-local-agent-transport.d.ts +36 -0
- package/api/ios-local-agent-transport.d.ts.map +1 -0
- package/api/ios-local-agent-transport.js +566 -0
- package/api/onboarding-voice-lines.d.ts +23 -0
- package/api/onboarding-voice-lines.d.ts.map +1 -0
- package/api/onboarding-voice-lines.js +8 -0
- package/api/perf-instrument.d.ts +43 -0
- package/api/perf-instrument.d.ts.map +1 -0
- package/api/perf-instrument.js +113 -0
- package/api/response.d.ts.map +1 -1
- package/api/response.js +14 -14
- package/api/runtime-mode-routes.d.ts.map +1 -1
- package/api/runtime-mode-routes.js +2 -2
- package/api/secrets-inventory-routes.js +2 -2
- package/api/secrets-manager-routes.d.ts +1 -1
- package/api/secrets-manager-routes.d.ts.map +1 -1
- package/api/secrets-manager-routes.js +9 -10
- package/api/sensitive-request-routes.d.ts.map +1 -1
- package/api/sensitive-request-routes.js +5 -5
- package/api/sensitive-request-store.d.ts +12 -3
- package/api/sensitive-request-store.d.ts.map +1 -1
- package/api/server-cors.d.ts.map +1 -1
- package/api/server-cors.js +13 -2
- package/api/server-first-run-helpers.d.ts +26 -0
- package/api/server-first-run-helpers.d.ts.map +1 -0
- package/api/server-first-run-helpers.js +271 -0
- package/api/server-security.js +1 -1
- package/api/server-startup.d.ts.map +1 -1
- package/api/server-startup.js +3 -4
- package/api/server-wallet-trade.js +1 -1
- package/api/server.d.ts +4 -4
- package/api/server.d.ts.map +1 -1
- package/api/server.js +222 -88
- package/api/setup-contract.d.ts +63 -0
- package/api/setup-contract.d.ts.map +1 -0
- package/api/setup-contract.js +39 -0
- package/api/training-benchmarks.d.ts +97 -0
- package/api/training-benchmarks.d.ts.map +1 -0
- package/api/training-benchmarks.js +307 -0
- package/api/workbench-compat-routes.js +2 -2
- package/benchmark/cerebras-autowire.d.ts +28 -0
- package/benchmark/cerebras-autowire.d.ts.map +1 -0
- package/benchmark/cerebras-autowire.js +62 -0
- package/benchmark/lifeops-bench-handler.d.ts +36 -0
- package/benchmark/lifeops-bench-handler.d.ts.map +1 -1
- package/benchmark/lifeops-bench-handler.js +63 -1
- package/benchmark/lifeops-fake-backend.d.ts +39 -0
- package/benchmark/lifeops-fake-backend.d.ts.map +1 -1
- package/benchmark/lifeops-fake-backend.js +993 -21
- package/benchmark/mock-plugin.d.ts.map +1 -1
- package/benchmark/mock-plugin.js +0 -24
- package/benchmark/plugin.d.ts +2 -1
- package/benchmark/plugin.d.ts.map +1 -1
- package/benchmark/plugin.js +989 -68
- package/benchmark/replay-capture.d.ts +2 -2
- package/benchmark/replay-capture.d.ts.map +1 -1
- package/benchmark/replay-capture.js +3 -3
- package/benchmark/server-utils.d.ts +162 -9
- package/benchmark/server-utils.d.ts.map +1 -1
- package/benchmark/server-utils.js +625 -62
- package/benchmark/server.d.ts.map +1 -1
- package/benchmark/server.js +1962 -118
- package/boot-profile.d.ts +3 -0
- package/boot-profile.d.ts.map +1 -0
- package/boot-profile.js +30 -0
- package/browser.d.ts +23 -1
- package/browser.d.ts.map +1 -1
- package/browser.js +20 -1
- package/cli/argv.js +1 -1
- package/cli/banner.js +1 -1
- package/cli/command-format.js +2 -2
- package/cli/doctor/checks.d.ts.map +1 -1
- package/cli/doctor/checks.js +6 -6
- package/cli/plugins-cli.d.ts.map +1 -1
- package/cli/plugins-cli.js +77 -32
- package/cli/profile.d.ts.map +1 -1
- package/cli/profile.js +5 -4
- package/cli/program/build-program.js +4 -4
- package/cli/program/command-registry.d.ts.map +1 -1
- package/cli/program/command-registry.js +13 -11
- package/cli/program/help.js +5 -5
- package/cli/program/preaction.js +5 -5
- package/cli/program/register.auth.d.ts.map +1 -1
- package/cli/program/register.auth.js +6 -12
- package/cli/program/register.capability-router.d.ts +29 -0
- package/cli/program/register.capability-router.d.ts.map +1 -0
- package/cli/program/register.capability-router.js +568 -0
- package/cli/program/register.config.js +1 -1
- package/cli/program/register.configure.d.ts.map +1 -1
- package/cli/program/register.configure.js +1 -1
- package/cli/program/register.dashboard.d.ts.map +1 -1
- package/cli/program/register.dashboard.js +6 -7
- package/cli/program/register.db.d.ts.map +1 -1
- package/cli/program/register.db.js +3 -4
- package/cli/program/register.doctor.js +7 -7
- package/cli/program/register.setup.d.ts.map +1 -1
- package/cli/program/register.setup.js +14 -10
- package/cli/program/register.start.d.ts.map +1 -1
- package/cli/program/register.start.js +5 -3
- package/cli/program/register.subclis.js +3 -3
- package/cli/program/register.update.d.ts +6 -0
- package/cli/program/register.update.d.ts.map +1 -1
- package/cli/program/register.update.js +58 -6
- package/cli/program.js +1 -1
- package/cli/run-main.js +4 -4
- package/config/app-config.d.ts +2 -0
- package/config/app-config.d.ts.map +1 -0
- package/config/app-config.js +1 -0
- package/connectors/capacitor-jsc.d.ts.map +1 -1
- package/connectors/capacitor-jsc.js +16 -10
- package/connectors/capacitor-quickjs.d.ts.map +1 -1
- package/connectors/capacitor-quickjs.js +18 -13
- package/connectors/capacitor-sqlite.d.ts.map +1 -1
- package/connectors/capacitor-sqlite.js +27 -12
- package/dispatch/approval-queue.d.ts +37 -0
- package/dispatch/approval-queue.d.ts.map +1 -0
- package/dispatch/approval-queue.js +25 -0
- package/dispatch/channel-registry.d.ts +30 -0
- package/dispatch/channel-registry.d.ts.map +1 -0
- package/dispatch/channel-registry.js +22 -0
- package/dispatch/connector-registry.d.ts +39 -0
- package/dispatch/connector-registry.d.ts.map +1 -0
- package/dispatch/connector-registry.js +24 -0
- package/dispatch/index.d.ts +14 -0
- package/dispatch/index.d.ts.map +1 -0
- package/dispatch/index.js +13 -0
- package/dispatch/send-policy.d.ts +36 -0
- package/dispatch/send-policy.d.ts.map +1 -0
- package/dispatch/send-policy.js +16 -0
- package/entry.js +28 -11
- package/first-run/first-run-config.d.ts +55 -0
- package/first-run/first-run-config.d.ts.map +1 -0
- package/first-run/first-run-config.js +178 -0
- package/first-run/runtime-target.d.ts +4 -0
- package/first-run/runtime-target.d.ts.map +1 -0
- package/first-run/runtime-target.js +13 -0
- package/index.d.ts +16 -3
- package/index.d.ts.map +1 -1
- package/index.js +57 -33
- package/package.json +159 -50
- package/packaging/debian/apt-repo-config/README.md +18 -0
- package/packaging/debian/apt-repo-config/conf/distributions +11 -0
- package/packaging/flatpak/README.md +26 -16
- package/packaging/flatpak/ai.elizaos.App.metainfo.xml +17 -12
- package/packaging/flatpak/ai.elizaos.App.store.yml +5 -5
- package/packaging/flatpak/ai.elizaos.App.yml +10 -24
- package/packaging/flatpak/elizaos-app-wrapper.store.sh +2 -2
- package/packaging/flatpak/generate-sources.sh +74 -0
- package/packaging/flatpak/node-sources.json +7930 -0
- package/packaging/inno/build-inno.ps1 +34 -9
- package/packaging/msix/AppxManifest.store.xml +1 -1
- package/packaging/msix/README.md +39 -19
- package/packaging/msix/build-msix.ps1 +44 -14
- package/packaging/snap/snapcraft.yaml +22 -21
- package/packaging/test-packaging.sh +2 -2
- package/permissions/types.d.ts +1 -1
- package/permissions/types.js +1 -1
- package/platform/elizaos-agent-browser-stub.d.ts +144 -0
- package/platform/elizaos-agent-browser-stub.d.ts.map +1 -0
- package/platform/elizaos-agent-browser-stub.js +158 -0
- package/platform/elizaos-plugin-elizacloud-browser-stub.d.ts +34 -0
- package/platform/elizaos-plugin-elizacloud-browser-stub.d.ts.map +1 -0
- package/platform/elizaos-plugin-elizacloud-browser-stub.js +51 -0
- package/platform/empty-node-module.d.ts +148 -0
- package/platform/empty-node-module.d.ts.map +1 -1
- package/platform/empty-node-module.js +140 -3
- package/platform/ios-runtime-backends.d.ts +83 -0
- package/platform/ios-runtime-backends.d.ts.map +1 -0
- package/platform/ios-runtime-backends.js +133 -0
- package/platform/ios-runtime-bridge.d.ts +15 -0
- package/platform/ios-runtime-bridge.d.ts.map +1 -0
- package/platform/ios-runtime-bridge.js +527 -0
- package/platform/native-library-policy.d.ts +23 -0
- package/platform/native-library-policy.d.ts.map +1 -0
- package/platform/native-library-policy.js +112 -0
- package/platform/native-plugin-entrypoints.d.ts +19 -0
- package/platform/native-plugin-entrypoints.d.ts.map +1 -0
- package/platform/native-plugin-entrypoints.js +29 -0
- package/platforms/android/README.md +68 -10
- package/platforms/android/app/build.gradle +268 -3
- package/platforms/android/app/capacitor.build.gradle +18 -1
- package/platforms/android/app/proguard-rules.pro +17 -2
- package/platforms/android/app/src/androidTest/java/ai/elizaos/app/ElizaOsInstrumentedTest.java +1 -1
- package/platforms/android/app/src/main/AndroidManifest.xml +334 -17
- package/platforms/android/app/src/main/assets/runners/eliza-tasks.js +177 -0
- package/platforms/android/app/src/main/elizavoice-jni/CMakeLists.txt +75 -0
- package/platforms/android/app/src/main/elizavoice-jni/elizavoice-jni.cpp +1045 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/AgentPlugin.java +111 -171
- package/platforms/android/app/src/main/java/ai/elizaos/app/AndroidVirtualizationBridge.java +284 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/BatteryOptimizationPlugin.java +95 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAccessibilityService.java +55 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAgentService.java +1198 -141
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAndroidSystemBridge.java +83 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAssistActivity.java +50 -1
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBootReceiver.java +90 -8
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBrowserActivity.java +2 -2
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaCalendarActivity.java +1 -1
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaCameraActivity.java +1 -1
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaClockActivity.java +2 -2
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaContactsActivity.java +1 -1
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaDialActivity.java +1 -1
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaInCallService.java +1 -1
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaMmsReceiver.java +1 -1
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaNativeBridge.java +22 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaNotificationListenerService.java +45 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaQuickActionsWidgetProvider.java +68 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaShareActivity.java +132 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsComposeActivity.java +1 -1
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsGatewayService.java +268 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsReceiver.java +12 -1
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaTasksWorker.java +194 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoiceCaptureService.java +198 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoiceNative.java +160 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoicePlugin.java +450 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoiceTileService.java +39 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaWorkScheduler.java +60 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/GatewayConnectionService.java +53 -19
- package/platforms/android/app/src/main/java/ai/elizaos/app/MainActivity.java +160 -33
- package/platforms/android/app/src/main/java/ai/elizaos/app/ResourceProbePlugin.java +169 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/VoiceCapturePlugin.java +119 -0
- package/platforms/android/app/src/main/res/drawable/eliza_widget_background.xml +10 -0
- package/platforms/android/app/src/main/res/drawable/eliza_widget_button_background.xml +13 -0
- package/platforms/android/app/src/main/res/drawable/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-hdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-mdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-xhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-xxhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-land-xxxhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-hdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-mdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-xhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-xxhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/drawable-port-xxxhdpi/splash.png +0 -0
- package/platforms/android/app/src/main/res/layout/eliza_quick_actions_widget.xml +86 -0
- package/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +2 -1
- package/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +2 -1
- package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png +0 -0
- package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/platforms/android/app/src/main/res/values/android_app_actions.xml +48 -0
- package/platforms/android/app/src/main/res/values/colors.xml +8 -0
- package/platforms/android/app/src/main/res/values/ic_launcher_background.xml +2 -2
- package/platforms/android/app/src/main/res/values/strings.xml +2 -2
- package/platforms/android/app/src/main/res/values/styles.xml +25 -1
- package/platforms/android/app/src/main/res/xml/eliza_accessibility_service.xml +9 -0
- package/platforms/android/app/src/main/res/xml/eliza_quick_actions_widget.xml +13 -0
- package/platforms/android/app/src/main/res/xml/shortcuts.xml +121 -0
- package/platforms/android/build.gradle +2 -2
- package/platforms/android/capacitor-cordova-android-plugins/build.gradle +9 -3
- package/platforms/android/capacitor-cordova-android-plugins/cordova.variables.gradle +6 -2
- package/platforms/android/capacitor-cordova-android-plugins/src/main/AndroidManifest.xml +7 -2
- package/platforms/android/capacitor-cordova-android-plugins/src/main/java/.gitkeep +0 -1
- package/platforms/android/capacitor.settings.gradle +66 -16
- package/platforms/android/gradle.properties +1 -0
- package/platforms/android/update-manifest/generate-manifest.mjs +97 -0
- package/platforms/android/update-manifest/schema.json +26 -0
- package/platforms/apple-store-entitlements.reviewed.json +155 -0
- package/platforms/electrobun/.generated/brand-config.json +3 -2
- package/platforms/electrobun/LICENSE +21 -0
- package/platforms/electrobun/README.md +15 -1
- package/platforms/electrobun/assets/appIcon.icns +0 -0
- package/platforms/electrobun/assets/appIcon.ico +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_128x128.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_128x128@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_16x16.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_16x16@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_256x256.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_256x256@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_32x32.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_32x32@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.iconset/icon_512x512.png +0 -0
- package/platforms/electrobun/assets/brand-config.json +6 -6
- package/platforms/electrobun/biome.json +9 -9
- package/platforms/electrobun/docs/capability-collapse-matrix.json +318 -0
- package/platforms/electrobun/docs/capability-collapse-matrix.md +129 -0
- package/platforms/electrobun/docs/capability-routing.md +86 -0
- package/platforms/electrobun/docs/convergence-audit.json +3505 -0
- package/platforms/electrobun/docs/convergence-audit.md +694 -0
- package/platforms/electrobun/docs/database-boot-policy.md +90 -0
- package/platforms/electrobun/docs/riscv64-port.md +175 -0
- package/platforms/electrobun/docs/startup-first-run-cleanup.md +18 -0
- package/platforms/electrobun/docs/trace-first-annotations.md +52 -0
- package/platforms/electrobun/docs/ui-boundary-audit.json +580 -0
- package/platforms/electrobun/docs/ui-boundary-audit.md +257 -0
- package/platforms/electrobun/electrobun.config.ts +592 -364
- package/platforms/electrobun/entitlements/JUSTIFICATIONS.md +141 -0
- package/platforms/electrobun/entitlements/README.md +34 -6
- package/platforms/electrobun/entitlements/mas-bun.entitlements +15 -0
- package/platforms/electrobun/entitlements/mas.entitlements +6 -4
- package/platforms/electrobun/native/macos/window-effects.mm +1522 -0
- package/platforms/electrobun/package.json +18 -12
- package/platforms/electrobun/remotes/fs/README.md +70 -0
- package/platforms/electrobun/remotes/fs/electrobun.config.ts +38 -0
- package/platforms/electrobun/remotes/fs/package.json +12 -0
- package/platforms/electrobun/remotes/fs/plugin.json +25 -0
- package/platforms/electrobun/remotes/fs/src/bun/errors.ts +57 -0
- package/platforms/electrobun/remotes/fs/src/bun/file-limits.ts +50 -0
- package/platforms/electrobun/remotes/fs/src/bun/fs-service.ts +389 -0
- package/platforms/electrobun/remotes/fs/src/bun/path-guard.ts +270 -0
- package/platforms/electrobun/remotes/fs/src/bun/protocol.ts +149 -0
- package/platforms/electrobun/remotes/fs/src/bun/worker.ts +174 -0
- package/platforms/electrobun/remotes/fs/src/dev/phase5-smoke.ts +171 -0
- package/platforms/electrobun/remotes/fs/src/web/index.html +8 -0
- package/platforms/electrobun/remotes/git/README.md +75 -0
- package/platforms/electrobun/remotes/git/electrobun.config.ts +44 -0
- package/platforms/electrobun/remotes/git/package.json +12 -0
- package/platforms/electrobun/remotes/git/plugin.json +31 -0
- package/platforms/electrobun/remotes/git/src/bun/errors.ts +69 -0
- package/platforms/electrobun/remotes/git/src/bun/git-command.ts +156 -0
- package/platforms/electrobun/remotes/git/src/bun/git-service.ts +446 -0
- package/platforms/electrobun/remotes/git/src/bun/operation-history.ts +124 -0
- package/platforms/electrobun/remotes/git/src/bun/protocol.ts +252 -0
- package/platforms/electrobun/remotes/git/src/bun/worker.ts +316 -0
- package/platforms/electrobun/remotes/git/src/dev/phase7-smoke.ts +141 -0
- package/platforms/electrobun/remotes/git/src/web/index.html +8 -0
- package/platforms/electrobun/remotes/local-model/README.md +138 -0
- package/platforms/electrobun/remotes/local-model/electrobun.config.ts +46 -0
- package/platforms/electrobun/remotes/local-model/package.json +12 -0
- package/platforms/electrobun/remotes/local-model/plugin.json +33 -0
- package/platforms/electrobun/remotes/local-model/src/bun/download-state.ts +115 -0
- package/platforms/electrobun/remotes/local-model/src/bun/eliza1-catalog.ts +425 -0
- package/platforms/electrobun/remotes/local-model/src/bun/errors.ts +74 -0
- package/platforms/electrobun/remotes/local-model/src/bun/hf-eliza1-client.ts +169 -0
- package/platforms/electrobun/remotes/local-model/src/bun/local-inference-api-client.ts +245 -0
- package/platforms/electrobun/remotes/local-model/src/bun/model-service.ts +490 -0
- package/platforms/electrobun/remotes/local-model/src/bun/protocol.ts +301 -0
- package/platforms/electrobun/remotes/local-model/src/bun/worker.ts +248 -0
- package/platforms/electrobun/remotes/local-model/src/dev/phase8-smoke.ts +117 -0
- package/platforms/electrobun/remotes/local-model/src/web/index.html +13 -0
- package/platforms/electrobun/remotes/pty/README.md +65 -0
- package/platforms/electrobun/remotes/pty/electrobun.config.ts +47 -0
- package/platforms/electrobun/remotes/pty/package.json +12 -0
- package/platforms/electrobun/remotes/pty/plugin.json +34 -0
- package/platforms/electrobun/remotes/pty/src/bun/errors.ts +57 -0
- package/platforms/electrobun/remotes/pty/src/bun/output-buffer.ts +127 -0
- package/platforms/electrobun/remotes/pty/src/bun/protocol.ts +192 -0
- package/platforms/electrobun/remotes/pty/src/bun/pty-service.ts +562 -0
- package/platforms/electrobun/remotes/pty/src/bun/worker.ts +218 -0
- package/platforms/electrobun/remotes/pty/src/dev/phase6-smoke.ts +127 -0
- package/platforms/electrobun/remotes/pty/src/web/index.html +8 -0
- package/platforms/electrobun/remotes/runtime/README.md +370 -0
- package/platforms/electrobun/remotes/runtime/electrobun.config.ts +48 -0
- package/platforms/electrobun/remotes/runtime/package.json +14 -0
- package/platforms/electrobun/remotes/runtime/plugin.json +30 -0
- package/platforms/electrobun/remotes/runtime/src/bun/api-client.ts +620 -0
- package/platforms/electrobun/remotes/runtime/src/bun/errors.ts +45 -0
- package/platforms/electrobun/remotes/runtime/src/bun/log-buffer.ts +33 -0
- package/platforms/electrobun/remotes/runtime/src/bun/protocol.ts +366 -0
- package/platforms/electrobun/remotes/runtime/src/bun/route-discovery.ts +419 -0
- package/platforms/electrobun/remotes/runtime/src/bun/runtime-manager.ts +423 -0
- package/platforms/electrobun/remotes/runtime/src/bun/sse-parser.ts +99 -0
- package/platforms/electrobun/remotes/runtime/src/bun/stream-manager.ts +887 -0
- package/platforms/electrobun/remotes/runtime/src/bun/worker.ts +1231 -0
- package/platforms/electrobun/remotes/runtime/src/dev/phase1-smoke.ts +34 -0
- package/platforms/electrobun/remotes/runtime/src/dev/phase2-smoke.ts +86 -0
- package/platforms/electrobun/remotes/runtime/src/dev/phase3-smoke.ts +141 -0
- package/platforms/electrobun/remotes/runtime/src/web/index.css +187 -0
- package/platforms/electrobun/remotes/runtime/src/web/index.html +76 -0
- package/platforms/electrobun/remotes/runtime/src/web/index.ts +192 -0
- package/platforms/electrobun/remotes/surface/README.md +201 -0
- package/platforms/electrobun/remotes/surface/electrobun.config.ts +38 -0
- package/platforms/electrobun/remotes/surface/package.json +12 -0
- package/platforms/electrobun/remotes/surface/plugin.json +28 -0
- package/platforms/electrobun/remotes/surface/src/bun/worker.ts +132 -0
- package/platforms/electrobun/remotes/surface/src/dev/phase4-smoke.ts +566 -0
- package/platforms/electrobun/remotes/surface/src/protocol/event-types.ts +84 -0
- package/platforms/electrobun/remotes/surface/src/protocol/runtime-client.ts +673 -0
- package/platforms/electrobun/remotes/surface/src/web/app.ts +595 -0
- package/platforms/electrobun/remotes/surface/src/web/index.css +460 -0
- package/platforms/electrobun/remotes/surface/src/web/index.html +466 -0
- package/platforms/electrobun/remotes/surface/src/web/index.ts +5 -0
- package/platforms/electrobun/remotes/surface/src/web/render.ts +455 -0
- package/platforms/electrobun/remotes/surface/src/web/state.ts +427 -0
- package/platforms/electrobun/scripts/build-macos-effects.sh +4 -0
- package/platforms/electrobun/scripts/ensure-build-folder.ts +28 -0
- package/platforms/electrobun/scripts/ensure-whisper-gguf.sh +55 -0
- package/platforms/electrobun/scripts/ensure-whisper-model.sh +22 -80
- package/platforms/electrobun/scripts/generate-convergence-audit.ts +1203 -0
- package/platforms/electrobun/scripts/local-adhoc-sign-macos.ts +159 -159
- package/platforms/electrobun/scripts/postwrap-diagnostics.ts +424 -339
- package/platforms/electrobun/scripts/postwrap-sign-runtime-macos.ts +302 -271
- package/platforms/electrobun/scripts/smoke-test-windows.ps1 +17 -16
- package/platforms/electrobun/scripts/smoke-test.sh +5 -7
- package/platforms/electrobun/scripts/sync-web-assets.mjs +13 -13
- package/platforms/electrobun/scripts/verify-rpc-handlers.ts +109 -110
- package/platforms/electrobun/scripts/verify-windows-installer-proof.ps1 +3 -8
- package/platforms/electrobun/src/__stubs__/bun-ffi.ts +31 -31
- package/platforms/electrobun/src/__stubs__/electrobun-bun.ts +1 -1
- package/platforms/electrobun/src/agent-ready-state.ts +8 -8
- package/platforms/electrobun/src/agent-reset-from-main.test.ts +162 -0
- package/platforms/electrobun/src/agent-reset-from-main.ts +62 -62
- package/platforms/electrobun/src/agent-status-rpc.test.ts +95 -0
- package/platforms/electrobun/src/agent-status-rpc.ts +156 -0
- package/platforms/electrobun/src/api-base.test.ts +247 -0
- package/platforms/electrobun/src/api-base.ts +202 -93
- package/platforms/electrobun/src/application-menu-action-registry.ts +9 -9
- package/platforms/electrobun/src/application-menu.ts +348 -348
- package/platforms/electrobun/src/background-notice.ts +36 -36
- package/platforms/electrobun/src/boot-progress.test.ts +188 -0
- package/platforms/electrobun/src/boot-progress.ts +111 -0
- package/platforms/electrobun/src/brand-config.test.ts +39 -0
- package/platforms/electrobun/src/brand-config.ts +141 -129
- package/platforms/electrobun/src/bridge/browser-tabs-renderer-registry.ts +28 -28
- package/platforms/electrobun/src/bridge/electrobun-boot-config.ts +42 -0
- package/platforms/electrobun/src/bridge/electrobun-crypto-ready.ts +120 -0
- package/platforms/electrobun/src/bridge/electrobun-direct-rpc.ts +342 -357
- package/platforms/electrobun/src/bridge/electrobun-stub.ts +13 -13
- package/platforms/electrobun/src/browser-workspace-bridge-server.ts +285 -243
- package/platforms/electrobun/src/cloud-auth-window.ts +136 -136
- package/platforms/electrobun/src/cloud-disconnect-from-main.ts +90 -90
- package/platforms/electrobun/src/config-and-auth-rpc.test.ts +256 -0
- package/platforms/electrobun/src/config-and-auth-rpc.ts +302 -0
- package/platforms/electrobun/src/conversations-and-character-rpc.test.ts +185 -0
- package/platforms/electrobun/src/conversations-and-character-rpc.ts +131 -0
- package/platforms/electrobun/src/dashboard-rpc.test.ts +200 -0
- package/platforms/electrobun/src/dashboard-rpc.ts +344 -0
- package/platforms/electrobun/src/database/database-lock.ts +141 -0
- package/platforms/electrobun/src/database/database-mode.ts +149 -0
- package/platforms/electrobun/src/database/database-recovery.ts +72 -0
- package/platforms/electrobun/src/database/database-snapshot.ts +190 -0
- package/platforms/electrobun/src/database/database.test.ts +196 -0
- package/platforms/electrobun/src/database/index.ts +5 -0
- package/platforms/electrobun/src/database/pglite-paths.ts +100 -0
- package/platforms/electrobun/src/desktop-deep-link-events.test.ts +30 -0
- package/platforms/electrobun/src/desktop-deep-link-events.ts +17 -0
- package/platforms/electrobun/src/desktop-http-request.test.ts +73 -73
- package/platforms/electrobun/src/desktop-http-request.ts +85 -85
- package/platforms/electrobun/src/desktop-pill-config.test.ts +27 -0
- package/platforms/electrobun/src/desktop-pill-config.ts +40 -0
- package/platforms/electrobun/src/desktop-test-bridge-server.ts +204 -204
- package/platforms/electrobun/src/desktop-tray-config.test.ts +87 -0
- package/platforms/electrobun/src/desktop-tray-config.ts +84 -0
- package/platforms/electrobun/src/devtools-layout.ts +41 -41
- package/platforms/electrobun/src/diagnostic-format.test.ts +71 -0
- package/platforms/electrobun/src/diagnostic-format.ts +75 -36
- package/platforms/electrobun/src/dynamic-view-rpc-schema.test.ts +37 -0
- package/platforms/electrobun/src/dynamic-views/README.md +44 -0
- package/platforms/electrobun/src/dynamic-views/demo/agent-run-trace.html +135 -0
- package/platforms/electrobun/src/dynamic-views/errors.ts +29 -0
- package/platforms/electrobun/src/dynamic-views/host.test.ts +353 -0
- package/platforms/electrobun/src/dynamic-views/host.ts +332 -0
- package/platforms/electrobun/src/dynamic-views/index.ts +57 -0
- package/platforms/electrobun/src/dynamic-views/kiosk-canvas.ts +89 -0
- package/platforms/electrobun/src/dynamic-views/registry.test.ts +139 -0
- package/platforms/electrobun/src/dynamic-views/registry.ts +196 -0
- package/platforms/electrobun/src/dynamic-views/session-manager.test.ts +355 -0
- package/platforms/electrobun/src/dynamic-views/session-manager.ts +348 -0
- package/platforms/electrobun/src/dynamic-views/types.ts +105 -0
- package/platforms/electrobun/src/electrobun-boot-config.test.ts +50 -0
- package/platforms/electrobun/src/electrobun-config.test.ts +62 -0
- package/platforms/electrobun/src/electrobun-crypto-ready.test.ts +65 -0
- package/platforms/electrobun/src/electrobun-window-options.ts +25 -0
- package/platforms/electrobun/src/extension-rpc.test.ts +88 -0
- package/platforms/electrobun/src/extension-rpc.ts +102 -0
- package/platforms/electrobun/src/fatal-shutdown.test.ts +10 -10
- package/platforms/electrobun/src/fatal-shutdown.ts +1 -1
- package/platforms/electrobun/src/first-party-remotes.test.ts +169 -0
- package/platforms/electrobun/src/first-party-remotes.ts +297 -0
- package/platforms/electrobun/src/first-run-rpc.test.ts +192 -0
- package/platforms/electrobun/src/first-run-rpc.ts +146 -0
- package/platforms/electrobun/src/floating-chat-window.ts +181 -181
- package/platforms/electrobun/src/inbox-rpc.test.ts +123 -0
- package/platforms/electrobun/src/inbox-rpc.ts +158 -0
- package/platforms/electrobun/src/index.ts +2555 -2096
- package/platforms/electrobun/src/kiosk-mode.ts +50 -0
- package/platforms/electrobun/src/launch/index.ts +4 -0
- package/platforms/electrobun/src/launch/launch-dynamic-view.ts +37 -0
- package/platforms/electrobun/src/launch/launch-orchestrator.test.ts +224 -0
- package/platforms/electrobun/src/launch/launch-orchestrator.ts +456 -0
- package/platforms/electrobun/src/launch/launch-store.test.ts +97 -0
- package/platforms/electrobun/src/launch/launch-store.ts +134 -0
- package/platforms/electrobun/src/launch/types.ts +103 -0
- package/platforms/electrobun/src/launch/views/launch-diagnostics.html +205 -0
- package/platforms/electrobun/src/lifecycle/agent-ready-publish.test.ts +50 -0
- package/platforms/electrobun/src/lifecycle/agent-ready-publish.ts +27 -0
- package/platforms/electrobun/src/lifecycle/api-base-owner.ts +42 -31
- package/platforms/electrobun/src/lifecycle/desktop-session-prime.ts +44 -44
- package/platforms/electrobun/src/logger.ts +14 -14
- package/platforms/electrobun/src/main-window-runtime.ts +83 -83
- package/platforms/electrobun/src/main-window-session.test.ts +109 -0
- package/platforms/electrobun/src/main-window-session.ts +87 -51
- package/platforms/electrobun/src/menu-reset-from-main.ts +158 -158
- package/platforms/electrobun/src/native/agent-env.test.ts +52 -0
- package/platforms/electrobun/src/native/agent-runtime-layout.test.ts +42 -0
- package/platforms/electrobun/src/native/agent-state-dir.test.ts +91 -0
- package/platforms/electrobun/src/native/agent.ts +2122 -1682
- package/platforms/electrobun/src/native/auth-bridge.test.ts +67 -0
- package/platforms/electrobun/src/native/auth-bridge.ts +464 -360
- package/platforms/electrobun/src/native/browser-workspace.ts +723 -471
- package/platforms/electrobun/src/native/camera.ts +50 -50
- package/platforms/electrobun/src/native/canvas.ts +444 -445
- package/platforms/electrobun/src/native/credentials.ts +673 -616
- package/platforms/electrobun/src/native/desktop-window.test.ts +300 -0
- package/platforms/electrobun/src/native/desktop.ts +2196 -2156
- package/platforms/electrobun/src/native/editor-bridge.ts +201 -201
- package/platforms/electrobun/src/native/file-watcher.ts +154 -154
- package/platforms/electrobun/src/native/gateway.ts +179 -180
- package/platforms/electrobun/src/native/gpu-window.ts +256 -256
- package/platforms/electrobun/src/native/index.ts +76 -74
- package/platforms/electrobun/src/native/location.test.ts +44 -0
- package/platforms/electrobun/src/native/location.ts +90 -80
- package/platforms/electrobun/src/native/loopback-port.ts +60 -60
- package/platforms/electrobun/src/native/mac-window-effects.ts +166 -104
- package/platforms/electrobun/src/native/music-player.ts +38 -38
- package/platforms/electrobun/src/native/permissions-shared.ts +249 -150
- package/platforms/electrobun/src/native/permissions.ts +301 -208
- package/platforms/electrobun/src/native/power-state.ts +129 -129
- package/platforms/electrobun/src/native/remote-plugin-host.test.ts +1394 -0
- package/platforms/electrobun/src/native/remote-plugin-host.ts +1531 -0
- package/platforms/electrobun/src/native/screencapture.ts +667 -573
- package/platforms/electrobun/src/native/steward.ts +207 -204
- package/platforms/electrobun/src/native/swabble.ts +68 -324
- package/platforms/electrobun/src/native/talkmode.ts +253 -422
- package/platforms/electrobun/src/native/webgpu-browser-support.test.ts +18 -0
- package/platforms/electrobun/src/native/webgpu-browser-support.ts +165 -147
- package/platforms/electrobun/src/native/whisper-env.test.ts +71 -0
- package/platforms/electrobun/src/native/whisper-env.ts +68 -0
- package/platforms/electrobun/src/native-onboarding.ts +270 -0
- package/platforms/electrobun/src/onboarding-overlay-window.ts +141 -0
- package/platforms/electrobun/src/persisted-deployment.ts +91 -0
- package/platforms/electrobun/src/pill-window.test.ts +91 -0
- package/platforms/electrobun/src/pill-window.ts +99 -0
- package/platforms/electrobun/src/preload-validation.ts +44 -44
- package/platforms/electrobun/src/preload.js +1 -1
- package/platforms/electrobun/src/print-electrobun-dev-settings-banner.ts +120 -120
- package/platforms/electrobun/src/renderer-api-proxy.test.ts +73 -0
- package/platforms/electrobun/src/renderer-api-proxy.ts +86 -0
- package/platforms/electrobun/src/renderer-static.test.ts +53 -0
- package/platforms/electrobun/src/renderer-static.ts +144 -57
- package/platforms/electrobun/src/rpc-handler-slices.ts +121 -0
- package/platforms/electrobun/src/rpc-handlers.test.ts +267 -0
- package/platforms/electrobun/src/rpc-handlers.ts +1306 -913
- package/platforms/electrobun/src/rpc-parse-utils.ts +57 -0
- package/platforms/electrobun/src/rpc-port-resolver.test.ts +45 -0
- package/platforms/electrobun/src/rpc-port-resolver.ts +31 -0
- package/platforms/electrobun/src/rpc-schema.ts +2556 -1619
- package/platforms/electrobun/src/runtime-layout.ts +105 -105
- package/platforms/electrobun/src/runtime-permissions.ts +95 -95
- package/platforms/electrobun/src/runtime-rpc.test.ts +126 -0
- package/platforms/electrobun/src/runtime-rpc.ts +237 -0
- package/platforms/electrobun/src/screenshot-dev-server.ts +87 -87
- package/platforms/electrobun/src/settings-mutations-rpc.test.ts +193 -0
- package/platforms/electrobun/src/settings-mutations-rpc.ts +220 -0
- package/platforms/electrobun/src/startup-trace.ts +274 -270
- package/platforms/electrobun/src/subscription-rpc.test.ts +89 -0
- package/platforms/electrobun/src/subscription-rpc.ts +192 -0
- package/platforms/electrobun/src/surface-windows.test.ts +355 -0
- package/platforms/electrobun/src/surface-windows.ts +410 -410
- package/platforms/electrobun/src/trace/README.md +73 -0
- package/platforms/electrobun/src/trace/errors.ts +21 -0
- package/platforms/electrobun/src/trace/index.ts +40 -0
- package/platforms/electrobun/src/trace/trace-dynamic-view.ts +40 -0
- package/platforms/electrobun/src/trace/trace-host-requests.ts +473 -0
- package/platforms/electrobun/src/trace/trace-service.test.ts +186 -0
- package/platforms/electrobun/src/trace/trace-service.ts +324 -0
- package/platforms/electrobun/src/trace/trace-store.test.ts +141 -0
- package/platforms/electrobun/src/trace/trace-store.ts +551 -0
- package/platforms/electrobun/src/trace/types.ts +250 -0
- package/platforms/electrobun/src/trace/views/agent-run-trace.html +311 -0
- package/platforms/electrobun/src/types/web-speech.d.ts +28 -28
- package/platforms/electrobun/src/types.ts +5 -5
- package/platforms/electrobun/src/update-availability.test.ts +72 -0
- package/platforms/electrobun/src/update-availability.ts +90 -0
- package/platforms/electrobun/src/update-rpc.test.ts +83 -0
- package/platforms/electrobun/src/update-rpc.ts +123 -0
- package/platforms/electrobun/src/voice/README.md +184 -0
- package/platforms/electrobun/src/voice/errors.ts +42 -0
- package/platforms/electrobun/src/voice/index.ts +78 -0
- package/platforms/electrobun/src/voice/types.ts +316 -0
- package/platforms/electrobun/src/voice/voice-host-requests.ts +259 -0
- package/platforms/electrobun/src/voice/voice-latency-budget.test.ts +66 -0
- package/platforms/electrobun/src/voice/voice-latency-budget.ts +243 -0
- package/platforms/electrobun/src/voice/voice-live-validation.test.ts +352 -0
- package/platforms/electrobun/src/voice/voice-live-validation.ts +838 -0
- package/platforms/electrobun/src/voice/voice-pipeline.ts +250 -0
- package/platforms/electrobun/src/voice/voice-playback-adapter.ts +31 -0
- package/platforms/electrobun/src/voice/voice-runtime-adapter.test.ts +213 -0
- package/platforms/electrobun/src/voice/voice-runtime-adapter.ts +686 -0
- package/platforms/electrobun/src/voice/voice-service.test.ts +561 -0
- package/platforms/electrobun/src/voice/voice-service.ts +1027 -0
- package/platforms/electrobun/src/voice/voice-stream-coordinator.test.ts +115 -0
- package/platforms/electrobun/src/voice/voice-stream-coordinator.ts +270 -0
- package/platforms/electrobun/src/voice/voice-trace.ts +97 -0
- package/platforms/electrobun/src/voice/voice-tts-chunker.test.ts +91 -0
- package/platforms/electrobun/src/voice/voice-tts-chunker.ts +194 -0
- package/platforms/electrobun/src/windows-cef-profile.ts +88 -88
- package/platforms/electrobun/tsconfig.json +73 -13
- package/platforms/electrobun/update-channels.json +22 -0
- package/platforms/electrobun/vitest.electrobun.config.ts +72 -42
- package/platforms/ios/App/App/App.entitlements +4 -0
- package/platforms/ios/App/App/AppDelegate.swift +80 -18
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ios-marketing-1024.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-20x20@1x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-20x20@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-29x29@1x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-29x29@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-40x40@1x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-40x40@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-76x76@1x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-76x76@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-83_5x83_5@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-20x20@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-20x20@3x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-29x29@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-29x29@3x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-40x40@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-40x40@3x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-60x60@2x.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-60x60@3x.png +0 -0
- package/platforms/ios/App/App/Base.lproj/LaunchScreen.storyboard +1 -4
- package/platforms/ios/App/App/ComputerUseBridge.swift +589 -0
- package/platforms/ios/App/App/DeviceActivityMonitorExtension/DeviceActivityMonitorExtension.entitlements +12 -0
- package/platforms/ios/App/App/DeviceActivityMonitorExtension/DeviceActivityMonitorExtension.swift +34 -0
- package/platforms/ios/App/App/DeviceActivityMonitorExtension/Info.plist +29 -0
- package/platforms/ios/App/App/DeviceActivityReportExtension/DeviceActivityReportExtension.entitlements +12 -0
- package/platforms/ios/App/App/DeviceActivityReportExtension/DeviceActivityReportExtension.swift +53 -0
- package/platforms/ios/App/App/DeviceActivityReportExtension/Info.plist +27 -0
- package/platforms/ios/App/App/ElizaAppIntents.swift +183 -0
- package/platforms/ios/App/App/ElizaIntentPlugin.swift +342 -5
- package/platforms/ios/App/App/Info.plist +17 -1
- package/platforms/ios/App/App/runners/eliza-tasks.js +177 -0
- package/platforms/ios/App/App.xcodeproj/project.pbxproj +262 -6
- package/platforms/ios/App/BroadcastExtension/SampleHandler.swift +100 -0
- package/platforms/ios/App/Podfile +5 -0
- package/platforms/ios/App/Podfile.lock +83 -59
- package/register-runtime-hooks.js +11 -5
- package/registry/app-registry.d.ts +14 -0
- package/registry/app-registry.d.ts.map +1 -0
- package/registry/app-registry.js +29 -0
- package/registry/entries/apps/app-polymarket.json +31 -0
- package/registry/entries/apps/clawville.json +27 -0
- package/registry/entries/apps/companion.json +28 -0
- package/registry/entries/apps/database-viewer.json +27 -0
- package/registry/entries/apps/defense-of-the-agents.json +27 -0
- package/registry/entries/apps/documents.json +30 -0
- package/registry/entries/apps/feed.json +27 -0
- package/registry/entries/apps/hyperliquid.json +31 -0
- package/registry/entries/apps/log-viewer.json +27 -0
- package/registry/entries/apps/memory-viewer.json +27 -0
- package/registry/entries/apps/model-tester.json +31 -0
- package/registry/entries/apps/plugin-viewer.json +27 -0
- package/registry/entries/apps/relationship-viewer.json +27 -0
- package/registry/entries/apps/runtime-debugger.json +27 -0
- package/registry/entries/apps/shopify.json +31 -0
- package/registry/entries/apps/skills-viewer.json +27 -0
- package/registry/entries/apps/steward.json +31 -0
- package/registry/entries/apps/training.json +54 -0
- package/registry/entries/apps/trajectory-viewer.json +27 -0
- package/registry/entries/apps/vincent.json +31 -0
- package/registry/entries/connectors/bluebubbles.json +99 -0
- package/registry/entries/connectors/bluesky.json +173 -0
- package/registry/entries/connectors/discord.json +119 -0
- package/registry/entries/connectors/farcaster.json +174 -0
- package/registry/entries/connectors/feishu.json +79 -0
- package/registry/entries/connectors/google-chat.json +120 -0
- package/registry/entries/connectors/google.json +82 -0
- package/registry/entries/connectors/imessage.json +96 -0
- package/registry/entries/connectors/instagram.json +64 -0
- package/registry/entries/connectors/line.json +86 -0
- package/registry/entries/connectors/matrix.json +94 -0
- package/registry/entries/connectors/mattermost.json +110 -0
- package/registry/entries/connectors/msteams.json +104 -0
- package/registry/entries/connectors/nextcloud-talk.json +104 -0
- package/registry/entries/connectors/nostr.json +70 -0
- package/registry/entries/connectors/signal.json +81 -0
- package/registry/entries/connectors/slack.json +102 -0
- package/registry/entries/connectors/telegram.json +71 -0
- package/registry/entries/connectors/tlon.json +94 -0
- package/registry/entries/connectors/twitch.json +110 -0
- package/registry/entries/connectors/whatsapp.json +113 -0
- package/registry/entries/connectors/x.json +231 -0
- package/registry/entries/connectors/zalo.json +112 -0
- package/registry/entries/connectors/zalouser.json +122 -0
- package/registry/entries/plugins/agent-orchestrator.json +33 -0
- package/registry/entries/plugins/agent-skills.json +72 -0
- package/registry/entries/plugins/anthropic.json +73 -0
- package/registry/entries/plugins/app-control.json +23 -0
- package/registry/entries/plugins/auto-trader.json +203 -0
- package/registry/entries/plugins/background-runner.json +26 -0
- package/registry/entries/plugins/blooio.json +102 -0
- package/registry/entries/plugins/browser.json +75 -0
- package/registry/entries/plugins/cli.json +40 -0
- package/registry/entries/plugins/clipboard.json +44 -0
- package/registry/entries/plugins/coding-tools.json +71 -0
- package/registry/entries/plugins/commands.json +63 -0
- package/registry/entries/plugins/computeruse.json +74 -0
- package/registry/entries/plugins/copilot-proxy.json +93 -0
- package/registry/entries/plugins/directives.json +63 -0
- package/registry/entries/plugins/edge-tts.json +97 -0
- package/registry/entries/plugins/elevenlabs.json +169 -0
- package/registry/entries/plugins/elizacloud.json +208 -0
- package/registry/entries/plugins/evm.json +134 -0
- package/registry/entries/plugins/experience.json +34 -0
- package/registry/entries/plugins/facewear.json +131 -0
- package/registry/entries/plugins/form.json +26 -0
- package/registry/entries/plugins/github.json +93 -0
- package/registry/entries/plugins/gmail-watch.json +25 -0
- package/registry/entries/plugins/goals.json +77 -0
- package/registry/entries/plugins/google-genai.json +106 -0
- package/registry/entries/plugins/groq.json +93 -0
- package/registry/entries/plugins/hedera.json +48 -0
- package/registry/entries/plugins/inmemorydb.json +25 -0
- package/registry/entries/plugins/linear.json +51 -0
- package/registry/entries/plugins/local-inference.json +142 -0
- package/registry/entries/plugins/local-storage.json +36 -0
- package/registry/entries/plugins/localdb.json +25 -0
- package/registry/entries/plugins/mcp.json +44 -0
- package/registry/entries/plugins/memory.json +124 -0
- package/registry/entries/plugins/minecraft.json +79 -0
- package/registry/entries/plugins/moltbook.json +83 -0
- package/registry/entries/plugins/music.json +155 -0
- package/registry/entries/plugins/mysticism.json +48 -0
- package/registry/entries/plugins/nearai.json +82 -0
- package/registry/entries/plugins/ngrok.json +69 -0
- package/registry/entries/plugins/ollama.json +96 -0
- package/registry/entries/plugins/openai.json +189 -0
- package/registry/entries/plugins/openrouter.json +188 -0
- package/registry/entries/plugins/pdf.json +26 -0
- package/registry/entries/plugins/plugin-manager.json +23 -0
- package/registry/entries/plugins/prose.json +48 -0
- package/registry/entries/plugins/rlm.json +26 -0
- package/registry/entries/plugins/roblox.json +88 -0
- package/registry/entries/plugins/rss.json +64 -0
- package/registry/entries/plugins/s3-storage.json +91 -0
- package/registry/entries/plugins/scheduling.json +35 -0
- package/registry/entries/plugins/shell.json +94 -0
- package/registry/entries/plugins/social-alpha.json +72 -0
- package/registry/entries/plugins/tailscale.json +81 -0
- package/registry/entries/plugins/tee.json +53 -0
- package/registry/entries/plugins/todos.json +26 -0
- package/registry/entries/plugins/trajectory-logger.json +33 -0
- package/registry/entries/plugins/trust.json +39 -0
- package/registry/entries/plugins/tts.json +71 -0
- package/registry/entries/plugins/tunnel.json +45 -0
- package/registry/entries/plugins/twilio.json +168 -0
- package/registry/entries/plugins/vercel-ai-gateway.json +128 -0
- package/registry/entries/plugins/video.json +23 -0
- package/registry/entries/plugins/vision.json +43 -0
- package/registry/entries/plugins/webhooks.json +23 -0
- package/registry/entries/plugins/workflow.json +25 -0
- package/registry/entries/plugins/xai.json +75 -0
- package/registry/index.d.ts +2 -1
- package/registry/index.d.ts.map +1 -1
- package/registry/index.js +46 -12
- package/registry/loader.d.ts +2 -1
- package/registry/loader.d.ts.map +1 -1
- package/registry/loader.js +49 -2
- package/registry/schema.d.ts +244 -34
- package/registry/schema.d.ts.map +1 -1
- package/registry/schema.js +36 -0
- package/runtime/android-avf-microdroid-bridge.d.ts +29 -0
- package/runtime/android-avf-microdroid-bridge.d.ts.map +1 -0
- package/runtime/android-avf-microdroid-bridge.js +149 -0
- package/runtime/api-dev-settings-banner.d.ts.map +1 -1
- package/runtime/api-dev-settings-banner.js +5 -13
- package/runtime/app-core-runtime-hooks.d.ts +21 -0
- package/runtime/app-core-runtime-hooks.d.ts.map +1 -0
- package/runtime/app-core-runtime-hooks.js +10 -0
- package/runtime/autonomy-policy.d.ts +2 -0
- package/runtime/autonomy-policy.d.ts.map +1 -0
- package/runtime/autonomy-policy.js +4 -0
- package/runtime/desktop/AppWindowRenderer.d.ts +17 -0
- package/runtime/desktop/AppWindowRenderer.d.ts.map +1 -0
- package/runtime/desktop/AppWindowRenderer.js +360 -0
- package/runtime/desktop/DesktopSurfaceNavigationRuntime.d.ts +2 -0
- package/runtime/desktop/DesktopSurfaceNavigationRuntime.d.ts.map +1 -0
- package/runtime/desktop/DesktopSurfaceNavigationRuntime.js +41 -0
- package/runtime/desktop/DesktopTrayRuntime.d.ts +2 -0
- package/runtime/desktop/DesktopTrayRuntime.d.ts.map +1 -0
- package/runtime/desktop/DesktopTrayRuntime.js +174 -0
- package/runtime/desktop/DetachedShellRoot.d.ts +10 -0
- package/runtime/desktop/DetachedShellRoot.d.ts.map +1 -0
- package/runtime/desktop/DetachedShellRoot.js +111 -0
- package/runtime/desktop/index.d.ts +6 -0
- package/runtime/desktop/index.d.ts.map +1 -0
- package/runtime/desktop/index.js +5 -0
- package/runtime/desktop/tray-menu.d.ts +20 -0
- package/runtime/desktop/tray-menu.d.ts.map +1 -0
- package/runtime/desktop/tray-menu.js +143 -0
- package/runtime/dev-server.d.ts +1 -1
- package/runtime/dev-server.d.ts.map +1 -1
- package/runtime/dev-server.js +93 -17
- package/runtime/eliza.d.ts +75 -1
- package/runtime/eliza.d.ts.map +1 -1
- package/runtime/eliza.js +596 -122
- package/runtime/ensure-text-to-speech-handler.d.ts.map +1 -1
- package/runtime/ensure-text-to-speech-handler.js +10 -3
- package/runtime/mobile-safe-runtime.d.ts +181 -2
- package/runtime/mobile-safe-runtime.d.ts.map +1 -1
- package/runtime/mobile-safe-runtime.js +1019 -12
- package/runtime/mode/remote-forwarder.d.ts.map +1 -1
- package/runtime/mode/remote-forwarder.js +2 -2
- package/runtime/mode/route-mode-guard.d.ts +1 -2
- package/runtime/mode/route-mode-guard.d.ts.map +1 -1
- package/runtime/mode/route-mode-guard.js +4 -5
- package/runtime/mode/route-mode-matrix.d.ts.map +1 -1
- package/runtime/mode/route-mode-matrix.js +14 -1
- package/runtime/mode/runtime-mode.d.ts +1 -1
- package/runtime/mode/runtime-mode.d.ts.map +1 -1
- package/runtime/mode/runtime-mode.js +15 -4
- package/runtime/runtime-bootstrap-policy.d.ts.map +1 -1
- package/runtime/runtime-bootstrap-policy.js +14 -2
- package/runtime/telegram-standalone-handler.d.ts.map +1 -1
- package/runtime/telegram-standalone-handler.js +10 -9
- package/runtime/tts-cache-wiring.d.ts +29 -0
- package/runtime/tts-cache-wiring.d.ts.map +1 -0
- package/runtime/tts-cache-wiring.js +114 -0
- package/runtime/voice-warmup.d.ts +81 -0
- package/runtime/voice-warmup.d.ts.map +1 -0
- package/runtime/voice-warmup.js +111 -0
- package/scripts/android-sms-gateway-template.test.mjs +1014 -0
- package/scripts/aosp/README.md +19 -15
- package/scripts/aosp/compile-libllama.mjs +1344 -248
- package/scripts/aosp/compile-shim.mjs +47 -18
- package/scripts/aosp/deploy-pixel.mjs +405 -0
- package/scripts/aosp/lib/load-variant-config.mjs +3 -3
- package/scripts/aosp/llama-cpp-patches/README.md +8 -8
- package/scripts/aosp/llama-cpp-patches/apply-patches.mjs +23 -6
- package/scripts/aosp/llama-cpp-patches/polarquant/README.md +37 -0
- package/scripts/aosp/llama-cpp-patches/qjl/README.md +37 -0
- package/scripts/aosp/seccomp-shim/sigsys-handler-arm64.c +169 -0
- package/scripts/aosp/seccomp-shim/sigsys-handler-riscv64.c +217 -0
- package/scripts/aosp/smoke-cuttlefish.mjs +34 -4
- package/scripts/aosp/stage-default-models.mjs +18 -18
- package/scripts/aosp/variant-config-schema.ts +2 -2
- package/scripts/assert-required-bundled-packages.test.ts +534 -0
- package/scripts/audit-apple-store-sandbox.mjs +146 -0
- package/scripts/audit-live-test-surface.mjs +5 -2
- package/scripts/build-capacitor-app.mjs +21 -0
- package/scripts/build-flatpak.mjs +5 -5
- package/scripts/build-helpers/arm64-simd.mjs +72 -0
- package/scripts/build-helpers/omnivoice-merged.mjs +87 -0
- package/scripts/build-helpers/verify-fused-symbols.mjs +567 -0
- package/scripts/build-image.sh +1 -1
- package/scripts/build-llama-cpp-mtp.mjs +487 -0
- package/scripts/build-native-plugins.mjs +230 -18
- package/scripts/build-patched-electrobun-cli.mjs +68 -10
- package/scripts/build-win.mjs +1 -1
- package/scripts/bun-riscv64/Dockerfile +418 -0
- package/scripts/bun-riscv64/README.md +316 -0
- package/scripts/bun-riscv64/build.sh +469 -0
- package/scripts/bun-riscv64/bun-patches/0001-config-add-riscv64-arch.patch +74 -0
- package/scripts/bun-riscv64/bun-patches/0002-flags-add-riscv64-march-mabi.patch +16 -0
- package/scripts/bun-riscv64/bun-patches/0003-zig-add-riscv64-target-triple-and-cpu.patch +26 -0
- package/scripts/bun-riscv64/bun-patches/0004-webkit-force-local-mode-on-riscv64.patch +33 -0
- package/scripts/bun-riscv64/bun-patches/0005-tinycc-disable-on-riscv64.patch +16 -0
- package/scripts/bun-riscv64/bun-patches/0006-build-add-riscv64-cli-validation.patch +15 -0
- package/scripts/bun-riscv64/bun-patches/0007-deps-per-dep-riscv64-checks.patch +24 -0
- package/scripts/bun-riscv64/bun-patches/0008-source-stabilize-riscv64-musl-build.patch +226 -0
- package/scripts/bun-riscv64/bun-patches/0009-disable-wasm-streaming-hooks-for-c-loop.patch +162 -0
- package/scripts/bun-riscv64/bun-patches/0010-disable-inspector-profiler-for-riscv64-c-loop.patch +80 -0
- package/scripts/bun-riscv64/bun-patches/0011-process-arch-add-riscv64.patch +23 -0
- package/scripts/bun-riscv64/bun-patches/0012-cpu-features-add-riscv64-fallback.patch +13 -0
- package/scripts/bun-riscv64/bun-patches/0013-disable-console-inspector-hooks-for-riscv64-c-loop.patch +43 -0
- package/scripts/bun-riscv64/bun-patches/0014-disable-custom-inspector-dispatchers-on-riscv64.patch +127 -0
- package/scripts/bun-riscv64/bun-patches/0015-disable-jsc-profiler-builtins-on-riscv64.patch +75 -0
- package/scripts/bun-riscv64/bun-patches/0016-node-vm-disable-jit-cached-data-on-riscv64-c-loop.patch +96 -0
- package/scripts/bun-riscv64/bun-patches/0017-disable-performance-domjit-signature-on-riscv64-c-loop.patch +34 -0
- package/scripts/bun-riscv64/bun-patches/0018-fix-serialized-script-identifier-big-endian-path.patch +19 -0
- package/scripts/bun-riscv64/bun-patches/0019-add-wtf-timer-fire-bridge-for-c-loop.patch +24 -0
- package/scripts/bun-riscv64/bun-patches/0020-run-riscv64-smoke-test-under-qemu.patch +13 -0
- package/scripts/bun-riscv64/bun-patches/0021-fix-riscv64-linux-open-flags.patch +25 -0
- package/scripts/bun-riscv64/bun-patches/0022-zlib-riscv64-generic-kernels.patch +25 -0
- package/scripts/bun-riscv64/bun-patches/README.md +127 -0
- package/scripts/bun-riscv64/bun-version.json +202 -0
- package/scripts/bun-riscv64/run-build.sh +162 -0
- package/scripts/bun-riscv64/rust-core/0001-riscv64-rust-core-port.patch +868 -0
- package/scripts/bun-riscv64/rust-core/0002-second-wave-riscv64-source-gaps.patch +130 -0
- package/scripts/bun-riscv64/rust-core/0003-third-wave-riscv64-crash-handler-gaps.patch +78 -0
- package/scripts/bun-riscv64/rust-core/0004-rust-target-cpu-riscv64.patch +39 -0
- package/scripts/bun-riscv64/rust-core/0005-fifth-wave-riscv64-source-gaps.patch +96 -0
- package/scripts/bun-riscv64/rust-core/0006-cpp-wasm-and-inspector-guards-riscv64.patch +91 -0
- package/scripts/bun-riscv64/rust-core/0007-bun-alloc-max-align-t-riscv64.patch +36 -0
- package/scripts/bun-riscv64/rust-core/0008-workspace-lints-warn-not-deny-riscv64.patch +75 -0
- package/scripts/bun-riscv64/rust-core/0009-zigglobalobject-wasm-streaming-guards-riscv64.patch +109 -0
- package/scripts/bun-riscv64/rust-core/0010-tcc-externs-stub-on-riscv64.patch +62 -0
- package/scripts/bun-riscv64/rust-core/0011-clippy-ptr-cast-lints-warn-riscv64.patch +61 -0
- package/scripts/bun-riscv64/rust-core/README.md +80 -0
- package/scripts/bun-riscv64/rust-core/webkit-patches/0003-disable-dfg-ftl-on-riscv64.patch +60 -0
- package/scripts/bun-riscv64/rust-core/webkit-patches/0004-riscv64-do-not-force-wasm-in-c-loop.patch +31 -0
- package/scripts/bun-riscv64/rust-core/webkit-patches/0005-domjit-effect-allow-no-dfg-c-loop.patch +40 -0
- package/scripts/bun-riscv64/rust-core/webkit-patches/0006-disable-usewasm-when-webassembly-compiled-out.patch +33 -0
- package/scripts/bun-riscv64/rust-core/webkit-patches/0007-restore-dropped-includes-and-llint-fwd-decl.patch +31 -0
- package/scripts/bun-riscv64/validate.sh +264 -0
- package/scripts/bun-riscv64/webkit-patches/0001-cherry-pick-llint-riscv64.recipe +155 -0
- package/scripts/bun-riscv64/webkit-patches/0002-cherry-pick-baseline-jit-riscv64.recipe +40 -0
- package/scripts/bun-riscv64/webkit-patches/0003-disable-dfg-ftl-on-riscv64.patch +60 -0
- package/scripts/bun-riscv64/webkit-patches/0004-riscv64-do-not-force-wasm-in-c-loop.patch +31 -0
- package/scripts/bun-riscv64/webkit-patches/0005-domjit-effect-allow-no-dfg-c-loop.patch +40 -0
- package/scripts/bun-riscv64/webkit-patches/0006-disable-usewasm-when-webassembly-compiled-out.patch +33 -0
- package/scripts/bun-riscv64/webkit-patches/0007-restore-dropped-includes-and-llint-fwd-decl.patch +72 -0
- package/scripts/bun-riscv64/webkit-patches/README.md +146 -0
- package/scripts/check-homepage-public-readiness.mjs +353 -0
- package/scripts/check-homepage-release-data.mjs +110 -0
- package/scripts/check-i18n.mjs +2 -1
- package/scripts/check-real-local-chat.ts +147 -0
- package/scripts/check-real-local-provisioning.ts +104 -0
- package/scripts/check-real-local-reset.ts +249 -0
- package/scripts/check-sms-gateway-completion-audit.mjs +428 -0
- package/scripts/check-sms-gateway-readiness.mjs +266 -0
- package/scripts/clean-repo.mjs +5 -5
- package/scripts/codesign-mas.mjs +222 -16
- package/scripts/collect-docker-runtime-deps.mjs +229 -0
- package/scripts/continue-sms-gateway-work.mjs +121 -0
- package/scripts/copy-runtime-node-modules.ts +903 -195
- package/scripts/deploy-cloud-api-production-gateway.mjs +52 -0
- package/scripts/desktop-build.mjs +655 -101
- package/scripts/dev-platform.mjs +346 -102
- package/scripts/dev-startup-smoke.mjs +248 -0
- package/scripts/dev-ui.mjs +418 -176
- package/scripts/disable-local-eliza-workspace.mjs +35 -0
- package/scripts/docker-ci-smoke.sh +298 -96
- package/scripts/docker-entrypoint.sh +62 -1
- package/scripts/docker-entrypoint.test.ts +283 -0
- package/scripts/ensure-avatars.mjs +2 -2
- package/scripts/ensure-electrobun-core.mjs +1 -1
- package/scripts/ensure-generated-core-proto-js.mjs +1 -1
- package/scripts/ensure-type-package-aliases.mjs +62 -5
- package/scripts/ensure-vision-deps.mjs +20 -1
- package/scripts/entry.ts +1 -1
- package/scripts/ffi-stub/Makefile +64 -0
- package/scripts/ffi-stub/README.md +391 -0
- package/scripts/ffi-stub/asr-ffi-smoke.ts +139 -0
- package/scripts/ffi-stub/ffi-stub.c +539 -0
- package/scripts/ffi-stub/ffi.h +538 -0
- package/scripts/ffi-stub/libelizainference_stub.so +0 -0
- package/scripts/ffi-stub/tts-stream-ffi-smoke.ts +349 -0
- package/scripts/generate-first-run-voicelines.mjs +194 -0
- package/scripts/generate-plugin-index.js +4 -3
- package/scripts/generate-static-asset-manifest.mjs +1 -1
- package/scripts/i18n-dynamic-keys.json +5 -5
- package/scripts/init-submodules.mjs +2 -2
- package/scripts/install-android-sms-gateway.md +177 -0
- package/scripts/install-android-sms-gateway.mjs +1088 -0
- package/scripts/ios-xcframework/README.md +74 -72
- package/scripts/ios-xcframework/build-xcframework.mjs +204 -43
- package/scripts/ios-xcframework/run-physical-device-smoke.mjs +1943 -0
- package/scripts/ios-xcframework/runtime-symbol-shim.c +450 -0
- package/scripts/kernel-patches/cpu-polar-kernels.mjs +441 -0
- package/scripts/kernel-patches/cpu-simd-kernels.mjs +253 -0
- package/scripts/kernel-patches/cpu-thread-parallelism.mjs +368 -0
- package/scripts/kernel-patches/cuda-kernels.mjs +117 -0
- package/scripts/kernel-patches/metal-kernels.mjs +1698 -109
- package/scripts/kernel-patches/server-omnivoice-route.mjs +718 -0
- package/scripts/kernel-patches/server-structured-output.mjs +279 -0
- package/scripts/kernel-patches/vulkan-dispatch-log.mjs +166 -0
- package/scripts/kernel-patches/vulkan-dispatch-log.test.mjs +50 -0
- package/scripts/kernel-patches/vulkan-dispatch-patches/01-vulkan-shaders-gen.patch +30 -16
- package/scripts/kernel-patches/vulkan-dispatch-patches/02-ggml-vulkan-pipelines.patch +75 -30
- package/scripts/kernel-patches/vulkan-kernels.mjs +800 -49
- package/scripts/lib/agent-source-watcher.mjs +174 -0
- package/scripts/lib/agent-source-watcher.test.mjs +184 -0
- package/scripts/lib/api-supervisor.mjs +78 -9
- package/scripts/lib/api-supervisor.test.mjs +121 -0
- package/scripts/lib/app-dir.mjs +2 -16
- package/scripts/lib/apple-entitlement-audit.mjs +655 -0
- package/scripts/lib/apple-entitlement-audit.test.mjs +144 -0
- package/scripts/lib/bun-version-guard.mjs +13 -13
- package/scripts/lib/capacitor-plugin-build-needed.mjs +4 -3
- package/scripts/lib/capacitor-plugin-names.mjs +30 -14
- package/scripts/lib/desktop-preflight.mjs +9 -5
- package/scripts/lib/desktop-startup-embedding-warmup-policy.mjs +51 -0
- package/scripts/lib/desktop-startup-embedding-warmup-policy.test.mjs +55 -0
- package/scripts/lib/duet-bridge.d.mts +63 -0
- package/scripts/lib/duet-bridge.mjs +193 -0
- package/scripts/lib/node-path-env.mjs +4 -2
- package/scripts/lib/orchestrator-desktop-dev-banner.mjs +12 -3
- package/scripts/lib/patch-bun-exports.mjs +90 -27
- package/scripts/lib/patch-bun-exports.test.mjs +79 -0
- package/scripts/lib/renderer-build-action.mjs +35 -0
- package/scripts/lib/renderer-build-action.test.mjs +70 -0
- package/scripts/lib/stage-android-agent.mjs +748 -99
- package/scripts/lib/sync-eliza-env-aliases.mjs +3 -25
- package/scripts/lib/ui-smoke-stub-decision.mjs +33 -0
- package/scripts/lib/ui-smoke-stub-decision.test.mjs +46 -0
- package/scripts/lib/vite-renderer-dist-stale.mjs +5 -0
- package/scripts/lib/voice-latency-report.mjs +154 -0
- package/scripts/lifeops-prompt-benchmark.ts +21 -12
- package/scripts/link-docker-local-app-packages.mjs +89 -36
- package/scripts/local-stt-bench.ts +192 -0
- package/scripts/maintain-cloud-api-production-gateway.mjs +54 -0
- package/scripts/mas-smoke.mjs +459 -0
- package/scripts/mas-smoke.test.mjs +220 -0
- package/scripts/mobile-auth-simulator-smoke.mjs +0 -1
- package/scripts/normalize-eliza-capture.ts +97 -0
- package/scripts/omnivoice-fuse/prepare.mjs +2543 -23
- package/scripts/pack-upstreams.mjs +65 -5
- package/scripts/package-electrobun-linux.mjs +303 -0
- package/scripts/patch-deps.mjs +5 -3
- package/scripts/patches/llama-mobile-kokoro-tts.patch +480 -0
- package/scripts/playwright-ui-live-stack.ts +194 -49
- package/scripts/playwright-ui-smoke-api-stub.mjs +3501 -109
- package/scripts/pre-review-local.mjs +2 -2
- package/scripts/prepare-ios-cocoapods.sh +41 -3
- package/scripts/release-check.ts +180 -84
- package/scripts/release-workflow-drift.test.ts +57 -0
- package/scripts/relink-workspace-packages-to-dist.mjs +21 -4
- package/scripts/rt.mjs +16 -1
- package/scripts/run-biome-check.mjs +1 -1
- package/scripts/run-coding-agent-e2e.mjs +3 -3
- package/scripts/run-eliza-app-core-script.mjs +34 -0
- package/scripts/run-local-plugin-live-smoke.mjs +71 -2
- package/scripts/run-mobile-build-android-app-actions.test.mjs +426 -0
- package/scripts/run-mobile-build.mjs +4757 -607
- package/scripts/run-node-runtime.mjs +184 -7
- package/scripts/run-node-runtime.test.mjs +167 -0
- package/scripts/run-node-tsx.mjs +80 -33
- package/scripts/run-node.mjs +41 -1
- package/scripts/run-production-build.mjs +34 -27
- package/scripts/run-release-check.mjs +19 -0
- package/scripts/run-release-contract-suite.mjs +107 -14
- package/scripts/run-ui-smoke-playwright-suite.mjs +0 -2
- package/scripts/runtime-package-manifest.ts +21 -3
- package/scripts/setup-upstreams.mjs +42 -1
- package/scripts/sms-gateway-status.mjs +194 -0
- package/scripts/stage-android-agent.test.mjs +97 -0
- package/scripts/stage-elizavoice-lib.mjs +203 -0
- package/scripts/startup-integration-script-drift.test.ts +82 -4
- package/scripts/streaming-pipeline-bench.ts +543 -0
- package/scripts/sync-homepage-porkbun-dns.mjs +262 -0
- package/scripts/test-sms-gateway-software.mjs +100 -0
- package/scripts/type-audit.mjs +1 -1
- package/scripts/validate-bluebubbles-outbound.mjs +293 -0
- package/scripts/validate-cdn-assets.mjs +15 -7
- package/scripts/validate-regression-matrix.mjs +109 -8
- package/scripts/verify-android-sms-gateway-e2e.mjs +362 -0
- package/scripts/verify-bluebubbles-gateway-e2e.mjs +191 -0
- package/scripts/verify-bluebubbles-inbound-readiness.mjs +88 -0
- package/scripts/verify-cloud-api-production-deploy.mjs +87 -0
- package/scripts/verify-cloud-sms-onboarding-flow.mjs +336 -0
- package/scripts/voice/freeze-voice.mjs +521 -0
- package/scripts/voice-attribution-smoke.ts +538 -0
- package/scripts/voice-create-profile.mjs +379 -0
- package/scripts/voice-duet.mjs +1355 -0
- package/scripts/voice-e2e-hardware.ts +871 -0
- package/scripts/voice-interactive.mjs +1750 -0
- package/scripts/voice-latency-report.mjs +96 -0
- package/scripts/voice-latency-report.test.ts +176 -0
- package/scripts/voice-preset/build-default-voice-preset.mjs +249 -0
- package/scripts/voice-preset/build-onboarding-voice.mjs +281 -0
- package/scripts/watch-sms-gateway-readiness.mjs +303 -0
- package/scripts/write-homepage-release-data.mjs +458 -26
- package/security/agent-vault-id.d.ts +1 -1
- package/security/agent-vault-id.js +1 -1
- package/security/hydrate-wallet-keys-from-platform-store.d.ts.map +1 -1
- package/security/hydrate-wallet-keys-from-platform-store.js +23 -14
- package/security/platform-secure-store-node.d.ts +2 -2
- package/security/platform-secure-store-node.js +3 -3
- package/security/wallet-os-store-actions.d.ts +0 -9
- package/security/wallet-os-store-actions.d.ts.map +1 -1
- package/security/wallet-os-store-actions.js +3 -10
- package/services/account-pool.d.ts +23 -14
- package/services/account-pool.d.ts.map +1 -1
- package/services/account-pool.js +86 -24
- package/services/account-usage.d.ts.map +1 -1
- package/services/account-usage.js +2 -5
- package/services/ambient-audio/consent.d.ts +9 -0
- package/services/ambient-audio/consent.d.ts.map +1 -0
- package/services/ambient-audio/consent.js +28 -0
- package/services/ambient-audio/index.d.ts +7 -0
- package/services/ambient-audio/index.d.ts.map +1 -0
- package/services/ambient-audio/index.js +4 -0
- package/services/ambient-audio/replay-buffer.d.ts +14 -0
- package/services/ambient-audio/replay-buffer.d.ts.map +1 -0
- package/services/ambient-audio/replay-buffer.js +66 -0
- package/services/ambient-audio/response-gate.d.ts +3 -0
- package/services/ambient-audio/response-gate.d.ts.map +1 -0
- package/services/ambient-audio/response-gate.js +33 -0
- package/services/ambient-audio/service.d.ts +22 -0
- package/services/ambient-audio/service.d.ts.map +1 -0
- package/services/ambient-audio/service.js +47 -0
- package/services/ambient-audio/types.d.ts +42 -0
- package/services/ambient-audio/types.d.ts.map +1 -0
- package/services/app-updates/update-policy.d.ts +64 -0
- package/services/app-updates/update-policy.d.ts.map +1 -0
- package/services/app-updates/update-policy.js +228 -0
- package/services/auth-store.d.ts +37 -1
- package/services/auth-store.d.ts.map +1 -1
- package/services/auth-store.js +59 -26
- package/services/cloud-jwks-store.d.ts +3 -3
- package/services/cloud-jwks-store.d.ts.map +1 -1
- package/services/cloud-jwks-store.js +5 -8
- package/services/coding-account-bridge.d.ts +71 -0
- package/services/coding-account-bridge.d.ts.map +1 -0
- package/services/coding-account-bridge.js +267 -0
- package/services/connector-target-catalog.d.ts +10 -3
- package/services/connector-target-catalog.d.ts.map +1 -1
- package/services/connector-target-catalog.js +7 -4
- package/services/credential-tunnel-service.d.ts +66 -0
- package/services/credential-tunnel-service.d.ts.map +1 -0
- package/services/credential-tunnel-service.js +227 -0
- package/services/github-credentials.d.ts +1 -1
- package/services/github-credentials.js +1 -1
- package/services/inference-abort.d.ts +47 -0
- package/services/inference-abort.d.ts.map +1 -0
- package/services/inference-abort.js +76 -0
- package/services/persistence.d.ts +2 -3
- package/services/persistence.d.ts.map +1 -1
- package/services/persistence.js +2 -3
- package/services/phrase-chunked-tts.d.ts +136 -0
- package/services/phrase-chunked-tts.d.ts.map +1 -0
- package/services/phrase-chunked-tts.js +208 -0
- package/services/sandbox-registry.d.ts +78 -0
- package/services/sandbox-registry.d.ts.map +1 -0
- package/services/sandbox-registry.js +323 -0
- package/services/secrets-manager-installer.d.ts +8 -1
- package/services/secrets-manager-installer.d.ts.map +1 -1
- package/services/secrets-manager-installer.js +27 -2
- package/services/sensitive-requests/cloud-link-adapter.d.ts +15 -0
- package/services/sensitive-requests/cloud-link-adapter.d.ts.map +1 -0
- package/services/sensitive-requests/cloud-link-adapter.js +73 -0
- package/services/sensitive-requests/index.d.ts +27 -0
- package/services/sensitive-requests/index.d.ts.map +1 -0
- package/services/sensitive-requests/index.js +51 -0
- package/services/sensitive-requests/instruct-dm-only-adapter.d.ts +14 -0
- package/services/sensitive-requests/instruct-dm-only-adapter.d.ts.map +1 -0
- package/services/sensitive-requests/instruct-dm-only-adapter.js +22 -0
- package/services/sensitive-requests/owner-app-inline-adapter.d.ts +3 -0
- package/services/sensitive-requests/owner-app-inline-adapter.d.ts.map +1 -0
- package/services/sensitive-requests/owner-app-inline-adapter.js +146 -0
- package/services/sensitive-requests/owner-app-oauth-adapter.d.ts +3 -0
- package/services/sensitive-requests/owner-app-oauth-adapter.d.ts.map +1 -0
- package/services/sensitive-requests/owner-app-oauth-adapter.js +156 -0
- package/services/sensitive-requests/public-link-adapter.d.ts +14 -0
- package/services/sensitive-requests/public-link-adapter.d.ts.map +1 -0
- package/services/sensitive-requests/public-link-adapter.js +86 -0
- package/services/sensitive-requests/tunnel-link-adapter.d.ts +17 -0
- package/services/sensitive-requests/tunnel-link-adapter.d.ts.map +1 -0
- package/services/sensitive-requests/tunnel-link-adapter.js +38 -0
- package/services/steward-credentials.d.ts +1 -1
- package/services/steward-credentials.d.ts.map +1 -1
- package/services/steward-credentials.js +10 -6
- package/services/steward-sidecar/health-check.d.ts.map +1 -1
- package/services/steward-sidecar/health-check.js +4 -3
- package/services/steward-sidecar/process-management.d.ts +1 -1
- package/services/steward-sidecar/process-management.d.ts.map +1 -1
- package/services/steward-sidecar/process-management.js +9 -3
- package/services/steward-sidecar/types.d.ts +1 -1
- package/services/steward-sidecar/types.d.ts.map +1 -1
- package/services/steward-sidecar/wallet-setup.d.ts.map +1 -1
- package/services/steward-sidecar/wallet-setup.js +8 -7
- package/services/steward-sidecar.d.ts +2 -2
- package/services/steward-sidecar.d.ts.map +1 -1
- package/services/steward-sidecar.js +27 -19
- package/services/task-host-capabilities.d.ts +60 -0
- package/services/task-host-capabilities.d.ts.map +1 -0
- package/services/task-host-capabilities.js +122 -0
- package/services/tool-call-cache/index.d.ts +2 -2
- package/services/tool-call-cache/index.d.ts.map +1 -1
- package/services/tool-call-cache/index.js +1 -1
- package/services/trigger-event-bridge.js +1 -1
- package/services/tunnel-to-mobile/index.d.ts +2 -0
- package/services/tunnel-to-mobile/index.d.ts.map +1 -0
- package/services/tunnel-to-mobile/index.js +1 -0
- package/services/tunnel-to-mobile/tunnel-to-mobile-client.d.ts +105 -0
- package/services/tunnel-to-mobile/tunnel-to-mobile-client.d.ts.map +1 -0
- package/services/tunnel-to-mobile/tunnel-to-mobile-client.js +190 -0
- package/services/vault-bootstrap.d.ts.map +1 -1
- package/services/vault-bootstrap.js +48 -21
- package/services/vault-mirror.d.ts +1 -1
- package/services/vault-mirror.d.ts.map +1 -1
- package/services/vault-mirror.js +29 -6
- package/services/voice-profiles/diarization-pipeline.d.ts +6 -0
- package/services/voice-profiles/diarization-pipeline.d.ts.map +1 -0
- package/services/voice-profiles/diarization-pipeline.js +20 -0
- package/services/voice-profiles/index.d.ts +12 -0
- package/services/voice-profiles/index.d.ts.map +1 -0
- package/services/voice-profiles/index.js +5 -0
- package/services/voice-profiles/nickname-evaluator.d.ts +14 -0
- package/services/voice-profiles/nickname-evaluator.d.ts.map +1 -0
- package/services/voice-profiles/nickname-evaluator.js +46 -0
- package/services/voice-profiles/owner-confidence.d.ts +10 -0
- package/services/voice-profiles/owner-confidence.d.ts.map +1 -0
- package/services/voice-profiles/owner-confidence.js +38 -0
- package/services/voice-profiles/private-challenge.d.ts +20 -0
- package/services/voice-profiles/private-challenge.d.ts.map +1 -0
- package/services/voice-profiles/private-challenge.js +44 -0
- package/services/voice-profiles/store.d.ts +21 -0
- package/services/voice-profiles/store.d.ts.map +1 -0
- package/services/voice-profiles/store.js +50 -0
- package/services/voice-profiles/types.d.ts +38 -0
- package/services/voice-profiles/types.d.ts.map +1 -0
- package/services/voice-profiles/types.js +1 -0
- package/styles/electrobun-mac-window-drag.css +4 -4
- package/test/helpers/__tests__/live-agent-test.smoke.test.ts +43 -70
- package/test/helpers/browser-mocks.ts +2 -2
- package/test/helpers/conditional-tests.ts +2 -2
- package/test/helpers/i18n.ts +1 -1
- package/test/helpers/live-agent-test.ts +537 -551
- package/test/helpers/live-provider.test.ts +4 -4
- package/test/helpers/live-provider.ts +41 -7
- package/test/helpers/live-runtime-server.ts +4 -4
- package/test/helpers/pglite-runtime.ts +1 -1
- package/test/helpers/real-runtime.ts +54 -15
- package/test/helpers/trajectory-harness.ts +11 -7
- package/test/scripts/start-eliza-live.ts +9 -0
- package/test/scripts/test-parallel.mjs +1 -1
- package/test/scripts/test-root-unit.mjs +6 -7
- package/ui-compat.d.ts +13 -2
- package/ui-compat.d.ts.map +1 -1
- package/ui-compat.js +19 -3
- package/api/auth-pairing-compat-routes.d.ts +0 -17
- package/api/auth-pairing-compat-routes.d.ts.map +0 -1
- package/api/auth-pairing-compat-routes.js +0 -301
- package/api/local-inference-compat-routes.d.ts +0 -16
- package/api/local-inference-compat-routes.d.ts.map +0 -1
- package/api/local-inference-compat-routes.js +0 -617
- package/api/onboarding-compat-routes.d.ts +0 -4
- package/api/onboarding-compat-routes.d.ts.map +0 -1
- package/api/onboarding-compat-routes.js +0 -207
- package/api/plugins-compat-routes.d.ts +0 -103
- package/api/plugins-compat-routes.d.ts.map +0 -1
- package/api/plugins-compat-routes.js +0 -1181
- package/api/server-onboarding-compat.d.ts +0 -31
- package/api/server-onboarding-compat.d.ts.map +0 -1
- package/api/server-onboarding-compat.js +0 -283
- package/benchmark/cua-routes.d.ts +0 -10
- package/benchmark/cua-routes.d.ts.map +0 -1
- package/benchmark/cua-routes.js +0 -179
- package/benchmark/mock-plugin-base.d.ts +0 -9
- package/benchmark/mock-plugin-base.d.ts.map +0 -1
- package/benchmark/mock-plugin-base.js +0 -325
- package/cli/parse-duration.d.ts +0 -5
- package/cli/parse-duration.d.ts.map +0 -1
- package/cli/parse-duration.js +0 -27
- package/patches/llama-cpp-capacitor@0.1.5.patch +0 -2387
- package/platform/agent-browser-stub.d.ts +0 -27
- package/platform/agent-browser-stub.d.ts.map +0 -1
- package/platform/agent-browser-stub.js +0 -16
- package/platforms/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +0 -26
- package/platforms/android/app/src/main/res/drawable/ic_launcher_background.xml +0 -170
- package/platforms/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -34
- package/platforms/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +0 -18
- package/platforms/electrobun/assets/appIcon.iconset/icon_512x512@2x.png +0 -0
- package/platforms/electrobun/assets/appIcon.png +0 -0
- package/platforms/electrobun/scripts/build-whisper-universal.sh +0 -137
- package/platforms/electrobun/scripts/build-whisper.sh +0 -95
- package/platforms/electrobun/src/libMacWindowEffects.dylib +0 -0
- package/platforms/electrobun/src/native/whisper.ts +0 -280
- package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png +0 -0
- package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png +0 -0
- package/registry/generate-apps.d.ts +0 -2
- package/registry/generate-apps.d.ts.map +0 -1
- package/registry/generate-apps.js +0 -338
- package/registry/generate.d.ts +0 -2
- package/registry/generate.d.ts.map +0 -1
- package/registry/generate.js +0 -506
- package/runtime/embedding-manager-support.d.ts +0 -77
- package/runtime/embedding-manager-support.d.ts.map +0 -1
- package/runtime/embedding-manager-support.js +0 -309
- package/runtime/embedding-presets.d.ts +0 -5
- package/runtime/embedding-presets.d.ts.map +0 -1
- package/runtime/embedding-presets.js +0 -47
- package/runtime/embedding-warmup-policy.d.ts +0 -13
- package/runtime/embedding-warmup-policy.d.ts.map +0 -1
- package/runtime/embedding-warmup-policy.js +0 -33
- package/runtime/ensure-local-inference-handler.d.ts +0 -25
- package/runtime/ensure-local-inference-handler.d.ts.map +0 -1
- package/runtime/ensure-local-inference-handler.js +0 -389
- package/runtime/mobile-local-inference-gate.d.ts +0 -21
- package/runtime/mobile-local-inference-gate.d.ts.map +0 -1
- package/runtime/mobile-local-inference-gate.js +0 -24
- package/scripts/aosp/avd-test.mjs +0 -403
- package/scripts/aosp/boot-validate.mjs +0 -536
- package/scripts/aosp/build-aosp.mjs +0 -448
- package/scripts/aosp/build-bootanimation.mjs +0 -178
- package/scripts/aosp/capture-screens.mjs +0 -325
- package/scripts/aosp/e2e-validate.mjs +0 -225
- package/scripts/aosp/lint-init-rc.mjs +0 -258
- package/scripts/aosp/llama-shim/eliza_llama_shim.c +0 -276
- package/scripts/aosp/sim.mjs +0 -277
- package/scripts/aosp/sync-to-aosp.mjs +0 -134
- package/scripts/aosp/validate.mjs +0 -1273
- package/scripts/build-llama-cpp-dflash.mjs +0 -1866
- package/scripts/generate-onboarding-voicelines.mjs +0 -194
- package/scripts/generated/static-asset-manifest.json +0 -4
- package/scripts/normalize-parallax-capture.ts +0 -97
- package/scripts/omnivoice-fuse/Makefile +0 -44
- package/scripts/omnivoice-fuse/README.md +0 -266
- package/scripts/omnivoice-fuse/cmake-graft.mjs +0 -180
- package/scripts/omnivoice-fuse/ffi-stub.c +0 -222
- package/scripts/omnivoice-fuse/ffi.h +0 -158
- package/scripts/omnivoice-fuse/libelizainference_stub.dylib +0 -0
- package/scripts/omnivoice-fuse/verify-symbols.mjs +0 -138
- package/security/cloud-secret-store.d.ts +0 -34
- package/security/cloud-secret-store.d.ts.map +0 -1
- package/security/cloud-secret-store.js +0 -65
- package/security/export-guard.d.ts +0 -34
- package/security/export-guard.d.ts.map +0 -1
- package/security/export-guard.js +0 -127
- package/services/local-inference/__stress__/cache-stress-helpers.d.ts +0 -76
- package/services/local-inference/__stress__/cache-stress-helpers.d.ts.map +0 -1
- package/services/local-inference/__stress__/cache-stress-helpers.js +0 -238
- package/services/local-inference/active-model.d.ts +0 -180
- package/services/local-inference/active-model.d.ts.map +0 -1
- package/services/local-inference/active-model.js +0 -362
- package/services/local-inference/assignments.d.ts +0 -58
- package/services/local-inference/assignments.d.ts.map +0 -1
- package/services/local-inference/assignments.js +0 -179
- package/services/local-inference/backend.d.ts +0 -200
- package/services/local-inference/backend.d.ts.map +0 -1
- package/services/local-inference/backend.js +0 -242
- package/services/local-inference/bundled-models.d.ts +0 -34
- package/services/local-inference/bundled-models.d.ts.map +0 -1
- package/services/local-inference/bundled-models.js +0 -104
- package/services/local-inference/cache-bridge.d.ts +0 -184
- package/services/local-inference/cache-bridge.d.ts.map +0 -1
- package/services/local-inference/cache-bridge.js +0 -333
- package/services/local-inference/catalog.d.ts +0 -57
- package/services/local-inference/catalog.d.ts.map +0 -1
- package/services/local-inference/catalog.js +0 -262
- package/services/local-inference/conversation-registry.d.ts +0 -122
- package/services/local-inference/conversation-registry.d.ts.map +0 -1
- package/services/local-inference/conversation-registry.js +0 -182
- package/services/local-inference/device-bridge.d.ts +0 -139
- package/services/local-inference/device-bridge.d.ts.map +0 -1
- package/services/local-inference/device-bridge.js +0 -774
- package/services/local-inference/dflash-doctor.d.ts +0 -27
- package/services/local-inference/dflash-doctor.d.ts.map +0 -1
- package/services/local-inference/dflash-doctor.js +0 -149
- package/services/local-inference/dflash-server.d.ts +0 -248
- package/services/local-inference/dflash-server.d.ts.map +0 -1
- package/services/local-inference/dflash-server.js +0 -1076
- package/services/local-inference/downloader.d.ts +0 -48
- package/services/local-inference/downloader.d.ts.map +0 -1
- package/services/local-inference/downloader.js +0 -688
- package/services/local-inference/engine.d.ts +0 -282
- package/services/local-inference/engine.d.ts.map +0 -1
- package/services/local-inference/engine.js +0 -743
- package/services/local-inference/external-scanner.d.ts +0 -17
- package/services/local-inference/external-scanner.d.ts.map +0 -1
- package/services/local-inference/external-scanner.js +0 -261
- package/services/local-inference/handler-registry.d.ts +0 -72
- package/services/local-inference/handler-registry.d.ts.map +0 -1
- package/services/local-inference/handler-registry.js +0 -159
- package/services/local-inference/hardware.d.ts +0 -26
- package/services/local-inference/hardware.d.ts.map +0 -1
- package/services/local-inference/hardware.js +0 -139
- package/services/local-inference/hf-search.d.ts +0 -19
- package/services/local-inference/hf-search.d.ts.map +0 -1
- package/services/local-inference/hf-search.js +0 -169
- package/services/local-inference/index.d.ts +0 -10
- package/services/local-inference/index.d.ts.map +0 -1
- package/services/local-inference/index.js +0 -7
- package/services/local-inference/llama-server-metrics.d.ts +0 -108
- package/services/local-inference/llama-server-metrics.d.ts.map +0 -1
- package/services/local-inference/llama-server-metrics.js +0 -175
- package/services/local-inference/manifest/index.d.ts +0 -4
- package/services/local-inference/manifest/index.d.ts.map +0 -1
- package/services/local-inference/manifest/index.js +0 -5
- package/services/local-inference/manifest/schema.d.ts +0 -419
- package/services/local-inference/manifest/schema.d.ts.map +0 -1
- package/services/local-inference/manifest/schema.js +0 -227
- package/services/local-inference/manifest/types.d.ts +0 -23
- package/services/local-inference/manifest/types.d.ts.map +0 -1
- package/services/local-inference/manifest/types.js +0 -5
- package/services/local-inference/manifest/validator.d.ts +0 -43
- package/services/local-inference/manifest/validator.d.ts.map +0 -1
- package/services/local-inference/manifest/validator.js +0 -180
- package/services/local-inference/paths.d.ts +0 -8
- package/services/local-inference/paths.d.ts.map +0 -1
- package/services/local-inference/paths.js +0 -7
- package/services/local-inference/providers.d.ts +0 -61
- package/services/local-inference/providers.d.ts.map +0 -1
- package/services/local-inference/providers.js +0 -334
- package/services/local-inference/ram-budget.d.ts +0 -57
- package/services/local-inference/ram-budget.d.ts.map +0 -1
- package/services/local-inference/ram-budget.js +0 -107
- package/services/local-inference/readiness.d.ts +0 -9
- package/services/local-inference/readiness.d.ts.map +0 -1
- package/services/local-inference/readiness.js +0 -153
- package/services/local-inference/recommendation.d.ts +0 -62
- package/services/local-inference/recommendation.d.ts.map +0 -1
- package/services/local-inference/recommendation.js +0 -309
- package/services/local-inference/registry.d.ts +0 -35
- package/services/local-inference/registry.d.ts.map +0 -1
- package/services/local-inference/registry.js +0 -117
- package/services/local-inference/router-handler.d.ts +0 -51
- package/services/local-inference/router-handler.d.ts.map +0 -1
- package/services/local-inference/router-handler.js +0 -165
- package/services/local-inference/routing-policy.d.ts +0 -55
- package/services/local-inference/routing-policy.d.ts.map +0 -1
- package/services/local-inference/routing-policy.js +0 -195
- package/services/local-inference/routing-preferences.d.ts +0 -8
- package/services/local-inference/routing-preferences.d.ts.map +0 -1
- package/services/local-inference/routing-preferences.js +0 -7
- package/services/local-inference/service.d.ts +0 -88
- package/services/local-inference/service.d.ts.map +0 -1
- package/services/local-inference/service.js +0 -210
- package/services/local-inference/session-pool.d.ts +0 -72
- package/services/local-inference/session-pool.d.ts.map +0 -1
- package/services/local-inference/session-pool.js +0 -125
- package/services/local-inference/types.d.ts +0 -309
- package/services/local-inference/types.d.ts.map +0 -1
- package/services/local-inference/types.js +0 -23
- package/services/local-inference/verify.d.ts +0 -8
- package/services/local-inference/verify.d.ts.map +0 -1
- package/services/local-inference/verify.js +0 -7
- package/services/local-inference/voice/barge-in.d.ts +0 -15
- package/services/local-inference/voice/barge-in.d.ts.map +0 -1
- package/services/local-inference/voice/barge-in.js +0 -20
- package/services/local-inference/voice/engine-bridge.d.ts +0 -256
- package/services/local-inference/voice/engine-bridge.d.ts.map +0 -1
- package/services/local-inference/voice/engine-bridge.js +0 -398
- package/services/local-inference/voice/ffi-bindings.d.ts +0 -114
- package/services/local-inference/voice/ffi-bindings.d.ts.map +0 -1
- package/services/local-inference/voice/ffi-bindings.js +0 -281
- package/services/local-inference/voice/index.d.ts +0 -51
- package/services/local-inference/voice/index.d.ts.map +0 -1
- package/services/local-inference/voice/index.js +0 -50
- package/services/local-inference/voice/lifecycle.d.ts +0 -135
- package/services/local-inference/voice/lifecycle.d.ts.map +0 -1
- package/services/local-inference/voice/lifecycle.js +0 -189
- package/services/local-inference/voice/phoneme-tokenizer.d.ts +0 -58
- package/services/local-inference/voice/phoneme-tokenizer.d.ts.map +0 -1
- package/services/local-inference/voice/phoneme-tokenizer.js +0 -53
- package/services/local-inference/voice/phrase-cache.d.ts +0 -24
- package/services/local-inference/voice/phrase-cache.d.ts.map +0 -1
- package/services/local-inference/voice/phrase-cache.js +0 -32
- package/services/local-inference/voice/phrase-chunker.d.ts +0 -20
- package/services/local-inference/voice/phrase-chunker.d.ts.map +0 -1
- package/services/local-inference/voice/phrase-chunker.js +0 -85
- package/services/local-inference/voice/ring-buffer.d.ts +0 -40
- package/services/local-inference/voice/ring-buffer.d.ts.map +0 -1
- package/services/local-inference/voice/ring-buffer.js +0 -85
- package/services/local-inference/voice/rollback-queue.d.ts +0 -24
- package/services/local-inference/voice/rollback-queue.d.ts.map +0 -1
- package/services/local-inference/voice/rollback-queue.js +0 -49
- package/services/local-inference/voice/scheduler.d.ts +0 -47
- package/services/local-inference/voice/scheduler.d.ts.map +0 -1
- package/services/local-inference/voice/scheduler.js +0 -123
- package/services/local-inference/voice/shared-resources.d.ts +0 -119
- package/services/local-inference/voice/shared-resources.d.ts.map +0 -1
- package/services/local-inference/voice/shared-resources.js +0 -83
- package/services/local-inference/voice/speaker-preset-cache.d.ts +0 -28
- package/services/local-inference/voice/speaker-preset-cache.d.ts.map +0 -1
- package/services/local-inference/voice/speaker-preset-cache.js +0 -44
- package/services/local-inference/voice/types.d.ts +0 -80
- package/services/local-inference/voice/types.d.ts.map +0 -1
- package/services/local-inference/voice/voice-preset-format.d.ts +0 -56
- package/services/local-inference/voice/voice-preset-format.d.ts.map +0 -1
- package/services/local-inference/voice/voice-preset-format.js +0 -184
- package/services/plugin-installer.d.ts +0 -22
- package/services/plugin-installer.d.ts.map +0 -1
- package/services/plugin-installer.js +0 -41
- package/test/scripts/task-agent-live-smoke.ts +0 -1335
- /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
|
|
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 = "
|
|
57
|
-
public static final String ACTION_STOP = "
|
|
58
|
-
public static final String ACTION_RESTART = "
|
|
59
|
-
public static final String ACTION_UPDATE_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
|
|
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
|
|
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 (
|
|
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
|
|
594
|
-
*
|
|
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
|
-
//
|
|
735
|
-
//
|
|
736
|
-
//
|
|
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(
|
|
739
|
-
command.add(
|
|
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
|
-
//
|
|
764
|
-
//
|
|
765
|
-
//
|
|
766
|
-
|
|
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
|
-
|
|
775
|
-
//
|
|
776
|
-
//
|
|
777
|
-
//
|
|
778
|
-
//
|
|
779
|
-
|
|
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
|
-
//
|
|
796
|
-
//
|
|
797
|
-
//
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
//
|
|
801
|
-
//
|
|
802
|
-
//
|
|
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
|
-
|
|
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
|
|
939
|
-
//
|
|
940
|
-
//
|
|
941
|
-
//
|
|
942
|
-
//
|
|
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
|
-
|
|
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
|
-
//
|
|
992
|
-
//
|
|
993
|
-
//
|
|
994
|
-
//
|
|
995
|
-
//
|
|
996
|
-
//
|
|
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
|
-
|
|
1012
|
-
|
|
1013
|
-
// stderrPump
|
|
1014
|
-
//
|
|
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 = "
|
|
1826
|
+
currentStatus = "starting";
|
|
1017
1827
|
updateNotification();
|
|
1018
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
|
1327
|
-
* hard connection failure (port
|
|
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/
|
|
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 "
|
|
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
|
-
|
|
1457
|
-
//
|
|
1458
|
-
|
|
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) {
|