# waku-agent: a local-first AI agent harness you can read in an afternoon

> ShenSeanChen/waku-agent is a Python personal assistant that keeps the loop, memory and evals in plain files and one SQLite database. It is built for engineers who want to step through the whole agent rather than configure someone else's stack.

**ShenSeanChen/waku-agent** — Waku Waku! Waku Agent is a local-first AI agent harness you actually own, including loop, memory, eval, all in code built to stay legible as it grows.

- Repository: https://github.com/ShenSeanChen/waku-agent
- Website: waku.one
- Stars: 1,881 · Forks: 381
- Language: Python
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/shenseanchen-waku-agent

## The problem waku-agent solves, and who it is actually for

Most agent stacks are assembled from a framework, a vector store, an orchestration layer and a separate tracing service. The result works, but the control flow is spread across four dependencies, and the part you care about (the loop that decides what to do next) is the part you cannot see. waku-agent takes the opposite position. The README describes it as "a local-first personal assistant that shows the four pillars behind every serious agent: Harness, Loop, Memory, Eval/LLM-Ops," and the repository layout backs that up: a `waku/` package, an `evals/` directory, a `skills/` directory, and a `sql/` directory for schema.

The intended reader is an engineer who wants to understand agent behaviour by reading code, not by reading documentation about someone else's abstractions. The README states the loop is roughly 95 lines of plain Python. That number is the whole pitch. If you have ever tried to debug why an agent called a tool twice, a loop you can hold in your head is worth more than a configuration file with forty options.

The secondary audience is people who want a personal assistant that does not ship their calendar and notes to a vendor. Memory lives in `.waku/state.db`, a single SQLite file. The README is explicit: "Open it. Read it. It's yours."

## Inside the harness: gate, loop, memory pillars and the graph engine

A turn enters through one of several gateways: the terminal CLI, the local dashboard, Telegram, Discord, WhatsApp or voice. The README says each message is tagged by source, and the Gateway tab shows one conversation across every channel. From there the turn hits a retrieval gate, which decides whether to pull from memory at all. This is the mechanism worth understanding. Most assistants always retrieve; waku-agent has a gate that decides whether to remember and a separate consolidation pass that decides what to keep. The README calls memory "the hero" and splits it into semantic facts, episodes and procedural skills, with an editable SOUL document alongside.

If the gate says retrieve, the loop runs. The loop is where tool calls happen, and the README's World Cup example shows it iterating eight times: repeated `search_web` calls followed by repeated `create_event` calls in a single turn. The Loop tab records each iteration with its gate decision, tool calls, token counts and cost. That per-iteration record is the practical difference between this and a black-box agent, because you can see iteration 2 and iteration 8 separately.

Version v0.1.1 added agent graphs. The README describes a Graph tab that draws the live triage topology from the engine itself and shows which door each turn took. The Makefile exposes this as a separate target: `make brief` runs the morning briefing as a loop, while `make gather` runs the same job as a graph with four sources in parallel and one digest. Two execution models over the same tools is an unusual design choice for a project this small, and it means the loop is not the only path through the system.

## Installing waku-agent and running a first memory test

The quickest path is the published package. The README gives this as the two-line version, and it tells you which key to set the first time you run it:

```bash
pip install waku-agent
waku
```

If you want to read the source, which the README says is the point of the repository, clone it instead and use uv:

```bash
uv venv && uv pip install -e .
cp .env.example .env
uv run waku
```

The `.env.example` file is generated by `scripts/generate_env_example.py`, and the definitions live in `waku/integrations.py`. It sets `WAKU_PROVIDER=anthropic` by default, with commented entries for OpenAI, OpenRouter, Gemini, DeepSeek, MiniMax, Kimi, GLM, xAI and the OpenCode providers. Paste one key and leave the rest commented.

The dashboard is a local web server on port 7777. The README notes it binds to `127.0.0.1` and that nothing leaves the machine:

```bash
waku dashboard
```

Now test the memory pillars directly. Type "Remember that Alex prefers morning meetings", then quit and restart. Ask "Book a catch-up with Alex on Friday." The README states it should remember the preference and book 9am. Open the Data tab, which the README describes as a live SQLite browser with per-table tabs, schema and a read-only SQL console over `state.db`. If the fact is not in that file, the memory path did not work, and you have found the first thing to debug.

## Where waku-agent is the wrong tool

The project is classified as Development Status 4 - Beta in `pyproject.toml`, and the first tagged release, v0.1.0, is dated 2026-07-26. v0.1.1 followed on 2026-07-31. Two releases in five days is a starting point, not a track record. If you need a dependency whose interfaces will not move under you, this is early.

The dashboard has a specific operational trap, and the Makefile comments on it directly: the server holds `dashboard.py` in memory, so static JS and CSS reload on refresh but Python routes do not. After pulling a change that touches `dashboard.py` or any imported module, you must stop and re-run the server or the UI shows stale backend data. That is a real failure mode during development, not a theoretical one.

