Skip to main content
Eve is Vercel’s agent framework. It gives an agent a code-execution sandbox through a single agent/sandbox.ts file, and the backend behind that file is swappable. @upstash/agentkit-eve ships an Upstash Box backend for it. It is a drop-in replacement for Eve’s vercel() backend: change one import and your agent runs its code inside a Box, with deny-all egress by default, snapshot-backed templates, and one box per conversation.

1. Start from an Eve project

Scaffold one if you do not have it yet. This installs eve and an AI SDK provider for you.
Use eve 0.43.0 or later.

2. Install the packages

@upstash/box is an optional peer dependency of the AgentKit package. You only need it because you are importing the sandbox backend. Get a Box API key from the Upstash Console:
.env
Redis backs the template registry described in step 5. It is only touched when your sandbox has a template, so a sandbox with no seed files and no bootstrap runs on the Box key alone.

3. Swap the backend

Point defineSandbox at the upstash backend. Everything else in the sandbox file stays as it is.
agent/sandbox.ts
upstash(config) takes the @upstash/box BoxConfig. Whatever you would pass to Box.create({ ... }) you pass here: runtime, size, apiKey (defaults to UPSTASH_BOX_API_KEY), keepAlive, initCommand, env, git, skills, mcpServers, timeout, and so on. There are no renamed knobs to keep in sync. Two things differ from a raw Box.create. networkPolicy is not accepted at all, because egress is governed per session (see the next step). And a few AgentKit-only fields sit alongside the Box config and are stripped before the rest is handed to Box.create: redis and templatePrefix for the template registry, baseSnapshot (step 5), and enableTelemetry. That is the whole setup. Run your agent and ask it to execute something:

4. Open egress per session

The sandbox runs model-generated code, so egress is deny-all by default. Open it where you need it, in the use(...) call, never as a backend-level setting.
agent/sandbox.ts
Pass "allow-all" when the agent genuinely needs the open internet, and nothing at all to inherit the secure default.
env passed to upstash({ env }) is readable by code running in the box. Do not put secrets there that the model should not see.

Brokering credentials

Box network policies are plain domain and CIDR allow lists. Eve’s per-domain firewall rules (transform header injection, forwardURL) have no Box equivalent, so passing them to use({ networkPolicy }) throws instead of quietly sending the request unauthenticated. Use Box’s attachHeaders instead. A proxy on the box injects the header at the firewall, so the secret never enters the box:
agent/sandbox.ts

5. Bake setup into a template

A bootstrap hook runs once, and Eve caches the result as a template so later sessions start from it. On Box that template is a snapshot.
agent/sandbox.ts
A box runs as the non-root boxuser, so system-wide installs need sudo -n. Without it apt-get exits 100 on the dpkg lock and the bootstrap fails. Workspace-local installs such as npm install need no sudo. Eve builds the template at build or startup time, while session creation runs per request in a different process. The snapshot id is therefore stored in a durable Redis registry (redis, defaulting to Redis.fromEnv(), under the agentkit:sandbox:template prefix). An in-memory map would orphan the prewarmed box. Bump revalidationKey when the bootstrap should run again.

Heavy, slow-changing setup

For things too heavy for a per-repo bootstrap (browser binaries, ffmpeg, a full toolchain), build a Box snapshot yourself out of band and point baseSnapshot at it. Every fresh session restores from it instead of creating a bare box.
Pass a snapshot id or a resolver, since Box addresses snapshots by id rather than by name. Returning undefined, or an id that no longer exists, falls back to a fresh box. When a prewarmed template snapshot also applies, the template wins and baseSnapshot is the fallback for sessions that have no template.

6. Lifecycle

Eve re-opens a session several times per turn. The backend reattaches to the same box instead of creating a new one, so you get one box per conversation rather than one per tool call. Boxes use Box’s pause-based idle lifecycle by default (keepAlive: false): auto-paused when idle, resumed on reattach, and reaped by Box. Pass keepAlive: true only when you want an always-running box that you manage and delete yourself.
Eve roots its tools at /workspace, while a Box session lives at /workspace/home. The backend rewrites paths and command text between the two automatically, so tools like glob and grep search the right directory.

Next steps

The same package carries the rest of AgentKit for Eve: long-term memory, searchable chat history, RAG over Redis Search, a rate-limit gate for your channel’s auth walk, and Redis-memoized tools.