activegraph 1.0.0rc2__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 (144) hide show
  1. activegraph-1.0.0rc2/PKG-INFO +228 -0
  2. activegraph-1.0.0rc2/README.md +191 -0
  3. activegraph-1.0.0rc2/activegraph/__init__.py +222 -0
  4. activegraph-1.0.0rc2/activegraph/__main__.py +5 -0
  5. activegraph-1.0.0rc2/activegraph/behaviors/__init__.py +1 -0
  6. activegraph-1.0.0rc2/activegraph/behaviors/base.py +153 -0
  7. activegraph-1.0.0rc2/activegraph/behaviors/decorators.py +218 -0
  8. activegraph-1.0.0rc2/activegraph/cli/__init__.py +17 -0
  9. activegraph-1.0.0rc2/activegraph/cli/main.py +793 -0
  10. activegraph-1.0.0rc2/activegraph/cli/quickstart.py +556 -0
  11. activegraph-1.0.0rc2/activegraph/core/__init__.py +1 -0
  12. activegraph-1.0.0rc2/activegraph/core/clock.py +46 -0
  13. activegraph-1.0.0rc2/activegraph/core/event.py +33 -0
  14. activegraph-1.0.0rc2/activegraph/core/graph.py +846 -0
  15. activegraph-1.0.0rc2/activegraph/core/ids.py +135 -0
  16. activegraph-1.0.0rc2/activegraph/core/patch.py +47 -0
  17. activegraph-1.0.0rc2/activegraph/core/view.py +59 -0
  18. activegraph-1.0.0rc2/activegraph/errors.py +342 -0
  19. activegraph-1.0.0rc2/activegraph/frame.py +15 -0
  20. activegraph-1.0.0rc2/activegraph/llm/__init__.py +51 -0
  21. activegraph-1.0.0rc2/activegraph/llm/anthropic.py +339 -0
  22. activegraph-1.0.0rc2/activegraph/llm/cache.py +180 -0
  23. activegraph-1.0.0rc2/activegraph/llm/errors.py +257 -0
  24. activegraph-1.0.0rc2/activegraph/llm/prompt.py +420 -0
  25. activegraph-1.0.0rc2/activegraph/llm/provider.py +66 -0
  26. activegraph-1.0.0rc2/activegraph/llm/recorded.py +270 -0
  27. activegraph-1.0.0rc2/activegraph/llm/types.py +130 -0
  28. activegraph-1.0.0rc2/activegraph/observability/__init__.py +61 -0
  29. activegraph-1.0.0rc2/activegraph/observability/logging.py +205 -0
  30. activegraph-1.0.0rc2/activegraph/observability/metrics.py +219 -0
  31. activegraph-1.0.0rc2/activegraph/observability/migration.py +404 -0
  32. activegraph-1.0.0rc2/activegraph/observability/prometheus.py +101 -0
  33. activegraph-1.0.0rc2/activegraph/observability/status.py +83 -0
  34. activegraph-1.0.0rc2/activegraph/packs/__init__.py +999 -0
  35. activegraph-1.0.0rc2/activegraph/packs/diligence/__init__.py +86 -0
  36. activegraph-1.0.0rc2/activegraph/packs/diligence/behaviors.py +447 -0
  37. activegraph-1.0.0rc2/activegraph/packs/diligence/fixtures/__init__.py +364 -0
  38. activegraph-1.0.0rc2/activegraph/packs/diligence/fixtures/companies.py +511 -0
  39. activegraph-1.0.0rc2/activegraph/packs/diligence/object_types.py +163 -0
  40. activegraph-1.0.0rc2/activegraph/packs/diligence/settings.py +60 -0
  41. activegraph-1.0.0rc2/activegraph/packs/diligence/tools.py +124 -0
  42. activegraph-1.0.0rc2/activegraph/packs/loader.py +709 -0
  43. activegraph-1.0.0rc2/activegraph/packs/scaffold.py +317 -0
  44. activegraph-1.0.0rc2/activegraph/policy.py +20 -0
  45. activegraph-1.0.0rc2/activegraph/runtime/__init__.py +1 -0
  46. activegraph-1.0.0rc2/activegraph/runtime/behavior_graph.py +151 -0
  47. activegraph-1.0.0rc2/activegraph/runtime/budget.py +120 -0
  48. activegraph-1.0.0rc2/activegraph/runtime/config_errors.py +124 -0
  49. activegraph-1.0.0rc2/activegraph/runtime/diff.py +145 -0
  50. activegraph-1.0.0rc2/activegraph/runtime/errors.py +216 -0
  51. activegraph-1.0.0rc2/activegraph/runtime/exec_errors.py +232 -0
  52. activegraph-1.0.0rc2/activegraph/runtime/patterns.py +946 -0
  53. activegraph-1.0.0rc2/activegraph/runtime/queue.py +27 -0
  54. activegraph-1.0.0rc2/activegraph/runtime/registration_errors.py +291 -0
  55. activegraph-1.0.0rc2/activegraph/runtime/registry.py +111 -0
  56. activegraph-1.0.0rc2/activegraph/runtime/runtime.py +2441 -0
  57. activegraph-1.0.0rc2/activegraph/runtime/scheduler.py +206 -0
  58. activegraph-1.0.0rc2/activegraph/runtime/view_builder.py +65 -0
  59. activegraph-1.0.0rc2/activegraph/store/__init__.py +41 -0
  60. activegraph-1.0.0rc2/activegraph/store/base.py +66 -0
  61. activegraph-1.0.0rc2/activegraph/store/conformance.py +161 -0
  62. activegraph-1.0.0rc2/activegraph/store/errors.py +84 -0
  63. activegraph-1.0.0rc2/activegraph/store/memory.py +118 -0
  64. activegraph-1.0.0rc2/activegraph/store/postgres.py +609 -0
  65. activegraph-1.0.0rc2/activegraph/store/serde.py +202 -0
  66. activegraph-1.0.0rc2/activegraph/store/sqlite.py +446 -0
  67. activegraph-1.0.0rc2/activegraph/store/url.py +230 -0
  68. activegraph-1.0.0rc2/activegraph/tools/__init__.py +64 -0
  69. activegraph-1.0.0rc2/activegraph/tools/base.py +57 -0
  70. activegraph-1.0.0rc2/activegraph/tools/cache.py +157 -0
  71. activegraph-1.0.0rc2/activegraph/tools/context.py +48 -0
  72. activegraph-1.0.0rc2/activegraph/tools/decorators.py +70 -0
  73. activegraph-1.0.0rc2/activegraph/tools/errors.py +320 -0
  74. activegraph-1.0.0rc2/activegraph/tools/graph_query.py +94 -0
  75. activegraph-1.0.0rc2/activegraph/tools/recorded.py +205 -0
  76. activegraph-1.0.0rc2/activegraph/tools/web_fetch.py +80 -0
  77. activegraph-1.0.0rc2/activegraph/trace/__init__.py +1 -0
  78. activegraph-1.0.0rc2/activegraph/trace/causal.py +123 -0
  79. activegraph-1.0.0rc2/activegraph/trace/printer.py +495 -0
  80. activegraph-1.0.0rc2/activegraph.egg-info/PKG-INFO +228 -0
  81. activegraph-1.0.0rc2/activegraph.egg-info/SOURCES.txt +142 -0
  82. activegraph-1.0.0rc2/activegraph.egg-info/dependency_links.txt +1 -0
  83. activegraph-1.0.0rc2/activegraph.egg-info/entry_points.txt +5 -0
  84. activegraph-1.0.0rc2/activegraph.egg-info/requires.txt +26 -0
  85. activegraph-1.0.0rc2/activegraph.egg-info/top_level.txt +1 -0
  86. activegraph-1.0.0rc2/pyproject.toml +156 -0
  87. activegraph-1.0.0rc2/setup.cfg +4 -0
  88. activegraph-1.0.0rc2/tests/test_activate_after.py +131 -0
  89. activegraph-1.0.0rc2/tests/test_causal_cross_tool.py +139 -0
  90. activegraph-1.0.0rc2/tests/test_cli.py +535 -0
  91. activegraph-1.0.0rc2/tests/test_clock.py +15 -0
  92. activegraph-1.0.0rc2/tests/test_diff.py +121 -0
  93. activegraph-1.0.0rc2/tests/test_diligence_pack.py +196 -0
  94. activegraph-1.0.0rc2/tests/test_diligence_with_tools.py +74 -0
  95. activegraph-1.0.0rc2/tests/test_doc_links.py +289 -0
  96. activegraph-1.0.0rc2/tests/test_errors_format.py +1498 -0
  97. activegraph-1.0.0rc2/tests/test_event.py +29 -0
  98. activegraph-1.0.0rc2/tests/test_fork.py +167 -0
  99. activegraph-1.0.0rc2/tests/test_graph.py +110 -0
  100. activegraph-1.0.0rc2/tests/test_ids.py +22 -0
  101. activegraph-1.0.0rc2/tests/test_llm_anthropic.py +185 -0
  102. activegraph-1.0.0rc2/tests/test_llm_behavior.py +231 -0
  103. activegraph-1.0.0rc2/tests/test_llm_budget.py +152 -0
  104. activegraph-1.0.0rc2/tests/test_llm_causal.py +66 -0
  105. activegraph-1.0.0rc2/tests/test_llm_claim_extraction.py +84 -0
  106. activegraph-1.0.0rc2/tests/test_llm_determinism.py +106 -0
  107. activegraph-1.0.0rc2/tests/test_llm_failure.py +214 -0
  108. activegraph-1.0.0rc2/tests/test_llm_prompt.py +357 -0
  109. activegraph-1.0.0rc2/tests/test_llm_provider_fixtures.py +132 -0
  110. activegraph-1.0.0rc2/tests/test_llm_replay.py +263 -0
  111. activegraph-1.0.0rc2/tests/test_llm_tool_loop.py +312 -0
  112. activegraph-1.0.0rc2/tests/test_llm_trace.py +144 -0
  113. activegraph-1.0.0rc2/tests/test_llm_trace_snapshot.py +112 -0
  114. activegraph-1.0.0rc2/tests/test_llm_types.py +51 -0
  115. activegraph-1.0.0rc2/tests/test_migration.py +190 -0
  116. activegraph-1.0.0rc2/tests/test_observability_logging.py +135 -0
  117. activegraph-1.0.0rc2/tests/test_observability_metrics.py +215 -0
  118. activegraph-1.0.0rc2/tests/test_operate_example.py +40 -0
  119. activegraph-1.0.0rc2/tests/test_pack_scaffold.py +119 -0
  120. activegraph-1.0.0rc2/tests/test_packs.py +561 -0
  121. activegraph-1.0.0rc2/tests/test_patch.py +61 -0
  122. activegraph-1.0.0rc2/tests/test_pattern_matcher.py +160 -0
  123. activegraph-1.0.0rc2/tests/test_pattern_parser.py +221 -0
  124. activegraph-1.0.0rc2/tests/test_pattern_subscriptions.py +132 -0
  125. activegraph-1.0.0rc2/tests/test_persistence.py +382 -0
  126. activegraph-1.0.0rc2/tests/test_postgres_store.py +51 -0
  127. activegraph-1.0.0rc2/tests/test_quickstart.py +309 -0
  128. activegraph-1.0.0rc2/tests/test_quickstart_snapshot.py +72 -0
  129. activegraph-1.0.0rc2/tests/test_replay.py +128 -0
  130. activegraph-1.0.0rc2/tests/test_replay_trace_snapshot.py +51 -0
  131. activegraph-1.0.0rc2/tests/test_requeue_unfired.py +206 -0
  132. activegraph-1.0.0rc2/tests/test_resume_example.py +148 -0
  133. activegraph-1.0.0rc2/tests/test_runtime.py +125 -0
  134. activegraph-1.0.0rc2/tests/test_runtime_status.py +149 -0
  135. activegraph-1.0.0rc2/tests/test_serde.py +65 -0
  136. activegraph-1.0.0rc2/tests/test_store_conformance.py +46 -0
  137. activegraph-1.0.0rc2/tests/test_store_url.py +57 -0
  138. activegraph-1.0.0rc2/tests/test_tool_replay.py +196 -0
  139. activegraph-1.0.0rc2/tests/test_tool_trace_snapshot.py +128 -0
  140. activegraph-1.0.0rc2/tests/test_tools.py +282 -0
  141. activegraph-1.0.0rc2/tests/test_trace.py +39 -0
  142. activegraph-1.0.0rc2/tests/test_tutorial_snippets.py +167 -0
  143. activegraph-1.0.0rc2/tests/test_version_sync.py +30 -0
  144. activegraph-1.0.0rc2/tests/test_view.py +47 -0
