Releases: rokbenko/quackd
Release list
v0.4.0 "adapters" — a brain for any small robot
quackd now drives four robots, and each one decides for itself what quackd may ask of it. Every robot is an adapter that hands over a manifest — this is what I am, this is what I can do — and the verbs the model is offered are built from that manifest and nothing else. The thesis does not change: the LLM picks verbs, the robot's own controllers move, quackd enforces the contract.
A head that cannot walk and a duck that cannot judge its own kick, finishing one task under one contract. Simulator, scripted pilots, zero planner LLM calls.
Highlights
- A verb that is not in the manifest does not exist — not in the registry, not in the MCP tool list, not in
.duckvalidation, not in the prompt. Every robot is aRobotAdapterthat returns aRobotManifestfromconnect(), anddefault_registry()is now just the Microduck's manifest compiled into verbs. Eight core verbs (observe,report_state,stop,say,move,go_to,search_scan,approach_and) exist only on a body whose manifest meets their requirements — a camera forobserve, thetwistintent and mobility formove— and declaring one the body cannot support makes the manifest refuse to build.get_frame,walk_toandwalkare permanent aliases in one table, so every 0.3.duckfile still runs unchanged (ADR-0017, ADR-0018). Write one in a day: docs/adapters.md, docs/manifest-spec.md. - Four adapters, eleven backends, one flag.
--robot <adapter>:<backend>onrun,validate,serve-mcp,doctorandlist-verbs:microduck(sim2d, mock, jsonrpc, websocket),reachy_mini(sim2d, mock, sdk),lerobot(mock, real),rosbridge(mock, ws) — one of the eleven is still a stub that raises with a link. Because the manifest decides the vocabulary, it is fifteen verbs on a Microduck, nine on a Reachy Mini head, seven on an SO-101 class arm with a camera and a pick policy, seven on a wheeled base with a camera topic: a head is never offeredkick, an arm is never offeredmove, andmove/go_toclamp to the speed limits the manifest names.--transport Xstill works as--robot microduck:X, warns once per process, and is gone in 0.5. Per-backend honesty table: docs/adapter-status.md. - A head and a duck finish one task together.
reachy-spots-duck-kicks: a stationary Reachy Mini spots the ball and judges the kick from its own fresh frames, a Microduck approaches and kicks with its own legs, and the actor never gets to claim success — only the spotter'sVERDICT, with the simulator's ground truth as a veto on top. Members are adapters sharing one arena and one lockstep clock, bids carry a capability term so a robot only bids for a role its manifest can fill, and a single auction fills every role. 10 of 10 seeds with the scripted pilots, zero planner LLM calls, every message inflock.jsonl. Simulator only, and the frame-of-reference limitation is written down rather than papered over (ADR-0020): docs/flock.md. .duckv1 makes "wrong robot" a validation error instead of a runtime failure.requires,robotsandflock.roles; v0 files parse unchanged and the bundled starters stay atduck: 0.quackd validate find-and-kick --robot reachy_mini:sim2dprintsrequires kick, but reachy-01 (reachy-mini) does not provide itand exits 1 before anything connects (ADR-0019): docs/duck-spec.md.- MCP fronts a fleet.
serve-mcp --robots duck=microduck:sim2d,reachy=reachy_mini:mockexposes sixrobot_*tools (robot_list,robot_list_verbs,robot_run_verb,robot_observe,robot_say,robot_load_duckfile), each robot with its own executor, budget, heartbeat and contract, androbot_load_duckfilechecks a contract'srequiresagainst that robot's manifest before adopting it. The eightduck_*tools remain as deprecated aliases of the default robot — 14 tools in all — and go away in 0.5. Every simulated robot over MCP gets its own world; a shared arena over MCP is future work: docs/mcp.md. - Also in 0.4: LAN discovery (
quackd discover/quackd announceover zeroconf, an identity-only TXT record checked under 200 bytes per pair) and an MQTT flock bus behind the same two-methodBusprotocol, both behindquackd[lan], both imported lazily, both library-only (ADR-0021, docs/lan.md); ADRs 0017 to 0023 and a page per adapter; goldens recorded from 0.3 that prove the seeded worlds, the starter ducks and theflock-kickconversation did not move; 360 tests, no network, no keys, and four seeded sweeps that CI holds at 10 of 10.
Nothing here has run on hardware, on any of the four bodies. What the demos and the sweeps use is microduck:sim2d, reachy_mini:sim2d and the mocks. The four SDK backends — microduck:jsonrpc, reachy_mini:sdk, lerobot:real, rosbridge:ws — are experimental in the strict sense: every upstream method, topic, socket and message name is read from pinned upstream source and marked VERIFIED or UNVERIFIED in one file per adapter, a test proves UNVERIFIED names are reachable only from those backends, and each has been exercised against fakes and nothing else. microduck:websocket is a stub that raises with links until upstream ships it. The Microduck arrives Christmas 2026; Reachy Mini hardware exists today and we do not have one. The LAN pieces are thinner still: zeroconf was exercised once for real between two processes on one machine, the MQTT bus once against a local amqtt broker on that same machine, and never between two machines — a flock across machines also needs a clock across machines, which does not exist yet, which is why there is no --bus flag.
uvx quackd run reachy-spots-duck-kicks --provider fake # two bodies, one contract, no API key
uvx quackd run reachy-spotter --provider fake # a Reachy Mini head, no legs, same loop
uvx quackd list-adapters # four adapters, eleven backends
uvx quackd validate find-and-kick --robot reachy_mini:sim2d # "requires kick, but reachy-01 (reachy-mini) does not provide it"
claude mcp add quackd -- uvx quackd serve-mcp --robots duck=microduck:sim2d,reachy=reachy_mini:mockquackd is an independent community project, not affiliated with or endorsed by Pollen Robotics, Hugging Face or Open Robotics.
Full changelog: v0.3.0...v0.4.0
v0.3.0 "flock" — ducks that cooperate (in the simulator)
Multiple simulated Microducks can now talk to each other and divide up a job, limited only by the skills each duck already has. The first choreography ships in this release: split the search, hold an auction, the closest duck kicks, and every message is on the record.
Highlights
- Flock mode: add a
flock:block to a.duckfile or pass--flock Nto put multiple ducks in one shared arena. They coordinate over an in-process message bus with typed messages (TASK, BID, CLAIM, ROLE, HB, RESULT), acting only through the verbs each duck already has, so the machinery is task-agnostic and the kick is simply the first choreography built on it (the target label is configurable). A deterministic Contract Net auction awards the claim from each duck's own camera distance estimate (20 % hysteresis, 6 s claim lease, one claimant lock, sim-time watchdog), and every message, bid, claim and role change lands inflock.jsonl. Guide: docs/flock.md, ADR-0015. - Multi-duck simulator:
World(n_ducks=…)with per-duck noise streams, duck-duck collisions and the four Microduck colorways. A lockstep clock freezes the world while any pilot thinks, so single-duck runs stay bit-identical per seed (ADR-0016). - One LLM call at most: the planner may tune task parameters through a single forced tool call, clamped per field with a deterministic fallback.
--provider fakecomputes the plan as a pure function.summary.jsonrecordsllm_callsas proof. - Ground truth everywhere: the outcome is judged from sim telemetry, not a model claim, and duck-duck separation is watched from world ground truth while a claim is live.
- Before release the flock diff went through an adversarial review (69 agents, 24 confirmed findings, all fixed): deadlock guards on the shared clock, per-duck budget enforcement, watchdog floors, cooldown gating at bid time and more. Details in the CHANGELOG.
Sim only, honestly labelled: one choreography ships today, and nothing multi-duck has run on hardware (Microducks ship Christmas 2026). More choreographies over the same bus and roles are the roadmap, not the release.
uvx quackd run flock-kick --provider fake --seed 3Full changelog: v0.2.0...v0.3.0
quackd v0.2.0 — local and open-source LLMs can pilot the duck
Local and open source LLMs can now pilot the duck. Ollama, vLLM, llama.cpp, LM Studio, or any OpenAI compatible server. No API key.
uvx --from "quackd[openai]" quackd run find-and-kick --provider ollama --model qwen3:8b
uvx --from "quackd[openai]" quackd run find-and-kick --provider vllm --model Qwen/Qwen3-8B
uvx --from "quackd[openai]" quackd run find-and-kick --provider local --base-url http://gpu-box:8000/v1
uvx quackd run --goal "find the ball and kick it" --provider fake # still no key, scripted pilotAdded
- Local providers
ollama,vllm,llamacpp,lmstudio,local(--base-url). Model discovery from/v1/modelswhen--modelis omitted,tool_choice=autoand noparallel_tool_callsfield for picky servers (QUACKD_TOOL_CHOICEto override), vision opt-in with--vision, and a JSON text fallback that understands a tool call a small model wrote as plain text (markedtext_fallbackin the transcript).quackd doctorprobes the four default local addresses. Guide:docs/local-llms.md. (ADR-0014) quackd run --goal "...": a plain language goal instead of a.duckfile. The scriptedfakepilot picks a strategy from the goal's keywords.--base-url,--api-key,--vision/--no-vision,--gif-size.- New README written for first time readers, a Microduck-like logo and a social preview card.
Changed
- Providers are named by company, not model family ("OpenAI"). Hero GIF re-recorded at 320 px panes.
Fixed
- Rich markup ate
quackd[extra]in CLI error hints. mypy on Python 3.12 (numpy stubs).
Known limitations
- Local model quality is unmeasured and we have not run a live local server ourselves yet. If you do, please share the transcript in Discussions.
- The simulator is a cartoon and nothing has run on a real Microduck. The hero GIF is the scripted pilot.
Full changelog: CHANGELOG.md. quackd is an independent community project, not affiliated with or endorsed by Pollen Robotics or Hugging Face.
quackd v0.1.0 — Give your Microduck a brain
Give a small robot a brain. Tell the Microduck what you want in plain language; an LLM uses the robot's existing skills to do it. First release: sim-first, honest about hardware.
uvx quackd run --goal "find the ball and kick it" --provider fake # no key, built-in simulator
uvx --from "quackd[anthropic]" quackd run find-and-kick --provider anthropic # with Claude
claude mcp add quackd -- uvx quackd serve-mcp --transport sim2d # drive it from Claude CodeWhat's in 0.1.0
.ducktask files — strict, validated frontmatter (allowlist, budgets, confirm gates, abort rules) + a Markdown body the model reads; five starters bundled;quackd run --goal "…"for ad-hoc goals.- 13 verbs — ten built-in (
walk sit stand kick grab stand_up stop quack gaze get_frame) mapping 1:1 to the robot's shipped behaviours, three composite (search_scan walk_to approach_and), and a reserved interface for learned verbs. - Safety executor — allowlist, confirm gates, budgets, dry-run, machine-enforced
abort_when, heartbeat, kill switch. Same layer for.duckruns and MCP sessions. - Built-in 2D simulator — deterministic under
--seed, upstream-style deadman, top-down + duck-cam renders, GIF + transcript per run;find-and-kicksucceeds on 10/10 seeds. - Providers — Claude (
claude-opus-5), OpenAI, Gemini, Grok, and a scriptedfake; vendor SDKs are optional extras. - MCP server —
quackd serve-mcpfor Claude Code / Claude Desktop, verified client config indocs/mcp.md. - Real robot — experimental
jsonrpctransport with method names verified against upstreamduck-ipc-protov16; never run on hardware yet. WebSocket transport is a stub tracking upstream's draft. quackd doctor,quackd validate,quackd list-verbs,quackd record; 124 tests, no network, no keys.
Known limitations
- The simulator is a cartoon (it tests the agent loop, not physics); nothing has run on a real Microduck.
- The hero GIF is the scripted pilot — a real-model recording is one command away once a key is available.
- Default model IDs for OpenAI / Gemini / Grok are unverified; override with
QUACKD_MODEL.
Full changelog: CHANGELOG.md. quackd is an independent community project, not affiliated with or endorsed by Pollen Robotics or Hugging Face.

