Merge pull request #770 from zhefox/main

fix(pool): show Antigravity quota reset times
This commit is contained in:
ZheFox
2026-09-01 12:09:41 +08:00
committed by GitHub
6 changed files with 44 additions and 15 deletions
@@ -443,7 +443,18 @@ fn provider_quota_metadata_bucket<'a>(
fn provider_quota_timestamp_unix_secs(value: Option<&Value>) -> Option<u64> {
let mut parsed = match value {
Some(Value::Number(number)) => number.as_f64(),
Some(Value::String(text)) => text.trim().parse::<f64>().ok(),
Some(Value::String(text)) => {
let text = text.trim();
if let Ok(timestamp) = text.parse::<f64>() {
Some(timestamp)
} else {
return chrono::DateTime::parse_from_rfc3339(text)
.ok()?
.timestamp()
.try_into()
.ok();
}
}
_ => None,
}?;
if !parsed.is_finite() || parsed <= 0.0 {
@@ -560,7 +571,10 @@ fn model_quota_window_snapshot(
.map(|value| value.clamp(0.0, 1.0))
.or_else(|| used_ratio.map(|value| (1.0 - value).max(0.0)));
let reset_at = provider_quota_timestamp_unix_secs(
item.get("reset_at").or_else(|| item.get("next_reset_at")),
item.get("reset_at")
.or_else(|| item.get("next_reset_at"))
.or_else(|| item.get("reset_time"))
.or_else(|| item.get("next_reset_time")),
);
let reset_seconds = quota_window_reset_seconds(observed_at_unix_secs, reset_at);
let is_exhausted = item
@@ -4083,7 +4097,8 @@ mod tests {
},
"claude-sonnet-4-6": {
"display_name": "Claude Sonnet 4.6 (Thinking)",
"remaining_fraction": 0.3
"remaining_fraction": 0.3,
"reset_time": "2026-04-07T12:34:56Z"
}
}
}
@@ -4128,6 +4143,16 @@ mod tests {
label_for_model("claude-sonnet-4-6"),
Some(json!("Claude Sonnet 4.6 (Thinking)"))
);
let claude_window = windows
.iter()
.filter_map(Value::as_object)
.find(|window| window.get("model") == Some(&json!("claude-sonnet-4-6")))
.expect("Claude quota window should exist");
assert_eq!(
claude_window.get("reset_at"),
Some(&json!(1_775_565_296u64))
);
assert_eq!(claude_window.get("reset_seconds"), Some(&json!(12_011u64)));
}
#[test]
@@ -6753,6 +6753,10 @@ mod tests {
["display_name"],
json!("Key-1")
);
assert_eq!(
parsed["models"]["RateLimitResetCredit_05cbb6eeeb9c81918e011d8300f9ebfb"]["reset_time"],
json!("2030-01-01T00:00:00Z")
);
assert_eq!(
parsed["models"]["gemini-3-pro-preview"]["display_name"],
json!("Gemini 3 Pro Preview")
@@ -99,7 +99,7 @@ describe('pool key display panels', () => {
label: 'Gemini额度',
remainingPercent: 90.6,
resetText: '1h 后重置',
meterText: '90.6100',
meterText: '90.6%100%',
barClass: 'bg-emerald-500',
meterClass: 'text-emerald-600',
},
@@ -107,7 +107,7 @@ describe('pool key display panels', () => {
label: 'Claude额度',
remainingPercent: 100,
resetText: '1h 后重置',
meterText: '100',
meterText: '100%',
barClass: 'bg-emerald-500',
meterClass: 'text-emerald-600',
},
@@ -121,8 +121,12 @@ describe('pool key display panels', () => {
'Gemini额度',
'Claude额度',
])
expect(Array.from(root.querySelectorAll('[data-testid="pool-quota-meter-text"]')).map(node => node.textContent)).toEqual(['90.6100', '100'])
expect(Array.from(root.querySelectorAll('[data-testid="pool-quota-meter-text"]')).map(node => node.textContent)).toEqual(['90.6%100%', '100%'])
expect(root.querySelectorAll('[data-testid="pool-quota-progress-track"]')).toHaveLength(2)
expect(Array.from(root.querySelectorAll('[data-testid="pool-quota-reset-text"]')).map(node => node.textContent)).toEqual([
'1h 后重置',
'1h 后重置',
])
app.unmount()
root.remove()
@@ -15,9 +15,10 @@ describe('summarizeAntigravityQuotaItems', () => {
])
expect(items.map(item => [item.label, item.remainingPercent, item.detail])).toEqual([
['Gemini额度', 90.6, '90.695'],
['Claude额度', 82, '82100'],
['Gemini额度', 90.6, '90.6%95%'],
['Claude额度', 82, '82%100%'],
])
expect(items.map(item => item.resetSeconds)).toEqual([180, 120])
expect(items[1]?.model).toBe('claude-sonnet-4-6')
})
})
@@ -158,5 +158,6 @@ export function summarizeAntigravityQuotaItems<T extends AntigravityQuotaSortabl
function formatAntigravityQuotaValue(value: number): string {
const rounded = Math.round(value)
return Math.abs(value - rounded) < 1e-6 ? String(rounded) : value.toFixed(1)
const formatted = Math.abs(value - rounded) < 1e-6 ? String(rounded) : value.toFixed(1)
return `${formatted}%`
}
@@ -3883,12 +3883,6 @@ function buildQuotaProgressItemsFromSnapshot(key: PoolKeyDetail): QuotaProgressI
}
})
.filter((item): item is QuotaProgressItem & { model: string, resetSeconds: number | null } => item != null)))
.map(item => ({
...item,
resetAtSeconds: null,
resetSeconds: null,
allowDynamicReset: false,
}))
}
if (providerType === 'gemini_cli') {