Skip to content

feat(sandbox): add Vercel Sandbox provider - #216

Merged
psinghal20 merged 6 commits into
mainfrom
feat/vercel-sandbox
Oct 15, 2026
Merged

psinghal20 merged 6 commits into
mainfrom
feat/vercel-sandbox

Conversation

@psinghal20

@psinghal20 psinghal20 commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

What and why

Closes #144. Supersedes #148 by @erulkey, carrying that PR's three commits unchanged with their authorship, and merging main into them. #148's head lives on vercel-labs/agentenv-framework, and a ruleset there requires signed commits. Merging main brings in its unsigned version-bump commits, so that branch can't be brought up to date. This branch is on scaleapi, which doesn't have that rule.

This PR adds the optional vercel sandbox provider, which runs Docker workloads in Vercel Sandbox, with network policies, artifact transfers, reconnect and teardown. To use it, install the vercel extra and select vercel in [sandbox]. CPU and memory are minimum requests, rounded up to supported sizes. Disk is fixed at 64 GB. It covers ephemeral runs. Persistent resume and credential brokering are follow-ups.

Changes in the merges since #148

  • Conflicts with the Tensorlake and Tenki providers, which landed on main in the meantime: both extras, both providers registered, egress hosts, network-policy stamping and the capability gates.
  • SandboxProvider.terminate_sandbox (new on main, now used to tear down records that name their backend) treats SandboxNotFoundError as already terminated, as its docstring says. Main's teardown no longer calls get_sandbox for those records, so without this, a Vercel sandbox that was already gone would be reported as failed. Records that don't name a backend keep main's live-handle path, where "not found" doesn't prove the sandbox is gone.
  • An earlier fix that this second merge replaced: teardown.py read handle.ON_THIS_MACHINE on the None returned for a gone sandbox.
  • vercel_sandbox_test.py passes dockerfile_path, which main now requires.

How it was tested

  • make unit-test on the merged tree: 8216 passed, 20 skipped.
  • Live against Vercel (Hobby team): a smoke test, the hello bundle on vercel, and the full deploy-env → load → deploy-agent → prompt → verify demo. The demo scored 1.0, and all three sandboxes were removed afterwards.
  • Live on the merged tree: calling terminate_sandbox on an already-destroyed sandbox returns cleanly, and get_sandbox raises SandboxNotFoundError.

Still open

  • _allow_download_hosts takes the policy lock and calls the API before checking whether there are any hosts to add.
  • _reap sleeps after its last attempt, retries 401 and 403, and logs "Destroyed" on a 404.
  • There are no unit tests for the core teardown paths when a sandbox is not found.
  • The README still links the demo on the vercel-labs fork and says the provider isn't in a published release. It should also say that Hobby plans cap sandbox timeouts at 45 minutes, while the default TTL is 2 hours.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge, with the earlier non-blocking output-buffer concern still open.

Fix All in CursorFindings

  1. P2 Output buffering has no bound ▶
Fix with agent prompt
### Issue 1
src/agent_env/providers/sandbox_providers/vercel/sandbox.py:139-141
`_OutputSink.write` puts every output chunk into a `StreamReader` without waiting for the reader. During large artifact collection, a fast command can outpace the caller decoding output and writing it to disk. The resulting backlog can consume excessive memory. Use a bounded buffer or disk-backed output so streamed transfers stay bounded.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds the optional vercel provider for ephemeral Docker workloads, with public routes, network policies, artifact transfers, reconnect, and cleanup.

  • AgentEnv can run Docker workloads in ephemeral Vercel Sandboxes.
  • Cleanup finishes when a sandbox is already gone.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Select vercel provider] --> B[Check resources and network policy]
  B --> C[Create ephemeral Vercel Sandbox]
  C --> D[Prepare Docker and Compose]
  D --> E[Load images and files]
  E --> F[Run workload through public routes]
  F --> G[Destroy sandbox and orphan snapshots]
  C --> H[Interrupted creation]
  H --> G
Loading

Reviews (2) · Last reviewed commit: "fix(vercel): address greptile review fin..." · Reviewed by Greptile

erulkey and others added 5 commits October 9, 2026 12:26
Resolve conflicts with the Tensorlake provider that main added:
- pyproject.toml: keep both the vercel and tensorlake extras; the dev extra
  takes both, plus main's fastmcp pin.
- sandbox_provider.py: keep SandboxNotFoundError beside main's Accepts, and
  register both built-in providers.
- teardown.py: take main's imports with SandboxNotFoundError added.
- tst/util/capabilities.py, tst/unit/test_capabilities.py: both providers in
  the capability gate; main's parametrized configured-provider tests plus the
  Vercel credential tests.
- egress_hosts_test.py, network_policy_stamping_test.py: both providers.
- uv.lock: main's lock, relocked with the vercel extra.

Fix what main changed under the PR:
- teardown.py: main's take_down reads handle.ON_THIS_MACHINE, and _terminate
  now returns None for a sandbox that is already gone.
- vercel_sandbox_test.py: a context-only image now has to record its
  Dockerfile (main's load_problem).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main added the Tenki provider and moved teardown of typed records to
SandboxProvider.terminate_sandbox. The base terminate_sandbox now treats
SandboxNotFoundError as already terminated, as its docstring says, so a
Vercel sandbox that is already gone tears down cleanly; untyped records
keep main's live-handle path, where "not found" is not proof it's gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@psinghal20
psinghal20 requested a review from a team as a code owner October 15, 2026 00:22
@socket-security

socket-security Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpypi/​vercel-sandbox@​0.7.094100100100100
Addedpypi/​httpx2@​2.13.1100100100100100

View full report

Comment thread src/agent_env/providers/sandbox_providers/vercel/sandbox.py
Comment thread src/agent_env/providers/sandbox_providers/vercel/sandbox.py Outdated
- Name the Docker readiness attempts, delay, dockerd log tail and setup
  error tail used by wait_for_vm's script.
- Drop an unused import in vercel_sandbox_test.py that fails ruff.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@psinghal20
psinghal20 merged commit e42f222 into main Oct 15, 2026
14 of 15 checks passed
@psinghal20
psinghal20 deleted the feat/vercel-sandbox branch October 15, 2026 01:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Vercel Sandbox as an in-tree provider

3 participants