Merge pull request #101 from lethanhson9901/fix/antigravity-project-id-discovery

fix(antigravity): implement automatic Project ID discovery to resolve 403 errors
This commit is contained in:
何夕2077 2025-12-09 12:03:13 +08:00 committed by GitHub
commit c7e30b5149

View file

@ -91,14 +91,14 @@ function generateProjectID() {
/**
* 将 Gemini 格式请求转换为 Antigravity 格式
*/
function geminiToAntigravity(modelName, payload) {
function geminiToAntigravity(modelName, payload, projectId) {
// 深拷贝请求体,避免修改原始对象
let template = JSON.parse(JSON.stringify(payload));
// 设置基本字段
template.model = modelName;
template.userAgent = 'antigravity';
template.project = generateProjectID();
template.project = projectId || generateProjectID();
template.requestId = generateRequestID();
// 确保 request 对象存在
@ -235,15 +235,13 @@ export class AntigravityApiService {
await this.initializeAuth();
if (!this.projectId) {
this.projectId = generateProjectID();
console.log(`[Antigravity] Generated Project ID: ${this.projectId}`);
this.projectId = await this.discoverProjectAndModels();
} else {
console.log(`[Antigravity] Using provided Project ID: ${this.projectId}`);
// 获取可用模型
await this.fetchAvailableModels();
}
// 获取可用模型
await this.fetchAvailableModels();
this.isInitialized = true;
console.log(`[Antigravity] Initialization complete. Project ID: ${this.projectId}`);
}
@ -381,6 +379,81 @@ export class AntigravityApiService {
return expiryTime <= (currentTime + refreshSkewMs);
}
async discoverProjectAndModels() {
if (this.projectId) {
console.log(`[Antigravity] Using pre-configured Project ID: ${this.projectId}`);
return this.projectId;
}
console.log('[Antigravity] Discovering Project ID...');
try {
const initialProjectId = "";
// Prepare client metadata
const clientMetadata = {
ideType: "IDE_UNSPECIFIED",
platform: "PLATFORM_UNSPECIFIED",
pluginType: "GEMINI",
duetProject: initialProjectId,
};
// Call loadCodeAssist to discover the actual project ID
const loadRequest = {
cloudaicompanionProject: initialProjectId,
metadata: clientMetadata,
};
const loadResponse = await this.callApi('loadCodeAssist', loadRequest);
// Check if we already have a project ID from the response
if (loadResponse.cloudaicompanionProject) {
console.log(`[Antigravity] Discovered existing Project ID: ${loadResponse.cloudaicompanionProject}`);
// 获取可用模型
await this.fetchAvailableModels();
return loadResponse.cloudaicompanionProject;
}
// If no existing project, we need to onboard
const defaultTier = loadResponse.allowedTiers?.find(tier => tier.isDefault);
const tierId = defaultTier?.id || 'free-tier';
const onboardRequest = {
tierId: tierId,
cloudaicompanionProject: initialProjectId,
metadata: clientMetadata,
};
let lroResponse = await this.callApi('onboardUser', onboardRequest);
// Poll until operation is complete with timeout protection
const MAX_RETRIES = 30; // Maximum number of retries (60 seconds total)
let retryCount = 0;
while (!lroResponse.done && retryCount < MAX_RETRIES) {
await new Promise(resolve => setTimeout(resolve, 2000));
lroResponse = await this.callApi('onboardUser', onboardRequest);
retryCount++;
}
if (!lroResponse.done) {
throw new Error('Onboarding timeout: Operation did not complete within expected time.');
}
const discoveredProjectId = lroResponse.response?.cloudaicompanionProject?.id || initialProjectId;
console.log(`[Antigravity] Onboarded and discovered Project ID: ${discoveredProjectId}`);
// 获取可用模型
await this.fetchAvailableModels();
return discoveredProjectId;
} catch (error) {
console.error('[Antigravity] Failed to discover Project ID:', error.response?.data || error.message);
console.log('[Antigravity] Falling back to generated Project ID as last resort...');
const fallbackProjectId = generateProjectID();
console.log(`[Antigravity] Generated fallback Project ID: ${fallbackProjectId}`);
// 获取可用模型
await this.fetchAvailableModels();
return fallbackProjectId;
}
}
async fetchAvailableModels() {
console.log('[Antigravity] Fetching available models...');
@ -637,7 +710,7 @@ export class AntigravityApiService {
const actualModelName = alias2ModelName(selectedModel);
// 将处理后的请求体转换为 Antigravity 格式
const payload = geminiToAntigravity(actualModelName, { request: processedRequestBody });
const payload = geminiToAntigravity(actualModelName, { request: processedRequestBody }, this.projectId);
// 设置模型名称为实际模型名
payload.model = actualModelName;
@ -660,7 +733,7 @@ export class AntigravityApiService {
const actualModelName = alias2ModelName(selectedModel);
// 将处理后的请求体转换为 Antigravity 格式
const payload = geminiToAntigravity(actualModelName, { request: processedRequestBody });
const payload = geminiToAntigravity(actualModelName, { request: processedRequestBody }, this.projectId);
// 设置模型名称为实际模型名
payload.model = actualModelName;