A Linux and macOS web client for operating a running Robonix deployment. It provides text tasks, voice turns, hands-free control, explicit Stop/steer behavior, audio-device routing, and live Pilot/RTDL execution events.
Requirements:
- Linux or macOS
- Python 3.11 or newer
- network access to the machine running Robonix Atlas
- a running Robonix deployment with Atlas, Liaison, Pilot, and Executor
Install from source:
git clone https://github.com/syswonder/robonix-client.git
cd robonix-client
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -e ".[audio]"The audio extra installs the PortAudio adapter used for microphone and
speaker access. Install the system library first when needed.
Ubuntu/Debian:
sudo apt update
sudo apt install -y libportaudio2 portaudio19-dev
pip install -e ".[audio]"macOS:
brew install portaudio
pip install -e ".[audio]"Assume Robonix Atlas is running on 100.87.172.93:50051:
source .venv/bin/activate
robonix-client --robot-host 100.87.172.93Open http://127.0.0.1:7860/.
The client starts its local audio service automatically. On Linux it uses the desktop's PipeWire, PulseAudio, or ALSA devices through PortAudio. In the UI:
- Confirm Robot Host is
100.87.172.93and Atlas Port is50051. - Click Connect. The status should become online.
- Enter a small text task and click Send.
- While a task is active, Send becomes Steer and Stop appears.
- Open Audio to select and test microphone/speaker providers and devices.
--host and --robot-host are different:
--host 127.0.0.1controls where this Web UI listens.--robot-host 100.87.172.93selects the remote Robonix machine.
Most users only need --robot-host.
Enter the IP or hostname of the machine that runs Robonix Atlas. It is not the Mac client IP and not an unrelated development PC.
Good choices are:
- the robot's Tailscale IP when both machines use Tailscale;
- the robot's LAN IP when both machines are on the same trusted LAN;
127.0.0.1only when Robonix and this client run on the same machine.
The required fields are:
| Field | Value |
|---|---|
| Robot Host | Atlas machine IP or hostname, for example 100.87.172.93 |
| Atlas Port | 50051 unless the deployment changed it |
| Liaison Endpoint | Leave empty; the client discovers Liaison through Atlas |
| User ID | Optional identity used by the deployment's access policy |
Liaison normally listens on port 50081, but clients should discover it
through Atlas instead of hard-coding that port.
For a Mac microphone/speaker, the Robonix deployment must include the
audio_client_bridge provider in client-initiated mode:
primitive:
- name: audio_client_bridge
path: ./primitives/audio_client_bridge
config:
transport: reverse
listen_port: 60002The word reverse only describes connection ownership: the Mac connects to
the robot. The deployment does not store the Mac IP. The client discovers the
bridge endpoint through Atlas, opens one outbound WebSocket, and carries both
microphone and speaker PCM over that connection.
In Audio, select audio_client_bridge for input and/or output, choose the
client machine's devices, click Apply Route, then run Test microphone and Test
speaker. Hands-free mode is disabled until explicitly enabled in the UI.
This flow runs Webots and Robonix on a Linux machine and the client on Linux or macOS.
The same-host case also works by using 127.0.0.1 as Robot Host.
On the Linux/Webots machine:
git clone --recursive https://github.com/syswonder/robonix.git
cd robonix
cd rust && make install && cd ..
export VLM_BASE_URL=https://api.openai.com/v1
export VLM_API_KEY=<your-key>
export VLM_MODEL=<your-model>
cd examples/webots
rbnx buildUse the reverse audio_client_bridge manifest block shown above if voice from
the Mac is part of the test. Text, planning, execution, and Stop tests do not
require client audio.
In terminal 1, from the Robonix repository root:
bash examples/webots/sim/start.shoffice.wbt is the default. To select another built-in world:
bash examples/webots/sim/start.sh --world complete_apartment.wbtWait until the simulator and Tiago controller are ready.
In terminal 2:
cd examples/webots
rbnx bootWait for Atlas, Liaison, Pilot, Executor, and the manifest providers to report
ready. rbnx caps can be used to confirm capability registration.
On the client machine:
cd robonix-client
source .venv/bin/activate
robonix-client --robot-host <webots-machine-ip>Open http://127.0.0.1:7860/, click Connect, and run the checks in this order:
- Send a harmless text request such as
Use Bash to print WEBOTS_CLIENT_OK. - Send a longer Bash task, then send a Steer update while it runs.
- Start another long Bash task and click Stop; verify the task becomes interrupted and its child process exits.
- Inspect the RTDL tree and execution history for one plan/call per request.
- If audio bridge is enabled, apply the route and test microphone, speaker, one Voice turn, then hands-free wake detection.
- Only after those checks, test simulated camera/navigation capabilities.
Stop the environment with:
cd examples/webots
rbnx shutdown
bash sim/stop.shBrowser UI
-> local robonix-client FastAPI/WebSocket adapter
-> Atlas discovery
-> Liaison task/voice API
-> Pilot planning harness
-> Executor and registered capabilities
-> structured Pilot/RTDL events back to the UI
The client does not embed a planner and does not call robot drivers directly. Atlas is the source of provider endpoints; Liaison is the interaction gateway; Pilot owns task/steer/abort semantics; Executor owns running capability calls.
- Send starts a new task when the session is idle.
- Steer targets the active turn using its expected turn ID. Stale steer is rejected rather than applied to a newer task.
- Stop sends an abort control event. Pilot interrupts the active turn and Executor cancels running work, including Bash child processes. If an F2 session is recording, recognizing, or speaking, Stop also cancels that voice stream and releases its audio devices.
- Pressing F2 while TTS is active performs barge-in: the old reply is interrupted, then a fresh voice capture starts. TTS is never recorded back into the new turn.
- Voice steer ASR text is shown as a
voice steeruser message and is fenced to the active turn ID. - Capture ends after speech plus 1.2 seconds of silence. If no speech is detected, it exits with a visible error after 5 seconds instead of occupying the microphone for the full record limit.
- Planning and node state are structured events. Only a completed answer or a real user-input boundary becomes an assistant reply.
- New Session is disabled while a task is active, so it cannot hide an execution that is still running.
Linux audio or macOS CoreAudio
<-> local audio service
<-> outbound WebSocket to audio_client_bridge on the robot
<-> standard Robonix mic/speaker contracts
<-> Liaison + Speech
The bridge-specific endpoint is discovered through the optional
robonix/primitive/audio/bridge_info capability. Normal robot-local audio
drivers do not need that capability.
- Client page does not open: check that
robonix-clientis running on127.0.0.1:7860. - Robot stays offline: verify the entered host is the Atlas machine and that
<robot-host>:50051is reachable from the client machine. - Liaison unavailable: leave the endpoint empty and confirm Liaison is registered in Atlas.
- Audio bridge unavailable: confirm the deployment uses
audio_client_bridge, port60002is reachable, and the provider exposesbridge_info. - Microphone test reports digital silence: every PCM sample was zero. Check
hardware mute and Linux/macOS audio routing, or select
audio_client_bridgeand a real input device. Quiet nonzero background audio is accepted. - Linux audio service is offline: install
libportaudio2and theaudioextra, then runpython -m sounddeviceto confirm that input and output devices are visible in the same desktop session that runs the client. - Stop does not end a task: inspect the RTDL event history and Executor log; a successful Stop must produce an interrupted turn and a cancelled running plan.
- Robonix core: https://github.com/syswonder/robonix