mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-30 16:01:49 +08:00
PR #17660 landed a sweep of CI fixes but left three loose ends:
1. tests/cli/test_cli_loading_indicator.py::test_reload_mcp_sets_busy_state_
and_prints_status — /reload-mcp gained a prompt-cache-invalidation
confirmation (commit 4d7fc0f37) that was never wired into this test.
The test exercises the loading-indicator path, so pre-approve via
config and go straight into _reload_mcp().
2. tools/mcp_tool.py _make_tool_handler — the added
getattr(server, '_rpc_lock', None) + 'skip the lock if missing'
branch is inconsistent with four sibling call sites that still
direct-access server._rpc_lock. The lock is guaranteed by
MCPServerTask.__init__; falling through to an unlocked
session.call_tool would silently serialize-strip RPCs if the guard
ever triggered. Restore direct access.
3. tui_gateway/server.py _messages_as_conversation — the helper
existed only to catch 'TypeError: include_ancestors unexpected'
from mocked SessionDBs that don't actually exist. The real
SessionDB.get_messages_as_conversation has accepted
include_ancestors since introduction, and every test FakeDB in
the repo already declares the kwarg. Remove the shim, inline the
two call sites.
73 lines
2.7 KiB
Python
73 lines
2.7 KiB
Python
"""Regression tests for loading feedback on slow slash commands."""
|
|
|
|
from unittest.mock import patch
|
|
|
|
from cli import HermesCLI
|
|
|
|
|
|
class TestCLILoadingIndicator:
|
|
def _make_cli(self):
|
|
cli_obj = HermesCLI.__new__(HermesCLI)
|
|
cli_obj._app = None
|
|
cli_obj._last_invalidate = 0.0
|
|
cli_obj._command_running = False
|
|
cli_obj._command_status = ""
|
|
return cli_obj
|
|
|
|
def test_skills_command_sets_busy_state_and_prints_status(self, capsys):
|
|
cli_obj = self._make_cli()
|
|
seen = {}
|
|
|
|
def fake_handle(cmd: str):
|
|
seen["cmd"] = cmd
|
|
seen["running"] = cli_obj._command_running
|
|
seen["status"] = cli_obj._command_status
|
|
print("skills done")
|
|
|
|
with patch.object(cli_obj, "_handle_skills_command", side_effect=fake_handle), \
|
|
patch.object(cli_obj, "_invalidate") as invalidate_mock:
|
|
assert cli_obj.process_command("/skills search kubernetes")
|
|
|
|
output = capsys.readouterr().out
|
|
assert "⏳ Searching skills..." in output
|
|
assert "skills done" in output
|
|
assert seen == {
|
|
"cmd": "/skills search kubernetes",
|
|
"running": True,
|
|
"status": "Searching skills...",
|
|
}
|
|
assert cli_obj._command_running is False
|
|
assert cli_obj._command_status == ""
|
|
assert invalidate_mock.call_count == 2
|
|
|
|
def test_reload_mcp_sets_busy_state_and_prints_status(self, capsys):
|
|
cli_obj = self._make_cli()
|
|
seen = {}
|
|
|
|
def fake_reload():
|
|
seen["running"] = cli_obj._command_running
|
|
seen["status"] = cli_obj._command_status
|
|
print("reload done")
|
|
|
|
# /reload-mcp now wraps the actual reload in a prompt-cache-invalidation
|
|
# confirmation prompt (commit 4d7fc0f37). This test exercises the
|
|
# loading-indicator path, not the confirmation UX, so pre-approve the
|
|
# reload via config so the handler goes straight into _reload_mcp().
|
|
fake_cfg = {"approvals": {"mcp_reload_confirm": False}}
|
|
|
|
with patch.object(cli_obj, "_reload_mcp", side_effect=fake_reload), \
|
|
patch.object(cli_obj, "_invalidate") as invalidate_mock, \
|
|
patch("cli.load_cli_config", return_value=fake_cfg):
|
|
assert cli_obj.process_command("/reload-mcp")
|
|
|
|
output = capsys.readouterr().out
|
|
assert "⏳ Reloading MCP servers..." in output
|
|
assert "reload done" in output
|
|
assert seen == {
|
|
"running": True,
|
|
"status": "Reloading MCP servers...",
|
|
}
|
|
assert cli_obj._command_running is False
|
|
assert cli_obj._command_status == ""
|
|
assert invalidate_mock.call_count == 2
|