Metadata-Version: 2.4
Name: strands-nicla
Version: 0.1.0
Summary: @tool decorated Arduino Nicla (Vision/Sense/Voice) control for Strands Agents
Author: cagataycali
License: MIT
Project-URL: Homepage, https://github.com/cagataycali/strands-nicla
Project-URL: Issues, https://github.com/cagataycali/strands-nicla/issues
Keywords: strands,agent,arduino,nicla,vision,sense,voice,openmv,micropython,devduck,llm-tools
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Hardware
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: strands-agents
Requires-Dist: pyserial>=3.5
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Provides-Extra: vision
Requires-Dist: Pillow>=10; extra == "vision"
Provides-Extra: mpremote
Requires-Dist: mpremote>=1.22; extra == "mpremote"
Dynamic: license-file

# 🌀 strands-nicla

**Arduino Nicla (Vision / Sense / Voice) control as a single `@tool` for Strands Agents.**

```python
from strands import Agent
from strands_nicla import nicla

agent = Agent(tools=[nicla])
agent("take a photo with the nicla vision and tell me what you see")
```

## What it does

Nicla **Vision** runs **MicroPython / OpenMV firmware** and exposes a USB CDC
serial REPL. `strands-nicla` wraps that REPL into Strands-friendly actions:

> **Nicla Voice does not.** A factory Voice enumerates as a CMSIS-DAP debug
> probe with a silent CDC port — no REPL, so `exec`/`ls`/`put` time out by
> design. It is a BLE-gateway device, not a REPL device. See
> [NICLA_VOICE.md](NICLA_VOICE.md).

| category     | actions |
|--------------|---------|
| **devices**  | `list_devices`, `select_device`, `info`, `reset(hard)`, `stop` |
| **repl**     | `exec`, `eval` |
| **fs**       | `ls`, `cat`, `put`, `get`, `rm`, `mkdir`, `run_file` |
| **vision**   | `snapshot` (JPEG → Converse image block, quality ladder for low light) |
| **sensors**  | `imu` (built-in SPI module first), `env`, `distance`, `mic_level` |
| **tiny**     | `provision` — write tiny.technology identity/WiFi to `/flash/tiny.json` over USB |
| **firmware** | `boot_mode`, `flash` (DFU) |

## The tiny necklace (firmware/ + hardware/)

This repo also carries the **tiny.technology wearable** built on Nicla Vision:

- `firmware/` — MicroPython device firmware: first-boot WiFi-AP portal,
  BLE GATT provisioning (pairs with the tiny iOS/Android apps' Nearby → 💎
  "Set up" flow), and the device-node loop (heartbeat + relay poll + commands:
  `photo`, `detect` person, `faces` FOMO, `distance`, `imu`, `info` — vision
  models run on-device from the QSPI romfs, ~48ms/inference).
- `hardware/` — flash map, measured board geometry, official docs/CAD, and the
  parametric pendant case (`tiny_necklace_case.scad`, USB-powered or
  `battery=true` LiPo variant), sliced plates for Bambu Lab X2D.
- `tests/` — the firmware's pure logic runs under CPython with hardware stubs.

See [hardware/README.md](./hardware/README.md) for the full device state,
provisioning paths, and MicroPython/OpenMV gotchas learned the hard way.
**Ops rule:** `reset(hard=True)` launches `main.py`; a soft reset with a
terminal attached drops to the REPL. Keep the OpenMV USB volume ejected
(`diskutil unmount "/Volumes/NO NAME"`) or macOS will corrupt `/flash`.

## Install

```bash
pip install strands-nicla

# or inject into devduck:
pipx inject devduck strands-nicla
```

## Supported boards

- Arduino **Nicla Vision** — STM32H747 + 2MP cam + mic + IMU + ToF
- Arduino **Nicla Sense ME** — nRF52832 + BHI260AP + BMM150 + BMP390 + BME688
- Arduino **Nicla Voice** — nRF52832 + NDP120 + IM69D130 mic + BMI270

All three expose a USB CDC port, but only Nicla Vision answers on it out of the
box. **Nicla Voice ships as a CMSIS-DAP debug probe (`2341:0065`) whose CDC port
returns nothing** — verified on hardware at 9600/115200/921600 with both `\r\n`
and Ctrl-C. It has no WiFi either (nRF52832), so it cannot run the Vision's
heartbeat/relay node loop; a phone acts as its BLE gateway. Nicla Sense ME runs
MbedOS and can also speak MicroPython via `mpremote`.

## Principles

- **Mirror strands-adb / strands-ios** action vocabulary where sensible.
- **Honest errors** — if the board doesn't support an action, say so.
- **Vision-first** — `snapshot` returns Converse API image blocks.
- **No extra daemons** — pure pyserial + MicroPython raw REPL protocol.

## Status

v0.1 — alpha. See [GOAL.md](./GOAL.md).
