Skip to content

feat(web): add Gemini Google Search Grounding provider#26021

Open
donbowman wants to merge 4 commits into
NousResearch:mainfrom
donbowman:add-gemini-search
Open

feat(web): add Gemini Google Search Grounding provider#26021
donbowman wants to merge 4 commits into
NousResearch:mainfrom
donbowman:add-gemini-search

Conversation

@donbowman

@donbowman donbowman commented May 15, 2026

Copy link
Copy Markdown

What does this PR do?

<- Implements a new GeminiWebSearchProvider plugin under plugins/web/gemini/ to support web search and extraction using the google-genai SDK and Google Search Grounding.

  • Updates tools/web_tools.py backend detection logic and allows falling back to gemini if GEMINI_API_KEY or GOOGLE_API_KEY are provided.
  • Configures web.gemini_model mapping in hermes_cli/config.py with a default of gemini-3.1-flash-lite.
  • Integrates the Gemini backend into the interactive CLI setup wizard (hermes_cli/setup.py).
  • Adds comprehensive unit testing under tests/plugins/web/test_gemini_provider.py to cover both search and content extraction paths.
  • Updates documentation (website/docs/user-guide/features/web-search.md) to reflect the new capabilities, API key prerequisites, and configuration examples.

Related Issue

N/A

Fixes N/A

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

modified:   hermes_cli/config.py
new file:   plugins/web/gemini/__init__.py
new file:   plugins/web/gemini/plugin.yaml
new file:   tests/plugins/web/test_gemini_provider.py
modified:   tests/plugins/web/test_web_search_provider_plugins.py
modified:   tools/web_tools.py
modified:   website/docs/user-guide/features/web-search.md

How to Test

in config.yaml:

web:
backend: gemini
gemini_model: gemini-3.1-flash-lite
search_backend: google_search

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: Ubuntu 26.04

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

@donbowman donbowman requested a review from a team May 15, 2026 00:48
@alt-glitch alt-glitch added type/feature New feature or request comp/plugins Plugin system and bundled plugins comp/tools Tool registry, model_tools, toolsets tool/web Web search and extraction provider/gemini Google Gemini (AI Studio, Cloud Code) P3 Low — cosmetic, nice to have labels May 15, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Competing implementation of #13268 (Gemini web search backend). This PR is more comprehensive (plugin structure, tests, docs, setup wizard integration) but implements the same feature. One should be chosen and the other closed.

@donbowman

Copy link
Copy Markdown
Author

Competing implementation of #13268 (Gemini web search backend). This PR is more comprehensive (plugin structure, tests, docs, setup wizard integration) but implements the same feature. One should be chosen and the other closed.

this one also fetches the grounding urls and normalises them. it also implements extract.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new built-in web backend plugin (gemini) that uses the google-genai SDK to perform web search + extraction via Gemini Google Search Grounding, and wires it into backend auto-detection, configuration defaults, CLI setup messaging, tests, and user documentation.

Changes:

  • Adds GeminiWebSearchProvider under plugins/web/gemini/ and registers it as a bundled backend.
  • Extends backend selection/availability logic to support gemini when GEMINI_API_KEY or GOOGLE_API_KEY is set, and adds a web.gemini_model config default.
  • Adds/updates tests and docs to include the new provider and configuration.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
plugins/web/gemini/provider.py Implements Gemini search/extract provider using google-genai with Google Search Grounding.
plugins/web/gemini/__init__.py Registers the Gemini provider with the plugin context.
plugins/web/gemini/plugin.yaml Declares the bundled backend plugin and provider name.
tools/web_tools.py Adds gemini to backend detection, availability checks, and status output.
tools/lazy_deps.py Adds a lazy-install mapping entry for google-genai.
hermes_cli/config.py Adds default web.gemini_model config value.
hermes_cli/setup.py Updates setup summary text to mention Gemini key(s).
hermes_cli/nous_subscription.py Treats Gemini keys as direct web credentials for feature availability detection.
tests/plugins/web/test_gemini_provider.py Adds unit tests for Gemini provider availability and unconfigured error handling.
tests/plugins/web/test_web_search_provider_plugins.py Extends plugin registry/capability tests to include gemini.
website/docs/user-guide/features/web-search.md Documents Gemini backend setup, env vars, and config examples.
pyproject.toml Adds google-genai to the google extra dependencies.
Comments suppressed due to low confidence (1)

