Compare commits

...

2 Commits

Author SHA1 Message Date
gemini-cli-robot f9331b1602 chore(release): v0.22.0-preview.3 2025-12-19 01:45:33 +00:00
gemini-cli-robot ed4b440ba0 fix(patch): cherry-pick 9e6914d to release/v0.22.0-preview.2-pr-15288 to patch version v0.22.0-preview.2 and create version 0.22.0-preview.3 (#15294)
Co-authored-by: Sehoon Shon <sshon@google.com>
2025-12-19 00:07:18 +00:00
9 changed files with 107 additions and 17 deletions
+7 -7
View File
@@ -1,12 +1,12 @@
{
"name": "@google/gemini-cli",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@google/gemini-cli",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"workspaces": [
"packages/*"
],
@@ -17671,7 +17671,7 @@
},
"packages/a2a-server": {
"name": "@google/gemini-cli-a2a-server",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"dependencies": {
"@a2a-js/sdk": "^0.3.2",
"@google-cloud/storage": "^7.16.0",
@@ -17981,7 +17981,7 @@
},
"packages/cli": {
"name": "@google/gemini-cli",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"license": "Apache-2.0",
"dependencies": {
"@google/gemini-cli-core": "file:../core",
@@ -18083,7 +18083,7 @@
},
"packages/core": {
"name": "@google/gemini-cli-core",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"license": "Apache-2.0",
"dependencies": {
"@google-cloud/logging": "^11.2.1",
@@ -18228,7 +18228,7 @@
},
"packages/test-utils": {
"name": "@google/gemini-cli-test-utils",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"license": "Apache-2.0",
"devDependencies": {
"typescript": "^5.3.3"
@@ -18239,7 +18239,7 @@
},
"packages/vscode-ide-companion": {
"name": "gemini-cli-vscode-ide-companion",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"license": "LICENSE",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.23.0",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"engines": {
"node": ">=20.0.0"
},
@@ -14,7 +14,7 @@
"url": "git+https://github.com/google-gemini/gemini-cli.git"
},
"config": {
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.22.0-preview.2"
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.22.0-preview.3"
},
"scripts": {
"start": "cross-env NODE_ENV=development node scripts/start.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-a2a-server",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"description": "Gemini CLI A2A Server",
"repository": {
"type": "git",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"description": "Gemini CLI",
"license": "Apache-2.0",
"repository": {
@@ -26,7 +26,7 @@
"dist"
],
"config": {
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.22.0-preview.2"
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.22.0-preview.3"
},
"dependencies": {
"@google/gemini-cli-core": "file:../core",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-core",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"description": "Gemini CLI Core",
"license": "Apache-2.0",
"repository": {
@@ -325,7 +325,7 @@ describe('classifyGoogleError', () => {
expect(result).toBeInstanceOf(TerminalQuotaError);
});
it('should return original error for 429 without specific details', () => {
it('should return RetryableQuotaError for any 429', () => {
const apiError: GoogleApiError = {
code: 429,
message: 'Too many requests',
@@ -340,7 +340,10 @@ describe('classifyGoogleError', () => {
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(apiError);
const originalError = new Error();
const result = classifyGoogleError(originalError);
expect(result).toBe(originalError);
expect(result).toBeInstanceOf(RetryableQuotaError);
if (result instanceof RetryableQuotaError) {
expect(result.retryDelayMs).toBe(5000);
}
});
it('should classify nested JSON string 404 error as ModelNotFoundError', () => {
@@ -389,4 +392,61 @@ describe('classifyGoogleError', () => {
});
}
});
it('should return RetryableQuotaError with 5s fallback for generic 429 without specific message', () => {
const generic429 = {
status: 429,
message: 'Resource exhausted. No specific retry info.',
};
const result = classifyGoogleError(generic429);
expect(result).toBeInstanceOf(RetryableQuotaError);
if (result instanceof RetryableQuotaError) {
expect(result.retryDelayMs).toBe(5000);
}
});
it('should return RetryableQuotaError with 5s fallback for 429 with empty details and no regex match', () => {
const errorWithEmptyDetails = {
error: {
code: 429,
message: 'A generic 429 error with no retry message.',
details: [],
},
};
const result = classifyGoogleError(errorWithEmptyDetails);
expect(result).toBeInstanceOf(RetryableQuotaError);
if (result instanceof RetryableQuotaError) {
expect(result.retryDelayMs).toBe(5000);
}
});
it('should return RetryableQuotaError with 5s fallback for 429 with some detail', () => {
const errorWithEmptyDetails = {
error: {
code: 429,
message: 'A generic 429 error with no retry message.',
details: [
{
'@type': 'type.googleapis.com/google.rpc.ErrorInfo',
reason: 'QUOTA_EXCEEDED',
domain: 'googleapis.com',
metadata: {
quota_limit: '',
},
},
],
},
};
const result = classifyGoogleError(errorWithEmptyDetails);
expect(result).toBeInstanceOf(RetryableQuotaError);
if (result instanceof RetryableQuotaError) {
expect(result.retryDelayMs).toBe(5000);
}
});
});
@@ -13,6 +13,8 @@ import type {
import { parseGoogleApiError } from './googleErrors.js';
import { getErrorStatus, ModelNotFoundError } from './httpErrors.js';
const DEFAULT_RETRYABLE_DELAY_SECOND = 5;
/**
* A non-retryable error indicating a hard quota limit has been reached (e.g., daily limit).
*/
@@ -112,6 +114,18 @@ export function classifyGoogleError(error: unknown): unknown {
retryDelaySeconds,
);
}
} else if (status === 429) {
// Fallback: If it is a 429 but doesn't have a specific "retry in" message,
// assume it is a temporary rate limit and retry after 5 sec (same as DEFAULT_RETRY_OPTIONS).
return new RetryableQuotaError(
errorMessage,
googleApiError ?? {
code: 429,
message: errorMessage,
details: [],
},
DEFAULT_RETRYABLE_DELAY_SECOND,
);
}
return error; // Not a 429 error we can handle with structured details or a parsable retry message.
@@ -232,5 +246,21 @@ export function classifyGoogleError(error: unknown): unknown {
);
}
}
// If we reached this point and the status is still 429, we return retryable.
if (status === 429) {
const errorMessage =
googleApiError?.message ||
(error instanceof Error ? error.message : String(error));
return new RetryableQuotaError(
errorMessage,
googleApiError ?? {
code: 429,
message: errorMessage,
details: [],
},
DEFAULT_RETRYABLE_DELAY_SECOND,
);
}
return error; // Fallback to original error if no specific classification fits.
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-test-utils",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"private": true,
"main": "src/index.ts",
"license": "Apache-2.0",
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "gemini-cli-vscode-ide-companion",
"displayName": "Gemini CLI Companion",
"description": "Enable Gemini CLI with direct access to your IDE workspace.",
"version": "0.22.0-preview.2",
"version": "0.22.0-preview.3",
"publisher": "google",
"icon": "assets/icon.png",
"repository": {