matrx-runtime 0.0.1__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 (31) hide show
  1. matrx_runtime-0.0.1/.gitignore +271 -0
  2. matrx_runtime-0.0.1/CLAUDE.md +114 -0
  3. matrx_runtime-0.0.1/PKG-INFO +48 -0
  4. matrx_runtime-0.0.1/README.md +27 -0
  5. matrx_runtime-0.0.1/matrx_runtime/__init__.py +146 -0
  6. matrx_runtime-0.0.1/matrx_runtime/_config.py +52 -0
  7. matrx_runtime-0.0.1/matrx_runtime/db/__init__.py +217 -0
  8. matrx_runtime-0.0.1/matrx_runtime/db/bootstrap/000_substrate.sql +82 -0
  9. matrx_runtime-0.0.1/matrx_runtime/db/bootstrap/010_identity.sql +84 -0
  10. matrx_runtime-0.0.1/matrx_runtime/db/bootstrap/020_runtime.sql +206 -0
  11. matrx_runtime-0.0.1/matrx_runtime/db/models_runtime.py +143 -0
  12. matrx_runtime-0.0.1/matrx_runtime/engine.py +865 -0
  13. matrx_runtime-0.0.1/matrx_runtime/lifecycle.py +142 -0
  14. matrx_runtime-0.0.1/matrx_runtime/models.py +353 -0
  15. matrx_runtime-0.0.1/matrx_runtime/origins.py +79 -0
  16. matrx_runtime-0.0.1/matrx_runtime/orm_store.py +388 -0
  17. matrx_runtime-0.0.1/matrx_runtime/store.py +364 -0
  18. matrx_runtime-0.0.1/pyproject.toml +54 -0
  19. matrx_runtime-0.0.1/tests/__init__.py +0 -0
  20. matrx_runtime-0.0.1/tests/test_bootstrap_schema.py +121 -0
  21. matrx_runtime-0.0.1/tests/test_engine.py +223 -0
  22. matrx_runtime-0.0.1/tests/test_idempotency.py +35 -0
  23. matrx_runtime-0.0.1/tests/test_lease_reaper.py +271 -0
  24. matrx_runtime-0.0.1/tests/test_lifecycle.py +76 -0
  25. matrx_runtime-0.0.1/tests/test_meter_and_context.py +73 -0
  26. matrx_runtime-0.0.1/tests/test_origins.py +53 -0
  27. matrx_runtime-0.0.1/tests/test_orm_store.py +206 -0
  28. matrx_runtime-0.0.1/tests/test_payload_blind.py +99 -0
  29. matrx_runtime-0.0.1/tests/test_proof.py +127 -0
  30. matrx_runtime-0.0.1/tests/test_scope.py +190 -0
  31. matrx_runtime-0.0.1/tests/test_tree_read.py +134 -0
@@ -0,0 +1,271 @@
1
+ *.pyc
2
+ secrets/
3
+ ignore/
4
+ temp/
5
+ logs/
6
+ # The broad `logs/` rule above is for RUNTIME log output, but it also matched
7
+ # the dashboard's SOURCE directory and silently swallowed an entire feature's
8
+ # files (only the pre-existing index.tsx stayed tracked), breaking the prod
9
+ # Docker build with "Could not resolve ./structured-tab". Re-include the source.
10
+ !apps/dashboard/src/features/logs/
11
+ !apps/dashboard/src/features/logs/**
12
+ todo
13
+ text_notes/
14
+ aidream/secrets/2.env
15
+ automation_matrix/matrix_processing/temp/*
16
+ cd
17
+ # Byte-compiled / optimized / DLL files
18
+ __pycache__/
19
+ *.py[cod]
20
+ *$py.class
21
+
22
+ # C extensions
23
+ *.so
24
+ .venv/
25
+
26
+ # Distribution / packaging
27
+ .Python
28
+ build/
29
+ develop-eggs/
30
+ dist/
31
+ downloads/
32
+ eggs/
33
+ .eggs/
34
+ lib/
35
+ lib64/
36
+ # The blanket lib/ rule above is from the standard Python .gitignore template
37
+ # and was silently swallowing TS source under the SPA `src/lib/` folders.
38
+ # Re-allow them explicitly so frontend builds don't ship without their lib layer.
39
+ !apps/dashboard/src/lib/
40
+ !apps/dashboard/src/lib/**
41
+ !apps/workflow-studio/src/lib/
42
+ !apps/workflow-studio/src/lib/**
43
+ parts/
44
+ sdist/
45
+ var/
46
+ wheels/
47
+ share/python-wheels/
48
+ *.egg-info/
49
+ .installed.cfg
50
+ *.egg
51
+ MANIFEST
52
+
53
+ # PyInstaller
54
+ # Usually these files are written by a python script from a template
55
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
56
+ *.manifest
57
+ *.spec
58
+
59
+ # Installer logs
60
+ pip-log.txt
61
+ pip-delete-this-directory.txt
62
+
63
+ # Unit test / coverage reports
64
+ ai/tests/clean_response.json
65
+ ai/tests/cx_storage_response.json
66
+ ai/tests/execution_test.py
67
+ ai/tests/final_response.json
68
+ htmlcov/
69
+ .tox/
70
+ .nox/
71
+ .coverage
72
+ .coverage.*
73
+ .cache
74
+ nosetests.xml
75
+ coverage.xml
76
+ *.cover
77
+ *.py,cover
78
+ .hypothesis/
79
+ .pytest_cache/
80
+ cover/
81
+
82
+ # Translations
83
+ *.mo
84
+ *.pot
85
+
86
+ # Django stuff:
87
+ *.log
88
+ local_settings.py
89
+ db.sqlite3
90
+ db.sqlite3-journal
91
+
92
+ # Flask stuff:
93
+ instance/
94
+ .webassets-cache
95
+
96
+ # Scrapy stuff:
97
+ .scrapy
98
+
99
+ # Sphinx documentation
100
+ docs/_build/
101
+
102
+ # PyBuilder
103
+ .pybuilder/
104
+ target/
105
+
106
+ # Jupyter Notebook
107
+ .ipynb_checkpoints
108
+
109
+ # IPython
110
+ profile_default/
111
+ ipython_config.py
112
+
113
+ # pyenv
114
+ # For a library or package, you might want to ignore these files since the code is
115
+ # intended to run in multiple environments; otherwise, check them in:
116
+ # .python-version
117
+
118
+ # pipenv
119
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
120
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
121
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
122
+ # install all needed dependencies.
123
+ #Pipfile.lock
124
+
125
+ # poetry
126
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
127
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
128
+ # commonly ignored for libraries.
129
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
130
+
131
+ # pdm
132
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
133
+ #pdm.lock
134
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
135
+ # in version control.
136
+ # https://pdm.fming.dev/#use-with-ide
137
+ .pdm.toml
138
+
139
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
140
+ __pypackages__/
141
+
142
+ # Celery stuff
143
+ celerybeat-schedule
144
+ celerybeat.pid
145
+
146
+ # SageMath parsed files
147
+ *.sage.py
148
+
149
+ # Environments
150
+ .env
151
+ .env_remote
152
+ .venv
153
+ env/
154
+ venv/
155
+ ENV/
156
+ env.bak/
157
+ venv.bak/
158
+ .env.armanonly
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # random armani files
179
+ /armani_dev/secrets/
180
+ /armani/
181
+ /_armani/
182
+
183
+
184
+
185
+ # pytype static type analyzer
186
+ .pytype/
187
+
188
+ # Cython debug symbols
189
+ cython_debug/
190
+
191
+ .idea/
192
+ .vscode/
193
+ /node_modules/
194
+
195
+ # Frontend pnpm workspace (apps/) — node_modules at the workspace root and any
196
+ # member, plus Vite caches and build output. The unified lockfile (apps/pnpm-lock.yaml)
197
+ # IS committed; everything below is regenerated.
198
+ node_modules/
199
+ apps/**/.vite/
200
+ apps/**/dist/
201
+ .vite/
202
+
203
+ dump.rdb
204
+
205
+ frontend/
206
+
207
+ # AME Temp Files and directory structure
208
+ # Ignore all files in the temp directory and its subdirectories
209
+ /temp/**/*
210
+ /tmp/**/*
211
+
212
+ # Allow .gitkeep files to retain directory structure
213
+ !/temp/**/.gitkeep
214
+ !/tmp/**/.gitkeep
215
+
216
+ # Armani
217
+ .history*
218
+ .history/
219
+ local_data/
220
+ local_reports_data/
221
+ webscraper/quick_scrapes/temp/
222
+ automation_matrix/ai_apis/fireworks/_dev/*
223
+ automation_matrix/ai_apis/fireworks/_dev/fireworks_sample.py
224
+ *.pdf
225
+ *.flac
226
+ *.mp3
227
+ *.wav
228
+ miniconda.sh
229
+ /database/python_sql/temp_data/
230
+ .history*
231
+ .history/
232
+ .history/
233
+
234
+ _dev/
235
+ /_dev/
236
+ requirements_filtered.txt
237
+
238
+ # matrx-dev-tools backups
239
+ .env-backups/
240
+ # Matrx Ship config (contains API key)
241
+ .matrx-ship.json
242
+
243
+ # Matrx config (contains API keys)
244
+ .matrx.json
245
+ .matrx-tools.conf
246
+
247
+ # Claude Code local worktrees and per-user settings
248
+ .claude/worktrees/
249
+ .claude/settings.local.json
250
+
251
+ # Append-only snapshots from matrx_utils.update_history (unbounded; do not commit)
252
+ common/utils/data_in_code/data_history.json
253
+ packages/matrx-utils/matrx_utils/data_in_code/data_history.json
254
+
255
+ # Tool-dispatch debug logs — one file per server start, never committed
256
+ .matrx-debug/
257
+
258
+ # macOS Finder metadata
259
+ .DS_Store
260
+ **/.DS_Store
261
+
262
+ # Environment files
263
+ .env
264
+ .env.*
265
+ *.env
266
+ *.env.*
267
+
268
+ # Keep safe templates trackable
269
+ !.env.example
270
+ !.env.sample
271
+ !.env.template
@@ -0,0 +1,114 @@
1
+ # CLAUDE.md — matrx-runtime
2
+
3
+ > **Operating Principle: Build the platform, not the artifact.** Full doctrine: [/PRINCIPLES.md](../../PRINCIPLES.md).
4
+
5
+ **Package:** `matrx-runtime` — the **Request Management Layer** — Python 3.13+ — pre-alpha (v0.0.1).
6
+ **Role in the graph:** the generic request/execution substrate. Sits **below** every consumer (`matrx-ai`, `matrx-graph`, `matrx-scraper`, aidream) and **above** `matrx-utils` / `matrx-connect` / `matrx-orm`.
7
+
8
+ Canonical design: **[docs/runtime/REQUEST_MANAGEMENT_LAYER.md](../../docs/runtime/REQUEST_MANAGEMENT_LAYER.md)** (read it first).
9
+
10
+ ---
11
+
12
+ ## What this package IS
13
+
14
+ > You hand us a request; we own its entire life and its whole nested tree —
15
+ > identity, nesting, status, every failure and success, accumulated cost and any
16
+ > metered limit, context propagation, cancellation, and resume — **without knowing
17
+ > or caring what the work is.**
18
+
19
+ ## The ONE invariant — payload-blind
20
+
21
+ matrx-runtime **must never** know the words **chat, agent, conversation, provider,
22
+ token, message, tool**. It deals only in generic `global_execution`s with an
23
+ **opaque `type`** label (a "registered_action": `utility`/`conversation`/`workflow`/…
24
+ — the host's strings, never enumerated here). Feature data lives in the consumer's
25
+ OWN tables, reached only via the opaque `link_kind`/`link_id` pointer. The interiors
26
+ of `MeterEvent` and `ExecutionContext` are opaque too — we sum numerics and
27
+ propagate context without interpreting them.
28
+
29
+ A test (`test_proof.py`) proves it: one engine drives `utility` + `conversation` +
30
+ `workflow` + every nesting case identically. Run `uv run pytest packages/matrx-runtime/tests/test_proof.py -s`.
31
+
32
+ ## The surface
33
+
34
+ - **`ExecutionEngine`** (`engine.py`) — the one typed service. `create_root` /
35
+ `spawn_child` (with a `ContextMode`: inherit|scope|replace) / lifecycle
36
+ transitions / `record(MeterEvent)` / tree rollups / `ensure_can_proceed` (budget
37
+ + per-quantity limit + cancel + deadline) / checkpoints. Status changes ONLY via
38
+ the lifecycle (`transition`), CAS so a terminal is written exactly once.
39
+ - **`ExecutionScope`** (`engine.execution(...)` / `scope.child(...)`) — the ONE
40
+ uniform lifecycle wrapper every consumer runs work inside: enter creates+starts,
41
+ clean exit auto-completes with accrued cost, an exception auto-fails (structured
42
+ error) or cancels and re-raises; `record` / `ensure_can_proceed` / `checkpoint` /
43
+ `request_input` / `renew_lease` / `note` (opaque observability annotation on THIS
44
+ execution — the scope-level door to `record_note`) for the body; explicit
45
+ `complete/fail/cancel` for return-based consumers. No consumer hand-rolls lifecycle — utility/conversation/
46
+ workflow differ only in the body.
47
+ - **Crash recovery — lease + reaper (layer 1, ACTS) + `find_stuck` (layer 2, ALARMS).**
48
+ `start(holder=, lease_seconds=)` leases a running execution (opt-in; unleased = never
49
+ reaped), `renew_lease(...)` heartbeats, **`reap_expired(now=)`** sweeps dead-worker
50
+ executions → FAILED `matrx_execution_abandoned` (cost preserved, CAS-safe). Because
51
+ unleased actives are structurally invisible to the reaper, **`find_stuck(now=, older_than=)`**
52
+ is the independent second layer: it RETURNS (never mutates) the reaper-blind stuck rows
53
+ (unleased/ never-started actives past a deadline) so the host watchdog screams — no work is
54
+ ever silently lost. Both host-scheduled.
55
+ - **`MeterEvent`** (`models.py`) — the metering primitive. A consumer subclasses it
56
+ with numeric fields; EVERY numeric is a tracked quantity summed per execution +
57
+ tree; `money_field` feeds the budgeted `cost`. Covers money, tokens, rate-limits,
58
+ rows — one mechanism, runtime knows none of their meanings.
59
+ - **`ExecutionContext`** + `ContextMode` — the typed context carrier. Runtime owns
60
+ PROPAGATION + per-execution SNAPSHOT across the tree (where the nested-handoff bug
61
+ class lived); the interior is opaque; creation stays Matrx Connect.
62
+ - **Origin registry** (`origins.py`) — `sync_origins` (config-driven, drift-checked,
63
+ soft-deleted) + `is_caller_allowed` (host admission policy). CORS/transport stays
64
+ Connect; runtime owns only the guest list + policy.
65
+ - **`ExecutionStore`** port + `InMemoryExecutionStore` (tests) + matrx-orm
66
+ `OrmExecutionStore` (the 7 `runtime.*` tables).
67
+
68
+ ## What this package is NOT
69
+
70
+ - **NOT an executor.** The conversation loop is `matrx-ai`'s; the workflow superstep
71
+ is `matrx-graph`'s; utilities are the consumer's. They drive the engine; their
72
+ complexity never leaks in here.
73
+ - **NOT transport** (CORS/auth/streaming = Matrx Connect), **NOT the work**, **NOT a
74
+ general logger**, **NOT feature tables.**
75
+
76
+ ## DB models
77
+
78
+ `db/models_runtime.py` is GENERATED (the `runtime` entry in aidream's
79
+ `db/matrx_orm.yaml`) — change the live schema, then `python db/generate.py`; never
80
+ hand-edit beyond keeping it in sync. The 7 tables: `global_origin`,
81
+ `global_request`, `global_execution`, `global_execution_control`,
82
+ `global_execution_event`, `global_execution_checkpoint`, `global_meter_entry`.
83
+
84
+ ## Standalone substrate (the package DEFINES its own schema)
85
+
86
+ matrx-runtime is a **standalone, opinionated** package: it ships the canonical
87
+ substrate it needs and CREATES it on a bare DB. `db/bootstrap/*.sql` (applied in
88
+ `NNN_*` order by **`apply_schema()`**) creates the schemas (`platform`/`iam`/`runtime`),
89
+ the `visibility`/`permission_level` enums, the portable `_touch_row`/`_stamp_actor`
90
+ trigger functions (GUC actor, NOT `auth.uid()`), a minimal `organizations` + registries
91
+ + fail-closed `iam.has_access`, and the 7 `runtime.*` tables + indexes + triggers + RLS.
92
+ - **Standalone:** `bootstrap_db()` (pool) → `await apply_schema()` (DDL). Fresh DB → working spine.
93
+ - **Hosted (aidream):** the real substrate exists; aidream does NOT call `apply_schema()`.
94
+ - **THE INVARIANT — non-destructive:** every statement is `IF NOT EXISTS` /
95
+ create-if-absent / `ON CONFLICT DO NOTHING`. Running it against aidream changes
96
+ NOTHING; it never overwrites a richer host object. `test_bootstrap_schema.py` enforces
97
+ this. Full design + the pattern for other packages: [docs/runtime/STANDALONE_SUBSTRATE.md](../../docs/runtime/STANDALONE_SUBSTRATE.md).
98
+
99
+ ## Dependency rules (mechanically enforced)
100
+
101
+ - Declare ONLY what you import (`pydantic`, `matrx-orm`). The boundary gate fails
102
+ the build on an undeclared sibling or any `aidream`/repo-root import.
103
+ - ❌ Never import an executor (`matrx-ai`, `matrx-graph`) — the dependency points the other way.
104
+ - ❌ Never name a chat/agent/provider concept in this package.
105
+
106
+ ## Testing
107
+
108
+ ```bash
109
+ uv run pytest packages/matrx-runtime/tests
110
+ ```
111
+
112
+ The whole behavioral core is tested against `InMemoryExecutionStore`, **no
113
+ database**. `OrmExecutionStore` is unit-tested with mocked matrx-orm Models
114
+ (`test_orm_store.py`) — call-shape only, never a live DB.
@@ -0,0 +1,48 @@
1
+ Metadata-Version: 2.4
2
+ Name: matrx-runtime
3
+ Version: 0.0.1
4
+ Summary: The durable-execution substrate: one global_execution spine, one lifecycle state machine, one cost ledger, that every matrx-* executor (agent loop, workflow superstep, utilities) plugs into.
5
+ Author-email: Matrx <admin@aimatrx.com>
6
+ License: MIT
7
+ Keywords: durable,execution,matrx,orchestration,runtime
8
+ Classifier: Development Status :: 2 - Pre-Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
+ Requires-Python: >=3.13
15
+ Requires-Dist: matrx-orm>=3.1
16
+ Requires-Dist: pydantic>=2.12
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
19
+ Requires-Dist: pytest>=8.0; extra == 'dev'
20
+ Description-Content-Type: text/markdown
21
+
22
+ # matrx-runtime
23
+
24
+ The durable-execution substrate for the Matrx platform.
25
+
26
+ Every unit of work — a utility call, a workflow run, an agent session — is one
27
+ row on a single `global_execution` spine that can nest inside any other. The
28
+ substrate owns the concerns all three flavors share, so they compose freely and
29
+ share **one lifecycle, one nesting tree, one cost ledger, and one enforced state
30
+ machine**:
31
+
32
+ - run identity + lineage (`parent_execution_id`, denormalized `root_execution_id`)
33
+ - the lifecycle state machine (`transition()` — the only legal way to change status)
34
+ - the cost ledger + tree-wide budget *(forthcoming)*
35
+ - cancellation signal + down-tree propagation *(forthcoming)*
36
+ - generalized checkpoint + lifecycle-event primitives *(forthcoming)*
37
+ - the hardened write coordinator *(moving in from matrx-ai)*
38
+ - the typed runtime context *(forthcoming)*
39
+
40
+ Executors plug in as strategies and are NOT owned here: the agent loop
41
+ (`matrx-ai`), the superstep DAG (`matrx-graph`), utility implementations
42
+ (`matrx-scraper`).
43
+
44
+ Status: **pre-alpha.** The pure decision core (lifecycle + spine models) is in
45
+ place; the persistence/coordinator/context drops follow. Built behind a `/v2`
46
+ route; the legacy `cx_*` / `wf_*` paths are untouched until cutover.
47
+
48
+ Design + phased plan: [`docs/runtime/EXECUTION_SPINE.md`](../../docs/runtime/EXECUTION_SPINE.md).
@@ -0,0 +1,27 @@
1
+ # matrx-runtime
2
+
3
+ The durable-execution substrate for the Matrx platform.
4
+
5
+ Every unit of work — a utility call, a workflow run, an agent session — is one
6
+ row on a single `global_execution` spine that can nest inside any other. The
7
+ substrate owns the concerns all three flavors share, so they compose freely and
8
+ share **one lifecycle, one nesting tree, one cost ledger, and one enforced state
9
+ machine**:
10
+
11
+ - run identity + lineage (`parent_execution_id`, denormalized `root_execution_id`)
12
+ - the lifecycle state machine (`transition()` — the only legal way to change status)
13
+ - the cost ledger + tree-wide budget *(forthcoming)*
14
+ - cancellation signal + down-tree propagation *(forthcoming)*
15
+ - generalized checkpoint + lifecycle-event primitives *(forthcoming)*
16
+ - the hardened write coordinator *(moving in from matrx-ai)*
17
+ - the typed runtime context *(forthcoming)*
18
+
19
+ Executors plug in as strategies and are NOT owned here: the agent loop
20
+ (`matrx-ai`), the superstep DAG (`matrx-graph`), utility implementations
21
+ (`matrx-scraper`).
22
+
23
+ Status: **pre-alpha.** The pure decision core (lifecycle + spine models) is in
24
+ place; the persistence/coordinator/context drops follow. Built behind a `/v2`
25
+ route; the legacy `cx_*` / `wf_*` paths are untouched until cutover.
26
+
27
+ Design + phased plan: [`docs/runtime/EXECUTION_SPINE.md`](../../docs/runtime/EXECUTION_SPINE.md).
@@ -0,0 +1,146 @@
1
+ """matrx-runtime — the Request Management Layer.
2
+
3
+ You hand us a request; we own its entire life and its whole nested tree —
4
+ identity, nesting, status, every failure and success, accumulated cost and any
5
+ metered limit, context propagation, cancellation, and resume — WITHOUT knowing or
6
+ caring what the work is. Payload-blind: never chat, agents, providers, tokens, or
7
+ messages. Feature data stays in the consumer's tables, reached via an opaque
8
+ `link_kind`/`link_id`.
9
+
10
+ Design: docs/runtime/REQUEST_MANAGEMENT_LAYER.md. Public API = exactly __all__.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from matrx_runtime.lifecycle import (
16
+ ALLOWED_TRANSITIONS,
17
+ InvalidExecutionTransition,
18
+ TransitionResult,
19
+ can_transition,
20
+ event_for_transition,
21
+ is_terminal,
22
+ transition,
23
+ )
24
+ from matrx_runtime.engine import (
25
+ DEFAULT_LEASE_SECONDS,
26
+ BudgetExceeded,
27
+ ConcurrentTransition,
28
+ DeadlineExceeded,
29
+ ExecutionCancelled,
30
+ ExecutionEngine,
31
+ ExecutionNotFound,
32
+ ExecutionScope,
33
+ InvalidLeaseState,
34
+ LimitExceeded,
35
+ )
36
+ from matrx_runtime.models import (
37
+ TERMINAL_STATUSES,
38
+ ContextMode,
39
+ ExecutionCheckpoint,
40
+ ExecutionContext,
41
+ ExecutionControl,
42
+ ExecutionError,
43
+ ExecutionEvent,
44
+ ExecutionEventKind,
45
+ ExecutionOutcome,
46
+ ExecutionStatus,
47
+ ExecutionTree,
48
+ ExecutionTreeNode,
49
+ GlobalExecution,
50
+ MeterEntry,
51
+ MeterEvent,
52
+ Origin,
53
+ Request,
54
+ )
55
+ from matrx_runtime.store import ExecutionStore, InMemoryExecutionStore
56
+ from matrx_runtime.orm_store import OrmExecutionStore
57
+ from matrx_runtime.origins import (
58
+ OriginSpec,
59
+ OriginSyncResult,
60
+ is_caller_allowed,
61
+ sync_origins,
62
+ )
63
+ from matrx_runtime.db import PACKAGE_DB_NAME, apply_schema, bind_to_host, bootstrap_db
64
+
65
+ __version__ = "0.0.1"
66
+
67
+
68
+ def configure(*, db_config_name: str | None = None) -> None:
69
+ """Host-injection entry point (called once at startup; mirrors matrx-rag).
70
+ `db_config_name` is the matrx-orm pool the host already registered — we alias
71
+ the package's `"matrx_runtime"` name onto it and register the `runtime.*`
72
+ Models the `OrmExecutionStore` needs. Standalone installs call `bootstrap_db()`."""
73
+ from matrx_runtime import _config
74
+
75
+ if db_config_name is not None:
76
+ _config.set_db_config_name(db_config_name)
77
+ from matrx_orm import is_database_registered
78
+
79
+ from matrx_runtime.db import bind_to_host as _bind
80
+
81
+ if is_database_registered(db_config_name):
82
+ _bind(db_config_name)
83
+ _config.mark_configured()
84
+
85
+
86
+ def is_configured() -> bool:
87
+ from matrx_runtime import _config
88
+
89
+ return _config.is_configured()
90
+
91
+
92
+ __all__ = [
93
+ # lifecycle
94
+ "transition",
95
+ "can_transition",
96
+ "is_terminal",
97
+ "event_for_transition",
98
+ "TransitionResult",
99
+ "InvalidExecutionTransition",
100
+ "ALLOWED_TRANSITIONS",
101
+ # engine
102
+ "ExecutionEngine",
103
+ "ExecutionScope",
104
+ "ExecutionNotFound",
105
+ "ConcurrentTransition",
106
+ "BudgetExceeded",
107
+ "LimitExceeded",
108
+ "DeadlineExceeded",
109
+ "ExecutionCancelled",
110
+ "InvalidLeaseState",
111
+ "DEFAULT_LEASE_SECONDS",
112
+ # store
113
+ "ExecutionStore",
114
+ "InMemoryExecutionStore",
115
+ "OrmExecutionStore",
116
+ # origin registry
117
+ "OriginSpec",
118
+ "OriginSyncResult",
119
+ "sync_origins",
120
+ "is_caller_allowed",
121
+ # host wiring / db binding
122
+ "configure",
123
+ "is_configured",
124
+ "bind_to_host",
125
+ "bootstrap_db",
126
+ "apply_schema",
127
+ "PACKAGE_DB_NAME",
128
+ # models / enums
129
+ "GlobalExecution",
130
+ "ExecutionStatus",
131
+ "ExecutionEventKind",
132
+ "ContextMode",
133
+ "ExecutionContext",
134
+ "ExecutionError",
135
+ "ExecutionOutcome",
136
+ "ExecutionControl",
137
+ "ExecutionEvent",
138
+ "ExecutionCheckpoint",
139
+ "ExecutionTree",
140
+ "ExecutionTreeNode",
141
+ "MeterEvent",
142
+ "MeterEntry",
143
+ "Origin",
144
+ "Request",
145
+ "TERMINAL_STATUSES",
146
+ ]
@@ -0,0 +1,52 @@
1
+ """Host-injection registry — the seam between matrx-runtime and its host.
2
+
3
+ The host calls :func:`matrx_runtime.configure` once at startup; the package reads
4
+ back what it needs here. Kept tiny and dependency-free (the boundary gate stays
5
+ green). Today the only seam is the matrx-orm pool name the spine persists to; the
6
+ Coordinator/context drops will add their seams here the same way.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+
13
+ _registry: dict[str, object] = {
14
+ # matrx-orm pool identifier the host registered via
15
+ # register_database_from_env. matrx_runtime.configure(db_config_name=...)
16
+ # aliases PACKAGE_DB_NAME onto it.
17
+ "db_config_name": None,
18
+ }
19
+
20
+ _configured = False
21
+
22
+
23
+ def set_db_config_name(name: str) -> None:
24
+ _registry["db_config_name"] = name
25
+
26
+
27
+ def is_configured() -> bool:
28
+ return _configured
29
+
30
+
31
+ def mark_configured() -> None:
32
+ global _configured
33
+ _configured = True
34
+
35
+
36
+ def get_db_config_name() -> str:
37
+ """Resolve the host's matrx-orm pool name.
38
+
39
+ Order: the name injected via ``configure(db_config_name=...)`` → the
40
+ ``MATRX_RUNTIME_DB_NAME`` env var (name of an already-registered config).
41
+ Raises if neither is set — running the ORM-bound store with no configured
42
+ pool is a wiring bug, surfaced loudly rather than silently no-op'd.
43
+ """
44
+ name = _registry.get("db_config_name") or os.environ.get("MATRX_RUNTIME_DB_NAME")
45
+ if not name:
46
+ raise RuntimeError(
47
+ "matrx-runtime: no database configured. Call "
48
+ "matrx_runtime.configure(db_config_name=<registered matrx-orm pool>) "
49
+ "at host startup, set MATRX_RUNTIME_DB_NAME, or use "
50
+ "matrx_runtime.bootstrap_db() for a standalone pool."
51
+ )
52
+ return str(name)