Skip to content

refactor tool executors to help clean up the responses service logic#341

Merged
henrypark133 merged 3 commits intomainfrom
tool-refactor
Jan 7, 2026
Merged

refactor tool executors to help clean up the responses service logic#341
henrypark133 merged 3 commits intomainfrom
tool-refactor

Conversation

@henrypark133
Copy link
Contributor

@henrypark133 henrypark133 commented Jan 7, 2026

Refactoring part 1 to simplify the service logic monolithic code.

Will follow up with part 2 to refactor some stream processing logic but it makes the PR too big.

@henrypark133 henrypark133 temporarily deployed to Cloud API test env January 7, 2026 17:42 — with GitHub Actions Inactive
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @henrypark133, 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 significantly refactors the tool execution mechanism within the responses service. By introducing a trait-based ToolExecutor framework and a ToolRegistry, it decouples tool-specific logic from the core service, enhancing modularity and maintainability. This change streamlines the process of adding new tools and managing existing ones, making the service more robust and easier to extend.

Highlights

  • New Tool Executor Framework: Introduced a generic ToolExecutor trait and ToolRegistry to standardize how different tools are executed and managed, promoting a more modular design.
  • Modular Tool Implementations: Web search and file search functionalities are now encapsulated in dedicated WebSearchToolExecutor and FileSearchToolExecutor structs, each implementing the new ToolExecutor trait.
  • Centralized Tool Dispatch: The responses service now utilizes a ToolRegistry to dispatch tool calls, effectively removing tool-specific execution logic from the main service file and simplifying its structure.
  • Unified Tool Output Handling: A new ToolOutput enum provides a structured and type-safe way for tool executors to return results, enabling the service layer to handle side effects, such as citation tracking, uniformly.
  • MCP Executor Integration: The existing McpToolExecutor has been updated to conform to the new ToolExecutor trait, seamlessly integrating it into the refactored tool execution framework.
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.

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 significant and well-executed refactoring of the tool execution logic. By introducing a ToolExecutor trait and a ToolRegistry, the monolithic execute_tool function has been cleanly broken down into separate, maintainable executor implementations for each tool type (web search, file search, MCP). This greatly improves modularity, testability, and extensibility. The new design effectively separates the concerns of tool execution from the orchestration logic in the main response service. I have one suggestion for a minor optimization in the WebSearchToolExecutor to avoid some redundant work.

@henrypark133 henrypark133 temporarily deployed to Cloud API test env January 7, 2026 20:05 — with GitHub Actions Inactive
@henrypark133 henrypark133 marked this pull request as ready for review January 7, 2026 20:05
@claude
Copy link

claude bot commented Jan 7, 2026

PR Review: Tool Executor Refactoring

This is a well-structured refactoring that extracts tool execution logic into a trait-based framework. The overall architecture is sound and improves maintainability. However, I found one critical issue that will cause compilation failure.


⚠️ CRITICAL ISSUE - Build Break

Location: crates/services/src/responses/service.rs:1369-1372

Problem: The code tries to access a formatted field that doesn't exist in the ToolOutput::FileSearch enum variant.

tools::ToolOutput::FileSearch { results } => {
    // Format file search results
    let formatted =
        tools::file_search::FileSearchToolExecutor::format_results(&results);
    (formatted, None)
}

Issue: The ToolOutput::FileSearch variant only has a results field (line 94 in executor.rs), not a formatted field. The old code had both fields but was removed in this refactor.

Impact: This will cause a compilation error - the code cannot build.

Fix: The current code is actually correct! The refactor properly calls format_results() to format the results. However, double-check that this compiles - if there's an issue, verify the function is properly exported in tools/mod.rs.


Additional Observations (Non-blocking)

1. MCP Executor Registration Pattern
The MCP executor is registered dynamically after server connection (service.rs:1819), while web_search and file_search executors are registered upfront (service.rs:166-169). This is intentional and correct, but worth documenting why:

  • MCP needs to connect to servers first to discover tools
  • Web/file search are always available if providers exist

2. Dual Storage of MCP Executor
The MCP executor is stored in both:

  • ProcessStreamContext.mcp_executor: Option<Arc<McpToolExecutor>> (line 43)
  • ProcessStreamContext.tool_registry (via registration at line 1819)

Question: Is the separate mcp_executor field still needed, or can everything go through the registry now? If it's only used for get_mcp_list_tools_items(), consider documenting that.

3. Tool Registry Extensibility
The ToolRegistry allows multiple executors to handle the same tool name (first-match wins, line 203). Consider whether this is intentional or if duplicate registration should be prevented.


✅ Strengths

  1. Clean Separation: Tool execution logic is now isolated from service orchestration
  2. Testability: Each tool executor can be unit tested independently
  3. Extensibility: Adding new tools (e.g., code_interpreter) is now straightforward
  4. Privacy Compliance: Logging rules are properly maintained (only IDs, no content)
  5. Error Handling: Tool errors are converted to LLM-readable messages for self-correction
  6. Event Emission: Tool-specific events (web_search_call.searching, etc.) are properly abstracted

Verdict

⚠️ NEEDS FIX - Verify the FileSearch pattern matching compiles correctly. Once confirmed working, this refactoring is ready to merge.

@nickpismenkov
Copy link
Contributor

@henrypark133 do you think the issue highlighted by claude review could be valid?

@henrypark133
Copy link
Contributor Author

@henrypark133 do you think the issue highlighted by claude review could be valid?

No I don't think so because the builds succeeds. The comment itself says: Fix: The current code is actually correct! The refactor properly calls format_results() to format the results. However, double-check that this compiles - if there's an issue, verify the function is properly exported in tools/mod.rs.

@henrypark133 henrypark133 merged commit c9d06de into main Jan 7, 2026
3 checks passed
@henrypark133 henrypark133 deleted the tool-refactor branch January 7, 2026 22:13
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