agentenv-framework-protocol 0.1.455__tar.gz → 0.1.458__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.455 → agentenv_framework_protocol-0.1.458}/PKG-INFO +1 -1
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/pyproject.toml +1 -1
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/_linux.py +3 -2
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/app.py +9 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/app_runtime.py +4 -2
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/conformance/checks.py +3 -1
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/driver.py +3 -3
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/platform.py +6 -4
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/recording.py +23 -3
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/probe_fake.py +6 -5
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_app_server.py +11 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_conformance.py +1 -1
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_declare.py +5 -2
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_driver.py +9 -5
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_recording.py +21 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/.gitignore +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/LICENSE +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/NOTICE +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/README.md +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/THIRD_PARTY_NOTICES.md +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/examples/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/examples/advanced_agent.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/examples/basic_agent.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/examples/custom_extensions_agent.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/examples/multimodal_agent.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/examples/reference_model.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/examples/streaming_agent.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/_trajectory_log.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/_triggers.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/extensions.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/framework.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/peer_agents.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/proxy.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/registry.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/staging.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/tasks/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/a2a_agent/tasks/v1.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/agent_env_environment.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/browser_cdp.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/client.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/_declare.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/_load.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/_with_fds.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/app_data.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/apps.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/card.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/checks.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/conformance/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/conformance/__main__.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/conformance/client.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/conformance/fixture.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/conformance/mp4.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/conformance/page_fixture.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/conformance/report.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/dataplane.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/errors.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/extensions.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/frames.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/keys.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/launch.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/manifest.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/operations.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/queue.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/results.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/run_install_step.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/runtime.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/seed.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/serve.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/serve_app.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/session.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/settings.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/skill.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/spaces.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/svc.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/computer/tools.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/errors.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/manifest.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/preflight.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/tool_access.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/tool_client.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/tool_context.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/transfers.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/types.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/src/agentenv_protocol/website_browser.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/computer_fake.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_a2a_agent.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_a2a_agent_examples.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_a2a_cdp_config.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_a2a_object_transfers.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_a2a_peer_agents.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_a2a_proxy.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_a2a_staging.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_a2a_trajectory_log.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_agent_env_environment.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_browser_cdp.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_client.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_app_data.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_conformance_checks.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_conformance_page.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_conformance_recording.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_dataplane.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_extensions.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_frames.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_page.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_queue.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_seed.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_serve.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_spaces.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_computer_svc_forward.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_control_token.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_data_objects.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_errors.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_extension_methods.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_intake.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_manifest.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_preflight.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_tool_access.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_tool_annotations.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_tool_client.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_tool_context.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_tool_context_fastmcp.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_tool_context_injection.py +0 -0
- {agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/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.458
|
|
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
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
"""The base class's
|
|
2
|
-
session, so both act directly: a command inherits the session's environment, a file
|
|
1
|
+
"""The base class's defaults for the OS operations on Linux and macOS, which use POSIX alone. The driver runs as the
|
|
2
|
+
session user inside the desktop session, so both act directly: a command inherits the session's environment, a file
|
|
3
|
+
lands as that user."""
|
|
3
4
|
from __future__ import annotations
|
|
4
5
|
|
|
5
6
|
import asyncio
|
|
@@ -251,6 +251,15 @@ class AppDeclaration(BaseModel):
|
|
|
251
251
|
ready_checks: list[AppReadyCheck]
|
|
252
252
|
browser: Optional[bool] = None
|
|
253
253
|
|
|
254
|
+
@model_validator(mode="after")
|
|
255
|
+
def _no_window_wait_on_macos(self) -> AppDeclaration:
|
|
256
|
+
"""A window's readiness is read from X11's windows, which macOS hasn't."""
|
|
257
|
+
launch = self.os["macos"].launch if "macos" in self.os else None
|
|
258
|
+
if launch is not None and launch.ready is not None and launch.ready.window:
|
|
259
|
+
raise ValueError("on macos an app's launch can't wait on its window, which is read from X11; wait on a "
|
|
260
|
+
"port, a command or a @ready_check")
|
|
261
|
+
return self
|
|
262
|
+
|
|
254
263
|
@model_validator(mode="before")
|
|
255
264
|
@classmethod
|
|
256
265
|
def _stored_before_each_os(cls, data: Any) -> Any:
|
|
@@ -9,6 +9,7 @@ import json
|
|
|
9
9
|
import os
|
|
10
10
|
import shlex
|
|
11
11
|
import signal
|
|
12
|
+
import sys
|
|
12
13
|
import time
|
|
13
14
|
from collections.abc import Awaitable, Callable
|
|
14
15
|
from datetime import datetime, timezone
|
|
@@ -22,8 +23,9 @@ from . import session
|
|
|
22
23
|
if TYPE_CHECKING:
|
|
23
24
|
from .app import Launch
|
|
24
25
|
|
|
25
|
-
#: Where an app's server marks that it launched the app since the computer booted, at boot or on demand
|
|
26
|
-
|
|
26
|
+
#: Where an app's server marks that it launched the app since the computer booted, at boot or on demand: a folder a
|
|
27
|
+
#: boot clears, under /tmp on macOS, which has no /run and lets the session user write nothing at its root.
|
|
28
|
+
LAUNCHED = Path("/tmp/agentenv/apps" if sys.platform == "darwin" else "/run/agentenv/apps")
|
|
27
29
|
#: How long one readiness check may take; an app's checks run at once.
|
|
28
30
|
CHECK_TIMEOUT_S = 10.0
|
|
29
31
|
#: Where an app's server keeps the pid of the app it launched last, in the app's folder, so a server that restarts can
|
|
@@ -48,6 +48,8 @@ MINIMUM_TOOLS = ("computer_screenshot", "computer_click", "computer_drag", "comp
|
|
|
48
48
|
DATA_PLANE = (INTAKE_EXTENSION_URI, DATA_OBJECTS_EXTENSION_URI)
|
|
49
49
|
#: Where the fixture is staged and keeps its state, relative to the session user's home.
|
|
50
50
|
STAGE = ".agentenv-probe"
|
|
51
|
+
#: How the probe reads a staged file's owner: through the python3 the fixture runs on, the same on every OS.
|
|
52
|
+
OWNER = ("python3", "-c", "import os, sys; print(os.stat(sys.argv[1]).st_uid)")
|
|
51
53
|
#: Where a page driver's computer_upload takes files from, relative to the session user's home.
|
|
52
54
|
UPLOADS = "Uploads"
|
|
53
55
|
#: What the probe answers the page fixture's prompt with.
|
|
@@ -605,7 +607,7 @@ class Probe:
|
|
|
605
607
|
async def _security(self) -> None:
|
|
606
608
|
async def one_user() -> str | None:
|
|
607
609
|
uid = (await self.driver.run("id", "-u"))["stdout"].strip()
|
|
608
|
-
owner = (await self.driver.run(
|
|
610
|
+
owner = (await self.driver.run(*OWNER, f"{STAGE}/{self.fixture}"))["stdout"].strip()
|
|
609
611
|
if uid == "0":
|
|
610
612
|
return "commands run as root"
|
|
611
613
|
return None if owner == uid else f"data/add wrote as uid {owner}, commands run as uid {uid}"
|
|
@@ -205,13 +205,13 @@ class ComputerDriverEnvironment(Tools, Extensions, DataPlane, AgentEnvEnvironmen
|
|
|
205
205
|
if self._computer is None:
|
|
206
206
|
raise TypeError(f"{type(self).__qualname__}.__init__ must call super().__init__()")
|
|
207
207
|
|
|
208
|
-
# The
|
|
208
|
+
# The defaults for the OS operations on Linux and macOS, POSIX alike.
|
|
209
209
|
|
|
210
|
-
@default_for("run_in_session", os="linux")
|
|
210
|
+
@default_for("run_in_session", os=["linux", "macos"])
|
|
211
211
|
async def _computer_linux_run_in_session(self, argv: list, cwd: str | None, env: dict | None, timeout_s: float):
|
|
212
212
|
return await _linux.run_in_session(argv, cwd, env, timeout_s, output_bytes=self.settings.exec_output_bytes)
|
|
213
213
|
|
|
214
|
-
@default_for("write_files", os="linux")
|
|
214
|
+
@default_for("write_files", os=["linux", "macos"])
|
|
215
215
|
async def _computer_linux_write_files(self, files: dict) -> None:
|
|
216
216
|
await asyncio.to_thread(_linux.write_files, files)
|
|
217
217
|
|
|
@@ -27,13 +27,15 @@ class Platform:
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def detect(environ: dict | None = None, os_release: Path = Path("/etc/os-release")) -> Platform:
|
|
30
|
-
"""The running platform: the OS, ``/etc/os-release``'s ID and VERSION_ID on Linux
|
|
31
|
-
display from ``XDG_SESSION_TYPE``, ``none`` for a computer with no display, else
|
|
32
|
-
``WAYLAND_DISPLAY`` (wayland)."""
|
|
30
|
+
"""The running platform: the OS, ``/etc/os-release``'s ID and VERSION_ID on Linux and the macOS version on macOS,
|
|
31
|
+
the machine, and the display: on Linux from ``XDG_SESSION_TYPE``, ``none`` for a computer with no display, else
|
|
32
|
+
``DISPLAY`` (x11) or ``WAYLAND_DISPLAY`` (wayland); on macOS Aqua."""
|
|
33
33
|
environ = os.environ if environ is None else environ
|
|
34
34
|
name = _OS.get(sys.platform, sys.platform)
|
|
35
35
|
release = _os_release(os_release) if name == "linux" else {}
|
|
36
|
-
|
|
36
|
+
if name == "macos":
|
|
37
|
+
release = {"VERSION_ID": _platform.mac_ver()[0] or None}
|
|
38
|
+
display = "aqua" if name == "macos" else None
|
|
37
39
|
if name == "linux":
|
|
38
40
|
session = (environ.get("XDG_SESSION_TYPE") or "").strip().lower()
|
|
39
41
|
if session in ("x11", "wayland", "none"):
|
|
@@ -52,6 +52,8 @@ FAILING_S = 60.0
|
|
|
52
52
|
GAP_S = 2.0
|
|
53
53
|
#: How long a stream that stopped or failed waits before it is started again.
|
|
54
54
|
RETRY_S = 1.0
|
|
55
|
+
#: How long a recording's start waits for its first frame, so a recording a start answered for is recording.
|
|
56
|
+
FIRST_FRAME_S = 5.0
|
|
55
57
|
#: How often free disk is checked while frames arrive.
|
|
56
58
|
DISK_CHECK_S = 5.0
|
|
57
59
|
KEEP_ENDED = 64
|
|
@@ -127,8 +129,9 @@ def recording_params(recording: Recording, streams: bool) -> dict:
|
|
|
127
129
|
|
|
128
130
|
|
|
129
131
|
class Recordings:
|
|
130
|
-
"""The recordings of one driver: started by request id,
|
|
131
|
-
ones kept with their manifests so a repeated ``end`` answers the
|
|
132
|
+
"""The recordings of one driver: started by request id, each start answering once its recording is recording, open
|
|
133
|
+
ones counted against ``max_concurrent``, ended ones kept with their manifests so a repeated ``end`` answers the
|
|
134
|
+
same."""
|
|
132
135
|
|
|
133
136
|
def __init__(self, runtime: ComputerRuntime) -> None:
|
|
134
137
|
self.runtime = runtime
|
|
@@ -144,7 +147,9 @@ class Recordings:
|
|
|
144
147
|
raise InvalidArgument("request_id is a non-empty string")
|
|
145
148
|
async with self._lock:
|
|
146
149
|
if request_id in self.started:
|
|
147
|
-
|
|
150
|
+
answer = self.started[request_id]
|
|
151
|
+
await self._live(self.running.get(answer["recording_id"]))
|
|
152
|
+
return answer
|
|
148
153
|
hints, grant = self._hints(features, scope, window, fps, max_edge, cursor, upload)
|
|
149
154
|
stopped = [rid for rid, r in self.running.items() if r.done]
|
|
150
155
|
for rid in stopped[:max(0, len(stopped) - KEEP_ENDED)]: # stopped by itself and never ended
|
|
@@ -164,8 +169,16 @@ class Recordings:
|
|
|
164
169
|
self.started[request_id] = answer
|
|
165
170
|
while len(self.started) > KEEP_STARTED:
|
|
166
171
|
self.started.popitem(last=False)
|
|
172
|
+
await self._live(recording)
|
|
167
173
|
return answer
|
|
168
174
|
|
|
175
|
+
@staticmethod
|
|
176
|
+
async def _live(recording: Optional[_Recording]) -> None:
|
|
177
|
+
"""Wait up to FIRST_FRAME_S for ``recording``, one still running, to have its first frame."""
|
|
178
|
+
if recording is not None:
|
|
179
|
+
with contextlib.suppress(TimeoutError):
|
|
180
|
+
await asyncio.wait_for(recording.live.wait(), FIRST_FRAME_S)
|
|
181
|
+
|
|
169
182
|
async def end(self, recording_id: str, upload: Optional[dict], reason: str) -> dict:
|
|
170
183
|
if reason not in REASONS:
|
|
171
184
|
raise InvalidArgument(f"reason is one of {list(REASONS)}, got {reason!r}")
|
|
@@ -219,6 +232,7 @@ class _Recording:
|
|
|
219
232
|
self.ended_by: Optional[str] = None
|
|
220
233
|
self.error: Optional[str] = None
|
|
221
234
|
self.done = False
|
|
235
|
+
self.live = asyncio.Event()
|
|
222
236
|
self.task: Optional[asyncio.Task] = None
|
|
223
237
|
self.timer: Optional[asyncio.TimerHandle] = None
|
|
224
238
|
self.released: Optional[asyncio.Future] = None
|
|
@@ -228,7 +242,11 @@ class _Recording:
|
|
|
228
242
|
self._last_disk_check = 0.0
|
|
229
243
|
|
|
230
244
|
async def run(self) -> None:
|
|
245
|
+
"""Frames or segments from the source, recorded until the recording ends; ``live`` once it's recording: a
|
|
246
|
+
stream from its start, the fallback's polling from its first frame, which a busy computer is slow to take."""
|
|
231
247
|
failing_since: Optional[float] = None
|
|
248
|
+
if self.streams:
|
|
249
|
+
self.live.set()
|
|
232
250
|
try:
|
|
233
251
|
while True:
|
|
234
252
|
try:
|
|
@@ -255,6 +273,7 @@ class _Recording:
|
|
|
255
273
|
await self._close()
|
|
256
274
|
finally:
|
|
257
275
|
self.done = True
|
|
276
|
+
self.live.set()
|
|
258
277
|
self.released = asyncio.ensure_future(self._release())
|
|
259
278
|
|
|
260
279
|
def expire(self) -> None:
|
|
@@ -315,6 +334,7 @@ class _Recording:
|
|
|
315
334
|
path = self.hints.directory / f"{len(self.segments):04d}.mp4"
|
|
316
335
|
self.encoder = await self._in_thread(_Encoder, path, frame.width, frame.height, self.hints.fps, at)
|
|
317
336
|
await self._in_thread(self.encoder.add, frame, at)
|
|
337
|
+
self.live.set()
|
|
318
338
|
self._check_disk()
|
|
319
339
|
|
|
320
340
|
async def _add_segment(self, item: RecordedSegment) -> None:
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/probe_fake.py
RENAMED
|
@@ -39,7 +39,7 @@ from agentenv_protocol.computer import (
|
|
|
39
39
|
upload,
|
|
40
40
|
)
|
|
41
41
|
from agentenv_protocol.computer import _linux as linux
|
|
42
|
-
from agentenv_protocol.computer.conformance.checks import STAGE
|
|
42
|
+
from agentenv_protocol.computer.conformance.checks import OWNER, STAGE
|
|
43
43
|
from agentenv_protocol.computer.conformance.page_fixture import QUESTION, TITLE, TWO, TWO_TITLE
|
|
44
44
|
|
|
45
45
|
CLIPBOARD = "agentenv-probe clipboard"
|
|
@@ -56,6 +56,7 @@ DESK_URL = "http://127.0.0.1:4343/"
|
|
|
56
56
|
TITLES = {DESK_URL: TITLE, DESK_URL + TWO.lstrip("/"): TWO_TITLE}
|
|
57
57
|
|
|
58
58
|
|
|
59
|
+
|
|
59
60
|
class FakeDesk:
|
|
60
61
|
"""What the Fixture Desk would record of the input the fake screen gets."""
|
|
61
62
|
|
|
@@ -202,7 +203,7 @@ class FixtureDriver(FakeDriver):
|
|
|
202
203
|
if f"python3 {STAGE}/fixture.py" in text:
|
|
203
204
|
self.desk.start()
|
|
204
205
|
return ExecResult(0, b"4242\n")
|
|
205
|
-
if argv in (["id", "-u"], [
|
|
206
|
+
if argv in (["id", "-u"], [*OWNER, f"{STAGE}/fixture.py"]):
|
|
206
207
|
return ExecResult(0, b"1000\n")
|
|
207
208
|
if argv[:1] in (["kill"], ["tail"]) or f"rm -rf {STAGE}/state" in text:
|
|
208
209
|
return ExecResult(0)
|
|
@@ -320,10 +321,10 @@ class PageFixtureDriver(FixtureDriver):
|
|
|
320
321
|
return ExecResult(0, b"4343") if self.desk.started else ExecResult(1)
|
|
321
322
|
if argv[:1] == ["cat"] and argv[1].endswith("layout.json") and self.desk.started:
|
|
322
323
|
return ExecResult(0, json.dumps(PAGE_LAYOUT).encode())
|
|
323
|
-
if argv == [
|
|
324
|
+
if argv == [*OWNER, f"{STAGE}/page_fixture.py"]:
|
|
324
325
|
return ExecResult(0, b"1000\n")
|
|
325
|
-
if argv == [
|
|
326
|
-
return ExecResult(1, b"", b"
|
|
326
|
+
if argv == [*OWNER, f"{STAGE}/fixture.py"]:
|
|
327
|
+
return ExecResult(1, b"", b"FileNotFoundError: [Errno 2] No such file or directory")
|
|
327
328
|
return super()._fixture(argv)
|
|
328
329
|
|
|
329
330
|
|
|
@@ -6,6 +6,7 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
import asyncio
|
|
8
8
|
import contextlib
|
|
9
|
+
import importlib.util
|
|
9
10
|
import os
|
|
10
11
|
import shlex
|
|
11
12
|
import signal
|
|
@@ -109,6 +110,16 @@ async def test_an_apps_server_is_ready_once_it_launched_the_app_and_each_check_p
|
|
|
109
110
|
assert after["ready"] is True and after["problems"] == []
|
|
110
111
|
|
|
111
112
|
|
|
113
|
+
|
|
114
|
+
@pytest.mark.parametrize("platform, folder", [("linux", "/run/agentenv/apps"), ("darwin", "/tmp/agentenv/apps")])
|
|
115
|
+
def test_a_launch_is_marked_in_a_folder_a_boot_clears_and_the_session_user_writes(monkeypatch, platform, folder):
|
|
116
|
+
monkeypatch.setattr(sys, "platform", platform)
|
|
117
|
+
spec = importlib.util.spec_from_file_location(f"agentenv_protocol.computer._app_runtime_on_{platform}",
|
|
118
|
+
app_runtime.__file__)
|
|
119
|
+
loaded = importlib.util.module_from_spec(spec)
|
|
120
|
+
spec.loader.exec_module(loaded)
|
|
121
|
+
assert loaded.LAUNCHED == Path(folder)
|
|
122
|
+
|
|
112
123
|
@pytest.mark.asyncio
|
|
113
124
|
async def test_checks_that_fail_hang_or_raise_say_so_at_once_without_holding_up_the_server(desktop, monkeypatch):
|
|
114
125
|
monkeypatch.setattr(app_runtime, "CHECK_TIMEOUT_S", 1.0)
|
|
@@ -167,7 +167,7 @@ async def test_each_app_a_driver_fronts_that_exports_is_asked_for_its_export_onc
|
|
|
167
167
|
|
|
168
168
|
@pytest.mark.asyncio
|
|
169
169
|
async def test_a_driver_without_exec_or_data_add_passes_basic_and_leaves_full_unverified():
|
|
170
|
-
report = await _probe(MinimalDriver(FakeScreen(640, 400), platform=Platform(os="
|
|
170
|
+
report = await _probe(MinimalDriver(FakeScreen(640, 400), platform=Platform(os="windows")))
|
|
171
171
|
assert report.passed, _failed(report)
|
|
172
172
|
unverified = [c for c in report.checks if c.status == "unverified"]
|
|
173
173
|
assert {c.check for c in unverified} == {"P3", "P4", "P5", "P6", "P7", "P9"}
|
|
@@ -264,6 +264,9 @@ def test_an_app_declaring_its_skill_twice_is_refused(folder):
|
|
|
264
264
|
"Changed.fonts runs on 'windows', which Changed declares no install for; it declares freebsd, linux"),
|
|
265
265
|
('@ready_check(os="macos")\n def window_shown(self): return True',
|
|
266
266
|
"Changed.window_shown runs on 'macos', which Changed declares no install for"),
|
|
267
|
+
('@install("macos", FreeBSD(), launch=Launch(command=["mail"], window={"class": "Mail"}, '
|
|
268
|
+
'ready=Ready(window=True)))',
|
|
269
|
+
"on macos an app's launch can't wait on its window, which is read from X11"),
|
|
267
270
|
('class BuildSettings(BaseModel): key: SecretStr = SecretStr("")',
|
|
268
271
|
"Changed.BuildSettings holds a secret at properties.key, which its computer's image would keep; declare it in "
|
|
269
272
|
"Settings"),
|
|
@@ -273,9 +276,9 @@ def test_an_app_declaring_its_skill_twice_is_refused(folder):
|
|
|
273
276
|
"Changed.BuildSettings holds a secret at $defs.Settings.properties.password, which"),
|
|
274
277
|
], ids=["no-wait", "no-window", "window-key", "download-sha", "script-escape", "os-skill-twice", "os-build-secret",
|
|
275
278
|
"step-os",
|
|
276
|
-
"check-os", "build-secret", "build-secrets-listed", "build-secret-nested"])
|
|
279
|
+
"check-os", "macos-window-wait", "build-secret", "build-secrets-listed", "build-secret-nested"])
|
|
277
280
|
def test_an_app_whose_declaration_cant_be_checked_is_refused_saying_why(folder, capsys, change, problem):
|
|
278
|
-
decorator, body = (change, "pass") if change.startswith("@linux") else ("", change)
|
|
281
|
+
decorator, body = (change, "pass") if change.startswith(("@linux", "@install(")) else ("", change)
|
|
279
282
|
(folder / "app.py").write_text(APP.format(supports=LINUX, sha='a' * 64) + f"""
|
|
280
283
|
|
|
281
284
|
@computer_app(supports={LINUX})
|
|
@@ -45,6 +45,8 @@ from agentenv_protocol.computer.settings import load_settings # noqa: E402
|
|
|
45
45
|
from agentenv_protocol.computer.tools import _modifiers # noqa: E402
|
|
46
46
|
|
|
47
47
|
MACOS = Platform(os="macos", arch="arm64")
|
|
48
|
+
#: A platform the base class has no OS defaults for.
|
|
49
|
+
WINDOWS = Platform(os="windows", arch="amd64")
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
def _required(namespace: dict) -> dict:
|
|
@@ -130,7 +132,8 @@ def test_set_display_without_modes_is_refused():
|
|
|
130
132
|
def test_a_driver_method_replaces_the_linux_default():
|
|
131
133
|
Driver = _define({"run": run_in_session(lambda self, *a: None)})
|
|
132
134
|
assert declared(Driver)["run_in_session"] == [("run", {})]
|
|
133
|
-
assert declared(MinimalDriver)["run_in_session"] == [("_computer_linux_run_in_session",
|
|
135
|
+
assert declared(MinimalDriver)["run_in_session"] == [("_computer_linux_run_in_session",
|
|
136
|
+
{"os": frozenset({"linux", "macos"})})]
|
|
134
137
|
|
|
135
138
|
|
|
136
139
|
def test_the_platform_is_detected(tmp_path, monkeypatch):
|
|
@@ -143,7 +146,8 @@ def test_the_platform_is_detected(tmp_path, monkeypatch):
|
|
|
143
146
|
assert detect({"WAYLAND_DISPLAY": "wayland-0"}, release).display == "wayland"
|
|
144
147
|
assert detect({}, tmp_path / "missing").as_dict() == {"os": "linux", "arch": "arm64"}
|
|
145
148
|
monkeypatch.setattr("agentenv_protocol.computer.platform.sys.platform", "darwin")
|
|
146
|
-
|
|
149
|
+
monkeypatch.setattr("agentenv_protocol.computer.platform._platform.mac_ver", lambda: ("26.5.2", ("", "", ""), ""))
|
|
150
|
+
assert detect({"DISPLAY": ":0"}, release) == Platform("macos", None, "26.5.2", "arm64", "aqua")
|
|
147
151
|
|
|
148
152
|
|
|
149
153
|
def test_settings_come_from_one_json_value():
|
|
@@ -222,7 +226,7 @@ async def test_a_driver_whose_software_ships_a_skill_leads_with_it_and_the_compu
|
|
|
222
226
|
|
|
223
227
|
@pytest.mark.asyncio
|
|
224
228
|
async def test_a_minimal_driver_declares_only_what_it_has():
|
|
225
|
-
async with http_client(MinimalDriver(platform=
|
|
229
|
+
async with http_client(MinimalDriver(platform=WINDOWS)) as http:
|
|
226
230
|
card = (await http.get("/.well-known/agent-env.json")).json()
|
|
227
231
|
display_set = await http.post("/agentenv/ext/computer-display/set", json={"width": 1, "height": 1})
|
|
228
232
|
exec_run = await http.post("/agentenv/ext/computer-exec/run", json={"argv": ["true"], "request_id": "r"})
|
|
@@ -449,14 +453,14 @@ def test_a_driver_class_declares_what_it_serves_on_each_platform(monkeypatch):
|
|
|
449
453
|
raise AssertionError("declaration builds the card without the subclass's __init__")
|
|
450
454
|
|
|
451
455
|
linux = Declared.declaration(LINUX)
|
|
452
|
-
elsewhere = MinimalDriver.declaration(Platform(os="
|
|
456
|
+
elsewhere = MinimalDriver.declaration(Platform(os="windows"))
|
|
453
457
|
uris = lambda card: {e.uri for e in card.capabilities.extensions} # noqa: E731
|
|
454
458
|
assert linux.name == "declared" and len(linux.capabilities.tools) == 14
|
|
455
459
|
assert {"urn:agentenv:computer-pointer/v1", "urn:agentenv:computer-exec/v1"} <= uris(linux)
|
|
456
460
|
assert elsewhere.name == "MinimalDriver" and len(elsewhere.capabilities.tools) == 7
|
|
457
461
|
assert "urn:agentenv:computer-exec/v1" not in uris(elsewhere)
|
|
458
462
|
computer = next(e for e in elsewhere.capabilities.extensions if e.uri == "urn:agentenv:computer/v1")
|
|
459
|
-
assert computer.params["platform"] == {"os": "
|
|
463
|
+
assert computer.params["platform"] == {"os": "windows"}
|
|
460
464
|
|
|
461
465
|
|
|
462
466
|
def test_a_supports_entry_names_each_platform_it_covers():
|
|
@@ -176,6 +176,27 @@ async def test_the_fallback_polls_capture_and_draws_the_pointer(home):
|
|
|
176
176
|
assert _at(manifest["started_at"]) <= _at(manifest["ended_at"])
|
|
177
177
|
|
|
178
178
|
|
|
179
|
+
@pytest.mark.asyncio
|
|
180
|
+
async def test_a_start_answers_once_its_recording_has_its_first_frame_however_slow_the_capture(home):
|
|
181
|
+
driver = Recorded()
|
|
182
|
+
driver.slow["capture"] = 0.5
|
|
183
|
+
async with http_client(driver) as http:
|
|
184
|
+
began = time.monotonic()
|
|
185
|
+
started = (await http.post(START, json={"request_id": "r", "fps": 10})).json()
|
|
186
|
+
took = time.monotonic() - began
|
|
187
|
+
recording = driver._computer.recordings.running[started["recording_id"]]
|
|
188
|
+
assert took >= 0.5 and recording.encoder is not None and recording.encoder.frames >= 1
|
|
189
|
+
await http.post(END, json={"recording_id": started["recording_id"]})
|
|
190
|
+
|
|
191
|
+
recordings = driver._computer.recordings
|
|
192
|
+
with pytest.raises(TimeoutError):
|
|
193
|
+
await asyncio.wait_for(recordings.start("cancelled", "display", None, 10, None, True, None), 0.1)
|
|
194
|
+
retried = await recordings.start("cancelled", "display", None, 10, None, True, None)
|
|
195
|
+
running = [r for r in recordings.running.values() if not r.done]
|
|
196
|
+
assert [r.id for r in running] == [retried["recording_id"]] and running[0].encoder.frames >= 1
|
|
197
|
+
await http.post(END, json={"recording_id": retried["recording_id"]})
|
|
198
|
+
|
|
199
|
+
|
|
179
200
|
@pytest.mark.asyncio
|
|
180
201
|
async def test_a_driver_without_the_pointer_group_records_without_a_cursor(home):
|
|
181
202
|
_, manifest = await _record(MinimalDriver(), 0.4)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/THIRD_PARTY_NOTICES.md
RENAMED
|
File without changes
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/examples/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/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
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/computer_fake.py
RENAMED
|
File without changes
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/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.455 → agentenv_framework_protocol-0.1.458}/tests/test_a2a_proxy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_client.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
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_errors.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_intake.py
RENAMED
|
File without changes
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/tests/test_manifest.py
RENAMED
|
File without changes
|
{agentenv_framework_protocol-0.1.455 → agentenv_framework_protocol-0.1.458}/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
|