fix(tui_gateway): export session profile to tool subprocesses

_set_session_context() populated session id/source/cwd but omitted the
session's profile, so a non-launch Desktop session never exported
HERMES_SESSION_PROFILE to its tools; tools/terminal_tool.py reads it for
the docker container/profile slot.

Trimmed to the surviving Desktop-side change of #72480 — the local/PTY
terminal, docker, and execute_code surfaces landed on main via 7138b9587a.
This commit is contained in:
Franco Roldán
2026-09-10 17:10:36 -03:00
committed by Teknium
parent 1eb5cd6124
commit 63e4e040bc
2 changed files with 41 additions and 1 deletions

View File

@@ -37,7 +37,14 @@ class _FakeAgent:
self.session_id = session_id
def _install_session(monkeypatch, *, session_key, agent_session_id, source="cli"):
def _install_session(
monkeypatch,
*,
session_key,
agent_session_id,
source="cli",
profile_home=None,
):
"""Register a fake session in server._sessions for the duration of a test."""
sess = {
"session_key": session_key,
@@ -45,6 +52,8 @@ def _install_session(monkeypatch, *, session_key, agent_session_id, source="cli"
"agent": _FakeAgent(agent_session_id) if agent_session_id is not None else None,
"cwd": "/home/user",
}
if profile_home is not None:
sess["profile_home"] = str(profile_home)
monkeypatch.setattr(server, "_sessions", {session_key: sess}, raising=False)
return sess
@@ -70,3 +79,30 @@ def test_set_session_context_falls_back_to_session_key(monkeypatch):
assert get_session_env("HERMES_SESSION_ID") == "skey-xyz"
def test_set_session_context_injects_session_profile(tmp_path, monkeypatch):
"""A non-launch Desktop session exports its own profile name to tools."""
profile_home = tmp_path / "profiles" / "work"
_install_session(
monkeypatch,
session_key="skey-work",
agent_session_id="session-work",
profile_home=profile_home,
)
server._set_session_context("skey-work")
assert get_session_env("HERMES_SESSION_PROFILE") == "work"
def test_set_session_context_uses_launch_profile_without_override(monkeypatch):
"""Launch-profile sessions also receive a non-empty profile identity."""
monkeypatch.setattr(server, "_current_profile_name", lambda: "default")
_install_session(
monkeypatch,
session_key="skey-default",
agent_session_id="session-default",
)
server._set_session_context("skey-default")
assert get_session_env("HERMES_SESSION_PROFILE") == "default"

View File

@@ -1249,12 +1249,15 @@ def _set_session_context(session_key: str, cwd: str | None = None, *, ui_session
# callers that know the workspace pass it.
resolved = cwd if cwd is not None else (str(sess.get("cwd") or "") if sess is not None else "")
source = _resolve_session_platform()
profile = _current_profile_name()
browser_control_principal = browser_control_transport_family = ""
# Live conversation id for subprocess HERMES_SESSION_ID: an explicitly empty contextvar is authoritative
# (no os.environ fallback), so never leave it "" — agent's durable session_id, then session_key.
session_id = session_key
if sess is not None:
source = _session_source(sess)
# App-global backends multiplex profiles: prefer the live session's own home.
profile = profile_name_for_home(sess.get("profile_home")) or profile
session_id = getattr(sess.get("agent"), "session_id", None) or session_key
identity = getattr(sess.get("transport"), "auth_identity", None)
if _methods_browser_control._is_authenticated_identity(identity):
@@ -1262,6 +1265,7 @@ def _set_session_context(session_key: str, cwd: str | None = None, *, ui_session
browser_control_transport_family = _methods_browser_control._CLOUD_TRANSPORT_FAMILY
return set_session_vars(
session_key=session_key, session_id=session_id, source=source,
profile=profile,
browser_control_principal=browser_control_principal,
browser_control_transport_family=browser_control_transport_family, cwd=resolved,
ui_session_id=ui_session_id, cron_session="")