chore: uptick

This commit is contained in:
Brooklyn Nicholson
2026-05-02 03:19:39 -05:00
parent 420f68e4e2
commit db884f4646
240 changed files with 25206 additions and 3155 deletions
@@ -0,0 +1,167 @@
"""Unit tests for _SupervisorRegistry cache-hit healthcheck.
Verifies that get_or_start() does NOT return a cached supervisor whose
thread has exited or whose event loop has stopped. Avoids a real Chrome —
the only thing under test is the registry's cache decision.
"""
from __future__ import annotations
import threading
from types import SimpleNamespace
import pytest
from tools import browser_supervisor as bs
class _FakeLoop:
def __init__(self, running: bool) -> None:
self._running = running
def is_running(self) -> bool:
return self._running
def _make_fake_supervisor(cdp_url: str, *, thread_alive: bool, loop_running: bool):
"""Build a minimal stand-in for a CDPSupervisor entry in the registry.
Only the attributes touched by the healthcheck (_thread, _loop, cdp_url)
and by the teardown path (stop()) need to exist.
"""
if thread_alive:
# A thread that is actually running — parks on an Event we never set.
hold = threading.Event()
t = threading.Thread(target=hold.wait, daemon=True)
t.start()
# Attach the release hook so the test can let the thread exit.
setattr(t, "_release", hold.set)
else:
# An un-started thread — is_alive() returns False.
t = threading.Thread(target=lambda: None)
stop_calls: list[bool] = []
fake = SimpleNamespace(
cdp_url=cdp_url,
_thread=t,
_loop=_FakeLoop(loop_running),
stop=lambda: stop_calls.append(True),
)
fake._stop_calls = stop_calls # type: ignore[attr-defined]
return fake
@pytest.fixture
def isolated_registry():
"""A fresh registry instance, independent of the global SUPERVISOR_REGISTRY."""
return bs._SupervisorRegistry()
@pytest.fixture
def stub_cdp_supervisor(monkeypatch):
"""Replace CDPSupervisor in the module so recreate paths don't touch Chrome.
Returns a callable that reads the last-constructed fake out.
"""
created: list[SimpleNamespace] = []
class _StubSupervisor:
def __init__(self, *, task_id, cdp_url, dialog_policy, dialog_timeout_s):
self.task_id = task_id
self.cdp_url = cdp_url
self.dialog_policy = dialog_policy
self.dialog_timeout_s = dialog_timeout_s
# Healthy by default — real thread, running "loop".
hold = threading.Event()
self._thread = threading.Thread(target=hold.wait, daemon=True)
self._thread.start()
self._thread_release = hold.set # type: ignore[attr-defined]
self._loop = _FakeLoop(True)
self.start_called = False
self.stop_called = False
created.append(self)
def start(self, timeout: float = 15.0) -> None:
self.start_called = True
def stop(self) -> None:
self.stop_called = True
# Release the parked thread so the process exits cleanly.
release = getattr(self, "_thread_release", None)
if release is not None:
release()
monkeypatch.setattr(bs, "CDPSupervisor", _StubSupervisor)
yield created
# Teardown: release any parked threads in stubs the test left behind.
for s in created:
release = getattr(s, "_thread_release", None)
if release is not None:
release()
def test_cache_hit_returns_same_instance_when_healthy(
isolated_registry, stub_cdp_supervisor
):
"""Sanity: healthy cached supervisor is returned without recreate."""
first = isolated_registry.get_or_start(task_id="t1", cdp_url="http://h/1")
second = isolated_registry.get_or_start(task_id="t1", cdp_url="http://h/1")
assert first is second
# Only one CDPSupervisor was ever constructed.
assert len(stub_cdp_supervisor) == 1
first.stop()
def test_dead_thread_triggers_recreate(isolated_registry, stub_cdp_supervisor):
"""Cached supervisor with a non-live thread must not be reused."""
cdp_url = "http://h/2"
dead = _make_fake_supervisor(cdp_url, thread_alive=False, loop_running=True)
isolated_registry._by_task["t2"] = dead # pre-seed cache with a dead entry
fresh = isolated_registry.get_or_start(task_id="t2", cdp_url=cdp_url)
assert fresh is not dead, "dead-thread supervisor must be replaced"
assert dead._stop_calls == [True], "dead supervisor must be torn down"
assert isolated_registry._by_task["t2"] is fresh
assert len(stub_cdp_supervisor) == 1
assert stub_cdp_supervisor[0].start_called
fresh.stop()
def test_stopped_loop_triggers_recreate(isolated_registry, stub_cdp_supervisor):
"""Cached supervisor whose event loop is no longer running is recreated."""
cdp_url = "http://h/3"
broken = _make_fake_supervisor(cdp_url, thread_alive=True, loop_running=False)
isolated_registry._by_task["t3"] = broken
fresh = isolated_registry.get_or_start(task_id="t3", cdp_url=cdp_url)
assert fresh is not broken
assert broken._stop_calls == [True]
# Release the still-live thread from the pre-seeded fake so we don't leak.
release = getattr(broken._thread, "_release", None)
if release is not None:
release()
assert isolated_registry._by_task["t3"] is fresh
fresh.stop()
def test_missing_thread_and_loop_attrs_trigger_recreate(
isolated_registry, stub_cdp_supervisor
):
"""Defensive: None _thread or None _loop counts as unhealthy."""
cdp_url = "http://h/4"
broken = SimpleNamespace(
cdp_url=cdp_url,
_thread=None,
_loop=None,
stop=lambda: None,
)
isolated_registry._by_task["t4"] = broken
fresh = isolated_registry.get_or_start(task_id="t4", cdp_url=cdp_url)
assert fresh is not broken
assert isolated_registry._by_task["t4"] is fresh
fresh.stop()
+20
View File
@@ -786,6 +786,26 @@ class TestDelegationCredentialResolution(unittest.TestCase):
self.assertEqual(creds["api_mode"], "chat_completions")
mock_resolve.assert_called_once_with(requested="openrouter")
@patch("hermes_cli.runtime_provider.resolve_runtime_provider")
def test_provider_resolution_uses_runtime_model_when_config_model_missing(self, mock_resolve):
"""Named providers should propagate their runtime default model to children."""
mock_resolve.return_value = {
"provider": "custom",
"base_url": "https://my-server.example/v1",
"api_key": "sk-test-key",
"api_mode": "chat_completions",
"model": "server-default-model",
}
parent = _make_mock_parent(depth=0)
cfg = {"provider": "custom:my-server", "model": ""}
creds = _resolve_delegation_credentials(cfg, parent)
self.assertEqual(creds["model"], "server-default-model")
self.assertEqual(creds["provider"], "custom")
self.assertEqual(creds["base_url"], "https://my-server.example/v1")
mock_resolve.assert_called_once_with(requested="custom:my-server")
def test_direct_endpoint_uses_configured_base_url_and_api_key(self):
parent = _make_mock_parent(depth=0)
cfg = {
+32
View File
@@ -696,6 +696,38 @@ class TestCapabilityDetection:
_detect_capabilities("tok", force=True)
assert mock_req.call_count == 2
@patch("tools.discord_tool._discord_request")
def test_cache_is_keyed_by_token(self, mock_req):
"""Regression: token A's capabilities must not leak to token B.
Before the fix, the cache was a single module-global dict. The first
call populated it and every subsequent call — regardless of token —
returned the same cached value, producing wrong schema gating for
rotated or multi-token deployments.
"""
def _per_token_flags(method, path, token, **_kwargs):
# token A: both intents; token B: neither.
if token == "tok_a":
return {"flags": (1 << 14) | (1 << 18)}
return {"flags": 0}
mock_req.side_effect = _per_token_flags
caps_a = _detect_capabilities("tok_a")
caps_b = _detect_capabilities("tok_b")
assert caps_a["has_members_intent"] is True
assert caps_a["has_message_content"] is True
assert caps_b["has_members_intent"] is False
assert caps_b["has_message_content"] is False
# Each token should hit the endpoint exactly once.
assert mock_req.call_count == 2
# Re-requesting either token serves from its own cache entry.
_detect_capabilities("tok_a")
_detect_capabilities("tok_b")
assert mock_req.call_count == 2
# ---------------------------------------------------------------------------
# Config allowlist
+1
View File
@@ -304,6 +304,7 @@ class TestBuiltinDiscovery:
"tools.file_tools",
"tools.homeassistant_tool",
"tools.image_generation_tool",
"tools.kanban_tools",
"tools.memory_tool",
"tools.mixture_of_agents_tool",
"tools.process_registry",
+15
View File
@@ -242,6 +242,21 @@ class TestSessionSearchConcurrency:
class TestRecentSessionListing:
def test_recent_mode_requests_last_active_ordering(self):
from unittest.mock import MagicMock
mock_db = MagicMock()
mock_db.list_sessions_rich.return_value = []
result = json.loads(_list_recent_sessions(mock_db, limit=5))
assert result["success"] is True
mock_db.list_sessions_rich.assert_called_once_with(
limit=10,
exclude_sources=["tool"],
order_by_last_active=True,
)
def test_current_child_session_excludes_root_lineage_even_when_child_id_is_longer(self):
from unittest.mock import MagicMock
+20
View File
@@ -567,6 +567,26 @@ class TestSecurityScanGate:
with patch("hermes_cli.config.load_config", side_effect=RuntimeError("boom")):
assert _guard_agent_created_enabled() is False
def test_guard_flag_quoted_false_stays_disabled(self):
"""Quoted 'false' from YAML edits must not enable the guard."""
from tools.skill_manager_tool import _guard_agent_created_enabled
for quoted in ("false", "False", "0", "no", "off"):
with patch("hermes_cli.config.load_config",
return_value={"skills": {"guard_agent_created": quoted}}):
assert _guard_agent_created_enabled() is False, \
f"guard_agent_created={quoted!r} must coerce to False"
def test_guard_flag_quoted_true_enables(self):
"""Quoted truthy strings must enable the guard."""
from tools.skill_manager_tool import _guard_agent_created_enabled
for quoted in ("true", "True", "1", "yes", "on"):
with patch("hermes_cli.config.load_config",
return_value={"skills": {"guard_agent_created": quoted}}):
assert _guard_agent_created_enabled() is True, \
f"guard_agent_created={quoted!r} must coerce to True"
# ---------------------------------------------------------------------------
# External skills directories (skills.external_dirs) — mutations in place
+51
View File
@@ -104,6 +104,57 @@ def test_cached_sudo_password_isolated_by_session_key(monkeypatch):
assert terminal_tool._get_cached_sudo_password() == "alpha-pass"
def test_passwordless_sudo_skips_interactive_prompt_and_rewrite(monkeypatch):
monkeypatch.delenv("SUDO_PASSWORD", raising=False)
monkeypatch.delenv("TERMINAL_ENV", raising=False)
monkeypatch.setenv("HERMES_INTERACTIVE", "1")
def _fail_prompt(*_args, **_kwargs):
raise AssertionError(
"interactive sudo prompt should not run when sudo -n already works"
)
monkeypatch.setattr(terminal_tool, "_prompt_for_sudo_password", _fail_prompt)
monkeypatch.setattr(terminal_tool, "_sudo_nopasswd_works", lambda: True, raising=False)
transformed, sudo_stdin = terminal_tool._transform_sudo_command("sudo whoami")
assert transformed == "sudo whoami"
assert sudo_stdin is None
def test_passwordless_sudo_probe_rechecks_local_terminal(monkeypatch):
monkeypatch.delenv("TERMINAL_ENV", raising=False)
calls = []
class Result:
def __init__(self, returncode):
self.returncode = returncode
def fake_run(args, **kwargs):
calls.append((args, kwargs))
return Result(0 if len(calls) == 1 else 1)
monkeypatch.setattr(terminal_tool.subprocess, "run", fake_run)
assert terminal_tool._sudo_nopasswd_works() is True
assert terminal_tool._sudo_nopasswd_works() is False
assert len(calls) == 2
assert calls[0][0] == ["sudo", "-n", "true"]
assert calls[1][0] == ["sudo", "-n", "true"]
def test_passwordless_sudo_probe_is_disabled_for_nonlocal_terminal_env(monkeypatch):
monkeypatch.setenv("TERMINAL_ENV", "docker")
def _fail_run(*_args, **_kwargs):
raise AssertionError("host sudo probe must not run for non-local terminal envs")
monkeypatch.setattr(terminal_tool.subprocess, "run", _fail_run)
assert terminal_tool._sudo_nopasswd_works() is False
def test_validate_workdir_allows_windows_drive_paths():
assert terminal_tool._validate_workdir(r"C:\Users\Alice\project") is None
assert terminal_tool._validate_workdir("C:/Users/Alice/project") is None
+27
View File
@@ -125,6 +125,33 @@ class TestYoloMode:
approval_callback=lambda *a: "deny")
assert not result["approved"]
@pytest.mark.parametrize("value", ["false", "False", "0", "off", "no"])
def test_false_like_yolo_values_do_not_bypass_dangerous_command(self, monkeypatch, value):
"""False-like env strings must not silently enable YOLO bypass."""
monkeypatch.setenv("HERMES_YOLO_MODE", value)
monkeypatch.setenv("HERMES_INTERACTIVE", "1")
monkeypatch.setenv("HERMES_SESSION_KEY", "test-session")
result = check_dangerous_command(
"rm -rf /tmp/stuff",
"local",
approval_callback=lambda *a: "deny",
)
assert not result["approved"]
@pytest.mark.parametrize("value", ["false", "False", "0", "off", "no"])
def test_false_like_yolo_values_do_not_bypass_combined_guard(self, monkeypatch, value):
"""Combined guard must treat false-like YOLO env strings as disabled."""
monkeypatch.setenv("HERMES_YOLO_MODE", value)
monkeypatch.setenv("HERMES_INTERACTIVE", "1")
result = check_all_command_guards(
"rm -rf /tmp/stuff",
"local",
approval_callback=lambda *a: "deny",
)
assert not result["approved"]
def test_session_scoped_yolo_only_bypasses_current_session(self, monkeypatch):
"""Gateway /yolo should only bypass approvals for the active session."""
monkeypatch.delenv("HERMES_YOLO_MODE", raising=False)