Skip to content

Conversation

@Kenny-Heitritter
Copy link
Member

Summary

Implements proper handling of Gemini 3 thought signatures in multi-turn function calling conversations.

Problem

Gemini 3 models require "thought signatures" to be passed back when sending tool results in multi-turn conversations with function calling. Without these signatures, Gemini returns an error:

function call `pod_mcp_list_devices` in the 2. content block is missing a `thought_signature`

Solution

This PR works in conjunction with changes in qbraid-account (PR anomalyco#147) to pass thought signatures through the OpenAI-compatible API.

Changes in this PR:

  1. New qBraid provider SDK (packages/opencode/src/provider/sdk/qbraid/):

    • Custom metadata extractor captures _thought_signature from tool calls
    • Stores signatures globally keyed by toolCallId
    • Exports getThoughtSignature() for retrieval
  2. processor.ts updates:

    • Looks up thought signatures after receiving tool-call events
    • Attaches them to part metadata under both vertex and google keys
  3. provider.ts:

    • Registers qBraid provider in BUNDLED_PROVIDERS
  4. models.json:

    • Updates qBraid to use @ai-sdk/qbraid npm identifier

Flow:

  1. qBraid proxy receives Gemini response with tool calls + thought signatures
  2. Proxy includes _thought_signature on each tool call in OpenAI-compatible response
  3. CodeQ's qBraid provider extracts signatures via metadata extractor
  4. processor.ts attaches signatures to tool part metadata
  5. When building next request, metadata flows through as providerOptions
  6. AI SDK includes signatures when sending tool results back to proxy
  7. Proxy passes signatures to Gemini via AI SDK's native handling

Testing

Requires qbraid-account PR anomalyco#147 to be deployed. Then test with:

codeq run --model qbraid/gemini-3-flash "can you submit a bell circuit to sv1"

Implements proper handling of Gemini 3 thought signatures in multi-turn
function calling conversations. Gemini 3 requires thought signatures to be
passed back when sending tool results.

Changes:
- Add new qBraid provider SDK at src/provider/sdk/qbraid/ that:
  - Uses a custom metadata extractor to capture _thought_signature from
    tool calls in both streaming and non-streaming responses
  - Stores thought signatures globally keyed by toolCallId
  - Exports getThoughtSignature() for retrieval

- Update processor.ts to:
  - Import getThoughtSignature from qBraid provider
  - Look up thought signatures after receiving tool-call events
  - Attach them to part metadata under both 'vertex' and 'google' keys
    for AI SDK compatibility

- Register qBraid provider in provider.ts BUNDLED_PROVIDERS

- Update branding/qbraid/models.json to use @ai-sdk/qbraid npm identifier
  so CodeQ uses our custom provider instead of generic openai-compatible

This works in conjunction with the qbraid-account proxy changes that:
1. Extract thought signatures from Gemini responses
2. Include them as _thought_signature in OpenAI-compatible tool call responses
3. Read _thought_signature from incoming requests and pass to AI SDK
@github-actions
Copy link

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@Kenny-Heitritter Kenny-Heitritter merged commit 3d05a3b into dev Jan 21, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants