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.
- package/dist/get-models-B5kAooWg.js.map +1 -1
- package/dist/main.js +124 -29
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
|
@@ -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
|
-
|
|
1335
|
+
const functionDeclarations = [];
|
|
1336
|
+
for (const tool of tools) {
|
|
1301
1337
|
const t = tool;
|
|
1302
|
-
if (t.type === "function" && t.function)
|
|
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
|
-
|
|
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
|
|
1348
|
+
* Build standard Gemini API request body (for API Key authentication)
|
|
1312
1349
|
*/
|
|
1313
|
-
function
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
1881
|
+
const functionDeclarations = [];
|
|
1882
|
+
for (const tool of tools) {
|
|
1796
1883
|
const t = tool;
|
|
1797
|
-
|
|
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
|
|
1896
|
+
function buildGeminiRequest(request) {
|
|
1808
1897
|
const { contents, systemInstruction } = convertMessages(request.messages, request.system);
|
|
1809
1898
|
const tools = convertTools(request.tools);
|
|
1810
|
-
const
|
|
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)
|
|
1821
|
-
if (tools)
|
|
1822
|
-
if (isThinkingModel(request.model))
|
|
1823
|
-
...
|
|
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
|
|
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 =
|
|
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
|
|
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 = {
|