Skip to content

feat(sandbox): configure the Modal environment for modal and modal_vm - #175

Merged
psinghal20 merged 2 commits into
mainfrom
pratyush/modal-environment-name
Oct 12, 2026
Merged

psinghal20 merged 2 commits into
mainfrom
pratyush/modal-environment-name

Conversation

@psinghal20

@psinghal20 psinghal20 commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

What and why

The modal and modal_vm providers always create their Apps in the default Modal environment of the token's workspace: neither passes environment_name, so the only way to move them is a process-wide MODAL_ENVIRONMENT. A deployment that wants its sandboxes in a dedicated environment, without moving everything else that process does on Modal, has no setting for it.

Both providers now take an optional environment_name from their config table:

[sandbox.providers.modal.config]
environment_name = "rl-prod"
ecr_pull_secret_name = "ecr-reader"   # must exist in that environment

[sandbox.providers.modal_vm.config]
environment_name = "rl-prod"
  • It goes to modal.App.lookup. A sandbox's environment comes from its App (Sandbox.create(environment_name=) is deprecated for that reason), so sandboxes and image builds follow.
  • For modal, it also goes to modal.Secret.from_name for the ECR pull secret, which Modal scopes to an environment too. Without this the App and its pull secret would resolve in different environments.
  • The process-wide cache of images built from a build context (modal_image_build._built_image_ids) is now keyed by environment as well, so an image built in one environment isn't reused by a provider pointed at another.

Unset is unchanged: Modal's own default, MODAL_ENVIRONMENT, else the workspace default.

The website's Modal section (content/docs/sandboxes.mdx) needs a line for the new key; that's a separate PR in agent-env-website.

How it was tested

  • pytest tst/unit/providers/sandbox_providers: 738 passed, 3 skipped. New tests:
    • test_modal_builtins_accept_an_environment_name[modal|modal_vm]: the config table reaches both providers.
    • test_apps_are_looked_up_in_the_configured_environment (both providers): App.lookup gets the environment.
    • The ECR pull-secret test now asserts Secret.from_name(..., environment_name=...).
    • test_each_modal_environment_builds_its_own_image_of_the_same_sources: same sources, two environments, two builds; repeats within one environment still reuse.
  • Full tst/unit + packages/agentenv-protocol/tests: 17 failures in test_optional_extras_stay_optional.py and the protocol tool-client tests. The identical 17 fail on unmodified main in the same venv (it has boto3 installed and the protocol package isn't installed from the checkout), so they're environmental.
  • ruff check on the changed files: no new findings against main.
  • Not run against a live Modal workspace.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no actionable issues were found.

Summary

Adds optional environment_name configuration to modal and modal_vm.

  • Modal sandbox providers can target a named environment.

No actionable issues found. Tests were inspected, not run; live Modal behavior was not verified.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Config["Provider config: environment_name"] --> Provider["modal or modal_vm provider"]
  Provider --> App["App.lookup with environment_name"]
  App --> Sandbox["Sandbox creation with app"]
  Provider --> Secret["modal: ECR secret lookup with environment_name"]
  Secret --> Sandbox
  Provider --> Cache["modal: image cache and lock key includes environment"]
  App --> Build["Build context image with app"]
  Cache --> Build
  Build --> Sandbox
Loading

Reviews (1) · Last reviewed commit: "refactor(sandbox): drop the environment_..." · Reviewed by Greptile

Both Modal providers take an optional `environment_name` from their
`[sandbox.providers.<name>.config]` table. It goes to `modal.App.lookup`, so
the Apps, and the sandboxes and image builds in them, land in that environment.
For `modal` it also goes to `modal.Secret.from_name` for the ECR pull secret,
which Modal scopes to an environment too.

The process-wide cache of images built from a build context is now keyed by
environment as well, so a build in one environment is not reused from another.

Unset keeps today's behavior: Modal's own default, `MODAL_ENVIRONMENT`, else
the workspace default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@psinghal20
psinghal20 requested a review from a team as a code owner October 12, 2026 21:27
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@psinghal20
psinghal20 merged commit 724f4d5 into main Oct 12, 2026
13 checks passed
@psinghal20
psinghal20 deleted the pratyush/modal-environment-name branch October 12, 2026 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant