hermes-agent/tools/environments
Teknium 569e9f9670
feat: execute_code runs on remote terminal backends (#5088)
* feat: execute_code runs on remote terminal backends (Docker/SSH/Modal/Daytona/Singularity)

When TERMINAL_ENV is not 'local', execute_code now ships the script to
the remote environment and runs it there via the terminal backend --
the same container/sandbox/SSH session used by terminal() and file tools.

Architecture:
- Local backend: unchanged (UDS RPC, subprocess.Popen)
- Remote backends: file-based RPC via execute_oneshot() polling
  - Script writes request files, parent polls and dispatches tool calls
  - Responses written atomically (tmp + rename) via base64/stdin
  - execute_oneshot() bypasses persistent shell lock for concurrency

Changes:
- tools/environments/base.py: add execute_oneshot() (delegates to execute())
- tools/environments/persistent_shell.py: override execute_oneshot() to
  bypass _shell_lock via _execute_oneshot(), enabling concurrent polling
- tools/code_execution_tool.py: add file-based transport to
  generate_hermes_tools_module(), _execute_remote() with full env
  get-or-create, file shipping, RPC poll loop, output post-processing

* fix: use _get_env_config() instead of raw TERMINAL_ENV env var

Read terminal backend type through the canonical config resolution
path (terminal_tool._get_env_config) instead of os.getenv directly.

* fix: use echo piping instead of stdin_data for base64 writes

Modal doesn't reliably deliver stdin_data to chained commands
(base64 -d > file && mv), producing 0-byte files. Switch to
echo 'base64' | base64 -d which works on all backends.

Verified E2E on both Docker and Modal.
2026-04-04 12:57:49 -07:00
..
__init__.py feat(environments): add Daytona cloud sandbox backend 2026-03-05 10:02:21 -08:00
base.py feat: execute_code runs on remote terminal backends (#5088) 2026-04-04 12:57:49 -07:00
daytona.py feat: mount skills directory into all remote backends with live sync (#3890) 2026-03-30 02:45:41 -07:00
docker.py feat: add docker_env config for explicit container environment variables (#4738) 2026-04-03 23:30:12 -07:00
local.py fix(terminal): preserve partial output when command times out (#3868) 2026-03-29 21:51:44 -07:00
managed_modal.py Fixes and refactors enabled by recent updates to main. 2026-03-31 09:29:59 +09:00
modal.py feat: add .zip document support and auto-mount cache dirs into remote backends (#4846) 2026-04-03 13:16:26 -07:00
modal_common.py Fixes and refactors enabled by recent updates to main. 2026-03-31 09:29:59 +09:00
persistent_shell.py feat: execute_code runs on remote terminal backends (#5088) 2026-04-04 12:57:49 -07:00
singularity.py feat: wire skills.external_dirs into all remaining discovery paths 2026-04-03 21:14:42 -07:00
ssh.py feat: wire skills.external_dirs into all remaining discovery paths 2026-04-03 21:14:42 -07:00