Skip to content

Conversation

@vorburger
Copy link
Member

@vorburger vorburger commented Oct 7, 2025

Related to #473.

Intentionally just for FunctionTool, for now; but this should eventually really be done everywhere like this (IMHO).

Alternative (and superior) to the initial #486 - but put on hold, until at least that basic version is merged (thus this is Draft).

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @vorburger, 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 improves the FunctionTool's adaptability by introducing dependency injection for its ObjectMapper. This change allows consumers to provide their own ObjectMapper configurations, which is crucial for handling diverse data structures and serialization requirements, while maintaining a sensible default for standard use cases. The refactoring ensures that all JSON-related operations within the tool leverage this configurable instance.

Highlights

  • Injectable ObjectMapper: The FunctionTool class has been refactored to allow an ObjectMapper instance to be injected during its construction, enhancing flexibility and customization for JSON serialization and deserialization.
  • Default ObjectMapper Source: When an ObjectMapper is not explicitly provided, the FunctionTool now defaults to using the mapper obtained from JsonBaseModel.getMapper(), ensuring a consistent default configuration.
  • Internal Method Refactoring: Internal helper methods such as createList and castValue have been converted from static to instance methods, enabling them to utilize the newly introduced instance-specific objectMapper for all JSON conversion operations.
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.

@vorburger vorburger force-pushed the issue-473_ObjectMapper-inject branch from 7d99d03 to f628dc9 Compare October 7, 2025 19:26
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 successfully refactors FunctionTool to allow injecting a custom ObjectMapper, which is a great step towards better flexibility and testability.

I've left a couple of comments on areas that could be improved for consistency and correctness:

  • The ObjectMapper used for schema generation in FunctionCallingUtils is still separate from the one injected into FunctionTool, which could lead to inconsistencies.
  • There's a potential bug in how List parameters are handled in the callLive method, which is different from the more robust implementation in the call method.

Addressing these points will make the FunctionTool more robust, especially when dealing with custom types. Overall, this is a valuable change.

this.funcDeclaration =
FunctionCallingUtils.buildFunctionDeclaration(
this.func, ImmutableList.of("toolContext", "inputStream"));
this.objectMapper = objectMapper;
Copy link
Contributor

Choose a reason for hiding this comment

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

high

While the runtime argument conversion now uses the injected objectMapper, the function declaration schema is built using FunctionCallingUtils, which has its own static, non-configurable ObjectMapper. This can lead to inconsistencies if the injected objectMapper has custom serializers, as the generated schema will not reflect them. This could cause mismatches between what the LLM expects and what the tool can handle at runtime. To ensure consistency, FunctionCallingUtils should also be updated to use the same ObjectMapper instance.

Copy link
Member Author

Choose a reason for hiding this comment

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

TBD...

}

