agentenv-framework-protocol 0.1.404__tar.gz → 0.1.406__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.404 → agentenv_framework_protocol-0.1.406}/PKG-INFO +49 -11
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/README.md +48 -10
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/pyproject.toml +1 -1
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/__init__.py +10 -2
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/_declare.py +2 -1
- agentenv_framework_protocol-0.1.406/src/agentenv_protocol/computer/app.py +482 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/driver.py +3 -3
- agentenv_framework_protocol-0.1.406/src/agentenv_protocol/computer/run_install_step.py +43 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/probe_fake.py +1 -1
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_app_server.py +14 -5
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_dataplane.py +1 -1
- agentenv_framework_protocol-0.1.406/tests/test_computer_declare.py +362 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_extensions.py +4 -4
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_serve.py +57 -2
- agentenv_framework_protocol-0.1.404/src/agentenv_protocol/computer/app.py +0 -240
- agentenv_framework_protocol-0.1.404/tests/test_computer_declare.py +0 -241
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/.gitignore +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/LICENSE +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/NOTICE +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/THIRD_PARTY_NOTICES.md +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/examples/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/examples/advanced_agent.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/examples/basic_agent.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/examples/custom_extensions_agent.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/examples/multimodal_agent.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/examples/reference_model.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/examples/streaming_agent.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/_trajectory_log.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/_triggers.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/extensions.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/framework.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/peer_agents.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/proxy.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/registry.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/staging.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/tasks/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/a2a_agent/tasks/v1.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/agent_env_environment.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/client.py +0 -0
- /agentenv_framework_protocol-0.1.404/src/agentenv_protocol/computer/linux.py → /agentenv_framework_protocol-0.1.406/src/agentenv_protocol/computer/_linux.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/_load.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/app_runtime.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/apps.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/card.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/checks.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/conformance/__init__.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/conformance/__main__.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/conformance/checks.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/conformance/client.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/conformance/fixture.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/conformance/mp4.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/conformance/report.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/dataplane.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/errors.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/extensions.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/frames.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/keys.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/launch.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/manifest.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/operations.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/platform.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/queue.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/recording.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/results.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/runtime.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/serve.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/serve_app.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/session.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/settings.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/skill.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/spaces.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/computer/tools.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/errors.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/manifest.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/preflight.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/tool_access.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/tool_client.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/tool_context.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/transfers.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/src/agentenv_protocol/types.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/computer_fake.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_a2a_agent.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_a2a_agent_examples.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_a2a_object_transfers.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_a2a_peer_agents.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_a2a_proxy.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_a2a_staging.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_a2a_trajectory_log.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_agent_env_environment.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_client.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_conformance.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_conformance_checks.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_conformance_recording.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_driver.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_frames.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_queue.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_recording.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_computer_spaces.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_data_objects.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_errors.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_extension_methods.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_intake.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_manifest.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_preflight.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_tool_access.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_tool_annotations.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_tool_client.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_tool_context.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_tool_context_fastmcp.py +0 -0
- {agentenv_framework_protocol-0.1.404 → agentenv_framework_protocol-0.1.406}/tests/test_tool_context_injection.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.406
|
|
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
|
|
@@ -671,37 +671,75 @@ server, which needs the `app` extra (below).
|
|
|
671
671
|
|
|
672
672
|
```python
|
|
673
673
|
from pydantic import BaseModel, SecretStr
|
|
674
|
-
from agentenv_protocol.computer import ComputerAppEnvironment, Launch,
|
|
674
|
+
from agentenv_protocol.computer import (ComputerAppEnvironment, Launch, Packages, Service, computer_app,
|
|
675
|
+
install_step, linux)
|
|
676
|
+
|
|
677
|
+
class LinuxSettings(BaseModel):
|
|
678
|
+
font: str = "DejaVu Sans"
|
|
675
679
|
|
|
676
680
|
@computer_app(supports=[{"os": {"type": "linux", "display": ["x11"]}, "arch": ["amd64", "arm64"]}])
|
|
681
|
+
@linux(packages=Packages(apt=["thunderbird"]), python="requirements.txt",
|
|
682
|
+
services=[Service(name="imap", command="venv/bin/python imap.py")],
|
|
683
|
+
launch=Launch(command=["thunderbird"], window={"class": "thunderbird"}), settings=LinuxSettings)
|
|
677
684
|
class MailApp(ComputerAppEnvironment):
|
|
678
|
-
linux = Linux(python="requirements.txt", services=[Service(name="imap", command="venv/bin/python imap.py")])
|
|
679
|
-
launch = Launch(command=["thunderbird"], window={"class": "thunderbird"})
|
|
680
685
|
skill = "skill.md"
|
|
681
686
|
|
|
682
687
|
class Settings(BaseModel):
|
|
683
688
|
signature: str = ""
|
|
684
689
|
password: SecretStr = SecretStr("")
|
|
690
|
+
|
|
691
|
+
class BuildSettings(BaseModel):
|
|
692
|
+
locale: str = "en_US"
|
|
693
|
+
|
|
694
|
+
@install_step(scope="session")
|
|
695
|
+
def profile(self) -> None: ...
|
|
685
696
|
```
|
|
686
697
|
|
|
687
698
|
- **`@computer_app`** names the platforms the app supports, as a driver names them, and the
|
|
688
699
|
`permissions` it needs of the computer. Its env.toml names the rest: the app itself
|
|
689
|
-
(`environment_name`)
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
700
|
+
(`environment_name`), the `computer` and `driver` it deploys alone on, and `build_settings`, its
|
|
701
|
+
build settings' values (`build_settings = { locale = "fr_FR" }`).
|
|
702
|
+
- **`@linux(...)`** is how a Linux computer installs it, `Linux`'s fields: `files`, a folder of the app's
|
|
703
|
+
copied under its prefix, which holds the class's file; `packages`, the OS's, as apt takes them
|
|
704
|
+
(`Packages(apt=["name", "name=version", "name/suite"])`); `python`, a requirements file there,
|
|
705
|
+
installed into the venv every app gets beside them; `sources`, extra apt repositories
|
|
706
|
+
(`AptSource`, with a key file in the folder); `downloads`, files fetched by URL and checked by
|
|
707
|
+
sha256 (`Download`); `run`, scripts of the folder run as root or the session user (`RunScript`);
|
|
708
|
+
`services`, programs the computer's init runs from the prefix as the session user; and `ports`,
|
|
709
|
+
those it listens on. Packages, requirements and downloads are resolved and fetched once, when the
|
|
710
|
+
computer env is put, and every build installs only those stored files, with the network closed.
|
|
711
|
+
Each value is checked as the class is defined: a URL, a sha256, a path that stays in the folder.
|
|
712
|
+
Installs are exact: apt installs each package without its recommends, and the venv gets exactly
|
|
713
|
+
the wheels resolved for it (`pip install --no-deps`). A requirements file lists everything itself,
|
|
714
|
+
since its lock covers that file alone: a line including another file (`-r`, `-c`), an editable
|
|
715
|
+
install (`-e`), a local path or a local folder of wheels is refused at put.
|
|
716
|
+
- **Each OS has its own decorator,** and what differs by OS goes in it: `launch=` always; and
|
|
717
|
+
optionally `skill=`, a file used instead of the class's, and `settings=` and `build_settings=`,
|
|
718
|
+
models whose fields add to the class's `Settings` and `BuildSettings` on that OS. What's on the
|
|
719
|
+
class applies to every OS. `@install(os_type, spec, launch=..., ...)` is the generic form, for an
|
|
720
|
+
OS type a plugin adds, with that OS type's own install model as `spec`; `@linux(...)` is
|
|
721
|
+
`@install("linux", Linux(...), ...)`. On the computer the class reads what's declared for the OS
|
|
722
|
+
it runs on (`platform.detect()`).
|
|
723
|
+
- **`launch=Launch(...)`** says how it starts in the desktop session: with it (`at="boot"`) or when
|
|
695
724
|
the agent opens it (`"demand"`). `ready=Ready(...)` says when it's ready, within `timeout_s` of its
|
|
696
725
|
launch: a window matching `launch.window` by its class, instance or title, a port answering on
|
|
697
726
|
loopback, or a command exiting 0. `@ready_check` marks a method for readiness that needs logic (a
|
|
698
727
|
sync one runs in a thread), and `@install_step(scope=...)` one a computer runs as it installs the
|
|
699
|
-
app
|
|
728
|
+
app, after its run scripts, offline and without the class's `__init__`. Each runs on every OS the
|
|
729
|
+
app installs on, or on those its `os=` names (`@install_step(os="linux")`, `@ready_check(os=[...])`);
|
|
730
|
+
naming one the app declares no install for is refused when the class is read. A step reads
|
|
731
|
+
`self.build_settings`; a deploy's `self.settings` aren't known at build, and reading one raises
|
|
732
|
+
`AttributeError` (`python -m agentenv_protocol.computer.run_install_step <file>:<Class> <method>`).
|
|
700
733
|
- **Its skill** is a file of its folder (`skill = "skill.md"`) or an `@agent_skill` method, not both;
|
|
701
734
|
its data hooks are the usual `@add_data`, `@get_data` and `@reset_data`.
|
|
702
735
|
- **`Settings`** is typed; a computer hands each app the values a deploy gives it, as one JSON value
|
|
703
736
|
in `APP_SETTINGS_ENV` (`AGENTENV_APP_SETTINGS`, the apps' values by name), and the base class reads
|
|
704
737
|
its own, by `ENVIRONMENT_NAME`, as `self.settings`. A `SecretStr` field is a secret.
|
|
738
|
+
- **`BuildSettings`** is typed too: values the app's env fixes in its computer's image, which only
|
|
739
|
+
another image changes, so a deploy can't give one. The composer writes them to
|
|
740
|
+
`.agentenv/build_settings.json` in the app's folder, and the base class reads them, over the
|
|
741
|
+
defaults, as `self.build_settings`, in its install steps and on the computer alike. None is a
|
|
742
|
+
secret, since the image keeps them; `declaration()` refuses a `SecretStr` one.
|
|
705
743
|
|
|
706
744
|
On a computer each app is its own server: `python -m agentenv_protocol.computer.serve_app
|
|
707
745
|
<file>:<Class>`, a program the computer's init runs from the app's folder in the app's venv, which
|
|
@@ -615,37 +615,75 @@ server, which needs the `app` extra (below).
|
|
|
615
615
|
|
|
616
616
|
```python
|
|
617
617
|
from pydantic import BaseModel, SecretStr
|
|
618
|
-
from agentenv_protocol.computer import ComputerAppEnvironment, Launch,
|
|
618
|
+
from agentenv_protocol.computer import (ComputerAppEnvironment, Launch, Packages, Service, computer_app,
|
|
619
|
+
install_step, linux)
|
|
620
|
+
|
|
621
|
+
class LinuxSettings(BaseModel):
|
|
622
|
+
font: str = "DejaVu Sans"
|
|
619
623
|
|
|
620
624
|
@computer_app(supports=[{"os": {"type": "linux", "display": ["x11"]}, "arch": ["amd64", "arm64"]}])
|
|
625
|
+
@linux(packages=Packages(apt=["thunderbird"]), python="requirements.txt",
|
|
626
|
+
services=[Service(name="imap", command="venv/bin/python imap.py")],
|
|
627
|
+
launch=Launch(command=["thunderbird"], window={"class": "thunderbird"}), settings=LinuxSettings)
|
|
621
628
|
class MailApp(ComputerAppEnvironment):
|
|
622
|
-
linux = Linux(python="requirements.txt", services=[Service(name="imap", command="venv/bin/python imap.py")])
|
|
623
|
-
launch = Launch(command=["thunderbird"], window={"class": "thunderbird"})
|
|
624
629
|
skill = "skill.md"
|
|
625
630
|
|
|
626
631
|
class Settings(BaseModel):
|
|
627
632
|
signature: str = ""
|
|
628
633
|
password: SecretStr = SecretStr("")
|
|
634
|
+
|
|
635
|
+
class BuildSettings(BaseModel):
|
|
636
|
+
locale: str = "en_US"
|
|
637
|
+
|
|
638
|
+
@install_step(scope="session")
|
|
639
|
+
def profile(self) -> None: ...
|
|
629
640
|
```
|
|
630
641
|
|
|
631
642
|
- **`@computer_app`** names the platforms the app supports, as a driver names them, and the
|
|
632
643
|
`permissions` it needs of the computer. Its env.toml names the rest: the app itself
|
|
633
|
-
(`environment_name`)
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
644
|
+
(`environment_name`), the `computer` and `driver` it deploys alone on, and `build_settings`, its
|
|
645
|
+
build settings' values (`build_settings = { locale = "fr_FR" }`).
|
|
646
|
+
- **`@linux(...)`** is how a Linux computer installs it, `Linux`'s fields: `files`, a folder of the app's
|
|
647
|
+
copied under its prefix, which holds the class's file; `packages`, the OS's, as apt takes them
|
|
648
|
+
(`Packages(apt=["name", "name=version", "name/suite"])`); `python`, a requirements file there,
|
|
649
|
+
installed into the venv every app gets beside them; `sources`, extra apt repositories
|
|
650
|
+
(`AptSource`, with a key file in the folder); `downloads`, files fetched by URL and checked by
|
|
651
|
+
sha256 (`Download`); `run`, scripts of the folder run as root or the session user (`RunScript`);
|
|
652
|
+
`services`, programs the computer's init runs from the prefix as the session user; and `ports`,
|
|
653
|
+
those it listens on. Packages, requirements and downloads are resolved and fetched once, when the
|
|
654
|
+
computer env is put, and every build installs only those stored files, with the network closed.
|
|
655
|
+
Each value is checked as the class is defined: a URL, a sha256, a path that stays in the folder.
|
|
656
|
+
Installs are exact: apt installs each package without its recommends, and the venv gets exactly
|
|
657
|
+
the wheels resolved for it (`pip install --no-deps`). A requirements file lists everything itself,
|
|
658
|
+
since its lock covers that file alone: a line including another file (`-r`, `-c`), an editable
|
|
659
|
+
install (`-e`), a local path or a local folder of wheels is refused at put.
|
|
660
|
+
- **Each OS has its own decorator,** and what differs by OS goes in it: `launch=` always; and
|
|
661
|
+
optionally `skill=`, a file used instead of the class's, and `settings=` and `build_settings=`,
|
|
662
|
+
models whose fields add to the class's `Settings` and `BuildSettings` on that OS. What's on the
|
|
663
|
+
class applies to every OS. `@install(os_type, spec, launch=..., ...)` is the generic form, for an
|
|
664
|
+
OS type a plugin adds, with that OS type's own install model as `spec`; `@linux(...)` is
|
|
665
|
+
`@install("linux", Linux(...), ...)`. On the computer the class reads what's declared for the OS
|
|
666
|
+
it runs on (`platform.detect()`).
|
|
667
|
+
- **`launch=Launch(...)`** says how it starts in the desktop session: with it (`at="boot"`) or when
|
|
639
668
|
the agent opens it (`"demand"`). `ready=Ready(...)` says when it's ready, within `timeout_s` of its
|
|
640
669
|
launch: a window matching `launch.window` by its class, instance or title, a port answering on
|
|
641
670
|
loopback, or a command exiting 0. `@ready_check` marks a method for readiness that needs logic (a
|
|
642
671
|
sync one runs in a thread), and `@install_step(scope=...)` one a computer runs as it installs the
|
|
643
|
-
app
|
|
672
|
+
app, after its run scripts, offline and without the class's `__init__`. Each runs on every OS the
|
|
673
|
+
app installs on, or on those its `os=` names (`@install_step(os="linux")`, `@ready_check(os=[...])`);
|
|
674
|
+
naming one the app declares no install for is refused when the class is read. A step reads
|
|
675
|
+
`self.build_settings`; a deploy's `self.settings` aren't known at build, and reading one raises
|
|
676
|
+
`AttributeError` (`python -m agentenv_protocol.computer.run_install_step <file>:<Class> <method>`).
|
|
644
677
|
- **Its skill** is a file of its folder (`skill = "skill.md"`) or an `@agent_skill` method, not both;
|
|
645
678
|
its data hooks are the usual `@add_data`, `@get_data` and `@reset_data`.
|
|
646
679
|
- **`Settings`** is typed; a computer hands each app the values a deploy gives it, as one JSON value
|
|
647
680
|
in `APP_SETTINGS_ENV` (`AGENTENV_APP_SETTINGS`, the apps' values by name), and the base class reads
|
|
648
681
|
its own, by `ENVIRONMENT_NAME`, as `self.settings`. A `SecretStr` field is a secret.
|
|
682
|
+
- **`BuildSettings`** is typed too: values the app's env fixes in its computer's image, which only
|
|
683
|
+
another image changes, so a deploy can't give one. The composer writes them to
|
|
684
|
+
`.agentenv/build_settings.json` in the app's folder, and the base class reads them, over the
|
|
685
|
+
defaults, as `self.build_settings`, in its install steps and on the computer alike. None is a
|
|
686
|
+
secret, since the image keeps them; `declaration()` refuses a `SecretStr` one.
|
|
649
687
|
|
|
650
688
|
On a computer each app is its own server: `python -m agentenv_protocol.computer.serve_app
|
|
651
689
|
<file>:<Class>`, a program the computer's init runs from the app's folder in the app's venv, which
|
|
@@ -11,13 +11,20 @@ from typing import TYPE_CHECKING, Any
|
|
|
11
11
|
from .app import (
|
|
12
12
|
APP_SETTINGS_ENV,
|
|
13
13
|
AppDeclaration,
|
|
14
|
+
AppOs,
|
|
15
|
+
AptSource,
|
|
14
16
|
ComputerAppEnvironment,
|
|
17
|
+
Download,
|
|
15
18
|
Launch,
|
|
16
19
|
Linux,
|
|
20
|
+
Packages,
|
|
17
21
|
Ready,
|
|
22
|
+
RunScript,
|
|
18
23
|
Service,
|
|
19
24
|
computer_app,
|
|
25
|
+
install,
|
|
20
26
|
install_step,
|
|
27
|
+
linux,
|
|
21
28
|
ready_check,
|
|
22
29
|
)
|
|
23
30
|
from .errors import (
|
|
@@ -97,8 +104,9 @@ def __getattr__(name: str) -> Any:
|
|
|
97
104
|
|
|
98
105
|
__all__ = [
|
|
99
106
|
"ComputerDriverEnvironment", "computer_driver", "DEFAULT_IDENTITY", "DriverDeclaration",
|
|
100
|
-
"ComputerAppEnvironment", "computer_app", "
|
|
101
|
-
"
|
|
107
|
+
"ComputerAppEnvironment", "computer_app", "install", "linux", "install_step", "ready_check", "Linux", "Service",
|
|
108
|
+
"Launch", "Ready", "Packages", "AptSource", "Download", "RunScript",
|
|
109
|
+
"AppDeclaration", "AppOs",
|
|
102
110
|
"APP_SETTINGS_ENV",
|
|
103
111
|
"Display", "Image", "Effect", "ExecResult", "ReadyCheck", "Platform", "ComputerSettings", "SETTINGS_ENV",
|
|
104
112
|
"PRINTABLE_KEYS",
|
|
@@ -98,7 +98,8 @@ def main(argv: list[str]) -> int:
|
|
|
98
98
|
with contextlib.redirect_stdout(sys.stderr):
|
|
99
99
|
declared = declare(Path(folder), file, name)
|
|
100
100
|
except ValidationError as e:
|
|
101
|
-
print("ValueError: " + "; ".join(
|
|
101
|
+
print("ValueError: " + "; ".join(f"{'.'.join([e.title, *map(str, error['loc'])])}: "
|
|
102
|
+
f"{error['msg'].removeprefix('Value error, ')}" for error in e.errors()),
|
|
102
103
|
file=sys.stderr)
|
|
103
104
|
return 1
|
|
104
105
|
except Exception as e:
|