What extra content is
Some providers attach opaque state to a reply and expect it back, unchanged, on the next turn. Gemini 3 signs its function calls with a thought signature and rejects a history that replays the call without it. Anthropic requires the thinking blocks of an assistant turn, signatures included, in front of a tool-use turn that continues. Such state has no OpenAI-compatible field, so GoModel carries it in one place: anextra_content object keyed by vendor.
Where it appears
State sits on the unit that maps to one provider part. A tool call becomes one
Gemini
part, so a per-call signature lives on the tool call. Thinking blocks
belong to the whole assistant turn, so they live on the message.
Rules
- Every translation copies it through. Chat, Responses, and Anthropic
Messages ingress, streaming, and the assistant-turn echo carry
extra_contentwithout looking inside. - Only the owning provider sees its own vendor. Before a request leaves for a provider, GoModel drops every vendor object that provider does not own. A Gemini signature never reaches Anthropic or OpenAI, and a history that moved between providers does not fail on foreign fields.
- Only the owning adapter reads or writes inside it. Nothing else in the gateway interprets the contents.
- Echo it verbatim. Do not rewrite, reorder, or trim the member.
Thought signature preservation
Gemini 3 attaches an encryptedthoughtSignature to the function calls it
emits. The next request must carry the same signature on the same call, or
Gemini answers with HTTP 400 “Function call is missing a thought_signature”.
One tool-call turn through Chat Completions looks like this. Only the fields
that matter are shown.
1
The client asks a question with a tool available
2
Gemini replies with a function call and a signature
GoModel translates the request into Gemini’s native
generateContent
shape. Gemini returns a functionCall part that carries the signature.3
GoModel returns the call with the signature under extra_content
4
The client runs the tool and sends the full history back
The assistant message is appended as received, so
extra_content comes
along for free.5
GoModel replays the signature on the matching Gemini part
tool_calls deltas, on Responses API
function_call items, on Anthropic Messages tool_use blocks, and, for
text-only turns, on the assistant message itself. On the Responses API a
text-only turn’s signature rides on a reasoning output item ahead of the
message, with no reasoning text of its own; echo the item back and the
signature lands on the assistant turn. Only the first call of a parallel
batch carries a signature. A flat thought_signature or
thoughtSignature on the tool call is accepted too, so clients built against
other gateways keep working.
When a Gemini 3 history contains a function call without any signature,
because the conversation started on another provider or a client dropped the
member, GoModel sends Google’s documented placeholder instead of surfacing the
400. Echo the real value whenever you have it; the placeholder costs reasoning
continuity for that turn. See Gemini thought
signatures for provider details.
Thinking blocks
Anthropic’s extended thinking returnsthinking and redacted_thinking
content blocks on an assistant turn. When that turn ends in a tool call, the
follow-up request must replay those blocks, signatures included, ahead of the
tool_use block. Through the Anthropic Messages API
the flow is:
1
The client sends a history that contains thinking blocks
2
GoModel keeps the blocks under extra_content.anthropic
Internally the history is chat-shaped. The thinking blocks ride on the
assistant message and
is_error on the tool result. Neither has an
OpenAI-compatible field, so both live under the anthropic vendor.
is_error is only written when the result failed.3
Anthropic receives the blocks verbatim
When the route lands on Anthropic, the thinking blocks are put back in
front of the
tool_use block exactly as sent, and is_error is restored
on the tool_result. Any other provider receives the tool call and the
result text only.On the way back
Anthropic signs every thinking block it returns, and rejects a later turn that replays one without its signature:signature_delta inside the thinking
block, before it closes, exactly as Anthropic does.
The other dialects have no thinking block, so they carry the same data under
extra_content.anthropic.thinking_blocks — on the assistant message in Chat
Completions, on the reasoning output item in the Responses API. Streaming
chat deltas carry the value once the thinking block completes, before any
text, and it is cumulative: the last one seen holds the whole turn.
reasoning_content stays what it has always been: the readable text, and
nothing to replay. A redacted_thinking block has no readable text at all,
so extra_content is the only thing that carries it.
Append the assistant turn to the history as received and the replay is
automatic. Routing that history to another provider drops the member, as
every foreign vendor object is dropped, and the conversation continues
without it.
Moving a history between providers
A conversation may start on one provider and continue on another. The rule is simple: every vendor object that the target provider does not own is removed before dispatch, on every route, in every dialect.
The client’s own history is never modified. The filtering happens on the copy
GoModel sends upstream.