This commit is contained in:
Fabzer 2026-04-24 19:24:50 -05:00 committed by GitHub
commit b4f338ccf4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 1022 additions and 29 deletions

View file

@ -106,7 +106,7 @@ hermes-agent/
│ ├── credential_files.py # File-based credential passthrough
│ ├── env_passthrough.py # Env var passthrough for sandboxes
│ ├── ansi_strip.py # ANSI escape stripping
│ └── environments/ # Terminal backends (local, docker, ssh, modal, daytona, singularity)
│ └── environments/ # Terminal backends (local, docker, ssh, modal, daytona, singularity, koyeb)
├── gateway/ # Messaging platform gateway
│ ├── run.py # GatewayRunner — message dispatch (~9,000 lines)

View file

@ -84,7 +84,7 @@ The foundation from `atroposlib`. Provides:
### HermesAgentBaseEnv
The hermes-agent layer (`environments/hermes_base_env.py`). Adds:
- **Terminal backend configuration** — sets `TERMINAL_ENV` for sandboxed execution (local, Docker, Modal, Daytona, SSH, Singularity)
- **Terminal backend configuration** — sets `TERMINAL_ENV` for sandboxed execution (local, Docker, Modal, Daytona, SSH, Singularity, Koyeb)
- **Tool resolution**`_resolve_tools_for_group()` calls hermes-agent's `get_tool_definitions()` to get the right tool schemas based on enabled/disabled toolsets
- **Agent loop integration**`collect_trajectory()` runs `HermesAgentLoop` and scores the result
- **Two-phase operation** — Phase 1 (OpenAI server) for eval/SFT, Phase 2 (VLLM ManagedServer) for full RL with logprobs
@ -426,7 +426,7 @@ See `environments/benchmarks/yc_bench/yc_bench_env.py` for a clean, well-documen
| `max_agent_turns` | `int` | `30` | Max LLM calls per rollout |
| `agent_temperature` | `float` | `1.0` | Sampling temperature |
| `system_prompt` | `str` | `None` | System message for the agent |
| `terminal_backend` | `str` | `"local"` | `local`, `docker`, `modal`, `daytona`, `ssh`, `singularity` |
| `terminal_backend` | `str` | `"local"` | `local`, `docker`, `modal`, `daytona`, `ssh`, `singularity`, `koyeb` |
| `terminal_timeout` | `int` | `120` | Seconds per terminal command |
| `terminal_lifetime` | `int` | `3600` | Max sandbox lifetime |
| `dataset_name` | `str` | `None` | HuggingFace dataset identifier |

View file

