mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
Salvaged from #57016 by @lEWFkRAD: - cli.py: handle file:///C:/... drive-letter URIs on nt (strip the leading slash urlparse leaves); join Termux example paths with literal forward slashes so hints stay POSIX on Windows. - gateway/status.py + hermes_cli/gateway.py: normalize backslashes to forward slashes before the HERMES_HOME substring match so separator style cannot defeat profile ownership detection. - hermes_cli/banner.py: cprint degrades to plain print when prompt_toolkit has no console (NoConsoleScreenBufferError on redirected/absent Windows stdout). - hermes_cli/browser_connect.py: posixpath.join for WSL /mnt/c/... bases (os.path.join would emit backslashes on nt). - Test hardening: symlink skip-guards, USERPROFILE alongside HOME for ntpath.expanduser, SIGKILL absence skipif fixed via monkeypatch, drive-letter URI / separator-normalization / banner-fallback coverage. Dropped from the original PR: tests/cli/conftest.py fixture and the AppSession _output monkeypatch — main's merged tests/cli/conftest.py already handles that prompt_toolkit pollution.
85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
"""Tests for banner toolset name normalization and skin color usage."""
|
|
|
|
from unittest.mock import patch
|
|
|
|
from rich.console import Console
|
|
|
|
import hermes_cli.banner as banner
|
|
import model_tools
|
|
import tools.mcp_tool
|
|
|
|
|
|
def test_cprint_falls_back_to_plain_print_when_prompt_toolkit_has_no_console(capsys):
|
|
with patch(
|
|
"prompt_toolkit.print_formatted_text",
|
|
side_effect=RuntimeError("no console screen buffer"),
|
|
):
|
|
banner.cprint("fallback text")
|
|
|
|
assert capsys.readouterr().out == "fallback text\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_build_welcome_banner_title_falls_back_when_no_tag():
|
|
"""Without a resolvable tag, the panel title renders as plain text (no hyperlink escape)."""
|
|
import io
|
|
from unittest.mock import patch as _patch
|
|
import hermes_cli.banner as _banner
|
|
import model_tools as _mt
|
|
import tools.mcp_tool as _mcp
|
|
|
|
_banner._latest_release_cache = None
|
|
buf = io.StringIO()
|
|
with (
|
|
_patch.object(_mt, "check_tool_availability", return_value=(["web"], [])),
|
|
_patch.object(_banner, "get_available_skills", return_value={}),
|
|
_patch.object(_banner, "get_update_result", return_value=None),
|
|
_patch.object(_mcp, "get_mcp_status", return_value=[]),
|
|
_patch.object(_banner, "get_latest_release_tag", return_value=None),
|
|
):
|
|
console = Console(file=buf, force_terminal=True, color_system="truecolor", width=160)
|
|
_banner.build_welcome_banner(
|
|
console=console, model="x", cwd="/tmp",
|
|
session_id="abc123",
|
|
tools=[{"function": {"name": "read_file"}}],
|
|
get_toolset_for_tool=lambda n: "file",
|
|
)
|
|
|
|
raw = buf.getvalue()
|
|
assert "Hermes Agent v" in raw, "Version label missing from title"
|
|
assert "\x1b]8;" not in raw, "OSC-8 hyperlink should not be emitted without a tag"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_build_welcome_banner_non_moa_unchanged(tmp_path, monkeypatch):
|
|
"""A normal provider still renders the bare model slug, no MoA prefix."""
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
|
(tmp_path / ".hermes").mkdir()
|
|
|
|
with (
|
|
patch.object(model_tools, "check_tool_availability", return_value=([], [])),
|
|
patch.object(banner, "get_available_skills", return_value={}),
|
|
patch.object(banner, "get_update_result", return_value=None),
|
|
patch.object(tools.mcp_tool, "get_mcp_status", return_value=[]),
|
|
):
|
|
console = Console(record=True, force_terminal=False, color_system=None, width=160)
|
|
banner.build_welcome_banner(
|
|
console=console,
|
|
model="anthropic/claude-opus-4.8",
|
|
cwd="/tmp/project",
|
|
tools=[],
|
|
enabled_toolsets=[],
|
|
provider="openrouter",
|
|
)
|
|
|
|
out = console.export_text()
|
|
assert "claude-opus-4.8" in out
|
|
assert "MoA:" not in out
|