lionagi: a governed multi-agent orchestration framework with a resumable CLI
An intelligence orchestra
At a glance
- What is it?
- lionagi is a Python framework and `li` CLI for building agent workflows with typed, inspectable state. It is best suited to engineers who want to run coding CLIs and API models in the same orchestration graph and keep every run on disk.
- Who is it for?
- Adopt lionagi if you are comfortable owning the orchestration loop in Python and want CLI coding agents and API models in one DAG. Do not adopt it if you need a hosted control plane or a non-Python runtime.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What lionagi solves, and for whom
Most agent frameworks make the orchestration loop the framework's property. You hand over prompt assembly, message history and the retry path, and you get back an opaque chain. lionagi takes the opposite position. Branches, sessions and flows are ordinary Python objects and CLI commands, and the README states plainly that there is "no framework runtime to surrender control to." That is the whole pitch, and it decides the audience.
This is for Python engineers building multi-step agent work who want to inspect state between steps. A Branch is a single conversation thread holding message history, tools and model configuration. A Session coordinates several Branches and runs DAG workflows across them. The `li o flow` command has an orchestrator plan a DAG of specialist workers, which then execute as dependency edges resolve. If your problem is one prompt and one answer, none of this earns its keep. If your problem is six agents whose outputs feed each other, and you need to see why step four produced what it did, the typed message model is the reason to look.
A second audience is teams already paying for coding CLI subscriptions. The README says CLI model aliases such as `claude` and `codex` spawn the provider's own CLI as a subprocess, so an existing `claude login` works without an API key. That is a real cost argument, not a stylistic one.
How the Branch, Session and flow layers fit together
The mechanism visible in the README is a three-level stack. At the bottom, a Branch holds a conversation as a collection of typed messages with explicit ordering. The README claims state "serializes, persists, and resumes; it is never an opaque blob inside a chain." Above that, a Session coordinates multiple Branches and runs DAG workflows across them. At the top, `li o flow` builds the DAG: an orchestrator plans which specialist workers exist, and workers run as their dependency edges resolve.
Two mechanisms sit alongside that stack. The first is persistence. Every run is saved under `~/.lionagi/runs/{run_id}/`, which is what makes `li agent -r <branch-id>` able to pick a conversation back up and `li monitor` able to show live and recent sessions, flows and plays. The second is governance. The README describes permission policies per tool call, guard hooks that block destructive commands and off-limits paths, and git-worktree sandboxing for speculative edits that stay off your branch until merged. Those hooks are the part worth scrutinising in your own environment, because a guard that blocks the wrong path is indistinguishable from a broken agent.
The fan-out path is simpler than the flow path and worth understanding separately. `li o fanout ... -n 3 --with-synthesis` runs N workers in parallel and then a synthesis pass. There is no orchestrator planning step in that mode; the parallelism is fixed by the flag.
Installing lionagi and running a first flow
The project publishes to PyPI and requires Python 3.10 or newer, per the pyproject classifiers and the README badge. Installation is a single pip command:
pip install lionagiBefore running anything, decide how the model endpoint authenticates. CLI aliases reuse an existing provider login; API providers read the usual environment keys. The repository ships a `.env.example` listing the accepted names, all commented out:
# OPENAI_API_KEY=
# ANTHROPIC_API_KEY=
# PERPLEXITY_API_KEY=
# GROQ_API_KEY=
# OPENROUTER_API_KEY=
# EXA_API_KEY=The simplest real run is a single agent, which the README gives as the first quick-start example:
li agent claude/sonnet "Explain the observer pattern in 3 sentences"The output is the model's reply, and the run is written to `~/.lionagi/runs/`. That path is what makes the next command possible: `li agent -r <branch-id> "follow up on your findings"` resumes the branch instead of starting a new one. To see the run while it is happening rather than after, `li monitor --since 1h` lists live and recent sessions, flows and plays.
From Python the same engine is reachable without the CLI. The README's structured-output example pairs a Pydantic model with `branch.operate`:
from pydantic import BaseModel
class Summary(BaseModel):
points: list[str]
confidence: float
result = await b.operate(instruction="Summarize this text.", response_format=Summary)Passing `response_format` is what turns the model's answer into a validated object rather than a string you parse yourself. Note that the snippet assumes a `b` already exists; the README's earlier example constructs one with `Branch(chat_model="openai/gpt-5.4", system="You are a concise assistant.")`.
Where lionagi gets in the way
The persistence layer is not optional. The README says every run is saved under `~/.lionagi/runs/`, and the `li monitor`, `li agent -r` and `li schedule` commands all depend on that directory. On a shared machine or in a container with a read-only home, that assumption is a constraint you have to plan around rather than a feature you can switch off. The README does not document a flag for relocating the run store.
The CLI worker watchdogs are a second edge. The `.env.example` documents `LIONAGI_WORKER_LIVENESS_TIMEOUT`, defaulting to 120 seconds, which is how long `run()` waits for a CLI worker's first stream chunk before retrying once and then failing with `WorkerLivenessError`. It applies by default only to CLI endpoints that stream output early, named as `claude_code` and `codex`; buffered endpoints such as `gemini_code` and `pi` are unaffected unless the timeout is passed explicitly. Setting it to 0 disables the watchdog. There is a second, stricter setting: `LIONAGI_WORKER_IDLE_TIMEOUT` defaults to 300 seconds and fires as `worker.stream_idle` when a streaming worker goes silent between chunks. The `.env.example` is explicit that this one is never retried, because partial output may already have been consumed. If your worker can legitimately think for five minutes without emitting a token, you will hit that failure and you will not get a retry.
Finally, the dependency floor is deliberate and tight. The pyproject pins `aiohttp>=3.14.3` with a comment naming a specific set of HTTP and WebSocket issues, and it declares `sniffio>=1.3.0` directly because anyio 4.10 dropped it from its own dependencies. Both choices are defensible. Both also mean lionagi will not coexist cleanly with a project that needs an older aiohttp.
lionagi compared with LangGraph and AG2
The README points to its own comparison page for the architecture-level difference with LangChain and LangGraph, and to a field matrix covering LlamaIndex and AG2. The distinction it draws is that lionagi has no framework runtime. In LangGraph the graph is the execution model you adopt; state lives in the graph's channels and you work through its API. In lionagi the flow is a command or an object you call, and the message history is a Python structure you can read directly.
That difference has a cost. LangGraph's runtime is also its integration surface: checkpointers, prebuilt agent constructors and a large ecosystem of node types come with it. lionagi gives you fewer pieces and expects you to assemble the loop. If you want the framework to own retries, persistence and streaming in a way you never see, LangGraph is the closer fit. If you want to read the message list at a breakpoint, lionagi's typed messages are the reason to pick it.
The AG2 comparison is less about architecture than about audience. AG2 descends from the AutoGen line and centres on conversational multi-agent patterns. lionagi's centre of gravity is the DAG flow plus the CLI agent as a first-class endpoint, which is a different shape of problem. The README notes the project has been built continuously since 2023, and the release list shows v0.35.0 in August 2026 followed by v0.35.1 and v0.35.2 later that month. The last push to the default branch was 2026-09-09. That is a fast-moving pre-1.0 line, so pin your version.
Licence and the cost of keeping up
lionagi is Apache-2.0, declared in pyproject as `license = {file = "LICENSE"}` and in the classifiers as an OSI-approved Apache licence. Apache-2.0 permits commercial use and modification and includes a patent grant. It also requires that you preserve notices and state changes. This is a summary of what the licence identifier means, not legal advice; read the LICENSE file for the terms that bind you.
The upgrade cost is the part that deserves attention before adoption. The version sits at 0.35.2, and three releases landed within a month of each other in August 2026. A pre-1.0 project at that cadence will move its Python API. The README's own examples already mix `b.communicate(...)` and `await b.operate(...)` as separate surfaces, and the repository carries a CHANGELOG.md, which is where you should look before bumping. Because state is persisted under `~/.lionagi/runs/`, an upgrade that changes the message schema has a second dimension: your existing run history may or may not load. The README does not document a migration path for stored runs, so treat the run directory as disposable until you have confirmed otherwise.
The dependency floor adds ongoing work too. The aiohttp pin with its CVE comment and the explicit sniffio declaration both mean you will occasionally need to move faster than your other dependencies allow. Budget for that.
Editorial conclusion
Adopt lionagi if you are comfortable owning the orchestration loop in Python and want CLI coding agents and API models in one DAG. Do not adopt it if you need a hosted control plane or a non-Python runtime. Verify first that `li o flow` resolves dependencies the way your workflow expects, and check which provider keys or CLI logins you already have, since the framework does not supply them.
Frequently asked questions
Do I need an API key to use lionagi?
Not for CLI aliases. The README states that aliases such as `claude` and `codex` spawn the provider's own CLI as a subprocess, so an existing `claude login` subscription works with no API key. API providers do need the usual environment keys, listed in `.env.example`.
Where does lionagi store run state?
The README says every run persists under `~/.lionagi/runs/{run_id}/`, and that you resume a branch with `li agent -r <branch-id>` or reattach with `-c`. The README does not document a flag for relocating that directory.
What is the difference between `li o fanout` and `li o flow` in lionagi?
`li o fanout` runs N parallel workers with a fixed count from `-n`, plus an optional synthesis pass via `--with-synthesis`. `li o flow` has an orchestrator plan a DAG of specialists, and workers run as their dependency edges resolve.
Which Python versions does lionagi support?
The pyproject requires Python 3.10 or newer, and the classifiers list 3.10 through 3.13. The README badge states the same 3.10+ floor.
Community notes