From 3ac100d5248e49a6aaa3b7efa6c1fd9d3dd14571 Mon Sep 17 00:00:00 2001 From: Ali Shaikh Date: Thu, 17 Sep 2026 20:06:19 +0700 Subject: [PATCH] fix(usage): improve DeepSeek credit balance display Display DeepSeek prepaid balances as credit with currency instead of a 0/total quota bar, and mark balance items as isCreditBalance. --- open-sse/providers/registry/opencode-go.js | 2 +- open-sse/services/usage/deepseek.js | 7 ++++--- .../usage/components/ProviderLimits/QuotaTable.js | 15 +++++++++++---- .../usage/components/ProviderLimits/utils.js | 2 ++ tests/unit/deepseek-usage.test.js | 2 ++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/open-sse/providers/registry/opencode-go.js b/open-sse/providers/registry/opencode-go.js index 1d1d12c0..d65d4c15 100644 --- a/open-sse/providers/registry/opencode-go.js +++ b/open-sse/providers/registry/opencode-go.js @@ -13,7 +13,7 @@ export default { textIcon: "OC", website: "https://opencode.ai/auth", notice: { - text: "OpenCode Go subscription: $5/mo (then 0/mo). Access to Kimi, GLM, Qwen, MiMo, MiniMax models.", + text: "OpenCode Go subscription: $5/mo (then 10/mo). Access to Kimi, GLM, Qwen, MiMo, MiniMax models.", apiKeyUrl: "https://opencode.ai/auth", }, }, diff --git a/open-sse/services/usage/deepseek.js b/open-sse/services/usage/deepseek.js index cb70a40d..9d2ed2ac 100644 --- a/open-sse/services/usage/deepseek.js +++ b/open-sse/services/usage/deepseek.js @@ -91,14 +91,15 @@ export async function getDeepseekUsage(apiKey = null, proxyOptions = null) { const quotas = {}; for (const b of balances) { const total = Math.max(0, b.totalBalance); - // Credit pot: show full remaining against current balance; never set absolute - // `remaining` โ€” QuotaTable treats it as a 0โ€“100 percentage. + // Credit balance: show as "Credit: $X.XX USD" not a usage quota quotas[`Balance (${b.currency})`] = { used: 0, total, remainingPercentage: total > 0 ? 100 : 0, resetAt: null, - unlimited: total > 0, + unlimited: false, + isCreditBalance: true, + currency: b.currency, }; } diff --git a/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/QuotaTable.js b/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/QuotaTable.js index 57a7a9d2..fef34f6c 100644 --- a/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/QuotaTable.js +++ b/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/QuotaTable.js @@ -151,7 +151,10 @@ export default function QuotaTable({
{currentPageRows.map((quota) => { const isUnlimited = quota.unlimited === true; - const colors = getColorClasses(quota.remaining); + const isCreditBalance = quota.isCreditBalance === true; + const colors = isCreditBalance + ? { text: "text-blue-600 dark:text-blue-400", bg: "bg-blue-500", bgLight: "bg-blue-500/10", emoji: "๐Ÿ’ฐ" } + : getColorClasses(quota.remaining); const countdown = formatResetTime(quota.resetAt); const resetDisplay = formatResetTimeDisplay(quota.resetAt); // recurring defaults true: a missing flag means the quota @@ -175,7 +178,7 @@ export default function QuotaTable({ {/* Progress + used/total */}
- {!isUnlimited && ( + {!isUnlimited && !isCreditBalance && (
@@ -192,15 +195,19 @@ export default function QuotaTable({ title={ isUnlimited ? `${quota.used.toLocaleString()} used ยท Unlimited` + : isCreditBalance + ? `Credit balance: ${quota.total.toFixed(2)} ${quota.currency || ""}` : `${quota.used.toLocaleString()} / ${quota.total > 0 ? quota.total.toLocaleString() : "โˆž"}` } > {isUnlimited ? `${quota.used.toLocaleString()} used ยท Unlimited` + : isCreditBalance + ? `Credit: ${quota.total.toFixed(2)} ${quota.currency || ""}` : `${quota.used.toLocaleString()} / ${quota.total > 0 ? quota.total.toLocaleString() : "โˆž"}`} - - {isUnlimited ? "Unlimited" : `${quota.remaining}%`} + + {isUnlimited ? "Unlimited" : isCreditBalance ? "" : `${quota.remaining}%`}
diff --git a/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/utils.js b/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/utils.js index ad321433..377bb02d 100644 --- a/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/utils.js +++ b/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/utils.js @@ -609,6 +609,8 @@ export function parseQuotaData(provider, data) { total: quota.total || 0, resetAt: quota.resetAt || null, remainingPercentage: quota.remainingPercentage, + isCreditBalance: quota.isCreditBalance ?? true, + currency: quota.currency || (name.includes("(") ? name.slice(name.indexOf("(") + 1, name.indexOf(")")) : "USD"), }); }); } diff --git a/tests/unit/deepseek-usage.test.js b/tests/unit/deepseek-usage.test.js index 0be26edc..d9048b09 100644 --- a/tests/unit/deepseek-usage.test.js +++ b/tests/unit/deepseek-usage.test.js @@ -80,6 +80,8 @@ describe("getUsageForProvider(deepseek)", () => { used: 0, total: 12.5, remainingPercentage: 100, + isCreditBalance: true, + currency: "USD", }); expect(usage.quotas["Balance (USD)"].remaining).toBeUndefined(); // Zero CNY still listed so user sees currency row