rho: a persistent AI operator built on the pi coding agent
An AI agent that stays running, remembers across sessions, and checks in on its own. macOS, Linux, Android. Built on Pi.
At a glance
- What is it?
- rho runs in the background, keeps an append-only memory file, and checks in on a schedule. It is aimed at people who want a stateful operator on their own machine rather than another chat tab, and the trade-off is that you own the daemon, the memory file and the provider setup.
- Who is it for?
- Adopt rho if you already run pi and want a background operator whose learned state you can open, search and edit in ~/.rho/brain/brain.jsonl. Do not adopt it if you need a hosted service with no local daemon, or if you expect the Android wrapper to hold a stream while the phone is locked without accepting the foreground notification and battery cost of Live Mode.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 112 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem rho targets: chat sessions that forget everything
The README frames the contrast plainly: most AI tools are stateless chat tabs, and rho is built for ongoing operation. That is the whole design premise. A chat tab has no memory between sessions, no reason to act when nobody is typing, and no place to store what it learned about you. rho answers each of those with a component: a heartbeat for scheduled check-ins, a brain for durable memory, and a vault for markdown knowledge. The stated audience is someone who wants a daily operator loop, a memory-backed coding copilot, or an inbox and Telegram agent, running on macOS, Linux or Android, with iPhone and iPad reached over SSH. The important word in that list is personal. The README states that memory and config stay on your machine and that no hosted rho memory backend is required, so the intended user is someone willing to run a daemon on hardware they control.
Heartbeat, brain and vault: the three pieces that make it stateful
The runtime is described as three core modules. Heartbeat handles scheduled autonomous check-ins, and the README gives 30 minutes as the default interval, with /rho now available to trigger an immediate check-in from inside a session. Brain is append-only structured memory stored as brain.jsonl, and the README calls memory observability a distinguishing feature: you can inspect, search and edit what the agent has learned. Vault is a separate markdown knowledge graph under ~/.rho/vault/. Keeping those two stores apart matters. Append-only JSONL suits facts the agent accumulates and you want to audit in order; markdown suits notes you want to read and restructure by hand. The web UI exposes the brain through /brain and the vault through /vault inbox, so both are reachable without opening files. What the material does not describe is a compaction, retention or conflict-resolution policy for brain.jsonl. An append-only file grows, and the README does not say what happens when it does.
Getting it running: the four commands and the first checks
The quick start requires Node.js 18 or later, tmux and git, then four commands: npm install -g @rhobot-dev/rho, followed by rho init && rho sync, then rho login && rho start, and finally rho. According to the README that sequence produces initialized config in ~/.rho/, authenticated provider access via pi, a background heartbeat daemon, and an attached interactive session. The first checks it suggests are rho status for daemon and module health, /rho status for heartbeat state inside a session, /rho now to force a check-in, /brain for the memory viewer, and /vault inbox for captured knowledge. The web workspace starts with rho web, with rho web --port 4000 to change the port and rho web --open to launch a browser; the default is http://localhost:3141. There are three alternative install paths: pi install npm:@rhobot-dev/rho, a git clone into ~/.rho/project followed by ./install.sh (the installer checks missing dependencies and supports NixOS), and a curl install script for Android under Termux. Config lives in ~/.rho/init.toml and package state in ~/.rho/packages.toml, and the web UI can edit the former.
The web UI is deliberately unbundled, and that shapes its limits
rho ships a browser workspace rather than treating the terminal as the only surface. The README describes a no-build split: server logic in web/*.ts and browser runtime in web/public/js/*.js, with no frontend bundler or transpile pipeline. The server is Hono-based with response compression enabled. Chat responses stream over live RPC or WebSocket. The client is told about changes by a sessions_changed event rather than polling, polling pauses when the tab is hidden or the user is idle, markdown updates during streaming are debounced at 150ms, and session metadata is cached by file mtime so files are not re-read unnecessarily. Those are concrete choices with a cost attached. A no-build frontend means no JSX, no TypeScript in the browser, and no tree-shaking, so anything you add to web/public/js is served as written. For a personal operator workspace that is a reasonable trade. It is a poor fit if you want a component framework or a shared build pipeline across surfaces.
Android Live Mode is the clearest trade-off in the project
The native Android wrapper in mobile/rho-android has two explicit background modes. Idle Mode is the default and is described as best for battery: no always-on background socket while the app is backgrounded, with reconnect and replay when the app becomes active again. Live Mode starts an Android foreground service with a persistent notification and lease heartbeats so active streams survive while the phone is locked. The README is direct about when this matters: without Live Mode, WebView background limits can cause disconnect or orphan behavior around the default orphan window. It is equally direct about the cost: higher battery and network usage while Live Mode is active, a persistent foreground notification, and a lifecycle you control explicitly through GO LIVE and STOP LIVE. The README also notes that baseline Live Mode reliability does not require Firebase credentials. If you want an always-on agent on a phone, this is the section to read twice, because the default mode is not always-on.
Channels, provider choice and the security model you inherit
rho reaches you through several surfaces: a CLI, session slash commands (/rho, /brain, /vault, /skill, /telegram, /email), a web UI, Telegram and email. Email gives the agent an address at name@rhobot.dev, where it polls, reads and replies. Telegram is a polling adapter with an allowlist and a moderation flow. The README lists Telegram allowlists and mention gating, plus email sender controls and outbound policy limits, as the controls on those channels. Provider access comes from rho login via pi, so the model and provider are yours to configure. That is the security model in one sentence: local memory at ~/.rho/brain/brain.jsonl, local config at ~/.rho/init.toml and ~/.rho/packages.toml, your own providers, and channel-level allowlists. What the material does not cover is what an allowlisted Telegram message or an inbound email can cause the agent to do once it is accepted. The allowlist decides who gets in, not what happens next.
Where rho is the wrong tool, and what to compare it against
rho is the wrong choice if you want a hosted assistant with no local process to keep alive. It depends on tmux and a daemon, and its state is files on your disk. If you cannot run a long-lived process on the machine, the heartbeat has nothing to run inside. The README also names two adjacent projects in its own positioning table. OpenClaw is described as having a strong Gateway Control UI and WebChat control plane; nanobot's README is said to emphasize CLI and channel gateway flows. The difference rho claims is a built-in operator workspace with stronger memory observability and a no-build stack covering chat, memory inspection and editing, tasks, config and review. Read that as a statement about where each project puts its weight, not as a benchmark. The practical question is whether you want memory you can open and edit as a file, which is rho's position, or a control plane oriented around gateways, which is closer to how the README describes OpenClaw.
Maintenance, licence and what the release history shows
rho is MIT licensed, which permits commercial and private use and modification, subject to the licence text; this is a description of the licence identifier, not legal advice. Releases v0.1.10, v0.1.11 and v0.1.12 all landed within roughly a day of each other in March 2026, and the repository's last push is dated 2026-05-26. Those version numbers, all 0.1.x, tell you the project treats itself as pre-1.0, and the README does not publish a stability or deprecation policy for the CLI, the slash commands or the init.toml keys. Upgrading means watching for changes to those surfaces yourself. The Android path carries its own maintenance cost: the README notes that if Termux cannot build the optional node-pty native module, rho still installs and runs, but the embedded web terminal drawer stays disabled until node-pty works on that device. That is a feature you lose silently on some hardware unless you check for it.
Editorial conclusion
Adopt rho if you already run pi and want a background operator whose learned state you can open, search and edit in ~/.rho/brain/brain.jsonl. Do not adopt it if you need a hosted service with no local daemon, or if you expect the Android wrapper to hold a stream while the phone is locked without accepting the foreground notification and battery cost of Live Mode. Before committing, run rho status, confirm the heartbeat interval you want in ~/.rho/init.toml, and check whether node-pty builds on your target machine, because without it the embedded web terminal is unavailable.
Community notes