Skip to content

Repository files navigation

Pomi for Rabbit R1

Pomi turns a rooted Rabbit R1 into a small, persistent voice-agent appliance. It provides a custom touch and wake-word interface and runs the Hermes gateway directly on the R1. The device uses Wi-Fi or cellular data to reach a remote LLM. Tailscale provides optional private dashboard access and remote maintenance, so a Mac is not part of the normal request path.

Early release: Installation modifies the Android system partition and can make the device unbootable. Read the recovery section and make a verified backup before installation.

Demo

Watch Pomi answer a weather question on a Rabbit R1

Watch the 30-second demonstration on YouTube.

Pomi is an independent software experiment inspired by the R1's distinctive hardware and agent-oriented form factor. It was not created out of frustration with Rabbit's software. The project explores a different question: how much of a custom, persistent voice-agent experience can run directly on the device?

Current experience

  • Tap the tomato to begin speaking.
  • See live transcription in a foreground conversation overlay.
  • Send automatically after a short pause.
  • Read and hear the agent's response in the same overlay.
  • Start a new conversation or clear the current one.
  • Use an ambient lock display when the device is idle.
  • Enable local “Hey Pomi” wake-word detection.

How it works

When you speak, the Pomi Android app captures and transcribes the request. It sends the text to the Hermes gateway running on the same R1 at 127.0.0.1:8642. Hermes contacts the configured remote LLM over the device's ordinary internet connection and returns the response to the interface.

Tailscale is not in the conversation path. It provides private access to the dashboard, diagnostics, and over-the-air application updates while the R1 is online.

What runs where

Component Location Purpose
Pomi Home APK Android Home, lock/ambient display, voice capture, chat
Hermes gateway Debian chroot on the R1 Agent sessions and tools
Porcupine Inside the APK Local “Hey Pomi” detection
Tailscale Debian chroot on the R1 Optional private remote access
LLM User-selected remote provider Inference

The APK talks to Hermes over http://127.0.0.1:8642. Credentials remain in private files on the R1. They are not compiled into the APK.

Supported device

The current release is deliberately narrow:

  • Rabbit R1 (arm64-v8a)
  • Android 13 / API 33
  • fingerprint matching rabbit/gsi_r1/r1:13/*
  • unlocked bootloader
  • root ADB (adb shell id reports uid=0)
  • USB debugging enabled
  • at least 2 GB free under /data

Pomi does not include Rabbit firmware, boot images, unlock tools, or bypasses. Start from a legally obtained Android 13 image for your own R1. The community r1_escape project describes the device-specific boot process. Its code and instructions are independent from Pomi. Confirm that ./scripts/verify-device.sh passes before continuing.

Host prerequisites

  • macOS or Linux
  • Android platform/build tools (adb, fastboot, and apksigner)
  • JDK 21
  • Docker with ARM64 build support
  • e2fsprogs (debugfs, e2fsck, and resize2fs)
  • curl, git, gzip, openssl, tar, and shasum
  • a private release keystore
  • your own LLM API key
  • your own Tailscale auth key
  • a Picovoice AccessKey and Android .ppn keyword file

The four release modules

Pomi separates the public installation path into four auditable modules:

  1. capture-system-image.sh privately captures the active, already-bootable compatible system partition; bootstrap-device.sh verifies and backs up the device before it patches and flashes that user-owned image.
  2. build-runtime.sh creates the pinned ARM64 Hermes/Tailscale runtime and its checksum manifest.
  3. configure.sh prompts without echoing secrets; provision-device.sh installs the resulting private configuration under /data.
  4. build-release.sh builds, verifies, and checksums an APK signed with the owner's private release key.

Deterministic runtime build

Clone the repository and build the pinned ARM64 runtime:

git clone https://github.com/sidmohan0/pomi.git
cd pomi
./scripts/build-runtime.sh

Runtime inputs are fixed in device-runtime/versions.env. The build checks the downloaded Tailscale archive and writes checksums for all runtime outputs.

Create a release keystore once and keep two secure backups:

./scripts/create-release-keystore.sh /private/path/pomi-release.jks

Export the four signing values without storing them in this repository:

export POMI_RELEASE_STORE_FILE=/private/path/pomi-release.jks
export POMI_RELEASE_STORE_PASSWORD='...'
export POMI_RELEASE_KEY_ALIAS=pomi
export POMI_RELEASE_KEY_PASSWORD='...'
./scripts/build-release.sh

The signed APK and SHA256SUMS are written under release/.

Secure interactive configuration

Create a private configuration file. Secret prompts are not echoed, the gateway key is generated locally, and the resulting file has mode 0600:

./scripts/configure.sh /private/path/pomi.env

The file is shell-readable so it can drive unattended recovery later. Keep it outside this checkout and never attach it to a bug report or release.

Clean-device bootstrap

Connect one R1 over USB. Do not rely on wireless ADB for recovery.

adb devices -l
./scripts/verify-device.sh
./scripts/backup-device.sh

The backup is created as an ignored, permission-restricted device-backup-TIMESTAMP/ directory. Copy it to separate storage. The script captures Pomi/Hermes state, package inventory, the installed APK, and both-slot boot, vbmeta, and dtbo partitions, then verifies every checksum.

This is not a complete userdata or proprietary firmware backup. Keep the private system capture and the original firmware/recovery package that you used to prepare the device.

Patch and flash the compatible system image

Pomi does not publish firmware. Start the R1 on the supported rooted Android build and privately capture its active system partition:

./scripts/capture-system-image.sh /private/path/compatible-system.img

Do not use a generic GSI or an image from another R1. The captured image stays on your host and must not be committed or redistributed.

After exporting the four signing variables shown above, the one-command bootstrap verifies the device and source artifacts, creates and validates a backup, builds the runtime and signed APK, patches and checksums the image, flashes it, provisions private state, and runs the health check:

./scripts/bootstrap-device.sh \
  /private/path/to/compatible-system.img \
  /private/path/pomi.env

To run the same modules separately, patch and flash as follows:

./scripts/patch-system-image.sh \
  /private/path/to/compatible-system.img \
  dist/pomi-system.img
./scripts/flash-system-image.sh dist/pomi-system.img

The patch contains the signed APK, pinned runtime, Tailscale binaries, and init service. It contains no credentials. Flashing overwrites the system partition. Never use an image from a different device or Android build.

Provision

If you did not use configure.sh, copy the example outside the repository and fill in your own values:

cp scripts/pomi.env.example /private/path/pomi.env
chmod 600 /private/path/pomi.env
./scripts/provision-device.sh /private/path/pomi.env
./scripts/health-check.sh

Provisioning:

  1. rejects unsupported, non-rooted, or unpatched devices;
  2. writes LLM and Tailscale credentials under /data with mode 0600;
  3. places the Picovoice key/model in private app storage;
  4. reboots once to start the runtime; and
  5. leaves credentials out of command output, Git, and the system image.

Expected final output:

PASS: runtime ready, gateway reachable, and Pomi APK installed.

Select Pomi as the Android Home app if Android prompts.

Maintainers can exercise a destructive clean-checkout reinstall on a backed-up test device:

./scripts/clean-install-test.sh \
  /private/path/pomi.env \
  dist/pomi-system.img

This test creates and verifies another backup before it removes Pomi state.

Update

Use the same signing keystore for every APK update. Rebuild the pinned runtime and rerun provisioning. The runtime is replaced atomically on the next boot; Hermes state and the workspace remain under /data.

./scripts/build-runtime.sh
./scripts/build-release.sh
./scripts/patch-system-image.sh /private/path/to/compatible-system.img dist/pomi-system.img
./scripts/flash-system-image.sh dist/pomi-system.img
./scripts/provision-device.sh /private/path/pomi.env
./scripts/health-check.sh

Diagnostics

adb shell getprop hermes.runtime.ready
adb shell tail -100 /data/hermes-runtime.log
adb shell tail -100 /data/hermes-gateway.log
adb shell tail -100 /data/tailscale.log
adb shell dumpsys package ai.hermes.rabbit | grep version

If the gateway is healthy, this command exits with status zero:

adb shell 'chroot /data/hermes-rootfs curl -fsS http://127.0.0.1:8642/v1/models >/dev/null'

Rollback and recovery

If Android still boots with root ADB:

adb root
adb remount
adb shell stop hermes-device
adb shell stop tailscale-device
adb shell rm /system/etc/init/hermes-device.rc
adb shell rm -r /system/hermes
adb uninstall ai.hermes.rabbit
adb reboot

If Android does not boot, use the bootloader/recovery procedure for the Android image you installed. Restore the matching backed-up boot, vbmeta, and dtbo images only to the same device and slot layout. Those files do not replace a complete firmware recovery package.

Security and privacy

  • Do not publish pomi.env, a keystore, backups, .ppn files, or runtime state.
  • Use short-lived or reusable-limited Tailscale auth keys.
  • Restrict LLM keys to the minimum required account/project.
  • The gateway listens on loopback. Tailscale exposure is opt-in and private.
  • Rotate a credential if it is ever committed or included in a release bundle.

Repository map

  • hermes-shell/ — Android Home application
  • device-runtime/ — pinned runtime recipe and Android init services
  • scripts/ — backup, build, provisioning, health, and release tools
  • ui-lab/ — browser-based visual prototype
  • docs/ — architecture, compatibility, licensing, and maintenance notes

Known limitations

  • Only the Android 13 R1 build above is currently tested.
  • Voice transcription uses Android speech services and can depend on network and installed system components.
  • Picovoice requires each user to accept its terms and provide their own key and model.
  • There is no automatic firmware unlock or recovery flow.
  • Runtime rebuilds require Docker and network access.

License

Original Pomi code is licensed under Apache-2.0. Third-party components keep their own licenses and are listed in THIRD_PARTY_NOTICES.md.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages