AI agents that don't stop when you close the tab.
Docs | Installation | Architecture | Home Assistant Addon | Issues
Wactorz runs LLM-driven agents as long-lived actors on the hardware you already have - a Raspberry Pi in the garage, an old laptop, a VM in your closet. You describe what you want in chat; the planner writes the Python, spawns it on a node, and supervises it. When an agent crashes, only that one restarts. State persists across restarts and you can move an agent to a different machine without losing it.
It runs on MQTT, so anything happening inside the system surfaces as a topic external code can subscribe to. Home Assistant talks to it the same way Discord and Telegram do - it's one channel among several, alongside a REST API and an MCP server. The LLM provider is configurable (Anthropic, OpenAI, Gemini, NIM) or fully local via Ollama for offline use.
How Wactorz is different
Most agent frameworks build a crew that runs a task and exits. Wactorz builds a system that keeps running. Agents are long-lived, supervised actors — they persist their state, restart themselves when they crash, and can move between machines — rather than functions you call inside one script.
| Wactorz | Orchestration libraries (LangChain, CrewAI, AutoGen) | Visual automation (n8n, Node-RED) | HA native automations | |
|---|---|---|---|---|
| Lifecycle | Long-lived, self-supervising actors | Task-scoped, exit when the script ends | Long-lived flows | Long-lived rules |
| Failure handling | Per-agent crash isolation + restart | Your code handles it | Per-flow | Per-rule |
| Distribution | Agents spawn and migrate across nodes over MQTT | Single process | Single instance | Single instance |
| How agents are built | LLM writes and runs the Python at runtime | You write the chain | You wire nodes by hand | You write YAML |
| Runs offline / self-hosted | Yes — BYO key or fully local via Ollama | Varies | Yes | Yes |
It's not a replacement for Home Assistant — it sits alongside it, adding an LLM planner and dynamic agents on top of the home you already automate.
Quick Start
git clone https://github.com/waldiez/wactorz
cd wactorz
pip install -e ".[all]"
# Start the MQTT broker
docker compose up -d mosquitto
# Set your provider, model, and key (or put them in .env)
export LLM_PROVIDER=anthropic # anthropic | openai | ollama | nim | gemini
export LLM_MODEL=claude-sonnet-4-6
export LLM_API_KEY=your-key-here
python -m wactorz
Dashboard: http://localhost:8888.
[!WARNING] Run Wactorz only on a trusted local network. The dashboard, REST API, and MQTT broker are unauthenticated by default, and agents can execute code. Do not expose ports
8888,8000, or1883to the internet or an untrusted LAN. See Security before deploying anywhere shared.
If you'd rather skip the clone, pull the image from Docker Hub. To run without an API key, use Ollama:
ollama pull llama3
python -m wactorz --llm ollama --ollama-model llama3
Windows setup is in docs/windows.md; the full set of deployment options lives in docs/deployment.md.
Example prompts
when a person is detected in my pc camera, open the office light
when the door opens, make reachy wakeup
when the light has been on for too long, send me a discord notification
Architecture
flowchart LR
User["User<br/>CLI, REST, Discord, Telegram, HA"] --> Main["MainActor<br/>intent routing"]
Main --> Actuate["OneOffActuatorAgent<br/>direct service calls"]
Main --> Planner["PlannerAgent<br/>pipeline planning"]
Main --> HA["HomeAssistantAgent<br/>REST + WebSocket"]
Main --> Chat["LLM reply<br/>streaming response"]
Planner --> Dynamic["DynamicAgents<br/>LLM-generated runtime code"]
Actuate --> Bus["MQTT broker"]
HA --> Bus
Dynamic --> Bus
Bus --> Dashboard["Live dashboard<br/>agents, logs, cost, heartbeats"]
Bus --> Remote["Remote nodes"]
Bus --> External["Sensors, services, and IoT systems"]
Interfaces
| Interface | How to use it |
|---|---|
| CLI | python -m wactorz |
| Live dashboard | http://localhost:8888 |
| REST API | python -m wactorz --interface rest |
| Discord | python -m wactorz --interface discord |
| Telegram | python -m wactorz --interface telegram |
| MCP server | wactorz-mcp |
| Home Assistant addon | One-click install inside the HA Supervisor |
LLM Configuration
Set these three env vars in .env or export them in your shell:
# Options: anthropic | openai | ollama | nim | gemini | none
LLM_PROVIDER=anthropic
# Model ID — examples:
# anthropic → claude-sonnet-4-6
# openai → gpt-4o
# ollama → llama3
# nim → meta/llama-3.3-70b-instruct
# gemini → gemini-2.5-flash
LLM_MODEL=claude-sonnet-4-6
# Generic key — used for anthropic / openai / nim / gemini
# For Ollama, set OLLAMA_URL instead (default: http://localhost:11434)
# For OpenAI-compatible endpoints (Groq, Together, vLLM…), set OPENAI_URL to redirect
LLM_API_KEY=your-key-here
# Optional — sampling temperature for every LLM call.
# 0 = deterministic (recommended for device control and classification);
# leave unset/empty to keep each provider's own default.
LLM_TEMPERATURE=0
At startup Wactorz logs the configuration it resolved, so you can confirm it at a glance:
LLM: anthropic/claude-sonnet-4-6 | temperature=0.0
Per-call-site overrides (hybrid setups)
Optionally, route individual call sites to different models with LLM_OVERRIDES —
for example run the cheap, high-frequency calls on a local model and keep the
planner on a hosted one:
# <site>=<provider>[:<model>], comma-separated. Unlisted sites use the global provider.
LLM_OVERRIDES="intent=ollama:qwen3:4b,actuator=ollama:llama3,planner=anthropic:claude-sonnet-4-6"
Sites: main (conversation), intent (intent routing), planner (pipeline
planning/codegen), actuator (one-off device control), ha (Home Assistant
agent), dynamic (the get_llm() shim inside generated agents).
To compare models per call site before choosing an override, run the built-in evaluation harness — it scores each site automatically and reports accuracy, latency and cost:
python -m wactorz.evalharness \
--models "ollama:qwen3:4b,anthropic:claude-sonnet-4-6" --temperature 0
See docs/evaluation.md for the benchmark format and metrics.
Security
Wactorz is under active development. Treat the current release as alpha from a security standpoint and deploy accordingly.
Threat model — what to assume today:
- The monitor dashboard, REST API, WebSocket, and MQTT broker are unauthenticated by default. Anyone who can reach those ports can spawn, control, and delete agents.
- Agents can execute code (the planner generates and runs Python; remote nodes run spawned code over SSH/MQTT). Anyone who can reach the control plane can run code on the host and on any connected node.
- The bundled MQTT broker ships with anonymous access for local development.
Deployment rules:
- ✅ Run on a trusted local network you control (a home LAN, a private VLAN).
- ✅ Prefer the Home Assistant add-on, which keeps the UI behind HA's ingress auth.
- ❌ Do not expose ports
8888(dashboard),8000(REST/WS), or1883/9001(MQTT) to the internet or a shared/untrusted network. - ❌ Do not run it as a multi-user or multi-tenant service yet.
- If you must reach it remotely, put it behind a VPN or an authenticating reverse proxy — never a bare port-forward.
Found a security issue? Please see SECURITY.md rather than opening a public issue.
Repository Map
| Path | What lives there |
|---|---|
wactorz/ |
Python actor runtime, built-in agents, interfaces, monitoring, HA integration |
frontend/ |
Vite + TypeScript card dashboard |
ha-addon/ |
Home Assistant Supervisor addon |
docs/ |
Markdown docs source |
infra/ |
Mosquitto, Prometheus, OpenTelemetry, nginx, and HA configs |
tests/ |
Python test suite |
Documentation
| Start here | For |
|---|---|
| Quickstart | First run and Windows setup |
| Docker Hub | Run from Docker without cloning the repo |
| Architecture | Actor system, supervision, MQTT flow |
| Agents | Built-in agents, recipes, and dynamic agents |
| Pipelines | Reactive automation patterns |
| Remote nodes | Edge deployment over SSH |
| Interfaces | CLI, REST, chat platforms, dashboard, MCP |
| API reference | REST endpoints and payloads |
| Deployment | Docker, Home Assistant add-on, environment setup |
| Prometheus | Metrics and monitoring |
| Evaluation harness | Compare models per LLM call site |
| Technical reference | Deeper internals |
Contributors
|
Panagiotis Kasnesis 📆 💻 |
Lazaros Toumanidis 💻 🎨 |
Chris 💻 📓 |
Amalia Contiero 💻 📣 |
Contributions of any kind are welcome. See CONTRIBUTING.md to get started.
Contributing
| What | How |
|---|---|
| Found a bug | Open an issue |
| Have an idea | Start a discussion |
| Want to code | Fork, branch, and open a PR against dev (main is releases only) |
| Docs, tests, UI | Same drill, open a PR |
| New agent recipe | Add it in wactorz/catalogue_agents/ and open a PR |
| Home Assistant | HA integrations and addon config PRs are very welcome |
Read CONTRIBUTING.md for setup instructions, code style, and the PR process.
License
Apache 2.0. Free to use, modify, and distribute.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wactorz-0.5.2.tar.gz.
File metadata
- Download URL: wactorz-0.5.2.tar.gz
- Upload date:
- Size: 2.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45ae430a84f8fabbe3e02bcd4baea7ba965a89813ca9cc191446d1c4065eb1b8
|
|
| MD5 |
edcafd5f189e7edcb856611280ea67ff
|
|
| BLAKE2b-256 |
aaf26219870306c0c21edd83aa3fae33fc783663ab09c577fdb18d24fa37d97a
|
Provenance
The following attestation bundles were made for wactorz-0.5.2.tar.gz:
Publisher:
release.yml on waldiez/wactorz
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wactorz-0.5.2.tar.gz -
Subject digest:
45ae430a84f8fabbe3e02bcd4baea7ba965a89813ca9cc191446d1c4065eb1b8 - Sigstore transparency entry: 2287106497
- Sigstore integration time:
-
Permalink:
waldiez/wactorz@4a416e073bc4d74deb0019dee034b25c8dc89859 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/waldiez
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4a416e073bc4d74deb0019dee034b25c8dc89859 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wactorz-0.5.2-py3-none-any.whl.
File metadata
- Download URL: wactorz-0.5.2-py3-none-any.whl
- Upload date:
- Size: 1.1 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cfebd3670c311e579f11c3283b235424046f6f79c097d77c553fd6fbe0a722d
|
|
| MD5 |
d77fc922dcd78bfdc245d79c5c0c6037
|
|
| BLAKE2b-256 |
50e3fe15187feaff00ec804d514af39cd3751688b8f46575ae37adbf8ebbe2bb
|
Provenance
The following attestation bundles were made for wactorz-0.5.2-py3-none-any.whl:
Publisher:
release.yml on waldiez/wactorz
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wactorz-0.5.2-py3-none-any.whl -
Subject digest:
8cfebd3670c311e579f11c3283b235424046f6f79c097d77c553fd6fbe0a722d - Sigstore transparency entry: 2287106537
- Sigstore integration time:
-
Permalink:
waldiez/wactorz@4a416e073bc4d74deb0019dee034b25c8dc89859 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/waldiez
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4a416e073bc4d74deb0019dee034b25c8dc89859 -
Trigger Event:
push
-
Statement type: