fix(dashboard): preserve placeholder cwd fallback
This commit is contained in:
+21
-2
@@ -3529,6 +3529,25 @@ def _terminal_env_value(value: Any) -> str:
|
||||
return str(value)
|
||||
|
||||
|
||||
def _terminal_config_value_is_bridgeable(key: str, value: Any) -> bool:
|
||||
"""Return whether a terminal config value owns its mirrored env var."""
|
||||
if key == "cwd" and str(value or "").strip() in {".", "auto", "cwd"}:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def terminal_config_owned_env_vars(terminal_config: Any) -> Set[str]:
|
||||
"""Return env vars explicitly owned by a raw ``terminal`` config section."""
|
||||
if not isinstance(terminal_config, dict):
|
||||
return set()
|
||||
return {
|
||||
env_var
|
||||
for key, env_var in TERMINAL_CONFIG_ENV_MAP.items()
|
||||
if key in terminal_config
|
||||
and _terminal_config_value_is_bridgeable(key, terminal_config[key])
|
||||
}
|
||||
|
||||
|
||||
def terminal_config_env_var_for_key(key: str) -> Optional[str]:
|
||||
"""Return the env var mirrored by a ``terminal.*`` config key."""
|
||||
prefix = "terminal."
|
||||
@@ -3599,10 +3618,10 @@ def apply_terminal_config_to_env(
|
||||
if cfg_key not in terminal_cfg:
|
||||
continue
|
||||
value = terminal_cfg[cfg_key]
|
||||
if not _terminal_config_value_is_bridgeable(cfg_key, value):
|
||||
continue
|
||||
if cfg_key == "cwd":
|
||||
raw_cwd = str(value or "").strip()
|
||||
if raw_cwd in {".", "auto", "cwd"}:
|
||||
continue
|
||||
if isinstance(value, str) and not _is_ssh_remote_tilde_cwd(
|
||||
terminal_backend, raw_cwd
|
||||
):
|
||||
|
||||
@@ -16380,9 +16380,9 @@ def _resolve_chat_argv(
|
||||
env["HERMES_HOME"] = str(profile_dir)
|
||||
try:
|
||||
from hermes_cli.config import (
|
||||
TERMINAL_CONFIG_ENV_MAP,
|
||||
apply_terminal_config_to_env,
|
||||
read_raw_config,
|
||||
terminal_config_owned_env_vars,
|
||||
)
|
||||
|
||||
if profile_dir is not None:
|
||||
@@ -16392,12 +16392,7 @@ def _resolve_chat_argv(
|
||||
# exported by the operator for keys omitted from the launch profile
|
||||
# remain valid fallbacks, matching apply_terminal_config_to_env().
|
||||
raw_launch_terminal = read_raw_config().get("terminal")
|
||||
if not isinstance(raw_launch_terminal, dict):
|
||||
raw_launch_terminal = {}
|
||||
for config_key in raw_launch_terminal:
|
||||
env_var = TERMINAL_CONFIG_ENV_MAP.get(config_key)
|
||||
if env_var is None:
|
||||
continue
|
||||
for env_var in terminal_config_owned_env_vars(raw_launch_terminal):
|
||||
env.pop(env_var, None)
|
||||
with _config_profile_scope(requested):
|
||||
apply_terminal_config_to_env(env=env)
|
||||
|
||||
@@ -710,6 +710,34 @@ class TestProfileScopedChatPty:
|
||||
assert env["TERMINAL_ENV"] == "docker"
|
||||
assert env["TERMINAL_SSH_USER"] == "operator-user"
|
||||
|
||||
@pytest.mark.parametrize("placeholder", [".", "auto", "cwd"])
|
||||
def test_chat_argv_placeholder_cwd_preserves_exported_value(
|
||||
self, isolated_profiles, monkeypatch, placeholder
|
||||
):
|
||||
import hermes_cli.web_server as web_server
|
||||
|
||||
(isolated_profiles["default"] / "config.yaml").write_text(
|
||||
f"terminal:\n backend: docker\n cwd: {placeholder}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(isolated_profiles["worker_beta"] / "config.yaml").write_text(
|
||||
"terminal:\n backend: ssh\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setenv("TERMINAL_ENV", "docker")
|
||||
monkeypatch.setenv("TERMINAL_CWD", "/operator/work")
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.main._make_tui_argv",
|
||||
lambda root, tui_dev=False: (["cat"], None),
|
||||
raising=False,
|
||||
)
|
||||
|
||||
_argv, _cwd, env = web_server._resolve_chat_argv(profile="worker_beta")
|
||||
|
||||
assert env is not None
|
||||
assert env["TERMINAL_ENV"] == "ssh"
|
||||
assert env["TERMINAL_CWD"] == "/operator/work"
|
||||
|
||||
def test_chat_argv_warns_when_profile_terminal_bridge_fails(
|
||||
self, isolated_profiles, monkeypatch, caplog
|
||||
):
|
||||
@@ -718,6 +746,11 @@ class TestProfileScopedChatPty:
|
||||
import hermes_cli.config as config_mod
|
||||
import hermes_cli.web_server as web_server
|
||||
|
||||
(isolated_profiles["default"] / "config.yaml").write_text(
|
||||
"terminal:\n backend: docker\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setenv("TERMINAL_ENV", "docker")
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.main._make_tui_argv",
|
||||
lambda root, tui_dev=False: (["cat"], None),
|
||||
@@ -734,6 +767,7 @@ class TestProfileScopedChatPty:
|
||||
|
||||
assert env is not None
|
||||
assert env["HERMES_HOME"] == str(isolated_profiles["worker_beta"])
|
||||
assert "TERMINAL_ENV" not in env
|
||||
assert "Failed to apply terminal config bridge for dashboard chat" in caplog.text
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user