Changelog
Concepts

Workspaces & execution

The sandboxed environment an agent's tools run in, and the executor plane that hosts it.

Agents that touch the real world need somewhere to run commands. A workspace is the sandboxed environment — a filesystem plus a shell — that an agent's tools run in, chosen when the agent is spawned.

What a workspace is

When an agent has workspace tools enabled, bash, read_file, write_file, and friends all operate inside its workspace. The workspace is picked at spawn time and fixed for the agent's life — an agent never switches workspaces mid-story, so "where did this file go" always has one answer.

Like agents, each workspace processes one command at a time. Two commands aimed at the same workspace run back to back, never interleaved — so even agents sharing a workspace can't trample each other mid-command.

Private and shared workspaces

By default every agent gets a private workspace, named after the agent itself — a fresh, isolated environment nobody else touches.

An agent can hand a child a named workspace instead when it spawns it: several agents spawned with the same name get one shared workspace and see the same filesystem. That's the tool for a team of agents collaborating on one checkout — a parent spawns each worker with workspace: "team-build" and they read each other's files, still one command at a time.

A workspace can be chosen at spawn from either side. An agent spawning another sets it with the workspace argument on the spawn_agent tool; a spawn through the gateway sets it with the optional workspaceRef field on POST /api/spawn — a <tenant>/<name>workspace key. Omit it and the new agent gets its own private workspace. The one exception is the teaspill CLI spawn, which has no workspace flag — spawn through the API (or the frontend SDK) when you need to place an agent in a shared workspace from outside.

The executor plane

Workspaces are hosted by the executor — a service plane you deploy alongside your agents, separate from them. It fronts real environments through adapters; the default adapter is Docker: one container per workspace, with a named volume so files persist across commands, container restarts, and idle teardowns.

The separation is deliberate: agent processes scale on how many model conversations you run; the executor fleet scales on how much compute and disk your workspaces demand. Ten thousand chatty agents with no shell access need lots of the former and none of the latter — and vice versa for three agents compiling a monorepo.

Long-running commands

A build that takes twenty minutes doesn't hold anything hostage. While a command runs, its output streams live to a per-workspace output stream — your UI can tail it in real time, the same way it live-follows a timeline. When the command finishes, the agent's tool call returns with the exit code and the tail of the output, and the agent's next step proceeds.

The trust boundary

The default Docker adapter works by mounting the host's Docker socket into the executor — and holding that socket is root-equivalent access to the host machine. This is a reasonable trade for a single-tenant, self-hosted deployment where the executor sits behind the gateway with your own agents; it is not a boundary for running hostile code. Keep the executor internal, never expose it to untrusted callers, and read the hardening options in Self-hosting before production.

The workspace containers themselves are hardened separately — image pinning, per-workspace network isolation — but that protects the workspaces, not the socket. The distinction, and the knobs, are in the Self-hosting guide.

Next steps

Workspaces are where tools run. The engine deciding which tools to call — the model loop itself — is the harness: Harnesses.