refactor: replace swe-rex with native Modal SDK for Modal backend (#3538)

Drop the swe-rex dependency for Modal terminal backend and use the
Modal SDK directly (Sandbox.create + Sandbox.exec). This fixes:

- AsyncUsageWarning from synchronous App.lookup() in async context
- DeprecationError from unencrypted_ports / .url on unencrypted tunnels
  (deprecated 2026-03-05)

The new implementation:
- Uses modal.App.lookup.aio() for async-safe app creation
- Uses Sandbox.create.aio() with 'sleep infinity' entrypoint
- Uses Sandbox.exec.aio() for direct command execution (no HTTP server
  or tunnel needed)
- Keeps all existing features: persistent filesystem snapshots,
  configurable resources (CPU/memory/disk), sudo support, interrupt
  handling, _AsyncWorker for event loop safety

Consistent with the Docker backend precedent (PR #2804) where we
removed mini-swe-agent in favor of direct docker run.

Files changed:
- tools/environments/modal.py - core rewrite
- tools/terminal_tool.py - health check: modal instead of swerex
- hermes_cli/setup.py - install modal instead of swe-rex[modal]
- pyproject.toml - modal extra: modal>=1.0.0 instead of swe-rex[modal]
- scripts/kill_modal.sh - grep for hermes-agent instead of swe-rex
- tests/ - updated for new implementation
- environments/README.md - updated patches section
- website/docs - updated install command
This commit is contained in:
Teknium 2026-03-28 11:21:44 -07:00 committed by GitHub
parent 455bf2e853
commit 735ca9dfb2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 113 additions and 102 deletions

View file

@ -4,10 +4,9 @@ Covers the bugs discovered while setting up TBLite evaluation:
1. Tool resolution terminal + file tools load correctly
2. CWD fix host paths get replaced with /root for container backends
3. ephemeral_disk version check
4. Tilde ~ replaced with /root for container backends
5. ensurepip fix in Modal image builder
6. install_pipx stays True for swerex-remote
7. /home/ added to host prefix check
4. ensurepip fix in Modal image builder
5. No swe-rex dependency uses native Modal SDK
6. /home/ added to host prefix check
"""
import os
@ -251,7 +250,7 @@ class TestModalEnvironmentDefaults:
# =========================================================================
# Test 7: ensurepip fix in patches.py
# Test 7: ensurepip fix in ModalEnvironment
# =========================================================================
class TestEnsurepipFix:
@ -275,17 +274,24 @@ class TestEnsurepipFix:
"to fix pip before Modal's bootstrap"
)
def test_modal_environment_uses_install_pipx(self):
"""ModalEnvironment should pass install_pipx to ModalDeployment."""
def test_modal_environment_uses_native_sdk(self):
"""ModalEnvironment should use Modal SDK directly, not swe-rex."""
try:
from tools.environments.modal import ModalEnvironment
except ImportError:
pytest.skip("tools.environments.modal not importable")
import inspect
source = inspect.getsource(ModalEnvironment.__init__)
assert "install_pipx" in source, (
"ModalEnvironment should pass install_pipx to ModalDeployment"
source = inspect.getsource(ModalEnvironment)
assert "swerex" not in source.lower(), (
"ModalEnvironment should not depend on swe-rex; "
"use Modal SDK directly via Sandbox.create() + exec()"
)
assert "Sandbox.create.aio" in source, (
"ModalEnvironment should use async Modal Sandbox.create.aio()"
)
assert "exec.aio" in source, (
"ModalEnvironment should use Sandbox.exec.aio() for command execution"
)