Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/agent_env/drivers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,5 +194,30 @@ another ChatGPT version, set `VERSION`, pin the zip's URL and sha256 in `env.tom
path), and take `mcp.json` again from what that version's `cua_repl` says at connect and lists. Name it as
`codex-computer-use`.

`envs/aside/` is At Inc.'s Aside Computer Use as a driver, for the same macOS computers. Its MCP server is Aside's CLI,
`aside mcp --computer-use`, with one tool, `repl`. `repl` runs the agent's JavaScript in a QuickJS sandbox whose only
app API is the `computer` global, with no file system, network or shell. `computer` reads apps' accessibility trees and
acts on them in the background through Aside's daemon and its helper app. `driver.py` pins two of At Inc.'s published
releases: the daemon component as `VERSION`, the CRX Aside's browsers update in the background, and the CLI as
`CLI_VERSION`. The install downloads both from `releases.aside.com` and checks them by sha256, and `install.sh` unpacks
them to `/opt/agentenv/aside/`, links `bin/aside` into the CLI app, and writes the account's settings with usage
analytics off before the daemon first starts. The daemon runs as a direct LaunchAgent of its own executable, since macOS
gives an app's TCC permissions only to the executable launchd starts itself. `[install.macos]` grants Accessibility,
Post Event and Screen Recording to the helper app, to the copy the daemon runs from its home, and to the driver's own
Python. The driver starts one server for each agent session, since the REPL keeps its bindings between calls, with the
session user's environment, Aside's home and the CLI's update check off. A server that stops is started afresh on the
next call, and nothing says when a session ends, so one left unused for 30 minutes, or past the eight kept, is closed,
the least recently used first. Each server gets an `--app` for each app its `allowed_apps` setting names, by name or
bundle identifier, case aside, so `computer.getApp` opens only those, or every app when it names none. Agents get the
server's instructions and its `repl` tool, as `mcp.json` pins them, marked as acting on apps. No Aside sign-in is
needed. Its `computer_*` tools are agent-desktop's, from `MacOSDriver`. `computer-ready` checks the executables' sha256
and that the daemon's health endpoint answers ready. It turns usage analytics off (`aside settings analytics disable`)
and Computer Use on (`aside settings computer-use enable`), then checks that the server gives the instructions and lists
the tool `mcp.json` pins and answers `computer.listApps()`, and the TCC permissions. To move it to other Aside releases,
set `VERSION` and `CLI_VERSION`, pin both downloads' URLs and sha256 in `env.toml` and the executables' in `driver.py`'s
`EXECUTABLES`, and take `mcp.json` again from what that version's server says at connect and lists. A unit test checks
that `env.toml`, `install.sh` and `driver.py` agree on the versions, the folder, the helper and the daemon. Name it as
`aside`.

This bundle has no tasks of its own: other bundles pull its drivers by alias, and `agent-env run drivers` has nothing
to run.
1 change: 1 addition & 0 deletions src/agent_env/drivers/aliases.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ page = ["page"]
agent-desktop = ["agent-desktop"]
macos-harness = ["macos-harness"]
codex-computer-use = ["codex-computer-use"]
aside = ["aside"]
318 changes: 318 additions & 0 deletions src/agent_env/drivers/envs/aside/driver.py

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src/agent_env/drivers/envs/aside/env.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
type = "computer_driver"
module = "driver.py:AsideDriver"
port = 18765

