test(cli): stub portable-MCP lookup in completer read test; bound resolve_toolset memo

- The readonly-loader completer test now stubs
  get_portable_mcp_server_names_nowait — real plugin discovery runs
  load_config() during one-time process init, which is not the
  per-keystroke read the test guards against.
- Cap _resolve_toolset_memo at 256 entries: generation-keyed entries
  from stale generations are never hit again, so clear on overflow to
  keep long sessions bounded.
This commit is contained in:
Teknium
2026-08-14 23:06:59 -07:00
parent 2f54ad4023
commit 46fe44fa8d
2 changed files with 9 additions and 1 deletions
@@ -52,9 +52,13 @@ class TestToolsCompletionsReadonlyConfig:
return {}
# The completer imports the loader inside the function, so patch the
# source module.
# source module. Portable-MCP lookup is stubbed because it triggers
# one-time plugin discovery (which legitimately calls load_config
# during process init) — this test asserts on the completer's own
# per-keystroke reads, not discovery's one-off startup reads.
with patch("hermes_cli.config.load_config", counting_deepcopy), \
patch("hermes_cli.config.load_config_readonly", counting_readonly), \
patch("hermes_cli.plugins.get_portable_mcp_server_names_nowait", lambda: set()), \
patch("hermes_cli.tools_config._get_plugin_toolset_keys", lambda: set()), \
patch("hermes_cli.tools_config._homeassistant_credentials_present", lambda: False), \
patch("hermes_cli.tools_config._xai_credentials_present", lambda: False):
+4
View File
@@ -870,6 +870,10 @@ def resolve_toolset(name: str, visited: Set[str] = None, *, include_registry: bo
except Exception:
registry_id = 0
generation = 0
# Entries from previous registry generations are never hit again;
# keep the memo bounded across long sessions with many MCP refreshes.
if len(_resolve_toolset_memo) >= 256:
_resolve_toolset_memo.clear()
_resolve_toolset_memo[(name, include_registry, registry_id, generation)] = list(result)
return result