mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(terminal): persistent sandbox envs survive between turns
`_cleanup_task_resources` was unconditionally calling `cleanup_vm()` at the end of every `run_conversation` (i.e. every user turn), tearing down the docker/daytona/modal sandbox container regardless of its `persistent_filesystem` setting. This contradicted the documented intent of `terminal.lifetime_seconds` (idle reaper) and `container_persistent`, and caused per-turn loss of `/workspace`, `~/.config`, agent CLI auth state, and any other content living inside the sandbox. The unconditional teardown was introduced infbd3a2fd("prevent leakage of morph instances between tasks", 2025-11-04) to plug a Morph backend leak, two days after `lifetime_seconds` shipped infaecbddd. It was later refactored into `_cleanup_task_resources` in70dd3a16without changing semantics. Code and docs have disagreed since. Fix: introduce `terminal_tool.is_persistent_env(task_id)` and skip the per-turn `cleanup_vm` when the active env is persistent. The idle reaper (`_cleanup_inactive_envs`) still tears persistent envs down once `terminal.lifetime_seconds` is exceeded. Non-persistent backends (Morph) are unchanged — still torn down per turn, preserving the original leak-prevention intent.
This commit is contained in:
parent
54db7cbbe1
commit
e7d3e9d767
2 changed files with 36 additions and 3 deletions
|
|
@ -814,6 +814,23 @@ def get_active_env(task_id: str):
|
|||
return _active_environments.get(task_id)
|
||||
|
||||
|
||||
def is_persistent_env(task_id: str) -> bool:
|
||||
"""Return True if the active environment for task_id is configured for
|
||||
cross-turn persistence (``persistent_filesystem=True``).
|
||||
|
||||
Used by the agent loop to skip per-turn teardown for backends whose whole
|
||||
point is to survive between turns (docker with ``container_persistent``,
|
||||
daytona, modal, etc.). Non-persistent backends (e.g. Morph) still get torn
|
||||
down at end-of-turn to prevent leakage. The idle reaper
|
||||
(``_cleanup_inactive_envs``) handles persistent envs once they exceed
|
||||
``terminal.lifetime_seconds``.
|
||||
"""
|
||||
env = get_active_env(task_id)
|
||||
if env is None:
|
||||
return False
|
||||
return bool(getattr(env, "_persistent", False))
|
||||
|
||||
|
||||
def get_active_environments_info() -> Dict[str, Any]:
|
||||
"""Get information about currently active environments."""
|
||||
info = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue