This release is a pre-release and may not be stable for production use.
ctxloom
Stop drawing the graph. Build agents as reactions to versioned, provable artifacts.
Most agent frameworks make you draw the graph: connect nodes, wire memory, declare control flow. But a knowledge question — "why did infra costs jump in Q2?" — needs Confluence + GitLab + CSV + calculations + verification, and the next question needs a different path. There is no universal graph to draw.
ctxloom flips the model. You describe what artifacts exist and what agents can do with them; the runtime derives what runs next from state changes. Agents react to events — there is no graph, no node pipeline.
from pydantic import BaseModel
from ctxloom import Budget, Consume, Context, Runtime, RuntimeResources, create_agent, produce
from ctxloom.sources import FileSystemSource
class Question(BaseModel):
text: str
class Answer(BaseModel):
text: str
@produce(Answer)
async def echo(context, inputs, event, effects):
question = next((a for a in inputs if isinstance(a.data, Question)), None)
if question is None:
return None
effects.create(Answer(text=f"echo: {question.data.text}"))
echo_agent = create_agent("echo", consumes=[Consume(Question)], produces=[echo])
ctx = Context(resources=RuntimeResources(sources={"docs": FileSystemSource("./docs")}))
runtime = Runtime(ctx, agents=[echo_agent], budget=Budget(max_runs=10))
ctx.create(Question(text="hello")) # agents that consume it react automatically
runtime.run()
print(ctx.latest(Answer).data.text) # "echo: hello"
How it works
ARTIFACT CREATED / UPDATED
│
▼
AGENTS REACT ──self.effects──► Effects ──compile──► Patch
▲ │
└──────────────────────────────────────────────────────┘
Context v+1
A produce writes what should change (self.effects.create/update/link/ask) and
returns None; the runtime compiles the effect set into one atomic Patch
and moves the context to the next version. The event that wakes an agent is
derived from that same change — the causal chain can never drift from the
actual state.
What makes it different
| Traditional agent (LangGraph / CrewAI / LangChain) | ctxloom |
|---|---|
| A program follows a graph / plan | Agents react to state changes |
| Messages are strings | Typed, versioned artifacts (Claim, Evidence, Answer) |
| Orchestration is explicit wiring | Orchestration falls out of the state |
| A unit of work returns a change | An agent writes effects; the runtime compiles them |
| Retries/rollback are manual | Context is git-like versioned (diff, rollback, branch, merge) |
| "Who produced this?" is lost | Provenance links every derived artifact to its inputs |
| The model guesses the numbers | Calculations are calculated — the LLM is a reasoning component, not the source of truth |
Reactive. Deterministic. Accountable.
Core primitives
- Context — versioned working state, git-like commits,
diff/rollback/merge. - Artifact — a first-class typed object (
Claim,Evidence,Answer), not a string blob. - Effects — an agent states its change via
self.effects.create/update/link/ask; the runtime compiles it. - Patch — the compiled, validated change-set applied as one atomic commit.
- Agent — a thin container declaring
consumes/produces; logic lives in aProduce. - Source — retrieval is a capability: vector search is one strategy; direct API, keyword, SQL, filesystem are equally first-class.
- Provenance — every derived artifact links to what produced it
(
Answer —supported_by→ Claim —derived_from→ Evidence —extracted_from→ Doc). - HITL — humans as
effects.ask(...)→PendingQuestion, answered viaeffects.resume(...)like any agent.
In the box
- Deterministic by design — calculations over structured data, honest
Nonefallbacks instead of hallucinated answers; the model reasons, never "knows". - Observability — every run traces agent spans, reads/writes, LLM calls, tokens: SQLite store + web dashboard, exportable to Langfuse/Postgres (async sinks).
- Budgets & replanning — cap by runs/time/iterations/tool-calls, replan on decline.
- Branching & replay —
context.branch(), three-waymerge(), deterministicReplayLLM, all for audit and safe alternative states. - Sessions —
SessionStoreoverFileKVBackend/SQLiteKVBackend(andPostgreSQLKVBackend) for durable chat memory. - Web layer —
ChatAssistant+create_chat_routermount a canonical SSE chat on your FastAPI app; errors degrade to a logged fallback, never a 500. - Recipes —
fan_out_sources,materialize_doc,StatusMachine, change→rebuild rollback helpers — pure, LLM-free. - Viz & CLI — Mermaid
blueprint/context_to_mermaid/trace_to_mermaid;ctxloomwithgraph/context/trace/replay/branch.
Run a demo
Offline-capable, no API keys required (deterministic fallbacks):
uv run python ./examples/llm_ladder/level1.py # the simplest LLM turn (offline too)
uv run python ./examples/repair/web.py # room renovation: plan, estimate, CSV export
uv run python ./examples/devops/web.py # HITL ops assistant + trace dashboard
Classic-pattern ports run as one-liners too:
python -m examples.{reflection,map_reduce,supervisor,summarize,time_travel,adaptive}.main.
Examples (in-repo, not shipped)
knowledge— multi-source chat: search → evidence → claim verification → answer, with CSV calculation.research— goes to the web (WebSource): lazy page fetch → evidence → verified claims → answer with URL provenance.medic-lab— hypothesis laboratory: competing hypotheses scored, HITL steering, honest report.devops— HITL tool agents + LLM tool router + trace dashboard.repair— budget-aware replanning (chat/data in Russian by design).forklab— deterministic branch & merge: two strategies on their own forks, three-way merge.llm_ladder— the workflow from one LLM call to state-changing patches (3 levels).adaptive— hybrid scheduler: rule filters + deterministic rank + LLM tie-break +rank_limit.{reflection,map_reduce,supervisor,summarize,time_travel}— canonical ports (see port-matrix).
Documentation
- English · Русский — concepts, sources, providers, recipes, patterns, observability, eval, branching, replay, viz/CLI, API.
- Why ctxloom — the design argument: why effects, why no graph, why determinism.
- Tutorial · llm-ladder — learn the workflow.
- CONSTITUTION.md — the full design rationale and invariants.
Development
uv sync --extra dev --extra web
.venv/bin/python -m pytest
.venv/bin/mypy
.venv/bin/ruff check
License
MIT — see LICENSE.
Metadata
Release files for ctxloom 0.4.0rc1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ctxloom-0.4.0rc1.tar.gz | 171.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ctxloom-0.4.0rc1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 307.8 kB
Release files / ctxloom-0.4.0rc1.tar.gz
| Download URL | ctxloom-0.4.0rc1.tar.gz |
|---|---|
| Size | 171.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7e69344608209c4ae373f63c4814c429de60f2775f84027769450f75b7e871bf
|
|
BLAKE2b-256 checksum How to use checksums |
49cf44997194c4afdd027e4926829af214044adffc908cdf663a6363151f92ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.5.31
|
Release files / ctxloom-0.4.0rc1-py3-none-any.whl
| Download URL | ctxloom-0.4.0rc1-py3-none-any.whl |
|---|---|
| Size | 136.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a49cdeb30ac7b529765e60eaec1d1c1bcfc518be17822872fc1dc8994a462184
|
|
BLAKE2b-256 checksum How to use checksums |
9065a02028bdd2acf6231d48c83d19228e9a109e40764b4036dc9e0b1fc18b42
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.5.31
|