fix: improve loadCodeAssist for Google One AI Pro accounts
- Add separate LOAD_CODE_ASSIST_ENDPOINTS (prod first) and LOAD_CODE_ASSIST_HEADERS (google-api-nodejs-client User-Agent) - Add duetProject to metadata for project discovery - Silent fallback when API returns success but no project (matches opencode-antigravity-auth behavior) - Only warn when all endpoints fail with actual errors Fixes #114, addresses discussion #113 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,8 +7,8 @@
|
|||||||
import {
|
import {
|
||||||
ANTIGRAVITY_DB_PATH,
|
ANTIGRAVITY_DB_PATH,
|
||||||
TOKEN_REFRESH_INTERVAL_MS,
|
TOKEN_REFRESH_INTERVAL_MS,
|
||||||
ANTIGRAVITY_ENDPOINT_FALLBACKS,
|
LOAD_CODE_ASSIST_ENDPOINTS,
|
||||||
ANTIGRAVITY_HEADERS,
|
LOAD_CODE_ASSIST_HEADERS,
|
||||||
DEFAULT_PROJECT_ID
|
DEFAULT_PROJECT_ID
|
||||||
} from '../constants.js';
|
} from '../constants.js';
|
||||||
import { refreshAccessToken } from '../auth/oauth.js';
|
import { refreshAccessToken } from '../auth/oauth.js';
|
||||||
@@ -113,31 +113,39 @@ export async function getProjectForAccount(account, token, projectCache) {
|
|||||||
* @returns {Promise<string>} Project ID
|
* @returns {Promise<string>} Project ID
|
||||||
*/
|
*/
|
||||||
export async function discoverProject(token) {
|
export async function discoverProject(token) {
|
||||||
for (const endpoint of ANTIGRAVITY_ENDPOINT_FALLBACKS) {
|
let lastError = null;
|
||||||
|
let gotSuccessfulResponse = false;
|
||||||
|
|
||||||
|
for (const endpoint of LOAD_CODE_ASSIST_ENDPOINTS) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${endpoint}/v1internal:loadCodeAssist`, {
|
const response = await fetch(`${endpoint}/v1internal:loadCodeAssist`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${token}`,
|
'Authorization': `Bearer ${token}`,
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
...ANTIGRAVITY_HEADERS
|
...LOAD_CODE_ASSIST_HEADERS
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
metadata: {
|
metadata: {
|
||||||
ideType: 'IDE_UNSPECIFIED',
|
ideType: 'IDE_UNSPECIFIED',
|
||||||
platform: 'PLATFORM_UNSPECIFIED',
|
platform: 'PLATFORM_UNSPECIFIED',
|
||||||
pluginType: 'GEMINI'
|
pluginType: 'GEMINI',
|
||||||
|
duetProject: DEFAULT_PROJECT_ID
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const errorText = await response.text();
|
const errorText = await response.text();
|
||||||
logger.warn(`[AccountManager] Project discovery failed at ${endpoint}: ${response.status} - ${errorText}`);
|
lastError = `${response.status} - ${errorText}`;
|
||||||
|
logger.debug(`[AccountManager] loadCodeAssist failed at ${endpoint}: ${lastError}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
gotSuccessfulResponse = true;
|
||||||
|
|
||||||
|
logger.debug(`[AccountManager] loadCodeAssist response from ${endpoint}:`, JSON.stringify(data));
|
||||||
|
|
||||||
if (typeof data.cloudaicompanionProject === 'string') {
|
if (typeof data.cloudaicompanionProject === 'string') {
|
||||||
logger.success(`[AccountManager] Discovered project: ${data.cloudaicompanionProject}`);
|
logger.success(`[AccountManager] Discovered project: ${data.cloudaicompanionProject}`);
|
||||||
@@ -147,13 +155,21 @@ export async function discoverProject(token) {
|
|||||||
logger.success(`[AccountManager] Discovered project: ${data.cloudaicompanionProject.id}`);
|
logger.success(`[AccountManager] Discovered project: ${data.cloudaicompanionProject.id}`);
|
||||||
return data.cloudaicompanionProject.id;
|
return data.cloudaicompanionProject.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API returned success but no project - this is normal for Google One AI Pro accounts
|
||||||
|
// Silently fall back to default project (matches opencode-antigravity-auth behavior)
|
||||||
|
logger.debug(`[AccountManager] No project in response, using default: ${DEFAULT_PROJECT_ID}`);
|
||||||
|
return DEFAULT_PROJECT_ID;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.warn(`[AccountManager] Project discovery failed at ${endpoint}:`, error.message);
|
lastError = error.message;
|
||||||
|
logger.debug(`[AccountManager] loadCodeAssist error at ${endpoint}:`, error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn(`[AccountManager] Project discovery failed for all endpoints. Using default project: ${DEFAULT_PROJECT_ID}`);
|
// Only warn if all endpoints failed with errors (not just missing project)
|
||||||
logger.warn(`[AccountManager] If you see 404 errors, your account may not have Gemini Code Assist enabled.`);
|
if (!gotSuccessfulResponse) {
|
||||||
|
logger.warn(`[AccountManager] loadCodeAssist failed for all endpoints: ${lastError}`);
|
||||||
|
}
|
||||||
return DEFAULT_PROJECT_ID;
|
return DEFAULT_PROJECT_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,13 @@
|
|||||||
* Handles model listing and quota retrieval from the Cloud Code API.
|
* Handles model listing and quota retrieval from the Cloud Code API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ANTIGRAVITY_ENDPOINT_FALLBACKS, ANTIGRAVITY_HEADERS, getModelFamily } from '../constants.js';
|
import {
|
||||||
|
ANTIGRAVITY_ENDPOINT_FALLBACKS,
|
||||||
|
ANTIGRAVITY_HEADERS,
|
||||||
|
LOAD_CODE_ASSIST_ENDPOINTS,
|
||||||
|
LOAD_CODE_ASSIST_HEADERS,
|
||||||
|
getModelFamily
|
||||||
|
} from '../constants.js';
|
||||||
import { logger } from '../utils/logger.js';
|
import { logger } from '../utils/logger.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -122,10 +128,10 @@ export async function getSubscriptionTier(token) {
|
|||||||
const headers = {
|
const headers = {
|
||||||
'Authorization': `Bearer ${token}`,
|
'Authorization': `Bearer ${token}`,
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
...ANTIGRAVITY_HEADERS
|
...LOAD_CODE_ASSIST_HEADERS
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const endpoint of ANTIGRAVITY_ENDPOINT_FALLBACKS) {
|
for (const endpoint of LOAD_CODE_ASSIST_ENDPOINTS) {
|
||||||
try {
|
try {
|
||||||
const url = `${endpoint}/v1internal:loadCodeAssist`;
|
const url = `${endpoint}/v1internal:loadCodeAssist`;
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
@@ -135,7 +141,8 @@ export async function getSubscriptionTier(token) {
|
|||||||
metadata: {
|
metadata: {
|
||||||
ideType: 'IDE_UNSPECIFIED',
|
ideType: 'IDE_UNSPECIFIED',
|
||||||
platform: 'PLATFORM_UNSPECIFIED',
|
platform: 'PLATFORM_UNSPECIFIED',
|
||||||
pluginType: 'GEMINI'
|
pluginType: 'GEMINI',
|
||||||
|
duetProject: 'rising-fact-p41fc'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -57,6 +57,25 @@ export const ANTIGRAVITY_HEADERS = {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Endpoint order for loadCodeAssist (prod first)
|
||||||
|
// loadCodeAssist works better on prod for fresh/unprovisioned accounts
|
||||||
|
export const LOAD_CODE_ASSIST_ENDPOINTS = [
|
||||||
|
ANTIGRAVITY_ENDPOINT_PROD,
|
||||||
|
ANTIGRAVITY_ENDPOINT_DAILY
|
||||||
|
];
|
||||||
|
|
||||||
|
// Hybrid headers specifically for loadCodeAssist
|
||||||
|
// Uses google-api-nodejs-client User-Agent (required for project discovery on some accounts)
|
||||||
|
export const LOAD_CODE_ASSIST_HEADERS = {
|
||||||
|
'User-Agent': 'google-api-nodejs-client/9.15.1',
|
||||||
|
'X-Goog-Api-Client': 'google-cloud-sdk vscode_cloudshelleditor/0.1',
|
||||||
|
'Client-Metadata': JSON.stringify({
|
||||||
|
ideType: 'IDE_UNSPECIFIED',
|
||||||
|
platform: 'PLATFORM_UNSPECIFIED',
|
||||||
|
pluginType: 'GEMINI'
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
// Default project ID if none can be discovered
|
// Default project ID if none can be discovered
|
||||||
export const DEFAULT_PROJECT_ID = 'rising-fact-p41fc';
|
export const DEFAULT_PROJECT_ID = 'rising-fact-p41fc';
|
||||||
|
|
||||||
@@ -171,6 +190,8 @@ export const MODEL_FALLBACK_MAP = {
|
|||||||
export default {
|
export default {
|
||||||
ANTIGRAVITY_ENDPOINT_FALLBACKS,
|
ANTIGRAVITY_ENDPOINT_FALLBACKS,
|
||||||
ANTIGRAVITY_HEADERS,
|
ANTIGRAVITY_HEADERS,
|
||||||
|
LOAD_CODE_ASSIST_ENDPOINTS,
|
||||||
|
LOAD_CODE_ASSIST_HEADERS,
|
||||||
DEFAULT_PROJECT_ID,
|
DEFAULT_PROJECT_ID,
|
||||||
TOKEN_REFRESH_INTERVAL_MS,
|
TOKEN_REFRESH_INTERVAL_MS,
|
||||||
REQUEST_BODY_LIMIT,
|
REQUEST_BODY_LIMIT,
|
||||||
|
|||||||
Reference in New Issue
Block a user