reachy_mini_central / docs /META_CONTRACT.md
cduss's picture
more info on central page
66918e9
|
Raw History Blame Contribute Delete
3.75 kB

Producer metadata contract

Every peer registers with POST /send {"type": "setPeerStatus", "roles": [...], "meta": {...}}. Central stores meta verbatim and forwards it unchanged to every owner-scoped surface: the SSE list / peerStatusChanged / sessionStateChanged frames, GET /api/robot-status and GET /api/debug/peers. Daemons may add fields at any time without a central change; clients must tolerate unknown keys.

This page lists the few keys central reads. Anything not listed is opaque to the server.

Keys interpreted by central

Key Sent by Server-side use
name producer, consumer Producer: robotName in /api/robot-status. Consumer: reported as activeApp while it holds a session. Display only.
hardware_id producer (daemons >= v1.7.2) Stable per-robot identity: a new registration with the same hardware_id under the same HF user evicts the older producer (last-writer-wins). Its presence also marks the daemon as heartbeat-capable, which opts it into the stale-producer sweep.
install_id producer (reserved) Same dedup semantics as hardware_id, checked independently. Not emitted by any shipped daemon yet.
kind producer Robot family, used only for the public per-kind counters (/health producers_by_kind, status page). See below.
robot_type producer Alias for kind, consulted only when kind is absent or empty.

Keys such as transport, release or api_version are passed through untouched and never interpreted.

kind

  • Missing means Reachy Mini. Reachy Mini daemons send no kind at all (their meta is {name, transport, hardware_id}), so when neither kind nor robot_type holds a non-blank string the producer classifies as reachy_mini. A kind that is absent, null, blank or not a string falls through to robot_type.
  • Known values: reachy_mini, microduck. Matching is case-insensitive and ignores every character outside a-z0-9, so Micro-Duck, micro duck, microduck, Reachy Mini, reachy-mini and reachymini all resolve to their canonical kind. A raw value longer than 64 characters is classified as other without any normalisation.
  • meta must be a JSON object. A setPeerStatus whose meta is not an object is rejected with HTTP 400 and leaves the previously registered meta untouched.
  • Anything else counts as other on the public counters. kind is untrusted input (any authenticated HF user can send any meta), so the public surfaces only ever expose the fixed key set {reachy_mini, microduck, other} - an unknown value can bump the other counter and nothing more. The status page labels for those keys are server-side constants; no meta string is ever rendered there.
  • The raw value is still forwarded verbatim to the owner's own listeners and /api/* endpoints. Classification is a read-only view for the public counters; it never rewrites meta.

Adding a robot family is a one-line change to KNOWN_ROBOT_KINDS (and a label in ROBOT_KIND_LABELS) in app.py; the tests in test_robot_kind.py and test_routes.py pin the behaviour above.

Public counters (GET /health)

{
  "status": "healthy",
  "peers": 3,
  "producers": 2,
  "sessions": 1,
  "producers_by_kind": {"reachy_mini": 1, "microduck": 1, "other": 0},
  "started_at": "2026-09-16T08:00:00Z",
  "uptime_seconds": 12345
}

peers, producers and producers_by_kind count connected peers only. started_at / uptime_seconds are wall-clock and exist so an operator can tell a fresh redeploy (all counters reset) from a quiet fleet. Both / and /health are served with Cache-Control: no-store.