Compare commits

...

3 Commits

Author SHA1 Message Date
gemini-cli-robot 13b443af4f chore(release): v0.13.0-preview.1 2025-11-05 17:26:20 +00:00
gemini-cli-robot fd885a3e50 fix(patch): cherry-pick f51d745 to release/v0.13.0-preview.0-pr-12586 to patch version v0.13.0-preview.0 and create version 0.13.0-preview.1 (#12595)
Co-authored-by: Gaurav <39389231+gsquared94@users.noreply.github.com>
2025-11-05 17:04:36 +00:00
gemini-cli-robot 25d7a8037f chore(release): v0.13.0-preview.0 2025-11-04 23:49:33 +00:00
9 changed files with 81 additions and 20 deletions
+7 -7
View File
@@ -1,12 +1,12 @@
{
"name": "@google/gemini-cli",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@google/gemini-cli",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"workspaces": [
"packages/*"
],
@@ -16959,7 +16959,7 @@
},
"packages/a2a-server": {
"name": "@google/gemini-cli-a2a-server",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"dependencies": {
"@a2a-js/sdk": "^0.3.2",
"@google-cloud/storage": "^7.16.0",
@@ -17249,7 +17249,7 @@
},
"packages/cli": {
"name": "@google/gemini-cli",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"dependencies": {
"@google/gemini-cli-core": "file:../core",
"@google/genai": "1.16.0",
@@ -17349,7 +17349,7 @@
},
"packages/core": {
"name": "@google/gemini-cli-core",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"dependencies": {
"@google-cloud/logging": "^11.2.1",
"@google-cloud/opentelemetry-cloud-monitoring-exporter": "^0.21.0",
@@ -17493,7 +17493,7 @@
},
"packages/test-utils": {
"name": "@google/gemini-cli-test-utils",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"license": "Apache-2.0",
"devDependencies": {
"typescript": "^5.3.3"
@@ -17504,7 +17504,7 @@
},
"packages/vscode-ide-companion": {
"name": "gemini-cli-vscode-ide-companion",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"license": "LICENSE",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.15.1",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"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.13.0-nightly.20251031.c89bc30d"
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.13.0-preview.1"
},
"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.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"description": "Gemini CLI A2A Server",
"repository": {
"type": "git",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"description": "Gemini CLI",
"repository": {
"type": "git",
@@ -25,7 +25,7 @@
"dist"
],
"config": {
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.13.0-nightly.20251031.c89bc30d"
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.13.0-preview.1"
},
"dependencies": {
"@google/gemini-cli-core": "file:../core",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-core",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"description": "Gemini CLI Core",
"repository": {
"type": "git",
@@ -25,6 +25,44 @@ describe('classifyGoogleError', () => {
expect(result).toBe(regularError);
});
it('should return RetryableQuotaError when message contains "Please retry in Xs"', () => {
const complexError = {
error: {
message:
'{"error": {"code": 429, "status": 429, "message": "You exceeded your current quota, please check your plan and billing details. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits. To monitor your current usage, head to: https://ai.dev/usage?tab=rate-limit. \n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_requests, limit: 2\nPlease retry in 44.097740004s.", "details": [{"detail": "??? to (unknown) : APP_ERROR(8) You exceeded your current quota, please check your plan and billing details. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits. To monitor your current usage, head to: https://ai.dev/usage?tab=rate-limit. \n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_requests, limit: 2\nPlease retry in 44.097740004s."}]}}',
code: 429,
status: 'Too Many Requests',
},
};
const rawError = new Error(JSON.stringify(complexError));
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(null);
const result = classifyGoogleError(rawError);
expect(result).toBeInstanceOf(RetryableQuotaError);
expect((result as RetryableQuotaError).retryDelayMs).toBe(44097.740004);
expect((result as RetryableQuotaError).message).toBe(rawError.message);
});
it('should return RetryableQuotaError when error is a string and message contains "Please retry in Xms"', () => {
const complexErrorString = JSON.stringify({
error: {
message:
'{"error": {"code": 429, "status": 429, "message": "You exceeded your current quota, please check your plan and billing details. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits. To monitor your current usage, head to: https://ai.dev/usage?tab=rate-limit. \n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_requests, limit: 2\nPlease retry in 900.2ms.", "details": [{"detail": "??? to (unknown) : APP_ERROR(8) You exceeded your current quota, please check your plan and billing details. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits. To monitor your current usage, head to: https://ai.dev/usage?tab=rate-limit. \n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_requests, limit: 2\nPlease retry in 900.2ms."}]}}',
code: 429,
status: 'Too Many Requests',
},
});
const rawError = new Error(complexErrorString);
vi.spyOn(errorParser, 'parseGoogleApiError').mockReturnValue(null);
const result = classifyGoogleError(rawError);
expect(result).toBeInstanceOf(RetryableQuotaError);
expect((result as RetryableQuotaError).retryDelayMs).toBeCloseTo(900.2);
expect((result as RetryableQuotaError).message).toBe(rawError.message);
});
it('should return original error if code is not 429', () => {
const apiError: GoogleApiError = {
code: 500,
+28 -5
View File
@@ -43,16 +43,20 @@ export class RetryableQuotaError extends Error {
}
/**
* Parses a duration string (e.g., "34.074824224s", "60s") and returns the time in seconds.
* Parses a duration string (e.g., "34.074824224s", "60s", "900ms") and returns the time in seconds.
* @param duration The duration string to parse.
* @returns The duration in seconds, or null if parsing fails.
*/
function parseDurationInSeconds(duration: string): number | null {
if (!duration.endsWith('s')) {
return null;
if (duration.endsWith('ms')) {
const milliseconds = parseFloat(duration.slice(0, -2));
return isNaN(milliseconds) ? null : milliseconds / 1000;
}
const seconds = parseFloat(duration.slice(0, -1));
return isNaN(seconds) ? null : seconds;
if (duration.endsWith('s')) {
const seconds = parseFloat(duration.slice(0, -1));
return isNaN(seconds) ? null : seconds;
}
return null;
}
/**
@@ -64,6 +68,7 @@ function parseDurationInSeconds(duration: string): number | null {
* - If the error suggests a retry delay of more than 2 minutes, it's a `TerminalQuotaError`.
* - If the error suggests a retry delay of 2 minutes or less, it's a `RetryableQuotaError`.
* - If the error indicates a per-minute limit, it's a `RetryableQuotaError`.
* - If the error message contains the phrase "Please retry in X[s|ms]", it's a `RetryableQuotaError`.
*
* @param error The error to classify.
* @returns A `TerminalQuotaError`, `RetryableQuotaError`, or the original `unknown` error.
@@ -72,6 +77,24 @@ export function classifyGoogleError(error: unknown): unknown {
const googleApiError = parseGoogleApiError(error);
if (!googleApiError || googleApiError.code !== 429) {
// Fallback: try to parse the error message for a retry delay
const errorMessage = error instanceof Error ? error.message : String(error);
const match = errorMessage.match(/Please retry in ([0-9.]+(?:ms|s))/);
if (match?.[1]) {
const retryDelaySeconds = parseDurationInSeconds(match[1]);
if (retryDelaySeconds !== null) {
return new RetryableQuotaError(
errorMessage,
googleApiError ?? {
code: 429,
message: errorMessage,
details: [],
},
retryDelaySeconds,
);
}
}
return error; // Not a 429 error we can handle.
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-test-utils",
"version": "0.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"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.13.0-nightly.20251031.c89bc30d",
"version": "0.13.0-preview.1",
"publisher": "google",
"icon": "assets/icon.png",
"repository": {