Skip to content

Conversation

@jayy-77
Copy link

@jayy-77 jayy-77 commented Jan 17, 2026

Repeated tool execution can happen when the model emits the same function call multiple times (same tool name + same arguments), which is especially painful for slow or expensive tools.

This change introduces an invocation-scoped single-flight cache:

  • Adds RunConfig.dedupe_tool_calls (opt-in) to reuse results for identical calls
  • Always dedupes BaseTool.is_long_running tools (safer default for long ops)
  • Ensures only the first execution applies tool side effects (state/artifacts)
  • Emits cached responses with per-call function_response.id and debug metadata

Tests:

  • Added unit tests covering duplicate calls across steps and within one step.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

…3940)

Repeated tool execution can happen when the model emits the same function call
multiple times (same tool name + same arguments), which is especially painful
for slow or expensive tools.

This change introduces an invocation-scoped single-flight cache:
- Adds RunConfig.dedupe_tool_calls (opt-in) to reuse results for identical calls
- Always dedupes BaseTool.is_long_running tools (safer default for long ops)
- Ensures only the first execution applies tool side effects (state/artifacts)
- Emits cached responses with per-call function_response.id and debug metadata

Tests:
- Added unit tests covering duplicate calls across steps and within one step.
@google-cla
Copy link

google-cla bot commented Jan 17, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jayy-77, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses the issue of redundant tool executions when a model repeatedly emits the same function call. By implementing an invocation-scoped caching mechanism, it significantly improves efficiency and reduces costs associated with slow or expensive tools. The changes ensure that identical tool calls are executed only once, while still providing the expected responses for all calls, and carefully manage side effects to prevent unintended multiple applications.

Highlights

  • Tool Call Deduplication: Introduced an invocation-scoped single-flight cache to prevent redundant execution of identical tool calls (same tool name and arguments) within a single invocation. This is particularly beneficial for slow or expensive tools.
  • Configurable Opt-in and Automatic Deduplication: Added a new dedupe_tool_calls boolean flag to RunConfig for opt-in deduplication. Additionally, tools marked as is_long_running will always be deduped by default, ensuring safer handling of long-running operations.
  • Side Effect Management: Ensures that tool side effects (state or artifact deltas) are applied only once, from the first successful execution of a tool, even if subsequent identical calls are deduped.
  • Cache Hit Metadata: Cached responses will now include adk_tool_call_cache_hit: True in their custom_metadata to indicate that the result was served from the cache.
  • New Caching Infrastructure: Implemented a new _tool_call_cache and associated locking mechanism within InvocationContext, along with methods to canonicalize tool arguments for consistent cache keys.
  • Comprehensive Unit Tests: Added new unit tests to cover scenarios where identical tool calls occur across different steps and within a single step, verifying the deduplication logic.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Jan 17, 2026
@adk-bot
Copy link
Collaborator

adk-bot commented Jan 17, 2026

Hello @jayy-77, thank you for your contribution!

Before we can merge this PR, you'll need to sign our Contributor License Agreement (CLA). You can do so here: https://cla.developers.google.com/

Response from ADK Triaging Agent

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a valuable feature for deduplicating identical tool calls within an invocation, which can significantly improve performance and reduce costs for slow or expensive tools. The implementation is robust, employing a single-flight pattern with asyncio.Task and proper locking to handle concurrent requests effectively. The exception handling, which clears the cache on failure, is a thoughtful addition that prevents caching failed states. The changes are well-contained, and the inclusion of unit tests covering both sequential and parallel duplicate calls is excellent. I have a couple of minor suggestions to reduce code duplication, but overall, this is a high-quality contribution.

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

Labels

core [Component] This issue is related to the core interface and implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tool Call has been called multiple times by ADK

2 participants