Skip to content

Conversation

pshiko
Copy link

@pshiko pshiko commented Oct 19, 2025

Add support for Gemini-specific tools like GoogleSearch and CodeExecution, with validation to prevent FunctionDeclarations and comprehensive test coverage.

Description

Background:
Gemini API provides powerful built-in tools that are distinct from standard FunctionDeclaration-based tools. These tools are defined in separate fields within the Gemini API's Tool type (see https://ai.google.dev/api/caching#Tool). The existing Strands tool interface is designed around standard function declarations and cannot accommodate these Gemini-specific capabilities.

Solution:
This PR implements support for Gemini's built-in tools by adding a new gemini_tools field to GeminiConfig. This approach was chosen over alternatives (modifying core ToolSpec interface or using magic string transformations) because it:

  • Minimizes impact scope (changes contained within Gemini provider)
  • Maintains type safety (uses genai.types.Tool directly)
  • Is future-proof (adapts to Gemini API changes)
  • Provides clear separation between standard function tools and Gemini built-in tools

Implementation Details:

  1. New Configuration Field:
class GeminiConfig(TypedDict, total=False):
    model_id: Required[str]
    params: dict[str, Any]
    gemini_tools: list[genai.types.Tool]  # New field for Gemini built-in tools
  1. Validation Function:
    Added _validate_gemini_tools() to ensure gemini_tools doesn't contain FunctionDeclarations (which should use the standard tools interface):
def _validate_gemini_tools(gemini_tools: list[genai.types.Tool]) -> None:
    for tool in gemini_tools:
        if hasattr(tool, "function_declarations") and tool.function_declarations:
            raise ValueError(
                "gemini_tools should not contain FunctionDeclarations. "
                "Use the standard tools interface for function calling tools."
            )
  1. Tool Merging:
    Updated _format_request_tools() to combine standard function declarations with Gemini-specific tools:
def _format_request_tools(self, tool_specs: Optional[list[ToolSpec]]) -> list[genai.types.Tool]:
    tools = [
        genai.types.Tool(
            function_declarations=[
                genai.types.FunctionDeclaration(...)
                for tool_spec in tool_specs or []
            ]
        )
    ]
    if self.config.get("gemini_tools"):
        tools.extend(self.config.get("gemini_tools", []))
    return tools

Example Usage:

from strands import Agent
from strands.models.gemini import GeminiModel
from google import genai
from google.genai import types

# Use Google Search for grounding with real-time web data
model = GeminiModel(
    model_id="gemini-2.5-flash",
    gemini_tools=[
        types.Tool(google_search=types.GoogleSearch())
    ]
)

agent = Agent(model=model)
response = agent("Who won the euro 2024?")
# Response will be grounded in recent web search results with citations

# Combine with standard function tools
agent_with_both = Agent(
    model=model,
    tools=[my_custom_function_tool]  # Standard function tools still work
)

Tool Usage Tracking:
Due to the fundamental differences in how Gemini's built-in tools operate (server-side execution without explicit tool call/result blocks), this PR does not implement execution history tracking for gemini_tools. Clear tracking of which specific tool was invoked and when is currently difficult with the server-side execution model, and the usage patterns differ significantly from standard function tools. If tool usage tracking for Gemini built-in tools is needed in the future, it can be addressed in a separate PR. The current implementation is fully functional and independent of any future tracking enhancements.

Related Issues

#1049

Documentation PR

Type of Change

New feature
Breaking change

Testing

How have you tested the change? Verify that the changes do not break functionality or introduce warnings in consuming repositories: agents-docs, agents-tools, agents-cli

  • I ran hatch run prepare

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Add support for Gemini-specific tools like GoogleSearch and CodeExecution,
with validation to prevent FunctionDeclarations and comprehensive test coverage.
@Copilot Copilot AI review requested due to automatic review settings October 19, 2025 07:20
Copy link

@Copilot Copilot AI left a comment

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 support for Gemini-specific built-in tools (e.g., GoogleSearch, CodeExecution) by introducing a new gemini_tools field to GeminiConfig. The implementation includes validation to prevent mixing FunctionDeclarations with built-in tools and ensures proper merging of both tool types when making API requests.

Key changes:

  • Added gemini_tools field to GeminiConfig for Gemini-specific tools
  • Implemented validation function to reject FunctionDeclarations in gemini_tools
  • Updated tool formatting to merge standard function declarations with Gemini-specific tools

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/strands/models/gemini.py Added gemini_tools config field, validation function, and tool merging logic
tests/strands/models/test_gemini.py Unit tests for validation logic and tool merging behavior
tests_integ/models/test_model_gemini.py Integration test demonstrating code execution tool usage

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@codecov
Copy link

codecov bot commented Oct 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!


model_id: Required[str]
params: dict[str, Any]
gemini_tools: list[genai.types.Tool]
Copy link
Member

Choose a reason for hiding this comment

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

@pgrayy thoughts on naming here? Would we want to be consistent among providers - maybe something like built_in_tools?

Copy link
Author

Choose a reason for hiding this comment

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

I also think built_in_tools is better — it’s more consistent across providers and the meaning is clearer. If you agree, I’ll make the change even though the PR has already been approved.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants