@google/gemini-cli-core 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/google-gemini-cli-core-0.11.1.tgz +0 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +1 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/src/config/config.js +1 -3
  6. package/dist/src/config/config.js.map +1 -1
  7. package/dist/src/config/config.test.js +1 -1
  8. package/dist/src/config/config.test.js.map +1 -1
  9. package/dist/src/generated/git-commit.d.ts +2 -2
  10. package/dist/src/generated/git-commit.js +2 -2
  11. package/dist/src/index.d.ts +1 -0
  12. package/dist/src/index.js +1 -0
  13. package/dist/src/index.js.map +1 -1
  14. package/dist/src/utils/errorParsing.d.ts +1 -1
  15. package/dist/src/utils/errorParsing.js +5 -33
  16. package/dist/src/utils/errorParsing.js.map +1 -1
  17. package/dist/src/utils/errorParsing.test.js +0 -88
  18. package/dist/src/utils/errorParsing.test.js.map +1 -1
  19. package/dist/src/utils/flashFallback.test.js +26 -45
  20. package/dist/src/utils/flashFallback.test.js.map +1 -1
  21. package/dist/src/utils/googleErrors.d.ts +104 -0
  22. package/dist/src/utils/googleErrors.js +152 -0
  23. package/dist/src/utils/googleErrors.js.map +1 -0
  24. package/dist/src/utils/googleErrors.test.d.ts +6 -0
  25. package/dist/src/utils/googleErrors.test.js +301 -0
  26. package/dist/src/utils/googleErrors.test.js.map +1 -0
  27. package/dist/src/utils/googleQuotaErrors.d.ts +35 -0
  28. package/dist/src/utils/googleQuotaErrors.js +131 -0
  29. package/dist/src/utils/googleQuotaErrors.js.map +1 -0
  30. package/dist/src/utils/googleQuotaErrors.test.d.ts +6 -0
  31. package/dist/src/utils/googleQuotaErrors.test.js +281 -0
  32. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -0
  33. package/dist/src/utils/quotaErrorDetection.d.ts +0 -2
  34. package/dist/src/utils/quotaErrorDetection.js +0 -46
  35. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  36. package/dist/src/utils/retry.js +41 -145
  37. package/dist/src/utils/retry.js.map +1 -1
  38. package/dist/src/utils/retry.test.js +31 -110
  39. package/dist/src/utils/retry.test.js.map +1 -1
  40. package/dist/tsconfig.tsbuildinfo +1 -1
  41. package/package.json +1 -1
