diff --git a/packages/ai/src/providers/google-shared.ts b/packages/ai/src/providers/google-shared.ts index 9c2381a7..93fe596c 100644 --- a/packages/ai/src/providers/google-shared.ts +++ b/packages/ai/src/providers/google-shared.ts @@ -58,6 +58,13 @@ function resolveThoughtSignature(isSameProviderAndModel: boolean, signature: str return isSameProviderAndModel && isValidThoughtSignature(signature) ? signature : undefined; } +/** + * Claude models via Google APIs require explicit tool call IDs in function calls/responses. + */ +export function requiresToolCallId(modelId: string): boolean { + return modelId.startsWith("claude-"); +} + /** * Convert internal messages to Gemini Content[] format. */ @@ -128,6 +135,7 @@ export function convertMessages(model: Model, contex functionCall: { name: block.name, args: block.arguments, + ...(requiresToolCallId(model.id) ? { id: block.id } : {}), }, }; const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thoughtSignature); @@ -169,12 +177,14 @@ export function convertMessages(model: Model, contex }, })); + const includeId = requiresToolCallId(model.id); const functionResponsePart: Part = { functionResponse: { name: msg.toolName, response: msg.isError ? { error: responseValue } : { output: responseValue }, // Nest images inside functionResponse.parts for Gemini 3 ...(hasImages && supportsMultimodalFunctionResponse && { parts: imageParts }), + ...(includeId ? { id: msg.toolCallId } : {}), }, };