diff --git a/dist/providers/google-gemini-cli.js b/dist/providers/google-gemini-cli.js index 93aa26c395e9bd0df64376408a13d15ee9e7cce7..41a439e5fc370038a5febef9e8f021ee279cf8aa 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..3fd8027edafdad4ca364af53f0a1811139705b21 100644 --- a/dist/providers/openai-codex-responses.js +++ b/dist/providers/openai-codex-responses.js @@ -433,9 +433,15 @@ function convertMessages(model, context) { } else if (msg.role === "assistant") { const output = []; + // OpenAI Responses rejects `reasoning` items that are not followed by a `message`. + // Tool-call-only turns (thinking + function_call) are valid assistant turns, but + // their stored reasoning items must not be replayed as standalone `reasoning` input. + const hasTextBlock = msg.content.some((b) => b.type === "text"); for (const block of msg.content) { if (block.type === "thinking" && msg.stopReason !== "error") { if (block.thinkingSignature) { + if (!hasTextBlock) + continue; const reasoningItem = JSON.parse(block.thinkingSignature); output.push(reasoningItem); } diff --git a/dist/providers/openai-responses.js b/dist/providers/openai-responses.js index 20fb0a22aaa28f7ff7c2f44a8b628fa1d9d7d936..0bf46bfb4a6fac5a0304652e42566b2c991bab48 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`. + // Tool-call-only turns (thinking + function_call) are valid assistant turns, but + // their stored reasoning items must not be replayed as standalone `reasoning` input. + const hasTextBlock = msg.content.some((b) => b.type === "text"); 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) + continue; const reasoningItem = JSON.parse(block.thinkingSignature); output.push(reasoningItem); }