copilot-api-plus 1.0.21 → 1.0.23

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.
@@ -1 +1 @@
1
- {"version":3,"file":"get-models-B5kAooWg.js","names":["FALLBACK_MODELS: Array<AntigravityModel>","cachedModels: Array<AntigravityModel> | null","cacheTimestamp: number","models: Array<AntigravityModel>","modelsQuota: Record<string, {\n remaining_fraction: number\n reset_time: string\n percent_remaining: number\n }>"],"sources":["../src/services/antigravity/get-models.ts"],"sourcesContent":["/**\n * Google Antigravity Models\n *\n * Provides list of available models from Antigravity.\n * Based on: https://github.com/liuw1535/antigravity2api-nodejs\n */\n\n/* eslint-disable require-atomic-updates */\n\nimport consola from \"consola\"\n\nimport { getValidAccessToken } from \"./auth\"\n\n// Antigravity API endpoints\nconst ANTIGRAVITY_API_HOST = \"daily-cloudcode-pa.sandbox.googleapis.com\"\nconst ANTIGRAVITY_MODELS_URL = `https://${ANTIGRAVITY_API_HOST}/v1internal:fetchAvailableModels`\nconst ANTIGRAVITY_USER_AGENT = \"antigravity/1.11.3 windows/amd64\"\n\nexport interface AntigravityQuotaInfo {\n remainingFraction: number\n resetTime: string\n}\n\nexport interface AntigravityModel {\n id: string\n object: string\n created: number\n owned_by: string\n quotaInfo?: AntigravityQuotaInfo\n}\n\nexport interface AntigravityModelsResponse {\n object: string\n data: Array<AntigravityModel>\n}\n\n/**\n * Fallback Antigravity models when API is unavailable\n * Updated based on actual API response (December 2024)\n */\nconst FALLBACK_MODELS: Array<AntigravityModel> = [\n // Gemini models\n {\n id: \"gemini-2.5-pro\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-2.5-flash\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-2.5-flash-lite\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-2.5-flash-thinking\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-3-pro-low\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-3-pro-high\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-3-pro-image\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-3-flash\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n\n // Claude models (via Antigravity)\n {\n id: \"claude-sonnet-4-5\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"anthropic\",\n },\n {\n id: \"claude-sonnet-4-5-thinking\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"anthropic\",\n },\n {\n id: \"claude-opus-4-5-thinking\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"anthropic\",\n },\n]\n\n// Cache for fetched models\nlet cachedModels: Array<AntigravityModel> | null = null\nlet cacheTimestamp: number = 0\nconst CACHE_TTL = 5 * 60 * 1000 // 5 minutes\n\n/**\n * Fetch models from Antigravity API\n */\nasync function fetchModelsFromApi(): Promise<Array<AntigravityModel> | null> {\n const accessToken = await getValidAccessToken()\n\n if (!accessToken) {\n consola.debug(\"No access token available, using fallback models\")\n return null\n }\n\n try {\n const response = await fetch(ANTIGRAVITY_MODELS_URL, {\n method: \"POST\",\n headers: {\n Host: ANTIGRAVITY_API_HOST,\n \"User-Agent\": ANTIGRAVITY_USER_AGENT,\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n },\n body: JSON.stringify({}),\n })\n\n if (!response.ok) {\n consola.warn(`Failed to fetch Antigravity models: ${response.status}`)\n return null\n }\n\n // API returns models as object (dictionary), not array\n // Format: { \"models\": { \"model-id\": { \"quotaInfo\": {...}, ... }, ... } }\n const data = (await response.json()) as {\n models?: Record<string, {\n displayName?: string\n maxTokens?: number\n quotaInfo?: {\n remainingFraction?: number\n resetTime?: string\n }\n }>\n }\n\n if (!data.models || typeof data.models !== \"object\") {\n consola.warn(\"No models object in response\")\n return null\n }\n\n // Convert object to array format\n const modelEntries = Object.entries(data.models)\n consola.debug(`Antigravity API returned ${modelEntries.length} models`)\n\n // Filter to only include Gemini and Claude models (skip internal models like chat_20706)\n const models: Array<AntigravityModel> = modelEntries\n .filter(([modelId, info]) => {\n // Only include gemini, learnlm, and claude models\n const isPublicModel = modelId.startsWith(\"gemini\") ||\n modelId.startsWith(\"learnlm\") ||\n modelId.startsWith(\"claude\")\n // Filter out models with no remaining quota\n const remaining = info.quotaInfo?.remainingFraction ?? 1\n return isPublicModel && remaining > 0\n })\n .map(([modelId, info]) => {\n const isGoogle = modelId.startsWith(\"gemini\") || modelId.startsWith(\"learnlm\")\n\n return {\n id: modelId,\n object: \"model\",\n created: 1700000000,\n owned_by: isGoogle ? \"google\" : \"anthropic\",\n quotaInfo: info.quotaInfo ? {\n remainingFraction: info.quotaInfo.remainingFraction ?? 1,\n resetTime: info.quotaInfo.resetTime ?? \"\",\n } : undefined,\n }\n })\n\n consola.debug(`Fetched ${models.length} models from Antigravity API`)\n return models\n } catch (error) {\n consola.warn(\"Error fetching Antigravity models:\", error)\n return null\n }\n}\n\n/**\n * Get available Antigravity models\n */\nexport async function getAntigravityModels(): Promise<AntigravityModelsResponse> {\n // Check cache\n if (cachedModels && Date.now() - cacheTimestamp < CACHE_TTL) {\n consola.debug(`Returning ${cachedModels.length} cached Antigravity models`)\n return {\n object: \"list\",\n data: cachedModels,\n }\n }\n\n // Try to fetch from API\n const apiModels = await fetchModelsFromApi()\n\n if (apiModels && apiModels.length > 0) {\n cachedModels = apiModels\n cacheTimestamp = Date.now()\n\n return {\n object: \"list\",\n data: apiModels,\n }\n }\n\n // Use fallback models\n consola.debug(\n `Returning ${FALLBACK_MODELS.length} fallback Antigravity models`,\n )\n\n return {\n object: \"list\",\n data: FALLBACK_MODELS,\n }\n}\n\n/**\n * Antigravity usage response format (compatible with Copilot usage viewer)\n */\nexport interface AntigravityUsageResponse {\n copilot_plan: string\n quota_reset_date: string\n quota_snapshots: {\n models: Record<string, {\n remaining_fraction: number\n reset_time: string\n percent_remaining: number\n }>\n }\n}\n\n/**\n * Get Antigravity usage/quota information\n */\nexport async function getAntigravityUsage(): Promise<AntigravityUsageResponse> {\n // Force refresh models to get latest quota\n cachedModels = null\n cacheTimestamp = 0\n\n const modelsResponse = await getAntigravityModels()\n\n // Find earliest reset time\n let earliestResetTime = \"\"\n const modelsQuota: Record<string, {\n remaining_fraction: number\n reset_time: string\n percent_remaining: number\n }> = {}\n\n let modelsWithQuota = 0\n for (const model of modelsResponse.data) {\n if (model.quotaInfo) {\n modelsWithQuota++\n const resetTime = model.quotaInfo.resetTime\n if (!earliestResetTime || (resetTime && resetTime < earliestResetTime)) {\n earliestResetTime = resetTime\n }\n\n modelsQuota[model.id] = {\n remaining_fraction: model.quotaInfo.remainingFraction,\n reset_time: model.quotaInfo.resetTime,\n percent_remaining: Math.round(model.quotaInfo.remainingFraction * 100),\n }\n }\n }\n\n consola.debug(`Antigravity usage: ${modelsWithQuota}/${modelsResponse.data.length} models have quota info`)\n\n return {\n copilot_plan: \"antigravity\",\n quota_reset_date: earliestResetTime,\n quota_snapshots: {\n models: modelsQuota,\n },\n }\n}\n\n/**\n * Check if a model is a Claude model\n */\nexport function isClaudeModel(modelId: string): boolean {\n return modelId.startsWith(\"claude-\")\n}\n\n/**\n * Check if a model is a thinking/reasoning model\n */\nexport function isThinkingModel(modelId: string): boolean {\n return modelId.includes(\"thinking\")\n}\n\n/**\n * Check if a model is an image generation model\n */\nexport function isImageModel(modelId: string): boolean {\n return modelId.includes(\"image\")\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"get-models-B5kAooWg.js","names":["FALLBACK_MODELS: Array<AntigravityModel>","cachedModels: Array<AntigravityModel> | null","cacheTimestamp: number","models: Array<AntigravityModel>","modelsQuota: Record<string, {\n remaining_fraction: number\n reset_time: string\n percent_remaining: number\n }>"],"sources":["../src/services/antigravity/get-models.ts"],"sourcesContent":["/**\n * Google Antigravity Models\n *\n * Provides list of available models from Antigravity.\n * Based on: https://github.com/liuw1535/antigravity2api-nodejs\n */\n\n/* eslint-disable require-atomic-updates */\n\nimport consola from \"consola\"\n\nimport { getValidAccessToken } from \"./auth\"\n\n// Antigravity API endpoints\nconst ANTIGRAVITY_API_HOST = \"daily-cloudcode-pa.sandbox.googleapis.com\"\nconst ANTIGRAVITY_MODELS_URL = `https://${ANTIGRAVITY_API_HOST}/v1internal:fetchAvailableModels`\nconst ANTIGRAVITY_USER_AGENT = \"antigravity/1.11.3 windows/amd64\"\n\nexport interface AntigravityQuotaInfo {\n remainingFraction: number\n resetTime: string\n}\n\nexport interface AntigravityModel {\n id: string\n object: string\n created: number\n owned_by: string\n quotaInfo?: AntigravityQuotaInfo\n}\n\nexport interface AntigravityModelsResponse {\n object: string\n data: Array<AntigravityModel>\n}\n\n/**\n * Fallback Antigravity models when API is unavailable\n * Updated based on actual API response (December 2024)\n */\nconst FALLBACK_MODELS: Array<AntigravityModel> = [\n // Gemini models\n {\n id: \"gemini-2.5-pro\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-2.5-flash\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-2.5-flash-lite\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-2.5-flash-thinking\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-3-pro-low\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-3-pro-high\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-3-pro-image\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n {\n id: \"gemini-3-flash\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"google\",\n },\n\n // Claude models (via Antigravity)\n {\n id: \"claude-sonnet-4-5\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"anthropic\",\n },\n {\n id: \"claude-sonnet-4-5-thinking\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"anthropic\",\n },\n {\n id: \"claude-opus-4-5-thinking\",\n object: \"model\",\n created: 1700000000,\n owned_by: \"anthropic\",\n },\n]\n\n// Cache for fetched models\nlet cachedModels: Array<AntigravityModel> | null = null\nlet cacheTimestamp: number = 0\nconst CACHE_TTL = 5 * 60 * 1000 // 5 minutes\n\n/**\n * Fetch models from Antigravity API\n */\nasync function fetchModelsFromApi(): Promise<Array<AntigravityModel> | null> {\n const accessToken = await getValidAccessToken()\n\n if (!accessToken) {\n consola.debug(\"No access token available, using fallback models\")\n return null\n }\n\n try {\n const response = await fetch(ANTIGRAVITY_MODELS_URL, {\n method: \"POST\",\n headers: {\n Host: ANTIGRAVITY_API_HOST,\n \"User-Agent\": ANTIGRAVITY_USER_AGENT,\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n },\n body: JSON.stringify({}),\n })\n\n if (!response.ok) {\n consola.warn(`Failed to fetch Antigravity models: ${response.status}`)\n return null\n }\n\n // API returns models as object (dictionary), not array\n // Format: { \"models\": { \"model-id\": { \"quotaInfo\": {...}, \"apiProvider\": \"...\", ... }, ... } }\n const data = (await response.json()) as {\n models?: Record<string, {\n displayName?: string\n maxTokens?: number\n apiProvider?: string\n model?: string\n quotaInfo?: {\n remainingFraction?: number\n resetTime?: string\n }\n }>\n }\n\n if (!data.models || typeof data.models !== \"object\") {\n consola.warn(\"No models object in response\")\n return null\n }\n\n // Convert object to array format\n const modelEntries = Object.entries(data.models)\n consola.debug(`Antigravity API returned ${modelEntries.length} models`)\n\n // Filter to only include Gemini and Claude models (skip internal models like chat_20706)\n const models: Array<AntigravityModel> = modelEntries\n .filter(([modelId, info]) => {\n // Only include gemini, learnlm, and claude models\n const isPublicModel = modelId.startsWith(\"gemini\") ||\n modelId.startsWith(\"learnlm\") ||\n modelId.startsWith(\"claude\")\n // Filter out models with no remaining quota\n const remaining = info.quotaInfo?.remainingFraction ?? 1\n return isPublicModel && remaining > 0\n })\n .map(([modelId, info]) => {\n const isGoogle = modelId.startsWith(\"gemini\") || modelId.startsWith(\"learnlm\")\n\n return {\n id: modelId,\n object: \"model\",\n created: 1700000000,\n owned_by: isGoogle ? \"google\" : \"anthropic\",\n quotaInfo: info.quotaInfo ? {\n remainingFraction: info.quotaInfo.remainingFraction ?? 1,\n resetTime: info.quotaInfo.resetTime ?? \"\",\n } : undefined,\n }\n })\n\n consola.debug(`Fetched ${models.length} models from Antigravity API`)\n return models\n } catch (error) {\n consola.warn(\"Error fetching Antigravity models:\", error)\n return null\n }\n}\n\n/**\n * Get available Antigravity models\n */\nexport async function getAntigravityModels(): Promise<AntigravityModelsResponse> {\n // Check cache\n if (cachedModels && Date.now() - cacheTimestamp < CACHE_TTL) {\n consola.debug(`Returning ${cachedModels.length} cached Antigravity models`)\n return {\n object: \"list\",\n data: cachedModels,\n }\n }\n\n // Try to fetch from API\n const apiModels = await fetchModelsFromApi()\n\n if (apiModels && apiModels.length > 0) {\n cachedModels = apiModels\n cacheTimestamp = Date.now()\n\n return {\n object: \"list\",\n data: apiModels,\n }\n }\n\n // Use fallback models\n consola.debug(\n `Returning ${FALLBACK_MODELS.length} fallback Antigravity models`,\n )\n\n return {\n object: \"list\",\n data: FALLBACK_MODELS,\n }\n}\n\n/**\n * Antigravity usage response format (compatible with Copilot usage viewer)\n */\nexport interface AntigravityUsageResponse {\n copilot_plan: string\n quota_reset_date: string\n quota_snapshots: {\n models: Record<string, {\n remaining_fraction: number\n reset_time: string\n percent_remaining: number\n }>\n }\n}\n\n/**\n * Get Antigravity usage/quota information\n */\nexport async function getAntigravityUsage(): Promise<AntigravityUsageResponse> {\n // Force refresh models to get latest quota\n cachedModels = null\n cacheTimestamp = 0\n\n const modelsResponse = await getAntigravityModels()\n\n // Find earliest reset time\n let earliestResetTime = \"\"\n const modelsQuota: Record<string, {\n remaining_fraction: number\n reset_time: string\n percent_remaining: number\n }> = {}\n\n let modelsWithQuota = 0\n for (const model of modelsResponse.data) {\n if (model.quotaInfo) {\n modelsWithQuota++\n const resetTime = model.quotaInfo.resetTime\n if (!earliestResetTime || (resetTime && resetTime < earliestResetTime)) {\n earliestResetTime = resetTime\n }\n\n modelsQuota[model.id] = {\n remaining_fraction: model.quotaInfo.remainingFraction,\n reset_time: model.quotaInfo.resetTime,\n percent_remaining: Math.round(model.quotaInfo.remainingFraction * 100),\n }\n }\n }\n\n consola.debug(`Antigravity usage: ${modelsWithQuota}/${modelsResponse.data.length} models have quota info`)\n\n return {\n copilot_plan: \"antigravity\",\n quota_reset_date: earliestResetTime,\n quota_snapshots: {\n models: modelsQuota,\n },\n }\n}\n\n/**\n * Check if a model is a Claude model\n */\nexport function isClaudeModel(modelId: string): boolean {\n return modelId.startsWith(\"claude-\")\n}\n\n/**\n * Check if a model is a thinking/reasoning model\n */\nexport function isThinkingModel(modelId: string): boolean {\n return modelId.includes(\"thinking\")\n}\n\n/**\n * Check if a model is an image generation model\n */\nexport function isImageModel(modelId: string): boolean {\n return modelId.includes(\"image\")\n}\n"],"mappings":"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"}
package/dist/main.js CHANGED
@@ -628,7 +628,7 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
628
628
  const fs$1 = __require("fs");