tests/plugins/web/test_web_search_provider_plugins.py:89

  • This test/docstring still says “seven” plugins, but the registry assertion now includes 8 providers (adds gemini). Please update the test name/docstring to match the new expected count so failures and future refactors aren’t misleading.
class TestBundledPluginsRegister:
    """All seven bundled web plugins discover and register correctly."""

    def test_all_seven_plugins_present_in_registry(self) -> None:
        _ensure_plugins_loaded()
        from agent.web_search_registry import list_providers

        names = sorted(p.name for p in list_providers())
        assert names == [
            "brave-free",
            "ddgs",
            "exa",
            "firecrawl",
            "gemini",
            "parallel",
            "searxng",
            "tavily",
        ]

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/plugins/web/test_web_search_provider_plugins.py Outdated
Comment thread plugins/web/gemini/provider.py Outdated
Comment thread plugins/web/gemini/plugin.yaml Outdated
Comment thread plugins/web/gemini/provider.py
Comment thread tests/plugins/web/test_gemini_provider.py
Comment thread plugins/web/gemini/provider.py Outdated
Comment thread tests/plugins/web/test_web_search_provider_plugins.py Outdated
Comment thread website/docs/user-guide/features/web-search.md Outdated
Comment thread plugins/web/gemini/provider.py Outdated
Comment thread website/docs/user-guide/features/web-search.md Outdated
@donbowman donbowman force-pushed the add-gemini-search branch from ed65963 to dffd3a8 Compare May 19, 2026 12:45

@austinpickett austinpickett left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please resolve comments from Copilot

@donbowman

Copy link
Copy Markdown
Author

Please resolve comments from Copilot

will do!

@austinpickett austinpickett requested a review from Copilot May 19, 2026 13:54

This comment was marked as spam.

@donbowman

Copy link
Copy Markdown
Author

I have addressed the issues copilot mentioned. It seems to have encountered an error tho? I don't think i can re-trigger it.

@donbowman

Copy link
Copy Markdown
Author

is there anything more needed from me on this?

@donbowman donbowman force-pushed the add-gemini-search branch from 9057cc9 to a0a504b Compare May 28, 2026 21:45
@donbowman donbowman force-pushed the add-gemini-search branch from a0a504b to 08d4565 Compare June 3, 2026 01:46
donbowman added a commit to donbowman/hermes-agent that referenced this pull request Jun 3, 2026
Resolve issues identified in
NousResearch#26021 (review)

* Removed Duplicate Tests: tests/plugins/web/test_web_search_provider_plugins.py
  - Removed the duplicated test_gemini_available_with_google_key definitions
    that were causing earlier tests to be overridden and losing coverage.

* Updated Environment Setup Clearing: tests/plugins/web/test_web_search_provider_plugins.py
  - Added GEMINI_API_KEY and GOOGLE_API_KEY to the _clear_web_env method so
    every test starts from a clean web-provider environment without flakiness.

* Improved Provider Setup Schema: plugins/web/gemini/provider.py - Updated
  get_setup_schema() to accept and explicitly list both GEMINI_API_KEY and
  GOOGLE_API_KEY options for authentication so users are better guided via
  the CLI picker.

* Plugin Configuration Tag Update: plugins/web/gemini/plugin.yaml - Updated
  the description to mention that both GEMINI_API_KEY and GOOGLE_API_KEY
  are acceptable configurations.

* Fixed Fallback URL Encoding: plugins/web/gemini/provider.py - Switched
  to using urllib.parse.quote_plus(query) for the Google Search fallback
  URL instead of query.replace(" ", "+") to properly handle non-ASCII
  characters and valid symbol queries.

* Added Success Path Tests: tests/plugins/web/test_gemini_provider.py
  - Added test_search_success and test_extract_success tests that mock
    the Google GenAI client and its responses. This verifies the actual
    implementation logic for valid requests, which wasn't previously covered.

* Included GOOGLE_API_KEY in Setup Summary: hermes_cli/setup.py -
  Mentioned GOOGLE_API_KEY next to GEMINI_API_KEY in the tool status
  summary help text to assure users who use a Google key that their setup
  is correctly detected.

* Re-mapped Lazy Dependency Key: tools/lazy_deps.py & plugins/web/gemini/provider.py
  - Changed the lazy loading identifier from google.genai to search.gemini to
    align with the convention used by other search providers like search.exa,
    search.firecrawl, etc.

