What agents need from computers
Just like people, agents need good interfaces to get things done. But agents aren't people, and the interfaces they need have different constraints. Here's what we've learned building them at Freestyle.
Your computer is in a state. Apps open, services logged in, maybe Chappell Roan on Spotify. You don't manage that state directly, you manage it through interfaces. Windows, menus, the dock, the little green dot that means your mic is on.
Agents need interfaces too. If an agent is going to write code, it needs a way to read what's already there and write something new. If it's going to modify a spreadsheet or search the web, same thing — it needs to perceive state and act on it.
The answer is going to look a lot like what we already have: an operating system and some applications. But the interfaces we use are tuned for humans, and agents are different:
- Text is cheap, pixels are expensive. We can glance at a well-designed dashboard and instantly process it. Agents think in tokens, and tokens map way better to text than to pixels.
- State changes are slow. Your monitor refreshes 60 times a second so you can track your cursor. An agent only notices the world has changed when it makes a tool call, maybe every few seconds.
- There can be many of them. You are one person doing one thing. An agent can fan out into subagents, each working in parallel on the same problem or different ones.
Each of these reshapes what a good interface looks like. The rest of this post is about what we've learned building them at Freestyle.
How much computer?
The industry has converged on a spectrum. On one end, give the agent a handful of tool calls and nothing else. On the other end, hand it a full computer, something like a Linux VM in the cloud and interface it with bash and computer use. In between, Cloudflare advocates agents generating dynamic TypeScript in v8 isolates, and Vercel created Just Bash.
How much computer you give an agent is how much agency you give it. You can get surprisingly far with pure code execution - for something like retrieving information from docs, Mintlify built a neat little agent - but access to a full computer unlocks a different class of work: running dev servers, installing arbitrary dependencies, inspecting process state. Even something like sleep 5 can be useful if an agent needs to wait for something.
And we're usually building agents to execute work we didn't plan for. For example, I asked an agent to generate a PDF report and it installed react-to-pdf on my computer and generated the report successfully. This particular agent was never designed to create PDFs. The more general the interface, the more likely the agent is going to succeed at tasks.
At Freestyle we support dynamic TypeScript execution and Just Bash through our execute API, but we keep finding ourselves reaching for the VM end of the spectrum. The overhead is lower than people expect, and the ceiling is much higher.
Managing persistence
Ok we have the computer, but how do we manage state?
If you run Claude Code on your local computer, it uses your local filesystem for persistent storage. This is convenient because your filesystem is probably mounted on an extremely fast NVMe SSD, and you as a human tend to that state.
But most agents run in the cloud, where you have a few options:
- Spin up a VM with an attached persisted disk. This closely mirrors a personal computer, but it's expensive, and without a human tending to it, things can get complicated. Freestyle has persistent VMs for this.
- Build an API-based persistence layer. You can build one on top of a vector database or a document store, and surface it as a tool call.
- Use FUSE to create a virtual filesystem. You store the user's data anywhere — S3, SQL, Freestyle Git if you want versions — and expose it to the agent as a POSIX filesystem. Caching matters (Freestyle VMs can mount SSDs to help here), and you don't have to build your own daemon — For example Cloudflare built ArtifactFS to mount git repos.
Managing process state
Files aren't the only state. A coding agent debugging an endpoint might have a dev server running, environment variables set, maybe a database connection open.
For remote sandboxes, you can usually use Docker or a startup script to rebuild a baseline process state every time, but that's really slow.
If you're on a good VM provider you can snapshot and resume memory. With Freestyle VMs, you can also fork memory - clone a running VM without pausing it, so two agents can branch off the same state and try different things in parallel.
Snapshots are great but someone has to create them, which is why we also let you declare them programmatically. You write a spec - base image, repo, setup commands, whatever services you need - and Freestyle builds and caches the snapshot for you. Check out the docs on templates and snapshots.
Managing external state
Then there's the hardest kind of state: the stuff that lives on someone else's server. An agent might be able to fork its memory, branch its filesystem, throw away work it doesn't like. But you can't snapshot Slack or unsend an email.
We don't have a clean answer here. Today we design around it case by case: we might add a human-in-the-loop step before executing an action that's irreversible or we might restrict an agent to only use certain APIs. But do we really want to annoy users with confirmation popups? And do we really want to limit which APIs an agent can use? It's hard. But at least we'll stay employed.

