Skip to content

fix(gemini): coalesce parallel tool responses into a single Content#2959

Merged
dgageot merged 1 commit into
docker:mainfrom
t-mizumoto1203:fix/gemini-parallel-tool-responses
Jun 3, 2026
Merged

fix(gemini): coalesce parallel tool responses into a single Content#2959
dgageot merged 1 commit into
docker:mainfrom
t-mizumoto1203:fix/gemini-parallel-tool-responses

Conversation

@t-mizumoto1203

Copy link
Copy Markdown
Contributor

Fixes #2958.

Problem

When a Gemini model (via Vertex AI) returns parallel function calls (multiple functionCall parts in one assistant turn), convertMessagesToGemini returned each tool result as its own genai.Content (one functionResponse part per Content). Vertex AI requires the response turn to carry the same number of functionResponse parts as the preceding turn's functionCall parts, so the request fails with:

Error 400 ... Please ensure that the number of function response parts is equal to the number of function call parts of the function call turn. INVALID_ARGUMENT

This is deterministic for a given turn, so retries reproduce it and the run eventually aborts. There is no opt-out: Vertex Gemini exposes no parameter to disable parallel function calling (go-genai FunctionCallingConfig only has Mode).

Change

convertMessagesToGemini now coalesces consecutive tool-response messages into a single Content (role user) with N functionResponse parts, flushing on the next non-tool message and at the end of the loop — instead of emitting one Content per response. Single (non-parallel) tool calls are unaffected (one response → one Content).

Added regression test TestConvertMessagesToGemini_ParallelToolResponsesCoalesced (fails on main, passes with this change).

Reference

Per the Vertex AI function-calling docs, parallel results are returned together as one Content(role="user", parts=function_response_parts) with the part count matching the calls:

Verification

  • go build ./... — ok
  • go vet ./pkg/model/provider/gemini/... — ok
  • go test ./pkg/model/provider/... — ok
  • golangci-lint run (repo .golangci.yml, v2.12.2) — 0 issues

@t-mizumoto1203 t-mizumoto1203 requested a review from a team as a code owner June 2, 2026 06:26
@t-mizumoto1203 t-mizumoto1203 force-pushed the fix/gemini-parallel-tool-responses branch from 8f76d0d to 614275c Compare June 2, 2026 09:55
@t-mizumoto1203

Copy link
Copy Markdown
Contributor Author

Rebased onto the latest main. The earlier red build-and-test was an unrelated pre-existing failure in pkg/config (TestParseExamples on examples/github-copilot.yaml: model "gpt-4o" not found in provider "github-copilot"), not caused by this change, which only touches pkg/model/provider/gemini/. That failure is fixed on main by #2961 (commit 36af646, gpt-4o → gpt-4.1), which this branch now includes — so the build-and-test check should pass on the re-run.

@dgageot

dgageot commented Jun 2, 2026

Copy link
Copy Markdown
Member

Sorry @t-mizumoto1203 we require all the contributors to sign and verify their commits. Could you sign your commit?

@aheritier aheritier added area/providers For features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.) area/providers/gemini Google Gemini provider support kind/fix PR fixes a bug (maps to fix: commit prefix) labels Jun 2, 2026
When a Gemini model returns parallel function calls, the tool responses must be returned together as multiple functionResponse parts within a single Content (role=user), matching the number of functionCall parts. convertMessagesToGemini emitted one Content per tool response, which Vertex AI rejects with "the number of function response parts is equal to the number of function call parts" (INVALID_ARGUMENT). Coalesce consecutive tool responses into one Content and add a regression test.

Fixes docker#2958

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: t.mizumoto <56530282+t-mizumoto1203@users.noreply.github.com>
@t-mizumoto1203 t-mizumoto1203 force-pushed the fix/gemini-parallel-tool-responses branch from 614275c to d516fdf Compare June 3, 2026 02:33
@t-mizumoto1203

Copy link
Copy Markdown
Contributor Author

@dgageot Apologies for the late update. I've signed and pushed the commit now

@dgageot dgageot merged commit b215ca2 into docker:main Jun 3, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/providers/gemini Google Gemini provider support area/providers For features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.) kind/fix PR fixes a bug (maps to fix: commit prefix)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vertex Gemini: parallel function-call responses are split across separate Contents, causing deterministic "function response parts" INVALID_ARGUMENT

3 participants