Local-first also means single-machine. Memory is one SQLite file, which is excellent for inspection and poor for concurrent writers. If you want several users hitting one agent from a hosted endpoint, or you want horizontal scaling, the architecture is working against you. The README also does not document rollback or migration for `state.db`; the `sql/` directory exists, but the README does not describe a versioned migration path. Treat the database as something you back up yourself before upgrading.

Finally, the project is a personal assistant at heart. Calendar events, notes, morning briefings. If your problem is batch document processing or a high-throughput classification pipeline, the gate and memory layers are overhead you would be paying for and not using.

## How it differs from a general agent framework

The obvious comparison is a general-purpose agent framework where you define tools, wire a graph and bring your own persistence. In that model, memory is a component you add, usually a vector database, and evaluation is a separate service. The difference here is not features; it is where the defaults sit. waku-agent ships the gate, the three memory pillars, the consolidation pass and the eval harness as part of the package, and it ships a dashboard that reads the same SQLite file the agent writes.

The README's own framing is that there are "no frameworks hiding the good parts." Take that as a design constraint rather than a claim. The dependency list in `pyproject.toml` is four entries: `anthropic`, `openai`, `python-dotenv` and `rich`. Everything else, including the web dashboard, is in the repository. That is a deliberate trade: you get fewer moving parts and a smaller surface to audit, and in exchange you inherit the maintenance of the parts a framework would have handled.

A second difference is the provider adapter. The README says one dialect runs in the loop and a roughly 60-line adapter in `waku/loop/models.py` handles the rest, with Anthropic and OpenAI wire formats covering Anthropic, Kimi, GLM, MiniMax, OpenAI, Gemini and DeepSeek. That is a thin layer by design, and it means adding a provider is a small, readable change rather than a plugin registration.

## Licence, packaging and the cost of upgrading

The code is MIT, but the package is not solely MIT. `pyproject.toml` declares `license = "MIT AND OFL-1.1 AND LicenseRef-Waku-Brand"` with three license files: `LICENSE`, `LICENSE-BRAND`, and the OFL text for the bundled fonts under `waku/ops/static/fonts/`. The comment in the file explains why: PEP 639 lets the package state all three, so PyPI no longer reports the whole wheel as MIT. If you fork this and redistribute a wheel, the brand assets and fonts carry their own terms. That is a packaging fact, not legal advice; read `LICENSE-BRAND` before you ship anything with the Waku marks.

The same file documents a versioning hazard that was fixed. Version is now dynamic, sourced from `waku/__init__.py`, because pyproject and the package disagreed for four releases (0.1.4 in one place, 0.1.0 in the other). If you pin waku-agent in a lockfile, verify the installed version against the package rather than trusting a single number.

Upgrade cost is mostly the database and the dashboard process. There is no documented migration tool for `.waku/state.db` in the README, so back the file up before pulling. Restart the dashboard after any backend change. Optional extras are installed per channel, for example `pip install -e '.[telegram]'` for Telegram and `pip install -e '.[discord]'` for Discord, so channel support is opt-in rather than bundled.

## Conclusion

Adopt waku-agent if you want to read and modify the loop, keep memory in a SQLite file you own, and run evals from the same repository. Skip it if you need a hosted multi-tenant service, a large plugin ecosystem, or a stable API surface; the project is still tagged Beta and the release history is short. Before committing, run `waku dashboard`, open the Data tab, and confirm that `state.db` in `.waku/` contains the turns you just made, because that file is the boundary between what you control and what you do not.

## FAQ

### What are the top 3 AI agents?

The README does not rank agents or compare waku-agent against a list. It positions waku-agent as a local-first personal assistant built around four pillars: harness, loop, memory and eval/LLM-Ops, so any ranking would have to come from elsewhere.

### What are the 7 types of AI agents?

The README does not present a taxonomy of agent types. It splits the system into gateways (CLI, dashboard, Telegram, Discord, WhatsApp, voice), a retrieval gate, a loop, three memory pillars and an eval harness, and the Graph tab in v0.1.1 adds graph workflows alongside the loop.

### How can I build my own AI harness with waku-agent?

Clone the repository, create a virtual environment with uv, install it in editable mode and copy `.env.example` to `.env` with one provider key. The README states the loop is roughly 95 lines of plain Python, so the intended path is to read that file and modify it rather than configure it.

### What is the main purpose of waku-agent as an AI agent?

It is a local-first personal assistant that runs on your machine and keeps its memory in a single SQLite file at `.waku/state.db`. The README frames it around four pillars: harness, loop, memory and eval/LLM-Ops.

## Sources

- [Issues](https://github.com/ShenSeanChen/waku-agent/issues)
- [License: MIT](https://github.com/ShenSeanChen/waku-agent/blob/main/LICENSE)
- [README](https://github.com/ShenSeanChen/waku-agent/blob/main/README.md)
- [Releases](https://github.com/ShenSeanChen/waku-agent/releases)
- [ShenSeanChen/waku-agent on GitHub](https://github.com/ShenSeanChen/waku-agent)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shenseanchen-waku-agent
