Repository navigation
fix(provider): Bedrock, Gemini, Vertex send a parallel tool call's results in one message - #368
Merged
Merged
Conversation
…sults in one message Each tool result went out as its own user message (and a steering message, stop marker or summary after them as another), while Converse requires alternating roles and Gemini a turn's function responses in one content. `provider::merge_same_role` merges consecutive same-role wire messages in the three request builders, keeping every block in order; on Gemini and Vertex `function_responses_first` puts a turn's function responses before its images and text. Tests: per-provider request bodies from a shared parallel-tool conversation (images included on Gemini/Vertex), the helper's cases (assistant pairs, empty and keyless messages), and a Bedrock run through the real loop against wiremock. Not run against a live endpoint. Closes #223. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG
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.
Closes #223.
Bug. The Bedrock, Gemini and Vertex request builders sent each
Message::ToolResultas its own user-role message, and a steering message / stop marker / compaction summary after them as another. Converse requires alternating roles; Gemini requires a turn's function responses in one content, as many as its function calls (the well-known "number of function response parts" 400). So the request after any turn with ≥2 tool calls — the default parallel strategy — could be rejected.Fix.
provider::merge_same_role(messages, key)merges consecutive same-role wire messages, appending theircontent(Bedrock) /parts(Gemini, Vertex) arrays in order: results in call order, then whatever followed. A message without the array is left as it is (get_mut, nonullinserted).google::function_responses_firstputs each user content'sfunctionResponseparts before its images and text, so a merged turn never interleaves a result's image between responses (images among responses are a reported cause of the same 400; Vertex matches responses by name and position).Tests.
parallel_tool_conversation()(request, 2 tool calls, 2 results, a steering message): rolesuser, assistant|model, user, results in call order, steering text last; on Gemini and Vertex also with an image result (responses first, then the image, then the text).merge_same_roleunit test: adjacency, order, assistant pairs, an empty message first/last in a run, a keyless message.toolResults in one user message.Not run against a live Bedrock or Gemini endpoint (no credentials), as the issue noted. Reviewed by code-reviewer (checked against Converse docs and Gemini's reported behaviour; no critical/important findings) and pr-test-analyzer; their suggestions are applied.
Checks:
--all-featurestest / clippy / doc / fmt clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG