fix token cost (#579)

This commit is contained in:
paisley
2026-03-18 18:39:21 +08:00
committed by GitHub
Unverified
parent dbc9972fb8
commit f9164b3d15

View File

@@ -37,9 +37,18 @@ export function Models() {
const [usageWindow, setUsageWindow] = useState<UsageWindow>('7d'); const [usageWindow, setUsageWindow] = useState<UsageWindow>('7d');
const [usagePage, setUsagePage] = useState(1); const [usagePage, setUsagePage] = useState(1);
const [selectedUsageEntry, setSelectedUsageEntry] = useState<UsageHistoryEntry | null>(null); const [selectedUsageEntry, setSelectedUsageEntry] = useState<UsageHistoryEntry | null>(null);
const [usageFetchDoneKey, setUsageFetchDoneKey] = useState<string | null>(null);
const usageFetchTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null); const usageFetchTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const usageFetchGenerationRef = useRef(0); const usageFetchGenerationRef = useRef(0);
// Stable key derived from the effect's dependencies — changes whenever a new
// fetch cycle should start. Comparing this to `usageFetchDoneKey` lets us
// derive the loading state without calling setState in the effect body or
// reading refs during render.
const usageFetchKey = isGatewayRunning
? `${gatewayStatus.pid ?? 'na'}:${gatewayStatus.connectedAt ?? 'na'}:${usageFetchMaxAttempts}`
: null;
useEffect(() => { useEffect(() => {
trackUiEvent('models.page_viewed'); trackUiEvent('models.page_viewed');
}, []); }, []);
@@ -50,8 +59,11 @@ export function Models() {
usageFetchTimerRef.current = null; usageFetchTimerRef.current = null;
} }
if (!isGatewayRunning) return; if (!isGatewayRunning) {
return;
}
const fetchKey = `${gatewayStatus.pid ?? 'na'}:${gatewayStatus.connectedAt ?? 'na'}:${usageFetchMaxAttempts}`;
const generation = usageFetchGenerationRef.current + 1; const generation = usageFetchGenerationRef.current + 1;
usageFetchGenerationRef.current = generation; usageFetchGenerationRef.current = generation;
const restartMarker = `${gatewayStatus.pid ?? 'na'}:${gatewayStatus.connectedAt ?? 'na'}`; const restartMarker = `${gatewayStatus.pid ?? 'na'}:${gatewayStatus.connectedAt ?? 'na'}`;
@@ -90,7 +102,8 @@ export function Models() {
usageFetchTimerRef.current = setTimeout(() => { usageFetchTimerRef.current = setTimeout(() => {
void fetchUsageHistoryWithRetry(attempt + 1); void fetchUsageHistoryWithRetry(attempt + 1);
}, USAGE_FETCH_RETRY_DELAY_MS); }, USAGE_FETCH_RETRY_DELAY_MS);
} else if (normalized.length === 0) { } else {
if (normalized.length === 0) {
trackUiEvent('models.token_usage_fetch_exhausted', { trackUiEvent('models.token_usage_fetch_exhausted', {
generation, generation,
attempt, attempt,
@@ -98,6 +111,8 @@ export function Models() {
restartMarker, restartMarker,
}); });
} }
setUsageFetchDoneKey(fetchKey);
}
} catch (error) { } catch (error) {
if (usageFetchGenerationRef.current !== generation) return; if (usageFetchGenerationRef.current !== generation) return;
trackUiEvent('models.token_usage_fetch_failed_attempt', { trackUiEvent('models.token_usage_fetch_failed_attempt', {
@@ -119,6 +134,7 @@ export function Models() {
return; return;
} }
setUsageHistory([]); setUsageHistory([]);
setUsageFetchDoneKey(fetchKey);
trackUiEvent('models.token_usage_fetch_exhausted', { trackUiEvent('models.token_usage_fetch_exhausted', {
generation, generation,
attempt, attempt,
@@ -145,7 +161,7 @@ export function Models() {
const usageTotalPages = Math.max(1, Math.ceil(filteredUsageHistory.length / usagePageSize)); const usageTotalPages = Math.max(1, Math.ceil(filteredUsageHistory.length / usagePageSize));
const safeUsagePage = Math.min(usagePage, usageTotalPages); const safeUsagePage = Math.min(usagePage, usageTotalPages);
const pagedUsageHistory = filteredUsageHistory.slice((safeUsagePage - 1) * usagePageSize, safeUsagePage * usagePageSize); const pagedUsageHistory = filteredUsageHistory.slice((safeUsagePage - 1) * usagePageSize, safeUsagePage * usagePageSize);
const usageLoading = isGatewayRunning && visibleUsageHistory.length === 0; const usageLoading = isGatewayRunning && usageFetchDoneKey !== usageFetchKey;
return ( return (
<div className="flex flex-col -m-6 dark:bg-background h-[calc(100vh-2.5rem)] overflow-hidden"> <div className="flex flex-col -m-6 dark:bg-background h-[calc(100vh-2.5rem)] overflow-hidden">