@@ -0,0 +1,301 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect } from 'vitest';
7
+ import { parseGoogleApiError } from './googleErrors.js';
8
+ describe('parseGoogleApiError', () => {
9
+ it('should return null for non-gaxios errors', () => {
10
+ expect(parseGoogleApiError(new Error('vanilla error'))).toBeNull();
11
+ expect(parseGoogleApiError(null)).toBeNull();
12
+ expect(parseGoogleApiError({})).toBeNull();
13
+ });
14
+ it('should parse a standard gaxios error', () => {
15
+ const mockError = {
16
+ response: {
17
+ status: 429,
18
+ data: {
19
+ error: {
20
+ code: 429,
21
+ message: 'Quota exceeded',
22
+ details: [
23
+ {
24
+ '@type': 'type.googleapis.com/google.rpc.QuotaFailure',
25
+ violations: [{ subject: 'user', description: 'daily limit' }],
26
+ },
27
+ ],
28
+ },
29
+ },
30
+ },
31
+ };
32
+ const parsed = parseGoogleApiError(mockError);
33
+ expect(parsed).not.toBeNull();
34
+ expect(parsed?.code).toBe(429);
35
+ expect(parsed?.message).toBe('Quota exceeded');
36
+ expect(parsed?.details).toHaveLength(1);
37
+ const detail = parsed?.details[0];
38
+ expect(detail['@type']).toBe('type.googleapis.com/google.rpc.QuotaFailure');
39
+ expect(detail.violations[0].description).toBe('daily limit');
40
+ });
41
+ it('should parse an error with details stringified in the message', () => {
42
+ const innerError = {
43
+ error: {
44
+ code: 429,
45
+ message: 'Inner quota message',
46
+ details: [
47
+ {
48
+ '@type': 'type.googleapis.com/google.rpc.RetryInfo',
49
+ retryDelay: '10s',
50
+ },
51
+ ],
52
+ },
53
+ };
54
+ const mockError = {
55
+ response: {
56
+ status: 429,
57
+ data: {
58
+ error: {
59
+ code: 429,
60
+ message: JSON.stringify(innerError),
61
+ details: [], // Top-level details are empty
62
+ },
63
+ },
64
+ },
65
+ };
66
+ const parsed = parseGoogleApiError(mockError);
67
+ expect(parsed).not.toBeNull();
68
+ expect(parsed?.code).toBe(429);
69
+ expect(parsed?.message).toBe('Inner quota message');
70
+ expect(parsed?.details).toHaveLength(1);
71
+ expect(parsed?.details[0]['@type']).toBe('type.googleapis.com/google.rpc.RetryInfo');
72
+ });
73
+ it('should return null if details are not in the expected format', () => {
74
+ const mockError = {
75
+ response: {
76
+ status: 400,
77
+ data: {
78
+ error: {
79
+ code: 400,
80
+ message: 'Bad Request',
81
+ details: 'just a string', // Invalid details format
82
+ },
83
+ },
84
+ },
85
+ };
86
+ expect(parseGoogleApiError(mockError)).toBeNull();
87
+ });
88
+ it('should return null if there are no valid details', () => {
89
+ const mockError = {
90
+ response: {
91
+ status: 400,
92
+ data: {
93
+ error: {
94
+ code: 400,
95
+ message: 'Bad Request',
96
+ details: [
97
+ {
98
+ // missing '@type'
99
+ reason: 'some reason',
100
+ },
101
+ ],
102
+ },
103
+ },
104
+ },
105
+ };
106
+ expect(parseGoogleApiError(mockError)).toBeNull();
107
+ });
108
+ it('should parse a doubly nested error in the message', () => {
109
+ const innerError = {
110
+ error: {
111
+ code: 429,
112
+ message: 'Innermost quota message',
113
+ details: [
114
+ {
115
+ '@type': 'type.googleapis.com/google.rpc.RetryInfo',
116
+ retryDelay: '20s',
117
+ },
118
+ ],
119
+ },
120
+ };
121
+ const middleError = {
122
+ error: {
123
+ code: 429,
124
+ message: JSON.stringify(innerError),
125
+ details: [],
126
+ },
127
+ };
128
+ const mockError = {
129
+ response: {
130
+ status: 429,
131
+ data: {
132
+ error: {
133
+ code: 429,
134
+ message: JSON.stringify(middleError),
135
+ details: [],
136
+ },
137
+ },
138
+ },
139
+ };
140
+ const parsed = parseGoogleApiError(mockError);
141
+ expect(parsed).not.toBeNull();
142
+ expect(parsed?.code).toBe(429);
143
+ expect(parsed?.message).toBe('Innermost quota message');
144
+ expect(parsed?.details).toHaveLength(1);
145
+ expect(parsed?.details[0]['@type']).toBe('type.googleapis.com/google.rpc.RetryInfo');
146
+ });
147
+ it('should parse an error that is not in a response object', () => {
148
+ const innerError = {
149
+ error: {
150
+ code: 429,
151
+ message: 'Innermost quota message',
152
+ details: [
153
+ {
154
+ '@type': 'type.googleapis.com/google.rpc.RetryInfo',
155
+ retryDelay: '20s',
156
+ },
157
+ ],
158
+ },
159
+ };
160
+ const mockError = {
161
+ error: {
162
+ code: 429,
163
+ message: JSON.stringify(innerError),
164
+ details: [],
165
+ },
166
+ };
167
+ const parsed = parseGoogleApiError(mockError);
168
+ expect(parsed).not.toBeNull();
169
+ expect(parsed?.code).toBe(429);
170
+ expect(parsed?.message).toBe('Innermost quota message');
171
+ expect(parsed?.details).toHaveLength(1);
172
+ expect(parsed?.details[0]['@type']).toBe('type.googleapis.com/google.rpc.RetryInfo');
173
+ });
174
+ it('should parse an error that is a JSON string', () => {
175
+ const innerError = {
176
+ error: {
177
+ code: 429,
178
+ message: 'Innermost quota message',
179
+ details: [
180
+ {
181
+ '@type': 'type.googleapis.com/google.rpc.RetryInfo',
182
+ retryDelay: '20s',
183
+ },
184
+ ],
185
+ },
186
+ };
187
+ const mockError = {
188
+ error: {
189
+ code: 429,
190
+ message: JSON.stringify(innerError),
191
+ details: [],
192
+ },
193
+ };
194
+ const parsed = parseGoogleApiError(JSON.stringify(mockError));
195
+ expect(parsed).not.toBeNull();
196
+ expect(parsed?.code).toBe(429);
197
+ expect(parsed?.message).toBe('Innermost quota message');
198
+ expect(parsed?.details).toHaveLength(1);
199
+ expect(parsed?.details[0]['@type']).toBe('type.googleapis.com/google.rpc.RetryInfo');
200
+ });
201
+ it('should parse the user-provided nested error string', () => {
202
+ const userErrorString = '{"error":{"message":"{\\n \\"error\\": {\\n \\"code\\": 429,\\n \\"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.\\\\n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_paid_tier_input_token_count, limit: 10000\\\\nPlease retry in 40.025771073s.\\",\\n \\"status\\": \\"RESOURCE_EXHAUSTED\\",\\n \\"details\\": [\\n {\\n \\"@type\\": \\"type.googleapis.com/google.rpc.DebugInfo\\",\\n \\"detail\\": \\"[ORIGINAL ERROR] generic::resource_exhausted: 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.\\\\n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_paid_tier_input_token_count, limit: 10000\\\\nPlease retry in 40.025771073s. [google.rpc.error_details_ext] { 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.\\\\\\\\n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_paid_tier_input_token_count, limit: 10000\\\\\\\\nPlease retry in 40.025771073s.\\\\\\" }\\"\\n },\\n {\\n \\"@type\\": \\"type.googleapis.com/google.rpc.QuotaFailure\\",\\n \\"violations\\": [\\n {\\n \\"quotaMetric\\": \\"generativelanguage.googleapis.com/generate_content_paid_tier_input_token_count\\",\\n \\"quotaId\\": \\"GenerateContentPaidTierInputTokensPerModelPerMinute\\",\\n \\"quotaDimensions\\": {\\n \\"location\\": \\"global\\",\\n \\"model\\": \\"gemini-2.5-pro\\"\\n },\\n \\"quotaValue\\": \\"10000\\"\\n }\\n ]\\n },\\n {\\n \\"@type\\": \\"type.googleapis.com/google.rpc.Help\\",\\n \\"links\\": [\\n {\\n \\"description\\": \\"Learn more about Gemini API quotas\\",\\n \\"url\\": \\"https://ai.google.dev/gemini-api/docs/rate-limits\\"\\n }\\n ]\\n },\\n {\\n \\"@type\\": \\"type.googleapis.com/google.rpc.RetryInfo\\",\\n \\"retryDelay\\": \\"40s\\"\\n }\\n ]\\n }\\n}\\n","code":429,"status":"Too Many Requests"}}';
203
+ const parsed = parseGoogleApiError(userErrorString);
204
+ expect(parsed).not.toBeNull();
205
+ expect(parsed?.code).toBe(429);
206
+ expect(parsed?.message).toContain('You exceeded your current quota');
207
+ expect(parsed?.details).toHaveLength(4);
208
+ expect(parsed?.details.some((d) => d['@type'] === 'type.googleapis.com/google.rpc.QuotaFailure')).toBe(true);
209
+ expect(parsed?.details.some((d) => d['@type'] === 'type.googleapis.com/google.rpc.RetryInfo')).toBe(true);
210
+ });
211
+ it('should parse an error that is an array', () => {
212
+ const mockError = [
213
+ {
214
+ error: {
215
+ code: 429,
216
+ message: 'Quota exceeded',
217
+ details: [
218
+ {
219
+ '@type': 'type.googleapis.com/google.rpc.QuotaFailure',
220
+ violations: [{ subject: 'user', description: 'daily limit' }],
221
+ },
222
+ ],
223
+ },
224
+ },
225
+ ];
226
+ const parsed = parseGoogleApiError(mockError);
227
+ expect(parsed).not.toBeNull();
228
+ expect(parsed?.code).toBe(429);
229
+ expect(parsed?.message).toBe('Quota exceeded');
230
+ });
231
+ it('should parse a gaxios error where data is an array', () => {
232
+ const mockError = {
233
+ response: {
234
+ status: 429,
235
+ data: [
236
+ {
237
+ error: {
238
+ code: 429,
239
+ message: 'Quota exceeded',
240
+ details: [
241
+ {
242
+ '@type': 'type.googleapis.com/google.rpc.QuotaFailure',
243
+ violations: [{ subject: 'user', description: 'daily limit' }],
244
+ },
245
+ ],
246
+ },
247
+ },
248
+ ],
249
+ },
250
+ };
251
+ const parsed = parseGoogleApiError(mockError);
252
+ expect(parsed).not.toBeNull();
253
+ expect(parsed?.code).toBe(429);
254
+ expect(parsed?.message).toBe('Quota exceeded');
255
+ });
256
+ it('should parse a gaxios error where data is a stringified array', () => {
257
+ const mockError = {
258
+ response: {
259
+ status: 429,
260
+ data: JSON.stringify([
261
+ {
262
+ error: {
263
+ code: 429,
264
+ message: 'Quota exceeded',
265
+ details: [
266
+ {
267
+ '@type': 'type.googleapis.com/google.rpc.QuotaFailure',
268
+ violations: [{ subject: 'user', description: 'daily limit' }],
269
+ },
270
+ ],
271
+ },
272
+ },
273
+ ]),
274
+ },
275
+ };
276
+ const parsed = parseGoogleApiError(mockError);
277
+ expect(parsed).not.toBeNull();
278
+ expect(parsed?.code).toBe(429);
279
+ expect(parsed?.message).toBe('Quota exceeded');
280
+ });
281
+ it('should parse an error with a malformed @type key (returned by Gemini API)', () => {
282
+ const malformedError = {
283
+ name: 'API Error',
284
+ message: {
285
+ error: {
286
+ message: '{\n "error": {\n "code": 429,\n "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.\\n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_requests, limit: 2\nPlease retry in 54.887755558s.",\n "status": "RESOURCE_EXHAUSTED",\n "details": [\n {\n " @type": "type.googleapis.com/google.rpc.DebugInfo",\n "detail": "[ORIGINAL ERROR] generic::resource_exhausted: 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.\\n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_requests, limit: 2\\nPlease retry in 54.887755558s. [google.rpc.error_details_ext] { 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.\\\\n* Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_requests, limit: 2\\\\nPlease retry in 54.887755558s.\\" }"\n },\n {\n" @type": "type.googleapis.com/google.rpc.QuotaFailure",\n "violations": [\n {\n "quotaMetric": "generativelanguage.googleapis.com/generate_content_free_tier_requests",\n "quotaId": "GenerateRequestsPerMinutePerProjectPerModel-FreeTier",\n "quotaDimensions": {\n "location": "global",\n"model": "gemini-2.5-pro"\n },\n "quotaValue": "2"\n }\n ]\n },\n {\n" @type": "type.googleapis.com/google.rpc.Help",\n "links": [\n {\n "description": "Learn more about Gemini API quotas",\n "url": "https://ai.google.dev/gemini-api/docs/rate-limits"\n }\n ]\n },\n {\n" @type": "type.googleapis.com/google.rpc.RetryInfo",\n "retryDelay": "54s"\n }\n ]\n }\n}\n',
287
+ code: 429,
288
+ status: 'Too Many Requests',
289
+ },
290
+ },
291
+ };
292
+ const parsed = parseGoogleApiError(malformedError);
293
+ expect(parsed).not.toBeNull();
294
+ expect(parsed?.code).toBe(429);
295
+ expect(parsed?.message).toContain('You exceeded your current quota');
296
+ expect(parsed?.details).toHaveLength(4);
297
+ expect(parsed?.details.some((d) => d['@type'] === 'type.googleapis.com/google.rpc.QuotaFailure')).toBe(true);
298
+ expect(parsed?.details.some((d) => d['@type'] === 'type.googleapis.com/google.rpc.RetryInfo')).toBe(true);
299
+ });
300
+ });
301
+ //# sourceMappingURL=googleErrors.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"googleErrors.test.js","sourceRoot":"","sources":["../../../src/utils/googleErrors.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { GoogleApiError } from './googleErrors.js';
7
+ /**
8
+ * A non-retryable error indicating a hard quota limit has been reached (e.g., daily limit).
9
+ */
10
+ export declare class TerminalQuotaError extends Error {
11
+ readonly cause: GoogleApiError;
12
+ constructor(message: string, cause: GoogleApiError);
13
+ }
14
+ /**
15
+ * A retryable error indicating a temporary quota issue (e.g., per-minute limit).
16
+ */
17
+ export declare class RetryableQuotaError extends Error {
18
+ readonly cause: GoogleApiError;
19
+ retryDelayMs: number;
20
+ constructor(message: string, cause: GoogleApiError, retryDelaySeconds: number);
21
+ }
22
+ /**
23
+ * Analyzes a caught error and classifies it as a specific quota-related error if applicable.
24
+ *
25
+ * It decides whether an error is a `TerminalQuotaError` or a `RetryableQuotaError` based on
26
+ * the following logic:
27
+ * - If the error indicates a daily limit, it's a `TerminalQuotaError`.
28
+ * - If the error suggests a retry delay of more than 2 minutes, it's a `TerminalQuotaError`.
29
+ * - If the error suggests a retry delay of 2 minutes or less, it's a `RetryableQuotaError`.
30
+ * - If the error indicates a per-minute limit, it's a `RetryableQuotaError`.
31
+ *
32
+ * @param error The error to classify.
33
+ * @returns A `TerminalQuotaError`, `RetryableQuotaError`, or the original `unknown` error.
34
+ */
35
+ export declare function classifyGoogleError(error: unknown): unknown;
@@ -0,0 +1,131 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { parseGoogleApiError } from './googleErrors.js';
7
+ /**
8
+ * A non-retryable error indicating a hard quota limit has been reached (e.g., daily limit).
9
+ */
10
+ export class TerminalQuotaError extends Error {
11
+ cause;
12
+ constructor(message, cause) {
13
+ super(message);
14
+ this.cause = cause;
15
+ this.name = 'TerminalQuotaError';
16
+ }
17
+ }
18
+ /**
19
+ * A retryable error indicating a temporary quota issue (e.g., per-minute limit).
20
+ */
21
+ export class RetryableQuotaError extends Error {
22
+ cause;
23
+ retryDelayMs;
24
+ constructor(message, cause, retryDelaySeconds) {
25
+ super(message);
26
+ this.cause = cause;
27
+ this.name = 'RetryableQuotaError';
28
+ this.retryDelayMs = retryDelaySeconds * 1000;
29
+ }
30
+ }
31
+ /**
32
+ * Parses a duration string (e.g., "34.074824224s", "60s") and returns the time in seconds.
33
+ * @param duration The duration string to parse.
34
+ * @returns The duration in seconds, or null if parsing fails.
35
+ */
36
+ function parseDurationInSeconds(duration) {
37
+ if (!duration.endsWith('s')) {
38
+ return null;
39
+ }
40
+ const seconds = parseFloat(duration.slice(0, -1));
41
+ return isNaN(seconds) ? null : seconds;
42
+ }
43
+ /**
44
+ * Analyzes a caught error and classifies it as a specific quota-related error if applicable.
45
+ *
46
+ * It decides whether an error is a `TerminalQuotaError` or a `RetryableQuotaError` based on
47
+ * the following logic:
48
+ * - If the error indicates a daily limit, it's a `TerminalQuotaError`.
49
+ * - If the error suggests a retry delay of more than 2 minutes, it's a `TerminalQuotaError`.
50
+ * - If the error suggests a retry delay of 2 minutes or less, it's a `RetryableQuotaError`.
51
+ * - If the error indicates a per-minute limit, it's a `RetryableQuotaError`.
52
+ *
53
+ * @param error The error to classify.
54
+ * @returns A `TerminalQuotaError`, `RetryableQuotaError`, or the original `unknown` error.
55
+ */
56
+ export function classifyGoogleError(error) {
57
+ const googleApiError = parseGoogleApiError(error);
58
+ if (!googleApiError || googleApiError.code !== 429) {
59
+ return error; // Not a 429 error we can handle.
60
+ }
61
+ const quotaFailure = googleApiError.details.find((d) => d['@type'] === 'type.googleapis.com/google.rpc.QuotaFailure');
62
+ const errorInfo = googleApiError.details.find((d) => d['@type'] === 'type.googleapis.com/google.rpc.ErrorInfo');
63
+ const retryInfo = googleApiError.details.find((d) => d['@type'] === 'type.googleapis.com/google.rpc.RetryInfo');
64
+ // 1. Check for long-term limits in QuotaFailure or ErrorInfo
65
+ if (quotaFailure) {
66
+ for (const violation of quotaFailure.violations) {
67
+ const quotaId = violation.quotaId ?? '';
68
+ if (quotaId.includes('PerDay') || quotaId.includes('Daily')) {
69
+ return new TerminalQuotaError(`${googleApiError.message}\nExpected quota reset within 24h.`, googleApiError);
70
+ }
71
+ }
72
+ }
73
+ if (errorInfo) {
74
+ // New Cloud Code API quota handling
75
+ if (errorInfo.domain) {
76
+ const validDomains = [
77
+ 'cloudcode-pa.googleapis.com',
78
+ 'staging-cloudcode-pa.googleapis.com',
79
+ 'autopush-cloudcode-pa.googleapis.com',
80
+ ];
81
+ if (validDomains.includes(errorInfo.domain)) {
82
+ if (errorInfo.reason === 'RATE_LIMIT_EXCEEDED') {
83
+ let delaySeconds = 10; // Default retry of 10s
84
+ if (retryInfo?.retryDelay) {
85
+ const parsedDelay = parseDurationInSeconds(retryInfo.retryDelay);
86
+ if (parsedDelay) {
87
+ delaySeconds = parsedDelay;
88
+ }
89
+ }
90
+ return new RetryableQuotaError(`${googleApiError.message}`, googleApiError, delaySeconds);
91
+ }
92
+ if (errorInfo.reason === 'QUOTA_EXHAUSTED') {
93
+ return new TerminalQuotaError(`${googleApiError.message}`, googleApiError);
94
+ }
95
+ }
96
+ }
97
+ // Existing Cloud Code API quota handling
98
+ const quotaLimit = errorInfo.metadata?.['quota_limit'] ?? '';
99
+ if (quotaLimit.includes('PerDay') || quotaLimit.includes('Daily')) {
100
+ return new TerminalQuotaError(`${googleApiError.message}\nExpected quota reset within 24h.`, googleApiError);
101
+ }
102
+ }
103
+ // 2. Check for long delays in RetryInfo
104
+ if (retryInfo?.retryDelay) {
105
+ const delaySeconds = parseDurationInSeconds(retryInfo.retryDelay);
106
+ if (delaySeconds) {
107
+ if (delaySeconds > 120) {
108
+ return new TerminalQuotaError(`${googleApiError.message}\nSuggested retry after ${retryInfo.retryDelay}.`, googleApiError);
109
+ }
110
+ // This is a retryable error with a specific delay.
111
+ return new RetryableQuotaError(`${googleApiError.message}\nSuggested retry after ${retryInfo.retryDelay}.`, googleApiError, delaySeconds);
112
+ }
113
+ }
114
+ // 3. Check for short-term limits in QuotaFailure or ErrorInfo
115
+ if (quotaFailure) {
116
+ for (const violation of quotaFailure.violations) {
117
+ const quotaId = violation.quotaId ?? '';
118
+ if (quotaId.includes('PerMinute')) {
119
+ return new RetryableQuotaError(`${googleApiError.message}\nSuggested retry after 60s.`, googleApiError, 60);
120
+ }
121
+ }
122
+ }
123
+ if (errorInfo) {
124
+ const quotaLimit = errorInfo.metadata?.['quota_limit'] ?? '';
125
+ if (quotaLimit.includes('PerMinute')) {
126
+ return new RetryableQuotaError(`${errorInfo.reason}\nSuggested retry after 60s.`, googleApiError, 60);
127
+ }
128
+ }
129
+ return error; // Fallback to original error if no specific classification fits.
130
+ }
131
+ //# sourceMappingURL=googleQuotaErrors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"googleQuotaErrors.js","sourceRoot":"","sources":["../../../src/utils/googleQuotaErrors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};