Skip to content

Commit 6caf204

Browse files
authored
Merge pull request #1519 from mnfst/fix/gemini-parallel-tools-and-anthropic-thinking
fix(routing): Gemini parallel tools + Anthropic extended-thinking round-trip
2 parents 2228bcf + 1932864 commit 6caf204

20 files changed

+2037
-212
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
"manifest": patch
3+
---
4+
5+
Fix three provider-adapter round-trip bugs discovered while shipping the Gemini 3 thoughtSignature fix.
6+
7+
**Gemini parallel tool calling.** `fromGoogleResponse` and the streaming adapter now preserve Google's own `functionCall.id` (e.g. `"4z1aadbn"`) instead of generating a synthetic `call_<uuid>`. Without this, parallel tool calls could not be correlated back to their originating calls on the follow-up turn, because Google pairs responses by id, not position.
8+
9+
**Gemini `functionResponse` name mapping.** `toGoogleRequest` now scans the assistant tool_calls history and resolves `functionResponse.name` from the originating function name (instead of stuffing the tool_call_id into the `name` field). It also emits `functionResponse.id` mirroring the tool_call_id so parallel-call pairing is unambiguous end-to-end. Gemini 2.x tolerated the old behavior; Gemini 3 tightens the contract.
10+
11+
**Anthropic extended-thinking round-trip.** New `ThinkingBlockCache` (mirrors `ThoughtSignatureCache`). `fromAnthropicResponse` extracts `thinking` and `redacted_thinking` blocks alongside tool_use blocks; the stateful stream transformer assembles them during streaming and flushes at `message_delta` (so late-arriving signature deltas can't corrupt the snapshot); `toAnthropicRequest` re-injects cached blocks before `tool_use` on the next turn. Without this, Claude 4.x with extended thinking + tools was returning HTTP 400 on any follow-up turn — "assistant messages that include tool_use content blocks must also include unmodified thinking or redacted_thinking blocks that preceded the tool use".
12+
13+
Verified end-to-end against the live Gemini 3 Pro Preview API with a parallel tool-call scenario (weather in Paris + Tokyo, tool responses sent in reversed order): HTTP 200 with both tool results correctly attributed.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
"manifest": patch
3+
---
4+
5+
Fix Gemini 3 tool calling by round-tripping `thoughtSignature` correctly.
6+
7+
The Google adapter was reading and writing `thought_signature` (snake_case, inside the `functionCall` object), but Google's actual wire format is `thoughtSignature` (camelCase, at the Part level, as a sibling of `functionCall`). Signatures were therefore never extracted from Gemini responses and never re-injected into follow-up requests. Gemini 3 made these signatures mandatory for tool-use follow-ups, surfacing the bug as `HTTP 400: Function call is missing a thought_signature in functionCall parts`. Gemini 2.5 Pro and 2.5 Flash were silently affected too, losing reasoning context across tool-call turns.
8+
9+
- Parse `thoughtSignature` from the Part level in both streaming and non-streaming Google responses
10+
- Re-inject cached signatures as a Part-level `thoughtSignature` field when building follow-up requests
11+
- Drop `thought: true` reasoning-summary text parts from assistant content (previously leaked into replies)
12+
- Replace the regex-on-transformed-output signature extraction in the stream handler with a structured return value from the adapter

0 commit comments

Comments
 (0)