fix(quota): stop showing misleading OpenRouter percentages (#1127)
* fix(quota): stop showing misleading OpenRouter percentages Fixes #1085 * fix(quota): clean up OpenRouter credit labels --------- Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Bohdan Triapitsyn
parent
b65edc3436
commit
3fbcdbc3dc
@@ -39,7 +39,7 @@ import { cn, hasModifier } from '@/lib/utils';
|
||||
import { McpDropdownContent } from '@/components/mcp/McpDropdown';
|
||||
import { McpIcon } from '@/components/icons/McpIcon';
|
||||
import { ProviderLogo } from '@/components/ui/ProviderLogo';
|
||||
import { formatPercent, formatWindowLabel, QUOTA_PROVIDERS, calculatePace, calculateExpectedUsagePercent } from '@/lib/quota';
|
||||
import { formatQuotaValueLabel, formatWindowLabel, QUOTA_PROVIDERS, calculatePace, calculateExpectedUsagePercent } from '@/lib/quota';
|
||||
import { UsageProgressBar } from '@/components/sections/usage/UsageProgressBar';
|
||||
import { PaceIndicator } from '@/components/sections/usage/PaceIndicator';
|
||||
import { updateDesktopSettings } from '@/lib/persistence';
|
||||
@@ -446,6 +446,7 @@ const DesktopServicesMenu = React.memo(function DesktopServicesMenu({
|
||||
? 100 - calculateExpectedUsagePercent(paceInfo.elapsedRatio)
|
||||
: calculateExpectedUsagePercent(paceInfo.elapsedRatio))
|
||||
: null;
|
||||
const metricLabel = formatQuotaValueLabel(window.valueLabel, displayPercent);
|
||||
return (
|
||||
<div key={`${group.providerId}-${label}`} className="flex flex-col gap-1.5">
|
||||
<div className="flex min-w-0 items-center justify-between gap-3">
|
||||
@@ -458,7 +459,7 @@ const DesktopServicesMenu = React.memo(function DesktopServicesMenu({
|
||||
) : null}
|
||||
</div>
|
||||
<span className="typography-ui-label tabular-nums text-foreground">
|
||||
{formatPercent(displayPercent) === '-' ? '' : formatPercent(displayPercent)}
|
||||
{metricLabel === '-' ? '' : metricLabel}
|
||||
</span>
|
||||
</div>
|
||||
<UsageProgressBar
|
||||
@@ -496,12 +497,13 @@ const DesktopServicesMenu = React.memo(function DesktopServicesMenu({
|
||||
? 100 - calculateExpectedUsagePercent(paceInfo.elapsedRatio)
|
||||
: calculateExpectedUsagePercent(paceInfo.elapsedRatio))
|
||||
: null;
|
||||
const metricLabel = formatQuotaValueLabel(window.valueLabel, displayPercent);
|
||||
return (
|
||||
<div key={`${group.providerId}-${modelName}`} className="flex flex-col gap-1.5">
|
||||
<div className="flex min-w-0 items-center justify-between gap-3">
|
||||
<span className="truncate typography-micro text-muted-foreground">{getDisplayModelName(modelName)}</span>
|
||||
<span className="typography-ui-label tabular-nums text-foreground">
|
||||
{formatPercent(displayPercent) === '-' ? '' : formatPercent(displayPercent)}
|
||||
{metricLabel === '-' ? '' : metricLabel}
|
||||
</span>
|
||||
</div>
|
||||
<UsageProgressBar
|
||||
@@ -2194,6 +2196,7 @@ export const Header: React.FC<HeaderProps> = ({
|
||||
? 100 - calculateExpectedUsagePercent(paceInfo.elapsedRatio)
|
||||
: calculateExpectedUsagePercent(paceInfo.elapsedRatio))
|
||||
: null;
|
||||
const metricLabel = formatQuotaValueLabel(window.valueLabel, displayPercent);
|
||||
return (
|
||||
<div key={`${group.providerId}-${label}`} className="flex flex-col gap-1.5">
|
||||
<div className="flex min-w-0 items-center justify-between gap-3">
|
||||
@@ -2206,7 +2209,7 @@ export const Header: React.FC<HeaderProps> = ({
|
||||
) : null}
|
||||
</div>
|
||||
<span className="typography-ui-label text-foreground tabular-nums">
|
||||
{formatPercent(displayPercent) === '-' ? '' : formatPercent(displayPercent)}
|
||||
{metricLabel === '-' ? '' : metricLabel}
|
||||
</span>
|
||||
</div>
|
||||
<UsageProgressBar
|
||||
@@ -2257,12 +2260,13 @@ export const Header: React.FC<HeaderProps> = ({
|
||||
? 100 - calculateExpectedUsagePercent(paceInfo.elapsedRatio)
|
||||
: calculateExpectedUsagePercent(paceInfo.elapsedRatio))
|
||||
: null;
|
||||
const metricLabel = formatQuotaValueLabel(window.valueLabel, displayPercent);
|
||||
return (
|
||||
<div key={`${group.providerId}-${modelName}`} className="flex flex-col gap-1.5">
|
||||
<div className="flex min-w-0 items-center justify-between gap-3">
|
||||
<span className="truncate typography-micro text-muted-foreground">{getDisplayModelName(modelName)}</span>
|
||||
<span className="typography-ui-label text-foreground tabular-nums">
|
||||
{formatPercent(displayPercent) === '-' ? '' : formatPercent(displayPercent)}
|
||||
{metricLabel === '-' ? '' : metricLabel}
|
||||
</span>
|
||||
</div>
|
||||
<UsageProgressBar
|
||||
|
||||
@@ -22,7 +22,7 @@ import { useI18n } from '@/lib/i18n';
|
||||
import { ProviderLogo } from '@/components/ui/ProviderLogo';
|
||||
import { UsageProgressBar } from '@/components/sections/usage/UsageProgressBar';
|
||||
import { PaceIndicator } from '@/components/sections/usage/PaceIndicator';
|
||||
import { formatPercent, formatWindowLabel, QUOTA_PROVIDERS, calculatePace, calculateExpectedUsagePercent } from '@/lib/quota';
|
||||
import { formatQuotaValueLabel, formatWindowLabel, QUOTA_PROVIDERS, calculatePace, calculateExpectedUsagePercent } from '@/lib/quota';
|
||||
import { useQuotaAutoRefresh, useQuotaStore } from '@/stores/useQuotaStore';
|
||||
import { useUpdateStore } from '@/stores/useUpdateStore';
|
||||
import { updateDesktopSettings } from '@/lib/persistence';
|
||||
@@ -823,6 +823,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
|
||||
? 100 - calculateExpectedUsagePercent(paceInfo.elapsedRatio)
|
||||
: calculateExpectedUsagePercent(paceInfo.elapsedRatio))
|
||||
: null;
|
||||
const metricLabel = formatQuotaValueLabel(window.valueLabel, displayPercent);
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={`${group.providerId}-${label}`}
|
||||
@@ -833,7 +834,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
|
||||
<span className="flex min-w-0 items-center justify-between gap-3">
|
||||
<span className="truncate typography-micro text-muted-foreground">{formatWindowLabel(label)}</span>
|
||||
<span className="typography-ui-label text-foreground tabular-nums">
|
||||
{formatPercent(displayPercent) === '-' ? '' : formatPercent(displayPercent)}
|
||||
{metricLabel === '-' ? '' : metricLabel}
|
||||
</span>
|
||||
</span>
|
||||
<UsageProgressBar
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { UsageWindow } from '@/types';
|
||||
import { formatPercent, formatWindowLabel, calculatePace, calculateExpectedUsagePercent } from '@/lib/quota';
|
||||
import { formatQuotaValueLabel, formatWindowLabel, calculatePace, calculateExpectedUsagePercent } from '@/lib/quota';
|
||||
import { UsageProgressBar } from './UsageProgressBar';
|
||||
import { PaceIndicator } from './PaceIndicator';
|
||||
import { useQuotaStore } from '@/stores/useQuotaStore';
|
||||
@@ -26,7 +26,7 @@ export const UsageCard: React.FC<UsageCardProps> = ({
|
||||
const displayMode = useQuotaStore((state) => state.displayMode);
|
||||
const displayPercent = displayMode === 'remaining' ? window.remainingPercent : window.usedPercent;
|
||||
const barLabel = displayMode === 'remaining' ? 'remaining' : 'used';
|
||||
const percentLabel = window.valueLabel ?? formatPercent(displayPercent);
|
||||
const percentLabel = formatQuotaValueLabel(window.valueLabel, displayPercent);
|
||||
const resetLabel = window.resetAfterFormatted ?? window.resetAtFormatted ?? '';
|
||||
const windowLabel = formatWindowLabel(title);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ export type { QuotaProviderMeta } from './providers';
|
||||
export {
|
||||
clampPercent,
|
||||
formatPercent,
|
||||
formatQuotaValueLabel,
|
||||
resolveUsageTone,
|
||||
formatWindowLabel,
|
||||
calculatePace,
|
||||
|
||||
@@ -12,6 +12,13 @@ export const formatPercent = (value: number | null): string => {
|
||||
return `${Math.round(value)}%`;
|
||||
};
|
||||
|
||||
export const formatQuotaValueLabel = (
|
||||
valueLabel: string | null | undefined,
|
||||
percent: number | null,
|
||||
): string => {
|
||||
return valueLabel ?? formatPercent(percent);
|
||||
};
|
||||
|
||||
export const resolveUsageTone = (percent: number | null): 'safe' | 'warn' | 'critical' => {
|
||||
if (percent === null) {
|
||||
return 'safe';
|
||||
|
||||
@@ -1420,10 +1420,10 @@ export const fetchOpenRouterQuota = async (): Promise<ProviderResult> => {
|
||||
const remaining = totalCredits !== null && totalUsage !== null
|
||||
? Math.max(0, totalCredits - totalUsage)
|
||||
: null;
|
||||
const usedPercent = totalCredits && totalUsage !== null
|
||||
? Math.max(0, Math.min(100, (totalUsage / totalCredits) * 100))
|
||||
: null;
|
||||
const valueLabel = remaining !== null ? `$${formatMoney(remaining)} remaining` : null;
|
||||
let valueLabel: string | null = null;
|
||||
if (remaining !== null && totalUsage !== null) {
|
||||
valueLabel = `$${formatMoney(remaining)} left · $${formatMoney(totalUsage)} spent`;
|
||||
}
|
||||
|
||||
return buildResult({
|
||||
providerId: 'openrouter',
|
||||
@@ -1433,7 +1433,7 @@ export const fetchOpenRouterQuota = async (): Promise<ProviderResult> => {
|
||||
usage: {
|
||||
windows: {
|
||||
credits: toUsageWindow({
|
||||
usedPercent,
|
||||
usedPercent: null,
|
||||
windowSeconds: null,
|
||||
resetAt: null,
|
||||
valueLabel,
|
||||
|
||||
@@ -59,14 +59,14 @@ export const fetchQuota = async () => {
|
||||
const remaining = totalCredits !== null && totalUsage !== null
|
||||
? Math.max(0, totalCredits - totalUsage)
|
||||
: null;
|
||||
const usedPercent = totalCredits && totalUsage !== null
|
||||
? Math.max(0, Math.min(100, (totalUsage / totalCredits) * 100))
|
||||
: null;
|
||||
const valueLabel = remaining !== null ? `$${formatMoney(remaining)} remaining` : null;
|
||||
let valueLabel = null;
|
||||
if (remaining !== null && totalUsage !== null) {
|
||||
valueLabel = `$${formatMoney(remaining)} left · $${formatMoney(totalUsage)} spent`;
|
||||
}
|
||||
|
||||
const windows = {
|
||||
credits: toUsageWindow({
|
||||
usedPercent,
|
||||
usedPercent: null,
|
||||
windowSeconds: null,
|
||||
resetAt: null,
|
||||
valueLabel
|
||||
|
||||
Reference in New Issue
Block a user