iagent-mesh 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iagent_mesh-0.4.0/.gitignore +10 -0
- iagent_mesh-0.4.0/LICENSE +21 -0
- iagent_mesh-0.4.0/PKG-INFO +84 -0
- iagent_mesh-0.4.0/README.md +45 -0
- iagent_mesh-0.4.0/app.py +99 -0
- iagent_mesh-0.4.0/docs/HANDOFF-meshtool-execute.md +238 -0
- iagent_mesh-0.4.0/docs/architecture_manifesto.md +162 -0
- iagent_mesh-0.4.0/docs/jupyter_guide.md +255 -0
- iagent_mesh-0.4.0/docs/outbound/README.md +56 -0
- iagent_mesh-0.4.0/docs/outbound/sdk-blocking-sync-handlers.patch +81 -0
- iagent_mesh-0.4.0/docs/outbound/sdk-discards-caller-identity.patch +107 -0
- iagent_mesh-0.4.0/iagent_mesh/__init__.py +27 -0
- iagent_mesh-0.4.0/iagent_mesh/client.py +189 -0
- iagent_mesh-0.4.0/iagent_mesh/config.py +62 -0
- iagent_mesh-0.4.0/iagent_mesh/core.py +618 -0
- iagent_mesh-0.4.0/iagent_mesh/identity_stanzas.py +77 -0
- iagent_mesh-0.4.0/iagent_mesh/models.py +16 -0
- iagent_mesh-0.4.0/iagent_mesh/registration_transport.py +145 -0
- iagent_mesh-0.4.0/iagent_mesh/scaffold_core.py +150 -0
- iagent_mesh-0.4.0/iagent_mesh/service_identity.py +95 -0
- iagent_mesh-0.4.0/iagent_mesh/shapes.py +163 -0
- iagent_mesh-0.4.0/iagent_mesh/transport_auth.py +492 -0
- iagent_mesh-0.4.0/mcp_server/__init__.py +1 -0
- iagent_mesh-0.4.0/mcp_server/server.py +71 -0
- iagent_mesh-0.4.0/pyproject.toml +89 -0
- iagent_mesh-0.4.0/pytest.ini +2 -0
- iagent_mesh-0.4.0/templates/01_pure_math/app.py +42 -0
- iagent_mesh-0.4.0/templates/01_pure_math/pyproject.toml +9 -0
- iagent_mesh-0.4.0/templates/01_pure_math/template.yaml +2 -0
- iagent_mesh-0.4.0/templates/02_instructor_polars/app.py +61 -0
- iagent_mesh-0.4.0/templates/02_instructor_polars/prompts/instructions.yaml +2 -0
- iagent_mesh-0.4.0/templates/02_instructor_polars/pyproject.toml +13 -0
- iagent_mesh-0.4.0/templates/02_instructor_polars/template.yaml +2 -0
- iagent_mesh-0.4.0/templates/03_baml_pandas/app.py +49 -0
- iagent_mesh-0.4.0/templates/03_baml_pandas/baml_src/schema.baml +11 -0
- iagent_mesh-0.4.0/templates/03_baml_pandas/pyproject.toml +12 -0
- iagent_mesh-0.4.0/templates/03_baml_pandas/template.yaml +2 -0
- iagent_mesh-0.4.0/templates/legacy_adapter/app.py +70 -0
- iagent_mesh-0.4.0/templates/legacy_adapter/pyproject.toml +15 -0
- iagent_mesh-0.4.0/templates/smolagents_subswarm/app.py +60 -0
- iagent_mesh-0.4.0/templates/smolagents_subswarm/pyproject.toml +14 -0
- iagent_mesh-0.4.0/tests/__init__.py +1 -0
- iagent_mesh-0.4.0/tests/conftest.py +22 -0
- iagent_mesh-0.4.0/tests/test_app.py +117 -0
- iagent_mesh-0.4.0/tests/test_caller_identity_reaches_handler.py +239 -0
- iagent_mesh-0.4.0/tests/test_client.py +169 -0
- iagent_mesh-0.4.0/tests/test_consumer_contracts_invincible_agent.py +118 -0
- iagent_mesh-0.4.0/tests/test_core.py +500 -0
- iagent_mesh-0.4.0/tests/test_cortex_data_client_contract.py +113 -0
- iagent_mesh-0.4.0/tests/test_disclosure_policy.py +177 -0
- iagent_mesh-0.4.0/tests/test_docs_disabled.py +75 -0
- iagent_mesh-0.4.0/tests/test_gauge_visibility.py +229 -0
- iagent_mesh-0.4.0/tests/test_mcp_server.py +156 -0
- iagent_mesh-0.4.0/tests/test_models.py +61 -0
- iagent_mesh-0.4.0/tests/test_packaging.py +119 -0
- iagent_mesh-0.4.0/tests/test_per_user_read_end_to_end.py +164 -0
- iagent_mesh-0.4.0/tests/test_postponed_annotations.py +110 -0
- iagent_mesh-0.4.0/tests/test_probe_path_exemption.py +146 -0
- iagent_mesh-0.4.0/tests/test_registration_consumer_is_bound.py +117 -0
- iagent_mesh-0.4.0/tests/test_registration_transport.py +116 -0
- iagent_mesh-0.4.0/tests/test_scaffold_core.py +121 -0
- iagent_mesh-0.4.0/tests/test_scoping_posture_is_declared.py +181 -0
- iagent_mesh-0.4.0/tests/test_sync_handlers_do_not_block.py +195 -0
- iagent_mesh-0.4.0/tests/test_templates.py +97 -0
- iagent_mesh-0.4.0/tests/test_transport_auth.py +171 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Edgy Solutions
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software χωρίς restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: iagent_mesh
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Universal contracts and infrastructure wrapper for the iagent Mesh — typed predicate registration, transport auth, and per-caller identity for mesh tools
|
|
5
|
+
Project-URL: Homepage, https://github.com/edgy-solutions/iagent-mesh-sdk
|
|
6
|
+
Project-URL: Repository, https://github.com/edgy-solutions/iagent-mesh-sdk
|
|
7
|
+
Project-URL: Issues, https://github.com/edgy-solutions/iagent-mesh-sdk/issues
|
|
8
|
+
Author-email: Chris Nogradi <cnogradi@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,ai-mesh,datahub,fastapi,knowledge-graph,predicate-graph,topaz
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Framework :: FastAPI
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: acryl-datahub>=0.13.0
|
|
24
|
+
Requires-Dist: fastapi>=0.100.0
|
|
25
|
+
Requires-Dist: httpx>=0.24.0
|
|
26
|
+
Requires-Dist: mcp<2,>=1.0.0
|
|
27
|
+
Requires-Dist: nest-asyncio>=1.5.0
|
|
28
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
29
|
+
Requires-Dist: pydantic>=2.0.0
|
|
30
|
+
Requires-Dist: pyjwt>=2.0.0
|
|
31
|
+
Requires-Dist: pyyaml>=6.0
|
|
32
|
+
Requires-Dist: uvicorn>=0.23.0
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: httpx; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-mock; extra == 'dev'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# iagent-mesh-sdk (DevEx Hub)
|
|
41
|
+
|
|
42
|
+
This repository serves as the Data-Driven Developer Experience (DevEx) Hub and provides the `iagent_mesh` SDK core library, which includes universal contracts and an infrastructure wrapper for the iagent Mesh platform.
|
|
43
|
+
|
|
44
|
+
> 📖 **Architectural Guide:** Read [Launch Domain Nodes, Not Scripts](docs/architecture_manifesto.md) to understand why this framework is required for enterprise AI deployments.
|
|
45
|
+
|
|
46
|
+
## Architecture & Features
|
|
47
|
+
|
|
48
|
+
This Hub leverages the **Inception Pattern** to dynamically scaffold new agent tools.
|
|
49
|
+
|
|
50
|
+
- **`iagent_mesh` Core Library**: Contains `MeshTool` for routing, FastAPI execution, and Topaz Zero-Trust security.
|
|
51
|
+
- **Templates**: Standardized data scientist environments (Pure Math, Instructor + Polars, BAML + Pandas).
|
|
52
|
+
- **Interactive Scaffolding**: Use `scripts/scaffold.sh` to locally generate a new agent from a template.
|
|
53
|
+
- **MCP Server**: The `mcp_server/server.py` exposes tools (`scaffold_local_workspace`, `publish_local_to_mesh`) for intelligent IDE-based agent creation.
|
|
54
|
+
- **Cloud Endpoints**: `app.py` exposes REST APIs (`scaffold_generator`, `mesh_publisher`) for the central orchestrator to provision workspaces dynamically.
|
|
55
|
+
|
|
56
|
+
## Environment Configuration
|
|
57
|
+
|
|
58
|
+
This SDK relies on centralized environment variables for all integrations to ensure no hardcoded enterprise strings are checked in. See the `.env.example` file in the root directory for a full list.
|
|
59
|
+
|
|
60
|
+
**Required URLs:**
|
|
61
|
+
- `GIT_PROVISION_API_URL`: The platform provisioning API for repositories.
|
|
62
|
+
- `GIT_SERVER_HOST`: The core Git server hostname.
|
|
63
|
+
- `ARTIFACTORY_BASE_URL`: The enterprise artifact repository.
|
|
64
|
+
|
|
65
|
+
**Optional URLs / tokens (only needed if `MESH_REGISTER_ON_STARTUP=true`):**
|
|
66
|
+
- `DATAHUB_GMS_URL`: The DataHub GMS endpoint the SDK pushes registrations to.
|
|
67
|
+
- `DATAHUB_TOKEN`: Bearer token for the GMS emitter.
|
|
68
|
+
|
|
69
|
+
**Required Tokens (Depending on deployment):**
|
|
70
|
+
- `PLATFORM_GIT_TOKEN`: Used by the cloud pod (`app.py`) for live git publishing.
|
|
71
|
+
- `MESH_DEV_TOKEN`: Used by the local `mcp_server` to authenticate against provisioning APIs.
|
|
72
|
+
|
|
73
|
+
## Installation & Testing
|
|
74
|
+
|
|
75
|
+
Data scientists can install the core SDK via:
|
|
76
|
+
```bash
|
|
77
|
+
uv pip install git+https://[your-repo-url]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
To run the robust regression testing suite:
|
|
81
|
+
```bash
|
|
82
|
+
uv pip install -e ".[dev]"
|
|
83
|
+
python -m pytest
|
|
84
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# iagent-mesh-sdk (DevEx Hub)
|
|
2
|
+
|
|
3
|
+
This repository serves as the Data-Driven Developer Experience (DevEx) Hub and provides the `iagent_mesh` SDK core library, which includes universal contracts and an infrastructure wrapper for the iagent Mesh platform.
|
|
4
|
+
|
|
5
|
+
> 📖 **Architectural Guide:** Read [Launch Domain Nodes, Not Scripts](docs/architecture_manifesto.md) to understand why this framework is required for enterprise AI deployments.
|
|
6
|
+
|
|
7
|
+
## Architecture & Features
|
|
8
|
+
|
|
9
|
+
This Hub leverages the **Inception Pattern** to dynamically scaffold new agent tools.
|
|
10
|
+
|
|
11
|
+
- **`iagent_mesh` Core Library**: Contains `MeshTool` for routing, FastAPI execution, and Topaz Zero-Trust security.
|
|
12
|
+
- **Templates**: Standardized data scientist environments (Pure Math, Instructor + Polars, BAML + Pandas).
|
|
13
|
+
- **Interactive Scaffolding**: Use `scripts/scaffold.sh` to locally generate a new agent from a template.
|
|
14
|
+
- **MCP Server**: The `mcp_server/server.py` exposes tools (`scaffold_local_workspace`, `publish_local_to_mesh`) for intelligent IDE-based agent creation.
|
|
15
|
+
- **Cloud Endpoints**: `app.py` exposes REST APIs (`scaffold_generator`, `mesh_publisher`) for the central orchestrator to provision workspaces dynamically.
|
|
16
|
+
|
|
17
|
+
## Environment Configuration
|
|
18
|
+
|
|
19
|
+
This SDK relies on centralized environment variables for all integrations to ensure no hardcoded enterprise strings are checked in. See the `.env.example` file in the root directory for a full list.
|
|
20
|
+
|
|
21
|
+
**Required URLs:**
|
|
22
|
+
- `GIT_PROVISION_API_URL`: The platform provisioning API for repositories.
|
|
23
|
+
- `GIT_SERVER_HOST`: The core Git server hostname.
|
|
24
|
+
- `ARTIFACTORY_BASE_URL`: The enterprise artifact repository.
|
|
25
|
+
|
|
26
|
+
**Optional URLs / tokens (only needed if `MESH_REGISTER_ON_STARTUP=true`):**
|
|
27
|
+
- `DATAHUB_GMS_URL`: The DataHub GMS endpoint the SDK pushes registrations to.
|
|
28
|
+
- `DATAHUB_TOKEN`: Bearer token for the GMS emitter.
|
|
29
|
+
|
|
30
|
+
**Required Tokens (Depending on deployment):**
|
|
31
|
+
- `PLATFORM_GIT_TOKEN`: Used by the cloud pod (`app.py`) for live git publishing.
|
|
32
|
+
- `MESH_DEV_TOKEN`: Used by the local `mcp_server` to authenticate against provisioning APIs.
|
|
33
|
+
|
|
34
|
+
## Installation & Testing
|
|
35
|
+
|
|
36
|
+
Data scientists can install the core SDK via:
|
|
37
|
+
```bash
|
|
38
|
+
uv pip install git+https://[your-repo-url]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
To run the robust regression testing suite:
|
|
42
|
+
```bash
|
|
43
|
+
uv pip install -e ".[dev]"
|
|
44
|
+
python -m pytest
|
|
45
|
+
```
|
iagent_mesh-0.4.0/app.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import uuid
|
|
3
|
+
import subprocess
|
|
4
|
+
from fastapi import FastAPI
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
from iagent_mesh.models import ToolInput, ToolOutput
|
|
7
|
+
from iagent_mesh.core import MeshTool
|
|
8
|
+
from iagent_mesh.scaffold_core import generate_template_files, publish_workspace_to_git
|
|
9
|
+
from iagent_mesh.config import settings
|
|
10
|
+
|
|
11
|
+
# 1. Define Schemas
|
|
12
|
+
class ScaffoldInput(ToolInput):
|
|
13
|
+
template_id: str = Field(...)
|
|
14
|
+
tool_name: str = Field(...)
|
|
15
|
+
is_mcp: bool = Field(False)
|
|
16
|
+
|
|
17
|
+
class ScaffoldOutput(ToolOutput):
|
|
18
|
+
workspace_uuid: str
|
|
19
|
+
target_path: str
|
|
20
|
+
|
|
21
|
+
class PublishInput(ToolInput):
|
|
22
|
+
workspace_uuid: str = Field(...)
|
|
23
|
+
tool_name: str = Field(...)
|
|
24
|
+
is_mcp: bool = Field(False)
|
|
25
|
+
target_git_group: str = Field(...)
|
|
26
|
+
|
|
27
|
+
class PublishOutput(ToolOutput):
|
|
28
|
+
status: str
|
|
29
|
+
git_url: str
|
|
30
|
+
|
|
31
|
+
# 2. Initialize MeshTools — these are platform tools (the DevEx Hub itself
|
|
32
|
+
# exists only because the mesh exists), so they use the ``mesh:`` namespace
|
|
33
|
+
# per ADR-0005. The predicate edges they create are:
|
|
34
|
+
#
|
|
35
|
+
# (mesh:ScaffoldRequest) --[mesh:scaffoldWorkspace]--> (mesh:ScaffoldedWorkspace)
|
|
36
|
+
# (mesh:PublishRequest) --[mesh:publishWorkspace]--> (mesh:GitDeployment)
|
|
37
|
+
scaffold_tool = MeshTool(
|
|
38
|
+
name="scaffold_generator",
|
|
39
|
+
description="Scaffolds a DevEx template into a fresh workspace directory.",
|
|
40
|
+
verb="mesh:scaffoldWorkspace",
|
|
41
|
+
input_uri="mesh:ScaffoldRequest",
|
|
42
|
+
output_uri="mesh:ScaffoldedWorkspace",
|
|
43
|
+
verb_synonyms=["scaffold", "generate workspace", "create from template"],
|
|
44
|
+
owner_persona="DATA_STEWARD",
|
|
45
|
+
cost_class="fast",
|
|
46
|
+
)
|
|
47
|
+
publish_tool = MeshTool(
|
|
48
|
+
name="mesh_publisher",
|
|
49
|
+
description="Publishes a scaffolded workspace to a managed git remote.",
|
|
50
|
+
verb="mesh:publishWorkspace",
|
|
51
|
+
input_uri="mesh:PublishRequest",
|
|
52
|
+
output_uri="mesh:GitDeployment",
|
|
53
|
+
verb_synonyms=["publish", "push to git", "deploy workspace"],
|
|
54
|
+
owner_persona="DATA_STEWARD",
|
|
55
|
+
cost_class="medium",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# 3. Define Tool Logic
|
|
59
|
+
@scaffold_tool.execute()
|
|
60
|
+
def run_scaffold(data: ScaffoldInput) -> ScaffoldOutput:
|
|
61
|
+
workspace_uuid = str(uuid.uuid4())
|
|
62
|
+
target_path = f"/tmp/{workspace_uuid}"
|
|
63
|
+
|
|
64
|
+
# Enforce standardized URN based on type
|
|
65
|
+
if data.is_mcp:
|
|
66
|
+
tool_urn = f"urn:li:mcpServer:{data.tool_name}"
|
|
67
|
+
else:
|
|
68
|
+
tool_urn = f"urn:li:aitool:{data.tool_name}"
|
|
69
|
+
|
|
70
|
+
generate_template_files(data.template_id, data.tool_name, tool_urn, target_path)
|
|
71
|
+
|
|
72
|
+
return ScaffoldOutput(workspace_uuid=workspace_uuid, target_path=target_path)
|
|
73
|
+
|
|
74
|
+
@publish_tool.execute()
|
|
75
|
+
def run_publish(data: PublishInput) -> PublishOutput:
|
|
76
|
+
target_path = f"/tmp/{data.workspace_uuid}"
|
|
77
|
+
if not os.path.exists(target_path):
|
|
78
|
+
raise ValueError(f"Workspace not found at {target_path}")
|
|
79
|
+
|
|
80
|
+
git_token = settings.require("PLATFORM_GIT_TOKEN")
|
|
81
|
+
git_host = settings.require("GIT_SERVER_HOST")
|
|
82
|
+
git_url = f"https://oauth2:{git_token}@{git_host}/{data.target_git_group}/{data.tool_name}.git"
|
|
83
|
+
|
|
84
|
+
# Use centralized utility
|
|
85
|
+
try:
|
|
86
|
+
publish_workspace_to_git(target_path, git_url)
|
|
87
|
+
except RuntimeError as e:
|
|
88
|
+
raise ValueError(str(e))
|
|
89
|
+
|
|
90
|
+
return PublishOutput(status="Success", git_url=git_url)
|
|
91
|
+
|
|
92
|
+
# 4. Master App
|
|
93
|
+
app = FastAPI(title="DevEx Hub Cloud Tools")
|
|
94
|
+
app.mount("/scaffold", scaffold_tool.app)
|
|
95
|
+
app.mount("/publish", publish_tool.app)
|
|
96
|
+
|
|
97
|
+
if __name__ == "__main__":
|
|
98
|
+
import uvicorn
|
|
99
|
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
> ## ✅ RESOLVED in v0.4.0 — both findings, landed together
|
|
2
|
+
>
|
|
3
|
+
> **Disposition: BOTH, in one change to `route_handler`** — the option this packet argued for.
|
|
4
|
+
> They were not landed separately, so the `run_in_executor` composition hazard described below
|
|
5
|
+
> never had a window to occur.
|
|
6
|
+
>
|
|
7
|
+
> * **Finding A** — a parameter annotated `CallerIdentity` (any name) now receives the invoker;
|
|
8
|
+
> `current_caller()` reads the same identity from a request-scoped `ContextVar` where no
|
|
9
|
+
> parameter can be threaded; `require_authz_id()` is the fail-closed read accessor.
|
|
10
|
+
> * **Finding B** — sync handlers run via `anyio.to_thread.run_sync` under an explicit
|
|
11
|
+
> `contextvars.copy_context()`, so the contextvar survives into the worker thread. The
|
|
12
|
+
> quickstart's promise is now true rather than corrected away.
|
|
13
|
+
> * **The silence** — the packet asked that not consuming the identity be *visible*. An
|
|
14
|
+
> undeclared unscoped handler now WARNS at registration; `@app.execute(caller_scoped=False)`
|
|
15
|
+
> records deliberate intent and silences it. All five shipped templates declare a posture.
|
|
16
|
+
>
|
|
17
|
+
> **Both rulings were answered by enumeration, not preference.** The census the packet demanded
|
|
18
|
+
> found ZERO `MeshTool.execute()` handlers in invincible-agent (zero `MeshTool` call sites at
|
|
19
|
+
> all), so the population holding retroactively-broken sync handlers was empty — fix the code,
|
|
20
|
+
> no migration debt.
|
|
21
|
+
>
|
|
22
|
+
> **Version:** ADDITIVE for tool authors — the single-parameter form is unchanged and untouched
|
|
23
|
+
> handlers keep working. Execution *semantics* change for sync handlers (they now run off the
|
|
24
|
+
> event loop), and undeclared handlers gain a startup warning. The `!` on v0.4.0 is for
|
|
25
|
+
> `MeshClient.ask()` and the `requires-python` bump, not for `execute()`.
|
|
26
|
+
>
|
|
27
|
+
> Seals: `tests/test_caller_identity_reaches_handler.py` (incl. an executable root-cause seal
|
|
28
|
+
> pinning that FastAPI discards app-level dependency return values),
|
|
29
|
+
> `tests/test_per_user_read_end_to_end.py` (three-caller discrimination),
|
|
30
|
+
> `tests/test_sync_handlers_do_not_block.py` (incl. `test_THE_COORDINATION_TEST...`),
|
|
31
|
+
> `tests/test_scoping_posture_is_declared.py`. Each was broken on purpose and shown red first.
|
|
32
|
+
>
|
|
33
|
+
> Original packet preserved below.
|
|
34
|
+
|
|
35
|
+
# Handoff — two defects in `MeshTool.execute()`, and why they are one job
|
|
36
|
+
|
|
37
|
+
> ## ✅ RESOLVED in 0.4.0 (2026-08-27)
|
|
38
|
+
>
|
|
39
|
+
> Both findings fixed together, in one change to `route_handler`, as this document required.
|
|
40
|
+
>
|
|
41
|
+
> * **Finding A** — a parameter annotated `CallerIdentity` receives the invoker;
|
|
42
|
+
> `current_caller()` reads the same identity from a request-scoped `ContextVar` with no
|
|
43
|
+
> parameter. `CallerIdentity.require_authz_id()` is the fail-closed read accessor: it raises
|
|
44
|
+
> rather than returning the `None` that silently becomes a service read.
|
|
45
|
+
> * **Finding B** — sync handlers run via `anyio.to_thread.run_sync` under an explicit
|
|
46
|
+
> `contextvars.copy_context()`, so the doc's threading promise is now true *and* A's contextvar
|
|
47
|
+
> survives into the worker thread.
|
|
48
|
+
>
|
|
49
|
+
> **Both rulings were answered by enumeration, not preference.** The handler census the document
|
|
50
|
+
> demanded returned **zero** `MeshTool.execute()` handlers in invincible-agent (and zero
|
|
51
|
+
> `MeshTool` / `MeshClient` call sites at all) — so the population holding retroactively-broken
|
|
52
|
+
> sync handlers was empty, and fixing the code carried no migration debt. Ruling 1 → fix the
|
|
53
|
+
> code. Ruling 2 → the count is zero; the five in-repo templates all use the unchanged
|
|
54
|
+
> single-parameter form.
|
|
55
|
+
>
|
|
56
|
+
> **The interaction this document predicted was reproduced, not assumed.** Implementing B with
|
|
57
|
+
> `loop.run_in_executor` passes every threading test while `current_caller()` reads `None` inside
|
|
58
|
+
> the recommended handler style. That is why the acceptance criterion below is a test named
|
|
59
|
+
> `test_THE_COORDINATION_TEST_...` — it is the only one that fails in that configuration.
|
|
60
|
+
>
|
|
61
|
+
> Tests: `tests/test_caller_identity_reaches_handler.py`,
|
|
62
|
+
> `tests/test_sync_handlers_do_not_block.py`, `tests/test_per_user_read_end_to_end.py`,
|
|
63
|
+
> `tests/test_cortex_data_client_contract.py`. Each fix was broken on purpose, shown red for its
|
|
64
|
+
> own reason, and restored.
|
|
65
|
+
>
|
|
66
|
+
> **Found while fixing these** (and fixed): `execute()` read the handler's annotation raw, so any
|
|
67
|
+
> tool module using `from __future__ import annotations` 422'd on *every* request with
|
|
68
|
+
> `'str' object is not callable` — see `tests/test_postponed_annotations.py`.
|
|
69
|
+
>
|
|
70
|
+
> Bridge to the data plane is `originator_email=caller.require_authz_id()` — dag-tools'
|
|
71
|
+
> `CortexDataClient` takes a string subject, carried opaque, so employee-id deployments work
|
|
72
|
+
> unchanged. `caller=` was not adopted because that parameter does not exist in dag-tools yet;
|
|
73
|
+
> `test_cortex_data_client_contract.py` watches its real source and goes red when it appears.
|
|
74
|
+
|
|
75
|
+
**To:** whoever owns `iagent-mesh-sdk`
|
|
76
|
+
**From:** the ADR-0044 / mesh-read session, 2026-08-27
|
|
77
|
+
**Both findings are in `iagent_mesh/core.py`, in the same function.**
|
|
78
|
+
|
|
79
|
+
Plan items (invincible-agent `docs/plans/`, on `docs/BOARD.md`):
|
|
80
|
+
`[[sdk-discards-caller-identity]]`, `[[sdk-blocking-sync-handlers]]`.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Read this first: they touch the same seam, so sequence them
|
|
85
|
+
|
|
86
|
+
Both fixes change `MeshTool.execute()`'s `route_handler`. **Two uncoordinated fixes to one
|
|
87
|
+
function is how it grows a third defect**, and in this case they interact directly:
|
|
88
|
+
|
|
89
|
+
- Fix A puts a `CallerIdentity` in a request-scoped `ContextVar`.
|
|
90
|
+
- Fix B moves sync handlers off the event loop onto a thread.
|
|
91
|
+
- **`asyncio.to_thread` copies the context. `loop.run_in_executor` does not.**
|
|
92
|
+
|
|
93
|
+
Do B with `run_in_executor` and A's contextvar reads `None` inside **exactly the handler style
|
|
94
|
+
the quickstart recommends** — and without A's fail-closed rule, that read lands on the service
|
|
95
|
+
identity, silently, in the most common case. Two correct-looking fixes producing a
|
|
96
|
+
cross-tenant read.
|
|
97
|
+
|
|
98
|
+
Do them together, or A then B with B's mechanism chosen for A.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Finding A — a tool cannot learn who invoked it
|
|
103
|
+
|
|
104
|
+
**`core.py:180`** registers the auth dependency at APP level:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
dependencies=[Depends(make_transport_auth_dependency(component=name))],
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`make_transport_auth_dependency` does the right thing — it returns a `CallerIdentity` whose
|
|
111
|
+
`authz_id` is documented as *"the ONLY field an authorization decision may key on."* But
|
|
112
|
+
**FastAPI discards an app-level dependency's return value.** It is not injectable into a route,
|
|
113
|
+
never reaches `request.state`, and `route_handler` does not ask for it.
|
|
114
|
+
|
|
115
|
+
Then **`core.py:440`**:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
return func(input_data)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The handler receives the validated input model and nothing else.
|
|
122
|
+
|
|
123
|
+
**So the caller is computed, logged, and thrown away** — one frame before anyone could use it.
|
|
124
|
+
|
|
125
|
+
### What that forces
|
|
126
|
+
|
|
127
|
+
A tool author has nothing to put here:
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
client = CortexDataClient(originator_email=???)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Their only working option is a bare constructor, which resolves to the **service identity**. So
|
|
134
|
+
**every user of that agent reads with the service's entitlements** — the confused deputy the
|
|
135
|
+
platform's own chart comment warns about on `CORTEX_CLIENT_ID`.
|
|
136
|
+
|
|
137
|
+
**It fails invisibly.** An agent reading as the service *works*. Rows come back, nothing errors,
|
|
138
|
+
no test fails. The only symptom is that every user sees data entitled to the service.
|
|
139
|
+
|
|
140
|
+
**Existence proof:** Engine DA does not get the caller from the SDK. It pulls `user_email` off
|
|
141
|
+
the request payload (`agent_fleet/data_analyst/main.py:271`) because the supervisor threads it
|
|
142
|
+
manually. The one agent doing per-user reads correctly had to route around the SDK.
|
|
143
|
+
|
|
144
|
+
### The target
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
@app.execute()
|
|
148
|
+
def detect_anomalies(data: AnomalyInput, caller: CallerIdentity) -> AnomalyOutput:
|
|
149
|
+
client = CortexDataClient(caller=caller)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
…and better, with a contextvar, no parameter at all:
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
client = CortexDataClient() # notebook, pipeline, agent handler — identical
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**The resolution order matters more than the mechanism, and it is the part to get right:**
|
|
159
|
+
|
|
160
|
+
> 1. explicit `caller=` — override, for tests. Wins over everything.
|
|
161
|
+
> 2. the request-scoped contextvar — the agent case.
|
|
162
|
+
> 3. `CORTEX_USER_TOKEN` — per-process user identity (notebook).
|
|
163
|
+
> 4. service identity — **opt-in only.**
|
|
164
|
+
>
|
|
165
|
+
> **Inside a request, failure to resolve RAISES.** It never falls through to 3 or 4.
|
|
166
|
+
|
|
167
|
+
**Why 2 must outrank 3:** everyone writing this by hand reaches for
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
return os.environ['CORTEX_USER_TOKEN'] if 'CORTEX_USER_TOKEN' in os.environ else caller
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
which works in all three contexts today — **only because that var happens to be unset on agent
|
|
174
|
+
pods.** Set it once for debugging and every request silently reads as one user, with code that
|
|
175
|
+
still looks correct. A confused deputy arriving via a *config* change, with nothing to review.
|
|
176
|
+
|
|
177
|
+
Steps 1 and 2 ship together. The contextvar without the fail-closed rule just relocates the
|
|
178
|
+
silent service-read from "author forgot `caller=`" to "contextvar was empty for a reason nobody
|
|
179
|
+
noticed."
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Finding B — the quickstart promises a background thread that does not exist
|
|
184
|
+
|
|
185
|
+
**`core.py:438`**:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
if inspect.iscoroutinefunction(func):
|
|
189
|
+
return await func(input_data)
|
|
190
|
+
return func(input_data) # no threadpool
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**`docs/jupyter_guide.md`**:
|
|
194
|
+
|
|
195
|
+
> **Use standard `def` (Recommended):** If you are crunching Polars DataFrames
|
|
196
|
+
> (`df.collect()`), stick to standard `def`. **We will execute it safely in a background
|
|
197
|
+
> thread.**
|
|
198
|
+
|
|
199
|
+
`grep -rn "run_in_threadpool\|to_thread\|run_in_executor" iagent_mesh/*.py` → nothing.
|
|
200
|
+
|
|
201
|
+
A recommended handler doing `df.collect()` holds the event loop for its duration. Every other
|
|
202
|
+
request to that tool, including health probes, waits.
|
|
203
|
+
|
|
204
|
+
**The doc recommended the failing path for the heaviest workload**, so authors who complied are
|
|
205
|
+
worse off than authors who ignored it.
|
|
206
|
+
|
|
207
|
+
### Two rulings, neither of them technical
|
|
208
|
+
|
|
209
|
+
1. **Fix the code or fix the doc?** Threading makes every existing sync handler retroactively
|
|
210
|
+
correct — and changes execution semantics for handlers written assuming single-threaded
|
|
211
|
+
module state. Correcting the doc makes them retroactively wrong and obliges migration. The
|
|
212
|
+
choice decides **which population currently holds broken code.**
|
|
213
|
+
2. **Who audits existing handlers, and how many are there?** Neither option can be sized
|
|
214
|
+
without a count. Enumerate before choosing — a remembered list of "the tools we know about"
|
|
215
|
+
is how the sixth one breaks.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Acceptance for the pair
|
|
220
|
+
|
|
221
|
+
- A tool handler can name its invoker; a read inside it authorizes as **that person**.
|
|
222
|
+
- Two different users invoking the same agent against the same asset get **different rows**.
|
|
223
|
+
- `CORTEX_USER_TOKEN` set on an agent pod changes nothing — the request's caller outranks it.
|
|
224
|
+
- Reading as the service requires saying so.
|
|
225
|
+
- A sync handler doing a multi-second `collect()` does not delay a concurrent request.
|
|
226
|
+
- **If threaded: a `ContextVar` set by the auth dependency is readable inside a sync handler.**
|
|
227
|
+
This is the test that proves the two fixes were coordinated.
|
|
228
|
+
|
|
229
|
+
## Context worth having
|
|
230
|
+
|
|
231
|
+
The mesh's read path was hardened today (invincible-agent ADR-0044, dag-tools 0.3.2): routing
|
|
232
|
+
tickets now carry only broker-minted credentials, scoped to the asset and expiring with the
|
|
233
|
+
access window. That closed *what a caller is handed*. Finding A is *whether an agent can say
|
|
234
|
+
who is asking* — and it is the blocker on the notebook→agent path, which is where the users
|
|
235
|
+
are actually heading.
|
|
236
|
+
|
|
237
|
+
Not filed by an agent unilaterally because both rulings are blast-radius questions, not
|
|
238
|
+
technical preferences.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# THE iagent MESH: LAUNCH DOMAIN NODES, NOT SCRIPTS
|
|
2
|
+
### An Architectural Guide for Data Science and AI Engineering Teams
|
|
3
|
+
|
|
4
|
+
Your team’s primary directive is to engineer state-of-the-art AI agents and custom user experiences. However, the path to production often forces data scientists to become part-time cloud infrastructure engineers. In an enterprise environment, AI cannot operate in the shadows; agents must be assigned to persons, and their actions must be entirely traceable, predictable, observable, grounded, and trustworthy.
|
|
5
|
+
|
|
6
|
+
This document outlines the architectural realities of deploying AI services in our enterprise ecosystem, comparing the traditional Do-It-Yourself (DIY) API deployment against adopting the native `MeshTool` framework.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## PART 1: THE DIY REALITY (THE HIDDEN COST OF CUSTOM INFRASTRUCTURE)
|
|
11
|
+
|
|
12
|
+
If you choose to bypass the framework and deploy your agents as standalone APIs (e.g., raw FastAPI/Flask) to serve your custom UIs, you assume full responsibility for the enterprise plumbing.
|
|
13
|
+
|
|
14
|
+
Here is the infrastructure you are now required to build, maintain, and secure to meet enterprise standards:
|
|
15
|
+
|
|
16
|
+
* **Identity & Policy Enforcement:** Enterprise agents must be definitively assigned to real persons. You must manually write middleware to intercept Keycloak JWTs, parse claims, and enforce complex data access policies on every single incoming request to prove authorization.
|
|
17
|
+
* **Data Access & Grounding:** To be trustworthy, an agent must be firmly grounded in secure enterprise data. You cannot simply ask for a dataset; you must manage your own AWS STS token exchanges, handle credential rotation, and manually enforce Row-Level Security (RLS) and column masking to remain compliant.
|
|
18
|
+
* **Distributed Tracing (The Black Hole):** An AI system must be completely observable. When your custom UI calls your agent, and your agent calls a vector DB or an LLM, the trace is easily broken. You must manually inject Langfuse observers, pass trace IDs through your thread pools, and manage the `contextvars` yourself. When a hallucination or failure occurs, your logging is siloed and untraceable.
|
|
19
|
+
* **Concurrency & Predictability:** AI behavior must be predictable. If your agent uses `asyncio` mixed with synchronous data crunching (Pandas/Polars) or nested sub-agents (`smolagents`), you risk freezing your event loop and crashing your Kubernetes pods under load unless you manually patch and manage thread pools.
|
|
20
|
+
* **Deployment Boilerplate:** You own the Dockerfiles, the Kubernetes YAMLs, the Helm charts, and the CI/CD pipeline definitions required to get your code into the cluster.
|
|
21
|
+
|
|
22
|
+
**The Result:** Your team spends 80% of its velocity maintaining backend plumbing and proving compliance, and only 20% engineering the actual AI and the custom UI.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## PART 2: THE `MeshTool` ADVANTAGE
|
|
27
|
+
|
|
28
|
+
The `MeshTool` framework is not a restriction; it is an exoskeleton. It provides a hardened, headless backend for your custom UI, absorbing all enterprise infrastructure and compliance complexity into three lines of code.
|
|
29
|
+
|
|
30
|
+
### 1. Frictionless, Trustworthy Data Plane
|
|
31
|
+
Never manage an AWS key, database password, or access policy again.
|
|
32
|
+
* **Identity Passthrough:** Agents are inherently assigned to persons. The moment you use `CortexDataClient()`, the mesh invisibly routes your user's Keycloak JWT through the cluster, ensuring every action is tied to a verified human.
|
|
33
|
+
* **Native Compliance & Grounding:** The platform automatically enforces central data access policies, RLS, and column masking before the data ever hits your agent. Your agent is guaranteed to be grounded in trustworthy, authorized enterprise data.
|
|
34
|
+
* **High-Throughput Ready:** Seamless integration with `dag_tools` returns Polars LazyFrames for instant, massive-scale data crunching without crashing your LLM context windows.
|
|
35
|
+
|
|
36
|
+
### 2. Complete Observability Out-of-the-Box
|
|
37
|
+
Debugging a nested AI loop shouldn't require guesswork.
|
|
38
|
+
* **End-to-End Traceability:** The mesh generates a unified Trace ID from your custom UI's HTTP header and propagates it flawlessly across all network boundaries and asynchronous threads.
|
|
39
|
+
* **Langfuse Native:** Every LLM call, tool use, and latency spike inside your agent is automatically tracked, made fully observable, and tied to the exact user session.
|
|
40
|
+
|
|
41
|
+
### 3. Predictable Concurrency & DevOps
|
|
42
|
+
You write the Python; the platform ensures predictable execution.
|
|
43
|
+
* **Safe Asynchronous Execution:** The framework natively applies `nest_asyncio` and thread-pool routing. You can spin up heavy data operations or nested agent loops without ever freezing your API.
|
|
44
|
+
* **One-Click Deployment:** Use the interactive `scaffold.sh` to generate a GitOps-ready repository. Push your code, and Jenkins automatically builds the container (via S2I) and deploys it. Zero Dockerfiles required.
|
|
45
|
+
|
|
46
|
+
### 4. Headless Architecture (Bring Your Own UI)
|
|
47
|
+
We do not force you into a centralized UI.
|
|
48
|
+
* **Perfect Portability:** `MeshTool` exposes standard, OpenAPI-compliant endpoints. Your custom React, Vue, or Streamlit frontend can communicate with your agent exactly as it does today.
|
|
49
|
+
* **Global Discoverability:** While you power your custom UI, the framework automatically registers your agent's OpenAPI schema to the DataHub Universal Registry. Engine A (the central mesh) can now discover and route relevant enterprise traffic to your endpoint, giving your domain expertise massive internal distribution for free.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## PART 3: SYSTEMS ARCHITECTURE (DoDAF VIEWS)
|
|
54
|
+
|
|
55
|
+
### The OV-1: Operational Concept Graphic
|
|
56
|
+
This diagram contrasts the high engineering burden of the DIY approach against the streamlined elegance of the Mesh ecosystem.
|
|
57
|
+
|
|
58
|
+
```mermaid
|
|
59
|
+
%%{init: {'theme': 'neutral'} }%%
|
|
60
|
+
flowchart TD
|
|
61
|
+
classDef nightmare fill:#ffe6e6,stroke:#ff3333,stroke-width:2px,color:#990000;
|
|
62
|
+
classDef mesh fill:#e6f3ff,stroke:#3399ff,stroke-width:2px,color:#004c99;
|
|
63
|
+
classDef platform fill:#e6ffe6,stroke:#33cc33,stroke-width:2px,color:#006600;
|
|
64
|
+
|
|
65
|
+
subgraph DIY[The DIY Silo: High Engineering Burden]
|
|
66
|
+
DS1((Data Scientist)) --> API[Custom API Engine]
|
|
67
|
+
API --> Auth[Manual Token Middleware]:::nightmare
|
|
68
|
+
API --> Trace[Fragmented Local Logging]:::nightmare
|
|
69
|
+
API --> DBConn[Raw AWS/DB Connections]:::nightmare
|
|
70
|
+
Auth -.-> Risk[Compliance Violations]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
subgraph MESH[The iagent Mesh Ecosystem]
|
|
74
|
+
DS2((Data Scientist)) --> Logic[AI Agent / Business Logic]
|
|
75
|
+
Logic --> MT[MeshTool Node Wrapper]:::mesh
|
|
76
|
+
|
|
77
|
+
Orchestrator[Engine A: Central Orchestrator] == Authenticated Traffic ==> MT
|
|
78
|
+
|
|
79
|
+
MT --> CDC[CortexDataClient]:::mesh
|
|
80
|
+
|
|
81
|
+
Topaz[Zero-Trust Policies] -. Invisible Enforcement .-> MT:::platform
|
|
82
|
+
Langfuse[Distributed Tracing] -. Invisible Telemetry .-> MT:::platform
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
style DIY fill:#cccccc,stroke:#666,stroke-width:1px,stroke-dasharray: 5 5
|
|
86
|
+
style MESH fill:#b8c8d8,stroke:#666,stroke-width:1px,stroke-dasharray: 5 5
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### The SV-1: Systems Interface Description
|
|
90
|
+
How existing legacy architectures (LangChain/LlamaIndex) interface securely with the central orchestrator via structured passthrough.
|
|
91
|
+
|
|
92
|
+
```mermaid
|
|
93
|
+
%%{init: { 'sequence': { 'boxBorderColor': '#666', 'showSequenceNumbers': true } } }%%
|
|
94
|
+
sequenceDiagram
|
|
95
|
+
autonumber
|
|
96
|
+
box rgba(0, 100, 255, 0.1) Platform Control Plane
|
|
97
|
+
participant U as Custom UI / User
|
|
98
|
+
participant EA as Engine A (Orchestrator)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
box rgba(0, 200, 0, 0.1) Domain Node (Data Science)
|
|
102
|
+
participant MT as MeshTool (Pydantic Ingress)
|
|
103
|
+
participant LR as Legacy Agent (LangChain/LlamaIndex)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
box rgba(255, 150, 0, 0.1) Platform Data Plane
|
|
107
|
+
participant DP as CortexDataClient
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
U->>EA: "Hey, check delays for supplier X and summarize"
|
|
111
|
+
Note over EA: Central LLM applies NLP Parsing<br/>& Intent Classification
|
|
112
|
+
EA->>MT: Validated Pydantic Object<br/>{intent: "delay_check", id: "X"}
|
|
113
|
+
MT->>LR: Clean Variables
|
|
114
|
+
Note over LR: Executes existing custom logic<br/>(No NLP parsing needed locally!)
|
|
115
|
+
LR->>DP: get_dataframe(urn:...)
|
|
116
|
+
DP-->>LR: RLS-Filtered Polars LazyFrame
|
|
117
|
+
LR-->>MT: Analysis Result
|
|
118
|
+
MT-->>EA: Standardized JSON Output
|
|
119
|
+
EA-->>U: Final Formatted Response
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### The SV-4: Systems Functionality / Data Security Flow
|
|
123
|
+
The invisible path of identity propagation ensuring every computation is grounded in verifiable enterprise access controls.
|
|
124
|
+
|
|
125
|
+
```mermaid
|
|
126
|
+
%%{init: {'theme': 'neutral'} }%%
|
|
127
|
+
flowchart LR
|
|
128
|
+
classDef secure fill:#e8f4f8,stroke:#1b85b8,stroke-width:2px;
|
|
129
|
+
classDef compute fill:#f4e8f8,stroke:#851bb8,stroke-width:2px;
|
|
130
|
+
classDef data fill:#e8f8ec,stroke:#1bb845,stroke-width:2px;
|
|
131
|
+
|
|
132
|
+
User([User Session]) -- 1. Injects JWT --> Jupyter[Jupyter / UI]:::compute
|
|
133
|
+
Jupyter -- 2. mesh.ask() --> EngineA[Engine A]:::compute
|
|
134
|
+
EngineA -- 3. Forwards JWT Header --> MeshTool[MeshTool Node]:::compute
|
|
135
|
+
|
|
136
|
+
subgraph Zero-Trust Perimeter
|
|
137
|
+
MeshTool -- 4. Request Asset --> Gateway[Central Data Gateway]:::secure
|
|
138
|
+
Gateway -- 5. Verify Token --> Keycloak[Keycloak IDP]:::secure
|
|
139
|
+
Gateway -- 6. Fetch Policies --> Topaz[AuthZ Engine]:::secure
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
subgraph Enterprise Data Lake
|
|
143
|
+
Topaz -- 7. Apply RLS & Masking --> S3[(AWS S3 / Database)]:::data
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
S3 -- 8. Mint STS & Stream Data --> MeshTool
|
|
147
|
+
|
|
148
|
+
MeshTool --- Logic[Data Scientist safely computes<br/>on Polars LazyFrame]:::compute
|
|
149
|
+
|
|
150
|
+
style Zero-Trust Perimeter fill:#c5d8e0,stroke:#1b85b8,stroke-dasharray: 5 5
|
|
151
|
+
style Enterprise Data Lake fill:#c5e0ca,stroke:#1bb845,stroke-dasharray: 5 5
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## THE VERDICT
|
|
157
|
+
|
|
158
|
+
If you build your own orchestrator and API from scratch, you own the burden of distributed tracing, token rotation, data access policy enforcement, and proving your agents are trustworthy.
|
|
159
|
+
|
|
160
|
+
If you wrap your logic in `@app.execute()`, the Mesh handles 100% of the enterprise plumbing, ensuring your agents are traceable, predictable, observable, and grounded by default.
|
|
161
|
+
|
|
162
|
+
**Focus your talent on building superior agents and exceptional custom UIs. Let the Mesh handle the infrastructure.**
|