@ -125,6 +125,7 @@ For native Anthropic auth, Hermes prefers Claude Code's own credential files whe
| `TINKER_API_KEY` | RL training ([tinker-console.thinkingmachines.ai](https://tinker-console.thinkingmachines.ai/)) |
| `WANDB_API_KEY` | RL training metrics ([wandb.ai](https://wandb.ai/)) |
| `DAYTONA_API_KEY` | Daytona cloud sandboxes ([daytona.io](https://daytona.io/)) |
| `KOYEB_API_TOKEN` | Koyeb cloud sandboxes ([koyeb.com](https://www.koyeb.com/)) |
### Nous Tool Gateway
@ -141,7 +142,7 @@ These variables configure the [Tool Gateway](/docs/user-guide/features/tool-gate
| Variable | Description |
|----------|-------------|
| `TERMINAL_ENV` | Backend: `local`, `docker`, `ssh`, `singularity`, `modal`, `daytona` |
| `TERMINAL_ENV` | Backend: `local`, `docker`, `ssh`, `singularity`, `modal`, `daytona`, `koyeb` |
| `TERMINAL_DOCKER_IMAGE` | Docker image (default: `nikolaik/python-nodejs:python3.11-nodejs20`) |
| `TERMINAL_DOCKER_FORWARD_ENV` | JSON array of env var names to explicitly forward into Docker terminal sessions. Note: skill-declared `required_environment_variables` are forwarded automatically — you only need this for vars not declared by any skill. |
| `TERMINAL_DOCKER_VOLUMES` | Additional Docker volume mounts (comma-separated `host:container` pairs) |
@ -149,6 +150,7 @@ These variables configure the [Tool Gateway](/docs/user-guide/features/tool-gate
| `TERMINAL_SINGULARITY_IMAGE` | Singularity image or `.sif` path |
| `TERMINAL_MODAL_IMAGE` | Modal container image |
| `TERMINAL_DAYTONA_IMAGE` | Daytona sandbox image |
| `TERMINAL_KOYEB_IMAGE` | Koyeb sandbox image |
| `TERMINAL_TIMEOUT` | Command timeout in seconds |
| `TERMINAL_LIFETIME_SECONDS` | Max lifetime for terminal sessions in seconds |
| `TERMINAL_CWD` | Working directory for all terminal sessions |
@ -166,7 +168,7 @@ For cloud sandbox backends, persistence is filesystem-oriented. `TERMINAL_LIFETI
| `TERMINAL_SSH_KEY` | Path to private key |
| `TERMINAL_SSH_PERSISTENT` | Override persistent shell for SSH (default: follows `TERMINAL_PERSISTENT_SHELL`) |
## Container Resources (Docker, Singularity, Modal, Daytona)
## Container Resources (Docker, Singularity, Modal, Daytona, Koyeb)
| Variable | Description |
|----------|-------------|
@ -176,6 +178,13 @@ For cloud sandbox backends, persistence is filesystem-oriented. `TERMINAL_LIFETI
| `TERMINAL_CONTAINER_PERSISTENT` | Persist container filesystem across sessions (default: `true`) |
| `TERMINAL_SANDBOX_DIR` | Host directory for workspaces and overlays (default: `~/.hermes/sandboxes/`) |
## Koyeb Backend
| Variable | Description |
|----------|-------------|
| `TERMINAL_KOYEB_INSTANCE_TYPE` | Koyeb instance type (default: `micro`). Options: `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`, etc. |
| `KOYEB_REGION` | Koyeb region (default: `na`). Options: `na`, `eu`, `fr`, etc. |
## Persistent Shell
| Variable | Description |

View file

@ -83,17 +83,18 @@ Leaving these unset keeps the legacy defaults (`HERMES_API_TIMEOUT=1800`s, `HERM
## Terminal Backend Configuration
Hermes supports six terminal backends. Each determines where the agent's shell commands actually execute — your local machine, a Docker container, a remote server via SSH, a Modal cloud sandbox, a Daytona workspace, or a Singularity/Apptainer container.
Hermes supports seven terminal backends. Each determines where the agent's shell commands actually execute — your local machine, a Docker container, a remote server via SSH, a Modal cloud sandbox, a Daytona workspace, a Singularity/Apptainer container, or a Koyeb cloud sandbox.
```yaml
terminal:
backend: local # local | docker | ssh | modal | daytona | singularity
backend: local # local | docker | ssh | modal | daytona | singularity | koyeb
cwd: "." # Working directory ("." = current dir for local, "/root" for containers)
timeout: 180 # Per-command timeout in seconds
env_passthrough: [] # Env var names to forward to sandboxed execution (terminal + execute_code)
singularity_image: "docker://nikolaik/python-nodejs:python3.11-nodejs20" # Container image for Singularity backend
modal_image: "nikolaik/python-nodejs:python3.11-nodejs20" # Container image for Modal backend
daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20" # Container image for Daytona backend
koyeb_image: "koyeb/sandbox:latest" # Container image for Koyeb backend
```
For cloud sandboxes such as Modal and Daytona, `container_persistent: true` means Hermes will try to preserve filesystem state across sandbox recreation. It does not promise that the same live sandbox, PID space, or background processes will still be running later.
@ -108,6 +109,7 @@ For cloud sandboxes such as Modal and Daytona, `container_persistent: true` mean
| **modal** | Modal cloud sandbox | Full (cloud VM) | Ephemeral cloud compute, evals |
| **daytona** | Daytona workspace | Full (cloud container) | Managed cloud dev environments |
| **singularity** | Singularity/Apptainer container | Namespaces (--containall) | HPC clusters, shared machines |
| **koyeb** | Koyeb cloud sandbox | Full (cloud sandbox) | Serverless cloud execution |
### Local Backend
@ -242,6 +244,28 @@ terminal:
**Isolation:** Uses `--containall --no-home` for full namespace isolation without mounting the host home directory.
### Koyeb Backend
Runs commands in a [Koyeb](https://www.koyeb.com) cloud sandbox. Each task gets an isolated sandbox that is deleted on cleanup.
```yaml
terminal:
backend: koyeb
koyeb_image: "koyeb/sandbox:latest"
```
**Required:** `KOYEB_API_TOKEN` environment variable. Get one from the [Koyeb control panel](https://app.koyeb.com/account/api).
**Install the SDK:**
```bash
pip install "hermes-agent[koyeb]"
```
**Lifecycle:** A new sandbox is created for each task and deleted when the agent cleans up. There is no persistent state between sessions.
**File sync:** `~/.hermes/` credentials and skills are synced to the sandbox via a single tarball upload for fast initialization.
### Common Terminal Backend Issues
If terminal commands fail immediately or the terminal tool is reported as disabled:
@ -252,6 +276,7 @@ If terminal commands fail immediately or the terminal tool is reported as disabl
- **Modal** — Needs `MODAL_TOKEN_ID` env var or `~/.modal.toml`. Run `hermes doctor` to check.
- **Daytona** — Needs `DAYTONA_API_KEY`. The Daytona SDK handles server URL configuration.
- **Singularity** — Needs `apptainer` or `singularity` in `$PATH`. Common on HPC clusters.
- **Koyeb** — Needs `KOYEB_API_TOKEN` and `pip install koyeb-sdk`. Run `hermes doctor` to check.
When in doubt, set `terminal.backend` back to `local` and verify that commands run there first.

View file

@ -64,13 +64,14 @@ The terminal tool can execute commands in different environments:
| `singularity` | HPC containers | Cluster computing, rootless |
| `modal` | Cloud execution | Serverless, scale |
| `daytona` | Cloud sandbox workspace | Persistent remote dev environments |
| `koyeb` | Koyeb cloud sandbox | Serverless cloud execution |
### Configuration
```yaml
# In ~/.hermes/config.yaml
terminal:
backend: local # or: docker, ssh, singularity, modal, daytona
backend: local # or: docker, ssh, singularity, modal, daytona, koyeb
cwd: "." # Working directory
timeout: 180 # Command timeout in seconds
```
@ -123,7 +124,7 @@ Configure CPU, memory, disk, and persistence for all container backends:
```yaml
terminal:
backend: docker # or singularity, modal, daytona
backend: docker # or singularity, modal, daytona, koyeb
container_cpu: 1 # CPU cores (default: 1)
container_memory: 5120 # Memory in MB (default: 5GB)
container_disk: 51200 # Disk in MB (default: 50GB)