Repository navigation
feat(sandbox): a provider that creates VMs loads an agent's image unless it declares otherwise - #164
Merged
Merged
Conversation
…ess it declares otherwise SANDBOX_ACCEPTS, the images an agent's own sandbox runs, now defaults to what a provider's create_sandbox gives: those a VM loads when it implements create_vm (its create_sandbox is a bare VM the deploy loads the image into), and its CONTAINER_ACCEPTS otherwise (its create_sandbox is one of its containers). A provider whose create_sandbox differs declares it, and its subclasses keep the declaration. The local provider, which creates VMs but runs an agent as a container by name, declares NAME; Modal VM, E2B and Sail drop their LOADABLE line, and Modal its duplicate. Every provider here and in the Scale layer ends up with the value it declared. A plugin that implements create_vm and relied on the old NAME default for a container create_sandbox now has to declare it; if it doesn't, the deploy says so as soon as the container comes back for an image it can't run by name. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…, and a container is checked against what its provider's containers run The deploy check looked at every provider in a chain rather than the one whose sandbox came back, so a chain could pass a container that can't run the image (when another link's containers could) or refuse a deploy its next provider would have served. It also asked whether the image runs by name, which refuses a container whose provider built the image first, as Modal's do, and named the wrong fix. SandboxProvider.sandbox_problem(sandbox, image) now says why a sandbox create_sandbox gave can't run the image: a VM that can't load it, or a container its CONTAINER_ACCEPTS leaves it out of, naming the SANDBOX_ACCEPTS to declare when that differs. A chain asks it of each provider's sandbox as it tries it, closes one that can't and tries the next (replacing its VM-only check); a lone provider is asked by the agent's deploy. A chain answers None, having checked its own. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…es like a VM has their containers checked A provider can declare that create_sandbox's containers run other images than create_container's (say SANDBOX_ACCEPTS = NAME_OR_CONTEXT, CONTAINER_ACCEPTS = NAME); checking those containers against CONTAINER_ACCEPTS refused sandboxes that work. sandbox_problem now checks a container only when the provider's SANDBOX_ACCEPTS is LOADABLE, the case where it said it gives a VM; a provider that declares the images its containers run is taken at its word, as preflight already checked against them. The two test fakes changed for the wider check are back as they were. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A new sandbox provider shaped like most of them (a VM per sandbox) no longer has to declare
SANDBOX_ACCEPTSto work.Why
SANDBOX_ACCEPTSsays which images an agent's own sandbox (create_sandbox) runs, and onlyA2AAgent.acceptsreads it. Its default,NAME, was right for one provider here (local) and wrong for the VM providers, which each carriedSANDBOX_ACCEPTS = Accepts.LOADABLEto override it. A VM provider that missed the line, as #148's Vercel provider does, had agents refused for images it runs fine: the default local setup's tar.gz images, and images that are only a build context.What
SANDBOX_ACCEPTSdefaults to whatcreate_sandboxgives, derived for each provider class in__init_subclass__:create_vm, since itscreate_sandboxis a bare VM the deploy loads the image into;CONTAINER_ACCEPTS, since itscreate_sandboxis one of its containers.create_sandboxdiffers declares it, and its subclasses keep the declaration. The local provider, which creates VMs but runs an agent as a container by name, declaresNAME.LOADABLEline, and Modal the duplicate half ofSANDBOX_ACCEPTS = CONTAINER_ACCEPTS = NAME_OR_CONTEXT.SandboxProvider.sandbox_problem(sandbox, image)says why: a VM that can't load it, or a container from a provider whoseSANDBOX_ACCEPTSisLOADABLE(it said it gives a VM) and whoseCONTAINER_ACCEPTSleaves the image out, naming theSANDBOX_ACCEPTSto declare. A provider that declares the images its agents' containers run is taken at its word, as preflight checked against them. A chain asks it of each provider's sandbox as it tries it, closes one that can't run the image and tries the next (this replaces its VM-only check); the agent's deploy asks a lone provider. So a provider taken to load the image that gives back a container is refused at once with the fix, instead of failing later on a pull or the card's timeout, and in a chain the next provider gets its turn. A container that runs the image, such as one whose provider built it first, goes on to serve it.Every provider ends up with the value it had: local
NAME; ModalNAME_OR_CONTEXT; Modal VM, E2B and SailLOADABLE; the chainNAME. The Scale layer's providers declareLOADABLEand are unchanged.For plugins
A plugin provider that implements
create_vmbut gives an agent a container fromcreate_sandbox, and relied on the oldNAMEdefault, now has to declareSANDBOX_ACCEPTS = Accepts.NAME. The plugin API check doesn't see a changed default, so this is the note; if one is missed, the deploy names the fix. #148's Vercel provider needs no declaration after this, and #155's Tensorlake provider can drop itsSANDBOX_ACCEPTSline, and itsCREATES_VMS, which #159 removed.Tests
Unit tier: 7,414 passed. New: the derivation for each provider shape (VM, container, a container that builds, declared, kept by a subclass, derived again by one), the local provider's declaration, and the deploy check: a lone undeclared provider's container refused with the declaration to add; containers that pull the image, built it first, or whose provider declared them let through; a chain that closes a container that can't run the image and serves the agent from Modal's, or names each refusal when no provider can; and a chain that falls back from a failing VM provider to Modal.
Live checks
On a Linux amd64 host, with Modal, Modal VM, Sail and the local provider:
local,modalandmodal_vm,modal, and the local provider refuses it; a tar.gz agent deploys on Modal VM, Sail, local andmodal_vm,local, and Modal refuses it.create_vmdeploys a context-only agent; one whosecreate_sandboxgives a stock container is refused with the declaration to add, alone or twice in a chain, and in a chain with Modal or Modal VM after it the next provider serves the agent.🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; the declared-container rejection is fixed.Summary
VM providers now default to accepting images they can load. Container providers default to
CONTAINER_ACCEPTS, and explicit declarations stay inherited.Diagram
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Check SANDBOX_ACCEPTS] --> B[Create sandbox] B --> C{VM?} C -->|Yes| D[Check load_problems] C -->|No| E{SANDBOX_ACCEPTS is LOADABLE?} E -->|No| F[Trust declaration] E -->|Yes| G[Check CONTAINER_ACCEPTS] D --> H{Image accepted?} G --> H F --> I[Continue deploy] H -->|Yes| I H -->|No| J[Close sandbox] J --> K[Try next provider or fail]Reviews (3) · Last reviewed commit: "fix(sandbox): only a provider that says ..." · Reviewed by Greptile