[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-83386":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":15,"stars7d":16,"stars30d":16,"stars90d":14,"forks30d":14,"starsTrendScore":17,"compositeScore":18,"rankGlobal":9,"rankLanguage":9,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":20,"topics":22,"createdAt":9,"pushedAt":9,"updatedAt":36,"readmeContent":37,"aiSummary":9,"trendingCount":14,"starSnapshotCount":14,"syncStatus":38,"lastSyncTime":39,"discoverSource":40},83386,"edge-agents","ForestHubAI\u002Fedge-agents","ForestHubAI","The 30 MB open-source AI agent runtime for edge devices. Offline by default — GPIO, UART, MQTT as first-class nodes. Industrial protocols (OPC-UA, Modbus) on the roadmap.",null,"TypeScript",75,29,18,0,1,20,7,4.43,"GNU Affero General Public License v3.0",false,"main",[23,5,24,25,26,27,28,29,30,31,32,33,34,35],"ai-agents","edge-ai","edge-computing","edge-devices","embedded","embedded-agents","golang","iot","llm","mqtt","raspberry-pi","react","slm","2026-06-12 02:04:33","# edge-agents\n\n**The 30 MB open-source AI agent runtime for edge devices.**\n\n[![CI](https:\u002F\u002Fgithub.com\u002FForestHubAI\u002Fedge-agents\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002FForestHubAI\u002Fedge-agents\u002Factions\u002Fworkflows\u002Fci.yml)\n[![Go Reference](https:\u002F\u002Fpkg.go.dev\u002Fbadge\u002Fgithub.com\u002FForestHubAI\u002Fedge-agents\u002Fgo.svg)](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002FForestHubAI\u002Fedge-agents\u002Fgo)\n[![License: AGPL v3](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-AGPL_v3-blue.svg)](LICENSE)\n\n![edge-agents demo](docs\u002Fassets\u002Fhero.gif)\n\n> *Build an edge agent visually, deploy it to a Raspberry Pi, and let it talk to GPIO, MQTT and local SLMs — no cloud required.*\n\nOffline by default. GPIO, UART, MQTT as first-class nodes. Local SLMs alongside cloud LLMs in the same workflow. Industrial protocols (OPC-UA, Modbus) are on the roadmap.\n\n**Runs on** Raspberry Pi 5 · Jetson Orin Nano · STM32MP25 · Bosch Rexroth ctrlX CORE.\n\n⭐ **Star the repo** if you think AI agents belong beyond the cloud.\n\n> Today's AI agents live in datacenters. The interesting workloads — sensors, machines, vehicles, gateways — live everywhere else. **edge-agents** brings the agent paradigm to the devices that interact with the real world: small enough to run on a Pi 5, capable enough to drive an industrial controller, with hardware I\u002FO as native primitives instead of REST shims.\n\n## What you can build\n\n- **Voice assistant on a Pi with a local SLM** — wake-word → STT → agent → TTS, no internet required\n- **Predictive maintenance on industrial gear** — live vibration stream over MQTT → LLM decides → MQTT alert\n- **Local RAG on a Jetson** *(on the roadmap)* — answers grounded in live sensor and machine state instead of the public web (today the retriever runs against an external backend; a fully on-device RAG path is in progress)\n\n## edge-agents vs other agent frameworks\n\n|                                             | edge-agents             | n8n             | LangGraph        | Dify           | OpenClaw           |\n| ------------------------------------------- | ----------------------- | --------------- | ---------------- | -------------- | ------------------ |\n| **Runtime size**                            | ~30 MB container        | ~500 MB Docker  | Python library   | ~500 MB Docker | ~1 GB Docker       |\n| **Offline by default**                      | ✅                      | ❌              | depends on host  | ❌             | ❌ datacenter-only |\n| **Hardware I\u002FO (GPIO, UART, ADC) as nodes** | ✅ first-class          | ❌              | ❌               | ❌             | ❌                 |\n| **On-device SLM provider**                  | ✅ typed multi-endpoint | ❌              | partial via libs | ❌             | ❌                 |\n| **MQTT as workflow transport**              | ✅ first-class          | community node  | ❌               | ❌             | ❌                 |\n| **Visual builder**                          | ✅                      | ✅              | ❌ code-only     | ✅             | ❌                 |\n| **Industrial protocols** (OPC-UA, Modbus)   | on roadmap              | community nodes | ❌               | ❌             | ❌                 |\n\n---\n\n# Using edge-agents\n\nTwo pieces: the **engine** (a small container that runs your workflows) and the\n**`fh-workflow` CLI** (authors, validates, and visually edits workflow files). You can\nrun the engine without ever cloning this repo, and author workflows with a single\n`npm i -g @foresthubai\u002Fworkflow-cli`.\n\n## Quickstart\n\nThe lightest path needs no clone and no Docker — just the CLI and the visual builder:\n\n```sh\nnpm i -g @foresthubai\u002Fworkflow-cli\nfh-workflow open my.workflow.json      # opens the visual builder; Save writes back to the file\n```\n\nDon't have a workflow yet? Let Claude Code write one from a single sentence — see\n[Generate workflows with Claude Code](#generate-workflows-with-claude-code). Ready to run\nit on real hardware? [Run the engine](#run-the-engine) on the device.\n\n## Run the engine\n\nThe engine ships as a small container you build from [`go\u002FDockerfile`](go\u002FDockerfile)\n(multi-arch, distroless, nonroot). Most edge targets are `arm64` (Pi, Jetson, STM32MP2,\nctrlX), so the common flow is to cross-build on an `amd64` workstation and ship the\nresult to the device:\n\n```sh\ncd go\n\n# Cross-build for an arm64 edge device (use --platform linux\u002Famd64 for x86 targets)\ndocker buildx build --platform linux\u002Farm64 -t edge-agents\u002Fengine:arm64 --load .\n\n# Ship to an offline device: save to a tar, copy it across, load it there\ndocker save edge-agents\u002Fengine:arm64 -o edge-agents-engine-arm64.tar\n#   scp edge-agents-engine-arm64.tar device:\u002Ftmp\u002F   ← then, on the device:\ndocker load -i edge-agents-engine-arm64.tar\ndocker run --rm -p 8081:8081 edge-agents\u002Fengine:arm64\n```\n\nBuilding for the same architecture you're already on? A plain\n`docker build -t edge-agents\u002Fengine:dev .` works too — the Dockerfile cross-compiles via\n`TARGETARCH`, so QEMU only emulates the trivial copy into the final layer.\n\nThe engine HTTP API listens on `:8081` **on all interfaces**. It runs **standalone by\ndefault** — no control plane, no account, no outbound calls beyond LLM provider APIs.\nThe deploy API is gated by a bearer token: set `ENGINE_SECRET` to enable `\u002Fdeploy` and\n`\u002Fstop` (without it those endpoints are closed and you load a workflow via\n`ENGINE_CONFIG_FILE` instead). `:8081` is meant to sit behind your own network controls,\nnot face the public internet. Configure via `ENGINE_*` env vars; see\n[`go\u002Fcmd\u002Fengine\u002Fconfig.go`](go\u002Fcmd\u002Fengine\u002Fconfig.go).\n\n**Hardware access:** the image runs as a nonroot distroless user, so reaching real GPIO,\nserial or analog devices needs them passed into the container with the right group — e.g.\n`--device \u002Fdev\u002Fgpiochip0 --group-add \"$(stat -c '%g' \u002Fdev\u002Fgpiochip0)\"` (or run with\n`--privileged` on a throwaway dev box). Pure-software workflows need none of this.\n\n## Author workflows\n\nA workflow is a `*.workflow.json` file you author, validate, and open in the visual\nbuilder. Install the `fh-workflow` CLI from npm — no clone required:\n\n```sh\nnpm i -g @foresthubai\u002Fworkflow-cli\n# or run it without installing:\nnpx @foresthubai\u002Fworkflow-cli \u003Ccommand>\n```\n\n```sh\nfh-workflow open my.workflow.json          # open the visual builder; Save writes back to the file\nfh-workflow validate my.workflow.json      # semantic: wiring, references, types\nfh-workflow check-schema my.workflow.json  # structural: types, required fields, enums\nfh-workflow update my.workflow.json        # migrate a workflow to the current schema version\nfh-workflow help                           # list all commands\n```\n\n`fh-workflow open` _is_ the visual builder — the same React Flow canvas, served locally;\nhit Save and it writes straight back to your file. See [`ts\u002Fworkflow-cli`](ts\u002Fworkflow-cli)\nfor the full command reference and the `--static` \u002F `--dev` open modes.\n\n## Generate workflows with Claude Code\n\nDescribe a workflow in plain language and the **`workflow-generate`** skill writes the\n`*.workflow.json` and runs the validators for you. Install it into any project with the\n[`skills`](https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fskills) CLI — no clone required:\n\n```sh\nnpx skills add ForestHubAI\u002Fedge-agents --skill workflow-generate\n```\n\nThe skill validates by shelling out to the `fh-workflow` CLI, so install that too\n(`npm i -g @foresthubai\u002Fworkflow-cli`). Then just describe a workflow — e.g.\n_\"read a sensor every 10s and toggle a relay\"_ — and the skill generates and validates\nthe file for you.\n\n## Deploy a workflow to a device\n\nA workflow is **binding-free**: it declares _what_ it needs — channels (GPIO, MQTT, …)\nand custom models — but not _where_ those live on a given device. You supply the _where_\nthrough a few small config files mounted into the engine container alongside the\nworkflow. See [`go\u002Fdocs\u002Fdeployment-layers.md`](go\u002Fdocs\u002Fdeployment-layers.md) for the file\nschemas and deploy-time validation rules.\n\nWhat the engine reads, and when each file is needed:\n\n| File               | Engine env var                   | When you need it                                                                                               |\n| ------------------ | -------------------------------- | -------------------------------------------------------------------------------------------------------------- |\n| workflow JSON      | `ENGINE_CONFIG_FILE`             | always — the graph itself                                                                                      |\n| device manifest    | `ENGINE_DEVICE_MANIFEST_FILE`    | only with hardware channels (GPIO \u002F ADC \u002F DAC \u002F PWM \u002F UART) — maps a logical id to a physical `\u002Fdev\u002F…`         |\n| external resources | `ENGINE_EXTERNAL_RESOURCES_FILE` | only with MQTT channels or custom\u002Fself-hosted models — broker connections and LLM endpoints                    |\n| deployment mapping | `ENGINE_DEPLOYMENT_MAPPING_FILE` | as soon as any channel **or** custom model exists — binds each logical id to a resource (+ index for hardware) |\n\n**Rule of thumb:** a workflow with no channels and only built-in catalog models (e.g.\n`claude-haiku-4-5`) needs none of the extra files — just the workflow JSON and the\nprovider's API key. Add the mapping the moment a channel or a custom model appears; add\nthe device manifest for hardware, external resources for MQTT and self-hosted models.\n\nShip the image with the `docker save` \u002F `docker load` flow from\n[Run the engine](#run-the-engine) and start it with `docker run`, mounting the files\nabove with `-v` and pointing the `ENGINE_*` env vars at them. The repo ships no\n`compose.yaml` — write your own if you prefer `docker compose`.\n\n## Features\n\n- **Workflow engine** — typed graph runtime; nodes for LLM calls, hardware I\u002FO, MQTT, web search, memory, control flow.\n- **Multi-provider LLMs** — Anthropic, OpenAI, Google Gemini, Mistral, plus a local SLM provider for `llama.cpp` \u002F `vLLM` \u002F `Ollama` \u002F any OpenAI-compatible endpoint.\n- **Visual React Flow builder** — embeddable component or runnable as bundled SPA, with typed parameters and live validation.\n- **Contract-typed wire format** — every API generated from `contract\u002F*.yaml` for both Go and TypeScript; CI fails on schema drift.\n\n## Local models (self-hosted SLMs)\n\nTo run a model on the device, use **`llama.cpp`**: pull its server image and run it as its\nown container serving a `.gguf` model file (e.g. a quantized Gemma):\n\n```sh\ndocker pull ghcr.io\u002Fggml-org\u002Fllama.cpp:server-b8589\n\ndocker run --rm --network host -v \"$PWD\u002Fmodels:\u002Fmodels:ro\" \\\n  ghcr.io\u002Fggml-org\u002Fllama.cpp:server-b8589 \\\n  --model \u002Fmodels\u002Fgemma-3-270m-it-Q4_0.gguf --host 0.0.0.0 --port 8090\n```\n\nThe model runs in **its own container, separate from the engine** — start it before the\nengine (or write a `compose.yaml` to bring both up together). In the workflow you reference the\nmodel as a **custom `LLMModel`** and point it at this endpoint through the deploy files\n(see [Deploy a workflow to a device](#deploy-a-workflow-to-a-device)).\n\n## Hardware and transports\n\n- **GPIO** via `go-gpiocdev` (digital in\u002Fout, edge triggers)\n- **ADC \u002F DAC \u002F PWM** via Linux character-device interfaces\n- **UART \u002F serial** via `go.bug.st\u002Fserial`\n- **MQTT** via Eclipse Paho — topic-scoped channels for device-to-device messaging\n- **Web search** as a pluggable node\n\nDigital and analog signal types are first-class in the workflow contract.\n\n## Target hardware\n\n✅ = brought up and exercised on our own bench. We don't yet publish a per-device CI matrix, so treat these as known-good targets rather than a continuously tested guarantee.\n\n| Target                         | Status                                                                                         |\n| ------------------------------ | ---------------------------------------------------------------------------------------------- |\n| Raspberry Pi 5 (8 GB)          | ✅                                                                                             |\n| NVIDIA Jetson Orin Nano (8 GB) | ✅                                                                                             |\n| x86 NUC (16 GB)                | ✅                                                                                             |\n| STM32MP25 (1 GB, Linux MCU)    | ✅                                                                                             |\n| Bosch Rexroth ctrlX CORE       | ✅                                                                                             |\n| Other Linux `amd64` \u002F `arm64`  | Works, untested                                                                                |\n| macOS `arm64` \u002F `amd64`        | Supported (development)                                                                        |\n| Bare-metal MCU (Cortex-M)      | Not supported by the Go engine. Contract is portable; dedicated MCU runtime is on the roadmap. |\n\n---\n\n# Developing edge-agents\n\nWant to hack on the engine, the builder, or the contract? Clone the repo — `go\u002F` and\n`ts\u002F` are independently buildable and releasable; only `contract\u002F` edits touch both.\n\n```sh\ngit clone https:\u002F\u002Fgithub.com\u002FForestHubAI\u002Fedge-agents\ncd edge-agents\n```\n\n## Build from source\n\n**Go engine** (requires the Go version pinned in [`go\u002Fgo.mod`](go\u002Fgo.mod)):\n\n```sh\ncd go\ngo build .\u002Fcmd\u002Fengine\n.\u002Fengine                 # runs standalone by default\ngo test .\u002F...            # testify-based tests\n```\n\n**TypeScript packages** (Node ≥ 20):\n\n```sh\ncd ts\nnpm ci\nnpm run dev              # Vite dev server with the visual builder → http:\u002F\u002Flocalhost:5173\nnpm run build            # build all three packages\nnpm run typecheck && npm run lint && npm test\n```\n\n**The CLI from your working tree** — the root `package.json` delegates to\n`ts\u002Fworkflow-cli`, so a single root `npm install` (its `postinstall` builds the `ts\u002F`\ntoolchain) runs the validators against your local changes instead of the published\npackage:\n\n```sh\nnpm install\nnpm run check-schema -- my.workflow.json   # the -- passes the path to the CLI, not to npm\nnpm run validate    -- my.workflow.json\nnpm run open        -- my.workflow.json\n```\n\nAfter a `git pull` that changed dependencies, just run `npm install` again. If a stale\n`node_modules` bites you after switching branches, do a clean reinstall:\n\n```sh\nrm -rf node_modules ts\u002Fnode_modules && npm install\n```\n\n## Contract is the source of truth\n\nEvery API type is generated from [`contract\u002F*.yaml`](contract) for **both** Go and\nTypeScript — CI fails on drift. Never hand-edit generated bindings; edit the contract,\nthen regenerate both sides:\n\n```sh\ncd go && go generate .\u002F...     # → go\u002Fapi\u002F*\u002Ftypes.gen.go, server.gen.go\ncd ts && npm run generate      # → ts\u002Fworkflow-core\u002Fsrc\u002Fapi\u002Fworkflow.ts\n```\n\nSee [`go\u002FCLAUDE.md`](go\u002FCLAUDE.md) and [`ts\u002FCLAUDE.md`](ts\u002FCLAUDE.md) for the full\ncontributor guide, conventions, and the domain-layer reconciliation each side needs.\n\n## Architecture\n\nA workflow is a directed graph of typed nodes — LLM call, hardware I\u002FO, MQTT, memory, control flow, expressions — connected by edges with one of five types: `control`, `tool`, `agentTask`, `agentChoice`, `agentDelegate`. The engine interprets the graph as a state machine: wait for event → execute node → transition. The contract (`contract\u002F*.yaml`) is the single source of truth — Go and TypeScript both regenerate from it, CI fails on drift.\n\nSee [`go\u002FCLAUDE.md`](go\u002FCLAUDE.md) and [`ts\u002FCLAUDE.md`](ts\u002FCLAUDE.md) for deeper architecture notes.\n\n## Repository layout\n\n| Path                                         | What it contains                                                                                            |\n| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |\n| [`contract\u002F`](contract)                      | OpenAPI 3.0.3 schemas — single source of truth for Go and TS.                                               |\n| [`go\u002F`](go)                                  | Engine binary, LLM proxy, hardware drivers, MQTT transport. Module `github.com\u002FForestHubAI\u002Fedge-agents\u002Fgo`. |\n| [`ts\u002Fworkflow-core`](ts\u002Fworkflow-core)       | `@foresthubai\u002Fworkflow-core` — headless workflow model, validation, (de)serialization. No React.            |\n| [`ts\u002Fworkflow-builder`](ts\u002Fworkflow-builder) | `@foresthubai\u002Fworkflow-builder` — React canvas component.                                                   |\n| [`ts\u002Fworkflow-cli`](ts\u002Fworkflow-cli)         | `@foresthubai\u002Fworkflow-cli` — the `fh-workflow` CLI + the reference SPA it serves.                          |\n\n## Releases\n\n- **Go runtime** — tagged `go\u002FvX.Y.Z`; consume with `go get github.com\u002FForestHubAI\u002Fedge-agents\u002Fgo@vX.Y.Z`.\n- **TypeScript packages** — `@foresthubai\u002Fworkflow-core`, `@foresthubai\u002Fworkflow-builder`, and `@foresthubai\u002Fworkflow-cli` ship in lockstep at the same version, published to public npm.\n- **Container image** — built from [`go\u002FDockerfile`](go\u002FDockerfile): multi-arch (`linux\u002Famd64`, `linux\u002Farm64`), distroless, nonroot. Build it yourself (see [Run the engine](#run-the-engine)).\n\nSee [RELEASING.md](RELEASING.md).\n\n## Contributing\n\nSee [CONTRIBUTING](.github\u002FCONTRIBUTING.md) and the [Code of Conduct](.github\u002FCODE_OF_CONDUCT.md). Open an issue before any non-trivial change. Every contribution is accepted under a Contributor License Agreement that preserves the dual-licensing model.\n\n## Security\n\nDo not open public issues for security vulnerabilities. Use [GitHub private vulnerability reporting](https:\u002F\u002Fgithub.com\u002FForestHubAI\u002Fedge-agents\u002Fsecurity\u002Fadvisories\u002Fnew) or email **root@foresthub.ai**. See [SECURITY.md](.github\u002FSECURITY.md) for scope and process.\n\n---\n\n## Talk to the team\n\nUsing `edge-agents` in a product, need a license that isn't AGPL-compatible, or want\nhelp getting an agent onto your hardware? Talk to the people who build it at\n[ForestHub](https:\u002F\u002Fforesthub.ai):\n\n- 📅 **Book a 30-min call** → https:\u002F\u002Fcalendar.app.google\u002FFZ93vzS5zMBc4Kjs7\n- ✉️  **Email** → root@foresthub.ai\n\n---\n\n## License\n\n`edge-agents` uses a **two-tier license model** designed to make the wire format and the headless workflow model maximally reusable while keeping the engine and the visual builder protected under copyleft.\n\n| Component                                                                          | License                             | Why                                                                                                                                       |\n| ---------------------------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| [`contract\u002F`](contract) (OpenAPI schemas)                                          | **Apache-2.0**                      | Wire format. Third-party Python, Rust, or Java clients should be free to implement against it.                                            |\n| [`ts\u002Fworkflow-core`](ts\u002Fworkflow-core) (headless model)                            | **Apache-2.0**                      | Workflow model and validation. Same reasoning — should be embeddable into any TypeScript\u002FJavaScript project without copyleft friction.    |\n| [`go\u002F`](go) (engine, LLM proxy, drivers)                                           | **AGPL-3.0-only** or **commercial** | Keeps hosted \"edge-agents as a service\" offerings honest. For commercial use cases incompatible with AGPL, [book a call](https:\u002F\u002Fcalendar.app.google\u002FFZ93vzS5zMBc4Kjs7) or contact **root@foresthub.ai**. |\n| [`ts\u002Fworkflow-builder`](ts\u002Fworkflow-builder) (React canvas)                        | **AGPL-3.0-only** or **commercial** | Same dual-license terms as the engine.                                                                                                    |\n| [`ts\u002Fworkflow-cli`](ts\u002Fworkflow-cli) (`@foresthubai\u002Fworkflow-cli` + reference SPA) | **AGPL-3.0-only** or **commercial** | Bundles the AGPL builder; same dual-license terms.                                                                                        |\n\nFor the AGPL components, the AGPL network clause applies — providing a modified version over a network requires making the corresponding source available to users of that service.\n\nThird-party components retain their own licenses; see [THIRD_PARTY_NOTICES](THIRD_PARTY_NOTICES) and [NOTICE](NOTICE).\n\n---\n\nBuilt by [ForestHub](https:\u002F\u002Fforesthub.ai) — the platform for embedded and edge AI agents. Questions or a commercial use case? **[Book a call](https:\u002F\u002Fcalendar.app.google\u002FFZ93vzS5zMBc4Kjs7).**\n",2,"2026-06-11 04:11:03","CREATED_QUERY"]