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:
commit
c7e30b5149
1 changed files with 172 additions and 99 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue