@elizaos/app-core 2.0.0-beta.2 → 2.0.3-beta.2
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 +457 -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 +335 -18
- package/platforms/android/app/src/main/assets/runners/eliza-tasks.js +177 -0
- package/platforms/android/app/src/main/elizavoice-jni/CMakeLists.txt +100 -0
- package/platforms/android/app/src/main/elizavoice-jni/elizavoice-jni.cpp +1485 -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 +1255 -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/ElizaBionicInferenceServer.java +400 -0
- 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 +220 -0
- package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoicePlugin.java +498 -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 +405 -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 +116 -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 +137 -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 +49 -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 +4 -2
- 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 +440 -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 +103 -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-asr-word-timestamps.patch +218 -0
- 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-desktop-fused-lib.mjs +424 -0
- package/scripts/stage-elizavoice-lib.mjs +363 -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 +72 -20
- 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";
|
|
@@ -87,9 +96,28 @@ public class ElizaAgentService extends Service {
|
|
|
87
96
|
private static final int AGENT_PORT = 31337;
|
|
88
97
|
private static final String HEALTH_URL = "http://127.0.0.1:" + AGENT_PORT + "/api/health";
|
|
89
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Abstract-namespace AF_UNIX socket the in-process bionic GPU inference
|
|
101
|
+
* server ({@link ElizaBionicInferenceServer}) binds, and the musl agent's
|
|
102
|
+
* BionicHostLoader connects to. Abstract namespace (no filesystem path)
|
|
103
|
+
* avoids SELinux file-label issues under the priv_app domain. The musl
|
|
104
|
+
* agent reaches it as {@code Bun.connect({unix:"\0" + name})}.
|
|
105
|
+
*/
|
|
106
|
+
static final String BIONIC_INFERENCE_SOCKET_NAME = "eliza_bionic_infer_v1";
|
|
107
|
+
private static final String LOCAL_AGENT_BASE_URL = "http://127.0.0.1:" + AGENT_PORT;
|
|
108
|
+
private static final int LOCAL_REQUEST_DEFAULT_TIMEOUT_MS = 10_000;
|
|
109
|
+
private static final int LOCAL_REQUEST_MAX_TIMEOUT_MS = 600_000;
|
|
110
|
+
// Read-timeout budget applied to slow on-device inference routes (ASR / TTS
|
|
111
|
+
// / transcription / chat generation) when the caller doesn't pin its own —
|
|
112
|
+
// matches LOCAL_REQUEST_MAX_TIMEOUT_MS and the agent's chat-generation
|
|
113
|
+
// budget so a cold model load never trips a spurious local_agent_unavailable.
|
|
114
|
+
private static final int LOCAL_INFERENCE_REQUEST_TIMEOUT_MS = 600_000;
|
|
115
|
+
private static final int LOCAL_REQUEST_MAX_BODY_BYTES = 10 * 1024 * 1024;
|
|
116
|
+
private static final int LOCAL_REQUEST_MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
|
|
117
|
+
|
|
90
118
|
// The on-device boot path is heavy: PGlite extension extraction +
|
|
91
119
|
// plugin resolution + libllama dlopen + first-time model load can
|
|
92
|
-
// exceed
|
|
120
|
+
// exceed several minutes on a cold cuttlefish x86_64 image. The chat path is
|
|
93
121
|
// even heavier: a single planner-produced prompt at ~12k tokens,
|
|
94
122
|
// chunked through llama_decode on emulated CPU, can run 15–30 min
|
|
95
123
|
// wall-clock for a single chat turn (multiple model invocations:
|
|
@@ -102,7 +130,7 @@ public class ElizaAgentService extends Service {
|
|
|
102
130
|
// event loop yet), we DO NOT count a strike — the process is doing
|
|
103
131
|
// exactly what it should be doing, just synchronously inside a
|
|
104
132
|
// native call. We only count strikes when the process is actually
|
|
105
|
-
// dead OR returns
|
|
133
|
+
// dead OR returns non-2xx / non-ready health (a real crash signal).
|
|
106
134
|
// Strikes accumulate when the process is dead, which forces a
|
|
107
135
|
// restart via the existing scheduleRestart() path.
|
|
108
136
|
//
|
|
@@ -116,16 +144,29 @@ public class ElizaAgentService extends Service {
|
|
|
116
144
|
private static final long WATCHDOG_INTERVAL_MS = 600_000L;
|
|
117
145
|
private static final int HEALTH_FAIL_STRIKES = 3;
|
|
118
146
|
private static final long HEALTH_TIMEOUT_MS = 30_000L;
|
|
147
|
+
// Keep this aligned with packages/app/scripts/mobile-local-chat-smoke.mjs:
|
|
148
|
+
// ANDROID_HEALTH_ATTEMPTS (240) × 2000 ms = 480 s.
|
|
149
|
+
private static final long STARTUP_HEALTH_GRACE_MS = 480_000L;
|
|
150
|
+
private static final long STARTUP_HEALTH_POLL_MS = 5_000L;
|
|
119
151
|
private static final int MAX_RESTART_ATTEMPTS = 5;
|
|
120
152
|
private static final long PROCESS_TERMINATE_GRACE_MS = 5_000L;
|
|
153
|
+
// How long after a detached launch we treat a not-yet-listening agent as
|
|
154
|
+
// "still cold-booting" and refuse to relaunch it (the boot — plugin
|
|
155
|
+
// resolution + first model load — runs ~60-90s on an emulated CPU). Past
|
|
156
|
+
// this the boot is considered failed and a relaunch is allowed.
|
|
157
|
+
private static final long AGENT_BOOT_GRACE_MS = 120_000L;
|
|
121
158
|
|
|
122
159
|
private final Object processLock = new Object();
|
|
123
160
|
private Process agentProcess;
|
|
124
161
|
private Thread stdoutPump;
|
|
125
162
|
private Thread stderrPump;
|
|
126
163
|
private WatchdogThread watchdog;
|
|
164
|
+
/** In-process bionic GPU inference host; non-null only when delegating. */
|
|
165
|
+
private volatile ElizaBionicInferenceServer bionicInferenceServer;
|
|
127
166
|
private Thread startWorker;
|
|
128
167
|
private volatile boolean shuttingDown;
|
|
168
|
+
private volatile boolean detachedAgentMode;
|
|
169
|
+
private volatile long detachedLaunchStartedAtMs;
|
|
129
170
|
private int restartAttempts;
|
|
130
171
|
private String currentStatus = "starting";
|
|
131
172
|
|
|
@@ -136,12 +177,424 @@ public class ElizaAgentService extends Service {
|
|
|
136
177
|
// include `Authorization: Bearer <token>`. The agent enforces the
|
|
137
178
|
// token via ELIZA_REQUIRE_LOCAL_AUTH=1.
|
|
138
179
|
private static volatile String currentLocalAgentToken;
|
|
180
|
+
private static volatile String currentTerminalRunToken;
|
|
139
181
|
|
|
140
182
|
/** Called by the Capacitor agent plugin Android binding. */
|
|
141
183
|
public static String localAgentToken() {
|
|
142
184
|
return currentLocalAgentToken;
|
|
143
185
|
}
|
|
144
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Cross-process token recovery. The token is a per-process static, but the
|
|
189
|
+
* bun agent is a DETACHED process that outlives the app process that started
|
|
190
|
+
* it — so a freshly-launched WebView process (e.g. after a boot autostart)
|
|
191
|
+
* sees a null static even though a healthy agent is running, which dead-ends
|
|
192
|
+
* the dashboard at the pairing screen. Fall back to the recovery file that
|
|
193
|
+
* {@link #writeLocalAgentTokenFile} persists, and cache it for this process.
|
|
194
|
+
*/
|
|
195
|
+
public static String localAgentToken(Context context) {
|
|
196
|
+
String token = currentLocalAgentToken;
|
|
197
|
+
if (token != null && !token.trim().isEmpty()) {
|
|
198
|
+
return token;
|
|
199
|
+
}
|
|
200
|
+
if (context == null) {
|
|
201
|
+
return token;
|
|
202
|
+
}
|
|
203
|
+
String fromFile = readLocalAgentTokenFile(context);
|
|
204
|
+
if (fromFile != null && !fromFile.trim().isEmpty()) {
|
|
205
|
+
currentLocalAgentToken = fromFile.trim();
|
|
206
|
+
return currentLocalAgentToken;
|
|
207
|
+
}
|
|
208
|
+
return token;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private static String readLocalAgentTokenFile(Context context) {
|
|
212
|
+
File file = new File(new File(context.getFilesDir(), "auth"), "local-agent-token");
|
|
213
|
+
if (!file.isFile()) {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
try (java.io.FileInputStream in = new java.io.FileInputStream(file)) {
|
|
217
|
+
java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
|
|
218
|
+
byte[] buf = new byte[256];
|
|
219
|
+
int n;
|
|
220
|
+
while ((n = in.read(buf)) != -1) {
|
|
221
|
+
bos.write(buf, 0, n);
|
|
222
|
+
}
|
|
223
|
+
return new String(bos.toByteArray(), java.nio.charset.StandardCharsets.UTF_8).trim();
|
|
224
|
+
} catch (IOException error) {
|
|
225
|
+
Log.w(TAG, "Unable to read local-agent token file: " + error.getMessage());
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** Called by trusted in-app code that needs to route shell requests. */
|
|
231
|
+
public static String terminalRunToken() {
|
|
232
|
+
return currentTerminalRunToken;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Shared in-process request surface for Android native plugins and workers.
|
|
237
|
+
*
|
|
238
|
+
* The current Android agent still serves routes from the Bun child process
|
|
239
|
+
* over loopback, but callers should route through this method instead of
|
|
240
|
+
* opening their own sockets. That keeps auth, header filtering, body caps,
|
|
241
|
+
* and future Binder/stdio replacement behind one app-owned boundary.
|
|
242
|
+
*/
|
|
243
|
+
/**
|
|
244
|
+
* Routes whose on-device handler does a synchronous, multi-second (cold
|
|
245
|
+
* model load) or open-ended (token-by-token generation) llama call before
|
|
246
|
+
* the HTTP response completes — they need the long inference read-timeout
|
|
247
|
+
* budget, not the 10s default used for ordinary CRUD API calls.
|
|
248
|
+
*/
|
|
249
|
+
private static boolean isLongRunningInferencePath(String path) {
|
|
250
|
+
if (path == null) return false;
|
|
251
|
+
String p = path.toLowerCase(Locale.US);
|
|
252
|
+
return p.contains("/asr")
|
|
253
|
+
|| p.contains("/tts")
|
|
254
|
+
|| p.contains("/transcription")
|
|
255
|
+
|| p.contains("/speech")
|
|
256
|
+
|| p.contains("/local-inference")
|
|
257
|
+
|| p.contains("/messages/stream")
|
|
258
|
+
|| p.contains("/messages")
|
|
259
|
+
|| p.contains("/greeting")
|
|
260
|
+
|| p.contains("/voice");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
public static String requestLocalAgent(String requestJson) throws IOException, JSONException {
|
|
264
|
+
JSONObject request = requestJson == null || requestJson.trim().isEmpty()
|
|
265
|
+
? new JSONObject()
|
|
266
|
+
: new JSONObject(requestJson);
|
|
267
|
+
String path = request.optString("path", "").trim();
|
|
268
|
+
if (!isSafeLocalAgentPath(path)) {
|
|
269
|
+
throw new IllegalArgumentException("Local agent request requires a path that starts with /");
|
|
270
|
+
}
|
|
271
|
+
String method = request.optString("method", "GET")
|
|
272
|
+
.trim()
|
|
273
|
+
.toUpperCase(Locale.US);
|
|
274
|
+
if (!method.matches("^[A-Z]{1,16}$")) {
|
|
275
|
+
throw new IllegalArgumentException("Unsupported HTTP method");
|
|
276
|
+
}
|
|
277
|
+
int timeoutMs = request.optInt("timeoutMs", LOCAL_REQUEST_DEFAULT_TIMEOUT_MS);
|
|
278
|
+
// On-device inference is inherently slow: a cold model load alone — the
|
|
279
|
+
// ~1 GB ASR GGUF, the OmniVoice TTS GGUFs, or evicting + reloading the
|
|
280
|
+
// chat model — is a multi-second synchronous llama load before the agent
|
|
281
|
+
// emits a single byte, and transcription/synthesis/generation on
|
|
282
|
+
// emulated or low-end CPU runs well past 10 s. The WebView transport
|
|
283
|
+
// sends its generic 10 s fetch timeout for these calls too, which aborts
|
|
284
|
+
// them mid-decode and surfaces "Local agent request failed" /
|
|
285
|
+
// local_agent_unavailable, failing the whole voice turn (and every route
|
|
286
|
+
// that touches inference). FLOOR inference/voice routes at the inference
|
|
287
|
+
// budget — raise a too-short caller timeout, never lower a longer one.
|
|
288
|
+
if (isLongRunningInferencePath(path)) {
|
|
289
|
+
timeoutMs = Math.max(timeoutMs, LOCAL_INFERENCE_REQUEST_TIMEOUT_MS);
|
|
290
|
+
}
|
|
291
|
+
timeoutMs = Math.max(1_000, Math.min(timeoutMs, LOCAL_REQUEST_MAX_TIMEOUT_MS));
|
|
292
|
+
JSONObject headers = request.optJSONObject("headers");
|
|
293
|
+
Object rawBody = request.opt("body");
|
|
294
|
+
String body = rawBody == null || rawBody == JSONObject.NULL ? null : rawBody.toString();
|
|
295
|
+
|
|
296
|
+
return performLocalAgentRequest(
|
|
297
|
+
method,
|
|
298
|
+
path,
|
|
299
|
+
headers == null ? new JSONObject() : headers,
|
|
300
|
+
body,
|
|
301
|
+
timeoutMs,
|
|
302
|
+
currentLocalAgentToken
|
|
303
|
+
).toString();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Streaming variant of {@link #requestLocalAgent}. Where that buffers the
|
|
308
|
+
* whole loopback response into one JSON string (so an SSE body's token
|
|
309
|
+
* frames arrive all at once and the chat reply never streams on mobile),
|
|
310
|
+
* this opens the same request and reads the response InputStream
|
|
311
|
+
* INCREMENTALLY, pushing each fragment to {@code onEvent} as a small JSON
|
|
312
|
+
* envelope the AgentPlugin maps to Capacitor events:
|
|
313
|
+
* {"type":"response","status":..,"statusText":..,"headers":{..}} (once, first)
|
|
314
|
+
* {"type":"chunk","dataBase64":".."} (per read)
|
|
315
|
+
* {"type":"complete"} or {"type":"complete","error":".."} (terminal)
|
|
316
|
+
*
|
|
317
|
+
* Single attempt by design: a connect failure emits a terminal error event
|
|
318
|
+
* and the WebView falls back to the buffered {@link #requestLocalAgent}
|
|
319
|
+
* (which carries the cold-load connect retry), so non-idempotent POSTs are
|
|
320
|
+
* never replayed here. Runs on the caller's thread (AgentPlugin spawns one).
|
|
321
|
+
*/
|
|
322
|
+
public static void requestLocalAgentStream(String requestJson, java.util.function.Consumer<String> onEvent) {
|
|
323
|
+
try {
|
|
324
|
+
JSONObject request = requestJson == null || requestJson.trim().isEmpty()
|
|
325
|
+
? new JSONObject()
|
|
326
|
+
: new JSONObject(requestJson);
|
|
327
|
+
String path = request.optString("path", "").trim();
|
|
328
|
+
if (!isSafeLocalAgentPath(path)) {
|
|
329
|
+
throw new IllegalArgumentException("Local agent request requires a path that starts with /");
|
|
330
|
+
}
|
|
331
|
+
String method = request.optString("method", "GET").trim().toUpperCase(Locale.US);
|
|
332
|
+
if (!method.matches("^[A-Z]{1,16}$")) {
|
|
333
|
+
throw new IllegalArgumentException("Unsupported HTTP method");
|
|
334
|
+
}
|
|
335
|
+
int timeoutMs = request.optInt("timeoutMs", LOCAL_REQUEST_DEFAULT_TIMEOUT_MS);
|
|
336
|
+
if (isLongRunningInferencePath(path)) {
|
|
337
|
+
timeoutMs = Math.max(timeoutMs, LOCAL_INFERENCE_REQUEST_TIMEOUT_MS);
|
|
338
|
+
}
|
|
339
|
+
timeoutMs = Math.max(1_000, Math.min(timeoutMs, LOCAL_REQUEST_MAX_TIMEOUT_MS));
|
|
340
|
+
JSONObject headers = request.optJSONObject("headers");
|
|
341
|
+
if (headers == null) headers = new JSONObject();
|
|
342
|
+
Object rawBody = request.opt("body");
|
|
343
|
+
String body = rawBody == null || rawBody == JSONObject.NULL ? null : rawBody.toString();
|
|
344
|
+
streamLocalAgentRequest(method, path, headers, body, timeoutMs, currentLocalAgentToken, onEvent);
|
|
345
|
+
} catch (Exception error) {
|
|
346
|
+
emitStreamComplete(onEvent, error.getMessage() == null ? "Local agent stream failed" : error.getMessage());
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
private static void streamLocalAgentRequest(
|
|
351
|
+
String method,
|
|
352
|
+
String path,
|
|
353
|
+
JSONObject headers,
|
|
354
|
+
String body,
|
|
355
|
+
int timeoutMs,
|
|
356
|
+
String token,
|
|
357
|
+
java.util.function.Consumer<String> onEvent
|
|
358
|
+
) throws IOException, JSONException {
|
|
359
|
+
byte[] bodyBytes = body == null ? null : body.getBytes(StandardCharsets.UTF_8);
|
|
360
|
+
if (bodyBytes != null && bodyBytes.length > LOCAL_REQUEST_MAX_BODY_BYTES) {
|
|
361
|
+
throw new IOException("Request body is too large");
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
HttpURLConnection conn = null;
|
|
365
|
+
try {
|
|
366
|
+
URL url = new URL(LOCAL_AGENT_BASE_URL + path);
|
|
367
|
+
conn = (HttpURLConnection) url.openConnection();
|
|
368
|
+
conn.setRequestMethod(method);
|
|
369
|
+
conn.setConnectTimeout(timeoutMs);
|
|
370
|
+
conn.setReadTimeout(timeoutMs);
|
|
371
|
+
conn.setInstanceFollowRedirects(false);
|
|
372
|
+
conn.setUseCaches(false);
|
|
373
|
+
applyLocalAgentHeaders(conn, headers);
|
|
374
|
+
if (token != null && !token.trim().isEmpty() && !hasHeader(headers, "authorization")) {
|
|
375
|
+
conn.setRequestProperty("Authorization", "Bearer " + token.trim());
|
|
376
|
+
}
|
|
377
|
+
if (bodyBytes != null && !"GET".equals(method) && !"HEAD".equals(method)) {
|
|
378
|
+
if (!hasHeader(headers, "content-type")) {
|
|
379
|
+
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
|
380
|
+
}
|
|
381
|
+
conn.setDoOutput(true);
|
|
382
|
+
try (OutputStream out = conn.getOutputStream()) {
|
|
383
|
+
out.write(bodyBytes);
|
|
384
|
+
out.flush();
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
int status = conn.getResponseCode();
|
|
389
|
+
JSONObject responseHeaders = new JSONObject();
|
|
390
|
+
for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
|
|
391
|
+
String key = entry.getKey();
|
|
392
|
+
List<String> values = entry.getValue();
|
|
393
|
+
if (key == null || values == null || values.isEmpty()) continue;
|
|
394
|
+
responseHeaders.put(key.toLowerCase(Locale.US), String.join(", ", values));
|
|
395
|
+
}
|
|
396
|
+
onEvent.accept(new JSONObject()
|
|
397
|
+
.put("type", "response")
|
|
398
|
+
.put("status", status)
|
|
399
|
+
.put("statusText", conn.getResponseMessage() == null ? "" : conn.getResponseMessage())
|
|
400
|
+
.put("headers", responseHeaders)
|
|
401
|
+
.toString());
|
|
402
|
+
|
|
403
|
+
// Read the body as it arrives. The agent flushes each SSE frame, so a
|
|
404
|
+
// blocking read returns per-frame rather than waiting for the whole
|
|
405
|
+
// body — that is exactly the incremental delivery the WebView needs.
|
|
406
|
+
InputStream stream = status >= 400 ? conn.getErrorStream() : conn.getInputStream();
|
|
407
|
+
if (stream != null) {
|
|
408
|
+
byte[] buffer = new byte[8192];
|
|
409
|
+
int read;
|
|
410
|
+
while ((read = stream.read(buffer)) != -1) {
|
|
411
|
+
if (read == 0) continue;
|
|
412
|
+
String dataBase64 = android.util.Base64.encodeToString(
|
|
413
|
+
java.util.Arrays.copyOf(buffer, read), android.util.Base64.NO_WRAP);
|
|
414
|
+
onEvent.accept(new JSONObject()
|
|
415
|
+
.put("type", "chunk")
|
|
416
|
+
.put("dataBase64", dataBase64)
|
|
417
|
+
.toString());
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
emitStreamComplete(onEvent, null);
|
|
421
|
+
} finally {
|
|
422
|
+
if (conn != null) conn.disconnect();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
private static void emitStreamComplete(java.util.function.Consumer<String> onEvent, String error) {
|
|
427
|
+
try {
|
|
428
|
+
JSONObject complete = new JSONObject().put("type", "complete");
|
|
429
|
+
if (error != null) complete.put("error", error);
|
|
430
|
+
onEvent.accept(complete.toString());
|
|
431
|
+
} catch (JSONException ignored) {
|
|
432
|
+
// A complete event with no error is the worst case if JSON fails.
|
|
433
|
+
onEvent.accept("{\"type\":\"complete\"}");
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
private static boolean isSafeLocalAgentPath(String path) {
|
|
438
|
+
return path != null
|
|
439
|
+
&& path.startsWith("/")
|
|
440
|
+
&& !path.startsWith("//")
|
|
441
|
+
&& !path.contains("://");
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
private static JSONObject performLocalAgentRequest(
|
|
445
|
+
String method,
|
|
446
|
+
String path,
|
|
447
|
+
JSONObject headers,
|
|
448
|
+
String body,
|
|
449
|
+
int timeoutMs,
|
|
450
|
+
String token
|
|
451
|
+
) throws IOException, JSONException {
|
|
452
|
+
// The on-device agent is single-threaded: while bun is inside a long
|
|
453
|
+
// synchronous FFI call (a cold ASR/TTS model load, or a llama_decode for
|
|
454
|
+
// a chat reply) its HTTP listener briefly stops accepting connections, so
|
|
455
|
+
// a concurrent request — e.g. createConversation right after a voice
|
|
456
|
+
// transcription — can hit "connection refused". The request bytes were
|
|
457
|
+
// never sent, so it is safe to back off and re-dial rather than surface a
|
|
458
|
+
// spurious local_agent_unavailable that fails the whole voice turn. Only
|
|
459
|
+
// connection-establishment failures are retried; a read timeout (request
|
|
460
|
+
// already sent) propagates so non-idempotent POSTs are never replayed.
|
|
461
|
+
// The window must outlast the longest event-loop stall: after a voice
|
|
462
|
+
// transcription the agent evicts + cold-reloads the chat model (a
|
|
463
|
+
// synchronous ~10-15 s llama load on phone CPU) before generating the
|
|
464
|
+
// reply, during which the HTTP listener refuses connections.
|
|
465
|
+
final int connectRetries = 15;
|
|
466
|
+
IOException lastConnectError = null;
|
|
467
|
+
for (int attempt = 0; attempt <= connectRetries; attempt++) {
|
|
468
|
+
try {
|
|
469
|
+
return performLocalAgentRequestOnce(
|
|
470
|
+
method, path, headers, body, timeoutMs, token);
|
|
471
|
+
} catch (java.net.ConnectException connectError) {
|
|
472
|
+
lastConnectError = connectError;
|
|
473
|
+
} catch (java.net.SocketTimeoutException timeoutError) {
|
|
474
|
+
// Distinguish connect-timeout (never sent → retry) from
|
|
475
|
+
// read-timeout (sent → must not replay). HttpURLConnection
|
|
476
|
+
// surfaces both as SocketTimeoutException; the connect phase
|
|
477
|
+
// message contains "connect".
|
|
478
|
+
String msg = timeoutError.getMessage();
|
|
479
|
+
if (msg != null && msg.toLowerCase(Locale.US).contains("connect")) {
|
|
480
|
+
lastConnectError = timeoutError;
|
|
481
|
+
} else {
|
|
482
|
+
throw timeoutError;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
if (attempt < connectRetries) {
|
|
486
|
+
try {
|
|
487
|
+
Thread.sleep(250L * (attempt + 1));
|
|
488
|
+
} catch (InterruptedException interrupted) {
|
|
489
|
+
Thread.currentThread().interrupt();
|
|
490
|
+
throw lastConnectError;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
throw lastConnectError != null
|
|
495
|
+
? lastConnectError
|
|
496
|
+
: new IOException("local agent unreachable");
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
private static JSONObject performLocalAgentRequestOnce(
|
|
500
|
+
String method,
|
|
501
|
+
String path,
|
|
502
|
+
JSONObject headers,
|
|
503
|
+
String body,
|
|
504
|
+
int timeoutMs,
|
|
505
|
+
String token
|
|
506
|
+
) throws IOException, JSONException {
|
|
507
|
+
byte[] bodyBytes = body == null ? null : body.getBytes(StandardCharsets.UTF_8);
|
|
508
|
+
if (bodyBytes != null && bodyBytes.length > LOCAL_REQUEST_MAX_BODY_BYTES) {
|
|
509
|
+
throw new IOException("Request body is too large");
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
HttpURLConnection conn = null;
|
|
513
|
+
try {
|
|
514
|
+
URL url = new URL(LOCAL_AGENT_BASE_URL + path);
|
|
515
|
+
conn = (HttpURLConnection) url.openConnection();
|
|
516
|
+
conn.setRequestMethod(method);
|
|
517
|
+
conn.setConnectTimeout(timeoutMs);
|
|
518
|
+
conn.setReadTimeout(timeoutMs);
|
|
519
|
+
conn.setInstanceFollowRedirects(false);
|
|
520
|
+
conn.setUseCaches(false);
|
|
521
|
+
applyLocalAgentHeaders(conn, headers);
|
|
522
|
+
if (token != null && !token.trim().isEmpty() && !hasHeader(headers, "authorization")) {
|
|
523
|
+
conn.setRequestProperty("Authorization", "Bearer " + token.trim());
|
|
524
|
+
}
|
|
525
|
+
if (bodyBytes != null && !"GET".equals(method) && !"HEAD".equals(method)) {
|
|
526
|
+
if (!hasHeader(headers, "content-type")) {
|
|
527
|
+
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
|
528
|
+
}
|
|
529
|
+
conn.setDoOutput(true);
|
|
530
|
+
try (OutputStream out = conn.getOutputStream()) {
|
|
531
|
+
out.write(bodyBytes);
|
|
532
|
+
out.flush();
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
int status = conn.getResponseCode();
|
|
537
|
+
InputStream stream = status >= 400 ? conn.getErrorStream() : conn.getInputStream();
|
|
538
|
+
// Read the raw response bytes so binary payloads (e.g. local TTS WAV
|
|
539
|
+
// audio, images) survive the bridge intact. `body` is a best-effort
|
|
540
|
+
// UTF-8 view for text callers; `bodyBase64` carries the lossless raw
|
|
541
|
+
// bytes that binary callers decode — encoding the bytes as a UTF-8
|
|
542
|
+
// String first (the old path) replaced every non-UTF-8 byte with
|
|
543
|
+
// U+FFFD, corrupting WAV/PNG payloads beyond recovery.
|
|
544
|
+
byte[] responseBytes = readResponseBytes(stream, LOCAL_REQUEST_MAX_RESPONSE_BYTES);
|
|
545
|
+
String responseBody = new String(responseBytes, StandardCharsets.UTF_8);
|
|
546
|
+
JSONObject responseHeaders = new JSONObject();
|
|
547
|
+
for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
|
|
548
|
+
String key = entry.getKey();
|
|
549
|
+
List<String> values = entry.getValue();
|
|
550
|
+
if (key == null || values == null || values.isEmpty()) continue;
|
|
551
|
+
responseHeaders.put(key.toLowerCase(Locale.US), String.join(", ", values));
|
|
552
|
+
}
|
|
553
|
+
return new JSONObject()
|
|
554
|
+
.put("status", status)
|
|
555
|
+
.put("statusText", conn.getResponseMessage() == null ? "" : conn.getResponseMessage())
|
|
556
|
+
.put("headers", responseHeaders)
|
|
557
|
+
.put("body", responseBody)
|
|
558
|
+
.put(
|
|
559
|
+
"bodyBase64",
|
|
560
|
+
android.util.Base64.encodeToString(responseBytes, android.util.Base64.NO_WRAP)
|
|
561
|
+
)
|
|
562
|
+
.put("bodyEncoding", "base64");
|
|
563
|
+
} finally {
|
|
564
|
+
if (conn != null) conn.disconnect();
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
private static void applyLocalAgentHeaders(HttpURLConnection conn, JSONObject headers) {
|
|
569
|
+
if (headers == null) return;
|
|
570
|
+
java.util.Iterator<String> keys = headers.keys();
|
|
571
|
+
while (keys.hasNext()) {
|
|
572
|
+
String key = keys.next();
|
|
573
|
+
if (isBlockedForwardedHeader(key)) continue;
|
|
574
|
+
Object value = headers.opt(key);
|
|
575
|
+
if (value == null || value == JSONObject.NULL) continue;
|
|
576
|
+
String stringValue = value.toString();
|
|
577
|
+
if (!stringValue.trim().isEmpty()) {
|
|
578
|
+
conn.setRequestProperty(key, stringValue);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
private static boolean hasHeader(JSONObject headers, String expected) {
|
|
584
|
+
if (headers == null) return false;
|
|
585
|
+
java.util.Iterator<String> keys = headers.keys();
|
|
586
|
+
while (keys.hasNext()) {
|
|
587
|
+
if (expected.equalsIgnoreCase(keys.next())) return true;
|
|
588
|
+
}
|
|
589
|
+
return false;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
private static boolean isBlockedForwardedHeader(String key) {
|
|
593
|
+
return "host".equalsIgnoreCase(key)
|
|
594
|
+
|| "connection".equalsIgnoreCase(key)
|
|
595
|
+
|| "content-length".equalsIgnoreCase(key);
|
|
596
|
+
}
|
|
597
|
+
|
|
145
598
|
// ── Lifecycle ────────────────────────────────────────────────────────
|
|
146
599
|
|
|
147
600
|
@Override
|
|
@@ -201,6 +654,10 @@ public class ElizaAgentService extends Service {
|
|
|
201
654
|
watchdog.interrupt();
|
|
202
655
|
watchdog = null;
|
|
203
656
|
}
|
|
657
|
+
if (bionicInferenceServer != null) {
|
|
658
|
+
bionicInferenceServer.stop();
|
|
659
|
+
bionicInferenceServer = null;
|
|
660
|
+
}
|
|
204
661
|
stopAgentProcess();
|
|
205
662
|
NotificationManager mgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
|
206
663
|
if (mgr != null) {
|
|
@@ -226,7 +683,11 @@ public class ElizaAgentService extends Service {
|
|
|
226
683
|
String[] supported = Build.SUPPORTED_ABIS;
|
|
227
684
|
if (supported != null) {
|
|
228
685
|
for (String abi : supported) {
|
|
229
|
-
if (
|
|
686
|
+
if (
|
|
687
|
+
"arm64-v8a".equals(abi) ||
|
|
688
|
+
"x86_64".equals(abi) ||
|
|
689
|
+
"riscv64".equals(abi)
|
|
690
|
+
) return abi;
|
|
230
691
|
}
|
|
231
692
|
if (supported.length > 0) return supported[0];
|
|
232
693
|
}
|
|
@@ -316,6 +777,10 @@ public class ElizaAgentService extends Service {
|
|
|
316
777
|
if (initDbWasm.exists()) initDbWasm.delete();
|
|
317
778
|
File pgData = new File(root, "pglite.data");
|
|
318
779
|
if (pgData.exists()) pgData.delete();
|
|
780
|
+
File ortWasmLoader = new File(root, "ort-wasm-simd-threaded.mjs");
|
|
781
|
+
if (ortWasmLoader.exists()) ortWasmLoader.delete();
|
|
782
|
+
File ortWasmBinary = new File(root, "ort-wasm-simd-threaded.wasm");
|
|
783
|
+
if (ortWasmBinary.exists()) ortWasmBinary.delete();
|
|
319
784
|
File vec = new File(getFilesDir(), "vector.tar.gz");
|
|
320
785
|
if (vec.exists()) vec.delete();
|
|
321
786
|
File fuzzy = new File(getFilesDir(), "fuzzystrmatch.tar.gz");
|
|
@@ -359,6 +824,13 @@ public class ElizaAgentService extends Service {
|
|
|
359
824
|
copyAssetIfPresent(assets, "agent/pglite.wasm", new File(root, "pglite.wasm"));
|
|
360
825
|
copyAssetIfPresent(assets, "agent/initdb.wasm", new File(root, "initdb.wasm"));
|
|
361
826
|
copyAssetIfPresent(assets, "agent/pglite.data", new File(root, "pglite.data"));
|
|
827
|
+
// Legacy ONNX Runtime Web sidecars used by the removed Android Kokoro
|
|
828
|
+
// TTS path. Current AOSP TTS uses fused OmniVoice, so fresh bundles do
|
|
829
|
+
// not ship these files; keep extraction best-effort for older APKs.
|
|
830
|
+
copyAssetIfPresent(assets, "agent/ort-wasm-simd-threaded.mjs",
|
|
831
|
+
new File(root, "ort-wasm-simd-threaded.mjs"));
|
|
832
|
+
copyAssetIfPresent(assets, "agent/ort-wasm-simd-threaded.wasm",
|
|
833
|
+
new File(root, "ort-wasm-simd-threaded.wasm"));
|
|
362
834
|
// aapt2 not only strips `.gz` from `*.tar.gz` asset names, it also
|
|
363
835
|
// DECOMPRESSES them into raw tar bytes. PGlite's loader does
|
|
364
836
|
// `new URL("../X.tar.gz", ...)` then pipes the bytes through
|
|
@@ -394,6 +866,8 @@ public class ElizaAgentService extends Service {
|
|
|
394
866
|
|
|
395
867
|
File bun = new File(abiDir, BUN_BINARY);
|
|
396
868
|
if (bun.exists()) bun.setExecutable(true, false);
|
|
869
|
+
File llamaServer = new File(abiDir, "llama-server");
|
|
870
|
+
if (llamaServer.exists()) llamaServer.setExecutable(true, false);
|
|
397
871
|
File launch = new File(root, AGENT_LAUNCH_SCRIPT);
|
|
398
872
|
if (launch.exists()) launch.setExecutable(true, false);
|
|
399
873
|
for (String name : abiFiles) {
|
|
@@ -511,6 +985,7 @@ public class ElizaAgentService extends Service {
|
|
|
511
985
|
private String packagedMuslLoaderName(String abi) {
|
|
512
986
|
if ("arm64-v8a".equals(abi)) return "libeliza_ld_musl_aarch64.so";
|
|
513
987
|
if ("x86_64".equals(abi)) return "libeliza_ld_musl_x86_64.so";
|
|
988
|
+
if ("riscv64".equals(abi)) return "libeliza_ld_musl_riscv64.so";
|
|
514
989
|
return null;
|
|
515
990
|
}
|
|
516
991
|
|
|
@@ -590,10 +1065,8 @@ public class ElizaAgentService extends Service {
|
|
|
590
1065
|
|
|
591
1066
|
/**
|
|
592
1067
|
* Like copyAssetIfMissing, but silently no-ops when the source asset is
|
|
593
|
-
* absent. Used for PGlite + plugin-manifest
|
|
594
|
-
*
|
|
595
|
-
* placeholder bundle the assets are simply not present and the agent
|
|
596
|
-
* runs without them.
|
|
1068
|
+
* absent. Used for optional PGlite + plugin-manifest payloads; minimal
|
|
1069
|
+
* mobile bundles can run without those embedded database extensions.
|
|
597
1070
|
*/
|
|
598
1071
|
private void copyAssetIfPresent(AssetManager assets, String assetPath, File target) throws IOException {
|
|
599
1072
|
try (InputStream probe = assets.open(assetPath)) {
|
|
@@ -647,6 +1120,11 @@ public class ElizaAgentService extends Service {
|
|
|
647
1120
|
if (!restartFirst && agentProcess != null && agentProcess.isAlive()) {
|
|
648
1121
|
return;
|
|
649
1122
|
}
|
|
1123
|
+
if (!restartFirst
|
|
1124
|
+
&& detachedAgentMode
|
|
1125
|
+
&& ("starting".equals(currentStatus) || "running".equals(currentStatus))) {
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
650
1128
|
if (startWorker != null && startWorker.isAlive()) {
|
|
651
1129
|
return;
|
|
652
1130
|
}
|
|
@@ -674,6 +1152,47 @@ public class ElizaAgentService extends Service {
|
|
|
674
1152
|
return;
|
|
675
1153
|
}
|
|
676
1154
|
|
|
1155
|
+
// Detached agents outlive the service/app process that launched
|
|
1156
|
+
// them. If a prior instance's agent is still bound to the loopback
|
|
1157
|
+
// port, ADOPT it instead of relaunching: launch.sh pkills any
|
|
1158
|
+
// running bun before forking a fresh one, so a needless relaunch
|
|
1159
|
+
// tears the live HTTP listener down for tens of seconds and the
|
|
1160
|
+
// WebView's /api/auth/me startup probe fails with "Backend
|
|
1161
|
+
// Unreachable". That is the emulator e2e churn — the Activity/FGS
|
|
1162
|
+
// gets recreated mid-run and onStartCommand → startAgentProcess
|
|
1163
|
+
// would relaunch a perfectly healthy agent. Gate on the raw TCP
|
|
1164
|
+
// listener (not /api/health), so a bun that is alive but busy
|
|
1165
|
+
// mid-llama_decode — when an HTTP probe would time out — is still
|
|
1166
|
+
// recognised as running and left alone.
|
|
1167
|
+
if (detachedAgentMode && isLoopbackAgentListening()) {
|
|
1168
|
+
if (!"running".equals(currentStatus)) {
|
|
1169
|
+
currentStatus = "running";
|
|
1170
|
+
updateNotification();
|
|
1171
|
+
}
|
|
1172
|
+
Log.i(TAG, "Detached agent already listening on port " + AGENT_PORT
|
|
1173
|
+
+ "; adopting it (no relaunch).");
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
// The agent may have been launched moments ago and still be in its
|
|
1178
|
+
// (slow) cold boot — plugin resolution + first model load can take
|
|
1179
|
+
// 60-90s on an emulated CPU before bun binds the port. During that
|
|
1180
|
+
// window isLoopbackAgentListening() is false, so without this guard a
|
|
1181
|
+
// recreated Activity/FGS (onStartCommand fires repeatedly as the e2e
|
|
1182
|
+
// foregrounds/navigates) would relaunch.sh-pkill the booting bun and
|
|
1183
|
+
// restart the whole boot — an endless churn that never reaches ready.
|
|
1184
|
+
// If we launched within the boot grace window, assume it is still
|
|
1185
|
+
// coming up and leave it alone rather than kill + restart it.
|
|
1186
|
+
if (detachedAgentMode
|
|
1187
|
+
&& detachedLaunchStartedAtMs > 0
|
|
1188
|
+
&& (System.currentTimeMillis() - detachedLaunchStartedAtMs)
|
|
1189
|
+
< AGENT_BOOT_GRACE_MS) {
|
|
1190
|
+
Log.i(TAG, "Detached agent still in cold boot (launched "
|
|
1191
|
+
+ (System.currentTimeMillis() - detachedLaunchStartedAtMs)
|
|
1192
|
+
+ "ms ago); not relaunching.");
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
677
1196
|
String abi = resolveRuntimeAbi();
|
|
678
1197
|
try {
|
|
679
1198
|
extractAssetsIfNeeded(abi);
|
|
@@ -687,6 +1206,7 @@ public class ElizaAgentService extends Service {
|
|
|
687
1206
|
File root = agentRoot();
|
|
688
1207
|
File abiDir = agentAbiDir(abi);
|
|
689
1208
|
File bundle = new File(root, AGENT_BUNDLE_NAME);
|
|
1209
|
+
File launchScript = new File(root, AGENT_LAUNCH_SCRIPT);
|
|
690
1210
|
File bun = new File(abiDir, BUN_BINARY);
|
|
691
1211
|
String loaderName = findMuslLoader(abiDir);
|
|
692
1212
|
|
|
@@ -702,6 +1222,12 @@ public class ElizaAgentService extends Service {
|
|
|
702
1222
|
updateNotification();
|
|
703
1223
|
return;
|
|
704
1224
|
}
|
|
1225
|
+
if (!launchScript.exists()) {
|
|
1226
|
+
Log.e(TAG, "Agent launch script missing at " + launchScript);
|
|
1227
|
+
currentStatus = "missing-launcher";
|
|
1228
|
+
updateNotification();
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
705
1231
|
if (loaderName == null) {
|
|
706
1232
|
Log.e(TAG, "musl loader missing under " + abiDir);
|
|
707
1233
|
currentStatus = "missing-loader";
|
|
@@ -723,21 +1249,25 @@ public class ElizaAgentService extends Service {
|
|
|
723
1249
|
// Android. ELIZA_REQUIRE_LOCAL_AUTH on the server side flips
|
|
724
1250
|
// that heuristic off so every request needs the bearer token.
|
|
725
1251
|
String token = generateLocalAgentToken();
|
|
1252
|
+
String terminalToken = generateLocalAgentToken();
|
|
726
1253
|
currentLocalAgentToken = token;
|
|
1254
|
+
currentTerminalRunToken = terminalToken;
|
|
727
1255
|
try {
|
|
728
1256
|
writeLocalAgentTokenFile(token);
|
|
729
1257
|
} catch (IOException error) {
|
|
730
1258
|
Log.w(TAG, "Failed to persist local-agent token file: " + error.getMessage());
|
|
731
1259
|
}
|
|
732
1260
|
|
|
733
|
-
// Invocation
|
|
734
|
-
//
|
|
735
|
-
//
|
|
736
|
-
//
|
|
1261
|
+
// Invocation goes through launch.sh instead of keeping bun as a
|
|
1262
|
+
// Java child process. Android has repeatedly killed the direct
|
|
1263
|
+
// child path after ~30-50 s with SIGTRAP-like exit 133 while the
|
|
1264
|
+
// same runtime stays alive when it is session-detached. The
|
|
1265
|
+
// service still owns auth, env, foreground lifetime, and health
|
|
1266
|
+
// supervision; launch.sh only performs the setsid double-fork and
|
|
1267
|
+
// writes raw Bun stdio to agent/agent.log.
|
|
737
1268
|
List<String> command = new ArrayList<>();
|
|
738
|
-
command.add(
|
|
739
|
-
command.add(
|
|
740
|
-
command.add(bundle.getAbsolutePath());
|
|
1269
|
+
command.add("/system/bin/sh");
|
|
1270
|
+
command.add(launchScript.getAbsolutePath());
|
|
741
1271
|
|
|
742
1272
|
ProcessBuilder pb = new ProcessBuilder(command);
|
|
743
1273
|
pb.directory(root);
|
|
@@ -747,8 +1277,38 @@ public class ElizaAgentService extends Service {
|
|
|
747
1277
|
"LD_LIBRARY_PATH",
|
|
748
1278
|
nativeLibraryDir().getAbsolutePath() + ":" + abiDir.getAbsolutePath()
|
|
749
1279
|
);
|
|
1280
|
+
// Native voice libs (Silero VAD + WeSpeaker/pyannote voice classifier)
|
|
1281
|
+
// ship as jniLibs and extract into nativeLibraryDir. The on-device bun
|
|
1282
|
+
// agent's bun:ffi loaders (vad-ggml.ts / encoder-ggml.ts /
|
|
1283
|
+
// diarizer-ggml.ts) honor these env overrides; without them they fall
|
|
1284
|
+
// back to the repo-local CMake build dirs, which do not exist on a
|
|
1285
|
+
// packaged install, so live diarization would report library-missing.
|
|
1286
|
+
// Only export when the .so actually shipped, so a stale env never
|
|
1287
|
+
// points the loader at a missing path.
|
|
1288
|
+
File sileroVadLib = new File(nativeLibraryDir(), "libsilero_vad.so");
|
|
1289
|
+
File voiceClassifierLib = new File(nativeLibraryDir(), "libvoice_classifier.so");
|
|
1290
|
+
if (sileroVadLib.isFile() && !env.containsKey("ELIZA_SILERO_VAD_LIB")) {
|
|
1291
|
+
agentEnv.put("ELIZA_SILERO_VAD_LIB", sileroVadLib.getAbsolutePath());
|
|
1292
|
+
Log.i(TAG, "libsilero_vad.so present; exporting ELIZA_SILERO_VAD_LIB="
|
|
1293
|
+
+ sileroVadLib.getAbsolutePath());
|
|
1294
|
+
}
|
|
1295
|
+
if (voiceClassifierLib.isFile() && !env.containsKey("ELIZA_VOICE_CLASSIFIER_LIB")) {
|
|
1296
|
+
agentEnv.put("ELIZA_VOICE_CLASSIFIER_LIB", voiceClassifierLib.getAbsolutePath());
|
|
1297
|
+
Log.i(TAG, "libvoice_classifier.so present; exporting ELIZA_VOICE_CLASSIFIER_LIB="
|
|
1298
|
+
+ voiceClassifierLib.getAbsolutePath());
|
|
1299
|
+
}
|
|
1300
|
+
agentEnv.put("AGENT_ROOT", root.getAbsolutePath());
|
|
1301
|
+
agentEnv.put("RUNTIME_DIR", abiDir.getAbsolutePath());
|
|
1302
|
+
agentEnv.put("DEVICE_DIR", abiDir.getAbsolutePath());
|
|
1303
|
+
agentEnv.put("LD_NAME", loaderName);
|
|
1304
|
+
agentEnv.put("LD_PATH", loader.getAbsolutePath());
|
|
1305
|
+
agentEnv.put("BUN_PATH", bun.getAbsolutePath());
|
|
1306
|
+
agentEnv.put("AGENT_BUNDLE", AGENT_BUNDLE_NAME);
|
|
1307
|
+
agentEnv.put("AGENT_BUNDLE_PATH", bundle.getAbsolutePath());
|
|
1308
|
+
agentEnv.put("LOG_FILE", new File(root, AGENT_LOG_NAME).getAbsolutePath());
|
|
750
1309
|
agentEnv.put("PORT", String.valueOf(AGENT_PORT));
|
|
751
1310
|
agentEnv.put("ELIZA_API_PORT", String.valueOf(AGENT_PORT));
|
|
1311
|
+
agentEnv.put("ELIZA_API_BIND", "127.0.0.1");
|
|
752
1312
|
// The agent's runtime-env resolver reads ELIZA_PORT / ELIZA_UI_PORT
|
|
753
1313
|
// (defaulting to 2138) before falling back to PORT. Without
|
|
754
1314
|
// these the agent binds 2138 even though the service advertises
|
|
@@ -759,25 +1319,295 @@ public class ElizaAgentService extends Service {
|
|
|
759
1319
|
agentEnv.put("ELIZA_UI_PORT", String.valueOf(AGENT_PORT));
|
|
760
1320
|
agentEnv.put("ELIZA_STATE_DIR", agentStateDir().getAbsolutePath());
|
|
761
1321
|
agentEnv.put("ELIZA_PLATFORM", "android");
|
|
1322
|
+
agentEnv.put("ELIZA_MOBILE_PLATFORM", "android");
|
|
1323
|
+
agentEnv.put("ELIZA_RUNTIME_MODE", "local-yolo");
|
|
1324
|
+
agentEnv.put("AGENT_COMMAND", "android-bridge");
|
|
762
1325
|
agentEnv.put("ELIZA_DISABLE_DIRECT_RUN", "1");
|
|
763
|
-
//
|
|
764
|
-
//
|
|
765
|
-
//
|
|
766
|
-
|
|
1326
|
+
// Local passwordless mode: the on-device agent trusts its own
|
|
1327
|
+
// loopback so the single device owner never hits a login/pairing
|
|
1328
|
+
// gate. The per-boot bearer-token guard (ELIZA_REQUIRE_LOCAL_AUTH=1)
|
|
1329
|
+
// is intentionally OFF — the WebView cannot reliably present that
|
|
1330
|
+
// token at cold start, which otherwise dead-ends the dashboard at
|
|
1331
|
+
// 401 ("Connecting to backend…" forever). Tradeoff: other apps on
|
|
1332
|
+
// THIS device can reach 127.0.0.1:31337. The token is still minted
|
|
1333
|
+
// and exposed via the Agent plugin for callers that opt to use it.
|
|
1334
|
+
agentEnv.put("ELIZA_REQUIRE_LOCAL_AUTH", "0");
|
|
767
1335
|
agentEnv.put("ELIZA_API_TOKEN", token);
|
|
1336
|
+
agentEnv.put("ELIZA_TERMINAL_RUN_TOKEN", terminalToken);
|
|
768
1337
|
// The Capacitor APK always hosts @elizaos/capacitor-llama in the
|
|
769
1338
|
// WebView, so the runtime should always be ready to broker
|
|
770
1339
|
// inference over the device-bridge WSS at /api/local-inference/
|
|
771
1340
|
// device-bridge. The WebView dials it over loopback once the
|
|
772
1341
|
// user picks the local runtime mode in onboarding.
|
|
773
1342
|
agentEnv.put("ELIZA_DEVICE_BRIDGE_ENABLED", "1");
|
|
774
|
-
|
|
775
|
-
//
|
|
776
|
-
//
|
|
777
|
-
//
|
|
778
|
-
//
|
|
779
|
-
|
|
1343
|
+
agentEnv.put("ELIZA_DEVICE_PAIRING_TOKEN", token);
|
|
1344
|
+
// CPU-only inference on a stock-Android Capacitor APK runs the
|
|
1345
|
+
// same on-device chat path as the AOSP variant — Snapdragon
|
|
1346
|
+
// 4 Gen 1 / Tensor G1 class hardware lands at 3–7 tok/s and a
|
|
1347
|
+
// ~4.5 k-token system prompt + 256-token reply needs the
|
|
1348
|
+
// same 600 s native/chat budget the bridge uses by default.
|
|
1349
|
+
// The upstream gate that previously bumped these (under
|
|
1350
|
+
// `BuildConfig.AOSP_BUILD && isBrandedDevice()` further down)
|
|
1351
|
+
// only fires for branded AOSP builds; stock-Android sideloads
|
|
1352
|
+
// get the defaults and time out on every first turn with
|
|
1353
|
+
// "Chat generation failed with no streamed text
|
|
1354
|
+
// (err=Chat generation timed out after 180000ms)". Set the
|
|
1355
|
+
// same 10 min budget here unconditionally so both build
|
|
1356
|
+
// types finish their cold first turn.
|
|
1357
|
+
if (!env.containsKey("ELIZA_CHAT_GENERATION_TIMEOUT_MS")) {
|
|
1358
|
+
agentEnv.put("ELIZA_CHAT_GENERATION_TIMEOUT_MS", "600000");
|
|
1359
|
+
}
|
|
1360
|
+
if (!env.containsKey("ELIZA_DEVICE_GENERATE_TIMEOUT_MS")) {
|
|
1361
|
+
agentEnv.put("ELIZA_DEVICE_GENERATE_TIMEOUT_MS", "600000");
|
|
1362
|
+
}
|
|
1363
|
+
// The mobile bridge ships the bge embedding GGUF disabled
|
|
1364
|
+
// by default (`ELIZA_LOCAL_EMBEDDING_ENABLED!="1"`) because
|
|
1365
|
+
// mmapping it alongside the chat GGUF would OOM a 4 GB
|
|
1366
|
+
// Moto G Play class device. With the embedding handler
|
|
1367
|
+
// returning the zero vector for every call, the chat-
|
|
1368
|
+
// augmentation document-retrieval branch never lands a
|
|
1369
|
+
// match above `CHAT_DOCUMENTS_THRESHOLD`, and its LLM-
|
|
1370
|
+
// driven query recovery fallback wastes one full
|
|
1371
|
+
// generate-text round-trip per turn (~60–90 s on this
|
|
1372
|
+
// hardware) producing queries that themselves match
|
|
1373
|
+
// nothing. Skip the whole augmentation path when the
|
|
1374
|
+
// embedding handler is in the disabled state.
|
|
1375
|
+
if (!env.containsKey("ELIZA_DOCUMENT_AUGMENTATION_DISABLED")
|
|
1376
|
+
&& !"1".equals(env.get("ELIZA_LOCAL_EMBEDDING_ENABLED"))) {
|
|
1377
|
+
agentEnv.put("ELIZA_DOCUMENT_AUGMENTATION_DISABLED", "1");
|
|
1378
|
+
}
|
|
1379
|
+
// Skip the auto-download of recommended GGUF models that
|
|
1380
|
+
// mobile-device-bridge-bootstrap kicks off at registration
|
|
1381
|
+
// time. On Android the bun process cannot reach the network
|
|
1382
|
+
// without specific SELinux carve-outs and the download fail
|
|
1383
|
+
// cascades into a mid-init crash with no stderr captured
|
|
1384
|
+
// (agent.log empty, no exit code). The WebView side handles
|
|
1385
|
+
// model selection + persistence; the bun process only needs
|
|
1386
|
+
// the bridge handlers registered, not pre-warmed.
|
|
1387
|
+
agentEnv.put("ELIZA_DISABLE_MODEL_AUTO_DOWNLOAD", "1");
|
|
1388
|
+
// Native bun:ffi inference path. When the APK bundles the eliza
|
|
1389
|
+
// llama.cpp fork's fused native lib under agent/{abi}/
|
|
1390
|
+
// (libelizainference.so), opt the bun process into loading it
|
|
1391
|
+
// directly via bun:ffi — see
|
|
1392
|
+
// eliza/plugins/plugin-aosp-local-inference/src/aosp-local-inference-bootstrap.ts
|
|
1393
|
+
// (tryBuildAospFusedTextLoader) and aosp-llama-paths.ts
|
|
1394
|
+
// (isAospEnabled reads ELIZA_LOCAL_LLAMA).
|
|
1395
|
+
// This is required, not optional: the eliza-1 model tiers are
|
|
1396
|
+
// qwen35-arch + QJL/PolarQuant/TBQ-quantized, and the stock
|
|
1397
|
+
// llama-cpp-capacitor JNI lib cannot load those GGUFs at all
|
|
1398
|
+
// (`context->loadModel() returned false`). The fused
|
|
1399
|
+
// libelizainference.so carries the kernels + qwen35 arch and is
|
|
1400
|
+
// the SOLE text/voice native library the bun agent loads.
|
|
1401
|
+
//
|
|
1402
|
+
// This was previously gated on `BuildConfig.AOSP_BUILD &&
|
|
1403
|
+
// isBrandedDevice()`. That gate's sole rationale was the
|
|
1404
|
+
// aosp loader's first-run model auto-download crashing a
|
|
1405
|
+
// network-restricted bun process — but that download is already
|
|
1406
|
+
// suppressed unconditionally above
|
|
1407
|
+
// (ELIZA_DISABLE_MODEL_AUTO_DOWNLOAD=1), and the loader itself
|
|
1408
|
+
// self-gates + defensively no-ops when the lib is absent or
|
|
1409
|
+
// incompatible. Presence of the bundled fused lib is therefore
|
|
1410
|
+
// the correct, sufficient signal for both build types.
|
|
1411
|
+
//
|
|
1412
|
+
// libelizainference.so is the lib actually dlopen'd at runtime;
|
|
1413
|
+
// libllama.so is kept as a legacy OR-condition so the gate still
|
|
1414
|
+
// activates on any APK that predates the fused-lib cutover (where
|
|
1415
|
+
// only libllama.so + shim were staged). Once libllama.so stops
|
|
1416
|
+
// being built the fused lib alone trips the gate.
|
|
1417
|
+
File abiFusedInference = new File(abiDir, "libelizainference.so");
|
|
1418
|
+
File abiLibllama = new File(abiDir, "libllama.so");
|
|
1419
|
+
File abiLlamaShim = new File(abiDir, "libeliza-llama-shim.so");
|
|
1420
|
+
File abiSpeculativeShim = new File(abiDir, "libeliza-llama-speculative-shim.so");
|
|
1421
|
+
File abiGgmlVulkan = new File(abiDir, "libggml-vulkan.so");
|
|
1422
|
+
boolean fusedInferenceBundled = abiFusedInference.isFile();
|
|
1423
|
+
boolean legacyLibllamaBundled = abiLibllama.isFile() && abiLlamaShim.isFile();
|
|
1424
|
+
boolean nativeLlamaBundled = fusedInferenceBundled || legacyLibllamaBundled;
|
|
1425
|
+
boolean brandedAospBuild = BuildConfig.AOSP_BUILD && isBrandedDevice();
|
|
1426
|
+
// When the dynamic-Vulkan fused lib is staged (libelizainference.so +
|
|
1427
|
+
// libggml-vulkan.so), the GPU is only reachable from THIS bionic app
|
|
1428
|
+
// process — the musl agent's ld can't load libvulkan's HIDL closure
|
|
1429
|
+
// (project_android_gpu_vulkan_wall). So instead of pointing the musl
|
|
1430
|
+
// agent at the bun:ffi AOSP loader (ELIZA_LOCAL_LLAMA=1 → the wall),
|
|
1431
|
+
// delegate inference over an abstract-namespace UDS to the in-process
|
|
1432
|
+
// ElizaBionicInferenceServer, which runs libelizainference on the Mali
|
|
1433
|
+
// GPU. The musl agent never tries to load the native lib itself.
|
|
1434
|
+
boolean delegateToBionicHost = fusedInferenceBundled && abiGgmlVulkan.isFile();
|
|
1435
|
+
if (delegateToBionicHost) {
|
|
1436
|
+
agentEnv.put("ELIZA_BIONIC_HOST_DELEGATED", "1");
|
|
1437
|
+
agentEnv.put("ELIZA_BIONIC_INFERENCE_SOCK", BIONIC_INFERENCE_SOCKET_NAME);
|
|
1438
|
+
// The bionic host reloads the model per call (the fork's Vulkan
|
|
1439
|
+
// backend corrupts shared GPU weights on reuse), so even a
|
|
1440
|
+
// token-capped post-turn reflection runs ~40-60s — past the
|
|
1441
|
+
// 30s default post-delivery side-effect timeout. That reflection
|
|
1442
|
+
// is non-blocking background work (the reply is already
|
|
1443
|
+
// delivered), so give it room to finish and persist instead of
|
|
1444
|
+
// logging a spurious timeout every turn. Don't clobber an
|
|
1445
|
+
// explicit operator override.
|
|
1446
|
+
if (!agentEnv.containsKey("ELIZA_POST_DELIVERY_SIDE_EFFECT_TIMEOUT_MS")) {
|
|
1447
|
+
agentEnv.put("ELIZA_POST_DELIVERY_SIDE_EFFECT_TIMEOUT_MS", "120000");
|
|
1448
|
+
}
|
|
1449
|
+
Log.i(TAG, "agent/" + abiDir.getName()
|
|
1450
|
+
+ "/libggml-vulkan.so present; delegating inference to the in-process"
|
|
1451
|
+
+ " bionic Vulkan host over UDS \"" + BIONIC_INFERENCE_SOCKET_NAME
|
|
1452
|
+
+ "\" (NOT taking the musl bun:ffi AOSP path)");
|
|
1453
|
+
// Stand up the in-process GPU inference server BEFORE the agent
|
|
1454
|
+
// spawns so the abstract socket is already bound when the agent's
|
|
1455
|
+
// BionicHostLoader first connects. Idempotent across restarts.
|
|
1456
|
+
if (bionicInferenceServer == null) {
|
|
1457
|
+
String defaultBundleDir =
|
|
1458
|
+
new File(getFilesDir(), "eliza-1/bundle").getAbsolutePath();
|
|
1459
|
+
bionicInferenceServer =
|
|
1460
|
+
new ElizaBionicInferenceServer(BIONIC_INFERENCE_SOCKET_NAME, defaultBundleDir);
|
|
1461
|
+
}
|
|
1462
|
+
bionicInferenceServer.start();
|
|
1463
|
+
}
|
|
1464
|
+
if (!delegateToBionicHost && nativeLlamaBundled
|
|
1465
|
+
&& !env.containsKey("ELIZA_LOCAL_LLAMA")) {
|
|
1466
|
+
agentEnv.put("ELIZA_LOCAL_LLAMA", "1");
|
|
1467
|
+
String bundledLib = fusedInferenceBundled
|
|
1468
|
+
? "libelizainference.so"
|
|
1469
|
+
: "libllama.so + shim (legacy)";
|
|
1470
|
+
Log.i(TAG, "agent/" + abiDir.getName()
|
|
1471
|
+
+ "/" + bundledLib + " present; enabling native bun:ffi inference (ELIZA_LOCAL_LLAMA=1)");
|
|
1472
|
+
}
|
|
1473
|
+
if (nativeLlamaBundled) {
|
|
1474
|
+
// When the Vulkan ggml backend (libggml-vulkan.so) is bundled —
|
|
1475
|
+
// i.e. the arm64 GPU build — offload the model to the GPU. The
|
|
1476
|
+
// aosp loader pins n_gpu_layers=0 by default, so without
|
|
1477
|
+
// this a Vulkan-capable build still runs entirely on CPU. CPU-
|
|
1478
|
+
// only builds (riscv64, or arm64 without the Vulkan backend) ship
|
|
1479
|
+
// no libggml-vulkan.so, so they correctly stay on CPU.
|
|
1480
|
+
// Skipped when delegating: the GPU offload happens in the bionic
|
|
1481
|
+
// host, not the musl bun:ffi path (which can't reach Vulkan).
|
|
1482
|
+
if (!delegateToBionicHost
|
|
1483
|
+
&& abiGgmlVulkan.isFile()
|
|
1484
|
+
&& !env.containsKey("ELIZA_AOSP_LLAMA_USE_GPU")
|
|
1485
|
+
&& !env.containsKey("ELIZA_LLAMA_N_GPU_LAYERS")) {
|
|
1486
|
+
agentEnv.put("ELIZA_AOSP_LLAMA_USE_GPU", "true");
|
|
1487
|
+
Log.i(TAG, "agent/" + abiDir.getName()
|
|
1488
|
+
+ "/libggml-vulkan.so present; offloading inference to GPU (ELIZA_AOSP_LLAMA_USE_GPU=true)");
|
|
1489
|
+
}
|
|
1490
|
+
if (!env.containsKey("ELIZA_MOBILE_LOCAL_DIRECT_REPLY")) {
|
|
1491
|
+
agentEnv.put("ELIZA_MOBILE_LOCAL_DIRECT_REPLY", "1");
|
|
1492
|
+
}
|
|
1493
|
+
if (!env.containsKey("ELIZA_KOKORO_PREWARM")) {
|
|
1494
|
+
agentEnv.put("ELIZA_KOKORO_PREWARM", "1");
|
|
1495
|
+
}
|
|
1496
|
+
if (!env.containsKey("ELIZA_KOKORO_PREWARM_DELAY_MS")) {
|
|
1497
|
+
// Kokoro's first on-device ORT/WASM synthesis can be
|
|
1498
|
+
// CPU-bound for tens of seconds. Keep the warmup opt-in,
|
|
1499
|
+
// but schedule it well after the local HTTP server should
|
|
1500
|
+
// be listening so app readiness is not blocked by audio
|
|
1501
|
+
// cache priming.
|
|
1502
|
+
agentEnv.put("ELIZA_KOKORO_PREWARM_DELAY_MS", "60000");
|
|
1503
|
+
}
|
|
1504
|
+
if (abiSpeculativeShim.isFile()
|
|
1505
|
+
&& !env.containsKey("ELIZA_SPEC_TYPE")
|
|
1506
|
+
&& !env.containsKey("ELIZA_SPECULATIVE_TYPE")) {
|
|
1507
|
+
// Prefer the in-process MTP path when the bundled
|
|
1508
|
+
// llama.cpp fork supports it. This is intentionally not
|
|
1509
|
+
// required: current mobile Eliza-1 bundles ship MTP
|
|
1510
|
+
// drafter GGUFs, and the adapter falls back to MTP when
|
|
1511
|
+
// the target model lacks NextN/MTP tensors.
|
|
1512
|
+
agentEnv.put("ELIZA_SPEC_TYPE", "mtp");
|
|
1513
|
+
Log.i(TAG, "agent/" + abiDir.getName()
|
|
1514
|
+
+ "/libeliza-llama-speculative-shim.so present; preferring MTP speculative decode with MTP fallback");
|
|
1515
|
+
}
|
|
1516
|
+
if (abiSpeculativeShim.isFile() && brandedAospBuild && !env.containsKey("ELIZA_MTP")) {
|
|
1517
|
+
agentEnv.put("ELIZA_MTP", "1");
|
|
1518
|
+
Log.i(TAG, "agent/" + abiDir.getName()
|
|
1519
|
+
+ "/libeliza-llama-speculative-shim.so present on branded AOSP build; enabling in-process MTP (ELIZA_MTP=1)");
|
|
1520
|
+
} else if (abiSpeculativeShim.isFile() && !brandedAospBuild) {
|
|
1521
|
+
// Ship the speculative shim in stock APKs so explicit
|
|
1522
|
+
// ELIZA_MTP diagnostics still work, but do not make
|
|
1523
|
+
// MTP the default merely because the .so is present.
|
|
1524
|
+
// Pixel APK validation showed the current 2B drafter path
|
|
1525
|
+
// is functional but slower than target-only decode for
|
|
1526
|
+
// short chat turns, so stock Android stays target-only
|
|
1527
|
+
// until benchmark gating or a faster drafter path lands.
|
|
1528
|
+
Log.i(TAG, "agent/" + abiDir.getName()
|
|
1529
|
+
+ "/libeliza-llama-speculative-shim.so present; leaving MTP opt-in for stock APK");
|
|
1530
|
+
}
|
|
1531
|
+
if (BuildConfig.DEBUG && !env.containsKey("ELIZA_AOSP_LLAMA_DEBUG_LOG")) {
|
|
1532
|
+
File debugLog = new File(agentStateDir(), "aosp-llama-debug.log");
|
|
1533
|
+
agentEnv.put("ELIZA_AOSP_LLAMA_DEBUG_LOG", debugLog.getAbsolutePath());
|
|
1534
|
+
}
|
|
1535
|
+
// Mobile llama.cpp defaults for the in-process fork loader.
|
|
1536
|
+
// The adapter has safe fallbacks, but Java is the only layer
|
|
1537
|
+
// that can reliably read the Android CPU count before bun's
|
|
1538
|
+
// seccomp-limited runtime starts. Keep these tied to the
|
|
1539
|
+
// bundled fork libs, not to full-AOSP branding: the regular
|
|
1540
|
+
// debug APK uses the same bun:ffi path when those libs ship.
|
|
1541
|
+
//
|
|
1542
|
+
// The Eliza-1 native context is 128k. The regular debug APK
|
|
1543
|
+
// runs the model in-process on phone CPU, so default to a
|
|
1544
|
+
// small interactive context and let the adapter keep the tail
|
|
1545
|
+
// of oversized prompts. Full branded AOSP builds keep the
|
|
1546
|
+
// larger 16k context used by CVD/system smoke tests. This
|
|
1547
|
+
// keeps the debug APK's first message-handler prefill bounded
|
|
1548
|
+
// on Pixel-class devices instead of pinning bun behind a
|
|
1549
|
+
// multi-minute FFI call before it can answer health checks or
|
|
1550
|
+
// honor aborts.
|
|
1551
|
+
if (!env.containsKey("ELIZA_LLAMA_N_CTX")) {
|
|
1552
|
+
agentEnv.put("ELIZA_LLAMA_N_CTX", brandedAospBuild ? "16384" : "4096");
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
if (!env.containsKey("ELIZA_LLAMA_THREADS")) {
|
|
1556
|
+
int cores = Runtime.getRuntime().availableProcessors();
|
|
1557
|
+
if (cores < 1) cores = 1;
|
|
1558
|
+
agentEnv.put("ELIZA_LLAMA_THREADS", String.valueOf(cores));
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
// Keep decode chunks bounded for stock APK runs while avoiding
|
|
1562
|
+
// unnecessary multi-chunk prompt prefill. Pixel validation on
|
|
1563
|
+
// eliza-1-0_8b showed 256-token chunks reduce native prefill
|
|
1564
|
+
// time versus the older 64-token default, without blocking
|
|
1565
|
+
// health/startup probes because the HTTP server binds after
|
|
1566
|
+
// model prewarm. Branded AOSP keeps the historical 512-token
|
|
1567
|
+
// chunk size for its longer smoke budget.
|
|
1568
|
+
if (!env.containsKey("ELIZA_LLAMA_N_BATCH")) {
|
|
1569
|
+
agentEnv.put("ELIZA_LLAMA_N_BATCH", brandedAospBuild ? "512" : "256");
|
|
1570
|
+
}
|
|
1571
|
+
if (!env.containsKey("ELIZA_LLAMA_N_UBATCH")) {
|
|
1572
|
+
agentEnv.put("ELIZA_LLAMA_N_UBATCH", brandedAospBuild ? "512" : "256");
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
// Stage-1 RESPONSE_HANDLER is an internal structured planning
|
|
1576
|
+
// call, not the user's requested chat completion budget. On the
|
|
1577
|
+
// debug APK's in-process phone-CPU path, leaving it at the
|
|
1578
|
+
// core default (1024) lets an unconstrained or malformed local
|
|
1579
|
+
// decode run for minutes before the trajectory can record the
|
|
1580
|
+
// first stage. The AOSP adapter now honors the Stage-1 GBNF
|
|
1581
|
+
// grammar, so 384 tokens is ample for the HANDLE_RESPONSE
|
|
1582
|
+
// envelope while still bounding failure cases tightly. Full
|
|
1583
|
+
// branded AOSP keeps the core default unless explicitly set.
|
|
1584
|
+
if (!brandedAospBuild && !env.containsKey("RESPONSE_HANDLER_MAX_TOKENS")) {
|
|
1585
|
+
agentEnv.put("RESPONSE_HANDLER_MAX_TOKENS", "384");
|
|
1586
|
+
}
|
|
1587
|
+
// Bound every native llama generation on debug APKs, not only
|
|
1588
|
+
// Stage-1. Some downstream TEXT_LARGE calls request 8192
|
|
1589
|
+
// tokens while the debug APK uses n_ctx=4096; without this cap
|
|
1590
|
+
// the adapter must reserve the whole context for output and
|
|
1591
|
+
// drops the prompt to a single token.
|
|
1592
|
+
if (!brandedAospBuild && !env.containsKey("ELIZA_LLAMA_MAX_OUTPUT_TOKENS")) {
|
|
1593
|
+
agentEnv.put("ELIZA_LLAMA_MAX_OUTPUT_TOKENS", "384");
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
if (BuildConfig.AOSP_BUILD && isBrandedDevice()) {
|
|
1597
|
+
agentEnv.put("ELIZA_AOSP_BUILD", "1");
|
|
780
1598
|
agentEnv.put("ELIZA_LOCAL_LLAMA", "1");
|
|
1599
|
+
// Branded AOSP unconditionally opts the bun agent into native
|
|
1600
|
+
// inference. If neither the fused libelizainference.so nor the
|
|
1601
|
+
// legacy libllama.so + shim shipped in this APK, that opt-in
|
|
1602
|
+
// cannot be honored — the bun agent's fused loader will fail at
|
|
1603
|
+
// its first TEXT_* call. Surface the broken pipeline LOUDLY here
|
|
1604
|
+
// (Commandment 8: no silent fallback) rather than letting the
|
|
1605
|
+
// failure first appear minutes later mid-inference.
|
|
1606
|
+
if (!nativeLlamaBundled) {
|
|
1607
|
+
Log.e(TAG, "agent/" + abiDir.getName()
|
|
1608
|
+
+ ": branded AOSP set ELIZA_LOCAL_LLAMA=1 but no native inference lib is bundled "
|
|
1609
|
+
+ "(libelizainference.so absent, libllama.so + shim absent); local inference WILL fail.");
|
|
1610
|
+
}
|
|
781
1611
|
// CPU-only inference of a 12k-token prompt on cuttlefish
|
|
782
1612
|
// x86_64 / Eliza-1 lands well past the 180 s default
|
|
783
1613
|
// chat-generation timeout (chat-routes.ts). On cvd a
|
|
@@ -791,52 +1621,52 @@ public class ElizaAgentService extends Service {
|
|
|
791
1621
|
// (Tensor / Adreno) finishes in seconds, so this only
|
|
792
1622
|
// matters for AOSP cvd runs.
|
|
793
1623
|
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
|
-
}
|
|
1624
|
+
// Device bridge is unused on AOSP (ELIZA_LOCAL_LLAMA=1 routes
|
|
1625
|
+
// inference through the fused libelizainference.so loader
|
|
1626
|
+
// instead). Set the same 1h budget explicitly so the intent is clear and
|
|
1627
|
+
// operator overrides above are not inadvertently in effect.
|
|
1628
|
+
agentEnv.put("ELIZA_DEVICE_GENERATE_TIMEOUT_MS", "3600000");
|
|
1629
|
+
|
|
1630
|
+
// Native llama.cpp ctx/thread/batch defaults are applied above
|
|
1631
|
+
// whenever the fork libs are bundled. Full AOSP only needs
|
|
1632
|
+
// its longer timeout budget here.
|
|
837
1633
|
}
|
|
838
1634
|
agentEnv.put("HOME", getFilesDir().getAbsolutePath());
|
|
839
|
-
|
|
1635
|
+
if (!env.containsKey("TMPDIR")) {
|
|
1636
|
+
agentEnv.put("TMPDIR", getCacheDir().getAbsolutePath());
|
|
1637
|
+
}
|
|
1638
|
+
agentEnv.put("SHELL", "/system/bin/sh");
|
|
1639
|
+
agentEnv.put("CODING_TOOLS_SHELL", "/system/bin/sh");
|
|
1640
|
+
agentEnv.put("SHELL_ALLOWED_DIRECTORY", agentStateDir().getAbsolutePath());
|
|
1641
|
+
agentEnv.put("CODING_TOOLS_WORKSPACE_ROOTS", agentStateDir().getAbsolutePath());
|
|
1642
|
+
String inheritedPath = env.get("PATH");
|
|
1643
|
+
StringBuilder pathBuilder = new StringBuilder();
|
|
1644
|
+
pathBuilder.append(abiDir.getAbsolutePath()).append("/bin");
|
|
1645
|
+
pathBuilder.append(":").append(abiDir.getAbsolutePath());
|
|
1646
|
+
pathBuilder.append(":").append(new File(root, "tools/bin").getAbsolutePath());
|
|
1647
|
+
pathBuilder.append(":").append(new File(root, "bin").getAbsolutePath());
|
|
1648
|
+
pathBuilder.append(":/system/bin:/system/xbin:/vendor/bin:/apex/com.android.runtime/bin");
|
|
1649
|
+
if (inheritedPath != null && !inheritedPath.trim().isEmpty()) {
|
|
1650
|
+
pathBuilder.append(":").append(inheritedPath);
|
|
1651
|
+
}
|
|
1652
|
+
agentEnv.put("PATH", pathBuilder.toString());
|
|
1653
|
+
|
|
1654
|
+
// ── No-terminal env hints for bun's stdio probe ───────────────
|
|
1655
|
+
// Untrusted-app SELinux policy denies `ioctl(TIOCGWINSZ)` on
|
|
1656
|
+
// both app_data_file and the Java-pipe fifo with `permissive=0`.
|
|
1657
|
+
// Bun's stdio init calls `ioctl(stdout, TIOCGWINSZ)` to detect
|
|
1658
|
+
// terminal width; on EACCES it has historically returned mid-
|
|
1659
|
+
// init without writing any diagnostic, leaving agent.log empty
|
|
1660
|
+
// and the watchdog probing a non-existent listener. The env
|
|
1661
|
+
// hints below put bun on its non-terminal path so it does not
|
|
1662
|
+
// bother probing — TERM=dumb gates the terminfo lookups,
|
|
1663
|
+
// NO_COLOR=1 + FORCE_COLOR=0 disable the ANSI emitter, and
|
|
1664
|
+
// CI=1 routes through bun's CI-mode logger (no progress bars,
|
|
1665
|
+
// no spinners, no width detection).
|
|
1666
|
+
agentEnv.put("TERM", "dumb");
|
|
1667
|
+
agentEnv.put("NO_COLOR", "1");
|
|
1668
|
+
agentEnv.put("FORCE_COLOR", "0");
|
|
1669
|
+
agentEnv.put("CI", "1");
|
|
840
1670
|
|
|
841
1671
|
// ── Android seccomp compatibility (SIGSYS / code 159 fix) ──────
|
|
842
1672
|
//
|
|
@@ -935,13 +1765,16 @@ public class ElizaAgentService extends Service {
|
|
|
935
1765
|
// - On AOSP cvd we want a deterministic agent binary, not
|
|
936
1766
|
// one that mutates its prompts mid-smoke.
|
|
937
1767
|
//
|
|
938
|
-
// Hard-disable
|
|
939
|
-
//
|
|
940
|
-
//
|
|
941
|
-
//
|
|
942
|
-
//
|
|
1768
|
+
// Hard-disable the bootstrap so the agent never spins up a
|
|
1769
|
+
// training round on-device. Keep trajectory persistence available
|
|
1770
|
+
// in debug APKs: Android local-llama bringup depends on the
|
|
1771
|
+
// per-turn trace files as the ground-truth failure record. Release
|
|
1772
|
+
// builds keep the historical opt-out unless an operator overrides
|
|
1773
|
+
// the env explicitly.
|
|
943
1774
|
agentEnv.put("ELIZA_DISABLE_AUTO_BOOTSTRAP", "1");
|
|
944
|
-
|
|
1775
|
+
if (!env.containsKey("ELIZA_DISABLE_TRAJECTORY_LOGGING")) {
|
|
1776
|
+
agentEnv.put("ELIZA_DISABLE_TRAJECTORY_LOGGING", BuildConfig.DEBUG ? "0" : "1");
|
|
1777
|
+
}
|
|
945
1778
|
|
|
946
1779
|
// ── Vault passphrase ──────────────────────────────────────
|
|
947
1780
|
// The runtime's vault-bootstrap mirrors process.env secrets
|
|
@@ -988,13 +1821,46 @@ public class ElizaAgentService extends Service {
|
|
|
988
1821
|
|
|
989
1822
|
env.putAll(agentEnv);
|
|
990
1823
|
|
|
991
|
-
//
|
|
992
|
-
//
|
|
993
|
-
//
|
|
994
|
-
//
|
|
995
|
-
//
|
|
996
|
-
//
|
|
1824
|
+
// ── Stdio redirection (TIOCGWINSZ SELinux workaround) ─────────
|
|
1825
|
+
// On Android `untrusted_app`, SELinux denies
|
|
1826
|
+
// `ioctl(fd, TIOCGWINSZ)` (cmd 0x5413) on every non-tty class
|
|
1827
|
+
// accessible to the app with `permissive=0`:
|
|
1828
|
+
// - `pipe:[...]` (Java ProcessBuilder PIPE) → fifo_file ioctl
|
|
1829
|
+
// - `/data/data/<pkg>/files/agent/agent.log` → app_data_file ioctl
|
|
1830
|
+
// The denial returns EACCES; bun's stdio init (or musl's
|
|
1831
|
+
// `__init_libc` terminal-width probe) treats the EACCES as a
|
|
1832
|
+
// hard failure and exits within ~100ms before any line is
|
|
1833
|
+
// flushed, leaving agent.log at 0 bytes and the watchdog
|
|
1834
|
+
// probing nothing. The one fd class that *does* allow ioctl
|
|
1835
|
+
// for untrusted_app is `null_device:chr_file` (rw_file_perms
|
|
1836
|
+
// grants ioctl, no xperm whitelist restriction). Verified
|
|
1837
|
+
// empirically: same ProcessBuilder spawn from `runas_app`
|
|
1838
|
+
// context (more permissive) reaches `/api/health 200`;
|
|
1839
|
+
// identical spawn from `untrusted_app` (service context)
|
|
1840
|
+
// dies silently on the file ioctl.
|
|
1841
|
+
//
|
|
1842
|
+
// Workaround: redirect all three fds to /dev/null so every
|
|
1843
|
+
// TIOCGWINSZ returns ENOTTY (kernel-level, no SELinux check
|
|
1844
|
+
// needed). We sacrifice stdout/stderr capture for liveness;
|
|
1845
|
+
// the agent runtime still writes structured logs to
|
|
1846
|
+
// `<stateDir>/logs/agent.log` via its own pino transport,
|
|
1847
|
+
// and Android's logcat captures every line emitted via
|
|
1848
|
+
// `Log.i(TAG, …)` from the Java side. For local debug
|
|
1849
|
+
// sessions that need raw bun stdio, set `ELIZA_LOG_STDOUT=1`
|
|
1850
|
+
// in the parent service env — that opts into the legacy
|
|
1851
|
+
// file-redirect path (which only works on rooted devices
|
|
1852
|
+
// or via `adb shell run-as`).
|
|
1853
|
+
File devNull = new File("/dev/null");
|
|
1854
|
+
pb.redirectInput(ProcessBuilder.Redirect.from(devNull));
|
|
997
1855
|
pb.redirectErrorStream(true);
|
|
1856
|
+
if ("1".equals(env.get("ELIZA_LOG_STDOUT"))) {
|
|
1857
|
+
File logFile = new File(root, AGENT_LOG_NAME);
|
|
1858
|
+
try { logFile.createNewFile(); } catch (IOException ignored) {}
|
|
1859
|
+
pb.redirectOutput(ProcessBuilder.Redirect.appendTo(logFile));
|
|
1860
|
+
Log.i(TAG, "Agent stdout/stderr capture enabled at " + logFile.getAbsolutePath());
|
|
1861
|
+
} else {
|
|
1862
|
+
pb.redirectOutput(ProcessBuilder.Redirect.to(devNull));
|
|
1863
|
+
}
|
|
998
1864
|
|
|
999
1865
|
Process started;
|
|
1000
1866
|
try {
|
|
@@ -1008,14 +1874,60 @@ public class ElizaAgentService extends Service {
|
|
|
1008
1874
|
}
|
|
1009
1875
|
|
|
1010
1876
|
agentProcess = started;
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
// stderrPump
|
|
1014
|
-
//
|
|
1877
|
+
detachedAgentMode = true;
|
|
1878
|
+
detachedLaunchStartedAtMs = System.currentTimeMillis();
|
|
1879
|
+
// stdoutPump/stderrPump no longer needed — bun writes straight
|
|
1880
|
+
// to agent.log on disk via the OS-level redirect above.
|
|
1881
|
+
stdoutPump = null;
|
|
1015
1882
|
stderrPump = null;
|
|
1016
|
-
currentStatus = "
|
|
1883
|
+
currentStatus = "starting";
|
|
1017
1884
|
updateNotification();
|
|
1018
|
-
|
|
1885
|
+
final long startedAtMs = System.currentTimeMillis();
|
|
1886
|
+
final long launchStartedAtMs = detachedLaunchStartedAtMs;
|
|
1887
|
+
final long pidForLog = safePid(started);
|
|
1888
|
+
Log.i(TAG, "Agent launcher started (pid=" + pidForLog + ").");
|
|
1889
|
+
// Immediate-exit watcher: bun on `untrusted_app` has been
|
|
1890
|
+
// observed dying within ~50ms with no stderr / no tombstone /
|
|
1891
|
+
// no audit hint past the standard musl init probe denials.
|
|
1892
|
+
// The 10-minute watchdog tick is far too slow to surface a
|
|
1893
|
+
// useful exit code. This thread blocks on `process.waitFor()`
|
|
1894
|
+
// and logs the exit value the moment the kernel reaps the
|
|
1895
|
+
// child, then hands off to the existing watchdog restart
|
|
1896
|
+
// path via scheduleRestart().
|
|
1897
|
+
final Process watched = started;
|
|
1898
|
+
Thread exitWatcher = new Thread(() -> {
|
|
1899
|
+
int code;
|
|
1900
|
+
try {
|
|
1901
|
+
code = watched.waitFor();
|
|
1902
|
+
} catch (InterruptedException ex) {
|
|
1903
|
+
Thread.currentThread().interrupt();
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
long aliveMs = System.currentTimeMillis() - startedAtMs;
|
|
1907
|
+
if (detachedAgentMode && code == 0) {
|
|
1908
|
+
Log.i(TAG, "Agent launcher exited after detached start (pid="
|
|
1909
|
+
+ pidForLog + " alive=" + aliveMs + "ms).");
|
|
1910
|
+
} else {
|
|
1911
|
+
Log.w(TAG, "Agent process exited early (pid=" + pidForLog
|
|
1912
|
+
+ " code=" + code + " alive=" + aliveMs + "ms).");
|
|
1913
|
+
}
|
|
1914
|
+
boolean stillThisProcess;
|
|
1915
|
+
synchronized (processLock) {
|
|
1916
|
+
stillThisProcess = (agentProcess == watched);
|
|
1917
|
+
if (stillThisProcess) {
|
|
1918
|
+
agentProcess = null;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
if (stillThisProcess && !shuttingDown && detachedAgentMode && code == 0) {
|
|
1922
|
+
startDetachedStartupProbe(launchStartedAtMs);
|
|
1923
|
+
return;
|
|
1924
|
+
}
|
|
1925
|
+
if (stillThisProcess && !shuttingDown) {
|
|
1926
|
+
scheduleRestart();
|
|
1927
|
+
}
|
|
1928
|
+
}, "ElizaAgent-exit-watcher");
|
|
1929
|
+
exitWatcher.setDaemon(true);
|
|
1930
|
+
exitWatcher.start();
|
|
1019
1931
|
}
|
|
1020
1932
|
}
|
|
1021
1933
|
|
|
@@ -1023,6 +1935,7 @@ public class ElizaAgentService extends Service {
|
|
|
1023
1935
|
Process toStop;
|
|
1024
1936
|
Thread outPump;
|
|
1025
1937
|
Thread errPump;
|
|
1938
|
+
boolean wasDetached;
|
|
1026
1939
|
synchronized (processLock) {
|
|
1027
1940
|
toStop = agentProcess;
|
|
1028
1941
|
outPump = stdoutPump;
|
|
@@ -1030,6 +1943,14 @@ public class ElizaAgentService extends Service {
|
|
|
1030
1943
|
agentProcess = null;
|
|
1031
1944
|
stdoutPump = null;
|
|
1032
1945
|
stderrPump = null;
|
|
1946
|
+
wasDetached = detachedAgentMode;
|
|
1947
|
+
detachedAgentMode = false;
|
|
1948
|
+
detachedLaunchStartedAtMs = 0L;
|
|
1949
|
+
currentLocalAgentToken = null;
|
|
1950
|
+
currentTerminalRunToken = null;
|
|
1951
|
+
}
|
|
1952
|
+
if (wasDetached) {
|
|
1953
|
+
stopDetachedAgentProcess();
|
|
1033
1954
|
}
|
|
1034
1955
|
if (toStop == null) {
|
|
1035
1956
|
return;
|
|
@@ -1053,6 +1974,38 @@ public class ElizaAgentService extends Service {
|
|
|
1053
1974
|
if (errPump != null) errPump.interrupt();
|
|
1054
1975
|
}
|
|
1055
1976
|
|
|
1977
|
+
private void stopDetachedAgentProcess() {
|
|
1978
|
+
String abi = resolveRuntimeAbi();
|
|
1979
|
+
File abiDir = agentAbiDir(abi);
|
|
1980
|
+
File bun = preferPackagedExecutable(new File(abiDir, BUN_BINARY), "libeliza_bun.so");
|
|
1981
|
+
File bundle = new File(agentRoot(), AGENT_BUNDLE_NAME);
|
|
1982
|
+
String killCommand = "pkill -f " + shellQuote(bun.getAbsolutePath())
|
|
1983
|
+
+ " 2>/dev/null || true; pkill -f "
|
|
1984
|
+
+ shellQuote(bundle.getAbsolutePath()) + " 2>/dev/null || true";
|
|
1985
|
+
try {
|
|
1986
|
+
Process killer = new ProcessBuilder("/system/bin/sh", "-c", killCommand)
|
|
1987
|
+
.redirectInput(ProcessBuilder.Redirect.from(new File("/dev/null")))
|
|
1988
|
+
.redirectOutput(ProcessBuilder.Redirect.to(new File("/dev/null")))
|
|
1989
|
+
.redirectError(ProcessBuilder.Redirect.to(new File("/dev/null")))
|
|
1990
|
+
.start();
|
|
1991
|
+
long deadline = System.currentTimeMillis() + PROCESS_TERMINATE_GRACE_MS;
|
|
1992
|
+
while (killer.isAlive() && System.currentTimeMillis() < deadline) {
|
|
1993
|
+
Thread.sleep(100);
|
|
1994
|
+
}
|
|
1995
|
+
if (killer.isAlive()) {
|
|
1996
|
+
killer.destroyForcibly();
|
|
1997
|
+
}
|
|
1998
|
+
} catch (IOException error) {
|
|
1999
|
+
Log.w(TAG, "Failed to stop detached agent process: " + error.getMessage());
|
|
2000
|
+
} catch (InterruptedException error) {
|
|
2001
|
+
Thread.currentThread().interrupt();
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
private static String shellQuote(String value) {
|
|
2006
|
+
return "'" + value.replace("'", "'\\''") + "'";
|
|
2007
|
+
}
|
|
2008
|
+
|
|
1056
2009
|
private static final java.security.SecureRandom TOKEN_RNG = new java.security.SecureRandom();
|
|
1057
2010
|
|
|
1058
2011
|
private static String generateLocalAgentToken() {
|
|
@@ -1160,6 +2113,163 @@ public class ElizaAgentService extends Service {
|
|
|
1160
2113
|
return t;
|
|
1161
2114
|
}
|
|
1162
2115
|
|
|
2116
|
+
private void startDetachedStartupProbe(final long launchStartedAtMs) {
|
|
2117
|
+
Thread probe = new Thread(() -> {
|
|
2118
|
+
long deadline = launchStartedAtMs + STARTUP_HEALTH_GRACE_MS;
|
|
2119
|
+
while (!shuttingDown && System.currentTimeMillis() < deadline) {
|
|
2120
|
+
ProbeResult result = probeHealth();
|
|
2121
|
+
if (result == ProbeResult.OK) {
|
|
2122
|
+
restartAttempts = 0;
|
|
2123
|
+
synchronized (processLock) {
|
|
2124
|
+
if (!detachedAgentMode || detachedLaunchStartedAtMs != launchStartedAtMs) {
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2127
|
+
currentStatus = "running";
|
|
2128
|
+
}
|
|
2129
|
+
updateNotification();
|
|
2130
|
+
Log.i(TAG, "Detached agent health check passed.");
|
|
2131
|
+
return;
|
|
2132
|
+
}
|
|
2133
|
+
try {
|
|
2134
|
+
Thread.sleep(STARTUP_HEALTH_POLL_MS);
|
|
2135
|
+
} catch (InterruptedException error) {
|
|
2136
|
+
Thread.currentThread().interrupt();
|
|
2137
|
+
return;
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
boolean stillCurrent;
|
|
2141
|
+
synchronized (processLock) {
|
|
2142
|
+
stillCurrent = detachedAgentMode && detachedLaunchStartedAtMs == launchStartedAtMs;
|
|
2143
|
+
}
|
|
2144
|
+
if (stillCurrent && !shuttingDown) {
|
|
2145
|
+
Log.w(TAG, "Detached agent did not become healthy within "
|
|
2146
|
+
+ STARTUP_HEALTH_GRACE_MS + "ms. Scheduling restart.");
|
|
2147
|
+
scheduleRestart();
|
|
2148
|
+
}
|
|
2149
|
+
}, "ElizaAgent-detached-startup-probe");
|
|
2150
|
+
probe.setDaemon(true);
|
|
2151
|
+
probe.start();
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2154
|
+
/**
|
|
2155
|
+
* Quick liveness probe for an already-running detached agent: can a TCP
|
|
2156
|
+
* connection be opened to the loopback agent port? Unlike {@link
|
|
2157
|
+
* #probeHealth()} this only completes the socket handshake, so it returns
|
|
2158
|
+
* true even while bun is busy inside a synchronous native call
|
|
2159
|
+
* (mid-llama_decode) and the HTTP layer is unresponsive — precisely the
|
|
2160
|
+
* state we must NOT mistake for a dead agent and relaunch over. Used by
|
|
2161
|
+
* {@link #startAgentProcess()} to adopt a surviving detached agent instead
|
|
2162
|
+
* of killing + restarting it when the service/Activity is recreated.
|
|
2163
|
+
*/
|
|
2164
|
+
private boolean isLoopbackAgentListening() {
|
|
2165
|
+
try (Socket socket = new Socket()) {
|
|
2166
|
+
socket.connect(new InetSocketAddress("127.0.0.1", AGENT_PORT), 2000);
|
|
2167
|
+
return true;
|
|
2168
|
+
} catch (IOException ignored) {
|
|
2169
|
+
return false;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
private ProbeResult probeHealth() {
|
|
2174
|
+
HttpURLConnection conn = null;
|
|
2175
|
+
try {
|
|
2176
|
+
URL url = new URL(HEALTH_URL);
|
|
2177
|
+
conn = (HttpURLConnection) url.openConnection();
|
|
2178
|
+
conn.setConnectTimeout((int) HEALTH_TIMEOUT_MS);
|
|
2179
|
+
conn.setReadTimeout((int) HEALTH_TIMEOUT_MS);
|
|
2180
|
+
conn.setRequestMethod("GET");
|
|
2181
|
+
String token = currentLocalAgentToken;
|
|
2182
|
+
if (token != null && !token.trim().isEmpty()) {
|
|
2183
|
+
conn.setRequestProperty("Authorization", "Bearer " + token.trim());
|
|
2184
|
+
}
|
|
2185
|
+
int status = conn.getResponseCode();
|
|
2186
|
+
if (status >= 200 && status < 300) {
|
|
2187
|
+
String body = readResponseBody(conn);
|
|
2188
|
+
if (!isReadyHealthBody(body)) {
|
|
2189
|
+
Log.w(TAG, "Agent health endpoint responded before ready: " + compactForLog(body));
|
|
2190
|
+
return ProbeResult.DEAD;
|
|
2191
|
+
}
|
|
2192
|
+
return ProbeResult.OK;
|
|
2193
|
+
}
|
|
2194
|
+
// Non-2xx: agent process is up but not healthy/authenticated.
|
|
2195
|
+
// Treat as DEAD so strikes accumulate — this is a crash or
|
|
2196
|
+
// readiness signal, not a busy signal.
|
|
2197
|
+
return ProbeResult.DEAD;
|
|
2198
|
+
} catch (IOException error) {
|
|
2199
|
+
// HTTP request failed (timeout / connect refused / read
|
|
2200
|
+
// interrupt). If the direct child process is still alive the
|
|
2201
|
+
// most likely cause is bun synchronously inside a native FFI
|
|
2202
|
+
// call. Detached mode has no live Java child to inspect, so a
|
|
2203
|
+
// closed port is treated as DEAD and the startup probe/watchdog
|
|
2204
|
+
// owns retry timing.
|
|
2205
|
+
Process current;
|
|
2206
|
+
synchronized (processLock) {
|
|
2207
|
+
current = agentProcess;
|
|
2208
|
+
}
|
|
2209
|
+
if (current != null && current.isAlive()) {
|
|
2210
|
+
return ProbeResult.BUSY;
|
|
2211
|
+
}
|
|
2212
|
+
return ProbeResult.DEAD;
|
|
2213
|
+
} finally {
|
|
2214
|
+
if (conn != null) conn.disconnect();
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
private static String readResponseBody(HttpURLConnection conn) throws IOException {
|
|
2219
|
+
try (InputStream in = conn.getInputStream()) {
|
|
2220
|
+
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
2221
|
+
byte[] buf = new byte[4096];
|
|
2222
|
+
int n;
|
|
2223
|
+
while ((n = in.read(buf)) >= 0) {
|
|
2224
|
+
out.write(buf, 0, n);
|
|
2225
|
+
}
|
|
2226
|
+
return out.toString(StandardCharsets.UTF_8.name());
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
private static String readResponseBody(InputStream in, int maxBytes) throws IOException {
|
|
2231
|
+
return new String(readResponseBytes(in, maxBytes), StandardCharsets.UTF_8);
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
private static byte[] readResponseBytes(InputStream in, int maxBytes) throws IOException {
|
|
2235
|
+
if (in == null) return new byte[0];
|
|
2236
|
+
try (InputStream input = in) {
|
|
2237
|
+
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
2238
|
+
byte[] buf = new byte[8192];
|
|
2239
|
+
int total = 0;
|
|
2240
|
+
int n;
|
|
2241
|
+
while ((n = input.read(buf)) >= 0) {
|
|
2242
|
+
total += n;
|
|
2243
|
+
if (total > maxBytes) {
|
|
2244
|
+
throw new IOException("Response body is too large");
|
|
2245
|
+
}
|
|
2246
|
+
out.write(buf, 0, n);
|
|
2247
|
+
}
|
|
2248
|
+
return out.toByteArray();
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
private static boolean isReadyHealthBody(String body) {
|
|
2253
|
+
if (body == null || body.trim().isEmpty()) return false;
|
|
2254
|
+
try {
|
|
2255
|
+
JSONObject json = new JSONObject(body);
|
|
2256
|
+
if (!json.optBoolean("ready", false)) return false;
|
|
2257
|
+
String runtime = json.optString("runtime", "");
|
|
2258
|
+
if (!runtime.isEmpty() && !"ok".equals(runtime)) return false;
|
|
2259
|
+
String agentState = json.optString("agentState", "");
|
|
2260
|
+
return agentState.isEmpty() || "running".equals(agentState);
|
|
2261
|
+
} catch (JSONException error) {
|
|
2262
|
+
return false;
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
private static String compactForLog(String value) {
|
|
2267
|
+
if (value == null) return "";
|
|
2268
|
+
String compact = value.replaceAll("\\s+", " ").trim();
|
|
2269
|
+
if (compact.length() <= 240) return compact;
|
|
2270
|
+
return compact.substring(0, 240) + "…";
|
|
2271
|
+
}
|
|
2272
|
+
|
|
1163
2273
|
private void scheduleRestart() {
|
|
1164
2274
|
if (shuttingDown) return;
|
|
1165
2275
|
if (restartAttempts >= MAX_RESTART_ATTEMPTS) {
|
|
@@ -1216,7 +2326,28 @@ public class ElizaAgentService extends Service {
|
|
|
1216
2326
|
current = agentProcess;
|
|
1217
2327
|
}
|
|
1218
2328
|
if (current == null) {
|
|
1219
|
-
|
|
2329
|
+
if (detachedAgentMode) {
|
|
2330
|
+
ProbeResult probe = probeHealth();
|
|
2331
|
+
if (probe == ProbeResult.OK) {
|
|
2332
|
+
if (unhealthyTicks > 0) {
|
|
2333
|
+
Log.i(TAG, "Detached agent health restored.");
|
|
2334
|
+
}
|
|
2335
|
+
unhealthyTicks = 0;
|
|
2336
|
+
restartAttempts = 0;
|
|
2337
|
+
if (!"running".equals(currentStatus)) {
|
|
2338
|
+
currentStatus = "running";
|
|
2339
|
+
updateNotification();
|
|
2340
|
+
}
|
|
2341
|
+
} else if (probe == ProbeResult.DEAD) {
|
|
2342
|
+
unhealthyTicks++;
|
|
2343
|
+
Log.w(TAG, "Detached agent health probe failed ("
|
|
2344
|
+
+ unhealthyTicks + " consecutive).");
|
|
2345
|
+
if (unhealthyTicks >= HEALTH_FAIL_STRIKES) {
|
|
2346
|
+
unhealthyTicks = 0;
|
|
2347
|
+
scheduleRestart();
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
1220
2351
|
continue;
|
|
1221
2352
|
}
|
|
1222
2353
|
if (!current.isAlive()) {
|
|
@@ -1261,7 +2392,7 @@ public class ElizaAgentService extends Service {
|
|
|
1261
2392
|
Log.i(TAG, "Agent HTTP probe timed out but process is alive — likely mid-decode. No strike.");
|
|
1262
2393
|
} else {
|
|
1263
2394
|
// ProbeResult.DEAD: process is dead, OR /api/health
|
|
1264
|
-
//
|
|
2395
|
+
// did not return 2xx with ready=true. Only here do we
|
|
1265
2396
|
// accumulate strikes toward a force-restart.
|
|
1266
2397
|
unhealthyTicks++;
|
|
1267
2398
|
Log.w(TAG, "Agent health probe failed (" + unhealthyTicks + " consecutive).");
|
|
@@ -1275,44 +2406,6 @@ public class ElizaAgentService extends Service {
|
|
|
1275
2406
|
}
|
|
1276
2407
|
}
|
|
1277
2408
|
|
|
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
2409
|
}
|
|
1317
2410
|
|
|
1318
2411
|
/**
|
|
@@ -1323,8 +2416,9 @@ public class ElizaAgentService extends Service {
|
|
|
1323
2416
|
* HEALTH_TIMEOUT_MS. Typically means bun is synchronously
|
|
1324
2417
|
* inside a native FFI call (llama_decode on a long prompt).
|
|
1325
2418
|
* No strike.
|
|
1326
|
-
* DEAD → process is dead, OR the HTTP server
|
|
1327
|
-
* hard connection failure (port
|
|
2419
|
+
* DEAD → process is dead, OR the HTTP server did not return 2xx
|
|
2420
|
+
* with ready=true, OR a hard connection failure (port
|
|
2421
|
+
* closed). Count a strike.
|
|
1328
2422
|
*/
|
|
1329
2423
|
private enum ProbeResult {
|
|
1330
2424
|
OK,
|
|
@@ -1430,7 +2524,7 @@ public class ElizaAgentService extends Service {
|
|
|
1430
2524
|
/**
|
|
1431
2525
|
* Storage key for the persisted mobile runtime mode. Must match
|
|
1432
2526
|
* MOBILE_RUNTIME_MODE_STORAGE_KEY in
|
|
1433
|
-
* eliza/packages/app-core/src/
|
|
2527
|
+
* eliza/packages/app-core/src/first-run/mobile-runtime-mode.ts.
|
|
1434
2528
|
*/
|
|
1435
2529
|
private static final String RUNTIME_MODE_KEY = "eliza:mobile-runtime-mode";
|
|
1436
2530
|
|
|
@@ -1448,17 +2542,37 @@ public class ElizaAgentService extends Service {
|
|
|
1448
2542
|
if (isBrandedDevice()) {
|
|
1449
2543
|
return true;
|
|
1450
2544
|
}
|
|
2545
|
+
// This APK is the on-device local-agent sideload build (the cloud
|
|
2546
|
+
// thin-client is a separate build). Autostart the agent unless the
|
|
2547
|
+
// user has explicitly chosen a cloud runtime mode. A fresh install
|
|
2548
|
+
// has no persisted mode yet (the renderer writes it only after the
|
|
2549
|
+
// WebView boots), so default to autostart instead of stranding the
|
|
2550
|
+
// dashboard with no agent to connect to.
|
|
1451
2551
|
String mode = readRuntimeMode(context);
|
|
1452
|
-
return "
|
|
2552
|
+
return !"cloud".equals(mode);
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
/**
|
|
2556
|
+
* True once the user (or the device image) has actually committed to
|
|
2557
|
+
* running the on-device agent — a branded device, or a stock phone whose
|
|
2558
|
+
* runtime mode has been explicitly persisted by the onboarding picker.
|
|
2559
|
+
*
|
|
2560
|
+
* Distinct from {@link #shouldAutoStart}: a fresh stock install has no
|
|
2561
|
+
* persisted mode yet, so the agent still auto-starts (so the dashboard has
|
|
2562
|
+
* something to talk to) but the user has chosen nothing. We use this to
|
|
2563
|
+
* avoid cold-asking for notification consent during first-run onboarding —
|
|
2564
|
+
* iOS-style, we ask only after there is a committed reason (the foreground
|
|
2565
|
+
* service still runs without the grant; its notification is just
|
|
2566
|
+
* suppressed until later granted).
|
|
2567
|
+
*/
|
|
2568
|
+
public static boolean hasCommittedRuntimeChoice(Context context) {
|
|
2569
|
+
return isBrandedDevice() || readRuntimeMode(context) != null;
|
|
1453
2570
|
}
|
|
1454
2571
|
|
|
1455
2572
|
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();
|
|
2573
|
+
// AOSP / ElizaOS images set ro.elizaos.product. White-label forks
|
|
2574
|
+
// that use a different sysprop should override shouldAutoStart locally.
|
|
2575
|
+
return !readSystemProperty("ro.elizaos.product").isEmpty();
|
|
1462
2576
|
}
|
|
1463
2577
|
|
|
1464
2578
|
private static String readRuntimeMode(Context context) {
|