Spaces:
Running
Running
| title: Reachy OpenWebUI | |
| emoji: 🐞 | |
| colorFrom: gray | |
| colorTo: blue | |
| sdk: gradio | |
| app_file: app.py | |
| pinned: false | |
| short_description: Phone-style OpenWebUI conversations for Reachy Mini. | |
| tags: | |
| - reachy_mini | |
| - reachy_mini_python_app | |
| sdk_version: 6.18.0 | |
| license: apache-2.0 | |
| <p align="center"> | |
| <img src="src/Reachy_OpenWebUI/static/assets/reachy-conversation-app.png" width="112" alt="Reachy OpenWebUI icon"> | |
| </p> | |
| # Reachy OpenWebUI | |
| Reachy OpenWebUI is a phone-style conversation app for Reachy Mini. OpenWebUI owns the model, transcription, chat behavior, user context, and TTS. This app owns the robot-side runtime: settings, no-wake-word listening, camera buffering, local Reachy tools, avatars, chat state, and motion. | |
| This Hugging Face Space is a project page. The real app runs inside the Reachy Mini app environment where it can access the robot daemon, microphone, speaker, camera, and movement APIs. | |
| ## Highlights | |
| - Phone-inspired settings and conversation UI served by the Reachy Mini app webserver. | |
| - OpenWebUI model/workspace picker shown as contacts. | |
| - OpenWebUI conversation list support for returning to saved chats. | |
| - Model and user avatar proxying from OpenWebUI profile image endpoints. | |
| - No-wake-word voice loop using Reachy audio, Silero VAD, OpenWebUI STT, OpenWebUI chat, and OpenWebUI TTS. | |
| - Sentence-by-sentence speech streaming so audio starts before the full model answer is finished. | |
| - Reachy-side tools for dance, recorded emotions, camera, head tracking, head movement, and speech. | |
| - Speech-reactive head motion blended with queued robot moves. | |
| - Robot attitudes that can shape idle motion, speaking motion, and which dance/emotion moves the model can choose. | |
| ## Runtime Flow | |
| ```text | |
| Reachy microphone | |
| -> audio startup tuning and SDK record loop | |
| -> Silero VAD and level fallback | |
| -> OpenWebUI audio transcription | |
| -> OpenWebUI chat stream with optional Reachy tool specs | |
| -> optional Reachy-side tool execution | |
| -> OpenWebUI speech | |
| -> Reachy speaker output plus speech-reactive motion | |
| ``` | |
| OpenWebUI may accept requests at `/api/chat/completions` while returning either | |
| classic chat-completion chunks (`chat.completion.chunk`) or Responses-style | |
| events (`response.output_text.delta`, `response.output_text.done`, | |
| `response.completed`). The runtime reader must support both formats because the | |
| selected OpenWebUI model/contact can route through different providers even when | |
| the model id shown in the UI is unchanged. | |
| ## Install | |
| This repo currently has no `uv.lock`, so do not use `uv sync --frozen`. | |
| ```bash | |
| uv venv --python python3.12 .venv | |
| source .venv/bin/activate | |
| uv sync | |
| ``` | |
| Editable pip install: | |
| ```bash | |
| python -m venv .venv | |
| source .venv/bin/activate | |
| pip install -e . | |
| ``` | |
| Optional local vision extra: | |
| ```bash | |
| uv sync --extra local_vision | |
| pip install -e .[local_vision] | |
| ``` | |
| Developer tools: | |
| ```bash | |
| uv sync --group dev | |
| ``` | |
| `requirements.txt` is only for this Hugging Face Space project page. The robot app dependencies live in `pyproject.toml`. | |
| ## Configuration | |
| The app reads `~/.config/settings/.env` first, then a local `.env` if present. The settings UI writes the stable file at `~/.config/settings/.env`. | |
| Core OpenWebUI settings: | |
| | Variable | Purpose | | |
| | --- | --- | | |
| | `OPENWEBUI_URL` | OpenWebUI base URL. Values ending in `/api` are accepted. | | |
| | `OPENWEB_LOADED_LLM` | Selected OpenWebUI model, workspace, or contact id. | | |
| | `OPENWEBUI_API_KEY` | API key for HTTP requests when your OpenWebUI server accepts API-key bearer auth. | | |
| | `OPENWEBUI_TOKEN` | Browser/session JWT. Preferred for chat, Socket.IO, transcription, and speech. | | |
| | `OPENWEBUI_CHAT_ID` | Saved OpenWebUI chat id. Leave blank on first launch. | | |
| | `MIC_GAIN` | Digital gain applied before VAD and transcription upload. | | |
| | `HF_HOME` | Hugging Face cache directory. | | |
| | `HF_TOKEN` | Optional token for gated or private assets. | | |
| User/context variables sent to OpenWebUI: | |
| | Variable | Purpose | | |
| | --- | --- | | |
| | `OPENWEBUI_USER_ID` | Optional user id. If blank, the app tries to derive it from the JWT. | | |
| | `OPENWEBUI_USER_NAME` | User name supplied to OpenWebUI variables and socket context. | | |
| | `OPENWEBUI_USER_EMAIL` | User email supplied to OpenWebUI variables and socket context. | | |
| | `OPENWEBUI_USER_LANGUAGE` | User language variable. | | |
| | `OPENWEBUI_USER_LOCATION` | User location variable. | | |
| | `OPENWEBUI_USER_TIMEZONE` | User timezone variable. | | |
| Audio and timing settings: | |
| | Variable | Purpose | | |
| | --- | --- | | |
| | `OPENWEBUI_TTS_READ_TIMEOUT` | Read timeout for OpenWebUI speech responses. | | |
| | `OPENWEBUI_CONVERSATION_IDLE_RESET_SECONDS` | Optional idle reset. `0` disables it. | | |
| | `VAD_THRESHOLD` | Silero speech probability threshold. | | |
| | `VAD_FALLBACK_THRESHOLD` | RMS fallback threshold. | | |
| | `VAD_SPEECH_ONSET_CHUNKS` | Speech chunks required before a turn starts. | | |
| | `VAD_SILENCE_END_CHUNKS` | Silence chunks required before a turn ends. | | |
| | `VAD_MIN_SPEECH_CHUNKS` | Minimum speech chunks before sending audio to OpenWebUI transcription. | | |
| | `SILERO_VAD_ONNX_PATH` | Optional path for the Silero ONNX model. | | |
| ## TTS Voices | |
| Set TTS voices in OpenWebUI. This app reads the selected model/contact voice metadata and sends that voice back to the OpenWebUI speech endpoint. | |
| If a model/contact has no voice set in OpenWebUI, the app sends no voice value and lets OpenWebUI use its default TTS behavior. There is intentionally no app-level voice picker because every OpenWebUI install can expose different TTS engines and voice names. | |
| ## Running | |
| The normal runtime path is the Reachy Mini Apps launcher. It provides the FastAPI settings app and serves the phone UI declared by: | |
| ```python | |
| custom_app_url = "http://0.0.0.0:7860/" | |
| ``` | |
| Console entry point: | |
| ```bash | |
| reachy-mini-conversation-app-openwebui | |
| ``` | |
| CLI options: | |
| | Option | Default | Description | | |
| | --- | --- | --- | | |
| | `--no-camera` | `False` | Skip camera frame buffering. | | |
| | `--smolvlm` | `False` | Try to initialize the optional local SmolVLM vision manager. | | |
| | `--robot-name <name>` | `None` | Connect to a daemon started with the same robot name. | | |
| | `--debug` | `False` | Enable verbose app logging. | | |
| ## Settings UI | |
| The phone-style UI lives in `src/Reachy_OpenWebUI/static/`. | |
| It includes: | |
| - Power-on screen while the backend is getting ready. | |
| - Home screen with contacts, conversations, quick connect, and settings. | |
| - Contacts page backed by OpenWebUI models. | |
| - Conversations page backed by OpenWebUI chat history. | |
| - Call screen with transcript bubbles, typing indicators, model avatar, user avatar, mute, end call, and back navigation. | |
| - Settings for OpenWebUI URL, model/contact, credentials, mic gain, vision-only contacts, attitude, and Reachy-side tools. | |
| ## Tools | |
| Default Reachy-side tool allow-list: | |
| ```text | |
| src/Reachy_OpenWebUI/profiles/default/tools.txt | |
| ``` | |
| Enabled by default: | |
| | Tool | Behavior | | |
| | --- | --- | | |
| | `dance` | Queue a named or random dance from `reachy_mini_dances_library`. | | |
| | `stop_dance` | Clear the dance queue. | | |
| | `play_emotion` | Queue a recorded emotion from `reachy-mini-emotions-library`. | | |
| | `stop_emotion` | Clear the emotion queue. | | |
| | `camera` | Read the latest buffered camera frame and pass it to an optional vision manager. | | |
| | `idle_do_nothing` | Explicit idle no-op for idle turns. | | |
| | `head_tracking` | Attempt to toggle camera-worker head tracking. | | |
| | `move_head` | Queue a head pose change: left, right, up, down, or front. | | |
| | `speak` | Send text through the same OpenWebUI speech path used by normal assistant responses. | | |
| The settings page can enable or disable Reachy-side tools. OpenWebUI tools are still managed in OpenWebUI. | |
| ## Attitudes | |
| `Attitude` is one user-facing movement setting. It is designed to control: | |
| - idle motion | |
| - speech-reactive motion | |
| - which dance and emotion moves are offered to the model | |
| The goal is simple: a serious model should not move like a silly one, and a playful model should not be stuck with the same tiny idle pattern as a formal one. | |
| ## Chat State | |
| OpenWebUI chat state is stored in the stable settings file and recorded in: | |
| ```text | |
| ~/.config/settings/openwebui_chat_history.json | |
| ``` | |
| The conversation window rolls over at local 7 AM. Callback and conversation selection clear or replace the saved chat id so OpenWebUI can attach the next turn to the right conversation. | |
| ## Vision Status | |
| Camera frame buffering is bundled and enabled unless `--no-camera` is passed. The optional local vision manager expects `Reachy_OpenWebUI.vision.processors`, which is not present in this checkout. If that module is absent, startup logs a warning and the `camera` tool returns an unavailable-vision error. | |
| ## Project Layout | |
| ```text | |
| app.py Hugging Face Space project page | |
| pyproject.toml package metadata, dependencies, app entry points | |
| requirements.txt Space-only dependency file | |
| src/Reachy_OpenWebUI/main.py Reachy Mini App entry point | |
| src/Reachy_OpenWebUI/console.py settings routes and media loop | |
| src/Reachy_OpenWebUI/local/ OpenWebUI chat, speech, transcription, VAD | |
| src/Reachy_OpenWebUI/tools/ Reachy-side tools | |
| src/Reachy_OpenWebUI/static/ phone-style UI | |
| src/Reachy_OpenWebUI/profiles/default/ default tool allow-list | |
| external_content/ starter external profile/tool examples | |
| ``` | |
| ## Development Checks | |
| Run the checks available in this checkout: | |
| ```bash | |
| uv run ruff check . | |
| uv run ruff format . --check | |
| uv run mypy --pretty --show-error-codes | |
| uv run python -m compileall src app.py | |
| ``` | |
| There is no `tests/` directory in this checkout. Add focused tests when adding behavior that can be tested off-robot. | |
| ## License | |
| Apache 2.0 |