Commit Graph

4 Commits

Author SHA1 Message Date
teknium1
3f80dc9a5a fix(plugins): stream observer hooks and event subscribers fail-report once, not per event
Two per-call WARNING surfaces were still outside the warn-once reporter:

- agent/plugin_stream_hooks.py::_worker — the on_stream_start/on_stream_delta/
  on_stream_end consumer, which fires once per streaming delta (far more often than
  per tool call). A mis-declared callback (signature naming tool_data) logged
  "Hook ... raised" at WARNING on every delta: 20 deltas -> 20 WARNING lines.
- hermes_cli/plugins_dispatch.py::_deliver_event — plugin event subscribers that
  raise identically were warned on every emit.

Both now go through PluginManager._report_hook_failure (keyed by module/qualname,
cleared on unload): the first failure warns and names the fields the hook/event
provides, identical repeats are DEBUG. Skip-and-continue semantics are unchanged.

Part of #111922
2026-09-17 09:03:29 -07:00
teknium1
0f98d5a1d9 fix(plugins): execution-chain middleware failures are reported once, not per call
The warn-once reporter added for hooks (and for PluginManager.invoke_middleware)
left the execution chain out: hermes_cli/middleware.py::_run_execution_chain — the
tool_execution / llm_execution frames that run once per tool or LLM call — still
logged "Middleware '%s' callback %s raised" at WARNING on every invocation. A
mis-declared callback (e.g. a signature naming tool_data) therefore flooded the
log exactly like the hook case #111922 reported: 5 calls -> 5 WARNING lines.

Route the frame's except through the manager's _report_hook_failure with the
"Middleware" surface label, so the first failure warns (listing the fields the
middleware does provide) and identical repeats go to DEBUG; the set is already
forgotten on plugin reload. The frame's skip-and-continue semantics are unchanged.

Part of #111922
2026-09-17 09:03:29 -07:00
teknium1
01d73210c2 fix(plugins): dedupe middleware failures too, and let unload forget reported hook failures
Review follow-up on the warn-once hook reporter. Middleware (agent_tool_execution
etc.) runs once per tool call exactly like a hook, so a mis-declared middleware
callback flooded WARNING identically; route its except through the same
_report_hook_failure helper with a "Middleware" surface label.

The reported-failure set was keyed on (hook, id(cb), repr(exc)) and never
cleared: a hook whose message embeds tool args grew it by one entry per call,
and id() recycling across plugin reloads could swallow a reloaded callback's
first failure. Key on (hook, module, qualname, exc type, str(exc)[:200]) and
clear the set in _reset_after_unload_all next to _hook_timeout_suppressed_until.

Part of #111922
2026-09-16 17:08:25 -07:00
teknium1
8beeb661c9 fix(plugins): report an identically failing hook callback once, not on every call
A plugin callback whose signature names a parameter the hook never sends
(on_pre_tool(tool_data) where core provides tool_name/args) raises the same
TypeError on every tool call; core logged a WARNING each time — ~1700 lines an
hour in the report, burying the freeze signature it was trying to find
(finding (c) of #111922). The mis-declared signature is the plugin's bug; the
per-call repeat is ours.

invoke_hook now reports one WARNING per distinct (hook, callback, error) and
names the fields the hook actually provides so the author can fix the
signature; identical repeats are logged at DEBUG. A callback failing in a new
way still warns.

Part of #111922
2026-09-16 17:08:25 -07:00