@@ -0,0 +1,228 @@
1
+ Metadata-Version: 2.4
2
+ Name: activegraph
3
+ Version: 1.0.0rc2
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
+
38
+ # Active Graph
39
+
40
+ > The graph is the world. Behaviors are physics. The trace is the proof.
41
+
42
+ An event-sourced reactive graph runtime for long-running, auditable,
43
+ agentic systems. Behaviors react to a shared graph instead of talking
44
+ to each other. Every change is traceable. Every run is resumable,
45
+ forkable, and diff-able from its event log.
46
+
47
+ If chat-based agents are a group conversation, Active Graph is a
48
+ shared workspace where everyone can see what changed, who changed
49
+ it, and why.
50
+
51
+ ## Try it in 30 seconds
52
+
53
+ ```bash
54
+ pip install activegraph
55
+ activegraph quickstart
56
+ ```
57
+
58
+ The bundled Diligence pack runs against recorded fixtures: no API
59
+ key, no configuration, byte-deterministic output. You see what the
60
+ framework does before you read about how it does it.
61
+
62
+ Then walk the 10-minute tutorial:
63
+
64
+ ```bash
65
+ activegraph quickstart --interactive
66
+ ```
67
+
68
+ It scaffolds a behavior, runs it against the same fixtures, and ends
69
+ with the fork-and-diff workflow — the framework's most differentiated
70
+ capability.
71
+
72
+ ## Install
73
+
74
+ ```bash
75
+ pip install activegraph # core runtime + SQLite store + Diligence pack
76
+ pip install "activegraph[llm]" # Anthropic provider
77
+ pip install "activegraph[postgres]" # Postgres-backed event store
78
+ pip install "activegraph[prometheus]" # Prometheus metrics
79
+ pip install "activegraph[all]" # everything
80
+ ```
81
+
82
+ Python 3.11+. Two hard dependencies (`click` for the CLI, `pydantic`
83
+ for the pack format); persistence backends and provider integrations
84
+ are opt-in extras.
85
+
86
+ ## What you get
87
+
88
+ - **Event-sourced graph runtime.** Objects + typed relations + an
89
+ append-only event log. Every mutation is an event; the trace is the
90
+ audit trail.
91
+ - **Reactive behaviors as first-class.** Function, class, LLM-backed,
92
+ or attached to typed edges (the relation-behavior primitive — edges
93
+ with logic). Subscriptions are event type + predicate + a Cypher
94
+ subset for graph-shape patterns.
95
+ - **Fork-and-diff.** Branch any run at any event into an independent
96
+ fork, configure it differently, and structurally diff the result
97
+ against the parent. Cache replay means the shared prefix doesn't
98
+ re-execute (no new LLM calls). Most agent frameworks can't do this.
99
+ - **Packs.** A pack bundles object types, behaviors, tools, prompts,
100
+ and policies for a specific domain. The bundled
101
+ [Diligence pack](activegraph/packs/diligence) is the reference:
102
+ 8 object types, 7 behaviors, 3 tools, recorded fixtures.
103
+ - **Per-error reference pages.** Every error message ends with a
104
+ `More:` link to a page that explains when it fires, why, and how to
105
+ fix it. Catalog at [docs.activegraph.dev/reference/errors](https://docs.activegraph.dev/reference/errors/).
106
+
107
+ ## A small example
108
+
109
+ The relation-behavior primitive — coordination logic on the edge,
110
+ not on either endpoint:
111
+
112
+ ```python
113
+ from activegraph import Graph, Runtime, behavior, relation_behavior
114
+
115
+ graph = Graph()
116
+ runtime = Runtime(graph, budget={"max_events": 200, "max_seconds": 60})
117
+
118
+ @behavior(name="planner", on=["goal.created"])
119
+ def planner(event, graph, ctx):
120
+ research = graph.add_object("task", {"title": "Research", "status": "open"})
121
+ memo = graph.add_object("task", {"title": "Draft memo", "status": "blocked"})
122
+ graph.add_relation(research.id, memo.id, "depends_on")
123
+
124
+ @behavior(name="researcher", on=["object.created"], where={"object.type": "task"})
125
+ def researcher(event, graph, ctx):
126
+ task = event.payload["object"]
127
+ if task["data"]["status"] != "open" or "Research" not in task["data"]["title"]:
128
+ return
129
+ graph.add_object("claim", {"text": "Market early but growing.", "confidence": 0.7})
130
+ graph.emit("task.completed", {"task_id": task["id"]})
131
+
132
+ @relation_behavior(name="unblock", relation_type="depends_on", on=["task.completed"])
133
+ def unblock(relation, event, graph, ctx):
134
+ if event.payload["task_id"] == relation.source:
135
+ graph.patch_object(relation.target, {"status": "open"})
136
+
137
+ runtime.run_goal("Evaluate this startup idea")
138
+ runtime.print_trace()
139
+ ```
140
+
141
+ The `unblock` relation behavior fires only for events touching one of
142
+ its edge endpoints. The conceptual deep-dive on edges-with-logic is
143
+ in [`docs/concepts/relations.md`](https://docs.activegraph.dev/concepts/relations/).
144
+
145
+ ## Documentation
146
+
147
+ - **[docs.activegraph.dev](https://docs.activegraph.dev/)** — full doc site:
148
+ concepts, guides, cookbook, CLI reference, API reference, the
149
+ per-error catalog.
150
+ - **[10-minute tutorial](https://docs.activegraph.dev/quickstart/)** — install
151
+ to a working custom behavior, including fork-and-diff.
152
+ - **[CHANGELOG.md](CHANGELOG.md)** — every release, with per-version
153
+ migration notes.
154
+ - **[CONTRACT.md](CONTRACT.md)** — locked design decisions, version
155
+ by version. Useful when you want to know *why* something is the way
156
+ it is.
157
+ - **[examples/](examples)** — runnable end-to-end demos:
158
+ [`diligence_real_run.py`](examples/diligence_real_run.py),
159
+ [`resume_and_fork.py`](examples/resume_and_fork.py),
160
+ [`llm_claim_extraction.py`](examples/llm_claim_extraction.py),
161
+ [`diligence_with_tools.py`](examples/diligence_with_tools.py),
162
+ [`operate_a_run.py`](examples/operate_a_run.py).
163
+
164
+ ## What this is not
165
+
166
+ - Not a chat framework. If your problem fits in one conversation, use
167
+ a chat framework.
168
+ - Not a workflow engine. Workflows model control flow. This models
169
+ world state.
170
+ - Not a rules engine, exactly. Rules engines forward-chain over
171
+ facts. This event-sources over a graph and supports LLM behaviors
172
+ as first-class.
173
+ - Not a production graph database. The default store is SQLite,
174
+ optionally Postgres. For a high-throughput graph backend, plug one
175
+ in behind the `EventStore` protocol.
176
+ - Not magic. Bad behaviors produce bad graphs. The runtime makes the
177
+ badness inspectable, not absent.
178
+
179
+ ## Status
180
+
181
+ **v1.0-rc1** (2026-05). v1.0 final ships after the first-time-user
182
+ gate per [CONTRACT v1.0 #C4](CONTRACT.md#v10-c4-v10-ships-as-v10-rc1-first-time-user-gate-is-owned-externally).
183
+ See [CHANGELOG.md](CHANGELOG.md) for the full v0 → v1.0 history and
184
+ per-version migration notes.
185
+
186
+ Major shipped milestones:
187
+
188
+ - **v1.0 (rc1)** — error hierarchy rewrite with per-error reference
189
+ pages, doc site at [docs.activegraph.dev](https://docs.activegraph.dev/),
190
+ `activegraph quickstart` command, mypy `--strict` and docstring
191
+ coverage CI gates.
192
+ - **v0.9** — pack format and the Diligence reference pack (8 object
193
+ types, 7 behaviors, 3 tools, recorded fixtures).
194
+ - **v0.8** — operator surface: structured logging, Prometheus
195
+ metrics, `runtime.status()`, full `activegraph` CLI,
196
+ `PostgresEventStore`.
197
+ - **v0.7** — `@tool` decorator, Cypher-subset pattern subscriptions,
198
+ temporal predicates.
199
+ - **v0.6** — `@llm_behavior` with structured output, frame-aware
200
+ prompt construction, cost accounting.
201
+ - **v0.5** — full event-log persistence, save/load across processes,
202
+ fork from any historical event, structural diff between runs.
203
+ - **v0** — core runtime: graph, behaviors, relation behaviors,
204
+ patches with optimistic concurrency, views, frames, policies,
205
+ budgets, the trace.
206
+
207
+ Roadmap items planned for v1.1 are tracked in
208
+ [CONTRACT.md § v1.1](CONTRACT.md).
209
+
210
+ ## License
211
+
212
+ MIT.
213
+
214
+ ## Contributing
215
+
216
+ The core runtime stays small and sharp. Contributions to packs,
217
+ backends, and LLM integrations are especially welcome. Open an issue
218
+ before large changes — the abstractions are still settling.
219
+
220
+ **Test discipline:** tests must remain deterministic. No live network
221
+ calls in CI. LLM and tool tests use recorded fixtures
222
+ (`RecordedLLMProvider`, `RecordedToolProvider`). If a contribution
223
+ adds a test that would only pass with a live API key or live HTTP,
224
+ it cannot land.
225
+
226
+ ---
227
+
228
+ The graph is the world. Behaviors are physics. The trace is the proof.
@@ -0,0 +1,191 @@
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.dev/reference/errors](https://docs.activegraph.dev/reference/errors/).
69
+
70
+ ## A small example
71
+
72
+ The relation-behavior primitive — coordination logic on the edge,
73
+ not on either endpoint:
74
+
75
+ ```python
76
+ from activegraph import Graph, Runtime, behavior, relation_behavior
77
+
78
+ graph = Graph()
79
+ runtime = Runtime(graph, budget={"max_events": 200, "max_seconds": 60})
80
+
81
+ @behavior(name="planner", on=["goal.created"])
82
+ def planner(event, graph, ctx):
83
+ research = graph.add_object("task", {"title": "Research", "status": "open"})
84
+ memo = graph.add_object("task", {"title": "Draft memo", "status": "blocked"})
85
+ graph.add_relation(research.id, memo.id, "depends_on")
86
+
87
+ @behavior(name="researcher", on=["object.created"], where={"object.type": "task"})
88
+ def researcher(event, graph, ctx):
89
+ task = event.payload["object"]
90
+ if task["data"]["status"] != "open" or "Research" not in task["data"]["title"]:
91
+ return
92
+ graph.add_object("claim", {"text": "Market early but growing.", "confidence": 0.7})
93
+ graph.emit("task.completed", {"task_id": task["id"]})
94
+
95
+ @relation_behavior(name="unblock", relation_type="depends_on", on=["task.completed"])
96
+ def unblock(relation, event, graph, ctx):
97
+ if event.payload["task_id"] == relation.source:
98
+ graph.patch_object(relation.target, {"status": "open"})
99
+
100
+ runtime.run_goal("Evaluate this startup idea")
101
+ runtime.print_trace()
102
+ ```
103
+
104
+ The `unblock` relation behavior fires only for events touching one of
105
+ its edge endpoints. The conceptual deep-dive on edges-with-logic is
106
+ in [`docs/concepts/relations.md`](https://docs.activegraph.dev/concepts/relations/).
107
+
108
+ ## Documentation
109
+
110
+ - **[docs.activegraph.dev](https://docs.activegraph.dev/)** — full doc site:
111
+ concepts, guides, cookbook, CLI reference, API reference, the
112
+ per-error catalog.
113
+ - **[10-minute tutorial](https://docs.activegraph.dev/quickstart/)** — install
114
+ to a working custom behavior, including fork-and-diff.
115
+ - **[CHANGELOG.md](CHANGELOG.md)** — every release, with per-version
116
+ migration notes.
117
+ - **[CONTRACT.md](CONTRACT.md)** — locked design decisions, version
118
+ by version. Useful when you want to know *why* something is the way
119
+ it is.
120
+ - **[examples/](examples)** — runnable end-to-end demos:
121
+ [`diligence_real_run.py`](examples/diligence_real_run.py),
122
+ [`resume_and_fork.py`](examples/resume_and_fork.py),
123
+ [`llm_claim_extraction.py`](examples/llm_claim_extraction.py),
124
+ [`diligence_with_tools.py`](examples/diligence_with_tools.py),
125
+ [`operate_a_run.py`](examples/operate_a_run.py).
126
+
127
+ ## What this is not
128
+
129
+ - Not a chat framework. If your problem fits in one conversation, use
130
+ a chat framework.
131
+ - Not a workflow engine. Workflows model control flow. This models
132
+ world state.
133
+ - Not a rules engine, exactly. Rules engines forward-chain over
134
+ facts. This event-sources over a graph and supports LLM behaviors
135
+ as first-class.
136
+ - Not a production graph database. The default store is SQLite,
137
+ optionally Postgres. For a high-throughput graph backend, plug one
138
+ in behind the `EventStore` protocol.
139
+ - Not magic. Bad behaviors produce bad graphs. The runtime makes the
140
+ badness inspectable, not absent.
141
+
142
+ ## Status
143
+
144
+ **v1.0-rc1** (2026-05). v1.0 final ships after the first-time-user
145
+ gate per [CONTRACT v1.0 #C4](CONTRACT.md#v10-c4-v10-ships-as-v10-rc1-first-time-user-gate-is-owned-externally).
146
+ See [CHANGELOG.md](CHANGELOG.md) for the full v0 → v1.0 history and
147
+ per-version migration notes.
148
+
149
+ Major shipped milestones:
150
+
151
+ - **v1.0 (rc1)** — error hierarchy rewrite with per-error reference
152
+ pages, doc site at [docs.activegraph.dev](https://docs.activegraph.dev/),
153
+ `activegraph quickstart` command, mypy `--strict` and docstring
154
+ coverage CI gates.
155
+ - **v0.9** — pack format and the Diligence reference pack (8 object
156
+ types, 7 behaviors, 3 tools, recorded fixtures).
157
+ - **v0.8** — operator surface: structured logging, Prometheus
158
+ metrics, `runtime.status()`, full `activegraph` CLI,
159
+ `PostgresEventStore`.
160
+ - **v0.7** — `@tool` decorator, Cypher-subset pattern subscriptions,
161
+ temporal predicates.
162
+ - **v0.6** — `@llm_behavior` with structured output, frame-aware
163
+ prompt construction, cost accounting.
164
+ - **v0.5** — full event-log persistence, save/load across processes,
165
+ fork from any historical event, structural diff between runs.
166
+ - **v0** — core runtime: graph, behaviors, relation behaviors,
167
+ patches with optimistic concurrency, views, frames, policies,
168
+ budgets, the trace.
169
+
170
+ Roadmap items planned for v1.1 are tracked in
171
+ [CONTRACT.md § v1.1](CONTRACT.md).
172
+
173
+ ## License
174
+
175
+ MIT.
176
+
177
+ ## Contributing
178
+
179
+ The core runtime stays small and sharp. Contributions to packs,
180
+ backends, and LLM integrations are especially welcome. Open an issue
181
+ before large changes — the abstractions are still settling.
182
+
183
+ **Test discipline:** tests must remain deterministic. No live network
184
+ calls in CI. LLM and tool tests use recorded fixtures
185
+ (`RecordedLLMProvider`, `RecordedToolProvider`). If a contribution
186
+ adds a test that would only pass with a live API key or live HTTP,
187
+ it cannot land.
188
+
189
+ ---
190
+
191
+ The graph is the world. Behaviors are physics. The trace is the proof.
@@ -0,0 +1,222 @@
1
+ """Active Graph Runtime. Public API surface.
2
+
3
+ The graph is the world. Behaviors are physics. The trace is the proof.
4
+ """
5
+
6
+ from activegraph.behaviors.base import Behavior, LLMBehavior, RelationBehavior
7
+ from activegraph.behaviors.decorators import (
8
+ behavior,
9
+ clear_registry,
10
+ get_registry,
11
+ llm_behavior,
12
+ relation_behavior,
13
+ )
14
+ from activegraph.core.clock import Clock, FrozenClock, TickingClock
15
+ from activegraph.core.event import Event
16
+ from activegraph.core.graph import Graph, Object, Relation
17
+ from activegraph.core.ids import IDGen
18
+ from activegraph.core.patch import Patch
19
+ from activegraph.core.view import View
20
+ from activegraph.errors import (
21
+ ActiveGraphError,
22
+ ConfigurationError,
23
+ ExecutionError,
24
+ MissingOptionalDependency,
25
+ PackError,
26
+ PatternError,
27
+ RegistrationError,
28
+ ReplayError,
29
+ StorageError,
30
+ )
31
+ from activegraph.runtime.registration_errors import (
32
+ AmbiguousBehaviorError,
33
+ AmbiguousToolError,
34
+ BehaviorNotFoundError,
35
+ InvalidToolRegistration,
36
+ ToolNotFoundError,
37
+ )
38
+ from activegraph.runtime.scheduler import InvalidActivateAfter
39
+ from activegraph.frame import Frame
40
+ from activegraph.llm.errors import LLMBehaviorError, MissingProviderError
41
+ from activegraph.policy import Policy
42
+ from activegraph.runtime.budget import Budget
43
+ from activegraph.runtime.diff import Diff, DivergentObject, DivergentRelation
44
+ from activegraph.runtime.config_errors import (
45
+ IncompatibleRuntimeState,
46
+ InvalidArgumentType,
47
+ InvalidRuntimeConfiguration,
48
+ )
49
+ from activegraph.runtime.errors import ReplayDivergenceError
50
+ from activegraph.runtime.exec_errors import (
51
+ ApprovalNotFoundError,
52
+ InternalEvaluatorError,
53
+ InvalidPatchLifecycleState,
54
+ RuntimeContextRequiredError,
55
+ )
56
+ from activegraph.runtime.patterns import UnsupportedPatternError
57
+ from activegraph.runtime.runtime import Runtime
58
+ from activegraph.store import (
59
+ CorruptedEventPayloadError,
60
+ DuplicateEventError,
61
+ EventNotFoundError,
62
+ EventStore,
63
+ InMemoryEventStore,
64
+ InvalidStoreURL,
65
+ NonSerializableEventError,
66
+ RunRecord,
67
+ SQLiteEventStore,
68
+ SchemaVersionMismatch,
69
+ open_store,
70
+ parse_store_url,
71
+ )
72
+ # v0.7 public surface for tools
73
+ from activegraph.tools import (
74
+ MissingToolError,
75
+ Tool,
76
+ ToolContext,
77
+ ToolError,
78
+ UnknownToolError,
79
+ clear_tool_registry,
80
+ get_tool_registry,
81
+ tool,
82
+ )
83
+ # v0.8 observability surface
84
+ from activegraph.observability import (
85
+ Metrics,
86
+ MigrationReport,
87
+ MigrationRunReport,
88
+ NoOpMetrics,
89
+ PrometheusMetrics,
90
+ RuntimeStatus,
91
+ configure_logging,
92
+ migrate,
93
+ )
94
+ # v0.9 packs surface (top-level: the API for *using* packs from user code).
95
+ # Pack-aware decorators live under `activegraph.packs` and are intentionally
96
+ # NOT re-exported here — pack authors must import them from `activegraph.packs`
97
+ # so the import path makes the boundary explicit. CONTRACT v0.9 #3.
98
+ from activegraph.packs import (
99
+ DiscoveredPack,
100
+ EmptySettings,
101
+ ObjectType,
102
+ Pack,
103
+ PackConflictError,
104
+ PackError,
105
+ PackNotFoundError,
106
+ PackPolicy,
107
+ PackPrompt,
108
+ PackPromptLoadError,
109
+ PackSchemaViolation,
110
+ PackSettingsMissingError,
111
+ PackValidationError,
112
+ PackVersionConflictError,
113
+ PendingApproval,
114
+ RelationType,
115
+ clear_discovery_cache,
116
+ discover,
117
+ load_by_name,
118
+ load_prompts_from_dir,
119
+ )
120
+
121
+ __all__ = [
122
+ "ActiveGraphError",
123
+ "AmbiguousBehaviorError",
124
+ "AmbiguousToolError",
125
+ "ApprovalNotFoundError",
126
+ "Behavior",
127
+ "BehaviorNotFoundError",
128
+ "Budget",
129
+ "Clock",
130
+ "ConfigurationError",
131
+ "CorruptedEventPayloadError",
132
+ "Diff",
133
+ "DiscoveredPack",
134
+ "DivergentObject",
135
+ "DivergentRelation",
136
+ "DuplicateEventError",
137
+ "EmptySettings",
138
+ "Event",
139
+ "EventNotFoundError",
140
+ "EventStore",
141
+ "ExecutionError",
142
+ "Frame",
143
+ "FrozenClock",
144
+ "Graph",
145
+ "IDGen",
146
+ "InMemoryEventStore",
147
+ "IncompatibleRuntimeState",
148
+ "InternalEvaluatorError",
149
+ "InvalidActivateAfter",
150
+ "InvalidArgumentType",
151
+ "InvalidPatchLifecycleState",
152
+ "InvalidRuntimeConfiguration",
153
+ "InvalidStoreURL",
154
+ "InvalidToolRegistration",
155
+ "LLMBehavior",
156
+ "LLMBehaviorError",
157
+ "Metrics",
158
+ "MigrationReport",
159
+ "MigrationRunReport",
160
+ "MissingOptionalDependency",
161
+ "MissingProviderError",
162
+ "MissingToolError",
163
+ "NoOpMetrics",
164
+ "NonSerializableEventError",
165
+ "Object",
166
+ "ObjectType",
167
+ "Pack",
168
+ "PackConflictError",
169
+ "PackError",
170
+ "PackNotFoundError",
171
+ "PackPolicy",
172
+ "PackPromptLoadError",
173
+ "PackPrompt",
174
+ "PackSchemaViolation",
175
+ "PackSettingsMissingError",
176
+ "PackValidationError",
177
+ "PackVersionConflictError",
178
+ "PatternError",
179
+ "Patch",
180
+ "PendingApproval",
181
+ "Policy",
182
+ "PrometheusMetrics",
183
+ "Relation",
184
+ "RelationBehavior",
185
+ "RegistrationError",
186
+ "RelationType",
187
+ "ReplayDivergenceError",
188
+ "ReplayError",
189
+ "RunRecord",
190
+ "Runtime",
191
+ "RuntimeContextRequiredError",
192
+ "RuntimeStatus",
193
+ "SQLiteEventStore",
194
+ "SchemaVersionMismatch",
195
+ "StorageError",
196
+ "TickingClock",
197
+ "Tool",
198
+ "ToolContext",
199
+ "ToolError",
200
+ "ToolNotFoundError",
201
+ "UnknownToolError",
202
+ "UnsupportedPatternError",
203
+ "View",
204
+ "behavior",
205
+ "clear_discovery_cache",
206
+ "clear_registry",
207
+ "clear_tool_registry",
208
+ "configure_logging",
209
+ "discover",
210
+ "get_registry",
211
+ "get_tool_registry",
212
+ "llm_behavior",
213
+ "load_by_name",
214
+ "load_prompts_from_dir",
215
+ "migrate",
216
+ "open_store",
217
+ "parse_store_url",
218
+ "relation_behavior",
219
+ "tool",
220
+ ]
221
+
222
+ __version__ = "1.0.0rc2"
@@ -0,0 +1,5 @@
1
+ """``python -m activegraph`` → CLI entry point."""
2
+
3
+ from activegraph.cli.main import main
4
+
5
+ raise SystemExit(main())
@@ -0,0 +1 @@
1
+ """Behavior decorators and base classes. Imports core only (CONTRACT #14)."""