ctxloom 0.1.0rc1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ctxloom-0.1.0rc1/LICENSE +21 -0
- ctxloom-0.1.0rc1/PKG-INFO +188 -0
- ctxloom-0.1.0rc1/README.md +167 -0
- ctxloom-0.1.0rc1/ctxloom/__init__.py +152 -0
- ctxloom-0.1.0rc1/ctxloom/__main__.py +280 -0
- ctxloom-0.1.0rc1/ctxloom/agents.py +120 -0
- ctxloom-0.1.0rc1/ctxloom/artifacts.py +114 -0
- ctxloom-0.1.0rc1/ctxloom/branching.py +55 -0
- ctxloom-0.1.0rc1/ctxloom/budget.py +38 -0
- ctxloom-0.1.0rc1/ctxloom/checkpoints.py +178 -0
- ctxloom-0.1.0rc1/ctxloom/commit.py +97 -0
- ctxloom-0.1.0rc1/ctxloom/consume.py +96 -0
- ctxloom-0.1.0rc1/ctxloom/context.py +711 -0
- ctxloom-0.1.0rc1/ctxloom/effects.py +191 -0
- ctxloom-0.1.0rc1/ctxloom/eval.py +288 -0
- ctxloom-0.1.0rc1/ctxloom/events.py +33 -0
- ctxloom-0.1.0rc1/ctxloom/interrupt.py +22 -0
- ctxloom-0.1.0rc1/ctxloom/llm_agent.py +158 -0
- ctxloom-0.1.0rc1/ctxloom/operations.py +192 -0
- ctxloom-0.1.0rc1/ctxloom/patches.py +112 -0
- ctxloom-0.1.0rc1/ctxloom/produce.py +162 -0
- ctxloom-0.1.0rc1/ctxloom/prompts.py +111 -0
- ctxloom-0.1.0rc1/ctxloom/providers/__init__.py +123 -0
- ctxloom-0.1.0rc1/ctxloom/providers/anthropic.py +164 -0
- ctxloom-0.1.0rc1/ctxloom/providers/azure.py +31 -0
- ctxloom-0.1.0rc1/ctxloom/providers/cerebras.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/chat.py +269 -0
- ctxloom-0.1.0rc1/ctxloom/providers/contracts.py +101 -0
- ctxloom-0.1.0rc1/ctxloom/providers/deepseek.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/fake.py +40 -0
- ctxloom-0.1.0rc1/ctxloom/providers/fireworks.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/gemini.py +261 -0
- ctxloom-0.1.0rc1/ctxloom/providers/github_models.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/groq.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/image.py +133 -0
- ctxloom-0.1.0rc1/ctxloom/providers/mistral.py +39 -0
- ctxloom-0.1.0rc1/ctxloom/providers/nvidia.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/ollama.py +18 -0
- ctxloom-0.1.0rc1/ctxloom/providers/openai.py +39 -0
- ctxloom-0.1.0rc1/ctxloom/providers/openrouter.py +50 -0
- ctxloom-0.1.0rc1/ctxloom/providers/perplexity.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/qwen.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/speech.py +251 -0
- ctxloom-0.1.0rc1/ctxloom/providers/together.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/video.py +345 -0
- ctxloom-0.1.0rc1/ctxloom/providers/xai.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/providers/zai.py +23 -0
- ctxloom-0.1.0rc1/ctxloom/recipes/__init__.py +42 -0
- ctxloom-0.1.0rc1/ctxloom/recipes/resolve.py +51 -0
- ctxloom-0.1.0rc1/ctxloom/recipes/rollback.py +87 -0
- ctxloom-0.1.0rc1/ctxloom/recipes/search.py +81 -0
- ctxloom-0.1.0rc1/ctxloom/recipes/status.py +79 -0
- ctxloom-0.1.0rc1/ctxloom/recipes/text.py +202 -0
- ctxloom-0.1.0rc1/ctxloom/replay.py +185 -0
- ctxloom-0.1.0rc1/ctxloom/resources.py +29 -0
- ctxloom-0.1.0rc1/ctxloom/runtime.py +549 -0
- ctxloom-0.1.0rc1/ctxloom/scheduler.py +188 -0
- ctxloom-0.1.0rc1/ctxloom/session.py +76 -0
- ctxloom-0.1.0rc1/ctxloom/sources.py +447 -0
- ctxloom-0.1.0rc1/ctxloom/streaming.py +58 -0
- ctxloom-0.1.0rc1/ctxloom/structured.py +194 -0
- ctxloom-0.1.0rc1/ctxloom/tool_use.py +490 -0
- ctxloom-0.1.0rc1/ctxloom/tools.py +111 -0
- ctxloom-0.1.0rc1/ctxloom/tracing/__init__.py +26 -0
- ctxloom-0.1.0rc1/ctxloom/tracing/langfuse.py +125 -0
- ctxloom-0.1.0rc1/ctxloom/tracing/models.py +93 -0
- ctxloom-0.1.0rc1/ctxloom/tracing/postgres.py +90 -0
- ctxloom-0.1.0rc1/ctxloom/tracing/store.py +206 -0
- ctxloom-0.1.0rc1/ctxloom/tracing/templates/ui.html +196 -0
- ctxloom-0.1.0rc1/ctxloom/tracing/templates/ui_run.html +264 -0
- ctxloom-0.1.0rc1/ctxloom/tracing/tracer.py +156 -0
- ctxloom-0.1.0rc1/ctxloom/tracing/web.py +110 -0
- ctxloom-0.1.0rc1/ctxloom/triggers.py +41 -0
- ctxloom-0.1.0rc1/ctxloom/viz.py +248 -0
- ctxloom-0.1.0rc1/ctxloom.egg-info/PKG-INFO +188 -0
- ctxloom-0.1.0rc1/ctxloom.egg-info/SOURCES.txt +137 -0
- ctxloom-0.1.0rc1/ctxloom.egg-info/dependency_links.txt +1 -0
- ctxloom-0.1.0rc1/ctxloom.egg-info/entry_points.txt +2 -0
- ctxloom-0.1.0rc1/ctxloom.egg-info/requires.txt +15 -0
- ctxloom-0.1.0rc1/ctxloom.egg-info/top_level.txt +1 -0
- ctxloom-0.1.0rc1/pyproject.toml +98 -0
- ctxloom-0.1.0rc1/setup.cfg +4 -0
- ctxloom-0.1.0rc1/tests/test_adaptive.py +168 -0
- ctxloom-0.1.0rc1/tests/test_anthropic_provider.py +93 -0
- ctxloom-0.1.0rc1/tests/test_artifacts.py +63 -0
- ctxloom-0.1.0rc1/tests/test_backbone.py +160 -0
- ctxloom-0.1.0rc1/tests/test_branching.py +149 -0
- ctxloom-0.1.0rc1/tests/test_budget.py +118 -0
- ctxloom-0.1.0rc1/tests/test_checkpoint.py +51 -0
- ctxloom-0.1.0rc1/tests/test_concurrency.py +148 -0
- ctxloom-0.1.0rc1/tests/test_consumes_produces.py +64 -0
- ctxloom-0.1.0rc1/tests/test_devops.py +168 -0
- ctxloom-0.1.0rc1/tests/test_devops_web.py +149 -0
- ctxloom-0.1.0rc1/tests/test_effects.py +137 -0
- ctxloom-0.1.0rc1/tests/test_eval.py +210 -0
- ctxloom-0.1.0rc1/tests/test_forklab.py +125 -0
- ctxloom-0.1.0rc1/tests/test_forklab_web.py +74 -0
- ctxloom-0.1.0rc1/tests/test_gemini_provider.py +158 -0
- ctxloom-0.1.0rc1/tests/test_hitl.py +147 -0
- ctxloom-0.1.0rc1/tests/test_invalidation.py +93 -0
- ctxloom-0.1.0rc1/tests/test_knowledge.py +279 -0
- ctxloom-0.1.0rc1/tests/test_knowledge_web.py +123 -0
- ctxloom-0.1.0rc1/tests/test_llm_ladder.py +108 -0
- ctxloom-0.1.0rc1/tests/test_medic_lab.py +220 -0
- ctxloom-0.1.0rc1/tests/test_medic_lab_web.py +54 -0
- ctxloom-0.1.0rc1/tests/test_multisource.py +174 -0
- ctxloom-0.1.0rc1/tests/test_openai_provider.py +95 -0
- ctxloom-0.1.0rc1/tests/test_patches.py +45 -0
- ctxloom-0.1.0rc1/tests/test_ports.py +110 -0
- ctxloom-0.1.0rc1/tests/test_produce_styles.py +137 -0
- ctxloom-0.1.0rc1/tests/test_prompts.py +102 -0
- ctxloom-0.1.0rc1/tests/test_provider_auth.py +219 -0
- ctxloom-0.1.0rc1/tests/test_providers_integration.py +51 -0
- ctxloom-0.1.0rc1/tests/test_recipes.py +231 -0
- ctxloom-0.1.0rc1/tests/test_relations.py +163 -0
- ctxloom-0.1.0rc1/tests/test_repair.py +555 -0
- ctxloom-0.1.0rc1/tests/test_repair_web.py +152 -0
- ctxloom-0.1.0rc1/tests/test_replay.py +154 -0
- ctxloom-0.1.0rc1/tests/test_research.py +81 -0
- ctxloom-0.1.0rc1/tests/test_resources.py +30 -0
- ctxloom-0.1.0rc1/tests/test_runtime.py +144 -0
- ctxloom-0.1.0rc1/tests/test_runtime_errors.py +51 -0
- ctxloom-0.1.0rc1/tests/test_sessions.py +134 -0
- ctxloom-0.1.0rc1/tests/test_sources.py +18 -0
- ctxloom-0.1.0rc1/tests/test_sources_search.py +49 -0
- ctxloom-0.1.0rc1/tests/test_sources_vector.py +87 -0
- ctxloom-0.1.0rc1/tests/test_speech_provider.py +95 -0
- ctxloom-0.1.0rc1/tests/test_streaming.py +68 -0
- ctxloom-0.1.0rc1/tests/test_structured.py +190 -0
- ctxloom-0.1.0rc1/tests/test_tools.py +487 -0
- ctxloom-0.1.0rc1/tests/test_tracing.py +492 -0
- ctxloom-0.1.0rc1/tests/test_vendor_factories.py +55 -0
- ctxloom-0.1.0rc1/tests/test_video_provider.py +222 -0
- ctxloom-0.1.0rc1/tests/test_view.py +69 -0
- ctxloom-0.1.0rc1/tests/test_viz.py +183 -0
- ctxloom-0.1.0rc1/tests/test_web_source.py +70 -0
- ctxloom-0.1.0rc1/tests/test_workspace.py +30 -0
- ctxloom-0.1.0rc1/tests/test_workspace_with_sources.py +53 -0
- ctxloom-0.1.0rc1/tests/tests_checkpoints_sqlite.py +34 -0
ctxloom-0.1.0rc1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 bzdv
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ctxloom
|
|
3
|
+
Version: 0.1.0rc1
|
|
4
|
+
Summary: Reactive, artifact-driven agent runtime: agents transform versioned, typed, provenance-aware artifacts inside an evolving context
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: pydantic>=2.13.4
|
|
9
|
+
Requires-Dist: pytest>=9.1.1
|
|
10
|
+
Requires-Dist: httpx>=0.27
|
|
11
|
+
Requires-Dist: python-dotenv>=1.0
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: ruff>=0.8; extra == "dev"
|
|
14
|
+
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
15
|
+
Provides-Extra: web
|
|
16
|
+
Requires-Dist: fastapi>=0.115; extra == "web"
|
|
17
|
+
Requires-Dist: uvicorn[standard]>=0.30; extra == "web"
|
|
18
|
+
Provides-Extra: pg
|
|
19
|
+
Requires-Dist: psycopg[binary]>=3.2; extra == "pg"
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
|
|
22
|
+
# ctxloom
|
|
23
|
+
|
|
24
|
+
**Reactive, artifact-driven agent runtime.**
|
|
25
|
+
|
|
26
|
+
`ctxloom` is a framework for building agents as reactive, stateful processes
|
|
27
|
+
that transform **versioned, typed, provenance-aware artifacts** inside an
|
|
28
|
+
**evolving context** — instead of describing execution as a graph.
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
ARTIFACT CREATED / UPDATED
|
|
32
|
+
│
|
|
33
|
+
▼
|
|
34
|
+
AGENTS REACT ──self.effects──► Effects ──compile──► Patch
|
|
35
|
+
▲ │
|
|
36
|
+
└──────────────────────────────────────────────────────┘
|
|
37
|
+
Context v+1
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
You describe _what data exists, what artifacts exist, what agents can do with
|
|
41
|
+
them_. The runtime derives execution from state changes: a produce writes
|
|
42
|
+
`self.effects.create/update/link/ask` and returns `None`; the runtime compiles
|
|
43
|
+
the effect set into one **atomic** `Patch` and moves the context to the next
|
|
44
|
+
version. No explicit graphs, no node pipelines.
|
|
45
|
+
|
|
46
|
+
## Core primitives
|
|
47
|
+
|
|
48
|
+
- **Context** — versioned working state, git-like commits, `diff`/`rollback`/`merge`.
|
|
49
|
+
- **Artifact** — a first-class typed object (`Claim`, `Evidence`, `Answer`, …),
|
|
50
|
+
not a string blob.
|
|
51
|
+
- **Effects** — the produce's authoring surface (`self.effects.create/update/link/ask`); the runtime compiles them into a `Patch`.
|
|
52
|
+
- **Patch** — the compiled, validated change-set the runtime applies as one atomic commit (§24).
|
|
53
|
+
- **Agent** — a thin container declaring `consumes`/`produces`; logic lives in `Produce`.
|
|
54
|
+
- **Source** — a retrieval capability. Vector search is _one_ strategy; direct API,
|
|
55
|
+
keyword, SQL, and filesystem are equally first-class. Embeddings optional.
|
|
56
|
+
- **Provenance** — every derived artifact links back to what produced it
|
|
57
|
+
(`Answer —supported_by→ Claim —derived_from→ Evidence —extracted_from→ Doc`).
|
|
58
|
+
- **HITL** — humans interact through `effects.ask(...)` → `PendingQuestion`, answered via `effects.resume(...)` like any agent (§60).
|
|
59
|
+
|
|
60
|
+
## Highlights
|
|
61
|
+
|
|
62
|
+
- Deterministic work stays deterministic (§67): calculations over structured data
|
|
63
|
+
(`CSVSource` → `Spreadsheet` → `Calculation`) instead of hallucinated numbers.
|
|
64
|
+
- Claims carry `confidence` and explicit contradictions (§35–§36), so the model is
|
|
65
|
+
a reasoning component, never the source of truth.
|
|
66
|
+
- Observability built in: every run traces agent spans, reads/writes, LLM calls,
|
|
67
|
+
tokens — SQLite store + web dashboard, exportable to Langfuse/Postgres.
|
|
68
|
+
- Budget by runs/time/iterations/tool-calls with replanning on decline.
|
|
69
|
+
|
|
70
|
+
## Also in the box
|
|
71
|
+
|
|
72
|
+
- **Recipes (`ctxloom.recipes`)** — `fan_out_sources`, `materialize_doc`,
|
|
73
|
+
`StatusMachine`, keyword scoring (EN/RU stems), and the change→rebuild
|
|
74
|
+
rollback helpers — pure, LLM-free.
|
|
75
|
+
- **Branching & merge** (§39-§40) — `context.branch()`, three-way `merge()`
|
|
76
|
+
with explicit `MergeConflict`, `BranchStore` over KV.
|
|
77
|
+
- **Replay** (§55) — `ReplayLLM` records every LLM call and replays a run
|
|
78
|
+
deterministically; state replay via the CLI.
|
|
79
|
+
- **Evaluation harness** (§56) — `ctxloom.eval`: metrics over the final state
|
|
80
|
+
(evidence/claim/provenance/calc/answer), weighted report.
|
|
81
|
+
- **Observability** — SQLite trace store + web dashboard (sequence and
|
|
82
|
+
evidence-graph diagrams), Langfuse/Postgres sinks.
|
|
83
|
+
- **Viz & CLI** — Mermaid `blueprint`/`context_to_mermaid`/`trace_to_mermaid`;
|
|
84
|
+
`python -m ctxloom` with `graph`/`context`/`trace`/`replay`/`branch`.
|
|
85
|
+
- **Sessions & checkpoints** — `SessionStore` over `FileKVBackend`/`SQLiteKVBackend`
|
|
86
|
+
for durable chat memory across requests.
|
|
87
|
+
|
|
88
|
+
## Quick start
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from pydantic import BaseModel
|
|
92
|
+
|
|
93
|
+
from ctxloom import (
|
|
94
|
+
Agent,
|
|
95
|
+
Budget,
|
|
96
|
+
Consume,
|
|
97
|
+
Context,
|
|
98
|
+
Patch,
|
|
99
|
+
Produce,
|
|
100
|
+
Runtime,
|
|
101
|
+
RuntimeResources,
|
|
102
|
+
)
|
|
103
|
+
from ctxloom.sources import FileSystemSource
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class Question(BaseModel):
|
|
107
|
+
text: str
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class Answer(BaseModel):
|
|
111
|
+
text: str
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class Echo(Produce[Answer]):
|
|
115
|
+
artifact_type = Answer
|
|
116
|
+
|
|
117
|
+
async def produce(self, context, inputs, event=None):
|
|
118
|
+
question = next(a for a in inputs if isinstance(a.data, Question))
|
|
119
|
+
self.effects.create(Answer(text=f"echo: {question.data.text}"))
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class EchoAgent(Agent):
|
|
124
|
+
name = "echo"
|
|
125
|
+
consumes = [Consume(Question)]
|
|
126
|
+
produces = [Echo()]
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
ctx = Context(resources=RuntimeResources(sources={"docs": FileSystemSource("./docs")}))
|
|
130
|
+
runtime = Runtime(ctx, agents=[EchoAgent()], budget=Budget(max_runs=10))
|
|
131
|
+
ctx.create(Question(text="hello")) # agents that consume it react automatically
|
|
132
|
+
runtime.run()
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
You describe artifacts, what agents consume and produce — and the runtime derives
|
|
136
|
+
the execution from state changes. Full documentation lives in [docs/](docs/README.md)
|
|
137
|
+
in two languages (English & Русский); the design and invariants are in
|
|
138
|
+
[CONSTITUTION.md](CONSTITUTION.md); the `examples/` ship several full demos and a tutorial ladder.
|
|
139
|
+
|
|
140
|
+
## Examples (in-repo, not shipped)
|
|
141
|
+
|
|
142
|
+
- `examples/knowledge` — multi-source chat: search → evidence → claim verification → answer,
|
|
143
|
+
with CSV calculation (CLI + FastAPI/SSE web).
|
|
144
|
+
- `examples/research` — research agent that _goes to the web_ (`WebSource`):
|
|
145
|
+
lazy page fetch → evidence → verified claims → answer with URL provenance.
|
|
146
|
+
- `examples/medic-lab` — hypothesis laboratory: a question spawns competing
|
|
147
|
+
hypotheses, each is investigated over an evidence pool, scored by
|
|
148
|
+
support/contradiction, and ended with an HITL steering + honest report.
|
|
149
|
+
- `examples/devops` — ops assistant: HITL tool agents + LLM tool router + trace dashboard.
|
|
150
|
+
- `examples/repair` — budget-aware replanning demo (chat and data are in Russian by design).
|
|
151
|
+
- `examples/forklab` — deterministic branch & merge demo (§39-§40): two research
|
|
152
|
+
strategies on their own forks, explicit three-way merge, evaluate on the merged state.
|
|
153
|
+
- `examples/llm_ladder` — the LLM workflow from simplest to state-changing patches
|
|
154
|
+
(3 self-contained levels, offline fallbacks, model mode via `.env`).
|
|
155
|
+
|
|
156
|
+
## Run a demo
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
uv run python ./examples/llm_ladder/level1.py # the simplest LLM turn (offline too)
|
|
160
|
+
uv run python ./examples/repair/web.py # room renovation: plan, estimate, CSV export
|
|
161
|
+
uv run python ./examples/devops/web.py # HITL ops assistant + trace dashboard
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Documentation
|
|
165
|
+
|
|
166
|
+
- [English docs](docs/en/index.md) — the produce contract & mental model,
|
|
167
|
+
concepts, sources, providers, recipes, patterns, observability, eval,
|
|
168
|
+
branching, replay, viz/CLI, examples, API reference.
|
|
169
|
+
- [Русская документация](docs/ru/index.md) — контракт produce и ментальная
|
|
170
|
+
модель, концепции, источники, провайдеры, рецепты, паттерны, наблюдаемость,
|
|
171
|
+
eval, ветвление, replay, viz/CLI, примеры, справочник API.
|
|
172
|
+
- [Tutorial · llm-ladder](docs/en/index.md#llm-ladder) — learn the workflow
|
|
173
|
+
from a single LLM call to linked and lifecycle patches.
|
|
174
|
+
|
|
175
|
+
## Development
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
uv sync --extra dev --extra web
|
|
179
|
+
.venv/bin/python -m pytest
|
|
180
|
+
.venv/bin/mypy
|
|
181
|
+
.venv/bin/ruff check
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
MIT — see [LICENSE](LICENSE).
|
|
187
|
+
|
|
188
|
+
The full design rationale and invariants live in [CONSTITUTION.md](CONSTITUTION.md).
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# ctxloom
|
|
2
|
+
|
|
3
|
+
**Reactive, artifact-driven agent runtime.**
|
|
4
|
+
|
|
5
|
+
`ctxloom` is a framework for building agents as reactive, stateful processes
|
|
6
|
+
that transform **versioned, typed, provenance-aware artifacts** inside an
|
|
7
|
+
**evolving context** — instead of describing execution as a graph.
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
ARTIFACT CREATED / UPDATED
|
|
11
|
+
│
|
|
12
|
+
▼
|
|
13
|
+
AGENTS REACT ──self.effects──► Effects ──compile──► Patch
|
|
14
|
+
▲ │
|
|
15
|
+
└──────────────────────────────────────────────────────┘
|
|
16
|
+
Context v+1
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
You describe _what data exists, what artifacts exist, what agents can do with
|
|
20
|
+
them_. The runtime derives execution from state changes: a produce writes
|
|
21
|
+
`self.effects.create/update/link/ask` and returns `None`; the runtime compiles
|
|
22
|
+
the effect set into one **atomic** `Patch` and moves the context to the next
|
|
23
|
+
version. No explicit graphs, no node pipelines.
|
|
24
|
+
|
|
25
|
+
## Core primitives
|
|
26
|
+
|
|
27
|
+
- **Context** — versioned working state, git-like commits, `diff`/`rollback`/`merge`.
|
|
28
|
+
- **Artifact** — a first-class typed object (`Claim`, `Evidence`, `Answer`, …),
|
|
29
|
+
not a string blob.
|
|
30
|
+
- **Effects** — the produce's authoring surface (`self.effects.create/update/link/ask`); the runtime compiles them into a `Patch`.
|
|
31
|
+
- **Patch** — the compiled, validated change-set the runtime applies as one atomic commit (§24).
|
|
32
|
+
- **Agent** — a thin container declaring `consumes`/`produces`; logic lives in `Produce`.
|
|
33
|
+
- **Source** — a retrieval capability. Vector search is _one_ strategy; direct API,
|
|
34
|
+
keyword, SQL, and filesystem are equally first-class. Embeddings optional.
|
|
35
|
+
- **Provenance** — every derived artifact links back to what produced it
|
|
36
|
+
(`Answer —supported_by→ Claim —derived_from→ Evidence —extracted_from→ Doc`).
|
|
37
|
+
- **HITL** — humans interact through `effects.ask(...)` → `PendingQuestion`, answered via `effects.resume(...)` like any agent (§60).
|
|
38
|
+
|
|
39
|
+
## Highlights
|
|
40
|
+
|
|
41
|
+
- Deterministic work stays deterministic (§67): calculations over structured data
|
|
42
|
+
(`CSVSource` → `Spreadsheet` → `Calculation`) instead of hallucinated numbers.
|
|
43
|
+
- Claims carry `confidence` and explicit contradictions (§35–§36), so the model is
|
|
44
|
+
a reasoning component, never the source of truth.
|
|
45
|
+
- Observability built in: every run traces agent spans, reads/writes, LLM calls,
|
|
46
|
+
tokens — SQLite store + web dashboard, exportable to Langfuse/Postgres.
|
|
47
|
+
- Budget by runs/time/iterations/tool-calls with replanning on decline.
|
|
48
|
+
|
|
49
|
+
## Also in the box
|
|
50
|
+
|
|
51
|
+
- **Recipes (`ctxloom.recipes`)** — `fan_out_sources`, `materialize_doc`,
|
|
52
|
+
`StatusMachine`, keyword scoring (EN/RU stems), and the change→rebuild
|
|
53
|
+
rollback helpers — pure, LLM-free.
|
|
54
|
+
- **Branching & merge** (§39-§40) — `context.branch()`, three-way `merge()`
|
|
55
|
+
with explicit `MergeConflict`, `BranchStore` over KV.
|
|
56
|
+
- **Replay** (§55) — `ReplayLLM` records every LLM call and replays a run
|
|
57
|
+
deterministically; state replay via the CLI.
|
|
58
|
+
- **Evaluation harness** (§56) — `ctxloom.eval`: metrics over the final state
|
|
59
|
+
(evidence/claim/provenance/calc/answer), weighted report.
|
|
60
|
+
- **Observability** — SQLite trace store + web dashboard (sequence and
|
|
61
|
+
evidence-graph diagrams), Langfuse/Postgres sinks.
|
|
62
|
+
- **Viz & CLI** — Mermaid `blueprint`/`context_to_mermaid`/`trace_to_mermaid`;
|
|
63
|
+
`python -m ctxloom` with `graph`/`context`/`trace`/`replay`/`branch`.
|
|
64
|
+
- **Sessions & checkpoints** — `SessionStore` over `FileKVBackend`/`SQLiteKVBackend`
|
|
65
|
+
for durable chat memory across requests.
|
|
66
|
+
|
|
67
|
+
## Quick start
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from pydantic import BaseModel
|
|
71
|
+
|
|
72
|
+
from ctxloom import (
|
|
73
|
+
Agent,
|
|
74
|
+
Budget,
|
|
75
|
+
Consume,
|
|
76
|
+
Context,
|
|
77
|
+
Patch,
|
|
78
|
+
Produce,
|
|
79
|
+
Runtime,
|
|
80
|
+
RuntimeResources,
|
|
81
|
+
)
|
|
82
|
+
from ctxloom.sources import FileSystemSource
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class Question(BaseModel):
|
|
86
|
+
text: str
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class Answer(BaseModel):
|
|
90
|
+
text: str
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class Echo(Produce[Answer]):
|
|
94
|
+
artifact_type = Answer
|
|
95
|
+
|
|
96
|
+
async def produce(self, context, inputs, event=None):
|
|
97
|
+
question = next(a for a in inputs if isinstance(a.data, Question))
|
|
98
|
+
self.effects.create(Answer(text=f"echo: {question.data.text}"))
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class EchoAgent(Agent):
|
|
103
|
+
name = "echo"
|
|
104
|
+
consumes = [Consume(Question)]
|
|
105
|
+
produces = [Echo()]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
ctx = Context(resources=RuntimeResources(sources={"docs": FileSystemSource("./docs")}))
|
|
109
|
+
runtime = Runtime(ctx, agents=[EchoAgent()], budget=Budget(max_runs=10))
|
|
110
|
+
ctx.create(Question(text="hello")) # agents that consume it react automatically
|
|
111
|
+
runtime.run()
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
You describe artifacts, what agents consume and produce — and the runtime derives
|
|
115
|
+
the execution from state changes. Full documentation lives in [docs/](docs/README.md)
|
|
116
|
+
in two languages (English & Русский); the design and invariants are in
|
|
117
|
+
[CONSTITUTION.md](CONSTITUTION.md); the `examples/` ship several full demos and a tutorial ladder.
|
|
118
|
+
|
|
119
|
+
## Examples (in-repo, not shipped)
|
|
120
|
+
|
|
121
|
+
- `examples/knowledge` — multi-source chat: search → evidence → claim verification → answer,
|
|
122
|
+
with CSV calculation (CLI + FastAPI/SSE web).
|
|
123
|
+
- `examples/research` — research agent that _goes to the web_ (`WebSource`):
|
|
124
|
+
lazy page fetch → evidence → verified claims → answer with URL provenance.
|
|
125
|
+
- `examples/medic-lab` — hypothesis laboratory: a question spawns competing
|
|
126
|
+
hypotheses, each is investigated over an evidence pool, scored by
|
|
127
|
+
support/contradiction, and ended with an HITL steering + honest report.
|
|
128
|
+
- `examples/devops` — ops assistant: HITL tool agents + LLM tool router + trace dashboard.
|
|
129
|
+
- `examples/repair` — budget-aware replanning demo (chat and data are in Russian by design).
|
|
130
|
+
- `examples/forklab` — deterministic branch & merge demo (§39-§40): two research
|
|
131
|
+
strategies on their own forks, explicit three-way merge, evaluate on the merged state.
|
|
132
|
+
- `examples/llm_ladder` — the LLM workflow from simplest to state-changing patches
|
|
133
|
+
(3 self-contained levels, offline fallbacks, model mode via `.env`).
|
|
134
|
+
|
|
135
|
+
## Run a demo
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
uv run python ./examples/llm_ladder/level1.py # the simplest LLM turn (offline too)
|
|
139
|
+
uv run python ./examples/repair/web.py # room renovation: plan, estimate, CSV export
|
|
140
|
+
uv run python ./examples/devops/web.py # HITL ops assistant + trace dashboard
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Documentation
|
|
144
|
+
|
|
145
|
+
- [English docs](docs/en/index.md) — the produce contract & mental model,
|
|
146
|
+
concepts, sources, providers, recipes, patterns, observability, eval,
|
|
147
|
+
branching, replay, viz/CLI, examples, API reference.
|
|
148
|
+
- [Русская документация](docs/ru/index.md) — контракт produce и ментальная
|
|
149
|
+
модель, концепции, источники, провайдеры, рецепты, паттерны, наблюдаемость,
|
|
150
|
+
eval, ветвление, replay, viz/CLI, примеры, справочник API.
|
|
151
|
+
- [Tutorial · llm-ladder](docs/en/index.md#llm-ladder) — learn the workflow
|
|
152
|
+
from a single LLM call to linked and lifecycle patches.
|
|
153
|
+
|
|
154
|
+
## Development
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
uv sync --extra dev --extra web
|
|
158
|
+
.venv/bin/python -m pytest
|
|
159
|
+
.venv/bin/mypy
|
|
160
|
+
.venv/bin/ruff check
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT — see [LICENSE](LICENSE).
|
|
166
|
+
|
|
167
|
+
The full design rationale and invariants live in [CONSTITUTION.md](CONSTITUTION.md).
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from .agents import Agent
|
|
2
|
+
from .artifacts import Artifact
|
|
3
|
+
from .branching import BranchStore
|
|
4
|
+
from .budget import Budget, RunOutcome, RunStats
|
|
5
|
+
from .checkpoints import (
|
|
6
|
+
CheckpointBackend,
|
|
7
|
+
FileBackend,
|
|
8
|
+
FileKVBackend,
|
|
9
|
+
KVBackend,
|
|
10
|
+
SQLiteBackend,
|
|
11
|
+
SQLiteKVBackend,
|
|
12
|
+
)
|
|
13
|
+
from .commit import Commit, Read, Write
|
|
14
|
+
from .consume import Consume, consume
|
|
15
|
+
from .context import Context, MergeConflict, View
|
|
16
|
+
from .eval import (
|
|
17
|
+
EvalCase,
|
|
18
|
+
EvalReport,
|
|
19
|
+
EvalResult,
|
|
20
|
+
Metric,
|
|
21
|
+
answer_coverage,
|
|
22
|
+
answer_present,
|
|
23
|
+
calculation_correctness,
|
|
24
|
+
claim_verification,
|
|
25
|
+
core_metrics,
|
|
26
|
+
evidence_quality,
|
|
27
|
+
provenance_grounded,
|
|
28
|
+
run_case,
|
|
29
|
+
run_suite,
|
|
30
|
+
source_coverage,
|
|
31
|
+
)
|
|
32
|
+
from .events import Event, EventType
|
|
33
|
+
from .interrupt import PendingQuestion
|
|
34
|
+
from .llm_agent import HITLLMAgent, LLMAgent, StructuredGenerateAgent
|
|
35
|
+
from .patches import Create, Delete, Link, Patch, Relation, Unlink, Update
|
|
36
|
+
from .produce import Produce, produce
|
|
37
|
+
from .prompts import MessagesPrompt, PromptTemplate
|
|
38
|
+
from .providers import (
|
|
39
|
+
EmbeddingProvider,
|
|
40
|
+
FakeEmbedder,
|
|
41
|
+
FakeLLM,
|
|
42
|
+
LLMProvider,
|
|
43
|
+
LLMRequest,
|
|
44
|
+
LLMResponse,
|
|
45
|
+
LLMResponseChunk,
|
|
46
|
+
Message,
|
|
47
|
+
)
|
|
48
|
+
from .replay import ReplayLLM, ReplayMiss, replay_context, replay_summary
|
|
49
|
+
from .resources import RuntimeResources
|
|
50
|
+
from .runtime import Runtime
|
|
51
|
+
from .scheduler import Scheduler, uncertainty_policy
|
|
52
|
+
from .session import Session, SessionStore
|
|
53
|
+
from .streaming import EventHub, ProgressEvent
|
|
54
|
+
from .structured import (
|
|
55
|
+
StructuredLLM,
|
|
56
|
+
llm_reply,
|
|
57
|
+
parse_structured,
|
|
58
|
+
structured_llm,
|
|
59
|
+
)
|
|
60
|
+
from .tool_use import Observation, ToolAnswer, ToolUse, ToolUseHITL
|
|
61
|
+
from .tools import FunctionTool, Tool, ToolOutput, tool
|
|
62
|
+
from .tracing import AgentSpan, CompositeTracer, RunTrace, Tracer, TraceStore
|
|
63
|
+
from .triggers import Trigger
|
|
64
|
+
from .viz import (
|
|
65
|
+
blueprint,
|
|
66
|
+
context_to_mermaid,
|
|
67
|
+
trace_provenance_to_mermaid,
|
|
68
|
+
trace_to_mermaid,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
__version__ = "0.1.0rc1"
|
|
72
|
+
|
|
73
|
+
__all__ = [
|
|
74
|
+
"Agent",
|
|
75
|
+
"Artifact",
|
|
76
|
+
"Budget",
|
|
77
|
+
"BranchStore",
|
|
78
|
+
"CheckpointBackend",
|
|
79
|
+
"Commit",
|
|
80
|
+
"Consume",
|
|
81
|
+
"Context",
|
|
82
|
+
"Create",
|
|
83
|
+
"Delete",
|
|
84
|
+
"EmbeddingProvider",
|
|
85
|
+
"Event",
|
|
86
|
+
"EventHub",
|
|
87
|
+
"EventType",
|
|
88
|
+
"FakeEmbedder",
|
|
89
|
+
"FakeLLM",
|
|
90
|
+
"FileBackend",
|
|
91
|
+
"FileKVBackend",
|
|
92
|
+
"FunctionTool",
|
|
93
|
+
"HITLLMAgent",
|
|
94
|
+
"KVBackend",
|
|
95
|
+
"LLMAgent",
|
|
96
|
+
"LLMProvider",
|
|
97
|
+
"LLMRequest",
|
|
98
|
+
"LLMResponse",
|
|
99
|
+
"LLMResponseChunk",
|
|
100
|
+
"Link",
|
|
101
|
+
"Message",
|
|
102
|
+
"MessagesPrompt",
|
|
103
|
+
"MergeConflict",
|
|
104
|
+
"Metric",
|
|
105
|
+
"Observation",
|
|
106
|
+
"Patch",
|
|
107
|
+
"PendingQuestion",
|
|
108
|
+
"Produce",
|
|
109
|
+
"ProgressEvent",
|
|
110
|
+
"PromptTemplate",
|
|
111
|
+
"Read",
|
|
112
|
+
"Relation",
|
|
113
|
+
"RunOutcome",
|
|
114
|
+
"RunStats",
|
|
115
|
+
"Runtime",
|
|
116
|
+
"Scheduler",
|
|
117
|
+
"RuntimeResources",
|
|
118
|
+
"ReplayLLM",
|
|
119
|
+
"ReplayMiss",
|
|
120
|
+
"SQLiteBackend",
|
|
121
|
+
"SQLiteKVBackend",
|
|
122
|
+
"Session",
|
|
123
|
+
"SessionStore",
|
|
124
|
+
"StructuredGenerateAgent",
|
|
125
|
+
"StructuredLLM",
|
|
126
|
+
"Tool",
|
|
127
|
+
"ToolAnswer",
|
|
128
|
+
"ToolOutput",
|
|
129
|
+
"ToolUse",
|
|
130
|
+
"ToolUseHITL",
|
|
131
|
+
"TraceStore",
|
|
132
|
+
"Tracer",
|
|
133
|
+
"Trigger",
|
|
134
|
+
"Unlink",
|
|
135
|
+
"uncertainty_policy",
|
|
136
|
+
"Update",
|
|
137
|
+
"View",
|
|
138
|
+
"Write",
|
|
139
|
+
"AgentSpan",
|
|
140
|
+
"CompositeTracer",
|
|
141
|
+
"RunTrace",
|
|
142
|
+
"blueprint",
|
|
143
|
+
"consume",
|
|
144
|
+
"context_to_mermaid",
|
|
145
|
+
"llm_reply",
|
|
146
|
+
"parse_structured",
|
|
147
|
+
"produce",
|
|
148
|
+
"structured_llm",
|
|
149
|
+
"tool",
|
|
150
|
+
"trace_provenance_to_mermaid",
|
|
151
|
+
"trace_to_mermaid",
|
|
152
|
+
]
|