Skip to content

Fix ClawBody on current OpenAI + OpenClaw stacks (GA Realtime API, gateway protocol v4, device identity) - #6

Open
JackieQi wants to merge 1 commit into
tomrikert:mainfrom
JackieQi:fix/openai-ga-realtime-and-gateway-protocol4
Open

Fix ClawBody on current OpenAI + OpenClaw stacks (GA Realtime API, gateway protocol v4, device identity)#6
JackieQi wants to merge 1 commit into
tomrikert:mainfrom
JackieQi:fix/openai-ga-realtime-and-gateway-protocol4

Conversation

@JackieQi

Copy link
Copy Markdown

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

  1. OpenAI Realtime reconnect loop — every connection closed with code 4000 / invalid_request_error.beta_api_shape_disabled because the handler used the retired Beta API via client.beta.realtime.connect.
  2. OpenClaw gateway rejects the bridge — in order encountered:
    • INVALID_REQUEST - protocol mismatch (bridge pinned protocol 3, current gateways speak 4)
    • control ui requires device identity (use HTTPS or localhost secure context) (bridge impersonated openclaw-control-ui)
    • invalid scope for requested roles: chat (legacy chat scope no longer exists; broke pairing approval)
    • missing scope: operator.write (remote token-only clients get unbound scopes stripped; a paired device identity is required)
  3. MediaPipe face tracking flooded errors — with numpy 2.x, Error in head position detection: Reference mode is unavailable if 'data' is not c_contiguous hundreds of times per second, because the BGR→RGB conversion produced a negative-stride view.

Changes

src/reachy_mini_openclaw/openai_realtime.py — GA Realtime migration

  • client.beta.realtime.connectclient.realtime.connect (drops the retired OpenAI-Beta: realtime=v1 wire protocol)
  • GA session.update shape: "type": "realtime", output_modalities, audio config nested under session.audio.{input,output} with {"type": "audio/pcm", "rate": 24000} format objects, voice under audio.output.voice, turn_detection under audio.input, transcription model gpt-4o-transcribe (GA replacement for whisper-1)
  • GA server event names: response.output_audio.delta, response.output_audio_transcript.delta/done. Client events (input_audio_buffer.append, conversation.item.create, response.create) and conversation.item.input_audio_transcription.completed are unchanged in GA.

src/reachy_mini_openclaw/openclaw_bridge.py — current gateway protocol

  • Protocol version 3 → 4
  • Client identity openclaw-control-ui/webchatgateway-client/backend (control-UI ids now require a browser secure context)
  • Scopes ["chat", "operator.write", "operator.read"]["operator.read", "operator.write"]
  • Ed25519 device identity: keypair persisted at ~/.clawbody/device-identity.json (0600), device id = sha256 of the raw public key, signs the connect.challenge nonce 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 and chat.send fails. Uses the cryptography package (already a transitive dependency on the robot image); degrades gracefully to a token-only connection if unavailable.
  • Friendlier log message pointing at openclaw devices approve when the gateway reports NOT_PAIRED (one-time approval on the gateway machine).

src/reachy_mini_openclaw/vision/mediapipe_tracker.py — numpy 2 compat

  • img[:, :, ::-1]np.ascontiguousarray(img[:, :, ::-1]) so MediaPipe accepts the frame.

.env.example — docs

  • OPENCLAW_GATEWAY_URL must be the gateway machine's LAN IP or mDNS name (not localhost) when ClawBody runs on the robot, and the gateway must have gateway.bind: "lan"
  • Note about the one-time device pairing approval
  • Replace the retired gpt-4o-realtime-preview-2024-12-17 example with a GA model

Testing

On a Reachy Mini Wireless (robot-side install in /venvs/apps_venv) against OpenClaw 2026.7.1 and the live OpenAI GA Realtime API:

  • GA realtime session established (session.createdsession.updated) with tools, voice, VAD, and transcription accepted; no beta_api_shape_disabled, stable across multi-turn voice conversations
  • Gateway connect PASS with device identity; after one openclaw devices approve, agent context fetch (chat.send) returns the full agent context; ask_openclaw tool calls work
  • MediaPipe face tracking runs with zero c_contiguous errors (verified with numpy 2.4)

This PR was written with the assistance of Warp: conversation

Co-Authored-By: Oz oz-agent@warp.dev

…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants