Ehu shubham shaw contribution --> Hardware support (#306)

* feat: add ZeroClaw firmware for ESP32 and Nucleo

* Introduced new firmware for ZeroClaw on ESP32 and Nucleo-F401RE, enabling JSON-over-serial communication for GPIO control.
* Added `zeroclaw-esp32` with support for commands like `gpio_read` and `gpio_write`, along with capabilities reporting.
* Implemented `zeroclaw-nucleo` firmware with similar functionality for STM32, ensuring compatibility with existing ZeroClaw protocols.
* Updated `.gitignore` to include new firmware targets and added necessary dependencies in `Cargo.toml` for both platforms.
* Created README files for both firmware projects detailing setup, build, and usage instructions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: enhance hardware peripheral support and documentation

- Added `Peripheral` trait implementation in `src/peripherals/` to manage hardware boards (STM32, RPi GPIO).
- Updated `AGENTS.md` to include new extension points for peripherals and their configuration.
- Introduced comprehensive documentation for adding boards and tools, including a quick start guide and supported boards.
- Enhanced `Cargo.toml` to include optional dependencies for PDF extraction and peripheral support.
- Created new datasheets for Arduino Uno, ESP32, and Nucleo-F401RE, detailing pin aliases and GPIO usage.
- Implemented new tools for hardware memory reading and board information retrieval in the agent loop.

This update significantly improves the integration and usability of hardware peripherals within the ZeroClaw framework.

* feat: add ZeroClaw firmware for ESP32 and Nucleo

* Introduced new firmware for ZeroClaw on ESP32 and Nucleo-F401RE, enabling JSON-over-serial communication for GPIO control.
* Added `zeroclaw-esp32` with support for commands like `gpio_read` and `gpio_write`, along with capabilities reporting.
* Implemented `zeroclaw-nucleo` firmware with similar functionality for STM32, ensuring compatibility with existing ZeroClaw protocols.
* Updated `.gitignore` to include new firmware targets and added necessary dependencies in `Cargo.toml` for both platforms.
* Created README files for both firmware projects detailing setup, build, and usage instructions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: enhance hardware peripheral support and documentation

- Added `Peripheral` trait implementation in `src/peripherals/` to manage hardware boards (STM32, RPi GPIO).
- Updated `AGENTS.md` to include new extension points for peripherals and their configuration.
- Introduced comprehensive documentation for adding boards and tools, including a quick start guide and supported boards.
- Enhanced `Cargo.toml` to include optional dependencies for PDF extraction and peripheral support.
- Created new datasheets for Arduino Uno, ESP32, and Nucleo-F401RE, detailing pin aliases and GPIO usage.
- Implemented new tools for hardware memory reading and board information retrieval in the agent loop.

This update significantly improves the integration and usability of hardware peripherals within the ZeroClaw framework.

* feat: Introduce hardware auto-discovery and expanded configuration options for agents, hardware, and security.

* chore: update dependencies and improve probe-rs integration

- Updated `Cargo.lock` to remove specific version constraints for several dependencies, including `zerocopy`, `syn`, and `strsim`, allowing for more flexibility in version resolution.
- Upgraded `bincode` and `bitfield` to their latest versions, enhancing serialization and memory management capabilities.
- Updated `Cargo.toml` to reflect the new version of `probe-rs` from `0.24` to `0.30`, improving hardware probing functionality.
- Refactored code in `src/hardware` and `src/tools` to utilize the new `SessionConfig` for session management in `probe-rs`, ensuring better compatibility and performance.
- Cleaned up documentation in `docs/datasheets/nucleo-f401re.md` by removing unnecessary lines.

* fix: apply cargo fmt

* docs: add hardware architecture diagram.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ehu shubham shaw 2026-02-16 11:40:10 -05:00 committed by GitHub
parent b36f23784a
commit de3ec87d16
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 9607 additions and 1885 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View file

@ -0,0 +1,116 @@
# Adding Boards and Tools — ZeroClaw Hardware Guide
This guide explains how to add new hardware boards and custom tools to ZeroClaw.
## Quick Start: Add a Board via CLI
```bash
# Add a board (updates ~/.zeroclaw/config.toml)
zeroclaw peripheral add nucleo-f401re /dev/ttyACM0
zeroclaw peripheral add arduino-uno /dev/cu.usbmodem12345
zeroclaw peripheral add rpi-gpio native # for Raspberry Pi GPIO (Linux)
# Restart daemon to apply
zeroclaw daemon --host 127.0.0.1 --port 8080
```
## Supported Boards
| Board | Transport | Path Example |
|-----------------|-----------|---------------------------|
| nucleo-f401re | serial | /dev/ttyACM0, /dev/cu.usbmodem* |
| arduino-uno | serial | /dev/ttyACM0, /dev/cu.usbmodem* |
| arduino-uno-q | bridge | (Uno Q IP) |
| rpi-gpio | native | native |
| esp32 | serial | /dev/ttyUSB0 |
## Manual Config
Edit `~/.zeroclaw/config.toml`:
```toml
[peripherals]
enabled = true
datasheet_dir = "docs/datasheets" # optional: RAG for "turn on red led" → pin 13
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
[[peripherals.boards]]
board = "arduino-uno"
transport = "serial"
path = "/dev/cu.usbmodem12345"
baud = 115200
```
## Adding a Datasheet (RAG)
Place `.md` or `.txt` files in `docs/datasheets/` (or your `datasheet_dir`). Name files by board: `nucleo-f401re.md`, `arduino-uno.md`.
### Pin Aliases (Recommended)
Add a `## Pin Aliases` section so the agent can map "red led" → pin 13:
```markdown
# My Board
## Pin Aliases
| alias | pin |
|-------------|-----|
| red_led | 13 |
| builtin_led | 13 |
| user_led | 5 |
```
Or use key-value format:
```markdown
## Pin Aliases
red_led: 13
builtin_led: 13
```
### PDF Datasheets
With the `rag-pdf` feature, ZeroClaw can index PDF files:
```bash
cargo build --features hardware,rag-pdf
```
Place PDFs in the datasheet directory. They are extracted and chunked for RAG.
## Adding a New Board Type
1. **Create a datasheet**`docs/datasheets/my-board.md` with pin aliases and GPIO info.
2. **Add to config**`zeroclaw peripheral add my-board /dev/ttyUSB0`
3. **Implement a peripheral** (optional) — For custom protocols, implement the `Peripheral` trait in `src/peripherals/` and register in `create_peripheral_tools`.
See `docs/hardware-peripherals-design.md` for the full design.
## Adding a Custom Tool
1. Implement the `Tool` trait in `src/tools/`.
2. Register in `create_peripheral_tools` (for hardware tools) or the agent tool registry.
3. Add a tool description to the agent's `tool_descs` in `src/agent/loop_.rs`.
## CLI Reference
| Command | Description |
|---------|-------------|
| `zeroclaw peripheral list` | List configured boards |
| `zeroclaw peripheral add <board> <path>` | Add board (writes config) |
| `zeroclaw peripheral flash` | Flash Arduino firmware |
| `zeroclaw peripheral flash-nucleo` | Flash Nucleo firmware |
| `zeroclaw hardware discover` | List USB devices |
| `zeroclaw hardware info` | Chip info via probe-rs |
## Troubleshooting
- **Serial port not found** — On macOS use `/dev/cu.usbmodem*`; on Linux use `/dev/ttyACM0` or `/dev/ttyUSB0`.
- **Build with hardware**`cargo build --features hardware`
- **Probe-rs for Nucleo**`cargo build --features hardware,probe`

217
docs/arduino-uno-q-setup.md Normal file
View file

@ -0,0 +1,217 @@
# ZeroClaw on Arduino Uno Q — Step-by-Step Guide
Run ZeroClaw on the Arduino Uno Q's Linux side. Telegram works over WiFi; GPIO control uses the Bridge (requires a minimal App Lab app).
---
## What's Included (No Code Changes Needed)
ZeroClaw includes everything needed for Arduino Uno Q. **Clone the repo and follow this guide — no patches or custom code required.**
| Component | Location | Purpose |
|-----------|----------|---------|
| Bridge app | `firmware/zeroclaw-uno-q-bridge/` | MCU sketch + Python socket server (port 9999) for GPIO |
| Bridge tools | `src/peripherals/uno_q_bridge.rs` | `gpio_read` / `gpio_write` tools that talk to the Bridge over TCP |
| Setup command | `src/peripherals/uno_q_setup.rs` | `zeroclaw peripheral setup-uno-q` deploys the Bridge via scp + arduino-app-cli |
| Config schema | `board = "arduino-uno-q"`, `transport = "bridge"` | Supported in `config.toml` |
Build with `--features hardware` (or the default features) to include Uno Q support.
---
## Prerequisites
- Arduino Uno Q with WiFi configured
- Arduino App Lab installed on your Mac (for initial setup and deployment)
- API key for LLM (OpenRouter, etc.)
---
## Phase 1: Initial Uno Q Setup (One-Time)
### 1.1 Configure Uno Q via App Lab
1. Download [Arduino App Lab](https://docs.arduino.cc/software/app-lab/) (AppImage on Linux).
2. Connect Uno Q via USB, power it on.
3. Open App Lab, connect to the board.
4. Follow the setup wizard:
- Set username and password (for SSH)
- Configure WiFi (SSID, password)
- Apply any firmware updates
5. Note the IP address shown (e.g. `arduino@192.168.1.42`) or find it later via `ip addr show` in App Lab's terminal.
### 1.2 Verify SSH Access
```bash
ssh arduino@<UNO_Q_IP>
# Enter the password you set
```
---
## Phase 2: Install ZeroClaw on Uno Q
### Option A: Build on the Device (Simpler, ~2040 min)
```bash
# SSH into Uno Q
ssh arduino@<UNO_Q_IP>
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source ~/.cargo/env
# Install build deps (Debian)
sudo apt-get update
sudo apt-get install -y pkg-config libssl-dev
# Clone zeroclaw (or scp your project)
git clone https://github.com/theonlyhennygod/zeroclaw.git
cd zeroclaw
# Build (takes ~1530 min on Uno Q)
cargo build --release
# Install
sudo cp target/release/zeroclaw /usr/local/bin/
```
### Option B: Cross-Compile on Mac (Faster)
```bash
# On your Mac — add aarch64 target
rustup target add aarch64-unknown-linux-gnu
# Install cross-compiler (macOS; required for linking)
brew tap messense/macos-cross-toolchains
brew install aarch64-unknown-linux-gnu
# Build
CC_aarch64_unknown_linux_gnu=aarch64-unknown-linux-gnu-gcc cargo build --release --target aarch64-unknown-linux-gnu
# Copy to Uno Q
scp target/aarch64-unknown-linux-gnu/release/zeroclaw arduino@<UNO_Q_IP>:~/
ssh arduino@<UNO_Q_IP> "sudo mv ~/zeroclaw /usr/local/bin/"
```
If cross-compile fails, use Option A and build on the device.
---
## Phase 3: Configure ZeroClaw
### 3.1 Run Onboard (or Create Config Manually)
```bash
ssh arduino@<UNO_Q_IP>
# Quick config
zeroclaw onboard --api-key YOUR_OPENROUTER_KEY --provider openrouter
# Or create config manually
mkdir -p ~/.zeroclaw/workspace
nano ~/.zeroclaw/config.toml
```
### 3.2 Minimal config.toml
```toml
api_key = "YOUR_OPENROUTER_API_KEY"
default_provider = "openrouter"
default_model = "anthropic/claude-sonnet-4"
[peripherals]
enabled = false
# GPIO via Bridge requires Phase 4
[channels_config.telegram]
bot_token = "YOUR_TELEGRAM_BOT_TOKEN"
allowed_users = ["*"]
[gateway]
host = "127.0.0.1"
port = 8080
allow_public_bind = false
[agent]
compact_context = true
```
---
## Phase 4: Run ZeroClaw Daemon
```bash
ssh arduino@<UNO_Q_IP>
# Run daemon (Telegram polling works over WiFi)
zeroclaw daemon --host 127.0.0.1 --port 8080
```
**At this point:** Telegram chat works. Send messages to your bot — ZeroClaw responds. No GPIO yet.
---
## Phase 5: GPIO via Bridge (ZeroClaw Handles It)
ZeroClaw includes the Bridge app and setup command.
### 5.1 Deploy Bridge App
**From your Mac** (with zeroclaw repo):
```bash
zeroclaw peripheral setup-uno-q --host 192.168.0.48
```
**From the Uno Q** (SSH'd in):
```bash
zeroclaw peripheral setup-uno-q
```
This copies the Bridge app to `~/ArduinoApps/zeroclaw-uno-q-bridge` and starts it.
### 5.2 Add to config.toml
```toml
[peripherals]
enabled = true
[[peripherals.boards]]
board = "arduino-uno-q"
transport = "bridge"
```
### 5.3 Run ZeroClaw
```bash
zeroclaw daemon --host 127.0.0.1 --port 8080
```
Now when you message your Telegram bot *"Turn on the LED"* or *"Set pin 13 high"*, ZeroClaw uses `gpio_write` via the Bridge.
---
## Summary: Commands Start to End
| Step | Command |
|------|---------|
| 1 | Configure Uno Q in App Lab (WiFi, SSH) |
| 2 | `ssh arduino@<IP>` |
| 3 | `curl -sSf https://sh.rustup.rs \| sh -s -- -y && source ~/.cargo/env` |
| 4 | `sudo apt-get install -y pkg-config libssl-dev` |
| 5 | `git clone https://github.com/theonlyhennygod/zeroclaw.git && cd zeroclaw` |
| 6 | `cargo build --release --no-default-features` |
| 7 | `zeroclaw onboard --api-key KEY --provider openrouter` |
| 8 | Edit `~/.zeroclaw/config.toml` (add Telegram bot_token) |
| 9 | `zeroclaw daemon --host 127.0.0.1 --port 8080` |
| 10 | Message your Telegram bot — it responds |
---
## Troubleshooting
- **"command not found: zeroclaw"** — Use full path: `/usr/local/bin/zeroclaw` or ensure `~/.cargo/bin` is in PATH.
- **Telegram not responding** — Check bot_token, allowed_users, and that the Uno Q has internet (WiFi).
- **Out of memory** — Use `--no-default-features` to reduce binary size; consider `compact_context = true`.
- **GPIO commands ignored** — Ensure Bridge app is running (`zeroclaw peripheral setup-uno-q` deploys and starts it). Config must have `board = "arduino-uno-q"` and `transport = "bridge"`.
- **LLM provider (GLM/Zhipu)** — Use `default_provider = "glm"` or `"zhipu"` with `GLM_API_KEY` in env or config. ZeroClaw uses the correct v4 endpoint.

View file

@ -0,0 +1,37 @@
# Arduino Uno
## Pin Aliases
| alias | pin |
|-------------|-----|
| red_led | 13 |
| builtin_led | 13 |
| user_led | 13 |
## Overview
Arduino Uno is a microcontroller board based on the ATmega328P. It has 14 digital I/O pins (013) and 6 analog inputs (A0A5).
## Digital Pins
- **Pins 013:** Digital I/O. Can be INPUT or OUTPUT.
- **Pin 13:** Built-in LED (onboard). Connect LED to GND or use for output.
- **Pins 01:** Also used for Serial (RX/TX). Avoid if using Serial.
## GPIO
- `digitalWrite(pin, HIGH)` or `digitalWrite(pin, LOW)` for output.
- `digitalRead(pin)` for input (returns 0 or 1).
- Pin numbers in ZeroClaw protocol: 013.
## Serial
- UART on pins 0 (RX) and 1 (TX).
- USB via ATmega16U2 or CH340 (clones).
- Baud rate: 115200 for ZeroClaw firmware.
## ZeroClaw Tools
- `gpio_read`: Read pin value (0 or 1).
- `gpio_write`: Set pin high (1) or low (0).
- `arduino_upload`: Agent generates full Arduino sketch code; ZeroClaw compiles and uploads it via arduino-cli. Use for "make a heart", custom patterns — agent writes the code, no manual editing. Pin 13 = built-in LED.

22
docs/datasheets/esp32.md Normal file
View file

@ -0,0 +1,22 @@
# ESP32 GPIO Reference
## Pin Aliases
| alias | pin |
|-------------|-----|
| builtin_led | 2 |
| red_led | 2 |
## Common pins (ESP32 / ESP32-C3)
- **GPIO 2**: Built-in LED on many dev boards (output)
- **GPIO 13**: General-purpose output
- **GPIO 21/20**: Often used for UART0 TX/RX (avoid if using serial)
## Protocol
ZeroClaw host sends JSON over serial (115200 baud):
- `gpio_read`: `{"id":"1","cmd":"gpio_read","args":{"pin":13}}`
- `gpio_write`: `{"id":"1","cmd":"gpio_write","args":{"pin":13,"value":1}}`
Response: `{"id":"1","ok":true,"result":"0"}` or `{"id":"1","ok":true,"result":"done"}`

View file

@ -0,0 +1,16 @@
# Nucleo-F401RE GPIO
## Pin Aliases
| alias | pin |
|-------------|-----|
| red_led | 13 |
| user_led | 13 |
| ld2 | 13 |
| builtin_led | 13 |
## GPIO
Pin 13: User LED (LD2)
- Output, active high
- PA5 on STM32F401

View file

@ -0,0 +1,324 @@
# Hardware Peripherals Design — ZeroClaw
ZeroClaw enables microcontrollers (MCUs) and Single Board Computers (SBCs) to **dynamically interpret natural language commands**, generate hardware-specific code, and execute peripheral interactions in real-time.
## 1. Vision
**Goal:** ZeroClaw acts as a hardware-aware AI agent that:
- Receives natural language triggers (e.g. "Move X arm", "Turn on LED") via channels (WhatsApp, Telegram)
- Fetches accurate hardware documentation (datasheets, register maps)
- Synthesizes Rust code/logic using an LLM (Gemini, local open-source models)
- Executes the logic to manipulate peripherals (GPIO, I2C, SPI)
- Persists optimized code for future reuse
**Mental model:** ZeroClaw = brain that understands hardware. Peripherals = arms and legs it controls.
## 2. Two Modes of Operation
### Mode 1: Edge-Native (Standalone)
**Target:** Wi-Fi-enabled boards (ESP32, Raspberry Pi).
ZeroClaw runs **directly on the device**. The board spins up a gRPC/nanoRPC server and communicates with peripherals locally.
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ZeroClaw on ESP32 / Raspberry Pi (Edge-Native) │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────────────────────┐ │
│ │ Channels │───►│ Agent Loop │───►│ RAG: datasheets, register maps │ │
│ │ WhatsApp │ │ (LLM calls) │ │ → LLM context │ │
│ │ Telegram │ └──────┬───────┘ └─────────────────────────────────┘ │
│ └─────────────┘ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ Code synthesis → Wasm / dynamic exec → GPIO / I2C / SPI → persist ││
│ └─────────────────────────────────────────────────────────────────────────┘│
│ │
│ gRPC/nanoRPC server ◄──► Peripherals (GPIO, I2C, SPI, sensors, actuators) │
└─────────────────────────────────────────────────────────────────────────────┘
```
**Workflow:**
1. User sends WhatsApp: *"Turn on LED on pin 13"*
2. ZeroClaw fetches board-specific docs (e.g. ESP32 GPIO mapping)
3. LLM synthesizes Rust code
4. Code runs in a sandbox (Wasm or dynamic linking)
5. GPIO is toggled; result returned to user
6. Optimized code is persisted for future "Turn on LED" requests
**All happens on-device.** No host required.
### Mode 2: Host-Mediated (Development / Debugging)
**Target:** Hardware connected via USB / J-Link / Aardvark to a host (macOS, Linux).
ZeroClaw runs on the **host** and maintains a hardware-aware link to the target. Used for development, introspection, and flashing.
```
┌─────────────────────┐ ┌──────────────────────────────────┐
│ ZeroClaw on Mac │ USB / J-Link / │ STM32 Nucleo-F401RE │
│ │ Aardvark │ (or other MCU) │
│ - Channels │ ◄────────────────► │ - Memory map │
│ - LLM │ │ - Peripherals (GPIO, ADC, I2C) │
│ - Hardware probe │ VID/PID │ - Flash / RAM │
│ - Flash / debug │ discovery │ │
└─────────────────────┘ └──────────────────────────────────┘
```
**Workflow:**
1. User sends Telegram: *"What are the readable memory addresses on this USB device?"*
2. ZeroClaw identifies connected hardware (VID/PID, architecture)
3. Performs memory mapping; suggests available address spaces
4. Returns result to user
**Or:**
1. User: *"Flash this firmware to the Nucleo"*
2. ZeroClaw writes/flashes via OpenOCD or probe-rs
3. Confirms success
**Or:**
1. ZeroClaw auto-discovers: *"STM32 Nucleo on /dev/ttyACM0, ARM Cortex-M4"*
2. Suggests: *"I can read/write GPIO, ADC, flash. What would you like to do?"*
---
### Mode Comparison
| Aspect | Edge-Native | Host-Mediated |
|------------------|--------------------------------|----------------------------------|
| ZeroClaw runs on | Device (ESP32, RPi) | Host (Mac, Linux) |
| Hardware link | Local (GPIO, I2C, SPI) | USB, J-Link, Aardvark |
| LLM | On-device or cloud (Gemini) | Host (cloud or local) |
| Use case | Production, standalone | Dev, debug, introspection |
| Channels | WhatsApp, etc. (via WiFi) | Telegram, CLI, etc. |
## 3. Legacy / Simpler Modes (Pre-LLM-on-Edge)
For boards without WiFi or before full Edge-Native is ready:
### Mode A: Host + Remote Peripheral (STM32 via serial)
Host runs ZeroClaw; peripheral runs minimal firmware. Simple JSON over serial.
### Mode B: RPi as Host (Native GPIO)
ZeroClaw on Pi; GPIO via rppal or sysfs. No separate firmware.
## 4. Technical Requirements
| Requirement | Description |
|-------------|-------------|
| **Language** | Pure Rust. `no_std` where applicable for embedded targets (STM32, ESP32). |
| **Communication** | Lightweight gRPC or nanoRPC stack for low-latency command processing. |
| **Dynamic execution** | Safely run LLM-generated logic on-the-fly: Wasm runtime for isolation, or dynamic linking where supported. |
| **Documentation retrieval** | RAG (Retrieval-Augmented Generation) pipeline to feed datasheet snippets, register maps, and pinouts into LLM context. |
| **Hardware discovery** | VID/PID-based identification for USB devices; architecture detection (ARM Cortex-M, RISC-V, etc.). |
### RAG Pipeline (Datasheet Retrieval)
- **Index:** Datasheets, reference manuals, register maps (PDF → chunks, embeddings).
- **Retrieve:** On user query ("turn on LED"), fetch relevant snippets (e.g. GPIO section for target board).
- **Inject:** Add to LLM system prompt or context.
- **Result:** LLM generates accurate, board-specific code.
### Dynamic Execution Options
| Option | Pros | Cons |
|-------|------|------|
| **Wasm** | Sandboxed, portable, no FFI | Overhead; limited HW access from Wasm |
| **Dynamic linking** | Native speed, full HW access | Platform-specific; security concerns |
| **Interpreted DSL** | Safe, auditable | Slower; limited expressiveness |
| **Pre-compiled templates** | Fast, secure | Less flexible; requires template library |
**Recommendation:** Start with pre-compiled templates + parameterization; evolve to Wasm for user-defined logic once stable.
## 5. CLI and Config
### CLI Flags
```bash
# Edge-Native: run on device (ESP32, RPi)
zeroclaw agent --mode edge
# Host-Mediated: connect to USB/J-Link target
zeroclaw agent --peripheral nucleo-f401re:/dev/ttyACM0
zeroclaw agent --probe jlink
# Hardware introspection
zeroclaw hardware discover
zeroclaw hardware introspect /dev/ttyACM0
```
### Config (config.toml)
```toml
[peripherals]
enabled = true
mode = "host" # "edge" | "host"
datasheet_dir = "docs/datasheets" # RAG: board-specific docs for LLM context
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
[[peripherals.boards]]
board = "rpi-gpio"
transport = "native"
[[peripherals.boards]]
board = "esp32"
transport = "wifi"
# Edge-Native: ZeroClaw runs on ESP32
```
## 6. Architecture: Peripheral as Extension Point
### New Trait: `Peripheral`
```rust
/// A hardware peripheral that exposes capabilities as tools.
#[async_trait]
pub trait Peripheral: Send + Sync {
fn name(&self) -> &str;
fn board_type(&self) -> &str; // e.g. "nucleo-f401re", "rpi-gpio"
async fn connect(&mut self) -> anyhow::Result<()>;
async fn disconnect(&mut self) -> anyhow::Result<()>;
async fn health_check(&self) -> bool;
/// Tools this peripheral provides (gpio_read, gpio_write, sensor_read, etc.)
fn tools(&self) -> Vec<Box<dyn Tool>>;
}
```
### Flow
1. **Startup:** ZeroClaw loads config, sees `peripherals.boards`.
2. **Connect:** For each board, create a `Peripheral` impl, call `connect()`.
3. **Tools:** Collect tools from all connected peripherals; merge with default tools.
4. **Agent loop:** Agent can call `gpio_write`, `sensor_read`, etc. — these delegate to the peripheral.
5. **Shutdown:** Call `disconnect()` on each peripheral.
### Board Support
| Board | Transport | Firmware / Driver | Tools |
|--------------------|-----------|------------------------|--------------------------|
| nucleo-f401re | serial | Zephyr / Embassy | gpio_read, gpio_write, adc_read |
| rpi-gpio | native | rppal or sysfs | gpio_read, gpio_write |
| esp32 | serial/ws | ESP-IDF / Embassy | gpio, wifi, mqtt |
## 7. Communication Protocols
### gRPC / nanoRPC (Edge-Native, Host-Mediated)
For low-latency, typed RPC between ZeroClaw and peripherals:
- **nanoRPC** or **tonic** (gRPC): Protobuf-defined services.
- Methods: `GpioWrite`, `GpioRead`, `I2cTransfer`, `SpiTransfer`, `MemoryRead`, `FlashWrite`, etc.
- Enables streaming, bidirectional calls, and code generation from `.proto` files.
### Serial Fallback (Host-Mediated, legacy)
Simple JSON over serial for boards without gRPC support:
**Request (host → peripheral):**
```json
{"id":"1","cmd":"gpio_write","args":{"pin":13,"value":1}}
```
**Response (peripheral → host):**
```json
{"id":"1","ok":true,"result":"done"}
```
## 8. Firmware (Separate Repo or Crate)
- **zeroclaw-firmware** or **zeroclaw-peripheral** — a separate crate/workspace.
- Targets: `thumbv7em-none-eabihf` (STM32), `armv7-unknown-linux-gnueabihf` (RPi), etc.
- Uses `embassy` or Zephyr for STM32.
- Implements the protocol above.
- User flashes this to the board; ZeroClaw connects and discovers capabilities.
## 9. Implementation Phases
### Phase 1: Skeleton ✅ (Done)
- [x] Add `Peripheral` trait, config schema, CLI (`zeroclaw peripheral list/add`)
- [x] Add `--peripheral` flag to agent
- [x] Document in AGENTS.md
### Phase 2: Host-Mediated — Hardware Discovery ✅ (Done)
- [x] `zeroclaw hardware discover`: enumerate USB devices (VID/PID)
- [x] Board registry: map VID/PID → architecture, name (e.g. Nucleo-F401RE)
- [x] `zeroclaw hardware introspect <path>`: memory map, peripheral list
### Phase 3: Host-Mediated — Serial / J-Link
- [x] `SerialPeripheral` for STM32 over USB CDC
- [ ] probe-rs or OpenOCD integration for flash/debug
- [x] Tools: `gpio_read`, `gpio_write` (memory_read, flash_write in future)
### Phase 4: RAG Pipeline ✅ (Done)
- [x] Datasheet index (markdown/text → chunks)
- [x] Retrieve-and-inject into LLM context on hardware-related queries
- [x] Board-specific prompt augmentation
**Usage:** Add `datasheet_dir = "docs/datasheets"` to `[peripherals]` in config.toml. Place `.md` or `.txt` files named by board (e.g. `nucleo-f401re.md`, `rpi-gpio.md`). Files in `_generic/` or named `generic.md` apply to all boards. Chunks are retrieved by keyword match and injected into the user message context.
### Phase 5: Edge-Native — RPi ✅ (Done)
- [x] ZeroClaw on Raspberry Pi (native GPIO via rppal)
- [ ] gRPC/nanoRPC server for local peripheral access
- [ ] Code persistence (store synthesized snippets)
### Phase 6: Edge-Native — ESP32
- [x] Host-mediated ESP32 (serial transport) — same JSON protocol as STM32
- [x] `zeroclaw-esp32` firmware crate (`firmware/zeroclaw-esp32`) — GPIO over UART
- [x] ESP32 in hardware registry (CH340 VID/PID)
- [ ] ZeroClaw *on* ESP32 (WiFi + LLM, edge-native) — future
- [ ] Wasm or template-based execution for LLM-generated logic
**Usage:** Flash `firmware/zeroclaw-esp32` to ESP32, add `board = "esp32"`, `transport = "serial"`, `path = "/dev/ttyUSB0"` to config.
### Phase 7: Dynamic Execution (LLM-Generated Code)
- [ ] Template library: parameterized GPIO/I2C/SPI snippets
- [ ] Optional: Wasm runtime for user-defined logic (sandboxed)
- [ ] Persist and reuse optimized code paths
## 10. Security Considerations
- **Serial path:** Validate `path` is in allowlist (e.g. `/dev/ttyACM*`, `/dev/ttyUSB*`); never arbitrary paths.
- **GPIO:** Restrict which pins are exposed; avoid power/reset pins.
- **No secrets on peripheral:** Firmware should not store API keys; host handles auth.
## 11. Non-Goals (For Now)
- Running full ZeroClaw *on* bare STM32 (no WiFi, limited RAM) — use Host-Mediated instead
- Real-time guarantees — peripherals are best-effort
- Arbitrary native code execution from LLM — prefer Wasm or templates
## 12. Related Documents
- [adding-boards-and-tools.md](./adding-boards-and-tools.md) — How to add boards and datasheets
- [network-deployment.md](./network-deployment.md) — RPi and network deployment
## 13. References
- [Zephyr RTOS Rust support](https://docs.zephyrproject.org/latest/develop/languages/rust/index.html)
- [Embassy](https://embassy.dev/) — async embedded framework
- [rppal](https://github.com/golemparts/rppal) — Raspberry Pi GPIO in Rust
- [STM32 Nucleo-F401RE](https://www.st.com/en/evaluation-tools/nucleo-f401re.html)
- [tonic](https://github.com/hyperium/tonic) — gRPC for Rust
- [probe-rs](https://probe.rs/) — ARM debug probe, flash, memory access
- [nusb](https://github.com/nic-hartley/nusb) — USB device enumeration (VID/PID)
## 14. Raw Prompt Summary
> *"Boards like ESP, Raspberry Pi, or boards with WiFi can connect to an LLM (Gemini or open-source). ZeroClaw runs on the device, creates its own gRPC, spins it up, and communicates with peripherals. User asks via WhatsApp: 'move X arm' or 'turn on LED'. ZeroClaw gets accurate documentation, writes code, executes it, stores it optimally, runs it, and turns on the LED — all on the development board.*
>
> *For STM Nucleo connected via USB/J-Link/Aardvark to my Mac: ZeroClaw from my Mac accesses the hardware, installs or writes what it wants on the device, and returns the result. Example: 'Hey ZeroClaw, what are the available/readable addresses on this USB device?' It can figure out what's connected where and suggest."*

182
docs/network-deployment.md Normal file
View file

@ -0,0 +1,182 @@
# Network Deployment — ZeroClaw on Raspberry Pi and Local Network
This document covers deploying ZeroClaw on a Raspberry Pi or other host on your local network, with Telegram and optional webhook channels.
---
## 1. Overview
| Mode | Inbound port needed? | Use case |
|------|----------------------|----------|
| **Telegram polling** | No | ZeroClaw polls Telegram API; works from anywhere |
| **Discord/Slack** | No | Same — outbound only |
| **Gateway webhook** | Yes | POST /webhook, WhatsApp, etc. need a public URL |
| **Gateway pairing** | Yes | If you pair clients via the gateway |
**Key:** Telegram, Discord, and Slack use **long-polling** — ZeroClaw makes outbound requests. No port forwarding or public IP required.
---
## 2. ZeroClaw on Raspberry Pi
### 2.1 Prerequisites
- Raspberry Pi (3/4/5) with Raspberry Pi OS
- USB peripherals (Arduino, Nucleo) if using serial transport
- Optional: `rppal` for native GPIO (`peripheral-rpi` feature)
### 2.2 Install
```bash
# Build for RPi (or cross-compile from host)
cargo build --release --features hardware
# Or install via your preferred method
```
### 2.3 Config
Edit `~/.zeroclaw/config.toml`:
```toml
[peripherals]
enabled = true
[[peripherals.boards]]
board = "rpi-gpio"
transport = "native"
# Or Arduino over USB
[[peripherals.boards]]
board = "arduino-uno"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
[channels_config.telegram]
bot_token = "YOUR_BOT_TOKEN"
allowed_users = ["*"]
[gateway]
host = "127.0.0.1"
port = 8080
allow_public_bind = false
```
### 2.4 Run Daemon (Local Only)
```bash
zeroclaw daemon --host 127.0.0.1 --port 8080
```
- Gateway binds to `127.0.0.1` — not reachable from other machines
- Telegram channel works: ZeroClaw polls Telegram API (outbound)
- No firewall or port forwarding needed
---
## 3. Binding to 0.0.0.0 (Local Network)
To allow other devices on your LAN to hit the gateway (e.g. for pairing or webhooks):
### 3.1 Option A: Explicit Opt-In
```toml
[gateway]
host = "0.0.0.0"
port = 8080
allow_public_bind = true
```
```bash
zeroclaw daemon --host 0.0.0.0 --port 8080
```
**Security:** `allow_public_bind = true` exposes the gateway to your local network. Only use on trusted LANs.
### 3.2 Option B: Tunnel (Recommended for Webhooks)
If you need a **public URL** (e.g. WhatsApp webhook, external clients):
1. Run gateway on localhost:
```bash
zeroclaw daemon --host 127.0.0.1 --port 8080
```
2. Start a tunnel:
```toml
[tunnel]
provider = "tailscale" # or "ngrok", "cloudflare"
```
Or use `zeroclaw tunnel` (see tunnel docs).
3. ZeroClaw will refuse `0.0.0.0` unless `allow_public_bind = true` or a tunnel is active.
---
## 4. Telegram Polling (No Inbound Port)
Telegram uses **long-polling** by default:
- ZeroClaw calls `https://api.telegram.org/bot{token}/getUpdates`
- No inbound port or public IP needed
- Works behind NAT, on RPi, in a home lab
**Config:**
```toml
[channels_config.telegram]
bot_token = "YOUR_BOT_TOKEN"
allowed_users = ["*"] # or specific @usernames / user IDs
```
Run `zeroclaw daemon` — Telegram channel starts automatically.
---
## 5. Webhook Channels (WhatsApp, Custom)
Webhook-based channels need a **public URL** so Meta (WhatsApp) or your client can POST events.
### 5.1 Tailscale Funnel
```toml
[tunnel]
provider = "tailscale"
```
Tailscale Funnel exposes your gateway via a `*.ts.net` URL. No port forwarding.
### 5.2 ngrok
```toml
[tunnel]
provider = "ngrok"
```
Or run ngrok manually:
```bash
ngrok http 8080
# Use the HTTPS URL for your webhook
```
### 5.3 Cloudflare Tunnel
Configure Cloudflare Tunnel to forward to `127.0.0.1:8080`, then set your webhook URL to the tunnel's public hostname.
---
## 6. Checklist: RPi Deployment
- [ ] Build with `--features hardware` (and `peripheral-rpi` if using native GPIO)
- [ ] Configure `[peripherals]` and `[channels_config.telegram]`
- [ ] Run `zeroclaw daemon --host 127.0.0.1 --port 8080` (Telegram works without 0.0.0.0)
- [ ] For LAN access: `--host 0.0.0.0` + `allow_public_bind = true` in config
- [ ] For webhooks: use Tailscale, ngrok, or Cloudflare tunnel
---
## 7. References
- [hardware-peripherals-design.md](./hardware-peripherals-design.md) — Peripherals design
- [adding-boards-and-tools.md](./adding-boards-and-tools.md) — Hardware setup and adding boards

147
docs/nucleo-setup.md Normal file
View file

@ -0,0 +1,147 @@
# ZeroClaw on Nucleo-F401RE — Step-by-Step Guide
Run ZeroClaw on your Mac or Linux host. Connect a Nucleo-F401RE via USB. Control GPIO (LED, pins) via Telegram or CLI.
---
## Get Board Info via Telegram (No Firmware Needed)
ZeroClaw can read chip info from the Nucleo over USB **without flashing any firmware**. Message your Telegram bot:
- *"What board info do I have?"*
- *"Board info"*
- *"What hardware is connected?"*
- *"Chip info"*
The agent uses the `hardware_board_info` tool to return chip name, architecture, and memory map. With the `probe` feature, it reads live data via USB/SWD; otherwise it returns static datasheet info.
**Config:** Add Nucleo to `config.toml` first (so the agent knows which board to query):
```toml
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
```
**CLI alternative:**
```bash
cargo build --features hardware,probe
zeroclaw hardware info
zeroclaw hardware discover
```
---
## What's Included (No Code Changes Needed)
ZeroClaw includes everything for Nucleo-F401RE:
| Component | Location | Purpose |
|-----------|----------|---------|
| Firmware | `firmware/zeroclaw-nucleo/` | Embassy Rust — USART2 (115200), gpio_read, gpio_write |
| Serial peripheral | `src/peripherals/serial.rs` | JSON-over-serial protocol (same as Arduino/ESP32) |
| Flash command | `zeroclaw peripheral flash-nucleo` | Builds firmware, flashes via probe-rs |
Protocol: newline-delimited JSON. Request: `{"id":"1","cmd":"gpio_write","args":{"pin":13,"value":1}}`. Response: `{"id":"1","ok":true,"result":"done"}`.
---
## Prerequisites
- Nucleo-F401RE board
- USB cable (USB-A to Mini-USB; Nucleo has built-in ST-Link)
- For flashing: `cargo install probe-rs-tools --locked` (or use the [install script](https://probe.rs/docs/getting-started/installation/))
---
## Phase 1: Flash Firmware
### 1.1 Connect Nucleo
1. Connect Nucleo to your Mac/Linux via USB.
2. The board appears as a USB device (ST-Link). No separate driver needed on modern systems.
### 1.2 Flash via ZeroClaw
From the zeroclaw repo root:
```bash
zeroclaw peripheral flash-nucleo
```
This builds `firmware/zeroclaw-nucleo` and runs `probe-rs run --chip STM32F401RETx`. The firmware runs immediately after flashing.
### 1.3 Manual Flash (Alternative)
```bash
cd firmware/zeroclaw-nucleo
cargo build --release --target thumbv7em-none-eabihf
probe-rs run --chip STM32F401RETx target/thumbv7em-none-eabihf/release/zeroclaw-nucleo
```
---
## Phase 2: Find Serial Port
- **macOS:** `/dev/cu.usbmodem*` or `/dev/tty.usbmodem*` (e.g. `/dev/cu.usbmodem101`)
- **Linux:** `/dev/ttyACM0` (or check `dmesg` after plugging in)
USART2 (PA2/PA3) is bridged to the ST-Link's virtual COM port, so the host sees one serial device.
---
## Phase 3: Configure ZeroClaw
Add to `~/.zeroclaw/config.toml`:
```toml
[peripherals]
enabled = true
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/cu.usbmodem101" # adjust to your port
baud = 115200
```
---
## Phase 4: Run and Test
```bash
zeroclaw daemon --host 127.0.0.1 --port 8080
```
Or use the agent directly:
```bash
zeroclaw agent --message "Turn on the LED on pin 13"
```
Pin 13 = PA5 = User LED (LD2) on Nucleo-F401RE.
---
## Summary: Commands
| Step | Command |
|------|---------|
| 1 | Connect Nucleo via USB |
| 2 | `cargo install probe-rs --locked` |
| 3 | `zeroclaw peripheral flash-nucleo` |
| 4 | Add Nucleo to config.toml (path = your serial port) |
| 5 | `zeroclaw daemon` or `zeroclaw agent -m "Turn on LED"` |
---
## Troubleshooting
- **flash-nucleo unrecognized** — Build from repo: `cargo run --features hardware -- peripheral flash-nucleo`. The subcommand is only in the repo build, not in crates.io installs.
- **probe-rs not found**`cargo install probe-rs-tools --locked` (the `probe-rs` crate is a library; the CLI is in `probe-rs-tools`)
- **No probe detected** — Ensure Nucleo is connected. Try another USB cable/port.
- **Serial port not found** — On Linux, add user to `dialout`: `sudo usermod -a -G dialout $USER`, then log out/in.
- **GPIO commands ignored** — Check `path` in config matches your serial port. Run `zeroclaw peripheral list` to verify.