activegraph 1.0.0rc2__py3-none-any.whl
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.
- activegraph/__init__.py +222 -0
- activegraph/__main__.py +5 -0
- activegraph/behaviors/__init__.py +1 -0
- activegraph/behaviors/base.py +153 -0
- activegraph/behaviors/decorators.py +218 -0
- activegraph/cli/__init__.py +17 -0
- activegraph/cli/main.py +793 -0
- activegraph/cli/quickstart.py +556 -0
- activegraph/core/__init__.py +1 -0
- activegraph/core/clock.py +46 -0
- activegraph/core/event.py +33 -0
- activegraph/core/graph.py +846 -0
- activegraph/core/ids.py +135 -0
- activegraph/core/patch.py +47 -0
- activegraph/core/view.py +59 -0
- activegraph/errors.py +342 -0
- activegraph/frame.py +15 -0
- activegraph/llm/__init__.py +51 -0
- activegraph/llm/anthropic.py +339 -0
- activegraph/llm/cache.py +180 -0
- activegraph/llm/errors.py +257 -0
- activegraph/llm/prompt.py +420 -0
- activegraph/llm/provider.py +66 -0
- activegraph/llm/recorded.py +270 -0
- activegraph/llm/types.py +130 -0
- activegraph/observability/__init__.py +61 -0
- activegraph/observability/logging.py +205 -0
- activegraph/observability/metrics.py +219 -0
- activegraph/observability/migration.py +404 -0
- activegraph/observability/prometheus.py +101 -0
- activegraph/observability/status.py +83 -0
- activegraph/packs/__init__.py +999 -0
- activegraph/packs/diligence/__init__.py +86 -0
- activegraph/packs/diligence/behaviors.py +447 -0
- activegraph/packs/diligence/fixtures/__init__.py +364 -0
- activegraph/packs/diligence/fixtures/companies.py +511 -0
- activegraph/packs/diligence/object_types.py +163 -0
- activegraph/packs/diligence/settings.py +60 -0
- activegraph/packs/diligence/tools.py +124 -0
- activegraph/packs/loader.py +709 -0
- activegraph/packs/scaffold.py +317 -0
- activegraph/policy.py +20 -0
- activegraph/runtime/__init__.py +1 -0
- activegraph/runtime/behavior_graph.py +151 -0
- activegraph/runtime/budget.py +120 -0
- activegraph/runtime/config_errors.py +124 -0
- activegraph/runtime/diff.py +145 -0
- activegraph/runtime/errors.py +216 -0
- activegraph/runtime/exec_errors.py +232 -0
- activegraph/runtime/patterns.py +946 -0
- activegraph/runtime/queue.py +27 -0
- activegraph/runtime/registration_errors.py +291 -0
- activegraph/runtime/registry.py +111 -0
- activegraph/runtime/runtime.py +2441 -0
- activegraph/runtime/scheduler.py +206 -0
- activegraph/runtime/view_builder.py +65 -0
- activegraph/store/__init__.py +41 -0
- activegraph/store/base.py +66 -0
- activegraph/store/conformance.py +161 -0
- activegraph/store/errors.py +84 -0
- activegraph/store/memory.py +118 -0
- activegraph/store/postgres.py +609 -0
- activegraph/store/serde.py +202 -0
- activegraph/store/sqlite.py +446 -0
- activegraph/store/url.py +230 -0
- activegraph/tools/__init__.py +64 -0
- activegraph/tools/base.py +57 -0
- activegraph/tools/cache.py +157 -0
- activegraph/tools/context.py +48 -0
- activegraph/tools/decorators.py +70 -0
- activegraph/tools/errors.py +320 -0
- activegraph/tools/graph_query.py +94 -0
- activegraph/tools/recorded.py +205 -0
- activegraph/tools/web_fetch.py +80 -0
- activegraph/trace/__init__.py +1 -0
- activegraph/trace/causal.py +123 -0
- activegraph/trace/printer.py +495 -0
- activegraph-1.0.0rc2.dist-info/METADATA +228 -0
- activegraph-1.0.0rc2.dist-info/RECORD +82 -0
- activegraph-1.0.0rc2.dist-info/WHEEL +5 -0
- activegraph-1.0.0rc2.dist-info/entry_points.txt +5 -0
- activegraph-1.0.0rc2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""Execution-layer error leaves. v1.0 PR-D — ExecutionError category.
|
|
2
|
+
|
|
3
|
+
The two carrier leaves (:class:`LLMBehaviorError`,
|
|
4
|
+
:class:`ToolError`) live in their topic modules (``activegraph/llm/errors.py``
|
|
5
|
+
and ``activegraph/tools/errors.py``) because the per-reason prose
|
|
6
|
+
tables are co-located with the modules that raise them. This module
|
|
7
|
+
holds the runtime-internal execution-layer leaves that don't fit
|
|
8
|
+
cleanly into either topic.
|
|
9
|
+
|
|
10
|
+
PR-D adds:
|
|
11
|
+
|
|
12
|
+
- :class:`ApprovalNotFoundError` — pending-approval lookup miss.
|
|
13
|
+
|
|
14
|
+
PR-F adds (cross-category audit findings — sites that looked like
|
|
15
|
+
ConfigurationError on the PR-E hand-off list but classified as
|
|
16
|
+
ExecutionError on closer reading):
|
|
17
|
+
|
|
18
|
+
- :class:`RuntimeContextRequiredError` — ``ctx.propose_object`` was
|
|
19
|
+
called from a behavior whose context wasn't bound to a runtime.
|
|
20
|
+
Fires inside a running behavior, not at construction time.
|
|
21
|
+
- :class:`InvalidPatchLifecycleState` — ``graph.apply_patch`` was
|
|
22
|
+
called on a patch that isn't in ``"proposed"`` state. Fires during
|
|
23
|
+
the patch lifecycle, mid-execution.
|
|
24
|
+
|
|
25
|
+
PR-G adds:
|
|
26
|
+
|
|
27
|
+
- :class:`InternalEvaluatorError` — for the view-filter evaluator in
|
|
28
|
+
``graph.py``. Sibling to the two pattern-evaluator internal-bug
|
|
29
|
+
raises in ``activegraph/runtime/patterns.py``; uses the shared
|
|
30
|
+
:func:`activegraph.errors.internal_bug_fields` helper so the
|
|
31
|
+
framework-bug prose is uniform across all three sites.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
from typing import Any, Optional
|
|
37
|
+
|
|
38
|
+
from activegraph.errors import DOCS_BASE_URL, ExecutionError
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ApprovalNotFoundError(ExecutionError, LookupError):
|
|
42
|
+
"""Pending-approval lookup miss.
|
|
43
|
+
|
|
44
|
+
Fires from ``runtime.approve(approval_id)`` when the id doesn't
|
|
45
|
+
refer to any currently-pending approval. Multi-inherits
|
|
46
|
+
:class:`LookupError` so user code that does ``except LookupError``
|
|
47
|
+
around the approval API continues to work.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
_doc_slug = "approval-not-found-error"
|
|
51
|
+
|
|
52
|
+
def __init__(
|
|
53
|
+
self,
|
|
54
|
+
approval_id: str,
|
|
55
|
+
*,
|
|
56
|
+
pending_count: Optional[int] = None,
|
|
57
|
+
) -> None:
|
|
58
|
+
self.approval_id = approval_id
|
|
59
|
+
self.pending_count = pending_count
|
|
60
|
+
ctx: dict[str, Any] = {"approval_id": approval_id}
|
|
61
|
+
if pending_count is not None:
|
|
62
|
+
ctx["pending_count"] = pending_count
|
|
63
|
+
pending_hint = (
|
|
64
|
+
f"There are currently {pending_count} pending approvals; "
|
|
65
|
+
f"none of them match {approval_id!r}."
|
|
66
|
+
if pending_count is not None
|
|
67
|
+
else "There are no pending approvals in this runtime."
|
|
68
|
+
)
|
|
69
|
+
ExecutionError.__init__(
|
|
70
|
+
self,
|
|
71
|
+
f"no pending approval named {approval_id!r}",
|
|
72
|
+
what_failed=(
|
|
73
|
+
f"runtime.approve({approval_id!r}) could not find a pending "
|
|
74
|
+
f"approval with that id.\n {pending_hint}"
|
|
75
|
+
),
|
|
76
|
+
why=(
|
|
77
|
+
"Approval ids are generated by the runtime when a behavior "
|
|
78
|
+
"calls ctx.propose_object under a gating policy "
|
|
79
|
+
"(memo_approval, risk_approval, etc.). Each id is unique "
|
|
80
|
+
"to its runtime instance and is consumed when approve() "
|
|
81
|
+
"succeeds. A miss means either the id is stale (already "
|
|
82
|
+
"approved or denied), the runtime instance is fresh "
|
|
83
|
+
"(approvals don't carry across Runtime.load), or the id is "
|
|
84
|
+
"a typo. The framework refuses to no-op an unknown id "
|
|
85
|
+
"because that would silently corrupt the approval audit "
|
|
86
|
+
"trail."
|
|
87
|
+
),
|
|
88
|
+
how_to_fix=(
|
|
89
|
+
"List the currently-pending approvals:\n"
|
|
90
|
+
" rt.pending_approvals()\n"
|
|
91
|
+
"to confirm what's actually pending. The diligence demo's\n"
|
|
92
|
+
"step_2_approval_demo (examples/diligence_real_run.py)\n"
|
|
93
|
+
"shows the canonical pattern: enumerate, then approve by id."
|
|
94
|
+
),
|
|
95
|
+
context=ctx,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class RuntimeContextRequiredError(ExecutionError, RuntimeError):
|
|
100
|
+
"""``ctx.propose_object`` (or another ctx method that requires the
|
|
101
|
+
runtime) was called from a behavior whose context isn't bound to a
|
|
102
|
+
runtime.
|
|
103
|
+
|
|
104
|
+
Fires at execution time, inside a running behavior — the caller is
|
|
105
|
+
the behavior body that invoked the ctx method, not the framework's
|
|
106
|
+
construction code. Multi-inherits :class:`RuntimeError` for
|
|
107
|
+
back-compat.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
_doc_slug = "runtime-context-required-error"
|
|
111
|
+
|
|
112
|
+
def __init__(self, *, method: str = "ctx.propose_object") -> None:
|
|
113
|
+
self.method = method
|
|
114
|
+
ExecutionError.__init__(
|
|
115
|
+
self,
|
|
116
|
+
f"{method} requires a runtime-bound context",
|
|
117
|
+
what_failed=(
|
|
118
|
+
f"A behavior called {method} on a BehaviorGraph context that "
|
|
119
|
+
f"was constructed without a Runtime — likely a test fixture "
|
|
120
|
+
f"that stubbed the graph without going through Runtime."
|
|
121
|
+
),
|
|
122
|
+
why=(
|
|
123
|
+
"ctx.propose_object writes to the runtime's pending-approvals "
|
|
124
|
+
"queue and emits a `approval.proposed` event. Without a "
|
|
125
|
+
"runtime, neither side effect can happen, and a no-op would "
|
|
126
|
+
"silently break the policy gate the behavior depends on — "
|
|
127
|
+
"the audit trail would show no proposal and the operator "
|
|
128
|
+
"would have no record to approve.\n"
|
|
129
|
+
"\n"
|
|
130
|
+
f"See {DOCS_BASE_URL}/concepts/failure-model "
|
|
131
|
+
f"for when the framework prefers exceptions over silent no-ops."
|
|
132
|
+
),
|
|
133
|
+
how_to_fix=(
|
|
134
|
+
"Construct the BehaviorGraph through a Runtime:\n"
|
|
135
|
+
" rt = Runtime(graph, ...)\n"
|
|
136
|
+
" rt.run_goal('...') # behaviors see ctx bound to rt\n"
|
|
137
|
+
"\n"
|
|
138
|
+
"In a test, drive the behavior through a real Runtime — the "
|
|
139
|
+
"ctx is built from the runtime's context factory and bound "
|
|
140
|
+
"automatically. Mocking the ctx directly bypasses this; if "
|
|
141
|
+
"the test really needs to bypass the runtime, mock the "
|
|
142
|
+
"policy gate as well so propose_object isn't reached."
|
|
143
|
+
),
|
|
144
|
+
context={"method": method},
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class InvalidPatchLifecycleState(ExecutionError, ValueError):
|
|
149
|
+
"""``graph.apply_patch(patch_id)`` was called on a patch that isn't
|
|
150
|
+
in ``"proposed"`` state.
|
|
151
|
+
|
|
152
|
+
Patches go through ``proposed → applied`` (success) or ``proposed →
|
|
153
|
+
rejected`` (policy or behavior rejection). Calling ``apply_patch``
|
|
154
|
+
on an already-applied or already-rejected patch is a programmer
|
|
155
|
+
error in the calling code path; the framework refuses rather than
|
|
156
|
+
re-apply or silently no-op. Multi-inherits :class:`ValueError`.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
_doc_slug = "invalid-patch-lifecycle-state"
|
|
160
|
+
|
|
161
|
+
def __init__(self, *, patch_id: str, current_status: str) -> None:
|
|
162
|
+
self.patch_id = patch_id
|
|
163
|
+
self.current_status = current_status
|
|
164
|
+
ExecutionError.__init__(
|
|
165
|
+
self,
|
|
166
|
+
f"patch {patch_id} is {current_status!r}, not 'proposed'",
|
|
167
|
+
what_failed=(
|
|
168
|
+
f"graph.apply_patch({patch_id!r}) was called, but the patch's "
|
|
169
|
+
f"current status is {current_status!r}. Only patches in the "
|
|
170
|
+
f"'proposed' state can be applied."
|
|
171
|
+
),
|
|
172
|
+
why=(
|
|
173
|
+
"Patches are one-shot: a 'proposed' patch becomes 'applied' "
|
|
174
|
+
"(success) or 'rejected' (refusal) exactly once. Re-applying "
|
|
175
|
+
"an already-applied patch would emit a duplicate "
|
|
176
|
+
"`patch.applied` event, which would break the replay "
|
|
177
|
+
"contract — replay would produce a different event stream "
|
|
178
|
+
"than the original run. The framework refuses re-application "
|
|
179
|
+
"rather than emit the duplicate.\n"
|
|
180
|
+
"\n"
|
|
181
|
+
f"See {DOCS_BASE_URL}/concepts/failure-model "
|
|
182
|
+
f"for the patch-lifecycle invariants."
|
|
183
|
+
),
|
|
184
|
+
how_to_fix=(
|
|
185
|
+
f"Check the patch's current status before applying:\n"
|
|
186
|
+
f" patch = graph.get_patch({patch_id!r})\n"
|
|
187
|
+
f" if patch.status == 'proposed':\n"
|
|
188
|
+
f" graph.apply_patch({patch_id!r})\n"
|
|
189
|
+
f"\n"
|
|
190
|
+
f"If the patch is already applied and the caller wants a "
|
|
191
|
+
f"new mutation, propose a new patch — patches don't get "
|
|
192
|
+
f"re-used."
|
|
193
|
+
),
|
|
194
|
+
context={"patch_id": patch_id, "current_status": current_status},
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class InternalEvaluatorError(ExecutionError, ValueError):
|
|
199
|
+
"""A framework-internal evaluator received input it does not
|
|
200
|
+
recognize. Should not fire in normal use — the framework's parsers
|
|
201
|
+
produce a closed set of operators / AST nodes, and an unrecognized
|
|
202
|
+
one means either drift between parser and evaluator or external
|
|
203
|
+
AST construction that bypassed the parser.
|
|
204
|
+
|
|
205
|
+
Multi-inherits :class:`ValueError` so user code that catches the
|
|
206
|
+
builtin around view operations continues to work. Used by
|
|
207
|
+
``activegraph/core/graph.py`` for the view-filter evaluator; the
|
|
208
|
+
pattern-subscription evaluator's two internal-bug raises stay as
|
|
209
|
+
:class:`UnsupportedPatternError` (the natural category) but use
|
|
210
|
+
the same :func:`activegraph.errors.internal_bug_fields` helper so
|
|
211
|
+
the prose is uniform across all three sites.
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
_doc_slug = "internal-evaluator-error"
|
|
215
|
+
|
|
216
|
+
def __init__(
|
|
217
|
+
self,
|
|
218
|
+
summary: str,
|
|
219
|
+
*,
|
|
220
|
+
what_failed: str,
|
|
221
|
+
why: str,
|
|
222
|
+
how_to_fix: str,
|
|
223
|
+
context: Optional[dict[str, Any]] = None,
|
|
224
|
+
) -> None:
|
|
225
|
+
ExecutionError.__init__(
|
|
226
|
+
self,
|
|
227
|
+
summary,
|
|
228
|
+
what_failed=what_failed,
|
|
229
|
+
why=why,
|
|
230
|
+
how_to_fix=how_to_fix,
|
|
231
|
+
context=context,
|
|
232
|
+
)
|