flue
A visual guide to Flue, the agent harness framework
an agent is a loop.
Every AI agent is doing the same thing underneath; running a loop.
The model does the deciding. It reads the conversation, judges what to do next, and produces text. Sometimes that text is a request to call a tool. Something else has to run the tool, take what comes back, hand it to the model, and ask what's next. Over and over, until the model says it's done.
That something else (the part that runs the tools, keeps track of the conversation, knows when to stop) is the harness.
An agent is what you get when a model is put inside a harness and the loop is started. The model decides what to do; the harness does it.
a programmable agent harness.
Writing a harness from scratch takes a decent amount of work. The only other options are slop-forking someone else's, or reaching for tools like Claude Code or Codex, but most of them don't give you the flexibility you need, since their harnesses aren't programmable.
Flue is the same harness, pulled out. Programmable. Ready to run wherever you need it to run.
It's the right level of abstraction; you're not writing the harness from scratch, you also not adopting someone else's whole tool. Just the primitives, small and simple to use.
a workspace.
Every agent in Flue has a name and an ID. When something triggers it (a webhook, a CLI command), the ID determines which agent runs. State is scoped by ID, so the same ID → same agent, new ID → new agent. Simple enough.
Files written and conversation history stick around, across requests, across deploys.
Under the hood, the ID is the shard key. On Cloudflare it maps to a Durable Object: one DO per agent ID, which is where the workspace state lives. On Node, it's a key into an in-memory store, or a custom session store if you wire one up.
state nests further.
Inside an agent, two more things nest.
A session is a conversation thread. Many sessions can live inside the same agent. They share the same files, but each has its own message history.
A task is a child agent inside a session. It shares the parent's files but keeps its own message history. Useful for handing a sub-problem off into its own context.
the project shape.
A Flue agent is a directory. Inside it, two things matter:
A small TypeScript file where you would declare the triggers, call the model, and return the result.
And a markdown file with agent instructions.
Composition is filesystem-driven. Where you point the agent's `cwd` decides which `AGENTS.md` and which skills it picks up. Drop a folder somewhere and you've changed the agent's personality. No imports, no config file linking it together.
The same idea extends to integrations. If you need a third-party service like Cloudflare Sandbox, you don't install a package; you run `flue add
same code, anywhere.
The same Flue agent can run as a webhook handler, a scheduled job, or a one-off CLI command. The framework figures out where it's running and adjusts the plumbing (where session memory lives, how requests come in) without the agent code changing.
On Cloudflare, you get Durable Object-backed persistence for free. On Node, sessions live in memory by default, or in a custom store when you wire one up. CI runs are ephemeral by design.
Triggers are declared in the agent file itself: one line each, no separate routing config.
What changes per target is the session store, the request adapter, and the environment binding. What doesn't change is the agent code, the AGENTS.md, the skills, or the tool signatures.
Write the agent once. Trigger it from wherever makes sense.