Fix ClawBody on current OpenAI + OpenClaw stacks (GA Realtime API, gateway protocol v4, device identity) - #6
Open
JackieQi wants to merge 1 commit into
Conversation
…ce identity, and MediaPipe numpy 2.x compat
- openai_realtime.py: migrate from the retired Realtime Beta API to the GA
API. OpenAI shut down the beta shape (beta_api_shape_disabled, close code
4000), which caused an endless reconnect loop. Uses client.realtime.connect,
the GA session.update shape (session.type, output_modalities, nested
session.audio.{input,output} with audio/pcm format objects, voice under
audio.output), and GA event names (response.output_audio.delta,
response.output_audio_transcript.delta/done).
- openclaw_bridge.py: update to current OpenClaw gateways.
* Protocol version 3 -> 4 (older gateways rejected with 'protocol mismatch')
* Identify as gateway-client/backend instead of impersonating
openclaw-control-ui (control-UI clients now require a secure context)
* Request valid scopes (operator.read, operator.write); the legacy 'chat'
scope no longer exists and broke pairing approval
* Implement Ed25519 device identity: keypair persisted at
~/.clawbody/device-identity.json, signs the connect.challenge nonce with
the v3 signature payload. Remote clients without a device identity get
their scopes stripped and chat.send fails with 'missing scope'.
Pairing is approved once on the gateway (openclaw devices approve).
- vision/mediapipe_tracker.py: make the BGR->RGB frame C-contiguous
(np.ascontiguousarray). With numpy 2.x mediapipe rejects negative-stride
views ('Reference mode is unavailable if data is not c_contiguous'),
which flooded logs and broke face tracking.
- .env.example: document that OPENCLAW_GATEWAY_URL must be the gateway
machine's LAN IP/mDNS name (not localhost) when running on the robot,
gateway.bind must be 'lan', note the one-time device pairing approval,
and replace the retired preview realtime model with a GA model.
Tested end-to-end on a Reachy Mini Wireless against OpenClaw 2026.7.1:
voice conversation, agent context fetch, ask_openclaw tool calls, and
MediaPipe face tracking all working.
Co-Authored-By: Oz <oz-agent@warp.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix ClawBody on current OpenAI + OpenClaw stacks (GA Realtime API, gateway protocol v4, device identity, MediaPipe/numpy 2 compat)
ClawBody no longer works out of the box on a Reachy Mini: OpenAI retired the Realtime Beta API (May 2026) and current OpenClaw gateways (tested with 2026.7.1) changed their WebSocket handshake requirements. This PR restores full functionality, tested end-to-end on a Reachy Mini Wireless.
What was broken
4000/invalid_request_error.beta_api_shape_disabledbecause the handler used the retired Beta API viaclient.beta.realtime.connect.INVALID_REQUEST - protocol mismatch(bridge pinned protocol 3, current gateways speak 4)control ui requires device identity (use HTTPS or localhost secure context)(bridge impersonatedopenclaw-control-ui)invalid scope for requested roles: chat(legacychatscope no longer exists; broke pairing approval)missing scope: operator.write(remote token-only clients get unbound scopes stripped; a paired device identity is required)Error in head position detection: Reference mode is unavailable if 'data' is not c_contiguoushundreds of times per second, because the BGR→RGB conversion produced a negative-stride view.Changes
src/reachy_mini_openclaw/openai_realtime.py— GA Realtime migrationclient.beta.realtime.connect→client.realtime.connect(drops the retiredOpenAI-Beta: realtime=v1wire protocol)session.updateshape:"type": "realtime",output_modalities, audio config nested undersession.audio.{input,output}with{"type": "audio/pcm", "rate": 24000}format objects, voice underaudio.output.voice,turn_detectionunderaudio.input, transcription modelgpt-4o-transcribe(GA replacement forwhisper-1)response.output_audio.delta,response.output_audio_transcript.delta/done. Client events (input_audio_buffer.append,conversation.item.create,response.create) andconversation.item.input_audio_transcription.completedare unchanged in GA.src/reachy_mini_openclaw/openclaw_bridge.py— current gateway protocolopenclaw-control-ui/webchat→gateway-client/backend(control-UI ids now require a browser secure context)["chat", "operator.write", "operator.read"]→["operator.read", "operator.write"]~/.clawbody/device-identity.json(0600), device id = sha256 of the raw public key, signs theconnect.challengenonce using the gateway's v3 signature payload (v3|deviceId|clientId|clientMode|role|scopes|signedAtMs|token|nonce|platform|deviceFamily). Without this, remote clients get their scopes stripped andchat.sendfails. Uses thecryptographypackage (already a transitive dependency on the robot image); degrades gracefully to a token-only connection if unavailable.openclaw devices approvewhen the gateway reportsNOT_PAIRED(one-time approval on the gateway machine).src/reachy_mini_openclaw/vision/mediapipe_tracker.py— numpy 2 compatimg[:, :, ::-1]→np.ascontiguousarray(img[:, :, ::-1])so MediaPipe accepts the frame..env.example— docsOPENCLAW_GATEWAY_URLmust be the gateway machine's LAN IP or mDNS name (notlocalhost) when ClawBody runs on the robot, and the gateway must havegateway.bind: "lan"gpt-4o-realtime-preview-2024-12-17example with a GA modelTesting
On a Reachy Mini Wireless (robot-side install in
/venvs/apps_venv) against OpenClaw 2026.7.1 and the live OpenAI GA Realtime API:session.created→session.updated) with tools, voice, VAD, and transcription accepted; nobeta_api_shape_disabled, stable across multi-turn voice conversationsopenclaw devices approve, agent context fetch (chat.send) returns the full agent context;ask_openclawtool calls workc_contiguouserrors (verified with numpy 2.4)This PR was written with the assistance of Warp: conversation
Co-Authored-By: Oz oz-agent@warp.dev