fix(openapi): disambiguate colliding truncated tool names - #7284
Open
chelsealong wants to merge 1 commit into
Open
chelsealong wants to merge 1 commit into
chelsealong wants to merge 1 commit into
Conversation
Operation IDs that share a >60-char prefix all truncate to the same name in OpenAPIToolset._parse, so distinct operations collapse to one RestApiTool and the model only sees the last-registered one; earlier endpoints become unreachable. Append a stable numeric suffix when a truncated name collides with one already generated for the toolset. Fixes google#7281
This was referenced Sep 25, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fixes #7281.
Gemini limits function names to less than 64 characters, so
OperationParser.get_function_name()andRestApiTool.__init__both hardtruncate the generated tool name to 60 characters. Codegen-style OpenAPI
specs routinely produce long
operationIds that share a long commonprefix, so distinct operations can truncate to the exact same name.
When that happens in
OpenAPIToolset._parse, every colliding operationproduces a
RestApiToolwith the same.name.LlmRequest.append_toolsstill sends a
FunctionDeclarationfor each tool, buttools_dictkeepsonly the last one registered, so the model gets duplicate declarations with
one name while every call is routed to the last-registered operation's
endpoint — the earlier endpoint(s) become silently unreachable.
Fix
OpenAPIToolset._parsebuilds everyRestApiToolfor a given spec in oneplace and therefore has full visibility into the whole toolset. After a
tool's name is generated, check it against the names already produced for
this toolset; on a collision, append a short numeric suffix (
_2,_3,...) and truncate so the final name still fits in 60 characters.
This is a minimal, additive change scoped to
OpenAPIToolset._parse— itdoes not change
get_function_name()orRestApiTool.__init__, which haveno visibility into sibling operations and can't dedupe on their own.
Test plan
Added
test_openapi_toolset_disambiguates_colliding_truncated_namesintests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py,using two operations whose
operationIds share a 63-character prefix(mirroring the issue's repro) and differ only after the 60-char truncation
point. It asserts the toolset produces two distinct tool names, each ≤60
chars, and that both original endpoints remain reachable via
get_tool().Confirmed the test fails without the fix (reverted just the source file
with
git checkout HEAD~1 -- src/.../openapi_toolset.pyand reran):With the fix restored:
pre-commit(ruff, isort, pyink, addlicense, codespell, etc.) was runagainst the changed files; the only failing hook
(
check-new-py-prefix, demanding a unit guide forsrc/google/adk/memory/_sqlite_memory_service.py) is pre-existing andunrelated to this change — that file was added in an earlier commit
(
9625b06c) not touched here.AI assistance disclosure
This change was authored with the assistance of Claude Code (Anthropic).
🤖 Generated with Claude Code