8000 fix: Allow injecting ObjectMapper in FunctionTool, default to ObjectMapper (re. #473) by vorburger · Pull Request #487 · google/adk-java · GitHub
[go: up one dir, main page]

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).

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

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

0