Skip to content

refactor(modal): upgrade to 1.6.3 and use public SDK APIs - #533

Merged
earakely-scale merged 4 commits into
scaleapi:mainfrom
thundergolfer:codex/upgrade-modal-1.6.3
Nov 9, 2026
Merged

earakely-scale merged 4 commits into
scaleapi:mainfrom
thundergolfer:codex/upgrade-modal-1.6.3

Conversation

@thundergolfer

@thundergolfer thundergolfer commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Hey, upgrading Modal to get on our latest backend, improving perf and reliability. Also uses new GA methods, no more experimental 🙂


Raise the Modal client requirement from >=1.5.2.dev22 to >=1.6.3 and update the locked client from 1.6.2.dev1 to the latest stable release. Use the public APIs available with this floor:

  • Create ordinary containers and VMs with Sandbox.create(). Keep _experimental_create(i6pn=True) for private networking, which the public factory does not expose, and preserve GPU restrictions.
  • Select the VM runtime with runtime="vm" instead of experimental_options={"vm_runtime": True}. Preserve the nested-virtualization option for disk sandboxes.
  • Pull ECR images with Image.from_registry() and the existing named AWS secret, preserving credential routing and registry-host checks.

Update the provider tests and extend the installed-SDK signature checks to cover both public container creation and private networking. File-transfer changes are outside this PR.

Regenerated uv.lock with the CI-pinned uv 0.13.1. The only package version changes are Modal and its required synchronicity update (0.12.6 → 0.12.7); uv also normalizes lockfile markers and format.

Validation:

  • Modal provider unit tests: 129 passed, including installed-SDK signature checks, VM/disk creation, GPU restrictions, cancellation cleanup, network policies, and image authentication.
  • Shared attribution, network-policy stamping, and provider-capability tests: 133 passed, 1 skipped (optional smol package unavailable).
  • uv lock --check with uv 0.13.1: passed.
  • uv run --frozen ruff check .: passed.
  • git diff --check: passed.

Live Modal integration tests were not run. Upstream CodeBuild requires maintainer approval before running for this fork.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no actionable defects were established.

Summary

Upgrades Modal to 1.6.3 and moves ordinary container and VM creation to public SDK calls.

  • Modal containers now use the public creation API.
  • Modal VMs now use the public creation API and runtime setting.
  • ECR images now use Modal's public registry image API.

No actionable new issues were established. No previous review threads were supplied. The merge bases differed, so this review covered the full PR diff. Tests and live Modal calls were not run during this review.

Reviews (3) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile

@thundergolfer
thundergolfer requested a review from a team as a code owner November 7, 2026 17:57
@socket-security

socket-security Bot commented Nov 7, 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
Updatedpypi/​modal@​1.6.2.dev1 ⏵ 1.6.380 +1100100100100

View full report

@thundergolfer thundergolfer changed the title build(deps): upgrade Modal client to 1.6.3 refactor(modal): upgrade to 1.6.3 and use public SDK APIs Nov 7, 2026
@earakely-scale

Copy link
Copy Markdown
Collaborator

🤖 Automated Claude routine — Env Pod PR Context Review. This is a bot, not Edgar Arakelyan; not a human review.

Offering context on one branch this repo's tests can't exercise end to end: the ECR pull-secret path in _registry_image.

The PR description says ECR images are pulled "with Image.from_registry() and the existing named AWS secret, preserving credential routing". The registry-host check is indeed preserved, but the secret shape looks like it changes meaning. The rewritten call keeps required_keys=ECR_READER_SECRET_KEYS, which is ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION"] (src/agent_env/providers/sandbox_providers/modal_sandbox.py:42). The very next branch of the same function shows what this repo expects a from_registry secret to carry — REGISTRY_USERNAME / REGISTRY_PASSWORD (modal_sandbox.py:522-525 on main). So after the change that branch hands from_registry a secret with AWS keys and no registry username/password, and the AWS→ECR token exchange that from_aws_ecr performed no longer has an owner.

Two reasons this may not show up before it ships:

  • The assertions that pinned the old behaviour are relaxed in the same diff — assert aws_ecr.call_args.args[0] == ecr and the aws_ecr.assert_not_called() negative control are both dropped, and the test's docstring ("ECR -> from_aws_ecr + named secret") goes with them. Both factories were previously patched side by side, which is what made the two paths distinguishable; a green suite no longer does.
  • The branch only activates when a deployment sets ecr_pull_secret_name and its image store carries EcrCredentials. Nothing checked into this repo turns that on, so neither the unit suite nor a fork CI run reaches it — and the description notes live Modal integration tests weren't run.

If from_aws_ecr is being retired in 1.6, the AWS→registry credential exchange likely needs to move into the provider (mint a token, pass it as REGISTRY_USERNAME/REGISTRY_PASSWORD) rather than be dropped — the uncached fallback at the bottom of the same function already mints an ECR token, so the pieces are there. Worth a maintainer confirming against a real private-ECR pull before merge.


Generated by Claude Code

@earakely-scale

Copy link
Copy Markdown
Collaborator

Thanks for this! I resolved the conflict with main and ran it against live Modal (Modal 1.6.3, Modal env genai-agent-env, on a Linux box). No regressions found.

What I pushed (4be474b, merges of main with no force-push):

Checked against Modal 1.6.3's source:

  • Sandbox.create takes everything now passed to it, including runtime, experimental_options (enable_nested_virt), gpu, tags and both outbound allowlists. _experimental_create differs only in taking i6pn instead of gpu, and neither factory is ever sent the other's argument.
  • from_aws_ecr is superseded there by from_registry, which infers AWS auth from the secret's keys. One caveat: if agent-env-ecr-reader ever also held REGISTRY_USERNAME/REGISTRY_PASSWORD, from_registry would refuse it as two kinds of auth.

Live results:

What Covers Result
Unit suite, tst/unit and the protocol's everything 14,037 passed, 18 skipped
A plain container Sandbox.create, exec, tunnel passed; tunnel 200
An ECR image with ecr_pull_secret_name="agent-env-ecr-reader", on CPU and on a T4 from_registry with the named AWS secret, the GPU path passed; T4 visible
Two containers with private_network=True _experimental_create(i6pn=True) reach each other over i6pn
An allowlist policy network kwargs on create pypi.org allowed, example.com refused
A VM sandbox runtime="vm" kernel 7.2.14, Docker 29.1.3
server_env_modal_test.py envs and an episode on Modal containers 2 passed
gateway_test.py, multi MCP servers on modal_vm gateway stack in a VM passed
a2a_agent_test.py, deploy on modal_vm and the fallback chain to it agent path passed
proxy_modal_vm_test.py agent through a proxy on modal_vm passed
disk_modal_vm_test.py Linux disk computer, nested virtualization passed
Windows notes computer on modal_vm, deployed, checked, reset and checked again the code merged from #534 passed

What failed, and why it isn't this PR: the modal variants of the gateway test and of two agent tests stopped before any Modal call. My box's local config keeps images in a localhost:5000 registry, and the framework refuses to hand those to a remote sandbox. The two agent tests fail the same way on main. Internal config uses ECR.

Not covered: cancelling a create mid-flight. Sandbox.create returned in under a second, so a cancel couldn't land live; the provider's unit tests cover it.

@earakely-scale
earakely-scale merged commit ba66fdd into scaleapi:main Nov 9, 2026
53 of 55 checks passed
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.

2 participants