[install.macos]
python = "requirements-macos.txt"
downloads = [
{ url = "https://releases.aside.com/dev-updater/components/1.26.1111.1046/AsideDaemon/mac-arm64/AsideDaemon-1.26.1111.1046.crx", sha256 = "47f54f506f1b8e7abb75d1ca263bb388e5d4e1bd295c3b52e64b5959082744c6", to = "aside-daemon.crx", arch = "arm64" },
{ url = "https://releases.aside.com/cli/AsideCLI-darwin-arm64-1.26.1111.1046.zip", sha256 = "f4b234e8a63eb2a721a9094b7ded1c286d4f253ede3b4eb347c2d3e0ef04765c", to = "aside-cli.zip", arch = "arm64" },
]
run = [{ script = "install.sh", scope = "session" }]
grants = [
{ executable = "venv/bin/python", services = ["accessibility", "post_event", "screen_capture"] },
{ app = "/opt/agentenv/aside/Aside Computer Use.app", services = ["accessibility", "post_event", "screen_capture"] },
{ app = "/opt/agentenv/aside/home/runtime-computer-use/Aside Computer Use.app", services = ["accessibility", "post_event", "screen_capture"] },
]
services = [
{ name = "daemon", command = "'/opt/agentenv/aside/Aside Daemon.app/Contents/MacOS/aside-daemon'", direct = true, environment = { ASIDE_HOME = "/opt/agentenv/aside/home" } },
{ name = "driver", command = "venv/bin/python -m agentenv_protocol.computer.serve driver.py:AsideDriver" },
]
20 changes: 20 additions & 0 deletions src/agent_env/drivers/envs/aside/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh
# The pinned daemon component and CLI, unpacked to where the grants and the daemon service name them, as the session
# user. The helper's runtime copy is placed before the daemon first starts, since macOS keys its approval to that path.
set -eu
daemon=aside-daemon.crx
cli=aside-cli.zip
dest=/opt/agentenv/aside
helper="Aside Computer Use.app"
rm -rf "$dest"
mkdir -p "$dest/bin" "$dest/home/runtime-computer-use"
# A CRX is a signature header and then a zip, which bsdtar reads.
tar -xf "$daemon" -C "$dest"
ditto -x -k "$cli" "$dest"
ln -s "../Aside CLI.app/Contents/MacOS/aside" "$dest/bin/aside"
rm -f "$daemon" "$cli"
xattr -dr com.apple.quarantine "$dest" || true
ditto "$dest/$helper" "$dest/home/runtime-computer-use/$helper"
# Usage analytics are off from the daemon's first start.
mkdir -p "$dest/home/u/0"
printf '%s\n' '{"analytics":{"enabled":false}}' > "$dest/home/u/0/settings.json"
29 changes: 29 additions & 0 deletions src/agent_env/drivers/envs/aside/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"instructions": "Operate native apps on this computer with the repl tool. Start with `await computer.getApp('<app name>')` and follow the guide it prints.",
"tools": [
{
"name": "repl",
"description": "Run JavaScript in a sandbox whose only API is the `computer` global, which reads and controls native apps on this computer. There is no file system, network, shell, or browser. Variables persist between calls. Start with `await computer.getApp('<app name>')`; it prints the app's state and the full usage guide.",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"code": {
"description": "JavaScript to run. Top-level await works.",
"type": "string"
},
"title": {
"description": "Action title, e.g. \"Type the note\".",
"type": "string"
}
},
"required": [
"code"
],
"type": "object"
},
"execution": {
"taskSupport": "forbidden"
}
}
]
}
4 changes: 4 additions & 0 deletions src/agent_env/drivers/envs/aside/requirements-macos.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# What a composed macOS computer installs into the driver's venv: the protocol with MacOSDriver, whose screen and input
# need its macos extra, and the MCP client the forwarded tool reaches Aside's MCP server with. A release pins it to the
# version it ships. Aside is the pinned download, whose executables' sha256 the driver checks.
agentenv-framework-protocol[computer,macos]>=0.1.459
1 change: 1 addition & 0 deletions tst/unit/bundle/shipped_bundles_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def test_the_shipped_env_aliases_name_the_mail_env_the_validator_deploys_the_dri
"agent-desktop": "@local/agentenv-framework/drivers/agent-desktop",
"macos-harness": "@local/agentenv-framework/drivers/macos-harness",
"codex-computer-use": "@local/agentenv-framework/drivers/codex-computer-use",
"aside": "@local/agentenv-framework/drivers/aside",
"chromium": "@local/agentenv-framework/browsers/chromium"}
assert A2AAgent.VALIDATION_ENV_ID == "mail"

Expand Down
Loading
Loading