hermes-agent/tests/plugins
Greg Gibeau c600fd46bd fix(memory): complete discovery and registration parity for out-of-tree providers
Builds on the three salvaged commits: adds the sources and integration points
they leave out, so a pip-installed memory provider is not a second-class
citizen next to a directory install.

Discovery
- Project-local providers (./.hermes/plugins/<name>/), gated on
  HERMES_ENABLE_PROJECT_PLUGINS exactly as PluginManager gates its own project
  scan. Completes the four sources CONTRIBUTING.md and AGENTS.md already
  promised; memory was the only discovery system missing two of them.
- find_provider_dir() now resolves a package entry point to its directory.
  This is load-bearing: config_schema.py (the dashboard panel) and cli.py (the
  `hermes <provider>` subcommands) are read from disk rather than imported, so
  without a directory a pip-installed provider silently lost both.
- list_memory_provider_names() includes entry-point providers, so they appear
  in the dashboard's memory.provider dropdown.

Resolution stays import-free. hermes_cli.plugins.resolve_module_origin() is
extracted from _resolve_module_source() (added by the salvaged #76567) and
shared, so discovery walks a module's file layout instead of importing it.
find_provider_dir() is called from the dashboard and from argparse setup, long
before the operator has chosen a provider — importing every installed candidate
would execute third-party code on the strength of a package being present.
A test asserts the resolution leaves no side effects and no sys.modules entry.

Registration
- PluginContext gains register_memory_provider(). Memory was the only provider
  category without one; context engine, image gen, video gen, web search,
  browser, TTS, transcription, secret source, dashboard auth and platform all
  have one.
- _ProviderCollector delegates unknown register_* calls to a real
  PluginContext instead of carrying three hand-written no-ops. It silently
  dropped register_tool/register_hook, and had no register_auxiliary_task at
  all — despite PluginContext.register_auxiliary_task documenting a memory
  provider (hindsight's pre-retain dedup) as its worked example. It can no
  longer drift behind PluginContext.
- A raise after register_memory_provider() no longer costs the provider. The
  loader caught it into a debug log, discarded the registered instance, and
  fell through to "instantiate any MemoryProvider subclass" — returning a
  different, unconfigured provider. A silent downgrade that looked like
  success, and the exact outcome of calling register_auxiliary_task.

Activation is unchanged: still gated on memory.provider naming the plugin, and
covered by a test so the real PluginContext cannot start requiring
plugins.enabled — that would break every existing user-installed provider.

Verified end to end against a real third-party provider (kainappsinc/elephant)
installed by pip alone, with no directory copy: it appears in the dropdown,
resolves its directory, loads with its tools, and renders its dashboard panel.

Closes #40101.
2026-08-13 11:49:14 -07:00
..
browser
…
dashboard_auth
…
image_gen
…
memory fix(memory): complete discovery and registration parity for out-of-tree providers 2026-08-13 11:49:14 -07:00
model_providers
…
platforms
…
transcription
…
tts
…
video_gen
…
web
…
__init__.py
…
test_a2a_phase23.py
…
test_a2a_plugin.py
…
test_achievements_plugin.py
…
test_chronos_cron.py
…
test_chronos_verify.py
…
test_discord_runtime_failure.py
…
test_disk_cleanup_plugin.py
…
test_google_meet_audio.py
…
test_google_meet_node.py
…
test_google_meet_plugin.py
…
test_google_meet_realtime.py
…
test_hindsight_health_grace_timeout.py
…
test_hindsight_root_guard.py
…
test_holographic_vector_storage.py
…
test_kanban_attachments.py
…
test_kanban_board_project_api.py
…
test_kanban_dashboard_plugin.py
…
test_kanban_dashboard_task_updated_hook.py
…
test_kanban_estimate.py
…
test_kanban_model_override.py
…
test_kanban_worker_runs.py
…
test_langfuse_plugin.py
…
test_nemo_relay_mark_turn_parenting.py
…
test_nemo_relay_plugin.py
…
test_plugin_dashboard_auth_contract.py fix(dashboard): sanction plugin WS/upload auth via SDK helpers (gated mode) 2026-06-03 16:59:36 -07:00
test_raft_check_fn_silent.py
…
test_retaindb_plugin.py
…
test_security_guidance_plugin.py
…
test_teams_pipeline_plugin.py
…