hermes-agent/agent
Bartok9 8be9c76f8c fix(plugins): hook delivery parity + symmetric force-reload (#64178)
Salvaged from PR #64188 (@Bartok9), re-reviewed against the #64229
ownership ledger (landed in #84923).

Delivery parity (survived):
- Module-level invoke_hook/invoke_middleware/has_hook/has_middleware
  lazily run plugin discovery via _delivery_manager(), so surfaces that
  never import model_tools (dashboards, TUI slash workers, query mode,
  cron, gateway platform events) deliver plugin callbacks instead of
  silently dropping them (#50776, #67597, #67890, #50937).
- _delivery_manager() joins any in-flight background discovery first and
  tolerates test doubles that monkeypatch get_plugin_manager().

Symmetric force-reload (survived):
- agent/shell_hooks.py gains re_register_config_hooks(); the force branch
  of discover_and_load() calls it after a successful sweep, restoring
  config.yaml shell hooks that the ledger-driven unload wiped but cannot
  restore (they are config-owned, not plugin-owned) (#60036).
- unload(plugin=None) now sweeps pre-ledger _plugin_tool_names entries
  out of the process-global tools.registry, mirroring the platform-name
  sweep that already existed, so zombie tools cannot survive a force
  reload in long-lived pre-ledger processes (#60050).

Superseded by the ownership ledger (dropped from #64188):
- _unload_global_plugin_registrations() bulk tool/platform teardown —
  the ledger's reverse-order handle disposal with previous-entry
  restoration covers it more precisely.
- tools.registry/platform_registry displaced-entry LIFO restore stacks —
  the ledger's restore_registration() identity-checked previous-entry
  restoration made them redundant.
- Discovery serialization lock + double-checked singleton — main already
  has _discovery_lock on every discover/unload path and a keyed,
  lock-guarded per-home manager cache (#24714 concern is covered).

Fixes tracked under #64178 (#50776, #60036, #60050, #24714, #67798,
#50937, #67597, #67890, #31480 — #31480 already handled on main by
_parse_hooks_block warn+suggest).
2026-08-12 19:40:59 -07:00
..
lsp
…
monitoring fix(otlp): span exporter now inherits configured resource_attributes 2026-08-08 18:11:02 -07:00
pet
…
proxy_sources
…
secret_sources fix(plugins): preserve force-path platform sweep + scoped plugin-source listing after rebase 2026-08-12 19:13:32 -07:00
transports fix: complete kanban review lifecycle 2026-08-10 12:43:46 -07:00
verify Integrate verify subsystem with the existing verification stack 2026-08-07 10:11:05 -07:00
__init__.py
…
account_usage.py
…
agent_init.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
agent_runtime_helpers.py fix: close provider-anthropic MiniMax proxy bypass + rework cache observability 2026-08-12 13:58:26 +05:30
anthropic_adapter.py fix(kimi): send Hermes attribution headers instead of claude-code/0.1.0 2026-08-11 13:25:37 +05:30
async_utils.py
…
aux_accounting.py
…
auxiliary_client.py fix(plugins): complete task-routed LLM integration 2026-08-12 16:25:20 -07:00
azure_identity_adapter.py
…
backend_identity.py
…
background_review.py simplify: match delegate_tool.py hasattr pattern, drop change-detector test 2026-08-09 16:13:52 +05:30
battery.py
…
bedrock_adapter.py
…
billing_links.py
…
billing_usage.py
…
billing_view.py
…
bounded_response.py
…
browser_provider.py feat(browser): integrate Browser Use CLI 3.0 2026-08-10 10:45:44 -07:00
browser_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
chat_completion_helpers.py feat(plugins): add streaming output observer hooks 2026-08-12 18:38:25 -07:00
codex_responses_adapter.py feat(compression): native OpenAI Responses server-side compaction for gpt-5.6 2026-08-08 11:24:45 -07:00
codex_runtime.py fix: widen APIConnectionError handling to finalization drain loop 2026-08-12 12:42:39 +05:30
coding_context.py
…
context_breakdown.py
…
context_compressor.py fix: double-paren bug in dropped-tools prefix + add empty-response nudge sibling 2026-08-09 16:20:48 +05:30
context_engine.py Revert "fix: rewire DCP context engine to current main architecture" 2026-08-08 23:09:45 +05:30
context_references.py feat(plugins): allow plugins to register custom @-prefix context references 2026-08-12 18:41:59 -07:00
conversation_compression.py fix(compression): preserve live tail before snapshot adoption 2026-08-09 22:29:39 +05:30
conversation_loop.py feat(plugins): add cache-safe system prompt sections 2026-08-12 16:34:58 -07:00
copilot_acp_client.py fix(file-safety): approval-gate ~/.ssh/config writes instead of hard-denying (#84663) 2026-08-12 11:04:45 -07:00
credential_persistence.py
…
credential_pool.py fix(agent): rebind pool entry id after env credential refresh 2026-08-08 19:17:02 -07:00
credential_sources.py fix(auth): read .env as utf-8-sig in the dotenv-vs-shell detector 2026-08-08 12:32:23 -07:00
credits_tracker.py
…
curator.py
…
curator_backup.py refactor: fold simplify findings — 6th copy in update_cmd, drop dead wrapper + speculative kwarg, behavior-contract tests 2026-08-08 15:10:35 +05:30
delegation_context.py
…
display.py feat(browser): integrate Browser Use CLI 3.0 2026-08-10 10:45:44 -07:00
error_classifier.py refactor(error_classifier): guard grammar check + extract shared constant 2026-08-13 01:17:02 +05:30
errors.py
…
estop.py fix: post-merge audit follow-ups for #81138/#81139/#81141/#81148 2026-08-08 05:21:09 -07:00
file_safety.py fix(file-safety): approval-gate ~/.ssh/config writes instead of hard-denying (#84663) 2026-08-12 11:04:45 -07:00
gemini_native_adapter.py
…
gemini_schema.py
…
i18n.py
…
image_gen_provider.py feat(media): opt-in upscale pass for image_generate and video_generate across FAL and Krea 2026-08-08 14:49:28 -07:00
image_gen_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
image_routing.py
…
insights.py
…
interrupt_compat.py
…
iteration_budget.py
…
jiter_preload.py
…
kanban_stop.py
…
learn_prompt.py fix(learn): process large sources incrementally 2026-08-08 05:09:43 -07:00
learning_graph.py
…
learning_graph_render.py
…
learning_mutations.py
…
lmstudio_reasoning.py
…
manual_compression_feedback.py
…
markdown_tables.py
…
memory_manager.py
…
memory_provider.py
…
message_content.py
…
message_sanitization.py fix(agent): preserve destroyed tool-call argument bytes in the WARNING log 2026-08-07 16:57:11 +05:30
moa_loop.py
…
moa_trace.py
…
model_metadata.py add grok 4.6 (#84661) 2026-08-12 13:37:04 -04:00
models_dev.py fix(models_dev): map meta-ai provider to models.dev 'meta' id (salvage #81418) (#84679) 2026-08-12 14:42:00 -04:00
moonshot_schema.py
…
native_compaction.py fix(compression): correct prune boundary + exempt native compaction checkpoints 2026-08-08 14:09:41 -07:00
nous_rate_guard.py
…
onboarding.py
…
oneshot.py
…
outbound_webhooks.py
…
plugin_llm.py fix(plugins): complete task-routed LLM integration 2026-08-12 16:25:20 -07:00
plugin_stream_hooks.py feat(plugins): add streaming output observer hooks 2026-08-12 18:38:25 -07:00
portal_tags.py
…
process_bootstrap.py
…
prompt_builder.py fix: steer agents off MSYS paths for native tools; pin line-ending preservation (#84426) 2026-08-12 02:43:17 -07:00
prompt_cache_boundary.py refactor(cache): share the boundary-declaration helper and simplify the registry 2026-08-09 15:25:12 +05:30
prompt_caching.py perf(cache): harden the stable-prefix boundary against eviction and memory growth 2026-08-09 15:25:12 +05:30
rate_limit_tracker.py
…
reactions.py
…
reasoning_summaries.py
…
reasoning_timeouts.py add grok 4.6 (#84661) 2026-08-12 13:37:04 -04:00
redact.py feat(plugins): per-source pattern attribution + explicit pre-screen rebuild proof 2026-08-12 18:55:14 -07:00
relay_llm.py fix(relay): bypass managed execution for nested calls inside managed callbacks 2026-08-08 23:46:17 -07:00
relay_runtime.py fix(relay): bound the interpreter-shutdown fallback lane; unwedge test fakes at teardown 2026-08-12 19:19:54 -07:00
relay_tools.py fix(relay): bypass managed execution for nested calls inside managed callbacks 2026-08-08 23:46:17 -07:00
replay_cleanup.py
…
retry_utils.py
…
runtime_cwd.py
…
secret_scope.py
…
session_activity.py
…
shell_hooks.py fix(plugins): hook delivery parity + symmetric force-reload (#64178) 2026-08-12 19:40:59 -07:00
skill_bundles.py
…
skill_commands.py refactor(cache): share the boundary-declaration helper and simplify the registry 2026-08-09 15:25:12 +05:30
skill_preprocessing.py
…
skill_utils.py
…
ssl_guard.py fix(ssl_guard): tolerate truststore SSLContext.get_ca_certs() NotImplementedError on Windows 2026-08-08 15:10:24 +05:30
ssl_verify.py
…
stream_diag.py
…
stream_single_writer.py
…
subagent_lifecycle.py
…
subdirectory_hints.py
…
subscription_view.py
…
system_prompt.py feat(plugins): add cache-safe system prompt sections 2026-08-12 16:34:58 -07:00
think_scrubber.py
…
thinking_timeout_guidance.py
…
thread_scoped_output.py
…
title_generator.py refactor(title): decide on the stored title and the real turns behind it 2026-08-09 04:33:58 -05:00
tool_dispatch_helpers.py
…
tool_executor.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
tool_guardrails.py
…
tool_result_classification.py
…
trace_upload.py
…
trajectory.py
…
transcription_provider.py feat(plugins): add pre_transcription hook and STT prompt threading 2026-08-12 19:01:30 -07:00
transcription_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
tts_provider.py
…
tts_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
turn_context.py fix(agent): stop cron and subagent runs auto-titling their sessions 2026-08-09 04:33:58 -05:00
turn_finalizer.py fix(agent,gateway): class-level lone-surrogate chokepoints (#80366 #55143 #55309 #50959 #19819) 2026-08-08 12:31:19 -07:00
turn_retry_state.py feat(compression): native OpenAI Responses server-side compaction for gpt-5.6 2026-08-08 11:24:45 -07:00
turn_summary.py
…
usage_pricing.py fix: close provider-anthropic MiniMax proxy bypass + rework cache observability 2026-08-12 13:58:26 +05:30
verification_evidence.py Integrate verify subsystem with the existing verification stack 2026-08-07 10:11:05 -07:00
verification_stop.py fix: make verify_on_stop opt-in everywhere (default False, not auto) (#84383) 2026-08-12 01:15:25 -07:00
verify_hooks.py
…
vertex_adapter.py
…
video_gen_provider.py feat(media): opt-in upscale pass for image_generate and video_generate across FAL and Krea 2026-08-08 14:49:28 -07:00
video_gen_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
web_search_provider.py
…
web_search_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00