Repository navigation
Conversation
GoogleApiToOpenApiConverter copied type, enum, format, default and pattern from each discovery parameter but ignored `repeated: true`. Every repeated query parameter (Sheets values.batchGet `ranges`, Gmail messages.list `labelIds`, Calendar events.list `eventTypes`, YouTube videos.list `id`) was therefore declared to the model as a single scalar, so the model could ask for only one value. Wrap the schema of a repeated parameter in an array of that schema, and turn its default into a one-item list. RestApiTool already sends a list query value as repeated keys (`?ranges=a&ranges=b`), so only the declaration changes.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
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
1. Link to an existing issue (if applicable):
RestApiToolignores querystyle/explode). That is a separate bug. This change does not depend on it.2. Or, if no issue exists, describe the change:
Problem:
GoogleApiToOpenApiConverter._convert_parameter_schemacopiestype,enum,format,defaultandpatternfrom each discovery parameter, but it ignoresrepeated: true. Every repeated query parameter therefore comes out as a scalar, both in the generated OpenAPI spec and in the function declaration the model sees. Some examples from the built-in toolsets:SheetsToolset:spreadsheets.values.batchGetrangesGmailToolset:users.messages.listlabelIdsCalendarToolset:events.listeventTypesYoutubeToolset:videos.listidBecause the declaration says
string, the model can ask for only one value. For example, it cannot read two ranges in onebatchGetcall, and a list does not match the declared schema. The discovery documents bundled with google-api-python-client 2.198.0 contain 975 repeated parameters (alllocation: query), and none of them was declared as an array.Request building already handles lists.
RestApiToolpasses query values to httpx unchanged, and httpx encodes a list as repeated keys (?ranges=a&ranges=b), which is what Google APIs expect. Only the declared schema is wrong.Steps to reproduce (this needs Application Default Credentials, like any
GoogleApiToolset):{'type': 'array', 'items': {'type': 'string'}}{'type': 'string'}mainat c08225d (google-adk 2.12.0), macOS, Python 3.12.14.Solution:
When a discovery parameter has
repeated: true, the converter now wraps the schema it has built in{"type": "array", "items": <that schema>}. A scalardefaultmoves to the array as a one-item list, so the default still matches the schema. Only one bundled document has a repeated parameter with a default: Bloggerblogs.listByUserstatus, defaultLIVE. Parameters withoutrepeatedare unchanged. The fix is 8 lines in that one function.Testing Plan
Unit Tests:
New tests in
tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py:test_convert_parameter_schemacases: a repeated string, a repeated enum, and a repeated parameter with a default;test_convert_repeated_query_parameter_to_array: a repeatedeventTypesquery parameter on the Calendarevents.listfixture comes out ofconvert()as an array of the enum.On the base commit (fix not applied, Python 3.12), all 4 new cases fail because the schema
typeis'string'where'array'is expected. With the fix:Both commands were run in a separate venv for each Python version CI tests:
google_api_tool+openapi_toolpyink, isort, ruff, codespell and
scripts/compliance_checks.pyare clean on the changed files. mypy reports no issues on the converter, before or after the change, with--python-version3.11, 3.12 and 3.13.pytest tests/unittests -n 4was also run on Python 3.12, on base c08225d and on this branch. The local venv does not have every optional extra (agentplatform,a2a,bs4,sqlalchemy,mcp, ...), so base reports 208 failures and 176 errors. They come from that environment: packages that are missing, or installed at versions the release-bounds test does not expect. This branch has the same failures plus one:tests/unittests/workflow/test_workflow_parallel_worker.py::test_parallel_worker_preserves_input_order_regardless_of_completion_order. That test depends onasyncio.sleeptiming and does not load the converter. Re-run on its own on the same busy machine, it also failed on base (1 of 6 runs) and on this branch (2 of 5 runs). No failure is ingoogle_api_tooloropenapi_tool. This branch passes 12155 tests and base passes 12152: the 4 new cases, minus that timing test.The full
toxmatrix (py311 to py314) that CONTRIBUTING.md asks for before a PR was not run. On 3.11, 3.13 and 3.14, only the tests in the table above were run. The full suite and the E2E runs below ran on Python 3.12 only.Manual End-to-End (E2E) Tests:
Setup: one
LlmAgentwithSheetsToolset(tool_filter=["sheets_spreadsheets_values_batch_get"])runs throughInMemoryRunner. The toolset uses the discovery document bundled with google-api-python-client, so it needs no network. Three boundaries are stubbed:BaseLlmthat records therangesdeclaration it receives, then calls the tool withranges=["Sheet1!A1:B2", "Sheet2!C1:D2"];httpx.MockTransportthat records the outgoing URL;Each mode was run before and after the fix: the default JSON-schema declarations, and
--legacy-schema, which turnsJSON_SCHEMA_FOR_FUNC_DECLoff to exercise thetypes.Schemapath. In the output below, warning lines are trimmed, and the legacy runs omit thefunction_call/function_responselines, which are identical.The request URL is the same before and after, because the scripted model sends a list either way. What changes is the declaration: before the fix, the model is told
rangesis a single string.A second script converted all 585 bundled discovery documents, then built every tool declaration of the seven built-in toolsets in both declaration modes. Nothing raised. Results:
arrayarraye2e_runner.py
Checklist
adk-reviewchecklist.)Additional context
This change was prepared with an AI coding agent (Claude Code), which found the bug, wrote the fix and tests, and ran the commands above. I am responsible for the change and will answer review comments.
Repeated parameters that are not strings take the same path. For example, Fitness
users.sessions.listactivityType(an integer) becomes an array of integers.🤖 Generated with Claude Code