activegraph 1.0.0__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.
Files changed (150) hide show
  1. activegraph-1.0.0/PKG-INFO +282 -0
  2. activegraph-1.0.0/README.md +241 -0
  3. activegraph-1.0.0/activegraph/__init__.py +222 -0
  4. activegraph-1.0.0/activegraph/__main__.py +5 -0
  5. activegraph-1.0.0/activegraph/behaviors/__init__.py +1 -0
  6. activegraph-1.0.0/activegraph/behaviors/base.py +153 -0
  7. activegraph-1.0.0/activegraph/behaviors/decorators.py +218 -0
  8. activegraph-1.0.0/activegraph/cli/__init__.py +17 -0
  9. activegraph-1.0.0/activegraph/cli/main.py +793 -0
  10. activegraph-1.0.0/activegraph/cli/quickstart.py +556 -0
  11. activegraph-1.0.0/activegraph/core/__init__.py +1 -0
  12. activegraph-1.0.0/activegraph/core/clock.py +46 -0
  13. activegraph-1.0.0/activegraph/core/event.py +33 -0
  14. activegraph-1.0.0/activegraph/core/graph.py +846 -0
  15. activegraph-1.0.0/activegraph/core/ids.py +135 -0
  16. activegraph-1.0.0/activegraph/core/patch.py +47 -0
  17. activegraph-1.0.0/activegraph/core/view.py +59 -0
  18. activegraph-1.0.0/activegraph/errors.py +345 -0
  19. activegraph-1.0.0/activegraph/frame.py +15 -0
  20. activegraph-1.0.0/activegraph/llm/__init__.py +51 -0
  21. activegraph-1.0.0/activegraph/llm/anthropic.py +339 -0
  22. activegraph-1.0.0/activegraph/llm/cache.py +180 -0
  23. activegraph-1.0.0/activegraph/llm/errors.py +257 -0
  24. activegraph-1.0.0/activegraph/llm/prompt.py +420 -0
  25. activegraph-1.0.0/activegraph/llm/provider.py +66 -0
  26. activegraph-1.0.0/activegraph/llm/recorded.py +270 -0
  27. activegraph-1.0.0/activegraph/llm/types.py +130 -0
  28. activegraph-1.0.0/activegraph/observability/__init__.py +61 -0
  29. activegraph-1.0.0/activegraph/observability/logging.py +205 -0
  30. activegraph-1.0.0/activegraph/observability/metrics.py +219 -0
  31. activegraph-1.0.0/activegraph/observability/migration.py +404 -0
  32. activegraph-1.0.0/activegraph/observability/prometheus.py +101 -0
  33. activegraph-1.0.0/activegraph/observability/status.py +83 -0
  34. activegraph-1.0.0/activegraph/packs/__init__.py +999 -0
  35. activegraph-1.0.0/activegraph/packs/diligence/__init__.py +86 -0
  36. activegraph-1.0.0/activegraph/packs/diligence/behaviors.py +447 -0
  37. activegraph-1.0.0/activegraph/packs/diligence/fixtures/__init__.py +364 -0
  38. activegraph-1.0.0/activegraph/packs/diligence/fixtures/companies.py +511 -0
  39. activegraph-1.0.0/activegraph/packs/diligence/object_types.py +163 -0
  40. activegraph-1.0.0/activegraph/packs/diligence/prompts/document_researcher.md +25 -0
  41. activegraph-1.0.0/activegraph/packs/diligence/prompts/memo_synthesizer.md +35 -0
  42. activegraph-1.0.0/activegraph/packs/diligence/prompts/question_generator.md +25 -0
  43. activegraph-1.0.0/activegraph/packs/diligence/prompts/risk_identifier.md +26 -0
  44. activegraph-1.0.0/activegraph/packs/diligence/settings.py +60 -0
  45. activegraph-1.0.0/activegraph/packs/diligence/tools.py +124 -0
  46. activegraph-1.0.0/activegraph/packs/loader.py +709 -0
  47. activegraph-1.0.0/activegraph/packs/scaffold.py +317 -0
  48. activegraph-1.0.0/activegraph/policy.py +20 -0
  49. activegraph-1.0.0/activegraph/runtime/__init__.py +1 -0
  50. activegraph-1.0.0/activegraph/runtime/behavior_graph.py +151 -0
  51. activegraph-1.0.0/activegraph/runtime/budget.py +120 -0
  52. activegraph-1.0.0/activegraph/runtime/config_errors.py +124 -0
  53. activegraph-1.0.0/activegraph/runtime/diff.py +145 -0
  54. activegraph-1.0.0/activegraph/runtime/errors.py +216 -0
  55. activegraph-1.0.0/activegraph/runtime/exec_errors.py +232 -0
  56. activegraph-1.0.0/activegraph/runtime/patterns.py +946 -0
  57. activegraph-1.0.0/activegraph/runtime/queue.py +27 -0
  58. activegraph-1.0.0/activegraph/runtime/registration_errors.py +291 -0
  59. activegraph-1.0.0/activegraph/runtime/registry.py +111 -0
  60. activegraph-1.0.0/activegraph/runtime/runtime.py +2441 -0
  61. activegraph-1.0.0/activegraph/runtime/scheduler.py +206 -0
  62. activegraph-1.0.0/activegraph/runtime/view_builder.py +65 -0
  63. activegraph-1.0.0/activegraph/store/__init__.py +41 -0
  64. activegraph-1.0.0/activegraph/store/base.py +66 -0
  65. activegraph-1.0.0/activegraph/store/conformance.py +161 -0
  66. activegraph-1.0.0/activegraph/store/errors.py +84 -0
  67. activegraph-1.0.0/activegraph/store/memory.py +118 -0
  68. activegraph-1.0.0/activegraph/store/postgres.py +609 -0
  69. activegraph-1.0.0/activegraph/store/serde.py +202 -0
  70. activegraph-1.0.0/activegraph/store/sqlite.py +446 -0
  71. activegraph-1.0.0/activegraph/store/url.py +230 -0
  72. activegraph-1.0.0/activegraph/tools/__init__.py +64 -0
  73. activegraph-1.0.0/activegraph/tools/base.py +57 -0
  74. activegraph-1.0.0/activegraph/tools/cache.py +157 -0
  75. activegraph-1.0.0/activegraph/tools/context.py +48 -0
  76. activegraph-1.0.0/activegraph/tools/decorators.py +70 -0
  77. activegraph-1.0.0/activegraph/tools/errors.py +320 -0
  78. activegraph-1.0.0/activegraph/tools/graph_query.py +94 -0
  79. activegraph-1.0.0/activegraph/tools/recorded.py +205 -0
  80. activegraph-1.0.0/activegraph/tools/web_fetch.py +80 -0
  81. activegraph-1.0.0/activegraph/trace/__init__.py +1 -0
  82. activegraph-1.0.0/activegraph/trace/causal.py +123 -0
  83. activegraph-1.0.0/activegraph/trace/printer.py +495 -0
  84. activegraph-1.0.0/activegraph.egg-info/PKG-INFO +282 -0
  85. activegraph-1.0.0/activegraph.egg-info/SOURCES.txt +148 -0
  86. activegraph-1.0.0/activegraph.egg-info/dependency_links.txt +1 -0
  87. activegraph-1.0.0/activegraph.egg-info/entry_points.txt +5 -0
  88. activegraph-1.0.0/activegraph.egg-info/requires.txt +31 -0
  89. activegraph-1.0.0/activegraph.egg-info/top_level.txt +1 -0
  90. activegraph-1.0.0/pyproject.toml +190 -0
  91. activegraph-1.0.0/setup.cfg +4 -0
  92. activegraph-1.0.0/tests/test_activate_after.py +131 -0
  93. activegraph-1.0.0/tests/test_causal_cross_tool.py +139 -0
  94. activegraph-1.0.0/tests/test_cli.py +535 -0
  95. activegraph-1.0.0/tests/test_clock.py +15 -0
  96. activegraph-1.0.0/tests/test_diff.py +121 -0
  97. activegraph-1.0.0/tests/test_diligence_pack.py +196 -0
  98. activegraph-1.0.0/tests/test_diligence_with_tools.py +74 -0
  99. activegraph-1.0.0/tests/test_doc_links.py +299 -0
  100. activegraph-1.0.0/tests/test_doc_site_reachable.py +121 -0
  101. activegraph-1.0.0/tests/test_errors_format.py +1498 -0
  102. activegraph-1.0.0/tests/test_event.py +29 -0
  103. activegraph-1.0.0/tests/test_fork.py +167 -0
  104. activegraph-1.0.0/tests/test_graph.py +110 -0
  105. activegraph-1.0.0/tests/test_ids.py +22 -0
  106. activegraph-1.0.0/tests/test_llm_anthropic.py +185 -0
  107. activegraph-1.0.0/tests/test_llm_behavior.py +231 -0
  108. activegraph-1.0.0/tests/test_llm_budget.py +152 -0
  109. activegraph-1.0.0/tests/test_llm_causal.py +66 -0
  110. activegraph-1.0.0/tests/test_llm_claim_extraction.py +84 -0
  111. activegraph-1.0.0/tests/test_llm_determinism.py +106 -0
  112. activegraph-1.0.0/tests/test_llm_failure.py +214 -0
  113. activegraph-1.0.0/tests/test_llm_prompt.py +357 -0
  114. activegraph-1.0.0/tests/test_llm_provider_fixtures.py +132 -0
  115. activegraph-1.0.0/tests/test_llm_replay.py +263 -0
  116. activegraph-1.0.0/tests/test_llm_tool_loop.py +312 -0
  117. activegraph-1.0.0/tests/test_llm_trace.py +144 -0
  118. activegraph-1.0.0/tests/test_llm_trace_snapshot.py +112 -0
  119. activegraph-1.0.0/tests/test_llm_types.py +51 -0
  120. activegraph-1.0.0/tests/test_migration.py +190 -0
  121. activegraph-1.0.0/tests/test_observability_logging.py +135 -0
  122. activegraph-1.0.0/tests/test_observability_metrics.py +215 -0
  123. activegraph-1.0.0/tests/test_operate_example.py +40 -0
  124. activegraph-1.0.0/tests/test_pack_scaffold.py +119 -0
  125. activegraph-1.0.0/tests/test_packs.py +561 -0
  126. activegraph-1.0.0/tests/test_patch.py +61 -0
  127. activegraph-1.0.0/tests/test_pattern_matcher.py +160 -0
  128. activegraph-1.0.0/tests/test_pattern_parser.py +221 -0
  129. activegraph-1.0.0/tests/test_pattern_subscriptions.py +132 -0
  130. activegraph-1.0.0/tests/test_persistence.py +382 -0
  131. activegraph-1.0.0/tests/test_postgres_store.py +51 -0
  132. activegraph-1.0.0/tests/test_quickstart.py +309 -0
  133. activegraph-1.0.0/tests/test_quickstart_snapshot.py +72 -0
  134. activegraph-1.0.0/tests/test_replay.py +128 -0
  135. activegraph-1.0.0/tests/test_replay_trace_snapshot.py +51 -0
  136. activegraph-1.0.0/tests/test_requeue_unfired.py +206 -0
  137. activegraph-1.0.0/tests/test_resume_example.py +148 -0
  138. activegraph-1.0.0/tests/test_runtime.py +125 -0
  139. activegraph-1.0.0/tests/test_runtime_status.py +149 -0
  140. activegraph-1.0.0/tests/test_serde.py +65 -0
  141. activegraph-1.0.0/tests/test_store_conformance.py +46 -0
  142. activegraph-1.0.0/tests/test_store_url.py +57 -0
  143. activegraph-1.0.0/tests/test_tool_replay.py +196 -0
  144. activegraph-1.0.0/tests/test_tool_trace_snapshot.py +128 -0
  145. activegraph-1.0.0/tests/test_tools.py +282 -0
  146. activegraph-1.0.0/tests/test_trace.py +39 -0
  147. activegraph-1.0.0/tests/test_tutorial_snippets.py +167 -0
  148. activegraph-1.0.0/tests/test_version_sync.py +30 -0
  149. activegraph-1.0.0/tests/test_view.py +47 -0
  150. activegraph-1.0.0/tests/test_wheel_completeness.py +99 -0
