Skip to main content

Hardware Mesh Protocol

FERAL controls physical devices through the Hardware Use Protocol (HUP) — a generic, self-describing hardware hub. Devices declare what they can do via an actions[] envelope; the brain converts that into a DeviceManifest, registers a transport adapter, auto-generates LLM tools, and runs a closed-loop honesty loop when capabilities declare a verify contract. Communication stays local-first over USB, WebSocket mesh, or phone-bridged BLE.

HUP Overview

HUP is to hardware what MCP is to software tools. Devices connect to the Brain (directly or through a bridge), announce their capabilities, and the agent invokes them as tools — without per-device skill code on the brain.
Key properties:
  • Local-first: all communication stays on the LAN (or host-attached USB).
  • Self-describing: devices publish an actions[] envelope; the brain maps it generically (HUP_ACTION_SCHEMA, device_capability_from_action, device_manifest_from_capabilities in hardware/protocol.py).
  • Bidirectional: the Brain sends commands; devices push telemetry.
  • Hot-pluggable: devices can join and leave; registration re-runs when manifests change.
  • Honest feedback: actuator tools report verified: true/false/none based on post-action sensor read-back, not bare firmware acks.

Ingress paths

Every ingress calls state.register_generic_hardware_skill_for(manifest, adapter) unless FERAL_GENERIC_HARDWARE_SKILLS=0.

Self-describing wire format (actions[])

Companion libraries and bridge nodes return a capabilities() / device_manifest envelope. Each actions[] entry becomes one LLM tool and one safety policy — no hand-written skill manifest required.
Optional per-action fields: action_type, rate_limit_per_minute, verify, returns, safety_notes. See HUP_ACTION_SCHEMA in feral-core/hardware/protocol.py for the full schema.

Device Manifests

The in-brain model is DeviceManifest + DeviceCapability (hardware/protocol.py). Once registered, capabilities appear as LLM tools named hwdev_<device_id>__<capability_id> (device IDs are sanitized; e.g. cutebot-usb-0hwdev_cutebot_usb_0__drive).
Once registered, the agent sees tools like:

Honesty loop (verify contract)

Actuator capabilities may declare a closed-loop verification contract on DeviceCapability.verify. After execution, GenericHardwareSkill re-reads the named sensor capability (via), checks field against expect, honors delay_ms and retries, and returns:
  • verified: true — observed state matches expectation
  • verified: false — action ran but state did not match (retries exhausted)
  • verified: none — no contract declared; telemetry attached but success is not asserted
History is recorded on the DeviceRegistry and exposed via GET /api/hardware/fleet.

Brain-local discovery

USB/host-attached devices are discovered via DEVICE_DISCOVERY_SPECS in hardware/discovery.py. Each entry names a Python module/class, availability probe, and adapter kind (generic or device-specific like cutebot). Set FERAL_CUTEBOT_PATH to point at the cuteferalbot repo when it is not installed as a package.

Kill switch

FERAL_GENERIC_HARDWARE_SKILLS defaults to "1" (generic path enabled). Set to "0" to disable auto-generated tools and use hand-written skill manifests only (legacy cutebot.json remains as a fallback).

Capability Types

Built-in Adapters

Wristband Adapter

For BLE-connected health wristbands. Bridges BLE GATT characteristics to HUP.

Smart Home Adapter

Bridges Zigbee/Z-Wave/WiFi smart home devices via Home Assistant or direct local APIs.

Robot Arm Adapter

Controls articulated robot arms via serial or network protocols.

Direct Local Control

HUP intentionally avoids cloud roundtrips. Commands go directly from the Brain to the device over the LAN. This gives:
  • Low latency: sub-10ms for local WebSocket commands.
  • Privacy: sensor data never leaves the home network.
  • Reliability: works without internet.
The Brain can also run on the same device as the adapter (e.g., a Raspberry Pi with a BLE dongle), reducing the path to a local function call.

Telemetry Ingestion

Devices push telemetry at their configured interval. The Brain routes it to:
  1. Working memory — latest values available to the LLM.
  2. Execution log — historical telemetry for trend analysis.
  3. Proactive engine — triggers alerts when thresholds are crossed.

Writing a Custom Adapter

For a self-describing companion library, use GenericSelfDescribingAdapter — it passthrough-executes any capability the device declares. Override _preprocess / _harden_params only for device-specific safety:
For phone-bridged BLE peripherals, the brain uses BridgedPeripheralAdapter — actions route through mesh.invoke to the bridge node. The peripheral’s manifest (from peripheral_bridge_register) drives tools and the honesty loop with no per-device code. Add brain-local discovery by appending a DeviceDiscoverySpec to DEVICE_DISCOVERY_SPECS in hardware/discovery.py.

API Reference