agentenv-framework-protocol 0.1.454__tar.gz → 0.1.455__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.
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/PKG-INFO +11 -1
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/README.md +10 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/pyproject.toml +1 -1
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/client.py +80 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_client.py +52 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/.gitignore +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/LICENSE +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/NOTICE +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/THIRD_PARTY_NOTICES.md +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/examples/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/examples/advanced_agent.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/examples/basic_agent.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/examples/custom_extensions_agent.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/examples/multimodal_agent.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/examples/reference_model.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/examples/streaming_agent.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/_trajectory_log.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/_triggers.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/extensions.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/framework.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/peer_agents.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/proxy.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/registry.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/staging.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/tasks/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/a2a_agent/tasks/v1.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/agent_env_environment.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/browser_cdp.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/_declare.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/_linux.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/_load.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/_with_fds.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/app.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/app_data.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/app_runtime.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/apps.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/card.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/checks.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/conformance/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/conformance/__main__.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/conformance/checks.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/conformance/client.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/conformance/fixture.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/conformance/mp4.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/conformance/page_fixture.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/conformance/report.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/dataplane.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/driver.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/errors.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/extensions.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/frames.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/keys.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/launch.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/manifest.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/operations.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/platform.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/queue.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/recording.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/results.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/run_install_step.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/runtime.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/seed.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/serve.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/serve_app.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/session.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/settings.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/skill.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/spaces.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/svc.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/computer/tools.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/errors.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/manifest.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/preflight.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/tool_access.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/tool_client.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/tool_context.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/transfers.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/types.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/src/agentenv_protocol/website_browser.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/computer_fake.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/probe_fake.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_agent.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_agent_examples.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_cdp_config.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_object_transfers.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_peer_agents.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_proxy.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_staging.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_trajectory_log.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_agent_env_environment.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_browser_cdp.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_app_data.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_app_server.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_conformance.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_conformance_checks.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_conformance_page.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_conformance_recording.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_dataplane.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_declare.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_driver.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_extensions.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_frames.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_page.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_queue.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_recording.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_seed.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_serve.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_spaces.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_computer_svc_forward.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_control_token.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_data_objects.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_errors.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_extension_methods.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_intake.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_manifest.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_preflight.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_tool_access.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_tool_annotations.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_tool_client.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_tool_context.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_tool_context_fastmcp.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_tool_context_injection.py +0 -0
- {agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_website_browser.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agentenv-framework-protocol
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.455
|
|
4
4
|
Summary: Open data-plane protocol and server SDK for agent environments.
|
|
5
5
|
Project-URL: Homepage, https://www.agentenvframework.com
|
|
6
6
|
Project-URL: Documentation, https://www.agentenvframework.com/docs
|
|
@@ -258,6 +258,16 @@ with any other transport are kept beside the SDK's entry. Card URLs are paths, r
|
|
|
258
258
|
address the card was fetched from. On the client side, `client.mcp_path(card)` returns the
|
|
259
259
|
declared path, or `/mcp` for a card without one.
|
|
260
260
|
|
|
261
|
+
A composed card, such as a gateway's, nests each backing environment's card under
|
|
262
|
+
`children_environments`, its `url` and endpoints rooted at the route the composer serves it at.
|
|
263
|
+
`client.children(card)` returns each as a `ChildEnv` (its `name`, `url` and `card`, with its
|
|
264
|
+
`extensions`, `operations` and `serves(method)`, and `base_url(address)`, its data plane resolved
|
|
265
|
+
against the composed card's address). Two children may share a name, as a website and an MCP
|
|
266
|
+
server can, so `client.child_at(card, url)` finds one by its url or route; `client.child_named(card,
|
|
267
|
+
name)` raises `AmbiguousChildError` for a shared name, and `client.find_child` returns the first.
|
|
268
|
+
`client.serves(card, method)` says whether a card serves a data-plane method by its declared
|
|
269
|
+
`operations`, None for a card that declares none.
|
|
270
|
+
|
|
261
271
|
Extensions are invoked from what the card advertises. `client.find_extension_method(card, uri,
|
|
262
272
|
method)` returns one advertised method, whose `endpoint` is the method's own or else the
|
|
263
273
|
extension's, and `client.invoke_extension(base_url, card, uri, params, method=...)` calls it with
|
|
@@ -199,6 +199,16 @@ with any other transport are kept beside the SDK's entry. Card URLs are paths, r
|
|
|
199
199
|
address the card was fetched from. On the client side, `client.mcp_path(card)` returns the
|
|
200
200
|
declared path, or `/mcp` for a card without one.
|
|
201
201
|
|
|
202
|
+
A composed card, such as a gateway's, nests each backing environment's card under
|
|
203
|
+
`children_environments`, its `url` and endpoints rooted at the route the composer serves it at.
|
|
204
|
+
`client.children(card)` returns each as a `ChildEnv` (its `name`, `url` and `card`, with its
|
|
205
|
+
`extensions`, `operations` and `serves(method)`, and `base_url(address)`, its data plane resolved
|
|
206
|
+
against the composed card's address). Two children may share a name, as a website and an MCP
|
|
207
|
+
server can, so `client.child_at(card, url)` finds one by its url or route; `client.child_named(card,
|
|
208
|
+
name)` raises `AmbiguousChildError` for a shared name, and `client.find_child` returns the first.
|
|
209
|
+
`client.serves(card, method)` says whether a card serves a data-plane method by its declared
|
|
210
|
+
`operations`, None for a card that declares none.
|
|
211
|
+
|
|
202
212
|
Extensions are invoked from what the card advertises. `client.find_extension_method(card, uri,
|
|
203
213
|
method)` returns one advertised method, whose `endpoint` is the method's own or else the
|
|
204
214
|
extension's, and `client.invoke_extension(base_url, card, uri, params, method=...)` calls it with
|
|
@@ -7,6 +7,7 @@ import contextlib
|
|
|
7
7
|
import logging
|
|
8
8
|
from collections.abc import Iterator
|
|
9
9
|
from contextvars import ContextVar
|
|
10
|
+
from dataclasses import dataclass, field
|
|
10
11
|
|
|
11
12
|
import httpx
|
|
12
13
|
|
|
@@ -210,6 +211,83 @@ def find_tool(card: dict, name: str) -> dict | None:
|
|
|
210
211
|
return None
|
|
211
212
|
|
|
212
213
|
|
|
214
|
+
def serves(card: dict, method: str) -> bool | None:
|
|
215
|
+
"""Whether a card serves the data-plane ``method`` (``data/get`` say): True or False by its declared
|
|
216
|
+
``capabilities.operations``, or None when it declares none, as an older card doesn't, so the caller decides as it
|
|
217
|
+
did before cards declared them (a probe, say)."""
|
|
218
|
+
declared = operations(card)
|
|
219
|
+
return None if declared is None else method in declared
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
@dataclass(frozen=True)
|
|
223
|
+
class ChildEnv:
|
|
224
|
+
"""One child env a composed card nests under ``children_environments``: its ``name`` and ``url`` as its card gives
|
|
225
|
+
them, and that ``card``, which says what it offers. A composer roots each child's ``url`` (and its endpoints) at
|
|
226
|
+
the route it serves the child at, so two children sharing a name have distinct urls; ``url`` is None for a child
|
|
227
|
+
whose card names none."""
|
|
228
|
+
|
|
229
|
+
name: str | None
|
|
230
|
+
url: str | None
|
|
231
|
+
card: dict = field(hash=False, repr=False)
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def extensions(self) -> list[dict]:
|
|
235
|
+
"""The extensions the child's card advertises (``capabilities.extensions``)."""
|
|
236
|
+
return list((self.card.get("capabilities") or {}).get("extensions") or [])
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
def operations(self) -> list[str] | None:
|
|
240
|
+
"""The data-plane methods the child's card declares (``operations``), or None when it declares none."""
|
|
241
|
+
return operations(self.card)
|
|
242
|
+
|
|
243
|
+
def find_extension(self, uri: str) -> dict | None:
|
|
244
|
+
"""The extension the child's card advertises under ``uri``, or None (``find_extension``)."""
|
|
245
|
+
return find_extension(self.card, uri)
|
|
246
|
+
|
|
247
|
+
def serves(self, method: str) -> bool | None:
|
|
248
|
+
"""Whether the child's card serves the data-plane ``method``, None when it declares no operations (``serves``)."""
|
|
249
|
+
return serves(self.card, method)
|
|
250
|
+
|
|
251
|
+
def base_url(self, address: str) -> str:
|
|
252
|
+
"""Where the child's data plane is, its ``url`` without the RPC path, resolved against ``address``, the composed
|
|
253
|
+
card's: a path joins onto it, a full URL stands alone, and a child naming no url is at ``address`` itself."""
|
|
254
|
+
url = (self.url or RPC_PATH).removesuffix(RPC_PATH)
|
|
255
|
+
return url if "://" in url else f"{address.rstrip('/')}{url}"
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def children(card: dict) -> list[ChildEnv]:
|
|
259
|
+
"""Each child env a composed card nests under ``children_environments``, in its order; none for a leaf card, or
|
|
260
|
+
one whose ``children_environments`` is missing or null. An entry that isn't an object is skipped."""
|
|
261
|
+
return [ChildEnv(name=child.get("name"), url=child.get("url"), card=child)
|
|
262
|
+
for child in card.get("children_environments") or [] if isinstance(child, dict)]
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def child_at(card: dict, url: str) -> ChildEnv | None:
|
|
266
|
+
"""The child env of a composed card at ``url``: the one whose ``url`` is ``url``, or whose data plane is there
|
|
267
|
+
(``url`` without the RPC path, ``/svc/mcp-slack`` for ``/svc/mcp-slack/agentenv`` say), a trailing slash aside;
|
|
268
|
+
None when no child is. A composer serves each child at its own route, so this is the lookup two children sharing a
|
|
269
|
+
name can't confuse."""
|
|
270
|
+
wanted = url.rstrip("/")
|
|
271
|
+
for child in children(card):
|
|
272
|
+
if child.url is not None and wanted in (child.url.rstrip("/"), child.url.removesuffix(RPC_PATH).rstrip("/")):
|
|
273
|
+
return child
|
|
274
|
+
return None
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
class AmbiguousChildError(LookupError):
|
|
278
|
+
"""More than one child env of a composed card has the name asked for, so the name can't say which is meant."""
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def child_named(card: dict, name: str) -> ChildEnv | None:
|
|
282
|
+
"""The one child env of a composed card named ``name``, or None when none is; raises ``AmbiguousChildError`` when
|
|
283
|
+
several are, as a website and an MCP server sharing a name are, which ``child_at`` tells apart by their urls."""
|
|
284
|
+
found = [child for child in children(card) if child.name == name]
|
|
285
|
+
if len(found) > 1:
|
|
286
|
+
raise AmbiguousChildError(f"{len(found)} child envs are named {name!r} ({', '.join(str(c.url) for c in found)}); "
|
|
287
|
+
"look one up by its url")
|
|
288
|
+
return found[0] if found else None
|
|
289
|
+
|
|
290
|
+
|
|
213
291
|
def find_child(card: dict, name: str) -> dict | None:
|
|
214
292
|
"""Return the nested child EnvironmentCard named `name`, or None.
|
|
215
293
|
|
|
@@ -218,6 +296,8 @@ def find_child(card: dict, name: str) -> dict | None:
|
|
|
218
296
|
rewritten to be reachable from the composed card's base_url. Callers resolve a service by
|
|
219
297
|
name here, then use the child card with `find_extension`/`invoke_extension`. Tolerates a
|
|
220
298
|
missing/null `children_environments` so single/leaf cards return None rather than raising.
|
|
299
|
+
Two children sharing `name` return the first; `child_named` refuses that, and `child_at`
|
|
300
|
+
finds a child by its url, which tells them apart.
|
|
221
301
|
"""
|
|
222
302
|
for child in card.get("children_environments") or []:
|
|
223
303
|
if child.get("name") == name:
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_client.py
RENAMED
|
@@ -190,6 +190,58 @@ def test_find_child_tolerates_missing_children():
|
|
|
190
190
|
assert protocol_v1.find_child({"children_environments": None}, "slack") is None
|
|
191
191
|
|
|
192
192
|
|
|
193
|
+
_SHARED_NAME = {"name": "gw", "children_environments": [
|
|
194
|
+
{"name": "mail", "url": "/svc/mcp-mail/agentenv", "capabilities": {"operations": ["data/get"], "extensions": [
|
|
195
|
+
{"uri": "urn:agentenv:clock/v1"}]}},
|
|
196
|
+
{"name": "mail", "url": "/svc/mail/agentenv", "capabilities": {"operations": []}},
|
|
197
|
+
{"name": "docs", "capabilities": {}},
|
|
198
|
+
"not a card",
|
|
199
|
+
]}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def test_children_are_each_nested_card_by_its_name_url_and_card():
|
|
203
|
+
found = protocol_v1.children(_SHARED_NAME)
|
|
204
|
+
|
|
205
|
+
assert [(c.name, c.url) for c in found] == [("mail", "/svc/mcp-mail/agentenv"), ("mail", "/svc/mail/agentenv"), ("docs", None)]
|
|
206
|
+
assert found[0].card is _SHARED_NAME["children_environments"][0]
|
|
207
|
+
assert [c.extensions for c in found] == [[{"uri": "urn:agentenv:clock/v1"}], [], []]
|
|
208
|
+
assert [c.operations for c in found] == [["data/get"], [], None]
|
|
209
|
+
assert [c.serves("data/get") for c in found] == [True, False, None]
|
|
210
|
+
assert found[0].find_extension("urn:agentenv:clock/v1") is not None and found[1].find_extension("urn:agentenv:clock/v1") is None
|
|
211
|
+
assert protocol_v1.children({"name": "leaf"}) == [] and protocol_v1.children({"children_environments": None}) == []
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def test_a_childs_base_url_is_its_url_without_the_rpc_path_against_the_composed_cards_address():
|
|
215
|
+
mcp, website, docs = protocol_v1.children(_SHARED_NAME)
|
|
216
|
+
|
|
217
|
+
assert mcp.base_url("https://env.example/") == "https://env.example/svc/mcp-mail"
|
|
218
|
+
assert website.base_url("https://env.example") == "https://env.example/svc/mail"
|
|
219
|
+
assert docs.base_url("https://env.example") == "https://env.example"
|
|
220
|
+
assert protocol_v1.ChildEnv("x", "https://x.example/agentenv", {}).base_url("https://env.example") == "https://x.example"
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def test_child_at_finds_a_child_by_its_url_or_data_plane_route_where_two_share_a_name():
|
|
224
|
+
assert protocol_v1.child_at(_SHARED_NAME, "/svc/mail").url == "/svc/mail/agentenv"
|
|
225
|
+
assert protocol_v1.child_at(_SHARED_NAME, "/svc/mcp-mail/").url == "/svc/mcp-mail/agentenv"
|
|
226
|
+
assert protocol_v1.child_at(_SHARED_NAME, "/svc/mail/agentenv").url == "/svc/mail/agentenv"
|
|
227
|
+
assert protocol_v1.child_at(_SHARED_NAME, "/svc/docs") is None
|
|
228
|
+
assert protocol_v1.child_at({"name": "leaf"}, "/svc/mail") is None
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def test_child_named_refuses_a_name_two_children_share():
|
|
232
|
+
assert protocol_v1.child_named(_SHARED_NAME, "docs").name == "docs"
|
|
233
|
+
assert protocol_v1.child_named(_SHARED_NAME, "gmail") is None
|
|
234
|
+
with pytest.raises(protocol_v1.AmbiguousChildError, match="2 child envs are named 'mail'"):
|
|
235
|
+
protocol_v1.child_named(_SHARED_NAME, "mail")
|
|
236
|
+
assert protocol_v1.find_child(_SHARED_NAME, "mail")["url"] == "/svc/mcp-mail/agentenv"
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def test_serves_is_what_a_card_declares_of_a_method_and_none_when_it_declares_no_operations():
|
|
240
|
+
assert protocol_v1.serves({"capabilities": {"operations": ["data/get"]}}, "data/get") is True
|
|
241
|
+
assert protocol_v1.serves({"capabilities": {"operations": ["data/add"]}}, "data/get") is False
|
|
242
|
+
assert protocol_v1.serves({"capabilities": {}}, "data/get") is None
|
|
243
|
+
|
|
244
|
+
|
|
193
245
|
def test_find_extension_ignores_children():
|
|
194
246
|
# set-errors/v1 is advertised only on the children, never at the top level
|
|
195
247
|
assert protocol_v1.find_extension(_CARD_WITH_CHILDREN, "urn:agentenv:set-errors/v1") is None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/THIRD_PARTY_NOTICES.md
RENAMED
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/examples/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/examples/basic_agent.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/computer_fake.py
RENAMED
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/probe_fake.py
RENAMED
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_agent.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_a2a_proxy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_errors.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_intake.py
RENAMED
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_manifest.py
RENAMED
|
File without changes
|
{agentenv_framework_protocol-0.1.454 → agentenv_framework_protocol-0.1.455}/tests/test_preflight.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|