Cloudbox gives your agent a repo computer. A browser tool gives the same agent Chrome. The model runs in your agent loop; the tools do the work:
model decides -> Cloudbox tools edit repo
-> browser tool inspects page
-> Cloudbox returns HANDOFF.md + receipts
Agent pattern
import { generateText } from "ai";
import { createCloudbox } from "cloudbox/client";
import { agentBrowser } from "agent-browser";
const cloudbox = createCloudbox({ token: process.env.CLOUDBOX_API_TOKEN });
const box = await cloudbox.boot({
repo: "https://github.com/acoyfellow/cloudbox",
});
const browser = await agentBrowser({
// Optional: reuse a Chrome profile when the browser needs login state.
profile: process.env.AGENT_BROWSER_PROFILE,
});
await generateText({
model: yourModel,
tools: {
...box.tools(["shell", "read", "write"]),
...browser.tools(),
},
prompt: `
Open the demo page in the browser.
Use grep/read to find the empty state source.
Edit the repo.
Run tests.
Reopen the page in the browser and verify the change.
Write HANDOFF.md with what changed and how you verified it.
`,
});
const proof = await box.submit("HANDOFF.md");
console.log(proof.artifact.content);
The important boundary: the AI call is outside the browser and outside the Container. The model gets tool results back, then decides the next tool call. Cloudbox tool calls run in the repo computer; browser tool calls run in Chrome.
Minimal Chrome profile support
With the agent-browser CLI, profiles are explicit:
agent-browser profiles
agent-browser --profile Default open https://example.com
For a persistent automation profile:
agent-browser --profile ~/.cloudbox-browser open https://app.example.com/login
# log in once
agent-browser --profile ~/.cloudbox-browser open https://app.example.com/dashboard
Keep profile paths and exported auth state out of git. Browser profiles can contain cookies and tokens.
Smoke test this wiring
Install the browser CLI once:
npm i -g agent-browser
agent-browser install
Run the deterministic smoke:
CLOUDBOX_BROWSER_URL=https://cloudbox.coey.dev \
AGENT_BROWSER_PROFILE=~/.cloudbox-browser \
node scripts/browser-agent-smoke.mjs
The smoke opens /demo, snapshots the page, captures a screenshot, and writes:
artifacts/BROWSER_AGENT.md
This smoke does not call a model. It proves the browser side of the agent loop is available and can inspect the Cloudbox demo. Add your model call on top when you want the full edit-and-verify loop.
Record the browser as an artifact
For UI work, do not rely on the model describing what it saw. Record the browser session and upload the video next to the Cloudbox proof.
Cloudbox returns the repo-side artifact:
HANDOFF.md + runner receipts
The browser smoke returns the browser-side artifact:
BROWSER_AGENT_VIDEO.md + .webm recording + screenshot
Run the video smoke:
CLOUDBOX_BROWSER_URL=https://cloudbox.coey.dev \
node scripts/browser-agent-video-smoke.mjs
It writes:
artifacts/BROWSER_AGENT_VIDEO.md
artifacts/browser-agent-video/*.webm
artifacts/browser-agent-video.png
The script passes only if it can open /demo, find the expected page text, close the browser cleanly, and produce a non-empty .webm file.
Upload the recording from GitHub Actions
- name: Browser video smoke
run: node scripts/browser-agent-video-smoke.mjs
env:
CLOUDBOX_BROWSER_URL: https://cloudbox.coey.dev
- name: Upload browser proof
if: always()
uses: actions/upload-artifact@v4
with:
name: browser-agent-proof
path: |
artifacts/BROWSER_AGENT_VIDEO.md
artifacts/browser-agent-video/*.webm
artifacts/browser-agent-video.png
For the full browser-agent workflow, upload both proof bundles:
Cloudbox proof: HANDOFF.md, runner receipts, work receipts
Browser proof: .webm recording, screenshot, browser smoke markdown
That gives reviewers both sides: what changed in the repo and what the agent actually saw in Chrome.