mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-22 05:22:09 +00:00
feat(plugins): HERMES_PLUGINS_DEBUG=1 surfaces plugin discovery logs (#22684)
Plugin authors had no easy way to figure out why their plugin wasn't loading — failures were buried in agent.log at WARNING and skip reasons (disabled, not enabled, depth cap, exclusive) were DEBUG-only and invisible by default. Set HERMES_PLUGINS_DEBUG=1 to attach a stderr handler at DEBUG to the hermes_cli.plugins logger only. Surfaces: - which directories were scanned + manifest counts per source - per manifest: resolved key, name, kind, source, on-disk path - skip reasons (disabled, not enabled, exclusive, depth cap, no register) - per load: tools/hooks/slash/CLI commands the plugin registered - full traceback on YAML parse failure (exc_info on the existing warning) - full traceback on register() exceptions, pointing at the plugin author's line Env var off (default) → zero new stderr output, same as before. Touches only hermes_cli/plugins.py + a doc section in the plugin-build guide + an entry in the env-vars reference. 3 new tests lock the attach/idempotent/no-attach behavior.
This commit is contained in:
parent
8f83046f6c
commit
79694018f8
4 changed files with 206 additions and 13 deletions
|
|
@ -1232,3 +1232,77 @@ class TestPluginDispatchTool:
|
|||
result = ctx.dispatch_tool("fake", {})
|
||||
|
||||
assert '"error"' in result
|
||||
|
||||
|
||||
class TestPluginDebugLogging:
|
||||
"""HERMES_PLUGINS_DEBUG opt-in stderr handler for plugin developers."""
|
||||
|
||||
def test_debug_handler_not_installed_when_env_var_absent(self, monkeypatch):
|
||||
"""Without the env var, no stderr handler is attached."""
|
||||
monkeypatch.delenv("HERMES_PLUGINS_DEBUG", raising=False)
|
||||
from hermes_cli import plugins as plugins_mod
|
||||
|
||||
# Snapshot, then force a re-evaluation.
|
||||
original_installed = plugins_mod._DEBUG_HANDLER_INSTALLED
|
||||
original_debug = plugins_mod._PLUGINS_DEBUG
|
||||
original_handlers = list(plugins_mod.logger.handlers)
|
||||
try:
|
||||
plugins_mod._DEBUG_HANDLER_INSTALLED = False
|
||||
plugins_mod._install_plugin_debug_handler(force=True)
|
||||
assert plugins_mod._PLUGINS_DEBUG is False
|
||||
assert plugins_mod._DEBUG_HANDLER_INSTALLED is False
|
||||
# No new stderr handler was attached.
|
||||
assert plugins_mod.logger.handlers == original_handlers
|
||||
finally:
|
||||
plugins_mod._DEBUG_HANDLER_INSTALLED = original_installed
|
||||
plugins_mod._PLUGINS_DEBUG = original_debug
|
||||
plugins_mod.logger.handlers = original_handlers
|
||||
|
||||
def test_debug_handler_installed_when_env_var_set(self, monkeypatch):
|
||||
"""With HERMES_PLUGINS_DEBUG=1, a DEBUG-level stderr handler is attached."""
|
||||
monkeypatch.setenv("HERMES_PLUGINS_DEBUG", "1")
|
||||
from hermes_cli import plugins as plugins_mod
|
||||
|
||||
original_installed = plugins_mod._DEBUG_HANDLER_INSTALLED
|
||||
original_debug = plugins_mod._PLUGINS_DEBUG
|
||||
original_level = plugins_mod.logger.level
|
||||
original_handlers = list(plugins_mod.logger.handlers)
|
||||
try:
|
||||
plugins_mod._DEBUG_HANDLER_INSTALLED = False
|
||||
plugins_mod._install_plugin_debug_handler(force=True)
|
||||
assert plugins_mod._PLUGINS_DEBUG is True
|
||||
assert plugins_mod._DEBUG_HANDLER_INSTALLED is True
|
||||
assert plugins_mod.logger.level == logging.DEBUG
|
||||
new_handlers = [
|
||||
h for h in plugins_mod.logger.handlers if h not in original_handlers
|
||||
]
|
||||
assert len(new_handlers) == 1
|
||||
assert isinstance(new_handlers[0], logging.StreamHandler)
|
||||
assert new_handlers[0].level == logging.DEBUG
|
||||
finally:
|
||||
plugins_mod._DEBUG_HANDLER_INSTALLED = original_installed
|
||||
plugins_mod._PLUGINS_DEBUG = original_debug
|
||||
plugins_mod.logger.setLevel(original_level)
|
||||
plugins_mod.logger.handlers = original_handlers
|
||||
|
||||
def test_debug_handler_idempotent(self, monkeypatch):
|
||||
"""Calling install twice (without force) does not double-attach."""
|
||||
monkeypatch.setenv("HERMES_PLUGINS_DEBUG", "1")
|
||||
from hermes_cli import plugins as plugins_mod
|
||||
|
||||
original_installed = plugins_mod._DEBUG_HANDLER_INSTALLED
|
||||
original_debug = plugins_mod._PLUGINS_DEBUG
|
||||
original_level = plugins_mod.logger.level
|
||||
original_handlers = list(plugins_mod.logger.handlers)
|
||||
try:
|
||||
plugins_mod._DEBUG_HANDLER_INSTALLED = False
|
||||
plugins_mod._install_plugin_debug_handler(force=True)
|
||||
count_after_first = len(plugins_mod.logger.handlers)
|
||||
plugins_mod._install_plugin_debug_handler() # no force
|
||||
count_after_second = len(plugins_mod.logger.handlers)
|
||||
assert count_after_first == count_after_second
|
||||
finally:
|
||||
plugins_mod._DEBUG_HANDLER_INSTALLED = original_installed
|
||||
plugins_mod._PLUGINS_DEBUG = original_debug
|
||||
plugins_mod.logger.setLevel(original_level)
|
||||
plugins_mod.logger.handlers = original_handlers
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue