fix(hermes): preserve reconnect history and browser access
Some checks failed
Tests / Declarative: Post Actions failed: 2, passed: 173

This commit is contained in:
jenkins 2026-08-09 13:19:12 -03:00
parent 36399fce6e
commit fcef1f79f5
5 changed files with 55 additions and 2 deletions

View File

@ -120,6 +120,13 @@ data:
tool_progress: all
interim_assistant_messages: true
long_running_notifications: true
# The upstream reconnect recap clips older messages to 300/200 chars.
# Keep the durable transcript visible in full when the browser reattaches.
resume_exchanges: 10000
resume_max_user_chars: 10000000
resume_max_assistant_chars: 10000000
resume_max_assistant_lines: 1000000
resume_skip_tool_only: true
tool_loop_guardrails:
warnings_enabled: true

View File

@ -24,7 +24,7 @@ spec:
ai.bstein.dev/execution: Herdr-supervised Codex and Claude Code
ai.bstein.dev/model-policy: Jetson-assisted AUTO routing, low through xhigh, cross-provider fallback
ai.bstein.dev/placement: rpi5 preferred; Jetson deferred until state storage is available
ai.bstein.dev/config-rev: "20260809-browser-delegation-tools"
ai.bstein.dev/config-rev: "20260809-browser-runtime-complete-resume"
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: hermes-agent
vault.hashicorp.com/agent-inject-secret-anthropic-token: kv/data/atlas/hermes/agent-tokens
@ -277,6 +277,9 @@ spec:
- {name: HERDR_CONFIG_PATH, value: /opt/data/home/.config/herdr/config.toml}
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
- {name: PATH, value: /opt/data/tools/bin:/opt/data/home/.local/bin:/opt/hermes/.venv/bin:/opt/hermes/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin}
- {name: PLAYWRIGHT_BROWSERS_PATH, value: /opt/hermes/.playwright}
- {name: AGENT_BROWSER_EXECUTABLE_PATH, value: /opt/hermes/.playwright/chromium_headless_shell-1228/chrome-linux/headless_shell}
- {name: AGENT_BROWSER_ARGS, value: "--no-sandbox,--disable-dev-shm-usage"}
- {name: HERMES_DASHBOARD, value: "0"}
- {name: HERMES_DASHBOARD_PUBLIC_URL, value: https://agent.hermes.bstein.dev}
- {name: API_SERVER_ENABLED, value: "true"}
@ -478,6 +481,9 @@ spec:
--env HERMES_AUTH_FILE=/shared-auth/auth.json \
--env HOME=/opt/data/home \
--env PYTHONPATH=/opt/hermes \
--env PLAYWRIGHT_BROWSERS_PATH=/opt/hermes/.playwright \
--env AGENT_BROWSER_EXECUTABLE_PATH=/opt/hermes/.playwright/chromium_headless_shell-1228/chrome-linux/headless_shell \
--env AGENT_BROWSER_ARGS=--no-sandbox,--disable-dev-shm-usage \
--focus)"
pane="$(printf '%s' "${created}" | /opt/hermes/.venv/bin/python -c \
'import json,sys; print(json.load(sys.stdin)["result"]["root_pane"]["pane_id"])')"
@ -510,6 +516,9 @@ spec:
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
- {name: PYTHONPATH, value: /opt/hermes}
- {name: PATH, value: /opt/data/tools/bin:/opt/hermes/.venv/bin:/usr/local/bin:/usr/bin:/bin}
- {name: PLAYWRIGHT_BROWSERS_PATH, value: /opt/hermes/.playwright}
- {name: AGENT_BROWSER_EXECUTABLE_PATH, value: /opt/hermes/.playwright/chromium_headless_shell-1228/chrome-linux/headless_shell}
- {name: AGENT_BROWSER_ARGS, value: "--no-sandbox,--disable-dev-shm-usage"}
securityContext:
allowPrivilegeEscalation: false
runAsUser: 10000

View File

