--- 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 ---

Reachy OpenWebUI icon

# 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 ` | `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