629
629
  const path$1 = __require("path");
630
630
  const os$1 = __require("os");
631
- const crypto = __require("crypto");
631
+ const crypto$1 = __require("crypto");
632
632
  const version = require_package().version;
633
633
  const TIPS = [
634
634
  "🔐 encrypt with Dotenvx: https://dotenvx.com",
@@ -843,7 +843,7 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
843
843
  const authTag = ciphertext.subarray(-16);
844
844
  ciphertext = ciphertext.subarray(12, -16);
845
845
  try {
846
- const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
846
+ const aesgcm = crypto$1.createDecipheriv("aes-256-gcm", key, nonce);
847
847
  aesgcm.setAuthTag(authTag);
848
848
  return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
849
849
  } catch (error) {
@@ -1293,28 +1293,64 @@ function parseBase64Image(url) {
1293
1293
  };
1294
1294
  }
1295
1295
  /**
1296
+ * Clean and convert JSON schema to Gemini format
1297
+ * - Removes unsupported fields like $schema, additionalProperties
1298
+ * - Converts type values to uppercase (string -> STRING)
1299
+ */
1300
+ function cleanJsonSchema$1(schema) {
1301
+ if (!schema || typeof schema !== "object") return schema;
1302
+ if (Array.isArray(schema)) return schema.map((item) => cleanJsonSchema$1(item));
1303
+ const obj = schema;
1304
+ const cleaned = {};
1305
+ const unsupportedFields = new Set([
1306
+ "$schema",
1307
+ "$id",
1308
+ "$ref",
1309
+ "additionalProperties",
1310
+ "default",
1311
+ "examples",
1312
+ "minItems",
1313
+ "maxItems",
1314
+ "minLength",
1315
+ "maxLength",
1316
+ "minimum",
1317
+ "maximum",
1318
+ "pattern",
1319
+ "format"
1320
+ ]);
1321
+ for (const [key, value] of Object.entries(obj)) {
1322
+ if (unsupportedFields.has(key)) continue;
1323
+ if (key === "type" && typeof value === "string") cleaned[key] = value.toUpperCase();
1324
+ else if (typeof value === "object" && value !== null) cleaned[key] = cleanJsonSchema$1(value);
1325
+ else cleaned[key] = value;
1326
+ }
1327
+ return cleaned;
1328
+ }
1329
+ /**
1296
1330
  * Convert tools to Antigravity format
1331
+ * All tools should be in a single object with functionDeclarations array
1297
1332
  */
1298
1333
  function convertTools$1(tools) {
1299
1334
  if (!tools || tools.length === 0) return void 0;
1300
- return tools.map((tool) => {
1335
+ const functionDeclarations = [];
1336
+ for (const tool of tools) {
1301
1337
  const t = tool;
1302
- if (t.type === "function" && t.function) return { functionDeclarations: [{
1338
+ if (t.type === "function" && t.function) functionDeclarations.push({
1303
1339
  name: t.function.name,
1304
1340
  description: t.function.description || "",
1305
- parameters: t.function.parameters || {}
1306
- }] };
1307
- return tool;
1308
- });
1341
+ parameters: cleanJsonSchema$1(t.function.parameters) || {}
1342
+ });
1343
+ }
1344
+ if (functionDeclarations.length === 0) return void 0;
1345
+ return [{ functionDeclarations }];
1309
1346
  }
1310
1347
  /**
1311
- * Build Antigravity request body
1348
+ * Build standard Gemini API request body (for API Key authentication)
1312
1349
  */
1313
- function buildRequestBody(request) {
1350
+ function buildStandardGeminiRequestBody(request) {
1314
1351
  const { contents, systemInstruction } = convertMessages$1(request.messages);
1315
1352
  const tools = convertTools$1(request.tools);
1316
1353
  const body = {
1317
- model: request.model,
1318
1354
  contents,
1319
1355
  generationConfig: {
1320
1356
  temperature: request.temperature ?? 1,
@@ -1332,6 +1368,19 @@ function buildRequestBody(request) {
1332
1368
  return body;
1333
1369
  }
1334
1370
  /**
1371
+ * Build Antigravity request body
1372
+ * The Antigravity API expects a specific nested structure with request object
1373
+ */
1374
+ function buildAntigravityRequestBody(request) {
1375
+ const innerRequest = buildStandardGeminiRequestBody(request);
1376
+ return {
1377
+ model: request.model,
1378
+ userAgent: "antigravity",
1379
+ requestId: `agent-${crypto.randomUUID()}`,
1380
+ request: innerRequest
1381
+ };
1382
+ }
1383
+ /**
1335
1384
  * Create error response
1336
1385
  */
1337
1386
  function createErrorResponse$1(message, type, status, details) {
@@ -1361,7 +1410,7 @@ async function createAntigravityChatCompletion(request) {
1361
1410
  */
1362
1411
  async function createWithApiKey(request, apiKey) {
1363
1412
  const endpoint = request.stream ? getGeminiStreamUrl(request.model, apiKey) : getGeminiNoStreamUrl(request.model, apiKey);
1364
- const body = buildRequestBody(request);
1413
+ const body = buildStandardGeminiRequestBody(request);
1365
1414
  consola.debug(`Gemini API request with model ${request.model}`);
1366
1415
  try {
1367
1416
  const response = await fetch(endpoint, {
@@ -1378,10 +1427,11 @@ async function createWithApiKey(request, apiKey) {
1378
1427
  }
1379
1428
  /**
1380
1429
  * Create chat completion using OAuth (Antigravity private API)
1430
+ * Note: Both Gemini and Claude models use the same endpoint and Gemini-style format
1381
1431
  */
1382
1432
  async function createWithOAuth(request, accessToken) {
1383
1433
  const endpoint = request.stream ? ANTIGRAVITY_STREAM_URL$1 : ANTIGRAVITY_NO_STREAM_URL$1;
1384
- const body = buildRequestBody(request);
1434
+ const body = buildAntigravityRequestBody(request);
1385
1435
  consola.debug(`Antigravity request to ${endpoint} with model ${request.model}`);
1386
1436
  try {
1387
1437
  const response = await fetch(endpoint, {
@@ -1514,7 +1564,8 @@ function buildOpenAIChunk(part, requestId, model, finishReason) {
1514
1564
  * Transform Antigravity non-stream response to OpenAI format
1515
1565
  */
1516
1566
  async function transformNonStreamResponse$1(response, model) {
1517
- const data = await response.json();
1567
+ const rawData = await response.json();
1568
+ const data = rawData.response ?? rawData;
1518
1569
  const parts = (data.candidates?.[0])?.content?.parts ?? [];
1519
1570
  const { content, reasoningContent, toolCalls } = extractNonStreamContent(parts);
1520
1571
  const message = {
@@ -1788,27 +1839,64 @@ function buildParts(content) {
1788
1839
  return parts;
1789
1840
  }
1790
1841
  /**
1842
+ * Clean and convert JSON schema to Gemini format
1843
+ * - Removes unsupported fields like $schema, additionalProperties
1844
+ * - Converts type values to uppercase (string -> STRING)
1845
+ */
1846
+ function cleanJsonSchema(schema) {
1847
+ if (!schema || typeof schema !== "object") return schema;
1848
+ if (Array.isArray(schema)) return schema.map((item) => cleanJsonSchema(item));
1849
+ const obj = schema;
1850
+ const cleaned = {};
1851
+ const unsupportedFields = new Set([
1852
+ "$schema",
1853
+ "$id",
1854
+ "$ref",
1855
+ "additionalProperties",
1856
+ "default",
1857
+ "examples",
1858
+ "minItems",
1859
+ "maxItems",
1860
+ "minLength",
1861
+ "maxLength",
1862
+ "minimum",
1863
+ "maximum",
1864
+ "pattern",
1865
+ "format"
1866
+ ]);
1867
+ for (const [key, value] of Object.entries(obj)) {
1868
+ if (unsupportedFields.has(key)) continue;
1869
+ if (key === "type" && typeof value === "string") cleaned[key] = value.toUpperCase();
1870
+ else if (typeof value === "object" && value !== null) cleaned[key] = cleanJsonSchema(value);
1871
+ else cleaned[key] = value;
1872
+ }
1873
+ return cleaned;
1874
+ }
1875
+ /**
1791
1876
  * Convert tools to Antigravity format
1877
+ * All tools should be in a single object with functionDeclarations array
1792
1878
  */
1793
1879
  function convertTools(tools) {
1794
1880
  if (!tools || tools.length === 0) return void 0;
1795
- return tools.map((tool) => {
1881
+ const functionDeclarations = [];
1882
+ for (const tool of tools) {
1796
1883
  const t = tool;
1797
- return { functionDeclarations: [{
1884
+ functionDeclarations.push({
1798
1885
  name: t.name,
1799
1886
  description: t.description || "",
1800
- parameters: t.input_schema || {}
1801
- }] };
1802
- });
1887
+ parameters: cleanJsonSchema(t.input_schema) || {}
1888
+ });
1889
+ }
1890
+ return [{ functionDeclarations }];
1803
1891
  }
1804
1892
  /**
1805
1893
  * Build Antigravity request body
1894
+ * The Antigravity API expects a specific nested structure with request object
1806
1895
  */
1807
- function buildAntigravityRequest(request) {
1896
+ function buildGeminiRequest(request) {
1808
1897
  const { contents, systemInstruction } = convertMessages(request.messages, request.system);
1809
1898
  const tools = convertTools(request.tools);
1810
- const body = {
1811
- model: request.model,
1899
+ const innerRequest = {
1812
1900
  contents,
1813
1901
  generationConfig: {
1814
1902
  temperature: request.temperature ?? 1,
@@ -1817,13 +1905,18 @@ function buildAntigravityRequest(request) {
1817
1905
  maxOutputTokens: request.max_tokens ?? 8096
1818
1906
  }
1819
1907
  };
1820
- if (systemInstruction) body.systemInstruction = systemInstruction;
1821
- if (tools) body.tools = tools;
1822
- if (isThinkingModel(request.model)) body.generationConfig = {
1823
- ...body.generationConfig,
1908
+ if (systemInstruction) innerRequest.systemInstruction = systemInstruction;
1909
+ if (tools) innerRequest.tools = tools;
1910
+ if (isThinkingModel(request.model)) innerRequest.generationConfig = {
1911
+ ...innerRequest.generationConfig,
1824
1912
  thinkingConfig: { includeThoughts: true }
1825
1913
  };
1826
- return body;
1914
+ return {
1915
+ model: request.model,
1916
+ userAgent: "antigravity",
1917
+ requestId: `agent-${crypto.randomUUID()}`,
1918
+ request: innerRequest
1919
+ };
1827
1920
  }
1828
1921
  /**
1829
1922
  * Create error response
@@ -1842,12 +1935,13 @@ function createErrorResponse(type, message, status) {
1842
1935
  }
1843
1936
  /**
1844
1937
  * Create Anthropic-compatible message response using Antigravity
1938
+ * Note: Both Gemini and Claude models use the same endpoint and Gemini-style format
1845
1939
  */
1846
1940
  async function createAntigravityMessages(request) {
1847
1941
  const accessToken = await getValidAccessToken();
1848
1942
  if (!accessToken) return createErrorResponse("authentication_error", "No valid Antigravity access token available. Please run login first.", 401);
1849
1943
  const endpoint = request.stream ? ANTIGRAVITY_STREAM_URL : ANTIGRAVITY_NO_STREAM_URL;
1850
- const body = buildAntigravityRequest(request);
1944
+ const body = buildGeminiRequest(request);
1851
1945
  consola.debug(`Antigravity messages request to ${endpoint} with model ${request.model}`);
1852
1946
  try {
1853
1947
  const response = await fetch(endpoint, {
@@ -1977,7 +2071,8 @@ async function processStream(reader, decoder, state$1, controller) {
1977
2071
  * Transform Antigravity non-stream response to Anthropic format
1978
2072
  */
1979
2073
  async function transformNonStreamResponse(response, model) {
1980
- const data = await response.json();
2074
+ const rawData = await response.json();
2075
+ const data = rawData.response ?? rawData;
1981
2076
  const parts = (data.candidates?.[0])?.content?.parts ?? [];
1982
2077
  const content = buildNonStreamContent(parts);
1983
2078
  const anthropicResponse = {