Split out of #6018, where the founder named this gap: "Tracking that separately rather than widening the guard here, since some gateways do handle signatures themselves."
The gap. Thought signatures are captured and replayed only on the exact official Google route (generativelanguage.googleapis.com/v1beta/openai). A Gemini model reached through a hand-configured generic OpenAI-compatible row has the field stripped, so signatures are guaranteed absent there — and that is exactly the case validate_google_thought_signature_replay (crates/tui/src/client/chat.rs:665) skips with an early return Ok(()) for non-official routes. The turn then dies on Google's raw Function call is missing a thought_signature in functionCall parts 400 instead of CodeWhale's actionable error (which on the official route names the model, the tool call, and the recovery: start a new session).
Why not just widen the guard. Some gateways handle signatures themselves, so fail-closed on every non-official route would break working setups. The fix needs to distinguish "this route requires signatures and none exist" from "this gateway manages signatures itself" — e.g. only warn/fail for Gemini model ids on routes that look like Google's endpoint, or surface the hint when Google's 400 arrives rather than pre-flight.
Repro shape. Configure a Gemini thinking model via the generic OpenAI-compatible provider, make a tool call, continue the turn: Google 400s on the missing thought_signature with no CodeWhale-authored guidance. No reasoning setting avoids it — the signature is not a reasoning feature.
Workaround (from #6018). Use the built-in google provider for Gemini, not a hand-configured OpenAI-compatible row.
Split out of #6018, where the founder named this gap: "Tracking that separately rather than widening the guard here, since some gateways do handle signatures themselves."
The gap. Thought signatures are captured and replayed only on the exact official Google route (
generativelanguage.googleapis.com/v1beta/openai). A Gemini model reached through a hand-configured generic OpenAI-compatible row has the field stripped, so signatures are guaranteed absent there — and that is exactly the casevalidate_google_thought_signature_replay(crates/tui/src/client/chat.rs:665) skips with an earlyreturn Ok(())for non-official routes. The turn then dies on Google's rawFunction call is missing a thought_signature in functionCall parts400 instead of CodeWhale's actionable error (which on the official route names the model, the tool call, and the recovery: start a new session).Why not just widen the guard. Some gateways handle signatures themselves, so fail-closed on every non-official route would break working setups. The fix needs to distinguish "this route requires signatures and none exist" from "this gateway manages signatures itself" — e.g. only warn/fail for Gemini model ids on routes that look like Google's endpoint, or surface the hint when Google's 400 arrives rather than pre-flight.
Repro shape. Configure a Gemini thinking model via the generic OpenAI-compatible provider, make a tool call, continue the turn: Google 400s on the missing
thought_signaturewith no CodeWhale-authored guidance. No reasoning setting avoids it — the signature is not a reasoning feature.Workaround (from #6018). Use the built-in
googleprovider for Gemini, not a hand-configured OpenAI-compatible row.