private static List<Object> createList(List<Object> values, Class<?> type) {
private List<Object> createList(List<Object> values, Class<?> type) {
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The callLive method, a caller of this function, has a potential bug. It obtains a java.lang.reflect.Type and casts it directly to Class before passing it here. This is unsafe and will cause a ClassCastException if the type is a ParameterizedType (e.g., for a List<Map<String, String>>). The call method contains the correct, more robust logic for handling this, which should be replicated in callLive to prevent runtime errors.

Copy link
Member Author

Choose a reason for hiding this comment

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

==> #489

@vorburger vorburger marked this pull request as draft October 7, 2025 19:31
vorburger added a commit to vorburger/adk-java that referenced this pull request Oct 7, 2025
vorburger added a commit to vorburger/adk-java that referenced this pull request Oct 24, 2025
tomekpanek added a commit to tomekpanek/adk-java that referenced this pull request Oct 27, 2025
Update core/src/main/java/com/google/adk/sessions/VertexAiSessionService.java

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

test: Add tests for ExampleUtils

Note the bug in the "no input" test.  The header is missing.

PiperOrigin-RevId: 822299706

feat: add `GoogleMapsTool` to enable Google Maps search integration for Gemini 2 models

refactor: Refactoring ExampleUtil

- convertExamplesToText() is broken down into smaller methods (header, user turn, model turns, footer).
- The Example header is always added, even if the input is missing.

PiperOrigin-RevId: 822643263

refactor: Simplify LlmRequest code

PiperOrigin-RevId: 822715169

docs: Adds missing comments

PiperOrigin-RevId: 822718215

fix: Add OpenTelemetry context propagation to span creation

Resolves issue google#403 where ADK Java spans were not properly linking to
parent contexts, causing distributed tracing to break across RxJava
async boundaries. Add Telemetry traceFlowable and use in Runner and BaseAgent

Impact:
- Enables unified trace hierarchy in observability tools
- Preserves backward compatibility (Context.current() safe when no parent)
- All 656 existing tests pass

Test coverage:
- Parent-child span linking
- Root span creation when no parent exists
- Nested span hierarchy (4 levels deep)
- Parallel tool execution
- Thread boundary context propagation

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 823136285

test: Adding a test for telemetry in RunnerTest

PiperOrigin-RevId: 823192673

refactor: Simplifying TestUtils

Basically, the single Event case and multi-Event case had duplicate code.  I consolidated the implementation, and broke down different parts of the process into helper methods.

PiperOrigin-RevId: 823580027

fix: Avoid ClassCastException and reduce copy/pasta 🍝 in FunctionTool

Prompted by google#487 (comment).
tomekpanek added a commit to tomekpanek/adk-java that referenced this pull request Oct 27, 2025
Update core/src/main/java/com/google/adk/sessions/VertexAiSessionService.java

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

test: Add tests for ExampleUtils

Note the bug in the "no input" test.  The header is missing.

PiperOrigin-RevId: 822299706

feat: add `GoogleMapsTool` to enable Google Maps search integration for Gemini 2 models

refactor: Refactoring ExampleUtil

- convertExamplesToText() is broken down into smaller methods (header, user turn, model turns, footer).
- The Example header is always added, even if the input is missing.

PiperOrigin-RevId: 822643263

refactor: Simplify LlmRequest code

PiperOrigin-RevId: 822715169

docs: Adds missing comments

PiperOrigin-RevId: 822718215

fix: Add OpenTelemetry context propagation to span creation

Resolves issue google#403 where ADK Java spans were not properly linking to
parent contexts, causing distributed tracing to break across RxJava
async boundaries. Add Telemetry traceFlowable and use in Runner and BaseAgent

Impact:
- Enables unified trace hierarchy in observability tools
- Preserves backward compatibility (Context.current() safe when no parent)
- All 656 existing tests pass

Test coverage:
- Parent-child span linking
- Root span creation when no parent exists
- Nested span hierarchy (4 levels deep)
- Parallel tool execution
- Thread boundary context propagation

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 823136285

test: Adding a test for telemetry in RunnerTest

PiperOrigin-RevId: 823192673

refactor: Simplifying TestUtils

Basically, the single Event case and multi-Event case had duplicate code.  I consolidated the implementation, and broke down different parts of the process into helper methods.

PiperOrigin-RevId: 823580027

fix: Avoid ClassCastException and reduce copy/pasta 🍝 in FunctionTool

Prompted by google#487 (comment).

feat: add `GoogleMapsTool` to enable Google Maps search integration for Gemini 2 models

refactor: Refactoring ExampleUtil

- convertExamplesToText() is broken down into smaller methods (header, user turn, model turns, footer).
- The Example header is always added, even if the input is missing.

PiperOrigin-RevId: 822643263

refactor: Simplify LlmRequest code

PiperOrigin-RevId: 822715169

docs: Adds missing comments

PiperOrigin-RevId: 822718215

fix: Add OpenTelemetry context propagation to span creation

Resolves issue google#403 where ADK Java spans were not properly linking to
parent contexts, causing distributed tracing to break across RxJava
async boundaries. Add Telemetry traceFlowable and use in Runner and BaseAgent

Impact:
- Enables unified trace hierarchy in observability tools
- Preserves backward compatibility (Context.current() safe when no parent)
- All 656 existing tests pass

Test coverage:
- Parent-child span linking
- Root span creation when no parent exists
- Nested span hierarchy (4 levels deep)
- Parallel tool execution
- Thread boundary context propagation

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 823136285

test: Adding a test for telemetry in RunnerTest

PiperOrigin-RevId: 823192673

refactor: Simplifying TestUtils

Basically, the single Event case and multi-Event case had duplicate code.  I consolidated the implementation, and broke down different parts of the process into helper methods.

PiperOrigin-RevId: 823580027

fix: Avoid ClassCastException and reduce copy/pasta 🍝 in FunctionTool

Prompted by google#487 (comment).

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 824617972
tomekpanek pushed a commit to tomekpanek/adk-java that referenced this pull request Oct 27, 2025
    This is needed for the policy engine which consumes metadata from the tools. The current design allows tools to be created first and then they get metadata during registration.

PiperOrigin-RevId: 822277777

listSessions returns sessions with empty state

Update core/src/main/java/com/google/adk/sessions/VertexAiSessionService.java

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

test: Add tests for ExampleUtils

Note the bug in the "no input" test.  The header is missing.

PiperOrigin-RevId: 822299706

feat: add `GoogleMapsTool` to enable Google Maps search integration for Gemini 2 models

refactor: Refactoring ExampleUtil

- convertExamplesToText() is broken down into smaller methods (header, user turn, model turns, footer).
- The Example header is always added, even if the input is missing.

PiperOrigin-RevId: 822643263

refactor: Simplify LlmRequest code

PiperOrigin-RevId: 822715169

docs: Adds missing comments

PiperOrigin-RevId: 822718215

fix: Add OpenTelemetry context propagation to span creation

Resolves issue google#403 where ADK Java spans were not properly linking to
parent contexts, causing distributed tracing to break across RxJava
async boundaries. Add Telemetry traceFlowable and use in Runner and BaseAgent

Impact:
- Enables unified trace hierarchy in observability tools
- Preserves backward compatibility (Context.current() safe when no parent)
- All 656 existing tests pass

Test coverage:
- Parent-child span linking
- Root span creation when no parent exists
- Nested span hierarchy (4 levels deep)
- Parallel tool execution
- Thread boundary context propagation

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 823136285

test: Adding a test for telemetry in RunnerTest

PiperOrigin-RevId: 823192673

refactor: Simplifying TestUtils

Basically, the single Event case and multi-Event case had duplicate code.  I consolidated the implementation, and broke down different parts of the process into helper methods.

PiperOrigin-RevId: 823580027

fix: Avoid ClassCastException and reduce copy/pasta 🍝 in FunctionTool

Prompted by google#487 (comment).

test: Add tests for ExampleUtils

Note the bug in the "no input" test.  The header is missing.

PiperOrigin-RevId: 822299706

feat: add `GoogleMapsTool` to enable Google Maps search integration for Gemini 2 models

refactor: Refactoring ExampleUtil

- convertExamplesToText() is broken down into smaller methods (header, user turn, model turns, footer).
- The Example header is always added, even if the input is missing.

PiperOrigin-RevId: 822643263

refactor: Simplify LlmRequest code

PiperOrigin-RevId: 822715169

docs: Adds missing comments

PiperOrigin-RevId: 822718215

fix: Add OpenTelemetry context propagation to span creation

Resolves issue google#403 where ADK Java spans were not properly linking to
parent contexts, causing distributed tracing to break across RxJava
async boundaries. Add Telemetry traceFlowable and use in Runner and BaseAgent

Impact:
- Enables unified trace hierarchy in observability tools
- Preserves backward compatibility (Context.current() safe when no parent)
- All 656 existing tests pass

Test coverage:
- Parent-child span linking
- Root span creation when no parent exists
- Nested span hierarchy (4 levels deep)
- Parallel tool execution
- Thread boundary context propagation

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 823136285

test: Adding a test for telemetry in RunnerTest

PiperOrigin-RevId: 823192673

refactor: Simplifying TestUtils

Basically, the single Event case and multi-Event case had duplicate code.  I consolidated the implementation, and broke down different parts of the process into helper methods.

PiperOrigin-RevId: 823580027

fix: Avoid ClassCastException and reduce copy/pasta 🍝 in FunctionTool

Prompted by google#487 (comment).

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 824617972

listSessions returns sessions with empty state

Update core/src/main/java/com/google/adk/sessions/VertexAiSessionService.java

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

test: Add tests for ExampleUtils

Note the bug in the "no input" test.  The header is missing.

PiperOrigin-RevId: 822299706

feat: add `GoogleMapsTool` to enable Google Maps search integration for Gemini 2 models

refactor: Refactoring ExampleUtil

- convertExamplesToText() is broken down into smaller methods (header, user turn, model turns, footer).
- The Example header is always added, even if the input is missing.

PiperOrigin-RevId: 822643263

refactor: Simplify LlmRequest code

PiperOrigin-RevId: 822715169

docs: Adds missing comments

PiperOrigin-RevId: 822718215

fix: Add OpenTelemetry context propagation to span creation

Resolves issue google#403 where ADK Java spans were not properly linking to
parent contexts, causing distributed tracing to break across RxJava
async boundaries. Add Telemetry traceFlowable and use in Runner and BaseAgent

Impact:
- Enables unified trace hierarchy in observability tools
- Preserves backward compatibility (Context.current() safe when no parent)
- All 656 existing tests pass

Test coverage:
- Parent-child span linking
- Root span creation when no parent exists
- Nested span hierarchy (4 levels deep)
- Parallel tool execution
- Thread boundary context propagation

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 823136285

test: Adding a test for telemetry in RunnerTest

PiperOrigin-RevId: 823192673

refactor: Simplifying TestUtils

Basically, the single Event case and multi-Event case had duplicate code.  I consolidated the implementation, and broke down different parts of the process into helper methods.

PiperOrigin-RevId: 823580027

fix: Avoid ClassCastException and reduce copy/pasta 🍝 in FunctionTool

Prompted by google#487 (comment).

feat: add `GoogleMapsTool` to enable Google Maps search integration for Gemini 2 models

refactor: Refactoring ExampleUtil

- convertExamplesToText() is broken down into smaller methods (header, user turn, model turns, footer).
- The Example header is always added, even if the input is missing.

PiperOrigin-RevId: 822643263

refactor: Simplify LlmRequest code

PiperOrigin-RevId: 822715169

docs: Adds missing comments

PiperOrigin-RevId: 822718215

fix: Add OpenTelemetry context propagation to span creation

Resolves issue google#403 where ADK Java spans were not properly linking to
parent contexts, causing distributed tracing to break across RxJava
async boundaries. Add Telemetry traceFlowable and use in Runner and BaseAgent

Impact:
- Enables unified trace hierarchy in observability tools
- Preserves backward compatibility (Context.current() safe when no parent)
- All 656 existing tests pass

Test coverage:
- Parent-child span linking
- Root span creation when no parent exists
- Nested span hierarchy (4 levels deep)
- Parallel tool execution
- Thread boundary context propagation

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 823136285

test: Adding a test for telemetry in RunnerTest

PiperOrigin-RevId: 823192673

refactor: Simplifying TestUtils

Basically, the single Event case and multi-Event case had duplicate code.  I consolidated the implementation, and broke down different parts of the process into helper methods.

PiperOrigin-RevId: 823580027

fix: Avoid ClassCastException and reduce copy/pasta 🍝 in FunctionTool

Prompted by google#487 (comment).

feat: HITL/Introduce ToolConfirmations and integrate them into ToolContext

This is a port of the python implementation and part of the "human in the loop" workflow.

PiperOrigin-RevId: 824617972
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.

1 participant