@ -28,7 +28,7 @@ spec:
ai.bstein.dev/role: isolated-user-chat
ai.bstein.dev/isolation: one Hermes process and PVC per Keycloak subject
ai.bstein.dev/model-policy: uniform automatic policy with per-user overrides
ai.bstein.dev/config-rev: "20260809-browser-files-auth-refresh"
ai.bstein.dev/config-rev: "20260809-browser-runtime-path"
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: hermes-chat
vault.hashicorp.com/agent-inject-secret-anthropic-token: kv/data/atlas/hermes/agent-tokens
@ -185,6 +185,9 @@ spec:
- {name: TERMINAL_CWD, value: /opt/data/workspace}
- {name: HERMES_WRITE_SAFE_ROOT, value: /opt/data/workspace}
- {name: PATH, value: /opt/data/home/.local/bin:/opt/hermes/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin}
- {name: PLAYWRIGHT_BROWSERS_PATH, value: /opt/hermes/.playwright}
- {name: AGENT_BROWSER_EXECUTABLE_PATH, value: /opt/hermes/.playwright/chromium_headless_shell-1228/chrome-linux/headless_shell}
- {name: AGENT_BROWSER_ARGS, value: "--no-sandbox,--disable-dev-shm-usage"}
- {name: HERMES_DASHBOARD, value: "0"}
- {name: API_SERVER_ENABLED, value: "true"}
- {name: API_SERVER_HOST, value: 0.0.0.0}

View File

@ -128,6 +128,13 @@ def test_chat_auth_file_mount_survives_atomic_provider_refresh():
assert mount["mountPath"] == "/shared-auth"
assert "subPath" not in mount
hermes_env = {
item["name"]: item["value"]
for item in next(item for item in containers if item["name"] == "hermes")["env"]
}
assert hermes_env["AGENT_BROWSER_EXECUTABLE_PATH"].endswith("/chrome-linux/headless_shell")
assert "--no-sandbox" in hermes_env["AGENT_BROWSER_ARGS"]
def test_sandbox_executes_python_with_bounded_output(tmp_path: Path, monkeypatch):
source = ROOT / "dockerfiles" / "hermes-chat-sandbox-server.py"

View File

@ -199,6 +199,11 @@ def test_agent_installs_hermes_integration_before_startup():
env = {item["name"]: item["value"] for item in containers[name]["env"]}
assert "/opt/hermes/.venv/bin" in env["PATH"].split(":")
for name in ("hermes", "herdr-server"):
env = {item["name"]: item["value"] for item in containers[name]["env"]}
assert env["AGENT_BROWSER_EXECUTABLE_PATH"].endswith("/chrome-linux/headless_shell")
assert "--no-sandbox" in env["AGENT_BROWSER_ARGS"]
server_command = containers["herdr-server"]["command"][-1]
assert 'herdr pane process-info --pane "${pane}"' in server_command
assert 'herdr workspace close "${workspace}"' in server_command
@ -208,6 +213,7 @@ def test_agent_installs_hermes_integration_before_startup():
assert "herdr agent start coordinator" in server_command
assert "--kind hermes" in server_command
assert "--timeout 60000" in server_command
assert "--env AGENT_BROWSER_EXECUTABLE_PATH=" in server_command
tui_command = containers["herdr-tui"]["args"][0]
assert "while true" in tui_command
@ -233,6 +239,27 @@ def test_agent_mounts_auto_router_into_both_hermes_runtimes():
assert volume["configMap"]["name"] == "hermes-auto-router-plugin"
def test_agent_reconnect_renders_complete_conversation_history():
documents = [
document
for document in yaml.safe_load_all((HERMES / "agent-configmap.yaml").read_text())
if document
]
config_map = next(
document
for document in documents
if document["kind"] == "ConfigMap"
and document["metadata"]["name"] == "hermes-agent-config"
)
config = yaml.safe_load(config_map["data"]["config.yaml"])
display = config["display"]
assert display["resume_exchanges"] >= 10000
assert display["resume_max_user_chars"] >= 10000000
assert display["resume_max_assistant_chars"] >= 10000000
assert display["resume_max_assistant_lines"] >= 1000000
def test_agent_coordinator_has_a_long_running_tool_budget():
configmap = yaml.safe_load((HERMES / "agent-configmap.yaml").read_text())
config = yaml.safe_load(configmap["data"]["config.yaml"])