fix(web): correct 'disabled plugin' diagnosis for web backends (#59573)
When a bundled web provider (firecrawl, tavily, exa, ...) is listed in
plugins.disabled, its provider never registers and the web_search/
web_extract dispatchers emitted the misleading "No web extract provider
configured. Set web.extract_backend to ..." — even though the backend was
configured correctly. The real fix is to re-enable the plugin.
- web_tools.py + web_search_registry.py: when the configured backend names
a disabled bundled web plugin, both dispatchers now point the user at the
actual cause (re-enable the plugin) instead of a wrong config hint.
- plugins_cmd.py cmd_enable: enabling by canonical key now also clears the
manifest-name alias (web-firecrawl) from plugins.disabled, so the
suggested command actually re-enables the plugin ('explicit disable wins'
matches on the name too).
- plugins_cmd.py cmd_toggle / _run_composite_ui / _run_composite_fallback:
the interactive 'hermes plugins' menu now persists the canonical key
(web/firecrawl), never the bare manifest name — the drift that put the
offending entry in plugins.disabled in the first place.
Follow-up to #59518 (which fixed web credential resolution, a different
cause). Fixes the disabled-plugin symptom reported after that PR.
This commit is contained in:
+46
-7
@@ -661,6 +661,7 @@ def web_search_tool(query: str, limit: int = 5) -> str:
|
||||
from agent.web_search_registry import (
|
||||
get_active_search_provider,
|
||||
get_provider as _wsp_get_provider,
|
||||
_disabled_web_plugin_for,
|
||||
)
|
||||
|
||||
backend = _get_search_backend()
|
||||
@@ -672,13 +673,29 @@ def web_search_tool(query: str, limit: int = 5) -> str:
|
||||
provider = get_active_search_provider()
|
||||
|
||||
if provider is None:
|
||||
response_data = {
|
||||
"success": False,
|
||||
"error": (
|
||||
"No web search provider configured. "
|
||||
"Run `hermes tools` to set one up."
|
||||
),
|
||||
}
|
||||
# A bundled web plugin the user explicitly disabled looks
|
||||
# identical to "no provider" here — point at the real cause
|
||||
# (re-enable the plugin) rather than a generic setup hint.
|
||||
disabled_key = _disabled_web_plugin_for(capability="search")
|
||||
if disabled_key:
|
||||
_vendor = disabled_key.split("/", 1)[-1]
|
||||
response_data = {
|
||||
"success": False,
|
||||
"error": (
|
||||
f"web.search_backend is set to '{_vendor}', but its "
|
||||
f"plugin ('{disabled_key}') is disabled in config. "
|
||||
f"Re-enable it with `hermes plugins enable {disabled_key}` "
|
||||
"(or remove it from plugins.disabled)."
|
||||
),
|
||||
}
|
||||
else:
|
||||
response_data = {
|
||||
"success": False,
|
||||
"error": (
|
||||
"No web search provider configured. "
|
||||
"Run `hermes tools` to set one up."
|
||||
),
|
||||
}
|
||||
else:
|
||||
logger.info(
|
||||
"Web search via %s: '%s' (limit: %d)",
|
||||
@@ -814,6 +831,7 @@ async def web_extract_tool(
|
||||
from agent.web_search_registry import (
|
||||
get_active_extract_provider,
|
||||
get_provider as _wsp_get_provider,
|
||||
_disabled_web_plugin_for,
|
||||
)
|
||||
|
||||
provider = _wsp_get_provider(backend) if backend else None
|
||||
@@ -839,6 +857,27 @@ async def web_extract_tool(
|
||||
)
|
||||
provider = get_active_extract_provider()
|
||||
if provider is None:
|
||||
# If the configured backend is a bundled web plugin the
|
||||
# user explicitly disabled, the backend is set correctly
|
||||
# and the real fix is to re-enable the plugin — say so
|
||||
# instead of telling them to set web.extract_backend
|
||||
# (which they already did). #40190 follow-up.
|
||||
disabled_key = _disabled_web_plugin_for(capability="extract")
|
||||
if disabled_key:
|
||||
_vendor = disabled_key.split("/", 1)[-1]
|
||||
return json.dumps(
|
||||
{
|
||||
"success": False,
|
||||
"error": (
|
||||
f"web.extract_backend is set to '{_vendor}', "
|
||||
f"but its plugin ('{disabled_key}') is disabled "
|
||||
"in config. Re-enable it with "
|
||||
f"`hermes plugins enable {disabled_key}` "
|
||||
"(or remove it from plugins.disabled)."
|
||||
),
|
||||
},
|
||||
ensure_ascii=False,
|
||||
)
|
||||
return json.dumps(
|
||||
{
|
||||
"success": False,
|
||||
|
||||
Reference in New Issue
Block a user