Drop the mini-swe-agent git submodule. All terminal backends now use hermes-agent's own environment implementations directly. Docker backend: - Inline the `docker run -d` container startup (was 15 lines in minisweagent's DockerEnvironment). Our wrapper already handled execute(), cleanup(), security hardening, volumes, and resource limits. Modal backend: - Import swe-rex's ModalDeployment directly instead of going through minisweagent's 90-line passthrough wrapper. - Bake the _AsyncWorker pattern (from environments/patches.py) directly into ModalEnvironment for Atropos compatibility without monkey-patching. Cleanup: - Remove minisweagent_path.py (submodule path resolution helper) - Remove submodule init/install from install.sh and setup-hermes.sh - Remove mini-swe-agent from .gitmodules - environments/patches.py is now a no-op (kept for backward compat) - terminal_tool.py no longer does sys.path hacking for minisweagent - mini_swe_runner.py guards imports (optional, for RL training only) - Update all affected tests to mock the new direct subprocess calls - Update README.md, CONTRIBUTING.md No functionality change — all Docker, Modal, local, SSH, Singularity, and Daytona backends behave identically. 6093 tests pass.
43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
"""
|
|
Monkey patches for making hermes-agent tools work inside async frameworks (Atropos).
|
|
|
|
Problem:
|
|
Some tools use asyncio.run() internally (e.g., Modal backend via SWE-ReX,
|
|
web_extract). This crashes when called from inside Atropos's event loop because
|
|
asyncio.run() can't be nested.
|
|
|
|
Solution:
|
|
The Modal environment (tools/environments/modal.py) now uses a dedicated
|
|
_AsyncWorker thread internally, making it safe for both CLI and Atropos use.
|
|
No monkey-patching is required.
|
|
|
|
This module is kept for backward compatibility — apply_patches() is now a no-op.
|
|
|
|
Usage:
|
|
Call apply_patches() once at import time (done automatically by hermes_base_env.py).
|
|
This is idempotent — calling it multiple times is safe.
|
|
"""
|
|
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
_patches_applied = False
|
|
|
|
|
|
def apply_patches():
|
|
"""Apply all monkey patches needed for Atropos compatibility.
|
|
|
|
Now a no-op — Modal async safety is built directly into ModalEnvironment.
|
|
Safe to call multiple times.
|
|
"""
|
|
global _patches_applied
|
|
if _patches_applied:
|
|
return
|
|
|
|
# Modal async-safety is now built into tools/environments/modal.py
|
|
# via the _AsyncWorker class. No monkey-patching needed.
|
|
logger.debug("apply_patches() called — no patches needed (async safety is built-in)")
|
|
|
|
_patches_applied = True
|