()
| 47 | |
| 48 | |
| 49 | def main(): |
| 50 | hermes_home = os.environ["HERMES_HOME"] |
| 51 | project_root = os.environ["TRACEDECAY_PROJECT_ROOT"] |
| 52 | sys.path.insert(0, os.getcwd()) |
| 53 | |
| 54 | # 1. Stock general plugin manager: discovery, enablement, registrations. |
| 55 | from hermes_cli.plugins import get_plugin_manager, get_plugin_context_engine |
| 56 | |
| 57 | manager = get_plugin_manager() |
| 58 | manager.discover_and_load() |
| 59 | loaded = manager._plugins.get("tracedecay") |
| 60 | assert loaded is not None, f"tracedecay missing from {sorted(manager._plugins)}" |
| 61 | assert loaded.enabled, f"tracedecay plugin not enabled: {loaded.error}" |
| 62 | assert loaded.error is None, f"tracedecay plugin load error: {loaded.error}" |
| 63 | ok("plugin loads via stock PluginManager") |
| 64 | assert "pre_llm_call" in loaded.hooks_registered, loaded.hooks_registered |
| 65 | ok("pre_llm_call hook registered") |
| 66 | assert "tracedecay_status" in loaded.commands_registered, loaded.commands_registered |
| 67 | ok("/tracedecay_status command registered") |
| 68 | # Code-graph / memory / transcript tools register unconditionally; only |
| 69 | # the live-ingest LCM verbs (whose schemas take the in-memory messages |
| 70 | # list) depend on the context_engine_tool_handlers_receive_messages |
| 71 | # capability, which stock does not advertise. |
| 72 | registered = set(loaded.tools_registered) |
| 73 | assert "tracedecay_search" in registered, sorted(registered) |
| 74 | assert "tracedecay_context" in registered, sorted(registered) |
| 75 | assert "tracedecay_message_search" in registered, sorted(registered) |
| 76 | assert "tracedecay_lcm_compress" not in registered, sorted(registered) |
| 77 | assert "tracedecay_lcm_preflight" not in registered, sorted(registered) |
| 78 | # memory.provider is tracedecay here, so the provider-owned fact trio |
| 79 | # must not register as direct duplicates. |
| 80 | assert "tracedecay_fact_store" not in registered, sorted(registered) |
| 81 | assert "tracedecay_fact_feedback" not in registered, sorted(registered) |
| 82 | assert "tracedecay_memory_status" not in registered, sorted(registered) |
| 83 | ok( |
| 84 | "code-graph tools register on stock; LCM + provider-owned tools stay gated", |
| 85 | f"{len(registered)} tools", |
| 86 | ) |
| 87 | |
| 88 | # 2. Context engine: registered through the plugin and selected the way |
| 89 | # stock agent/agent_init.py selects it (config-driven, plugin fallback). |
| 90 | from hermes_cli.config import load_config |
| 91 | |
| 92 | config = load_config() |
| 93 | engine_name = (config.get("context") or {}).get("engine") |
| 94 | assert engine_name == "tracedecay", f"context.engine = {engine_name!r}" |
| 95 | ok("config.yaml selects context.engine: tracedecay") |
| 96 | |
| 97 | from plugins.context_engine import load_context_engine |
| 98 | |
| 99 | assert load_context_engine(engine_name) is None |
| 100 | engine = get_plugin_context_engine() |
| 101 | assert engine is not None and engine.name == engine_name |
| 102 | from agent.context_engine import ContextEngine |
| 103 | |
| 104 | assert isinstance(engine, ContextEngine) |
| 105 | ok("context engine activates via stock plugin fallback") |
| 106 |
no test coverage detected