Fix thought_signature: it's a sibling of functionCall, not nested inside it
The Gemini REST API returns thoughtSignature as a sibling part field:
{ "functionCall": {...}, "thoughtSignature": "..." }
not inside functionCall. We were reading part.functionCall.thought_signature
(always undefined) and writing fc.thought_signature inside the functionCall
object (also wrong). Now correctly reads part.thoughtSignature and writes
part.thoughtSignature when building history.
Made-with: Cursor
This commit is contained in:
@@ -55,20 +55,22 @@ function toGeminiContents(messages: ChatMessage[]) {
|
||||
if (msg.content) parts.push({ text: msg.content });
|
||||
if (msg.toolCalls?.length) {
|
||||
for (const tc of msg.toolCalls) {
|
||||
const fc: any = { name: tc.name, args: tc.args, id: tc.id };
|
||||
if (tc.thoughtSignature) fc.thought_signature = tc.thoughtSignature;
|
||||
parts.push({ functionCall: fc });
|
||||
// thoughtSignature is a SIBLING of functionCall in the part object,
|
||||
// not nested inside it. See: ai.google.dev/gemini-api/docs/thought-signatures
|
||||
const part: any = { functionCall: { name: tc.name, args: tc.args, id: tc.id } };
|
||||
if (tc.thoughtSignature) part.thoughtSignature = tc.thoughtSignature;
|
||||
parts.push(part);
|
||||
}
|
||||
}
|
||||
if (parts.length) contents.push({ role: 'model', parts });
|
||||
} else if (msg.role === 'tool') {
|
||||
const fr: any = {
|
||||
name: msg.toolName || 'unknown',
|
||||
id: msg.toolCallId,
|
||||
response: { content: msg.content },
|
||||
const part = {
|
||||
functionResponse: {
|
||||
name: msg.toolName || 'unknown',
|
||||
id: msg.toolCallId,
|
||||
response: { content: msg.content },
|
||||
},
|
||||
};
|
||||
if (msg.thoughtSignature) fr.thought_signature = msg.thoughtSignature;
|
||||
const part = { functionResponse: fr };
|
||||
const last = contents[contents.length - 1];
|
||||
if (last?.role === 'user') {
|
||||
last.parts.push(part);
|
||||
@@ -147,7 +149,8 @@ export async function callGeminiChat(opts: {
|
||||
id: part.functionCall.id || `tc-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
||||
name: part.functionCall.name,
|
||||
args: part.functionCall.args ?? {},
|
||||
thoughtSignature: part.functionCall.thought_signature,
|
||||
// thoughtSignature is a SIBLING of functionCall in the part, not inside it
|
||||
thoughtSignature: part.thoughtSignature,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user