tigrbl-runtime 0.4.5.dev1__tar.gz → 0.4.5.dev6__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.
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/PKG-INFO +21 -16
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/README.md +17 -12
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/pyproject.toml +4 -7
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_jsonrpc.py +11 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_send.py +79 -5
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_webtransport.py +31 -4
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/ctx/context.py +1 -5
- tigrbl_runtime-0.4.5.dev1/tigrbl_runtime/executors/ctx/hot_namespaces.py → tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/ctx/hot_namespace_values.py +0 -221
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/ctx/hot_namespaces.py +240 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/__init__.py +4 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/_shared.py +168 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/batch.py +337 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/error_edges.py +303 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/execute.py +368 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/executor.py +86 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/hot_access.py +222 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/hot_context.py +301 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/input_compile.py +336 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/input_extract.py +310 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/request_select.py +209 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/route_select.py +397 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/route_select_websocket.py +34 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/runner_resolve.py +379 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/executors/packed/segments.py +337 -0
- tigrbl_runtime-0.4.5.dev6/tigrbl_runtime/lowering_services.py +22 -0
- tigrbl_runtime-0.4.5.dev1/tigrbl_runtime/executors/packed.py +0 -3591
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/LICENSE +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/NOTICE +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/__init__.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/callbacks.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/__init__.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_completion.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_context.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_receive.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_scope.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/asgi.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/capabilities.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/websocket.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/config/__init__.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/config/constants.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/__init__.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/_invoke_support.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/base.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/ctx/__init__.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/ctx/hot.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/ctx/hot_state.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/kernel_executor.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/numba_packed.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/phase.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/phase_runner.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/types.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/runtime/__init__.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/runtime/_typing_aliases.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/runtime/base.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/runtime/channel.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/runtime/exceptions.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/runtime/hook_types.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/runtime/response.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/runtime/runtime.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/runtime/system.py +0 -0
- {tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/semantics.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tigrbl-runtime
|
|
3
|
-
Version: 0.4.5.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.5.dev6
|
|
4
|
+
Summary: Execution bridge for compiled Tigrbl kernel plans and narrow runtime context/carrier compatibility.
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
7
7
|
http://www.apache.org/licenses/
|
|
@@ -205,7 +205,7 @@ License: Apache License
|
|
|
205
205
|
limitations under the License.
|
|
206
206
|
License-File: LICENSE
|
|
207
207
|
License-File: NOTICE
|
|
208
|
-
Keywords: tigrbl,asgi,api,
|
|
208
|
+
Keywords: tigrbl,asgi,api,sqlalchemy,pydantic,runtime,pipeline,bridge,schema-first
|
|
209
209
|
Author: Jacob Stewart
|
|
210
210
|
Author-email: jacob@swarmauri.com
|
|
211
211
|
Requires-Python: >=3.10,<3.15
|
|
@@ -235,17 +235,17 @@ Project-URL: Discord, https://discord.gg/K4YTAPapjR
|
|
|
235
235
|
Project-URL: Homepage, https://github.com/tigrbl/tigrbl
|
|
236
236
|
Project-URL: Issues, https://github.com/tigrbl/tigrbl/issues
|
|
237
237
|
Project-URL: Organization, https://github.com/tigrbl
|
|
238
|
-
Project-URL: Repository, https://github.com/tigrbl/tigrbl/tree/master/pkgs/
|
|
238
|
+
Project-URL: Repository, https://github.com/tigrbl/tigrbl/tree/master/pkgs/50_runtime/tigrbl_runtime
|
|
239
239
|
Description-Content-Type: text/markdown
|
|
240
240
|
|
|
241
241
|
<div align="center">
|
|
242
242
|
<h1>tigrbl-runtime</h1>
|
|
243
243
|
<img src="https://raw.githubusercontent.com/swarmauri/swarmauri-sdk/master/assets/tigrbl_full_logo.png" alt="Tigrbl logo" width="140"/>
|
|
244
|
-
<p><strong>
|
|
244
|
+
<p><strong>Execution bridge for compiled Tigrbl kernel plans and narrow runtime context/carrier compatibility.</strong></p>
|
|
245
245
|
<a href="https://pypi.org/project/tigrbl-runtime/"><img src="https://img.shields.io/pypi/v/tigrbl-runtime?label=PyPI" alt="PyPI version for tigrbl-runtime"/></a>
|
|
246
246
|
<a href="https://pypi.org/project/tigrbl-runtime/"><img src="https://static.pepy.tech/badge/tigrbl-runtime" alt="Downloads for tigrbl-runtime"/></a>
|
|
247
247
|
<a href="https://discord.gg/K4YTAPapjR"><img src="https://img.shields.io/badge/Discord-Join%20chat-5865F2?logo=discord&logoColor=white" alt="Discord community for tigrbl-runtime"/></a>
|
|
248
|
-
<a href="https://github.com/tigrbl/tigrbl/blob/master/pkgs/
|
|
248
|
+
<a href="https://github.com/tigrbl/tigrbl/blob/master/pkgs/50_runtime/tigrbl_runtime/README.md"><img src="https://hits.sh/github.com/tigrbl/tigrbl/blob/master/pkgs/50_runtime/tigrbl_runtime/README.md.svg?label=hits" alt="Repository hits for tigrbl-runtime README"/></a>
|
|
249
249
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-525252" alt="Apache 2.0 license"/></a>
|
|
250
250
|
<a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-3776ab" alt="Python versions 3.10 | 3.11 | 3.12 | 3.13 | 3.14 for tigrbl-runtime"/></a>
|
|
251
251
|
<a href="https://github.com/tigrbl/tigrbl/blob/master/docs/README.md"><img src="https://img.shields.io/badge/workspace-core-1f6feb" alt="Workspace group for tigrbl-runtime"/></a>
|
|
@@ -253,7 +253,7 @@ Description-Content-Type: text/markdown
|
|
|
253
253
|
|
|
254
254
|
## What is tigrbl-runtime?
|
|
255
255
|
|
|
256
|
-
|
|
256
|
+
`tigrbl-runtime` executes compiled Tigrbl kernel plans and preserves the narrow runtime context/carrier bridge needed to run those plans. Route selection, protocol fallback policy, response shaping, transport envelopes, and operation semantics are owned by kernel, atoms, and ops packages.
|
|
257
257
|
|
|
258
258
|
## Why use tigrbl-runtime?
|
|
259
259
|
|
|
@@ -269,7 +269,7 @@ Framework maintainers, extension authors, and advanced users composing Tigrbl fr
|
|
|
269
269
|
|
|
270
270
|
## Where does tigrbl-runtime fit?
|
|
271
271
|
|
|
272
|
-
`tigrbl-runtime` lives at `pkgs/
|
|
272
|
+
`tigrbl-runtime` lives at `pkgs/50_runtime/tigrbl_runtime` and serves a focused layer in the split Tigrbl framework.
|
|
273
273
|
|
|
274
274
|
## How does tigrbl-runtime work?
|
|
275
275
|
|
|
@@ -291,7 +291,7 @@ pip install tigrbl-runtime
|
|
|
291
291
|
| Surface | Value |
|
|
292
292
|
|---|---|
|
|
293
293
|
| PyPI package | [`tigrbl-runtime`](https://pypi.org/project/tigrbl-runtime/) |
|
|
294
|
-
| Repository path | [`pkgs/
|
|
294
|
+
| Repository path | [`pkgs/50_runtime/tigrbl_runtime`](https://github.com/tigrbl/tigrbl/tree/master/pkgs/50_runtime/tigrbl_runtime) |
|
|
295
295
|
| Python import root | `tigrbl_runtime` |
|
|
296
296
|
| Console scripts | none declared |
|
|
297
297
|
| Entry points | none declared |
|
|
@@ -301,17 +301,18 @@ pip install tigrbl-runtime
|
|
|
301
301
|
|
|
302
302
|
## What It Owns
|
|
303
303
|
|
|
304
|
-
`tigrbl-runtime` owns the
|
|
304
|
+
`tigrbl-runtime` owns the compiled-plan execution boundary. It should be installed when you need the narrow bridge that runs already-planned Tigrbl work without assuming the full facade is present.
|
|
305
305
|
|
|
306
306
|
Implementation orientation:
|
|
307
|
-
- `tigrbl_runtime`:
|
|
307
|
+
- `tigrbl_runtime`: compiled plan execution, runtime context compatibility, and declared carrier lifecycle bridges
|
|
308
308
|
|
|
309
309
|
Runtime authoring BCP:
|
|
310
|
-
- Do use this package for
|
|
311
|
-
- Do keep
|
|
310
|
+
- Do use this package for executing compiled kernel plans and maintaining runtime context/carrier compatibility.
|
|
311
|
+
- Do keep execution aligned with compiled plans.
|
|
312
|
+
- Do not add route matching semantics, protocol fallback policy, JSON-RPC/REST envelope policy, response rendering, chunk emission semantics, operation behavior, or new executor families.
|
|
312
313
|
- Do not make application route handlers, FastAPI/Starlette objects, direct SQLAlchemy session calls, or ad-hoc engine construction the runtime contract.
|
|
313
314
|
- Do not bypass kernel plans or lifecycle phases when adding REST, JSON-RPC, stream, SSE, WebSocket, or WebTransport behavior.
|
|
314
|
-
- Avoid hiding behavior in
|
|
315
|
+
- Avoid hiding behavior in runtime wrappers that diagnostics and compiled plans cannot inspect.
|
|
315
316
|
|
|
316
317
|
## Public API and Import Surface
|
|
317
318
|
|
|
@@ -386,7 +387,7 @@ Choose `tigrbl-runtime` when the quick-answer table matches your use case. Choos
|
|
|
386
387
|
|
|
387
388
|
- Community: [Discord](https://discord.gg/K4YTAPapjR).
|
|
388
389
|
- Issues: [GitHub Issues](https://github.com/tigrbl/tigrbl/issues).
|
|
389
|
-
- Repository: [pkgs/
|
|
390
|
+
- Repository: [pkgs/50_runtime/tigrbl_runtime](https://github.com/tigrbl/tigrbl/tree/master/pkgs/50_runtime/tigrbl_runtime).
|
|
390
391
|
|
|
391
392
|
## Package-local Boundary
|
|
392
393
|
|
|
@@ -397,10 +398,14 @@ This README is the package-local distribution entry point for `tigrbl-runtime`.
|
|
|
397
398
|
- Package status: governed package in the `tigrbl/tigrbl` workspace.
|
|
398
399
|
- Governance source: [SSOT registry](https://github.com/tigrbl/tigrbl/blob/master/.ssot/registry.json).
|
|
399
400
|
- Release evidence: [publish workflow](https://github.com/tigrbl/tigrbl/actions/workflows/publish.yml) validates package builds, tests, GitHub release assets, and PyPI publication for managed packages.
|
|
400
|
-
- Local certification guard: `pkgs/
|
|
401
|
+
- Local certification guard: `pkgs/97_tests/tigrbl_tests/tests/unit/test_package_badges_and_notices.py` verifies every package README keeps the Discord badge, Apache 2.0 badge, explicit Python-version badge, `LICENSE`, and `NOTICE`.
|
|
401
402
|
- Scope note: this README documents the package boundary. Runtime feature support remains governed by `.ssot/` entities and the conformance docs linked below.
|
|
402
403
|
|
|
403
404
|
## License
|
|
404
405
|
|
|
405
406
|
Licensed under the Apache License, Version 2.0. See `LICENSE`, `NOTICE`, and the official [Apache 2.0 license text](https://www.apache.org/licenses/LICENSE-2.0).
|
|
406
407
|
|
|
408
|
+
## Lowering integration
|
|
409
|
+
|
|
410
|
+
`lowering_services` lazily exposes canonical kernel operation-view compilation and WebSocket JSON-RPC session construction to concrete integration code. It preserves the kernel function objects and keeps kernel imports out of concrete authoring modules.
|
|
411
|
+
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h1>tigrbl-runtime</h1>
|
|
3
3
|
<img src="https://raw.githubusercontent.com/swarmauri/swarmauri-sdk/master/assets/tigrbl_full_logo.png" alt="Tigrbl logo" width="140"/>
|
|
4
|
-
<p><strong>
|
|
4
|
+
<p><strong>Execution bridge for compiled Tigrbl kernel plans and narrow runtime context/carrier compatibility.</strong></p>
|
|
5
5
|
<a href="https://pypi.org/project/tigrbl-runtime/"><img src="https://img.shields.io/pypi/v/tigrbl-runtime?label=PyPI" alt="PyPI version for tigrbl-runtime"/></a>
|
|
6
6
|
<a href="https://pypi.org/project/tigrbl-runtime/"><img src="https://static.pepy.tech/badge/tigrbl-runtime" alt="Downloads for tigrbl-runtime"/></a>
|
|
7
7
|
<a href="https://discord.gg/K4YTAPapjR"><img src="https://img.shields.io/badge/Discord-Join%20chat-5865F2?logo=discord&logoColor=white" alt="Discord community for tigrbl-runtime"/></a>
|
|
8
|
-
<a href="https://github.com/tigrbl/tigrbl/blob/master/pkgs/
|
|
8
|
+
<a href="https://github.com/tigrbl/tigrbl/blob/master/pkgs/50_runtime/tigrbl_runtime/README.md"><img src="https://hits.sh/github.com/tigrbl/tigrbl/blob/master/pkgs/50_runtime/tigrbl_runtime/README.md.svg?label=hits" alt="Repository hits for tigrbl-runtime README"/></a>
|
|
9
9
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-525252" alt="Apache 2.0 license"/></a>
|
|
10
10
|
<a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-3776ab" alt="Python versions 3.10 | 3.11 | 3.12 | 3.13 | 3.14 for tigrbl-runtime"/></a>
|
|
11
11
|
<a href="https://github.com/tigrbl/tigrbl/blob/master/docs/README.md"><img src="https://img.shields.io/badge/workspace-core-1f6feb" alt="Workspace group for tigrbl-runtime"/></a>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
## What is tigrbl-runtime?
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
`tigrbl-runtime` executes compiled Tigrbl kernel plans and preserves the narrow runtime context/carrier bridge needed to run those plans. Route selection, protocol fallback policy, response shaping, transport envelopes, and operation semantics are owned by kernel, atoms, and ops packages.
|
|
17
17
|
|
|
18
18
|
## Why use tigrbl-runtime?
|
|
19
19
|
|
|
@@ -29,7 +29,7 @@ Framework maintainers, extension authors, and advanced users composing Tigrbl fr
|
|
|
29
29
|
|
|
30
30
|
## Where does tigrbl-runtime fit?
|
|
31
31
|
|
|
32
|
-
`tigrbl-runtime` lives at `pkgs/
|
|
32
|
+
`tigrbl-runtime` lives at `pkgs/50_runtime/tigrbl_runtime` and serves a focused layer in the split Tigrbl framework.
|
|
33
33
|
|
|
34
34
|
## How does tigrbl-runtime work?
|
|
35
35
|
|
|
@@ -51,7 +51,7 @@ pip install tigrbl-runtime
|
|
|
51
51
|
| Surface | Value |
|
|
52
52
|
|---|---|
|
|
53
53
|
| PyPI package | [`tigrbl-runtime`](https://pypi.org/project/tigrbl-runtime/) |
|
|
54
|
-
| Repository path | [`pkgs/
|
|
54
|
+
| Repository path | [`pkgs/50_runtime/tigrbl_runtime`](https://github.com/tigrbl/tigrbl/tree/master/pkgs/50_runtime/tigrbl_runtime) |
|
|
55
55
|
| Python import root | `tigrbl_runtime` |
|
|
56
56
|
| Console scripts | none declared |
|
|
57
57
|
| Entry points | none declared |
|
|
@@ -61,17 +61,18 @@ pip install tigrbl-runtime
|
|
|
61
61
|
|
|
62
62
|
## What It Owns
|
|
63
63
|
|
|
64
|
-
`tigrbl-runtime` owns the
|
|
64
|
+
`tigrbl-runtime` owns the compiled-plan execution boundary. It should be installed when you need the narrow bridge that runs already-planned Tigrbl work without assuming the full facade is present.
|
|
65
65
|
|
|
66
66
|
Implementation orientation:
|
|
67
|
-
- `tigrbl_runtime`:
|
|
67
|
+
- `tigrbl_runtime`: compiled plan execution, runtime context compatibility, and declared carrier lifecycle bridges
|
|
68
68
|
|
|
69
69
|
Runtime authoring BCP:
|
|
70
|
-
- Do use this package for
|
|
71
|
-
- Do keep
|
|
70
|
+
- Do use this package for executing compiled kernel plans and maintaining runtime context/carrier compatibility.
|
|
71
|
+
- Do keep execution aligned with compiled plans.
|
|
72
|
+
- Do not add route matching semantics, protocol fallback policy, JSON-RPC/REST envelope policy, response rendering, chunk emission semantics, operation behavior, or new executor families.
|
|
72
73
|
- Do not make application route handlers, FastAPI/Starlette objects, direct SQLAlchemy session calls, or ad-hoc engine construction the runtime contract.
|
|
73
74
|
- Do not bypass kernel plans or lifecycle phases when adding REST, JSON-RPC, stream, SSE, WebSocket, or WebTransport behavior.
|
|
74
|
-
- Avoid hiding behavior in
|
|
75
|
+
- Avoid hiding behavior in runtime wrappers that diagnostics and compiled plans cannot inspect.
|
|
75
76
|
|
|
76
77
|
## Public API and Import Surface
|
|
77
78
|
|
|
@@ -146,7 +147,7 @@ Choose `tigrbl-runtime` when the quick-answer table matches your use case. Choos
|
|
|
146
147
|
|
|
147
148
|
- Community: [Discord](https://discord.gg/K4YTAPapjR).
|
|
148
149
|
- Issues: [GitHub Issues](https://github.com/tigrbl/tigrbl/issues).
|
|
149
|
-
- Repository: [pkgs/
|
|
150
|
+
- Repository: [pkgs/50_runtime/tigrbl_runtime](https://github.com/tigrbl/tigrbl/tree/master/pkgs/50_runtime/tigrbl_runtime).
|
|
150
151
|
|
|
151
152
|
## Package-local Boundary
|
|
152
153
|
|
|
@@ -157,9 +158,13 @@ This README is the package-local distribution entry point for `tigrbl-runtime`.
|
|
|
157
158
|
- Package status: governed package in the `tigrbl/tigrbl` workspace.
|
|
158
159
|
- Governance source: [SSOT registry](https://github.com/tigrbl/tigrbl/blob/master/.ssot/registry.json).
|
|
159
160
|
- Release evidence: [publish workflow](https://github.com/tigrbl/tigrbl/actions/workflows/publish.yml) validates package builds, tests, GitHub release assets, and PyPI publication for managed packages.
|
|
160
|
-
- Local certification guard: `pkgs/
|
|
161
|
+
- Local certification guard: `pkgs/97_tests/tigrbl_tests/tests/unit/test_package_badges_and_notices.py` verifies every package README keeps the Discord badge, Apache 2.0 badge, explicit Python-version badge, `LICENSE`, and `NOTICE`.
|
|
161
162
|
- Scope note: this README documents the package boundary. Runtime feature support remains governed by `.ssot/` entities and the conformance docs linked below.
|
|
162
163
|
|
|
163
164
|
## License
|
|
164
165
|
|
|
165
166
|
Licensed under the Apache License, Version 2.0. See `LICENSE`, `NOTICE`, and the official [Apache 2.0 license text](https://www.apache.org/licenses/LICENSE-2.0).
|
|
167
|
+
|
|
168
|
+
## Lowering integration
|
|
169
|
+
|
|
170
|
+
`lowering_services` lazily exposes canonical kernel operation-view compilation and WebSocket JSON-RPC session construction to concrete integration code. It preserves the kernel function objects and keeps kernel imports out of concrete authoring modules.
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tigrbl-runtime"
|
|
3
|
-
version = "0.4.5.
|
|
4
|
-
description = "
|
|
3
|
+
version = "0.4.5.dev6"
|
|
4
|
+
description = "Execution bridge for compiled Tigrbl kernel plans and narrow runtime context/carrier compatibility."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { file = "LICENSE" }
|
|
7
7
|
keywords = [
|
|
8
8
|
"tigrbl",
|
|
9
9
|
"asgi",
|
|
10
10
|
"api",
|
|
11
|
-
"json-rpc",
|
|
12
|
-
"rest",
|
|
13
11
|
"sqlalchemy",
|
|
14
12
|
"pydantic",
|
|
15
13
|
"runtime",
|
|
16
14
|
"pipeline",
|
|
17
15
|
"bridge",
|
|
18
|
-
"openapi",
|
|
19
|
-
"openrpc",
|
|
20
16
|
"schema-first",
|
|
21
17
|
]
|
|
22
18
|
classifiers = [
|
|
@@ -53,7 +49,7 @@ dependencies = [
|
|
|
53
49
|
Organization = "https://github.com/tigrbl"
|
|
54
50
|
Discord = "https://discord.gg/K4YTAPapjR"
|
|
55
51
|
Homepage = "https://github.com/tigrbl/tigrbl"
|
|
56
|
-
Repository = "https://github.com/tigrbl/tigrbl/tree/master/pkgs/
|
|
52
|
+
Repository = "https://github.com/tigrbl/tigrbl/tree/master/pkgs/50_runtime/tigrbl_runtime"
|
|
57
53
|
Issues = "https://github.com/tigrbl/tigrbl/issues"
|
|
58
54
|
|
|
59
55
|
[tool.uv.sources]
|
|
@@ -77,4 +73,5 @@ dev = [
|
|
|
77
73
|
"pytest>=8.0",
|
|
78
74
|
"pytest-asyncio>=0.23",
|
|
79
75
|
"ruff>=0.9",
|
|
76
|
+
"tomli>=2.0; python_version < '3.11'",
|
|
80
77
|
]
|
{tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_jsonrpc.py
RENAMED
|
@@ -36,3 +36,14 @@ def _resolve_jsonrpc_endpoint(ctx: Any, channel: OpChannel) -> str | None:
|
|
|
36
36
|
if path == _normalize_path(mapped_path):
|
|
37
37
|
return endpoint
|
|
38
38
|
return None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
_NO_ERROR_DATA = object()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _jsonrpc_error_payload(code: int, message: str, request_id: Any, *, data: Any = _NO_ERROR_DATA) -> dict[str, Any]:
|
|
45
|
+
"""Construct the existing compatibility error envelope without choosing policy."""
|
|
46
|
+
error: dict[str, Any] = {"code": code, "message": message}
|
|
47
|
+
if data is not _NO_ERROR_DATA:
|
|
48
|
+
error["data"] = data
|
|
49
|
+
return {"jsonrpc": "2.0", "error": error, "id": request_id}
|
{tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_send.py
RENAMED
|
@@ -19,6 +19,52 @@ from ._asgi_webtransport import (
|
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
def _webtransport_event_projection(ctx: Any) -> Mapping[str, Any]:
|
|
23
|
+
projection = ctx.get("channel_event_projection")
|
|
24
|
+
if isinstance(projection, Mapping):
|
|
25
|
+
return projection
|
|
26
|
+
channel = ctx.get("channel")
|
|
27
|
+
state = getattr(channel, "state", None) if channel is not None else None
|
|
28
|
+
if isinstance(state, dict):
|
|
29
|
+
projection = state.get("event_projection")
|
|
30
|
+
if isinstance(projection, Mapping):
|
|
31
|
+
return projection
|
|
32
|
+
return {}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _is_receive_only_webtransport_stream(ctx: Any) -> bool:
|
|
36
|
+
projection = _webtransport_event_projection(ctx)
|
|
37
|
+
if (
|
|
38
|
+
projection.get("lane") == "unidi_client_stream"
|
|
39
|
+
or projection.get("exchange") == "client_stream"
|
|
40
|
+
):
|
|
41
|
+
return True
|
|
42
|
+
message = ctx.get("channel_message")
|
|
43
|
+
return bool(
|
|
44
|
+
isinstance(message, Mapping)
|
|
45
|
+
and message.get("type") == "webtransport.stream.receive"
|
|
46
|
+
and message.get("stream_direction") == "client_to_server"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _validate_receive_only_webtransport_output(payload: Any) -> None:
|
|
51
|
+
if payload is None:
|
|
52
|
+
return
|
|
53
|
+
if not isinstance(payload, Mapping) or not any(
|
|
54
|
+
key in payload
|
|
55
|
+
for key in ("bidirectional_streams", "unidirectional_streams", "datagrams")
|
|
56
|
+
):
|
|
57
|
+
raise ValueError(
|
|
58
|
+
"cannot automatically reply on a client_to_server WebTransport stream; "
|
|
59
|
+
"return None or emit an explicit server_to_client stream or datagram"
|
|
60
|
+
)
|
|
61
|
+
if payload.get("bidirectional_streams"):
|
|
62
|
+
raise ValueError(
|
|
63
|
+
"bidirectional_streams output is invalid for a client_to_server "
|
|
64
|
+
"WebTransport stream; use unidirectional_streams or datagrams"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
22
68
|
async def _send_session_payload(
|
|
23
69
|
env: Any,
|
|
24
70
|
payload: Any,
|
|
@@ -87,11 +133,15 @@ async def _send_webtransport_payload(env: Any, ctx: Any, payload: Any) -> None:
|
|
|
87
133
|
for key in ("bidirectional_streams", "unidirectional_streams", "datagrams")
|
|
88
134
|
)
|
|
89
135
|
if structured_payload:
|
|
90
|
-
if
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
136
|
+
if (
|
|
137
|
+
message_type
|
|
138
|
+
in {
|
|
139
|
+
"webtransport.stream.receive",
|
|
140
|
+
"webtransport.datagram.receive",
|
|
141
|
+
}
|
|
142
|
+
and message not in queue
|
|
143
|
+
):
|
|
144
|
+
queue.append(message)
|
|
95
145
|
if not queue:
|
|
96
146
|
raise ValueError(
|
|
97
147
|
"structured WebTransport payloads require inbound stream.receive or datagram.receive events"
|
|
@@ -125,6 +175,12 @@ async def _send_webtransport_payload(env: Any, ctx: Any, payload: Any) -> None:
|
|
|
125
175
|
)
|
|
126
176
|
if payload is not None:
|
|
127
177
|
base = {**message, "session_id": session_id}
|
|
178
|
+
temp = getattr(ctx, "temp", None)
|
|
179
|
+
dispatch = temp.get("dispatch") if isinstance(temp, Mapping) else None
|
|
180
|
+
if isinstance(dispatch, Mapping):
|
|
181
|
+
request = dispatch.get("rpc") or dispatch.get("rpc_envelope")
|
|
182
|
+
if isinstance(request, Mapping) and request.get("id") is not None:
|
|
183
|
+
base["jsonrpc_request_id"] = request.get("id")
|
|
128
184
|
if structured_payload:
|
|
129
185
|
for event in _webtransport_structured_payload_events(
|
|
130
186
|
session_id=session_id,
|
|
@@ -151,6 +207,14 @@ async def _send_webtransport_payload(env: Any, ctx: Any, payload: Any) -> None:
|
|
|
151
207
|
)
|
|
152
208
|
await _run_webtransport_hooks(env, ctx, direction="send", message=event)
|
|
153
209
|
await send(event)
|
|
210
|
+
if isinstance(state, dict):
|
|
211
|
+
raw_queue = state.get("receive_queue")
|
|
212
|
+
consumed = min(len(queue), len(raw_queue or ()))
|
|
213
|
+
if isinstance(raw_queue, deque):
|
|
214
|
+
for _ in range(consumed):
|
|
215
|
+
raw_queue.popleft()
|
|
216
|
+
elif isinstance(raw_queue, list):
|
|
217
|
+
del raw_queue[:consumed]
|
|
154
218
|
else:
|
|
155
219
|
event = _webtransport_payload_event(base=base, payload=payload)
|
|
156
220
|
if isinstance(session, WebTransportSessionState):
|
|
@@ -222,6 +286,16 @@ async def send_transport_via_channel(env: Any, ctx: Any) -> None:
|
|
|
222
286
|
if payload is None:
|
|
223
287
|
payload = getattr(ctx, "result", None)
|
|
224
288
|
if scope_type == "webtransport":
|
|
289
|
+
if _is_receive_only_webtransport_stream(ctx):
|
|
290
|
+
_validate_receive_only_webtransport_output(payload)
|
|
291
|
+
if payload is None:
|
|
292
|
+
if isinstance(state, dict):
|
|
293
|
+
state["egress_disposition"] = "suppressed_receive_only"
|
|
294
|
+
state["emitted"] = False
|
|
295
|
+
if isinstance(egress, dict):
|
|
296
|
+
egress["response_suppressed"] = True
|
|
297
|
+
egress["suppression_reason"] = "receive_only_stream"
|
|
298
|
+
return
|
|
225
299
|
await _send_webtransport_payload(env, ctx, payload)
|
|
226
300
|
else:
|
|
227
301
|
await _send_session_payload(
|
{tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/channel/_asgi_webtransport.py
RENAMED
|
@@ -15,9 +15,12 @@ from tigrbl_kernel.channel_taxonomy import (
|
|
|
15
15
|
webtransport_event_metadata as _webtransport_event_metadata,
|
|
16
16
|
)
|
|
17
17
|
from tigrbl_kernel.webtransport_events import validate_webtransport_event_payload
|
|
18
|
+
from tigrbl_kernel.webtransport_session_plan import WebTransportSessionPlan
|
|
18
19
|
from tigrbl_atoms.runtime_channel import WebTransportSessionState
|
|
19
20
|
from tigrbl_typing.channel import OpChannel
|
|
20
21
|
|
|
22
|
+
MAX_EAGER_DRAIN_EVENTS = 16
|
|
23
|
+
|
|
21
24
|
|
|
22
25
|
def _webtransport_scope_state(env: Any) -> dict[str, Any]:
|
|
23
26
|
scope = getattr(env, "scope", {}) or {}
|
|
@@ -242,6 +245,20 @@ async def _receive_webtransport_session_messages(
|
|
|
242
245
|
queue: deque[Mapping[str, Any]] = deque()
|
|
243
246
|
session: WebTransportSessionState | None = None
|
|
244
247
|
|
|
248
|
+
session_plan = shared_state.get("session_plan")
|
|
249
|
+
if not isinstance(session_plan, WebTransportSessionPlan):
|
|
250
|
+
session_plan = WebTransportSessionPlan()
|
|
251
|
+
shared_state["session_plan"] = session_plan
|
|
252
|
+
|
|
253
|
+
async def _receive_record_or_event() -> Mapping[str, Any]:
|
|
254
|
+
if session_plan.has_pending():
|
|
255
|
+
return session_plan.pop_pending()
|
|
256
|
+
while True:
|
|
257
|
+
raw = _enrich_webtransport_message(env, await receive())
|
|
258
|
+
session_plan.project_receive(raw)
|
|
259
|
+
if session_plan.has_pending():
|
|
260
|
+
return session_plan.pop_pending()
|
|
261
|
+
|
|
245
262
|
def _ensure_session(message: Mapping[str, Any]) -> WebTransportSessionState | None:
|
|
246
263
|
nonlocal session
|
|
247
264
|
session_id = message.get("session_id") or _webtransport_scope_session_id(env)
|
|
@@ -292,6 +309,8 @@ async def _receive_webtransport_session_messages(
|
|
|
292
309
|
channel="receive",
|
|
293
310
|
payload={**message, "session_id": state.get("session_id")},
|
|
294
311
|
)
|
|
312
|
+
state["event_projection"] = dict(projection)
|
|
313
|
+
ctx["channel_event_projection"] = dict(projection)
|
|
295
314
|
if current_session is not None:
|
|
296
315
|
current_session.apply_event(
|
|
297
316
|
event=message_type,
|
|
@@ -334,18 +353,26 @@ async def _receive_webtransport_session_messages(
|
|
|
334
353
|
return
|
|
335
354
|
ctx["channel_message"] = message
|
|
336
355
|
|
|
337
|
-
message = await
|
|
356
|
+
message = await _receive_record_or_event()
|
|
338
357
|
await _record_payload_message(message)
|
|
339
358
|
if message.get("type") == "webtransport.connect":
|
|
340
359
|
if "channel_message" not in ctx:
|
|
341
|
-
message = await
|
|
360
|
+
message = await _receive_record_or_event()
|
|
342
361
|
await _record_payload_message(message)
|
|
343
362
|
|
|
344
|
-
|
|
363
|
+
drained_events = 0
|
|
364
|
+
while (
|
|
365
|
+
shared_state.get("eager_drain") is True
|
|
366
|
+
and not state.get("disconnected")
|
|
367
|
+
and drained_events < MAX_EAGER_DRAIN_EVENTS
|
|
368
|
+
):
|
|
345
369
|
try:
|
|
346
|
-
message = await asyncio.wait_for(
|
|
370
|
+
message = await asyncio.wait_for(
|
|
371
|
+
_receive_record_or_event(), timeout=0.001
|
|
372
|
+
)
|
|
347
373
|
except TimeoutError:
|
|
348
374
|
break
|
|
349
375
|
await _record_payload_message(message)
|
|
376
|
+
drained_events += 1
|
|
350
377
|
|
|
351
378
|
state["receive_queue"] = queue
|
{tigrbl_runtime-0.4.5.dev1 → tigrbl_runtime-0.4.5.dev6}/tigrbl_runtime/executors/ctx/context.py
RENAMED
|
@@ -16,11 +16,7 @@ from typing import (
|
|
|
16
16
|
runtime_checkable,
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
from sqlalchemy.ext.asyncio import AsyncSession
|
|
21
|
-
from sqlalchemy.orm import Session
|
|
22
|
-
except Exception: # pragma: no cover - optional ORM dependency for runtime typing
|
|
23
|
-
AsyncSession = Session = Any # type: ignore[assignment]
|
|
19
|
+
AsyncSession = Session = Any # type: ignore[assignment]
|
|
24
20
|
|
|
25
21
|
from tigrbl_atoms.types import BaseCtx
|
|
26
22
|
from tigrbl_base._base import AttrDict
|