Skip to content
Closed
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
17 changes: 17 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,20 @@ COMPUTER_RUNTIME=
# that granted the tool, which is where the grant, the policy and the audit row are. Absent, no Bot
# may call tools back and it is told so rather than being quietly allowed.
AGENT_TOOL_TOKEN=

# Remote computers on Daytona (https://daytona.io). Set an API key and every Bot gets a cloud
# sandbox of its own -- no local Docker needed for computers. Get a key at https://app.daytona.io
# under Dashboard -> Keys. Requires COMPUTER_TOKEN above, because a Daytona computer is reached
# over a public preview URL and the token is what refuses strangers ("/health" is the only
# unauthenticated route). Mutually exclusive with COMPUTER_SUPERVISOR_URL. AGENT_COMPUTER_URL is
# not needed in this mode.
#
# The first start builds a snapshot from agent-computer/ (a few minutes, streamed to the server
# log); later computers start from it in seconds. Idle computers stop after 15 minutes and wake
# on the next action.
# DAYTONA_API_KEY=
# Only for self-hosted or staging Daytona; the default is the hosted platform.
# DAYTONA_API_URL=
# DAYTONA_TARGET=
# Use a prebuilt snapshot by name instead of building from the local sources.
# DAYTONA_SNAPSHOT=
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ A Bot is any endpoint speaking [AG-UI](https://github.com/ag-ui-protocol/ag-ui),

## Requirements

- Docker, for PostgreSQL, browser computers, the supervisor, and the shipped Bots.
- Docker, for PostgreSQL and the shipped Bots. Bot computers can run locally on Docker or remotely on Daytona (set DAYTONA_API_KEY).
- [Bun](https://bun.sh) 1.3+, for the app and API server.
- A CopilotKit Intelligence project and license. A free plan is available, and Intelligence can be self-hosted.
- A model key. The proof-of-concept Bot uses OpenAI; the LangGraph Bot can use OpenAI, Anthropic, or Google.
Expand Down Expand Up @@ -124,7 +124,7 @@ A Bot is any endpoint speaking [AG-UI](https://github.com/ag-ui-protocol/ag-ui),

## Features

- **A computer per Bot**: the supervisor gives each Bot its own container, its own `/workspace` volume and its own browser profile. Set `COMPUTER_RUNTIME=runsc` to run them under gVisor where the host supports it.
- **A computer per Bot**: the supervisor gives each Bot its own container, its own `/workspace` volume and its own browser profile. Set `COMPUTER_RUNTIME=runsc` to run them under gVisor where the host supports it. Or set `DAYTONA_API_KEY` to run each computer in a remote Daytona sandbox instead of a local container.
- **The gateway is the only way in**: it resolves the target from a server-held snapshot, evaluates the policy, writes the audit row, and only then calls the computer. There is no path that acts without the record existing first.
- **CEL policy, fail closed**: rules can inspect `tool.name`, `intent`, `bot.id`, `actor.id`, `page.url`, `page.host`, `element.*`, `key`, `file.*` and `mcp.*`. Deny is evaluated before allow, a missing policy permits nothing, and a broken rule refuses rather than opens.
- **Take the wheel**: a Bot that hits a login wall or a 2FA prompt asks for help. Control is handed over in the same panel and recorded as `computer.help_requested`, `computer.control_taken` and `computer.control_released`. While a person is driving, Bot actions are refused rather than queued.
Expand Down Expand Up @@ -180,6 +180,7 @@ Settings worth knowing:
| `COMPUTER_TOKEN` | Secret every Bot computer request must present. `start.sh` sets one. |
| `SUPERVISOR_TOKEN` | Secret the supervisor requires. `start.sh` sets one. |
| `COMPUTER_SUPERVISOR_URL` | Gives each Bot a computer of its own instead of one shared computer. |
| `DAYTONA_API_KEY` | Runs each Bot's computer in a remote Daytona sandbox instead of local Docker. |
| `COMPUTER_RUNTIME` | Set to `runsc` to run computers under gVisor, where the host has it. |
| `AGENT_COMPUTER_POLICY` | JSON action policy. Malformed JSON stops server startup. |
| `AGENT_COMPUTER_ALLOW_PRIVATE_HOSTS` | Lets a Bot reach this machine's own services. |
Expand Down
2 changes: 1 addition & 1 deletion agent-computer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# The Bot's computer uses Playwright's image so Chromium and its system libraries stay matched.
#
# The image tag and Playwright dependency must be pinned to the same exact version. Bump both or
# neither.
# neither. Also keep aligned with the Daytona Image recipe in server/src/computer/daytona.ts.
FROM mcr.microsoft.com/playwright:v1.62.1-noble

# unzip is not in the Playwright image and bun's installer needs it.
Expand Down
10 changes: 6 additions & 4 deletions app/src/routes/_authed/admin/computers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type ComputerProfile = {
botId: string;
running: boolean;
startedAt: string | null;
egress: string | null;
egress?: string | null;
};

/** API placeholder id; the list endpoint returns all computers. */
Expand Down Expand Up @@ -159,9 +159,11 @@ function ComputersPage() {
? `Browser running since ${new Date(computer.startedAt ?? "").toLocaleTimeString()}`
: "No browser running. It starts when the Bot next needs it."}
{" · "}
{computer.egress
? `Leaves through ${computer.egress}`
: "Leaves directly"}
{computer.egress === undefined
? "Egress not reported"
: computer.egress === null
? "Leaves directly"
: `Leaves through ${computer.egress}`}
</ItemDescription>
</ItemContent>
<ItemActions>
Expand Down
Loading