copilot-api-plus 1.0.32 → 1.0.34

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.
package/dist/main.js CHANGED
@@ -2162,30 +2162,66 @@ function createErrorResponse(type, message, status) {
2162
2162
  * Create Anthropic-compatible message response using Antigravity
2163
2163
  * Note: Both Gemini and Claude models use the same endpoint and Gemini-style format
2164
2164
  */
2165
+ const MAX_RETRIES = 5;
2165
2166
  async function createAntigravityMessages(request) {
2166
- const accessToken = await getValidAccessToken();
2167
- if (!accessToken) return createErrorResponse("authentication_error", "No valid Antigravity access token available. Please run login first.", 401);
2168
2167
  const endpoint = request.stream ? ANTIGRAVITY_STREAM_URL : ANTIGRAVITY_NO_STREAM_URL;
2169
2168
  const body = buildGeminiRequest(request);
2170
- consola.debug(`Antigravity messages request to ${endpoint} with model ${request.model}`);
2171
- try {
2172
- const response = await fetch(endpoint, {
2173
- method: "POST",
2174
- headers: {
2175
- Host: ANTIGRAVITY_API_HOST,
2176
- "User-Agent": ANTIGRAVITY_USER_AGENT,
2177
- Authorization: `Bearer ${accessToken}`,
2178
- "Content-Type": "application/json",
2179
- "Accept-Encoding": "gzip"
2180
- },
2181
- body: JSON.stringify(body)
2182
- });
2183
- if (!response.ok) return await handleApiError(response);
2184
- return request.stream ? transformStreamResponse(response, request.model) : await transformNonStreamResponse(response, request.model);
2185
- } catch (error) {
2186
- consola.error("Antigravity messages request error:", error);
2187
- return createErrorResponse("api_error", `Request failed: ${String(error)}`, 500);
2169
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
2170
+ const accessToken = await getValidAccessToken();
2171
+ if (!accessToken) return createErrorResponse("authentication_error", "No valid Antigravity access token available. Please run login first.", 401);
2172
+ consola.debug(`Antigravity request to ${endpoint} (attempt ${attempt + 1}/${MAX_RETRIES + 1})`);
2173
+ try {
2174
+ const response = await fetch(endpoint, {
2175
+ method: "POST",
2176
+ headers: {
2177
+ Host: ANTIGRAVITY_API_HOST,
2178
+ "User-Agent": ANTIGRAVITY_USER_AGENT,
2179
+ Authorization: `Bearer ${accessToken}`,
2180
+ "Content-Type": "application/json",
2181
+ "Accept-Encoding": "gzip"
2182
+ },
2183
+ body: JSON.stringify(body)
2184
+ });
2185
+ if (response.ok) return request.stream ? transformStreamResponse(response, request.model) : await transformNonStreamResponse(response, request.model);
2186
+ const errorResult = await handleApiError(response);
2187
+ if (errorResult.shouldRetry && attempt < MAX_RETRIES) {
2188
+ consola.info(`Rate limited, retrying in ${errorResult.retryDelayMs}ms...`);
2189
+ await sleep(errorResult.retryDelayMs);
2190
+ continue;
2191
+ }
2192
+ return errorResult.response;
2193
+ } catch (error) {
2194
+ consola.error("Antigravity messages request error:", error);
2195
+ if (attempt < MAX_RETRIES) {
2196
+ await sleep(500);
2197
+ continue;
2198
+ }
2199
+ return createErrorResponse("api_error", `Request failed: ${String(error)}`, 500);
2200
+ }
2188
2201
  }
2202
+ return createErrorResponse("api_error", "Max retries exceeded", 429);
2203
+ }
2204
+ /**
2205
+ * Parse retry delay from error response
2206
+ */
2207
+ function parseRetryDelay(errorText) {
2208
+ try {
2209
+ const details = JSON.parse(errorText).error?.details ?? [];
2210
+ for (const detail of details) {
2211
+ if (detail["@type"]?.includes("RetryInfo") && detail.retryDelay) {
2212
+ const match = /(\d+(?:\.\d+)?)s/.exec(detail.retryDelay);
2213
+ if (match) return Math.ceil(Number.parseFloat(match[1]) * 1e3);
2214
+ }
2215
+ if (detail.quotaResetDelay) {
2216
+ const match = /(\d+(?:\.\d+)?)(?:ms|s)/.exec(detail.quotaResetDelay);
2217
+ if (match) {
2218
+ const value = Number.parseFloat(match[1]);
2219
+ return detail.quotaResetDelay.includes("ms") ? Math.ceil(value) : Math.ceil(value * 1e3);
2220
+ }
2221
+ }
2222
+ }
2223
+ } catch {}
2224
+ return 500;
2189
2225
  }
2190
2226
  /**
2191
2227
  * Handle API error response
@@ -2194,8 +2230,19 @@ async function handleApiError(response) {
2194
2230
  const errorText = await response.text();
2195
2231
  consola.error(`Antigravity error: ${response.status} ${errorText}`);
2196
2232
  if (response.status === 403) await disableCurrentAccount();
2197
- if (response.status === 429 || response.status === 503) await rotateAccount();
2198
- return createErrorResponse("api_error", `Antigravity API error: ${response.status}`, response.status);
2233
+ if (response.status === 429 || response.status === 503) {
2234
+ await rotateAccount();
2235
+ return {
2236
+ shouldRetry: true,
2237
+ retryDelayMs: parseRetryDelay(errorText),
2238
+ response: createErrorResponse("api_error", `Antigravity API error: ${response.status}`, response.status)
2239
+ };
2240
+ }
2241
+ return {
2242
+ shouldRetry: false,
2243
+ retryDelayMs: 0,
2244
+ response: createErrorResponse("api_error", `Antigravity API error: ${response.status}`, response.status)
2245
+ };
2199
2246
  }
2200
2247
  /**
2201
2248
  * Emit SSE event to controller based on stream event type
@@ -2272,12 +2319,14 @@ function transformStreamResponse(response, model) {
2272
2319
  */
2273
2320
  async function processStream(reader, decoder, state$1, controller) {
2274
2321
  const emit = (event) => emitSSEEvent(event, controller, state$1);
2275
- while (true) {
2322
+ let finished = false;
2323
+ while (!finished) {
2276
2324
  const { done, value } = await reader.read();
2277
2325
  if (done) break;
2278
2326
  const chunk = decoder.decode(value, { stream: true });
2279
2327
  const lines = processChunk(chunk, state$1);
2280
2328
  for (const line of lines) {
2329
+ if (finished) break;
2281
2330
  const data = parseSSELine(line);
2282
2331
  if (!data) continue;
2283
2332
  const { candidates, usage } = extractFromData(data);
@@ -2288,7 +2337,11 @@ async function processStream(reader, decoder, state$1, controller) {
2288
2337
  const candidate = candidates[0];
2289
2338
  const parts = candidate?.content?.parts ?? [];
2290
2339
  for (const part of parts) processPart(part, state$1, emit);
2291
- if (candidate?.finishReason === "STOP") handleFinish(state$1, emit);
2340
+ if (candidate?.finishReason === "STOP") {
2341
+ handleFinish(state$1, emit);
2342
+ finished = true;
2343
+ break;
2344
+ }
2292
2345
  }
2293
2346
  }
2294
2347
  }