v0.10.24 — Workflow + Agent peer primitives

Weave intelligent
agent graphs

A Python framework with two primitives. Agent hands the loop to the LLM. Workflow keeps you in charge of the graph. You can drop either one inside the other. user_idpartitions memory, budgets, and audit so you don't have to.

classify
route_billing
route_tech
agent.run()
wf.as_tool()
agent.run()
Developer experience

Graphs that read
like pseudocode

Draw the control flow as a graph, or hand it to the LLM. Nodes are functions. Or Agents. Or other Workflows. Edges are decisions. State, telemetry, and user_id ride along the whole way.

support.py
from loomflow import Agent, Workflow

# Two LLM-controlled specialists
billing = Agent("Handle billing.", model="gpt-4.1-mini", tools=[...])
tech    = Agent("Handle tech.",    model="gpt-4.1-mini", tools=[...])

async def classify(text: str) -> str:
    return (await Agent(
        "Reply 'billing' or 'tech'.",
        model="claude-haiku-4-5",
    ).run(text)).output

# Developer-controlled DAG, Agents inside it
support = Workflow.route(
    classify,
    {"billing": billing, "tech": tech},
)

r = await support.run(
    "My card was charged twice.",
    user_id="alice",
)
print(r.visited)  # ['classify', 'route_billing']

Two primitives

Pick Agent when you want the LLM in charge. Pick Workflow when you want yourself in charge. Pass an Agent as a Workflow node. Or call wf.as_tool() and the workflow becomes a tool the agent can call.

Cycles and branches

add_router branches on whatever the previous node returned. Cycles work too. There's a max_visits_per_node cap so a refinement loop can't spin forever.

Replay built in

Wrap with SqliteRuntime or PostgresRuntime. Crashed runs pick up where they left off. Every model call and tool dispatch gets journaled under (session_id, step_name).

Why Loomflow

What the framework
actually gives you

Workflow primitive

Workflow.chain · Workflow.route · Workflow.parallel. Or build the graph yourself. Cycles work; caps keep them honest.

Twelve agent architectures

ReAct, Plan-and-Execute, ReWOO, Reflexion, Self-Refine, ActorCritic, Tree of Thoughts, Router, Supervisor, Debate, Swarm, Blackboard.

Multi-tenant by default

user_id is a typed primitive. Memory, budgets, permissions, audit log all partition on it. No "forgot to namespace" leaks.

Composition both ways

Pass an Agent as a workflow node. Or call wf.as_tool() and the workflow becomes callable from inside an agent. The trace looks the same either way.

Streaming first

agent.stream() and wf.stream() yield events with backpressure. Wire them to SSE or WebSocket. Nothing buffers forever.

Model agnostic

OpenAI, Anthropic, LiteLLM (~100 providers), Echo for tests. Swap with one kwarg. Native structured outputs on OpenAI plus Anthropic strict mode.

Architecture

How threads flow through the loom

◆ instructions + prompt
◆ user_id partition
◆ memory rehydrate
▼ context seed ▼
→ Agent (ReAct)
→ Workflow.chain
→ Supervisor
→ Reflexion
▼ tools dispatch (parallel) ▼
⚙ @tool functions
⚙ MCP servers
⚙ filesystem / bash
⚙ vector retrieval
▼ persist + observe ▼
✓ episode + auto-extract facts
✓ HMAC audit log
✓ OTel spans
Get started in seconds

One line to begin weaving

$ pip install loomflow