fix: accurate quota reporting with project ID and improved rate limit handling

- Pass project ID to fetchAvailableModels for accurate per-project quota
- Treat missing remainingFraction with resetTime as 0% (exhausted)
- Fix double-escaped regex in rate-limit-parser.js (\\d -> \d)
- Use ANTIGRAVITY_HEADERS for loadCodeAssist consistency
- Store actual reset time from API instead of capping at default
- Add getRateLimitInfo() for detailed rate limit state
- Handle disabled accounts in rate limit checks

Fixes issue where free tier accounts showed 100% quota but were actually exhausted.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Badri Narayanan S
2026-01-15 16:18:13 +05:30
parent a20cba90ee
commit 77363c679e
8 changed files with 252 additions and 163 deletions

View File

@@ -57,22 +57,26 @@ export async function listModels(token) {
* Returns model quotas including remaining fraction and reset time
*
* @param {string} token - OAuth access token
* @param {string} [projectId] - Optional project ID for accurate quota info
* @returns {Promise<Object>} Raw response from fetchAvailableModels API
*/
export async function fetchAvailableModels(token) {
export async function fetchAvailableModels(token, projectId = null) {
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
...ANTIGRAVITY_HEADERS
};
// Include project ID in body for accurate quota info (per Quotio implementation)
const body = projectId ? { project: projectId } : {};
for (const endpoint of ANTIGRAVITY_ENDPOINT_FALLBACKS) {
try {
const url = `${endpoint}/v1internal:fetchAvailableModels`;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({})
body: JSON.stringify(body)
});
if (!response.ok) {
@@ -95,10 +99,11 @@ export async function fetchAvailableModels(token) {
* Extracts quota info (remaining fraction and reset time) for each model
*
* @param {string} token - OAuth access token
* @param {string} [projectId] - Optional project ID for accurate quota info
* @returns {Promise<Object>} Map of modelId -> { remainingFraction, resetTime }
*/
export async function getModelQuotas(token) {
const data = await fetchAvailableModels(token);
export async function getModelQuotas(token, projectId = null) {
const data = await fetchAvailableModels(token, projectId);
if (!data || !data.models) return {};
const quotas = {};
@@ -108,7 +113,8 @@ export async function getModelQuotas(token) {
if (modelData.quotaInfo) {
quotas[modelId] = {
remainingFraction: modelData.quotaInfo.remainingFraction ?? null,
// When remainingFraction is missing but resetTime is present, quota is exhausted (0%)
remainingFraction: modelData.quotaInfo.remainingFraction ?? (modelData.quotaInfo.resetTime ? 0 : null),
resetTime: modelData.quotaInfo.resetTime ?? null
};
}