fix: resolve Gemini agent 400 error on tool call responses (#5054)
* add gtc__ prefix to tool call names in Gemini agent message formatting * resolve Gemini agent 400 error on tool call responses * add comments explaining geminis thought signatures --------- Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
This commit is contained in:
parent
ac0b1d401d
commit
b13dd820cc
@ -83,6 +83,10 @@ class GeminiProvider extends Provider {
|
||||
* Format the messages to the Gemini API Responses format.
|
||||
* - Gemini has some loosely documented format for tool calls and it can change at any time.
|
||||
* - We need to map the function call to the correct id and Gemini will throw an error if it does not.
|
||||
* - Gemini requires a `thought_signature` (via `extra_content.google.thought_signature`) on function call
|
||||
* parts in multi-turn tool conversations. This is an encrypted token Gemini attaches to every tool call
|
||||
* it makes, and it must be passed back when sending tool results or Gemini rejects the request with a 400.
|
||||
* See: https://ai.google.dev/gemini-api/docs/thought-signatures
|
||||
* @param {any[]} messages - The messages to format.
|
||||
* @returns {OpenAI.OpenAI.Responses.ResponseInput[]} The formatted messages.
|
||||
*/
|
||||
@ -101,17 +105,25 @@ class GeminiProvider extends Provider {
|
||||
return;
|
||||
}
|
||||
|
||||
const prefixedName = this.prefixToolCall(
|
||||
message.originalFunctionCall.name,
|
||||
"add"
|
||||
);
|
||||
formattedMessages.push(
|
||||
{
|
||||
role: "assistant",
|
||||
content: "",
|
||||
tool_calls: [
|
||||
{
|
||||
type: "function",
|
||||
...(message.originalFunctionCall.extra_content
|
||||
? { extra_content: message.originalFunctionCall.extra_content }
|
||||
: {}),
|
||||
function: {
|
||||
arguments: JSON.stringify(
|
||||
message.originalFunctionCall.arguments
|
||||
),
|
||||
name: message.originalFunctionCall.name,
|
||||
name: prefixedName,
|
||||
},
|
||||
id: message.originalFunctionCall.id,
|
||||
},
|
||||
@ -120,6 +132,7 @@ class GeminiProvider extends Provider {
|
||||
{
|
||||
role: "tool",
|
||||
tool_call_id: message.originalFunctionCall.id,
|
||||
name: prefixedName,
|
||||
content: message.content,
|
||||
}
|
||||
);
|
||||
@ -188,6 +201,8 @@ class GeminiProvider extends Provider {
|
||||
name: this.prefixToolCall(toolCall.function.name, "strip"),
|
||||
call_id: toolCall.id,
|
||||
arguments: toolCall.function.arguments,
|
||||
// Preserve Gemini's thought_signature so it can be passed back in #formatMessages
|
||||
extra_content: toolCall.extra_content ?? null,
|
||||
};
|
||||
eventHandler?.("reportStreamEvent", {
|
||||
type: "toolCallInvocation",
|
||||
@ -208,6 +223,7 @@ class GeminiProvider extends Provider {
|
||||
id: completion.functionCall.call_id,
|
||||
name: completion.functionCall.name,
|
||||
arguments: completion.functionCall.arguments,
|
||||
extra_content: completion.functionCall.extra_content,
|
||||
},
|
||||
cost: this.getCost(),
|
||||
};
|
||||
@ -265,6 +281,8 @@ class GeminiProvider extends Provider {
|
||||
name: this.prefixToolCall(toolCall.function.name, "strip"),
|
||||
arguments: functionArgs,
|
||||
id: toolCall.id,
|
||||
// Preserve Gemini's thought_signature so it can be passed back in #formatMessages
|
||||
extra_content: toolCall.extra_content ?? null,
|
||||
},
|
||||
cost,
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user