diff --git a/dist/providers/google-gemini-cli.js b/dist/providers/google-gemini-cli.js index 93aa26c395e9bd0df64376408a13d15ee9e7cce7..beb585e2f2c13eec3bca98acade761101e4572ff 100644 --- a/dist/providers/google-gemini-cli.js +++ b/dist/providers/google-gemini-cli.js @@ -248,6 +248,11 @@ export const streamGoogleGeminiCli = (model, context, options) => { break; // Success, exit retry loop } const errorText = await response.text(); + // Fail immediately on 429 for Antigravity to let callers rotate accounts. + // Antigravity rate limits can have very long retry delays (10+ minutes). + if (isAntigravity && response.status === 429) { + throw new Error(`Cloud Code Assist API error (${response.status}): ${errorText}`); + } // Check if retryable if (attempt < MAX_RETRIES && isRetryableError(response.status, errorText)) { // Use server-provided delay or exponential backoff diff --git a/dist/providers/openai-codex-responses.js b/dist/providers/openai-codex-responses.js index 188a8294f26fe1bfe3fb298a7f58e4d8eaf2a529..ccfe2e835918530ddf9d2ce17b44b0069b41648e 100644 --- a/dist/providers/openai-codex-responses.js +++ b/dist/providers/openai-codex-responses.js @@ -515,7 +515,7 @@ function convertTools(tools) { name: tool.name, description: tool.description, parameters: tool.parameters, - strict: null, + strict: false, })); } function mapStopReason(status) { diff --git a/dist/providers/openai-responses.js b/dist/providers/openai-responses.js index f07085c64390b211340d6a826b28ea9c2e77302f..7f758532246cc7b062df48e9cec4e6c904b76a99 100644 --- a/dist/providers/openai-responses.js +++ b/dist/providers/openai-responses.js @@ -396,10 +396,16 @@ function convertMessages(model, context) { } else if (msg.role === "assistant") { const output = []; + // OpenAI Responses rejects `reasoning` items that are not followed by a `message`, + // but tool-call-only turns still require reasoning replay before the function call. + const hasTextBlock = msg.content.some((b) => b.type === "text"); + const hasToolCallBlock = msg.content.some((b) => b.type === "toolCall"); for (const block of msg.content) { // Do not submit thinking blocks if the completion had an error (i.e. abort) if (block.type === "thinking" && msg.stopReason !== "error") { if (block.thinkingSignature) { + if (!hasTextBlock && !hasToolCallBlock) + continue; const reasoningItem = JSON.parse(block.thinkingSignature); output.push(reasoningItem); } @@ -434,6 +440,16 @@ function convertMessages(model, context) { }); } } + const hasAssistantMessage = output.some((item) => item.type === "message"); + const hasFunctionCall = output.some((item) => item.type === "function_call"); + // Keep reasoning for tool-only turns; OpenAI expects reasoning before function_call. + if (!hasAssistantMessage && !hasFunctionCall) { + for (let i = output.length - 1; i >= 0; i -= 1) { + if (output[i].type === "reasoning") { + output.splice(i, 1); + } + } + } if (output.length === 0) continue; messages.push(...output); diff --git a/dist/providers/google-shared.js b/dist/providers/google-shared.js index 866446158b0ee3e4c4a4f3f78c71ce72b9aab6a1..c7f9d8a0b0c7a25b62a0bb5f8a4f9d63ccad1d24 100644 --- a/dist/providers/google-shared.js +++ b/dist/providers/google-shared.js @@ -52,6 +52,8 @@ export function convertMessages(model, context) { const contents = []; const transformedMessages = transformMessages(context.messages, model); + const shouldStripFunctionId = typeof model.provider === "string" && + model.provider.startsWith("google"); for (const msg of transformedMessages) { if (msg.role === "user") { @@ -110,8 +112,8 @@ export function convertMessages(model, context) { args: block.arguments, }, }; - if (model.provider === "google-vertex" && part?.functionCall?.id) { - delete part.functionCall.id; // Vertex AI does not support 'id' in functionCall + if (shouldStripFunctionId && part?.functionCall?.id) { + delete part.functionCall.id; // Google Gemini/Vertex do not support 'id' in functionCall } if (block.thoughtSignature) { part.thoughtSignature = block.thoughtSignature; @@ -159,8 +161,8 @@ export function convertMessages(model, context) { ...(hasImages && supportsMultimodalFunctionResponse && { parts: imageParts }), }, }; - if (model.provider === "google-vertex" && functionResponsePart.functionResponse?.id) { - delete functionResponsePart.functionResponse.id; // Vertex AI does not support 'id' in functionResponse + if (shouldStripFunctionId && functionResponsePart.functionResponse?.id) { + delete functionResponsePart.functionResponse.id; // Google Gemini/Vertex do not support 'id' in functionResponse } // Cloud Code Assist API requires all function responses to be in a single user turn. // Check if the last content is already a user turn with function responses and merge.