@@ -0,0 +1,282 @@
1
+ Metadata-Version: 2.4
2
+ Name: activegraph
3
+ Version: 1.0.0
4
+ Summary: An event-sourced reactive graph runtime for long-running, auditable, agentic systems.
5
+ Author: Active Graph contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yoheinakajima/activegraph
8
+ Keywords: graph,agents,event-sourcing,runtime
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Requires-Python: >=3.11
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: click<9,>=8
18
+ Requires-Dist: pydantic>=2
19
+ Provides-Extra: llm
20
+ Requires-Dist: anthropic>=0.40; extra == "llm"
21
+ Requires-Dist: pydantic>=2; extra == "llm"
22
+ Provides-Extra: sqlite
23
+ Provides-Extra: postgres
24
+ Requires-Dist: psycopg[binary]<4,>=3.1; extra == "postgres"
25
+ Provides-Extra: prometheus
26
+ Requires-Dist: prometheus_client>=0.20; extra == "prometheus"
27
+ Provides-Extra: all
28
+ Requires-Dist: anthropic>=0.40; extra == "all"
29
+ Requires-Dist: pydantic>=2; extra == "all"
30
+ Requires-Dist: psycopg[binary]<4,>=3.1; extra == "all"
31
+ Requires-Dist: prometheus_client>=0.20; extra == "all"
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=7; extra == "dev"
34
+ Requires-Dist: pydantic>=2; extra == "dev"
35
+ Requires-Dist: prometheus_client>=0.20; extra == "dev"
36
+ Requires-Dist: psycopg[binary]<4,>=3.1; extra == "dev"
37
+ Provides-Extra: docs
38
+ Requires-Dist: mkdocs>=1.6; extra == "docs"
39
+ Requires-Dist: mkdocs-material>=9.5; extra == "docs"
40
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
41
+
42
+ # Active Graph
43
+
44
+ > The graph is the world. Behaviors are physics. The trace is the proof.
45
+
46
+ An event-sourced reactive graph runtime for long-running, auditable,
47
+ agentic systems. Behaviors react to a shared graph instead of talking
48
+ to each other. Every change is traceable. Every run is resumable,
49
+ forkable, and diff-able from its event log.
50
+
51
+ If chat-based agents are a group conversation, Active Graph is a
52
+ shared workspace where everyone can see what changed, who changed
53
+ it, and why.
54
+
55
+ ## Try it in 30 seconds
56
+
57
+ ```bash
58
+ pip install activegraph
59
+ activegraph quickstart
60
+ ```
61
+
62
+ The bundled Diligence pack runs against recorded fixtures: no API
63
+ key, no configuration, byte-deterministic output. You see what the
64
+ framework does before you read about how it does it.
65
+
66
+ Then walk the 10-minute tutorial:
67
+
68
+ ```bash
69
+ activegraph quickstart --interactive
70
+ ```
71
+
72
+ It scaffolds a behavior, runs it against the same fixtures, and ends
73
+ with the fork-and-diff workflow — the framework's most differentiated
74
+ capability.
75
+
76
+ ## Install
77
+
78
+ ```bash
79
+ pip install activegraph # core runtime + SQLite store + Diligence pack
80
+ pip install "activegraph[llm]" # Anthropic provider
81
+ pip install "activegraph[postgres]" # Postgres-backed event store
82
+ pip install "activegraph[prometheus]" # Prometheus metrics
83
+ pip install "activegraph[all]" # everything
84
+ ```
85
+
86
+ Python 3.11+. Two hard dependencies (`click` for the CLI, `pydantic`
87
+ for the pack format); persistence backends and provider integrations
88
+ are opt-in extras.
89
+
90
+ ## What you get
91
+
92
+ - **Event-sourced graph runtime.** Objects + typed relations + an
93
+ append-only event log. Every mutation is an event; the trace is the
94
+ audit trail.
95
+ - **Reactive behaviors as first-class.** Function, class, LLM-backed,
96
+ or attached to typed edges (the relation-behavior primitive — edges
97
+ with logic). Subscriptions are event type + predicate + a Cypher
98
+ subset for graph-shape patterns.
99
+ - **Fork-and-diff.** Branch any run at any event into an independent
100
+ fork, configure it differently, and structurally diff the result
101
+ against the parent. Cache replay means the shared prefix doesn't
102
+ re-execute (no new LLM calls). Most agent frameworks can't do this.
103
+ - **Packs.** A pack bundles object types, behaviors, tools, prompts,
104
+ and policies for a specific domain. The bundled
105
+ [Diligence pack](activegraph/packs/diligence) is the reference:
106
+ 8 object types, 7 behaviors, 3 tools, recorded fixtures.
107
+ - **Per-error reference pages.** Every error message ends with a
108
+ `More:` link to a page that explains when it fires, why, and how to
109
+ fix it. Catalog at [docs.activegraph.ai/reference/errors](https://docs.activegraph.ai/reference/errors/).
110
+
111
+ ## Concepts at a glance
112
+
113
+ The framework's twelve primitives, in roughly the order you meet them
114
+ when reading a trace. Each links to its concept page on the doc site;
115
+ read those when you want depth on one piece.
116
+
117
+ - **Graph** — objects and typed relations forming the world the
118
+ framework reasons about. The graph is a projection of the event log;
119
+ every mutation is an event. [→ concepts/graph](https://docs.activegraph.ai/concepts/graph/)
120
+ - **Events** — the append-only history. Every behavior fires in
121
+ response to events and produces more events; the trace is the
122
+ ordered log of all of them. [→ concepts/events](https://docs.activegraph.ai/concepts/events/)
123
+ - **Behaviors** — the unit of reactive code. Function, class, or
124
+ LLM-backed; declares what events it subscribes to and what it
125
+ produces. The determinism contract is per-behavior. [→ concepts/behaviors](https://docs.activegraph.ai/concepts/behaviors/)
126
+ - **Relations** — typed edges between objects, with their own
127
+ behaviors. The relation-behavior primitive — coordination logic on
128
+ the edge, not on either endpoint — is uncommon in other agent
129
+ frameworks. [→ concepts/relations](https://docs.activegraph.ai/concepts/relations/)
130
+ - **Patches** — proposed mutations with optimistic concurrency.
131
+ Behaviors propose patches; the runtime applies or rejects them;
132
+ rejections are events in their own right. [→ concepts/patches](https://docs.activegraph.ai/concepts/patches/)
133
+ - **Views** — scoped reads of the graph for behavior context. Type
134
+ filters, depth filters, recent-event windows. Views are how
135
+ pattern-driven behaviors see only what they need to. [→ concepts/views](https://docs.activegraph.ai/concepts/views/)
136
+ - **Frames** — bounded contexts for a run. Goal, constraints, budget,
137
+ and the registered behaviors for this frame. A run can have one
138
+ frame or many. [→ concepts/frames](https://docs.activegraph.ai/concepts/frames/)
139
+ - **Policies** — approval and gating for behavior capabilities. Which
140
+ behaviors can call which tools, which mutations require human
141
+ approval, what the runtime refuses. [→ concepts/policies](https://docs.activegraph.ai/concepts/policies/)
142
+ - **Patterns** — the Cypher subset for pattern subscriptions. Beyond
143
+ event-type + predicate, behaviors can subscribe to graph shapes
144
+ (claim-cited-by-evidence, task-blocks-task, …) with `NOT EXISTS`
145
+ and temporal predicates. [→ concepts/patterns](https://docs.activegraph.ai/concepts/patterns/)
146
+ - **Replay** — re-execute a run from its event log. Strict mode
147
+ re-fires every behavior and fails on divergence; permissive mode
148
+ reconstructs state without re-firing. The LLM replay cache is what
149
+ makes fork cheap. [→ concepts/replay](https://docs.activegraph.ai/concepts/replay/)
150
+ - **Forking** — branch any run at any event into an independent
151
+ fork; structurally diff the fork against the parent. The framework's
152
+ mechanism for hypothesis testing on agentic systems. [→ concepts/forking](https://docs.activegraph.ai/concepts/forking/)
153
+ - **Failure model** — a behavior failure is a `behavior.failed`
154
+ event, not an exception. The audit trail captures failures as
155
+ first-class history. Exceptions live at runtime entry points only.
156
+ [→ concepts/failure-model](https://docs.activegraph.ai/concepts/failure-model/)
157
+
158
+ ## A small example
159
+
160
+ The relation-behavior primitive — coordination logic on the edge,
161
+ not on either endpoint:
162
+
163
+ ```python
164
+ from activegraph import Graph, Runtime, behavior, relation_behavior
165
+
166
+ graph = Graph()
167
+ runtime = Runtime(graph, budget={"max_events": 200, "max_seconds": 60})
168
+
169
+ @behavior(name="planner", on=["goal.created"])
170
+ def planner(event, graph, ctx):
171
+ research = graph.add_object("task", {"title": "Research", "status": "open"})
172
+ memo = graph.add_object("task", {"title": "Draft memo", "status": "blocked"})
173
+ graph.add_relation(research.id, memo.id, "depends_on")
174
+
175
+ @behavior(name="researcher", on=["object.created"], where={"object.type": "task"})
176
+ def researcher(event, graph, ctx):
177
+ task = event.payload["object"]
178
+ if task["data"]["status"] != "open" or "Research" not in task["data"]["title"]:
179
+ return
180
+ graph.add_object("claim", {"text": "Market early but growing.", "confidence": 0.7})
181
+ graph.emit("task.completed", {"task_id": task["id"]})
182
+
183
+ @relation_behavior(name="unblock", relation_type="depends_on", on=["task.completed"])
184
+ def unblock(relation, event, graph, ctx):
185
+ if event.payload["task_id"] == relation.source:
186
+ graph.patch_object(relation.target, {"status": "open"})
187
+
188
+ runtime.run_goal("Evaluate this startup idea")
189
+ runtime.print_trace()
190
+ ```
191
+
192
+ The `unblock` relation behavior fires only for events touching one of
193
+ its edge endpoints. The conceptual deep-dive on edges-with-logic is
194
+ in [`docs/concepts/relations.md`](https://docs.activegraph.ai/concepts/relations/).
195
+
196
+ ## Documentation
197
+
198
+ - **[docs.activegraph.ai](https://docs.activegraph.ai/)** — full doc site:
199
+ concepts, guides, cookbook, CLI reference, API reference, the
200
+ per-error catalog.
201
+ - **[10-minute tutorial](https://docs.activegraph.ai/quickstart/)** — install
202
+ to a working custom behavior, including fork-and-diff.
203
+ - **[CHANGELOG.md](CHANGELOG.md)** — every release, with per-version
204
+ migration notes.
205
+ - **[CONTRACT.md](CONTRACT.md)** — locked design decisions, version
206
+ by version. Useful when you want to know *why* something is the way
207
+ it is.
208
+ - **[examples/](examples)** — runnable end-to-end demos:
209
+ [`diligence_real_run.py`](examples/diligence_real_run.py),
210
+ [`resume_and_fork.py`](examples/resume_and_fork.py),
211
+ [`llm_claim_extraction.py`](examples/llm_claim_extraction.py),
212
+ [`diligence_with_tools.py`](examples/diligence_with_tools.py),
213
+ [`operate_a_run.py`](examples/operate_a_run.py).
214
+
215
+ ## What this is not
216
+
217
+ - Not a chat framework. If your problem fits in one conversation, use
218
+ a chat framework.
219
+ - Not a workflow engine. Workflows model control flow. This models
220
+ world state.
221
+ - Not a rules engine, exactly. Rules engines forward-chain over
222
+ facts. This event-sources over a graph and supports LLM behaviors
223
+ as first-class.
224
+ - Not a production graph database. The default store is SQLite,
225
+ optionally Postgres. For a high-throughput graph backend, plug one
226
+ in behind the `EventStore` protocol.
227
+ - Not magic. Bad behaviors produce bad graphs. The runtime makes the
228
+ badness inspectable, not absent.
229
+
230
+ ## Status
231
+
232
+ **v1.0 (stable)** (2026-05). The first-time-user gate per
233
+ [CONTRACT v1.0 #C4](CONTRACT.md#v10-c4-v10-ships-as-v10-rc1-first-time-user-gate-is-owned-externally)
234
+ ran through three rcs; v1.0 final ships rc3 plus a tutorial-step-7
235
+ output fix and a README "Concepts at a glance" index. See
236
+ [CHANGELOG.md](CHANGELOG.md) for the full v0 → v1.0 history and
237
+ per-version migration notes.
238
+
239
+ Major shipped milestones:
240
+
241
+ - **v1.0** — error hierarchy rewrite with per-error reference
242
+ pages, doc site at [docs.activegraph.ai](https://docs.activegraph.ai/),
243
+ `activegraph quickstart` command, mypy `--strict` and docstring
244
+ coverage CI gates, wheel-completeness and deploy-verification CI
245
+ gates.
246
+ - **v0.9** — pack format and the Diligence reference pack (8 object
247
+ types, 7 behaviors, 3 tools, recorded fixtures).
248
+ - **v0.8** — operator surface: structured logging, Prometheus
249
+ metrics, `runtime.status()`, full `activegraph` CLI,
250
+ `PostgresEventStore`.
251
+ - **v0.7** — `@tool` decorator, Cypher-subset pattern subscriptions,
252
+ temporal predicates.
253
+ - **v0.6** — `@llm_behavior` with structured output, frame-aware
254
+ prompt construction, cost accounting.
255
+ - **v0.5** — full event-log persistence, save/load across processes,
256
+ fork from any historical event, structural diff between runs.
257
+ - **v0** — core runtime: graph, behaviors, relation behaviors,
258
+ patches with optimistic concurrency, views, frames, policies,
259
+ budgets, the trace.
260
+
261
+ Roadmap items planned for v1.1 are tracked in
262
+ [CONTRACT.md § v1.1](CONTRACT.md).
263
+
264
+ ## License
265
+
266
+ MIT.
267
+
268
+ ## Contributing
269
+
270
+ The core runtime stays small and sharp. Contributions to packs,
271
+ backends, and LLM integrations are especially welcome. Open an issue
272
+ before large changes — the abstractions are still settling.
273
+
274
+ **Test discipline:** tests must remain deterministic. No live network
275
+ calls in CI. LLM and tool tests use recorded fixtures
276
+ (`RecordedLLMProvider`, `RecordedToolProvider`). If a contribution
277
+ adds a test that would only pass with a live API key or live HTTP,
278
+ it cannot land.
279
+
280
+ ---
281
+
282
+ The graph is the world. Behaviors are physics. The trace is the proof.
@@ -0,0 +1,241 @@
1
+ # Active Graph
2
+
3
+ > The graph is the world. Behaviors are physics. The trace is the proof.
4
+
5
+ An event-sourced reactive graph runtime for long-running, auditable,
6
+ agentic systems. Behaviors react to a shared graph instead of talking
7
+ to each other. Every change is traceable. Every run is resumable,
8
+ forkable, and diff-able from its event log.
9
+
10
+ If chat-based agents are a group conversation, Active Graph is a
11
+ shared workspace where everyone can see what changed, who changed
12
+ it, and why.
13
+
14
+ ## Try it in 30 seconds
15
+
16
+ ```bash
17
+ pip install activegraph
18
+ activegraph quickstart
19
+ ```
20
+
21
+ The bundled Diligence pack runs against recorded fixtures: no API
22
+ key, no configuration, byte-deterministic output. You see what the
23
+ framework does before you read about how it does it.
24
+
25
+ Then walk the 10-minute tutorial:
26
+
27
+ ```bash
28
+ activegraph quickstart --interactive
29
+ ```
30
+
31
+ It scaffolds a behavior, runs it against the same fixtures, and ends
32
+ with the fork-and-diff workflow — the framework's most differentiated
33
+ capability.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install activegraph # core runtime + SQLite store + Diligence pack
39
+ pip install "activegraph[llm]" # Anthropic provider
40
+ pip install "activegraph[postgres]" # Postgres-backed event store
41
+ pip install "activegraph[prometheus]" # Prometheus metrics
42
+ pip install "activegraph[all]" # everything
43
+ ```
44
+
45
+ Python 3.11+. Two hard dependencies (`click` for the CLI, `pydantic`
46
+ for the pack format); persistence backends and provider integrations
47
+ are opt-in extras.
48
+
49
+ ## What you get
50
+
51
+ - **Event-sourced graph runtime.** Objects + typed relations + an
52
+ append-only event log. Every mutation is an event; the trace is the
53
+ audit trail.
54
+ - **Reactive behaviors as first-class.** Function, class, LLM-backed,
55
+ or attached to typed edges (the relation-behavior primitive — edges
56
+ with logic). Subscriptions are event type + predicate + a Cypher
57
+ subset for graph-shape patterns.
58
+ - **Fork-and-diff.** Branch any run at any event into an independent
59
+ fork, configure it differently, and structurally diff the result
60
+ against the parent. Cache replay means the shared prefix doesn't
61
+ re-execute (no new LLM calls). Most agent frameworks can't do this.
62
+ - **Packs.** A pack bundles object types, behaviors, tools, prompts,
63
+ and policies for a specific domain. The bundled
64
+ [Diligence pack](activegraph/packs/diligence) is the reference:
65
+ 8 object types, 7 behaviors, 3 tools, recorded fixtures.
66
+ - **Per-error reference pages.** Every error message ends with a
67
+ `More:` link to a page that explains when it fires, why, and how to
68
+ fix it. Catalog at [docs.activegraph.ai/reference/errors](https://docs.activegraph.ai/reference/errors/).
69
+
70
+ ## Concepts at a glance
71
+
72
+ The framework's twelve primitives, in roughly the order you meet them
73
+ when reading a trace. Each links to its concept page on the doc site;
74
+ read those when you want depth on one piece.
75
+
76
+ - **Graph** — objects and typed relations forming the world the
77
+ framework reasons about. The graph is a projection of the event log;
78
+ every mutation is an event. [→ concepts/graph](https://docs.activegraph.ai/concepts/graph/)
79
+ - **Events** — the append-only history. Every behavior fires in
80
+ response to events and produces more events; the trace is the
81
+ ordered log of all of them. [→ concepts/events](https://docs.activegraph.ai/concepts/events/)
82
+ - **Behaviors** — the unit of reactive code. Function, class, or
83
+ LLM-backed; declares what events it subscribes to and what it
84
+ produces. The determinism contract is per-behavior. [→ concepts/behaviors](https://docs.activegraph.ai/concepts/behaviors/)
85
+ - **Relations** — typed edges between objects, with their own
86
+ behaviors. The relation-behavior primitive — coordination logic on
87
+ the edge, not on either endpoint — is uncommon in other agent
88
+ frameworks. [→ concepts/relations](https://docs.activegraph.ai/concepts/relations/)
89
+ - **Patches** — proposed mutations with optimistic concurrency.
90
+ Behaviors propose patches; the runtime applies or rejects them;
91
+ rejections are events in their own right. [→ concepts/patches](https://docs.activegraph.ai/concepts/patches/)
92
+ - **Views** — scoped reads of the graph for behavior context. Type
93
+ filters, depth filters, recent-event windows. Views are how
94
+ pattern-driven behaviors see only what they need to. [→ concepts/views](https://docs.activegraph.ai/concepts/views/)
95
+ - **Frames** — bounded contexts for a run. Goal, constraints, budget,
96
+ and the registered behaviors for this frame. A run can have one
97
+ frame or many. [→ concepts/frames](https://docs.activegraph.ai/concepts/frames/)
98
+ - **Policies** — approval and gating for behavior capabilities. Which
99
+ behaviors can call which tools, which mutations require human
100
+ approval, what the runtime refuses. [→ concepts/policies](https://docs.activegraph.ai/concepts/policies/)
101
+ - **Patterns** — the Cypher subset for pattern subscriptions. Beyond
102
+ event-type + predicate, behaviors can subscribe to graph shapes
103
+ (claim-cited-by-evidence, task-blocks-task, …) with `NOT EXISTS`
104
+ and temporal predicates. [→ concepts/patterns](https://docs.activegraph.ai/concepts/patterns/)
105
+ - **Replay** — re-execute a run from its event log. Strict mode
106
+ re-fires every behavior and fails on divergence; permissive mode
107
+ reconstructs state without re-firing. The LLM replay cache is what
108
+ makes fork cheap. [→ concepts/replay](https://docs.activegraph.ai/concepts/replay/)
109
+ - **Forking** — branch any run at any event into an independent
110
+ fork; structurally diff the fork against the parent. The framework's
111
+ mechanism for hypothesis testing on agentic systems. [→ concepts/forking](https://docs.activegraph.ai/concepts/forking/)
112
+ - **Failure model** — a behavior failure is a `behavior.failed`
113
+ event, not an exception. The audit trail captures failures as
114
+ first-class history. Exceptions live at runtime entry points only.
115
+ [→ concepts/failure-model](https://docs.activegraph.ai/concepts/failure-model/)
116
+
117
+ ## A small example
118
+
119
+ The relation-behavior primitive — coordination logic on the edge,
120
+ not on either endpoint:
121
+
122
+ ```python
123
+ from activegraph import Graph, Runtime, behavior, relation_behavior
124
+
125
+ graph = Graph()
126
+ runtime = Runtime(graph, budget={"max_events": 200, "max_seconds": 60})
127
+
128
+ @behavior(name="planner", on=["goal.created"])
129
+ def planner(event, graph, ctx):
130
+ research = graph.add_object("task", {"title": "Research", "status": "open"})
131
+ memo = graph.add_object("task", {"title": "Draft memo", "status": "blocked"})
132
+ graph.add_relation(research.id, memo.id, "depends_on")
133
+
134
+ @behavior(name="researcher", on=["object.created"], where={"object.type": "task"})
135
+ def researcher(event, graph, ctx):
136
+ task = event.payload["object"]
137
+ if task["data"]["status"] != "open" or "Research" not in task["data"]["title"]:
138
+ return
139
+ graph.add_object("claim", {"text": "Market early but growing.", "confidence": 0.7})
140
+ graph.emit("task.completed", {"task_id": task["id"]})
141
+
142
+ @relation_behavior(name="unblock", relation_type="depends_on", on=["task.completed"])
143
+ def unblock(relation, event, graph, ctx):
144
+ if event.payload["task_id"] == relation.source:
145
+ graph.patch_object(relation.target, {"status": "open"})
146
+
147
+ runtime.run_goal("Evaluate this startup idea")
148
+ runtime.print_trace()
149
+ ```
150
+
151
+ The `unblock` relation behavior fires only for events touching one of
152
+ its edge endpoints. The conceptual deep-dive on edges-with-logic is
153
+ in [`docs/concepts/relations.md`](https://docs.activegraph.ai/concepts/relations/).
154
+
155
+ ## Documentation
156
+
157
+ - **[docs.activegraph.ai](https://docs.activegraph.ai/)** — full doc site:
158
+ concepts, guides, cookbook, CLI reference, API reference, the
159
+ per-error catalog.
160
+ - **[10-minute tutorial](https://docs.activegraph.ai/quickstart/)** — install
161
+ to a working custom behavior, including fork-and-diff.
162
+ - **[CHANGELOG.md](CHANGELOG.md)** — every release, with per-version
163
+ migration notes.
164
+ - **[CONTRACT.md](CONTRACT.md)** — locked design decisions, version
165
+ by version. Useful when you want to know *why* something is the way
166
+ it is.
167
+ - **[examples/](examples)** — runnable end-to-end demos:
168
+ [`diligence_real_run.py`](examples/diligence_real_run.py),
169
+ [`resume_and_fork.py`](examples/resume_and_fork.py),
170
+ [`llm_claim_extraction.py`](examples/llm_claim_extraction.py),
171
+ [`diligence_with_tools.py`](examples/diligence_with_tools.py),
172
+ [`operate_a_run.py`](examples/operate_a_run.py).
173
+
174
+ ## What this is not
175
+
176
+ - Not a chat framework. If your problem fits in one conversation, use
177
+ a chat framework.
178
+ - Not a workflow engine. Workflows model control flow. This models
179
+ world state.
180
+ - Not a rules engine, exactly. Rules engines forward-chain over
181
+ facts. This event-sources over a graph and supports LLM behaviors
182
+ as first-class.
183
+ - Not a production graph database. The default store is SQLite,
184
+ optionally Postgres. For a high-throughput graph backend, plug one
185
+ in behind the `EventStore` protocol.
186
+ - Not magic. Bad behaviors produce bad graphs. The runtime makes the
187
+ badness inspectable, not absent.
188
+
189
+ ## Status
190
+
191
+ **v1.0 (stable)** (2026-05). The first-time-user gate per
192
+ [CONTRACT v1.0 #C4](CONTRACT.md#v10-c4-v10-ships-as-v10-rc1-first-time-user-gate-is-owned-externally)
193
+ ran through three rcs; v1.0 final ships rc3 plus a tutorial-step-7
194
+ output fix and a README "Concepts at a glance" index. See
195
+ [CHANGELOG.md](CHANGELOG.md) for the full v0 → v1.0 history and
196
+ per-version migration notes.
197
+
198
+ Major shipped milestones:
199
+
200
+ - **v1.0** — error hierarchy rewrite with per-error reference
201
+ pages, doc site at [docs.activegraph.ai](https://docs.activegraph.ai/),
202
+ `activegraph quickstart` command, mypy `--strict` and docstring
203
+ coverage CI gates, wheel-completeness and deploy-verification CI
204
+ gates.
205
+ - **v0.9** — pack format and the Diligence reference pack (8 object
206
+ types, 7 behaviors, 3 tools, recorded fixtures).
207
+ - **v0.8** — operator surface: structured logging, Prometheus
208
+ metrics, `runtime.status()`, full `activegraph` CLI,
209
+ `PostgresEventStore`.
210
+ - **v0.7** — `@tool` decorator, Cypher-subset pattern subscriptions,
211
+ temporal predicates.
212
+ - **v0.6** — `@llm_behavior` with structured output, frame-aware
213
+ prompt construction, cost accounting.
214
+ - **v0.5** — full event-log persistence, save/load across processes,
215
+ fork from any historical event, structural diff between runs.
216
+ - **v0** — core runtime: graph, behaviors, relation behaviors,
217
+ patches with optimistic concurrency, views, frames, policies,
218
+ budgets, the trace.
219
+
220
+ Roadmap items planned for v1.1 are tracked in
221
+ [CONTRACT.md § v1.1](CONTRACT.md).
222
+
223
+ ## License
224
+
225
+ MIT.
226
+
227
+ ## Contributing
228
+
229
+ The core runtime stays small and sharp. Contributions to packs,
230
+ backends, and LLM integrations are especially welcome. Open an issue
231
+ before large changes — the abstractions are still settling.
232
+
233
+ **Test discipline:** tests must remain deterministic. No live network
234
+ calls in CI. LLM and tool tests use recorded fixtures
235
+ (`RecordedLLMProvider`, `RecordedToolProvider`). If a contribution
236
+ adds a test that would only pass with a live API key or live HTTP,
237
+ it cannot land.
238
+
239
+ ---
240
+
241
+ The graph is the world. Behaviors are physics. The trace is the proof.