google.internal._gm_sig_marker
(internal) --------------------------------------------------------------------------- Thought signatures (Gemini 3.x).
Signature
(internal) --------------------------------------------------------------------------- Thought signatures (Gemini 3.x).
Gemini 3 returns a thoughtSignature on every functionCall part and
REJECTS the request (HTTP 400, "Function call is missing a thought_signature
in functionCall parts") when that call is replayed in contents without it.
Every multi-turn tool loop replays exactly that, so the signature has to
survive the round-trip through the journal — and the journal's
ai.content.ToolUse has only id, name and args, none of which is a
metadata slot.
The id is the one field this client OWNS: Gemini sends no call ids at all,
parse synthesizes them (call_<seq>_<i>), and they are opaque
correlation handles everywhere else (ai.wire documents id shape as "that
provider's business" and deliberately never rewrites them). So the signature
rides the id: call_0_0~gts~<signature>. It round-trips through
AssistantMessage -> ToolRequested -> ToolCompleted untouched, needs no shared
-file change, and is stripped back off at the one place that rebuilds the
wire part.
Signatures are base64, which cannot contain ~, so the marker is
unambiguous; an id without it (another provider's journal, a journal written
before this existed, a 2.x model) simply yields no signature.
Source:<builtin>/google/ns_internal/gemini.bamlbytes 19296–19347