* Parameterised Logging: plugins/web/gemini/provider.py - Replaced
  the eager f-string logic in logger.debug statements with standard
  parameterised logging (logger.debug("... %s", var)) for better performance
  and consistency.

* Refined Documentation (.env): website/docs/user-guide/features/web-search.md
  - Explicitly commented a # GOOGLE_API_KEY=your-google-key-here alternative
    in the .env code block, and added GOOGLE_API_KEY to the Gemini entry in
    the provider table to remove any ambiguity.
@JensRudolph

Copy link
Copy Markdown

I also would like to see this feature.

@donbowman

Copy link
Copy Markdown
Author

I also would like to see this feature.

its working well in my branch, you can feel free to merge this in to your tree if you wish to try.

i'm not sure what more is needed from me to get it merged.

- Implements a new `GeminiWebSearchProvider` plugin under `plugins/web/gemini/` to support web search and extraction using the `google-genai` SDK and Google Search Grounding.
- Updates `tools/web_tools.py` backend detection logic and allows falling back to `gemini` if `GEMINI_API_KEY` or `GOOGLE_API_KEY` are provided.
- Configures `web.gemini_model` mapping in `hermes_cli/config.py` with a default of `gemini-3.1-flash-lite`.
- Integrates the Gemini backend into the interactive CLI setup wizard (`hermes_cli/setup.py`).
- Adds comprehensive unit testing under `tests/plugins/web/test_gemini_provider.py` to cover both search and content extraction paths.
- Updates documentation (`website/docs/user-guide/features/web-search.md`) to reflect the new capabilities, API key prerequisites, and configuration examples.
Resolve issues identified in
NousResearch#26021 (review)

* Removed Duplicate Tests: tests/plugins/web/test_web_search_provider_plugins.py
  - Removed the duplicated test_gemini_available_with_google_key definitions
    that were causing earlier tests to be overridden and losing coverage.

* Updated Environment Setup Clearing: tests/plugins/web/test_web_search_provider_plugins.py
  - Added GEMINI_API_KEY and GOOGLE_API_KEY to the _clear_web_env method so
    every test starts from a clean web-provider environment without flakiness.

* Improved Provider Setup Schema: plugins/web/gemini/provider.py - Updated
  get_setup_schema() to accept and explicitly list both GEMINI_API_KEY and
  GOOGLE_API_KEY options for authentication so users are better guided via
  the CLI picker.

* Plugin Configuration Tag Update: plugins/web/gemini/plugin.yaml - Updated
  the description to mention that both GEMINI_API_KEY and GOOGLE_API_KEY
  are acceptable configurations.

* Fixed Fallback URL Encoding: plugins/web/gemini/provider.py - Switched
  to using urllib.parse.quote_plus(query) for the Google Search fallback
  URL instead of query.replace(" ", "+") to properly handle non-ASCII
  characters and valid symbol queries.

* Added Success Path Tests: tests/plugins/web/test_gemini_provider.py
  - Added test_search_success and test_extract_success tests that mock
    the Google GenAI client and its responses. This verifies the actual
    implementation logic for valid requests, which wasn't previously covered.

* Included GOOGLE_API_KEY in Setup Summary: hermes_cli/setup.py -
  Mentioned GOOGLE_API_KEY next to GEMINI_API_KEY in the tool status
  summary help text to assure users who use a Google key that their setup
  is correctly detected.

* Re-mapped Lazy Dependency Key: tools/lazy_deps.py & plugins/web/gemini/provider.py
  - Changed the lazy loading identifier from google.genai to search.gemini to
    align with the convention used by other search providers like search.exa,
    search.firecrawl, etc.

* Parameterised Logging: plugins/web/gemini/provider.py - Replaced
  the eager f-string logic in logger.debug statements with standard
  parameterised logging (logger.debug("... %s", var)) for better performance
  and consistency.

* Refined Documentation (.env): website/docs/user-guide/features/web-search.md
  - Explicitly commented a # GOOGLE_API_KEY=your-google-key-here alternative
    in the .env code block, and added GOOGLE_API_KEY to the Gemini entry in
    the provider table to remove any ambiguity.
Change from 'test seven plugins' to 'test plugins'
in test doc/name
@donbowman donbowman force-pushed the add-gemini-search branch from 08d4565 to 01a18ae Compare June 11, 2026 17:21
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 comp/tools Tool registry, model_tools, toolsets P3 Low — cosmetic, nice to have provider/gemini Google Gemini (AI Studio, Cloud Code) tool/web Web search and extraction type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants