hermes - ✅(Solved) Fix Daytona backend hardcodes `auto_stop_interval=0`; expose Daytona auto-stop/auto-delete as config [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#28804Fetched 2026-05-20 04:01:52
View on GitHub
Comments
0
Participants
1
Timeline
8
Reactions
0
Author
Participants
Timeline (top)
labeled ×5referenced ×2cross-referenced ×1

Fix Action

Fixed

PR fix notes

PR #28850: feat(daytona): expose auto-stop/auto-archive/auto-delete as terminal.* config keys

Description (problem / solution / changelog)

What does this PR do?

tools/environments/daytona.py was creating sandboxes with auto_stop_interval=0 (disabled) and never passed auto_archive_interval / auto_delete_interval, so a worker that crashes or is orphaned by a gateway restart leaves its Daytona sandbox running indefinitely until the account quota is exhausted — cleanup() only fires on a clean exit, and the in-process idle reaper only covers envs the current gateway tracks.

This PR wires all three Daytona sandbox-lifecycle intervals through the existing terminal.* config plumbing so users can opt into Daytona's native reaping without forking the backend.

Defaults preserve current behavior: daytona_auto_stop_interval stays at 0 (matching the prior hard-coded value), and auto_archive_interval / auto_delete_interval are omitted from the CreateSandboxFromImageParams call when unset so Daytona's SDK / account-level defaults remain authoritative.

Mirrors the existing terminal-config bridge precedence: config.yaml > .env > TERMINAL_DAYTONA_AUTO_* env vars, all consumed in _get_env_config() and forwarded into DaytonaEnvironment.__init__. The CLI (cli.py), gateway (gateway/run.py), and set_config_value env-sync maps are all updated in lockstep so the test_cli_and_gateway_env_maps_agree invariant continues to hold (this is the exact regression class that shipped silently for docker_run_as_host_user in April 2026).

Related Issue

Fixes #28804

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • tools/environments/daytona.pyDaytonaEnvironment.__init__ accepts auto_stop_interval (default 0, current behavior), auto_archive_interval (default None), auto_delete_interval (default None). Archive/delete are conditionally added to CreateSandboxFromImageParams so None means "use Daytona SDK / account default" rather than overriding to 0.
  • tools/terminal_tool.py_get_env_config() reads three new env vars (TERMINAL_DAYTONA_AUTO_STOP_INTERVAL, TERMINAL_DAYTONA_AUTO_ARCHIVE_INTERVAL, TERMINAL_DAYTONA_AUTO_DELETE_INTERVAL); _create_environment() forwards them to DaytonaEnvironment. Added _parse_optional_int_env() helper to keep "unset → SDK default" semantics distinct from "0".
  • hermes_cli/config.py — Defaults added to the terminal: section of DEFAULT_CONFIG, and entries added to _config_to_env_sync so hermes config set terminal.daytona_auto_stop_interval 15 propagates to .env.
  • cli.py + gateway/run.py — Same three keys added to the env_mappings / _terminal_env_map dicts so terminal.daytona_auto_* in config.yaml is bridged to env vars in both the CLI and gateway runtimes.
  • cli-config.yaml.example — Documented under the existing Daytona example block with a recommended starting point (15-minute auto-stop, 60-minute auto-archive, 24-hour auto-delete).
  • tests/tools/test_daytona_environment.py — New TestAutoStopConfig class covering: default auto_stop_interval=0 is still passed; explicit auto_stop_interval is forwarded; explicit auto_archive_interval / auto_delete_interval are forwarded; None for archive/delete is omitted from the create call (proves we don't override the SDK default to 0).

How to Test

  1. uv run --with pytest --with pytest-xdist --with pytest-asyncio python3 -m pytest tests/tools/test_daytona_environment.py tests/tools/test_terminal_config_env_sync.py -v — should be all green (30 + 5 new tests in the daytona file plus the 5 env-sync invariants).
  2. Regression guard for the new tests: revert tools/environments/daytona.py only, rerun TestAutoStopConfig — three of the four new tests fail with TypeError: DaytonaEnvironment.__init__() got an unexpected keyword argument 'auto_stop_interval', confirming the new tests would have caught the missing wiring.
  3. Live smoke (optional): set terminal.daytona_auto_stop_interval: 15 in config.yaml, run hermes chat with terminal.backend: daytona, kill the worker mid-task — confirm the sandbox stops itself ~15 minutes later in the Daytona dashboard instead of running indefinitely.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (feat(scope):, fix(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run focused tests for the touched code and all pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 15.x

Documentation & Housekeeping

  • I've updated relevant documentation (cli-config.yaml.example Daytona block)
  • I've updated cli-config.yaml.example because I added new config keys
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) — no platform-specific code paths touched
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

Audited siblings: confirmed the three new keys are mirrored across tools/terminal_tool._get_env_config, cli.load_cli_config:env_mappings, gateway/run.py:_terminal_env_map, and hermes_cli/config.py:_config_to_env_sync — i.e. every layer that bridges terminal.* keys to TERMINAL_* env vars. No widening needed; the invariant test test_cli_and_gateway_env_maps_agree enforces this.

Screenshots / Logs

None — config-plumbing change.

Changed files

  • cli-config.yaml.example (modified, +7/-0)
  • cli.py (modified, +9/-0)
  • gateway/run.py (modified, +9/-0)
  • hermes_cli/config.py (modified, +10/-0)
  • tests/tools/test_daytona_environment.py (modified, +133/-0)
  • tests/tools/test_parse_env_var.py (modified, +39/-0)
  • tools/environments/daytona.py (modified, +66/-7)
  • tools/terminal_tool.py (modified, +30/-0)
RAW_BUFFERClick to expand / collapse

Version: v0.14.0

Summary: In v0.14.0, tools/environments/daytona.py (~line 125) creates sandboxes with auto_stop_interval=0 (disabled) and never passes auto_archive_interval / auto_delete_interval. The Daytona SDK natively supports all three (CreateSandboxFromImageParams, plus runtime setters set_autostop_interval / set_auto_archive_interval / set_auto_delete_interval). No terminal.* config key exposes them.

Impact: A worker that crashes, blocks, or is orphaned by a gateway restart leaves its Daytona sandbox running indefinitely — cleanup() only runs on a clean exit, and the in-process idle reaper only covers envs the current gateway tracks. This silently consumes Daytona compute credits and storage; orphaned sandboxes accumulate until the account quota is exhausted.

Ask: Expose auto_stop_interval (and ideally auto_archive_interval / auto_delete_interval) as terminal.* config keys, and/or default auto_stop_interval to a non-zero value, so Daytona's native sandbox reaping is usable.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix Daytona backend hardcodes `auto_stop_interval=0`; expose Daytona auto-stop/auto-delete as config [1 pull requests, 1 participants]