Download tests/plugins/test_memory_hook_registration.py from SaylorTwift/hermes-agent: direct link, hf CLI and curl.
- Browser
- Download file 4.45 kB
-
https://huggingface.co/SaylorTwift/hermes-agent/resolve/main/tests/plugins/test_memory_hook_registration.py
- Command line
-
hf download hf://SaylorTwift/hermes-agent/tests/plugins/test_memory_hook_registration.py
-
curl -L -o test_memory_hook_registration.py https://huggingface.co/SaylorTwift/hermes-agent/resolve/main/tests/plugins/test_memory_hook_registration.py
4.45 kB
| """Exercise dual-kind plugins through the real general and memory loaders.""" | |
| import textwrap | |
| import pytest | |
| from hermes_cli.plugins import get_plugin_manager | |
| from plugins.memory import load_memory_provider | |
| def _install(home, monkeypatch, *, label="first", enabled=True): | |
| home.mkdir(parents=True, exist_ok=True) | |
| monkeypatch.setenv("HERMES_HOME", str(home)) | |
| monkeypatch.setenv("HERMES_BUNDLED_PLUGINS", str(home / "empty")) | |
| monkeypatch.delenv("HERMES_ENABLE_PROJECT_PLUGINS", raising=False) | |
| monkeypatch.chdir(home) | |
| (home / "config.yaml").write_text( | |
| f"plugins:\n enabled: {'[dual]' if enabled else '[]'}\nmemory:\n provider: dual\n" | |
| ) | |
| plugin = home / "plugins" / "dual" | |
| plugin.mkdir(parents=True) | |
| (plugin / "plugin.yaml").write_text("name: dual\nversion: 1.0.0\nkind: standalone\n") | |
| (plugin / "values.py").write_text(f"LABEL = {label!r}\n") | |
| (plugin / "__init__.py").write_text(textwrap.dedent('''\ | |
| from agent.memory_provider import MemoryProvider | |
| from .values import LABEL | |
| class Provider(MemoryProvider): | |
| name = "dual" | |
| def is_available(self): return True | |
| def initialize(self, session_id, **kwargs): pass | |
| def get_tool_schemas(self): return [] | |
| def make_hook(label): | |
| def callback(**kwargs): | |
| return {"context": label} | |
| return callback | |
| def register(ctx): | |
| ctx.register_memory_provider(Provider()) | |
| ctx.register_hook("pre_llm_call", make_hook(LABEL)) | |
| ctx.register_hook("pre_llm_call", make_hook("second")) | |
| ''')) | |
| return get_plugin_manager() | |
| def _contexts(manager): | |
| return manager.invoke_hook("pre_llm_call", session_id="") | |
| def test_dual_kind_plugin_hooks_run_once(tmp_path, monkeypatch, order): | |
| manager = _install(tmp_path, monkeypatch, enabled=order != "memory-only") | |
| try: | |
| if order == "plugin-first": | |
| manager.discover_and_load() | |
| provider = load_memory_provider("dual") | |
| assert provider is not None and provider.name == "dual" | |
| if order == "memory-first": | |
| manager.discover_and_load() | |
| expected = [{"context": "first"}, {"context": "second"}] | |
| assert _contexts(manager) == expected | |
| # New provider instances must not append another fallback hook group. | |
| assert load_memory_provider("dual") is not provider | |
| assert _contexts(manager) == expected | |
| manager.unload() | |
| assert _contexts(manager) == [] | |
| assert not manager._memory_hook_registrations | |
| if order != "memory-only": | |
| manager.discover_and_load(force=True) | |
| assert load_memory_provider("dual") is not None | |
| assert _contexts(manager) == expected | |
| finally: | |
| manager.unload() | |
| def test_same_name_different_sources_are_not_suppressed(tmp_path, monkeypatch): | |
| import shutil | |
| home = tmp_path / "home" | |
| manager = _install(home, monkeypatch) | |
| project = tmp_path / "project" | |
| source = project / ".hermes" / "plugins" / "dual" | |
| shutil.copytree(home / "plugins" / "dual", source) | |
| (source / "values.py").write_text('LABEL = "project"\n') | |
| monkeypatch.chdir(project) | |
| monkeypatch.setenv("HERMES_ENABLE_PROJECT_PLUGINS", "1") | |
| try: | |
| assert load_memory_provider("dual") is not None | |
| manager.discover_and_load() | |
| assert _contexts(manager) == [ | |
| {"context": "first"}, {"context": "second"}, | |
| {"context": "project"}, {"context": "second"}, | |
| ] | |
| finally: | |
| manager.unload() | |
| def test_reexported_register_uses_plugin_source(tmp_path, monkeypatch, order): | |
| manager = _install(tmp_path, monkeypatch) | |
| plugin = tmp_path / "plugins" / "dual" | |
| original = plugin / "__init__.py" | |
| (plugin / "implementation.py").write_text(original.read_text()) | |
| original.write_text("from .implementation import register, Provider # MemoryProvider\n") | |
| try: | |
| if order == "plugin-first": | |
| manager.discover_and_load() | |
| assert load_memory_provider("dual") is not None | |
| if order == "memory-first": | |
| manager.discover_and_load() | |
| assert _contexts(manager) == [{"context": "first"}, {"context": "second"}] | |
| finally: | |
| manager.unload() | |