Agent and CLI for operating the Reachy Mini expressive robot — device setup, app management, and runtime ops.
Project description
reachy-mini-cli
Agent and CLI for operating the Reachy Mini expressive robot — device setup, app management, and live runtime ops.
# Real mode (local robot: daemon binary + SDK):
uv tool install 'reachy-mini-cli[daemon]'
reachy-mini-cli quickstart # copy-paste install + bring-up sequence
reachy-mini-cli daemon start # bring the daemon up (wakes the robot)
reachy-mini-cli listen run # orient the head toward sound (Ctrl-C to stop)
The installed command is reachy-mini-cli (short alias: reachy).
New here? Read the Operating Reachy Mini guide —
it covers bring-up, verification, and the one model you must understand before
running two behaviors at once.
What Reachy Mini can do
Reachy Mini is an expressive desk robot — a movable head, two antennas, a
rotating body, a USB mic array (with direction-of-arrival), a camera, and a
speaker. reachy-mini-cli exposes each capability as a noun you run from a
shell or an agent loop: hold the hardware (daemon), feel alive when idle
(demo-mode), orient to sound (listen) or sight (vision), speak in a TTS
or offline harmonic voice (say), think out loud and move in step with its
thoughts (think), feel a head pat (pat), and fall asleep when left alone
(sleep). listen run --live folds every live sense into one loop, and
service makes one presence mode survive a reboot.
Noun map
The complete robot surface. Every noun supports --json; run
reachy-mini-cli explain <noun> for the full flag reference.
| Noun | What it does | Transport |
|---|---|---|
daemon |
Start/stop/status the local reachy-mini-daemon process |
none (manages the process) |
device |
Daemon + live robot state (status, state) |
http (default) |
app |
List / start / stop daemon apps | http |
move |
One-shot goto / wake / sleep animations |
http (default) |
demo-mode |
Always-on "feel alive" idle loop (breathe, glances, sway) | sdk/http |
behavior |
50 Hz engine that composes named behaviors per channel | sdk/http |
listen |
Two-tier sound orienting (antenna lean → head/body turn); --live folds every sense into one loop |
sdk default |
vision |
Turn toward motion or light (pure pixel math, no ML) | sdk default |
say |
Dumb pipe: text → voice (TTS or offline harmonic) → speaker | sdk default |
think |
LLM cognition loop: speaks (TTS or harmonic) + expresses; --export JSONL feed |
sdk default |
pat |
Feel a head pat and lean into it (no touch sensor) | sdk only |
sleep |
Decay to sleep when idle; wake on sound / wake-word / pat | sdk default |
service |
Boot-persist exactly one presence mode (demo or live) via systemd --user |
none (manages systemd) |
whoami quickstart learn explain overview doctor cli |
Agent-first introspection — no robot needed | — |
⚠️ Before you run two behaviors at once, read the single-SDK-owner model. The robot serves one in-process SDK client and one motion queue, each a single resource:
listen,think,sleep,vision, andpatare mutually exclusive on thesdktransport. This trips up humans and agents repeatedly. The conflict matrix and the two ways to compose behaviors anyway are in the guide.
Install
| Profile | Install | For |
|---|---|---|
| Real mode (recommended) | uv tool install 'reachy-mini-cli[daemon]' |
A local robot — pulls reachy-mini, so the sdk transport and daemon start work out of the box. |
| HTTP remote | pip install reachy-mini-cli |
No local robot — numpy-only; talk to a daemon elsewhere with --transport http + REACHY_BASE_URL. |
reachy-mini is an extra, not a base dep (its pycairo/gstreamer/pyaudio
stack needs system libraries a bare box lacks). Running the sdk transport on a
bare install exits 2 with a hint to install [sdk] — never a traceback. See
Install profiles for the full
rationale. reachy-cli remains a transitional alias that pulls in
reachy-mini-cli.
Operating Reachy live
The full operating guide is docs/operating-reachy.md:
- Bring Reachy up live — install → daemon → verify → behavior
- The single-SDK-owner model — the conflict matrix + how to compose behaviors
- Transports —
sdkvshttp - Boot persistence — make one presence (
demo/live) survive a reboot viaservice - The symbolic runtime — a deterministic, zero-LLM-token presence (
behavior+rules.toml) an AI agent can attach to (reachy-mini-cli agent attach) instead of replace - Verify it's working
- The
~/.asoundrcmic-array gotcha — the most common silent failure - Environment variables — every
REACHY_*var in one table - Troubleshooting — symptoms → fixes, exit codes
- Noun reference — each noun's sense, motion, and transport
Common commands
reachy-mini-cli daemon start # bring the daemon up (wakes the robot)
reachy-mini-cli device status # verify it answers
reachy-mini-cli move goto --z 10 --pitch -5 --duration 2 # one motion command
reachy-mini-cli demo-mode start # feel-alive idle loop (background)
reachy-mini-cli listen run # orient to sound (sdk; Ctrl-C to stop)
reachy-mini-cli vision run # orient to motion/light (sdk)
reachy-mini-cli say run "Hello from Reachy" # text-to-speech
reachy-mini-cli think run # LLM cognition loop (speaks + moves)
reachy-mini-cli pat run # feel a head pat and lean in
reachy-mini-cli sleep run # fall asleep when idle, wake when addressed
reachy-mini-cli listen run --live # ALL senses in one loop (the "live presence" mode)
reachy-mini-cli daemon stop # put it back down
The background nouns (demo-mode, listen, think, sleep) also expose
start / stop / restart / status; the sense nouns also expose demo (no
robot needed). See reachy-mini-cli explain <noun>.
The live loop and boot persistence
listen run --live folds think + vision + sleep into listen's single loop
(alongside the head-pat hook), so every live sense rides one SDK media
session and one motion queue in one process — arbitrated by the
sleep > pat > think priority flags. It is the supported way to run all the
senses at once (one media owner; see the single-SDK-owner model below).
Add --transcribe and live cognition hears words: nearby speech is
transcribed via the external STT service (model-gear / Parakeet at
REACHY_STT_URL, default localhost:9002) and the recognised words flow into
the think loop, so the robot reasons about what was said — not just that a
sound came from the left. Off by default (the live loop is unchanged when off);
--transcribe requires --live and the sdk transport. A self-mute window
means the robot never transcribes its own voice, and an unreachable STT degrades
to "no words" rather than stalling the loop. It is not a chat/turn-taking
assistant — words are one more perception. The deployed live boot service runs
with --transcribe on, so the on-robot presence hears words out of the box.
reachy-mini-cli listen run --live --transcribe # hear words + react to them
Add --voice-engine harmonic (or REACHY_VOICE_ENGINE=harmonic) and every
spoken sentence is voiced as an offline note-melody instead of TTS — fully
in-process, deterministic, no external service to reach. say run, think run/demo, and listen run --live all accept --voice-engine {tts,harmonic} (default tts); tune the voice with
REACHY_HARMONIC_IDENTITY / REACHY_HARMONIC_ARTICULATION. See
The harmonic voice for the full
picture.
reachy-mini-cli say run "Hello" --voice-engine harmonic # offline note-melody voice
service makes one presence boot-persistent via systemd --user; enable live now boots the harmonic-voiced loop by default (--voice-engine harmonic). Exactly one mode is enabled at a time — enabling one disables the
sibling — and it auto-restarts on crash. The daemon is a boot dependency of
both presence units.
reachy-mini-cli service install # write the systemd units (enable nothing)
reachy-mini-cli service enable live # boot-persist listen run --live (disables demo)
reachy-mini-cli service enable demo # switch to the idle demo loop (disables live)
reachy-mini-cli service status --json # which mode is enabled + daemon health
reachy-mini-cli service disable # stop the presence (daemon stays up)
A true machine-reboot check is manual: a systemctl --user service starts at
boot only when the user has linger enabled (loginctl enable-linger $USER).
See Boot persistence.
Export feed
think run --export - streams a live newline-delimited JSON (NDJSON) feed of
what the robot is thinking / saying / feeling — one object per line. The
renderer stays out of this repo by design (the export decoupling boundary):
reachy-mini-cli emits a documented contract, a separate consumer renders it.
reachy-mini-cli think run --export - # all block types
reachy-mini-cli think run --export - --export-blocks message,emotion
reachy-mini-cli think run --export - | <your renderer>
Wire format: docs/export-schema.md. For the renderer
boundary and the reference reterminal consumer, see
Export feed & the external renderer.
What you get
- An agent-first CLI cited from teken
(
afi-cli). - A mesh identity —
culture.yaml(suffix+backend) and the matching prompt file (CLAUDE.mdforbackend: claude). - The canonical guildmaster skill kit (11 skills) under
.claude/skills/, vendored cite-don't-import. Seedocs/skill-sources.md. - A build + deploy baseline — pytest, lint, the agent-first rubric gate, and PyPI Trusted Publishing wired into GitHub Actions.
Developer quickstart
For working on the repo itself (an editable checkout, not an end-user install):
uv sync --extra daemon # recommended — SDK + the reachy-mini-daemon binary
uv sync # bare — numpy only; HTTP remote profile (--transport http)
uv run pytest -n auto # run the test suite
uv run reachy whoami # identity from culture.yaml
uv run reachy learn # self-teaching prompt (add --json)
uv run teken cli doctor . --strict # the agent-first rubric gate CI runs
CLI (introspection)
The agent-first verbs that work with no robot attached:
| Verb | What it does |
|---|---|
whoami |
Report this agent's nick, version, backend, model from culture.yaml. |
quickstart |
Print the copy-paste install + bring-up sequence. |
learn |
Print a structured self-teaching prompt. |
explain <path> |
Markdown docs for any noun/verb path. |
overview |
Read-only descriptive snapshot of the agent. |
doctor |
Check the agent-identity invariants (prompt-file-present, backend-consistency). |
cli overview |
Describe the CLI surface itself. |
Every command supports --json. Results go to stdout, errors/diagnostics to
stderr (never mixed). Exit codes: 0 success, 1 user error, 2 environment
error, 3+ reserved.
Make it your own
- Rename the package
reachy/and thereachy-mini-cliCLI/dist name throughoutpyproject.toml, the package,tests/, andsonar-project.properties. - Edit
culture.yamlwith yoursuffixandbackend. - Rewrite
CLAUDE.mdfor your agent and run/init. - Re-vendor only the skills you need from guildmaster (see
docs/skill-sources.md).
See CLAUDE.md for the full conventions (version-bump-every-PR,
the cicd PR lane, deploy setup).
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file reachy_mini_cli-0.37.0.tar.gz.
File metadata
- Download URL: reachy_mini_cli-0.37.0.tar.gz
- Upload date:
- Size: 1.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14e7931e7b79861c2767f9fc55e301eb30bc9a0521fda15d24fe151826c19f96
|
|
| MD5 |
767c8854c7f4344fcdaf34c97fc8f4f0
|
|
| BLAKE2b-256 |
9055aa8cce5395e01e1a79a2dc6e119ea243630fc1b2dcd62c35e44be3da6698
|
File details
Details for the file reachy_mini_cli-0.37.0-py3-none-any.whl.
File metadata
- Download URL: reachy_mini_cli-0.37.0-py3-none-any.whl
- Upload date:
- Size: 560.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a6241b8dd2d9aa03ee3564a6cf00d727ec1b34105eb2ff9ad2df05e96d140f2
|
|
| MD5 |
5b7bb90e48cc54c12fc8926ca9378a03
|
|
| BLAKE2b-256 |
37762fa7d4e1f15537a144943851feadc219188c2a0dff0c49fdc0b478d8c7d8
|