mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-05 02:31:47 +00:00
fix(cli): CLI/TUI on local backend always uses launch directory, ignores terminal.cwd (#19242)
CLI/TUI sessions on the local backend now unconditionally use os.getcwd() as the working directory. The terminal.cwd config value is only consumed by gateway/cron/delegation modes (where there's no shell to cd from). Previously, 'hermes setup' would write an absolute path (e.g. $HOME) into terminal.cwd which then pinned the CLI to that directory regardless of where the user launched hermes from. This was a silent foot-gun — the user's 'cd' was being ignored. Changes: 1. cli.py: Restructured CWD resolution — if TERMINAL_CWD is not already set by the gateway, and the backend is local, always use os.getcwd(). Config terminal.cwd is irrelevant for interactive CLI/TUI sessions. 2. setup.py: Moved the cwd prompt from setup_terminal_backend() to setup_gateway(). It now only appears when configuring messaging platforms and is labeled 'Gateway working directory'. 3. Tests: Rewrote test_cwd_env_respect.py to validate the new behavior: explicit config paths are ignored for CLI, gateway pre-set values are preserved, non-local backends keep their config paths. 4. Docs: Updated configuration.md, profiles.md, and environment-variables.md to clarify that terminal.cwd only affects gateway/cron mode on local backend. Closes #19214
This commit is contained in:
parent
b8ae8cc801
commit
9eaddfafa3
6 changed files with 122 additions and 72 deletions
48
cli.py
48
cli.py
|
|
@ -459,32 +459,30 @@ def load_cli_config() -> Dict[str, Any]:
|
|||
if "backend" in terminal_config:
|
||||
terminal_config["env_type"] = terminal_config["backend"]
|
||||
|
||||
# Handle special cwd values: "." or "auto" means use current working directory.
|
||||
# Only resolve to the host's CWD for the local backend where the host
|
||||
# filesystem is directly accessible. For ALL remote/container backends
|
||||
# (ssh, docker, modal, singularity), the host path doesn't exist on the
|
||||
# target -- remove the key so terminal_tool.py uses its per-backend default.
|
||||
#
|
||||
# GUARD: If TERMINAL_CWD is already set to a real absolute path (by the
|
||||
# gateway's config bridge earlier in the process), don't clobber it.
|
||||
# This prevents a lazy import of cli.py during gateway runtime from
|
||||
# rewriting TERMINAL_CWD to the service's working directory.
|
||||
# See issue #10817.
|
||||
# CWD resolution: CLI/TUI on local backend always uses os.getcwd();
|
||||
# gateway/cron uses terminal.cwd from config. Detection: gateway's config
|
||||
# bridge (gateway/run.py) sets TERMINAL_CWD before this runs.
|
||||
# See #19214, #4672, #10225, #10817.
|
||||
_CWD_PLACEHOLDERS = (".", "auto", "cwd")
|
||||
if terminal_config.get("cwd") in _CWD_PLACEHOLDERS:
|
||||
_existing_cwd = os.environ.get("TERMINAL_CWD", "")
|
||||
if _existing_cwd and _existing_cwd not in _CWD_PLACEHOLDERS and os.path.isabs(_existing_cwd):
|
||||
# Gateway (or earlier startup) already resolved a real path — keep it
|
||||
terminal_config["cwd"] = _existing_cwd
|
||||
defaults["terminal"]["cwd"] = _existing_cwd
|
||||
else:
|
||||
effective_backend = terminal_config.get("env_type", "local")
|
||||
if effective_backend == "local":
|
||||
terminal_config["cwd"] = os.getcwd()
|
||||
defaults["terminal"]["cwd"] = terminal_config["cwd"]
|
||||
else:
|
||||
# Remove so TERMINAL_CWD stays unset → tool picks backend default
|
||||
terminal_config.pop("cwd", None)
|
||||
_existing_cwd = os.environ.get("TERMINAL_CWD", "")
|
||||
_is_gateway_import = (
|
||||
_existing_cwd
|
||||
and _existing_cwd not in _CWD_PLACEHOLDERS
|
||||
and os.path.isabs(_existing_cwd)
|
||||
)
|
||||
effective_backend = terminal_config.get("env_type", "local")
|
||||
|
||||
if _is_gateway_import:
|
||||
terminal_config["cwd"] = _existing_cwd
|
||||
defaults["terminal"]["cwd"] = _existing_cwd
|
||||
elif effective_backend == "local":
|
||||
# CLI/TUI: user's `cd` is the config — ignore terminal.cwd.
|
||||
terminal_config["cwd"] = os.getcwd()
|
||||
defaults["terminal"]["cwd"] = terminal_config["cwd"]
|
||||
elif terminal_config.get("cwd") in _CWD_PLACEHOLDERS:
|
||||
# Non-local backend with placeholder — let terminal_tool use its default.
|
||||
terminal_config.pop("cwd", None)
|
||||
# else: non-local backend with explicit path — keep as-is
|
||||
|
||||
env_mappings = {
|
||||
"env_type": "TERMINAL_ENV",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue