Fix: snake_case the OpenAPI tool name regardless of preservePropertyNames (adk-python parity) - #801
Open
AmaadMartin wants to merge 2 commits into
Conversation
added 2 commits
August 8, 2026 03:45
…Names getFunctionName() derived the tool name through getParamName(), so preservePropertyNames leaked out of parameter naming and returned the raw operationId. adk-python returns _to_snake_case(operation_id)[:60] there and never consults the flag, so the two SDKs exposed different tool names for the same document. Call snakeCase() directly, and document that the flag covers parameter and request-body property names only.
Cover the parser and the toolset. Each case asserts the snake_case tool name and the preserved property names together, which is the pairing the fix is about. One case pins that truncation runs after conversion. Ports test_openapi_toolset_preserve_property_names_body_params from adk-python.
7 tasks
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.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
n/a
Problem:
OperationParser.getFunctionName()derived the tool name through theprivate
getParamName()helper, which short-circuits whenpreservePropertyNamesis set. The flag therefore leaked out of parameternaming and into the tool name. adk-python returns
_to_snake_case(operation_id)[:60]there and never reads the flag, so the twoSDKs exposed different tool names for the same document.
Solution:
getFunctionName()now callssnakeCase()directly, so the toolname is always snake_case and then truncated to 60 characters.
getParamName()is untouched and still honours the flag for parameter and request-body property
names. Two doc comments record that split, because the missing contract is what
allowed the bug.
Behaviour change: a caller that passes
preservePropertyNames: truegets adifferent tool name.
createUsernow yieldscreate_user, notcreateUser. Aliteral
toolFilterallowlist or an agentinstructionthat names such a toolmust be respelled. The default (
false) path is byte-for-byte unchanged, theHTTP request is unchanged, and the affected classes are
@experimental.Stacked PR: this targets
fix/openapi-tool-name-snake-case-parity(#690),which adds the
snakeCase()helper this fix calls.snakeCasedoes not existon
main. Only my two commits are under review; seegit diff fix/openapi-tool-name-snake-case-parity.Collision check:
gh pr list --repo AmaadMartin/adk-js --state openplusgh pr diff --name-onlyon every adjacent OpenAPI PR (#690, #774, #748, #645,#605, #436). Only #690 touches
operation_parser.ts, and it deliberatelyleaves this bug alone — it fixes which snake_case algorithm runs, not
whether the flag suppresses it. No duplicate.
Testing Plan
Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
Four cases in
operation_parser_test.tsand one inopenapi_toolset_test.ts.Each asserts the snake_case tool name and the preserved property names
together, because that pairing is what the fix is about. No existing test was
edited.
Proof the tests can fail. I reverted the one-expression change (put
this.getParamName(operationId)back), rebuilt, and re-ran. All five newassertions failed; the 29 pre-existing tests passed unchanged, which is the
evidence the default path does not move.
The
preservePropertyNames: falserow of the first case passes either way byconstruction. It is the paired control, not a signal.
Coverage.
getFunctionName()is fully covered by these suites: 35 calls,the throw path 1 and the
snakeCasereturn path 34. The changed expression isthe only new production line.
Manual End-to-End (E2E) Tests:
I ran the same spec through both SDKs and compared the output.
adk-js,
new OpenAPIToolset({specDict, preservePropertyNames: true}), printing[tool.name, Object.keys(tool._getDeclaration().parameters.properties)]:adk-python,
OpenAPIToolset(spec_dict=spec, preserve_property_names=True),printing
[tool.name, [p.py_name for p in tool._operation_parser.get_parameters()]]:The tool names now match exactly. To reproduce: build an
OpenAPIToolsetfroma spec with
operationId: createUserand camelCase body propertiesfirstName/lastName/emailAddress, setpreservePropertyNames: true,and read the names back from
getTools().CI is absent, so I validated locally. The
validationworkflow triggers onpull_request: branches: [main], and this PR targets a stacked base, so itnever runs. On the pushed commit
eef0fb94:npm run build— passed.npm run lint— passed, no output.npm run format:check— "All matched files use Prettier code style!".npm run ts:check— 281 errors in 41 files, identical with and without mychange (measured by stashing it). The three errors in
openapi_toolset_test.tsare at lines 115, 425 and 470, all pre-existing andoutside the block I added. Several open PRs are dedicated to clearing this
backlog.
Checklist