diff --git a/frontend/src/components/account/AccountUsageCell.vue b/frontend/src/components/account/AccountUsageCell.vue
index 09236edd..9c145530 100644
--- a/frontend/src/components/account/AccountUsageCell.vue
+++ b/frontend/src/components/account/AccountUsageCell.vue
@@ -75,7 +75,7 @@
-
-
-
-
-
-
@@ -389,8 +371,43 @@
-
-
+
+
+
+
+
+
+ {{ formatKeyRequests }} req
+
+
+ {{ formatKeyTokens }}
+
+
+ A ${{ formatKeyCost }}
+
+
+ U ${{ formatKeyUserCost }}
+
+
+
+
+
+
+
+
+
+
-
-
-
@@ -423,12 +442,23 @@ import { adminAPI } from '@/api/admin'
import type { Account, AccountUsageInfo, GeminiCredentials, WindowStats } from '@/types'
import { buildOpenAIUsageRefreshKey } from '@/utils/accountUsageRefresh'
import { resolveCodexUsageWindow } from '@/utils/codexUsage'
+import { formatCompactNumber } from '@/utils/format'
import UsageProgressBar from './UsageProgressBar.vue'
import AccountQuotaInfo from './AccountQuotaInfo.vue'
-const props = defineProps<{
- account: Account
-}>()
+const props = withDefaults(
+ defineProps<{
+ account: Account
+ todayStats?: WindowStats | null
+ todayStatsLoading?: boolean
+ manualRefreshToken?: number
+ }>(),
+ {
+ todayStats: null,
+ todayStatsLoading: false,
+ manualRefreshToken: 0
+ }
+)
const { t } = useI18n()
@@ -490,26 +520,9 @@ const isActiveOpenAIRateLimited = computed(() => {
return !Number.isNaN(resetAt) && resetAt > Date.now()
})
-const preferFetchedOpenAIUsage = computed(() => {
- return (isActiveOpenAIRateLimited.value || isOpenAICodexSnapshotStale.value) && hasOpenAIUsageFallback.value
-})
-
const openAIUsageRefreshKey = computed(() => buildOpenAIUsageRefreshKey(props.account))
-const isOpenAICodexSnapshotStale = computed(() => {
- if (props.account.platform !== 'openai' || props.account.type !== 'oauth') return false
- const extra = props.account.extra as Record
| undefined
- const updatedAtRaw = extra?.codex_usage_updated_at
- if (!updatedAtRaw) return true
- const updatedAt = Date.parse(String(updatedAtRaw))
- if (Number.isNaN(updatedAt)) return true
- return Date.now() - updatedAt >= 10 * 60 * 1000
-})
-
const shouldAutoLoadUsageOnMount = computed(() => {
- if (props.account.platform === 'openai' && props.account.type === 'oauth') {
- return isActiveOpenAIRateLimited.value || !hasCodexUsage.value || isOpenAICodexSnapshotStale.value
- }
return shouldFetchUsage.value
})
@@ -1006,6 +1019,28 @@ const quotaTotalBar = computed((): QuotaBarInfo | null => {
return makeQuotaBar(props.account.quota_used ?? 0, limit)
})
+// ===== Key account today stats formatters =====
+
+const formatKeyRequests = computed(() => {
+ if (!props.todayStats) return ''
+ return formatCompactNumber(props.todayStats.requests, { allowBillions: false })
+})
+
+const formatKeyTokens = computed(() => {
+ if (!props.todayStats) return ''
+ return formatCompactNumber(props.todayStats.tokens)
+})
+
+const formatKeyCost = computed(() => {
+ if (!props.todayStats) return '0.00'
+ return props.todayStats.cost.toFixed(2)
+})
+
+const formatKeyUserCost = computed(() => {
+ if (!props.todayStats || props.todayStats.user_cost == null) return '0.00'
+ return props.todayStats.user_cost.toFixed(2)
+})
+
onMounted(() => {
if (!shouldAutoLoadUsageOnMount.value) return
loadUsage()
@@ -1014,10 +1049,21 @@ onMounted(() => {
watch(openAIUsageRefreshKey, (nextKey, prevKey) => {
if (!prevKey || nextKey === prevKey) return
if (props.account.platform !== 'openai' || props.account.type !== 'oauth') return
- if (!isActiveOpenAIRateLimited.value && hasCodexUsage.value && !isOpenAICodexSnapshotStale.value) return
loadUsage().catch((e) => {
console.error('Failed to refresh OpenAI usage:', e)
})
})
+
+watch(
+ () => props.manualRefreshToken,
+ (nextToken, prevToken) => {
+ if (nextToken === prevToken) return
+ if (!shouldFetchUsage.value) return
+
+ loadUsage().catch((e) => {
+ console.error('Failed to refresh usage after manual refresh:', e)
+ })
+ }
+)
diff --git a/frontend/src/components/account/UsageProgressBar.vue b/frontend/src/components/account/UsageProgressBar.vue
index cd5c991f..5ce8bfe0 100644
--- a/frontend/src/components/account/UsageProgressBar.vue
+++ b/frontend/src/components/account/UsageProgressBar.vue
@@ -2,7 +2,7 @@
@@ -12,12 +12,13 @@
{{ formatTokens }}
-
+
A ${{ formatAccountCost }}
U ${{ formatUserCost }}
@@ -56,7 +57,9 @@