Continue to work through 429/500s.

- The root of this issue was actually a genai SDK bug that was fixed here: https://critique.corp.google.com/cl/753255997
- Upgrade to latest genai SDK for latest bug fixes (including the above)
- Removed specific 429 handling for uncaught rejections.

Fixes https://b.corp.google.com/issues/413760164
This commit is contained in:
Taylor Mullen 2025-05-07 16:31:43 -07:00 committed by N. Taylor Mullen
parent 95ab38e8d6
commit 43c707b4e8
4 changed files with 24 additions and 56 deletions

8
package-lock.json generated
View File

@ -797,9 +797,9 @@
"link": true
},
"node_modules/@google/genai": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-0.10.0.tgz",
"integrity": "sha512-LAbp0em5A+wRtQR2+r5ckRBg2U2cBy8cJHgyTHa9PUbK8zucApw6A93HWyom/qlUQBNCpnIHFp20RiJuYMQwAw==",
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-0.13.0.tgz",
"integrity": "sha512-eaEncWt875H7046T04mOpxpHJUM+jLIljEf+5QctRyOeChylE/nhpwm1bZWTRWoOu/t46R9r+PmgsJFhTpE7tQ==",
"license": "Apache-2.0",
"dependencies": {
"google-auth-library": "^9.14.2",
@ -8167,7 +8167,7 @@
"name": "@gemini-code/server",
"version": "0.1.0",
"dependencies": {
"@google/genai": "^0.10.0",
"@google/genai": "^0.13.0",
"@modelcontextprotocol/sdk": "^1.11.0",
"diff": "^7.0.0",
"dotenv": "^16.4.7",

View File

@ -86,27 +86,6 @@ async function main() {
// --- Global Unhandled Rejection Handler ---
process.on('unhandledRejection', (reason, _promise) => {
// Check if this is the known 429 ClientError that sometimes escapes
// this is a workaround for a specific issue with the way we are calling gemini
// where a 429 error is thrown but not caught, causing an unhandled rejection
// TODO(adh): Remove this when the race condition is fixed
const isKnownEscaped429 =
reason instanceof Error &&
reason.name === 'ClientError' &&
reason.message.includes('got status: 429');
if (isKnownEscaped429) {
// Log it differently and DON'T exit, as it's likely already handled visually
console.warn('-----------------------------------------');
console.warn(
'WORKAROUND: Suppressed known escaped 429 Unhandled Rejection.',
);
console.warn('-----------------------------------------');
console.warn('Reason:', reason);
return;
// No process.exit(1); Don't exit.
}
// Log other unexpected unhandled rejections as critical errors
console.error('=========================================');
console.error('CRITICAL: Unhandled Promise Rejection!');

View File

@ -19,7 +19,7 @@
"dist"
],
"dependencies": {
"@google/genai": "^0.10.0",
"@google/genai": "^0.13.0",
"@modelcontextprotocol/sdk": "^1.11.0",
"diff": "^7.0.0",
"dotenv": "^16.4.7",

View File

@ -133,39 +133,28 @@ export class GeminiClient {
): AsyncGenerator<ServerGeminiStreamEvent> {
let turns = 0;
const availableTools = this.config.getToolRegistry().getAllTools();
try {
while (turns < this.MAX_TURNS) {
turns++;
const turn = new Turn(chat, availableTools);
const resultStream = turn.run(request, signal);
for await (const event of resultStream) {
yield event;
}
while (turns < this.MAX_TURNS) {
turns++;
const turn = new Turn(chat, availableTools);
const resultStream = turn.run(request, signal);
for await (const event of resultStream) {
yield event;
}
const confirmations = turn.getConfirmationDetails();
if (confirmations.length > 0) {
break;
}
const confirmations = turn.getConfirmationDetails();
if (confirmations.length > 0) {
break;
}
// What do we do when we have both function responses and confirmations?
const fnResponses = turn.getFunctionResponses();
if (fnResponses.length === 0) {
break; // user's turn to respond
}
request = fnResponses;
// What do we do when we have both function responses and confirmations?
const fnResponses = turn.getFunctionResponses();
if (fnResponses.length === 0) {
break; // user's turn to respond
}
if (turns >= this.MAX_TURNS) {
console.warn(
'sendMessageStream: Reached maximum tool call turns limit.',
);
}
} catch (error: unknown) {
if (error instanceof Error && error.name === 'AbortError') {
console.log('Gemini stream request aborted by user.');
throw error;
}
console.error(`Error during Gemini stream or tool interaction:`, error);
throw error;
request = fnResponses;
}
if (turns >= this.MAX_TURNS) {
console.warn('sendMessageStream: Reached maximum tool call turns limit.');
}
}