Document Agentbox runtime and model workflow

Co-authored-by: codegirl007 <codegirl-007@users.noreply.github.com>
This commit is contained in:
Cursor Agent
2026-08-17 16:47:22 +00:00
co-authored by codegirl007
parent 94146fcae2
commit e9197798f9
2 changed files with 123 additions and 53 deletions
+82 -37
View File
@@ -1,13 +1,16 @@
# Agentbox Phase 1 # Agentbox
This is a local technical spike for a programmable graphical Linux This is a local technical spike for a programmable graphical Linux
environment. It proves that a controller can launch an ordinary GUI process environment. It proves that a controller can launch an ordinary GUI process
headlessly, observe pixels, inject keyboard and mouse input, and shut the headlessly, observe pixels and logs, inject keyboard and mouse input, drive the
application through a replaceable agent, record a trace, and shut the
environment down. environment down.
Phase 1 does not contain an LLM, model provider, cloud control plane, or The default agent is deterministic and requires no API credentials. One
production sandbox. See [the architecture decision](docs/architecture.md) for optional OpenAI Responses adapter demonstrates screenshot + text model control.
the choices and security boundary. This is still a local spike, not a cloud control plane or production sandbox.
See [the architecture decision](docs/architecture.md) for the choices and
security boundary.
## Requirements ## Requirements
@@ -19,41 +22,78 @@ the choices and security boundary.
No X server, window manager, or C compiler is required on the host; those No X server, window manager, or C compiler is required on the host; those
dependencies are built into the container image. dependencies are built into the container image.
## Run the proof ## One-command demo
From this directory: From this directory:
```sh ```sh
make phase1 make demo
``` ```
That one command: That one command:
1. builds the local environment image; 1. builds the `agentbox` CLI and mover executable;
2. starts a restricted container with Xvfb and Openbox; 2. creates a restricted Xvfb/Openbox environment;
3. launches the mover application; 3. stages and launches the executable;
4. captures `before.png`; 4. runs the deterministic observe/press/wait/release/observe loop;
5. moves and clicks the mouse; 5. records screenshots, actions, decisions, logs, and final status;
6. holds the RIGHT key for one second; 6. stops and removes the environment, including on failure or interruption.
7. captures `after.png`;
8. locates the green square in both images and fails unless it moved at least
100 pixels right;
9. stops and removes the container, including on failure or interruption.
A passing run ends with output similar to: The equivalent explicit commands are:
```text ```sh
Capturing screenshot before input... make build demo-binary
Sending synthetic mouse input... ./agentbox run ./examples/mover \
Holding RIGHT for one second... --task "Launch the application, move the character to the right, and describe what happened."
Capturing screenshot after input...
Verified: square moved 180.0 pixels to the right.
Phase 1 passed. Artifacts: .../.agentbox/runs/20260817T...
Stopping environment...
Environment stopped cleanly.
``` ```
## Artifacts Flags can appear before or after the path.
## Run a private executable
Pass a prebuilt Linux executable:
```sh
./agentbox run ./path/to/application --task "Open the menu and click Settings."
```
For a directory, add `agentbox.json`:
```json
{
"command": "game",
"args": ["--windowed"],
"env": {"EXAMPLE": "value"},
"window_title": "My Game"
}
```
The command is resolved relative to the manifest. The current runtime is
Debian-based, so dynamically linked executables must have compatible libraries.
## Model agent
The model adapter is opt-in:
```sh
export OPENAI_API_KEY="..."
./agentbox run ./path/to/application \
--task "Move the character right and report the result." \
--agent openai \
--model gpt-5
```
Each request contains the task, current screenshot, previous actions, step
history, and recent application logs. Strict structured output allows one
backend-neutral input action or completion. Use `--max-steps` to bound a run.
The environment itself still has no network access.
## Runs and inspection
```sh
./agentbox runs
./agentbox inspect <run-id>
```
Each run writes: Each run writes:
@@ -61,17 +101,25 @@ Each run writes:
.agentbox/runs/<run-id>/ .agentbox/runs/<run-id>/
├── run.json ├── run.json
├── actions.jsonl ├── actions.jsonl
├── steps.jsonl
├── screenshots/ ├── screenshots/
│ ├── before.png │ ├── 0001.png
│ └── after.png │ └── ...
├── stdout.log ├── stdout.log
└── stderr.log └── stderr.log
``` ```
`run.json` contains the measured before/after centroids, movement distance, `run.json` has `schema_version: "1"` plus task, application, agent, timestamps,
container-engine version, timestamps, and pass/fail status. `actions.jsonl` status, and step count. `steps.jsonl` records each observation reference, agent
contains the backend-neutral input actions sent during this proof. Application message, and action. `actions.jsonl` is a compact action-only stream.
output is copied from the container before it is destroyed.
## Original environment proof
The visual centroid test from Phase 1 remains available:
```sh
make phase1
```
## Development checks ## Development checks
@@ -79,6 +127,3 @@ output is copied from the container before it is destroyed.
make test make test
go vet ./... go vet ./...
``` ```
The future `agentbox run <path> --task ...` flow belongs to Phases 2 and 3.
This branch intentionally stops after proving the environment mechanism.
+41 -16
View File
@@ -1,6 +1,6 @@
# Phase 1 architecture decision # Agentbox spike architecture decision
Status: accepted for the local spike Status: implemented for Phases 14 of the local spike
## Decision ## Decision
@@ -12,10 +12,10 @@ Run one application environment per Docker container. Inside the container:
- `scrot` captures the complete display as PNG. - `scrot` captures the complete display as PNG.
- `xdotool` injects keyboard and mouse events through X11's XTEST extension. - `xdotool` injects keyboard and mouse events through X11's XTEST extension.
The Go process on the host owns the lifecycle. It builds and creates the The Go control plane on the host owns the lifecycle. It builds and creates the
container, starts the display, launches the application as a separate step, container, starts the display, launches the application as a separate step,
captures images, sends input, copies artifacts out, and removes the container. captures images, sends input, copies artifacts out, and removes the container.
The first spike intentionally uses the Docker CLI as its narrow adapter rather The spike intentionally uses the Docker CLI as its narrow adapter rather
than adding a Docker SDK dependency. than adding a Docker SDK dependency.
```text ```text
@@ -79,23 +79,48 @@ source or package dependency without changing the tested path. The runtime is
not coupled to Xlib: any executable in a future staged image can use SDL, not coupled to Xlib: any executable in a future staged image can use SDL,
Raylib, Qt, GTK, a browser, or another X11-compatible toolkit. Raylib, Qt, GTK, a browser, or another X11-compatible toolkit.
## Separation preserved for later phases ## Runtime separation
Phase 1 contains concrete orchestration, but its data flow already keeps these The implemented data flow keeps these roles distinct:
roles distinct:
```text ```text
CLI -> lifecycle controller -> container environment -> application CLI -> runtime controller -> Environment -> application
| | |
observation/input | observation/input/logs
| |
deterministic driver Agent
|
deterministic or OpenAI
|
versioned trace
``` ```
Phase 2 should extract lifecycle, screenshot, input, and logs into an `internal/environment` defines lifecycle, screenshot, input, and log contracts
`Environment` interface with backend-neutral actions. Phase 3 should consume with backend-neutral actions. `internal/environment/dockerx11` is the only
that interface through an `Agent`; neither a deterministic agent nor a model package that knows about Docker, X11, `scrot`, or `xdotool`.
adapter should import Docker or X11 details.
`internal/agent` defines observations, history, and decisions. The deterministic
agent and optional OpenAI Responses adapter both implement that interface; they
do not import the Docker backend. The model adapter receives the task, current
PNG, action history, and recent logs, then returns one schema-constrained
action. It is intentionally one concrete adapter, not a provider framework.
`internal/runtime` connects those interfaces and contains no provider or X11
logic. `internal/trace` records versioned metadata plus append-only step and
action streams. Screenshots remain separate PNG files referenced by relative
path, which keeps traces readable and suitable for later replay or comparison.
## Application staging
`agentbox run` accepts one prebuilt Linux executable. A directory can contain
an `agentbox.json` manifest naming that executable, arguments, environment
variables, and an optional window title. The Docker backend streams the file
into the environment's tmpfs and makes it executable; no host directory is
mounted into the container.
The executable and its libraries must be compatible with the Debian-based
runtime image. Packaging arbitrary dependency trees is a separate upload/build
format problem and is not hidden by this spike.
## Security boundary ## Security boundary