Skip to content

feat(google_genai): add google_server_tools to GoogleGenAIChatGenerator#3571

Open
Aftabbs wants to merge 2 commits into
deepset-ai:mainfrom
Aftabbs:feat/google-genai-server-tools
Open

feat(google_genai): add google_server_tools to GoogleGenAIChatGenerator#3571
Aftabbs wants to merge 2 commits into
deepset-ai:mainfrom
Aftabbs:feat/google-genai-server-tools

Conversation

@Aftabbs

@Aftabbs Aftabbs commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds google_server_tools: list[dict[str, Any]] | None = None parameter to GoogleGenAIChatGenerator.__init__
  • Enables users to pass Google's built-in server-side tools (e.g. google_search, code_execution) to the Gemini API
  • Server tools are merged with Haystack Tool/Toolset at request time and passed in GenerateContentConfig.tools
  • Serializes/deserializes cleanly via to_dict() / from_dict()

Motivation

Google's Gemini API supports built-in tools that are not Haystack Tool objects and cannot be expressed as function declarations. For example:

from google.genai import types
# Native Google search tool
types.Tool(google_search=types.GoogleSearch())

# Code execution tool
types.Tool(code_execution=types.ToolCodeExecution())

Currently there is no way to pass these through GoogleGenAIChatGenerator because the tools parameter only accepts ToolsType (Haystack Tools/Toolsets). This PR adds google_server_tools to fill that gap.

Usage:

generator = GoogleGenAIChatGenerator(
    model="gemini-2.5-flash",
    google_server_tools=[{"google_search": {}}],
)

Or combined with Haystack tools:

generator = GoogleGenAIChatGenerator(
    model="gemini-2.5-flash",
    tools=[my_haystack_tool],
    google_server_tools=[{"google_search": {}}, {"code_execution": {}}],
)

Relation to existing work

Follows the same pattern as anthropic_server_tools introduced in #3386 for AnthropicChatGenerator.

Test plan

  • test_init_with_google_server_tools — verifies _google_server_tools is stored on init
  • test_to_dict_with_google_server_tools — verifies serialization round-trip
  • test_from_dict_with_google_server_tools — verifies deserialization round-trip
  • test_to_dict_default_google_server_tools_is_none — verifies default is None
  • test_run_with_google_server_tools — verifies native tool is passed to GenerateContentConfig
  • test_run_merges_haystack_and_google_server_tools — verifies Haystack + native tools are merged

…hatGenerator

Adds `google_server_tools: list[dict[str, Any]] | None = None` to
`GoogleGenAIChatGenerator.__init__`, enabling users to pass Google's
built-in server-side tools (e.g. google_search, code_execution) directly
to the Gemini API.

These tools are merged with any Haystack Tool/Toolset at request time:
each dict is converted to a `google.genai.types.Tool` via model_validate
and appended to the tools list sent in `GenerateContentConfig`.

Follows the same pattern as `anthropic_server_tools` in deepset-ai#3386.

Closes #<TBD>
@Aftabbs Aftabbs requested a review from a team as a code owner July 9, 2026 13:52
@Aftabbs Aftabbs requested review from anakin87 and removed request for a team July 9, 2026 13:52
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Heads-up for maintainers

This PR is from a fork and touches integrations whose integration tests require API keys.
Those tests are skipped in CI because fork PRs don't have access to repo secrets for security reasons.

Affected integrations:

  • google_genai

Please run the integration tests locally (hatch run test:integration inside each folder) before approving.

@github-actions github-actions Bot added the type:documentation Improvements or additions to documentation label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Coverage report (google_genai)

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  integrations/google_genai/src/haystack_integrations/components/generators/google_genai/chat
  chat_generator.py 597
Project Total  

This report was generated by python-coverage-comment-action

@anakin87 anakin87 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the contribution.

I found some opportunities for improvement.

Quick question: have you tried this feature locally yourself?

:param streaming_callback: A callback function that is called when a new token is received from the stream.
:param tools: A list of Tool and/or Toolset objects, or a single Toolset for which the model can prepare calls.
Each tool should have a unique name.
:param google_server_tools: A list of Google server-side (built-in) tools passed directly to the API.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you explain how this syntax works?

We should support all Google built-in tools if possible, also allowing to pass potential parameters they accept.

So let's verify that this syntax is functional for this goal or choose another one; also provide users with an example in docstring and a link to Google tools.

assert restored._generation_kwargs["response_format"] == schema
assert restored._generation_kwargs["temperature"] == 0.5

def test_init_with_google_server_tools(self, monkeypatch):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's incorporate these new tests into existing tests or at least move them close to other similar ones

# _convert_tools_to_google_genai_format bundles all function declarations into one Tool object,
# plus one Tool object for google_search
assert len(config.tools) == 2

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's add a live integration test in the appropriate section.

…ests

- Expand google_server_tools docstring: explain dict-to-Tool conversion,
  list all built-in tools (google_search, code_execution, url_context),
  add usage example and link to Google built-in tools docs
- Move serde tests (test_init/to_dict/from_dict_with_google_server_tools)
  adjacent to mixed-toolset tests in TestGoogleGenAIChatGeneratorInitSerDe
- Add live integration test test_live_run_with_google_server_tools to
  TestGoogleGenAIChatGeneratorInference
@Aftabbs

Aftabbs commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Yes — I tested the parameter wiring and serialization locally (unit tests pass). For the live API path, I've added test_live_run_with_google_server_tools to TestGoogleGenAIChatGeneratorInference which exercises the full end-to-end flow when GOOGLE_API_KEY is present. Since integration tests require an API key (which fork PRs don't have in CI), the live test is guarded and will only run with a real key. The unit tests cover the serialization, deserialization, and that the google_server_tools list reaches the request params correctly.

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

Labels

integration:google-genai type:documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants