fix: Desktop hooks registration gap and diagnostics improvements - #61315
fix: Desktop hooks registration gap and diagnostics improvements#61315seasonmsg wants to merge 1 commit into
Conversation
Four targeted fixes for Hermes desktop/TUI paths: 1. tui_gateway/server.py: Call discover_plugins() in _make_agent so Python plugins (and their shell-hook registrations) fire for every agent created via the desktop WebSocket path. discover_plugins() is idempotent - no-ops after the first call per process. 2. tools/delegate_tool.py: Add isinstance(result, dict) guard before result.get() to prevent 'list' object has no attribute 'get' crashes when background-review re-dispatches results. Also promote subagent_stop hook failure log from debug to warning so it's visible in default INFO-level logs. 3. hermes_cli/plugins.py: Log invoke_hook callback counts at DEBUG level for diagnostics. Previously silent when hooks fire. 4. agent/turn_finalizer.py: Include exc_info=True when on_session_end hook fails, so the traceback is available for debugging.
Related: #50787 / #60010 (the The |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the diagnostics work. The current implementation needs a narrower re-scope.
Problems
- The new
_make_agent()discovery call is redundant:tui_gateway/server.py:4472importsrun_agent.AIAgent;run_agent.py:136importsmodel_tools; andmodel_tools.py:203-208already invokesdiscover_plugins(). - This cannot register
config.yamlshell hooks. That behavior is implemented byagent/shell_hooks.py:203-278(register_from_config); CLI and gateway invoke it atcli.py:982-985andgateway/run.py:6947-6950, buttui_gateway/has no equivalent call. - The added delegate guard stringifies any non-dict result into
final_response. Becausetools/delegate_tool.py:2049-2057treats a non-empty summary as completed, a malformed list would be reported as completed instead of failed.
Suggested changes
- Re-scope the Desktop hook fix to explicit shell-hook registration and add a regression test.
- Represent unexpected child result types as a structured failure, not a successful textual summary.
- Preserve LF line endings and split the diagnostic-only changes from the hook fix.
Automated hermes-sweeper review.
|
|
||
| # Guard: result may be a list (e.g. from background-review re-dispatch) | ||
| if not isinstance(result, dict): | ||
| result = {"final_response": str(result)[:500], "completed": False, "interrupted": False, "api_calls": 0} |
There was a problem hiding this comment.
This coercion makes a list a non-empty final_response; the existing status branch then reports the child as completed even though completed is false. Return a structured failed entry with an explicit invalid-result-type error instead of stringifying an unsupported result.
Problem
When running Hermes in Desktop GUI mode, shell hooks configured in
config.yamlare not registered because:Desktop WebSocket path (
tui_gateway/server.py:_make_agent) never callsdiscover_plugins(), so Python plugins — including any that register shell hooks — are never loaded for agents created via the desktop GUI.Lack of diagnostics: When hooks fire (or fail), there's no visibility at INFO level — useful diagnostic information is locked behind DEBUG logging.
Crash risk:
delegate_taskcan crash with'list' object has no attribute 'get'when background-review re-dispatches results.Changes
1.
tui_gateway/server.py— Ensure plugin discovery in Desktop pathdiscover_plugins()is idempotent — no-ops after the first call per process, so this is safe.2.
tools/delegate_tool.py— Crash guard + diagnostic logging'list' object has no attribute 'get'whenresultis unexpectedly a list (observed with background-review re-dispatch).logger.debugtologger.warningso it's visible in default INFO-level logs.3.
hermes_cli/plugins.py— Hook execution diagnosticsLogs callback counts at DEBUG level when hooks fire, e.g.:
4.
agent/turn_finalizer.py— Better error diagnosticsIncludes
exc_info=Truewhenon_session_endhook fails, so the full traceback is available for debugging.Testing
discover_plugins) callingregister_from_config().Related
This addresses the same gap that required downstream users to patch
hermes_cli/main.py(cmd_dashboard),tui_gateway/entry.py, andcli.pywith manualregister_from_config()calls. Withdiscover_plugins()called in_make_agent, user Python plugins can handle shell-hook registration themselves — no source patches needed.