Skip to content

fix(web_tools): trigger plugin discovery before registry dispatch (#27683) - #27700

Closed
luyao618 wants to merge 1 commit into
NousResearch:mainfrom
luyao618:fix/web-tools-ensure-plugins-discovered
Closed

fix(web_tools): trigger plugin discovery before registry dispatch (#27683)#27700
luyao618 wants to merge 1 commit into
NousResearch:mainfrom
luyao618:fix/web-tools-ensure-plugins-discovered

Conversation

@luyao618

Copy link
Copy Markdown
Contributor

Summary

Closes #27683.

tools/web_tools.py dispatches to providers from agent.web_search_registry at three sites — web_search_tool (~L797), web_extract_tool (~L935), and web_crawl_tool (~L1193) — without first calling hermes_cli.plugins._ensure_plugins_discovered().

On a fresh install (or any session where plugin discovery hasn't already been triggered for some unrelated reason), the registry is empty. get_provider() and get_active_*_provider() therefore return None, and the user gets a "No web search/extract/crawl provider configured" error envelope — or a silent fallback — even though they have a backend (e.g. ddgs) installed and configured.

The sibling tools tools/image_generation_tool.py and tools/video_generation_tool.py both already guard against this exact failure mode by lazily importing and calling _ensure_plugins_discovered() before consulting their respective registries (see image_generation_tool.py:874, video_generation_tool.py:207). web_tools.py was the outlier.

Fix

Mirror the existing pattern at all three dispatch sites — a 6-line try/except block immediately before the agent.web_search_registry import:

try:
    from hermes_cli.plugins import _ensure_plugins_discovered

    _ensure_plugins_discovered()
except Exception:
    pass
  • Lazy import inside the function body so we don't perturb module-level import order.
  • except Exception so the path still works in slim/test environments where hermes_cli isn't importable (matches the defensive style in image_generation_tool.py).
  • Idempotent + cheap on subsequent calls — _ensure_plugins_discovered() short-circuits after the first run.
  • No provider-resolution semantics are changed.

Tests

New file tests/tools/test_web_tools_plugin_discovery.py adds three regression tests, one per dispatcher. Each patches hermes_cli.plugins._ensure_plugins_discovered, forces the registry to return None (so the tool short-circuits quickly), and asserts the discovery hook was invoked.

I verified both directions:

$ pytest tests/tools/test_web_tools_plugin_discovery.py -x -q     # on main (before fix)
3 failed in 6.01s

$ pytest tests/tools/test_web_tools_plugin_discovery.py -x -q     # with this patch
3 passed in 8.70s

Scope

  • tools/web_tools.py — 18 lines added (three 6-line blocks), no other edits, no formatting churn.
  • tests/tools/test_web_tools_plugin_discovery.py — new file, 111 lines.

Risk

Very low. Discovery is already invoked by image/video tools on every call; this brings web tools in line. The try/except Exception keeps the slim-environment path safe.

…usResearch#27683)

The three web tool dispatchers — `web_search_tool`, `web_extract_tool`, and
`web_crawl_tool` — resolve providers via `agent.web_search_registry`. On a
fresh install (or any path that hasn't already triggered plugin discovery
for some unrelated reason) the registry is empty, so every `get_provider()`
/ `get_active_*_provider()` call returns `None` and the user sees a 'no
provider configured' fallback even when they have a backend installed and
configured correctly.

`tools/image_generation_tool.py` and `tools/video_generation_tool.py`
already guard against this by lazily importing and calling
`hermes_cli.plugins._ensure_plugins_discovered()` before consulting their
registries. `web_tools.py` did not.

Mirror that pattern at all three dispatch sites — lazy import inside a
try/except so we still work in slim/test environments where `hermes_cli`
isn't importable. Discovery is idempotent and cheap on subsequent calls.

Regression test `tests/tools/test_web_tools_plugin_discovery.py` patches
`_ensure_plugins_discovered` and asserts each of the three entrypoints
invokes it. Verified the three tests fail on main and pass with this
patch.

Fixes NousResearch#27683
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists tool/web Web search and extraction comp/plugins Plugin system and bundled plugins labels May 18, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #27584 which already fixes the same missing _ensure_plugins_discovered() calls in web_tools.py (for #27580). The referenced issue #27683 was itself flagged as a duplicate of #27580.

@bbernstein616 bbernstein616 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Watchdog review: independently checked the patch and ran targeted verification locally. The change matches the existing image/video lazy plugin-discovery pattern, keeps import-order risk low, and all CI checks are green. Local verification: scripts/run_tests.sh tests/tools/test_web_tools_plugin_discovery.py (3 passed) and python -m ruff check tests/tools/test_web_tools_plugin_discovery.py tools/web_tools.py (passed). I attempted to merge, but this token/user lacks MergePullRequest permission.

@luyao618

Copy link
Copy Markdown
Contributor Author

Closing as duplicate of #27584 (same _ensure_plugins_discovered() fix in web_tools.py, also open). Deferring to that PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P2 Medium — degraded but workaround exists tool/web Web search and extraction type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

web_tools.py: missing _ensure_plugins_discovered() at search/extract/crawl dispatch sites causes web tools to silently fail

3 participants