fix(usage): correct MiniMax token plan quota display (#1642)

Integrated into release/v3.7.1 — fixes inverted MiniMax quota display for token_plan/remains endpoint and rounds floating-point percentages.
This commit is contained in:
Slavic Kozyuk
2026-04-26 21:57:55 -05:00
committed by GitHub
parent acf6ad4ba0
commit 4eef082cf3
3 changed files with 63 additions and 9 deletions

View File

@@ -206,6 +206,16 @@ function pickMiniMaxRepresentativeModel(
return pool.reduce((best, current) => (getTotal(current) > getTotal(best) ? current : best));
}
function createMiniMaxQuotaFromCount(
total: number,
count: number,
resetAt: string | null,
countMeansRemaining: boolean
): UsageQuota {
const used = countMeansRemaining ? Math.max(total - count, 0) : count;
return createQuotaFromUsage(used, total, resetAt);
}
function getMiniMaxAuthErrorMessage(message: string): string {
const normalized = message.toLowerCase();
if (
@@ -319,11 +329,12 @@ async function getMiniMaxUsage(apiKey: string, provider: "minimax" | "minimax-cn
return { message: "MiniMax connected. No text quota data was returned." };
}
const countMeansRemaining = usageUrl.includes("/coding_plan/remains");
const quotas: Record<string, UsageQuota> = {};
const sessionModel = pickMiniMaxRepresentativeModel(textModels, getMiniMaxSessionTotal);
if (sessionModel) {
const total = getMiniMaxSessionTotal(sessionModel);
const remain = Math.max(
const count = Math.max(
0,
toNumber(
getFieldValue(
@@ -334,9 +345,9 @@ async function getMiniMaxUsage(apiKey: string, provider: "minimax" | "minimax-cn
0
)
);
quotas["session (5h)"] = createQuotaFromUsage(
Math.max(total - remain, 0),
quotas["session (5h)"] = createMiniMaxQuotaFromCount(
total,
count,
getMiniMaxQuotaResetAt(
sessionModel,
capturedAtMs,
@@ -344,23 +355,24 @@ async function getMiniMaxUsage(apiKey: string, provider: "minimax" | "minimax-cn
"remainsTime",
"end_time",
"endTime"
)
),
countMeansRemaining
);
}
const weeklyModel = pickMiniMaxRepresentativeModel(textModels, getMiniMaxWeeklyTotal);
if (weeklyModel && getMiniMaxWeeklyTotal(weeklyModel) > 0) {
const total = getMiniMaxWeeklyTotal(weeklyModel);
const remain = Math.max(
const count = Math.max(
0,
toNumber(
getFieldValue(weeklyModel, "current_weekly_usage_count", "currentWeeklyUsageCount"),
0
)
);
quotas["weekly (7d)"] = createQuotaFromUsage(
Math.max(total - remain, 0),
quotas["weekly (7d)"] = createMiniMaxQuotaFromCount(
total,
count,
getMiniMaxQuotaResetAt(
weeklyModel,
capturedAtMs,
@@ -368,7 +380,8 @@ async function getMiniMaxUsage(apiKey: string, provider: "minimax" | "minimax-cn
"weeklyRemainsTime",
"weekly_end_time",
"weeklyEndTime"
)
),
countMeansRemaining
);
}

View File

@@ -611,9 +611,10 @@ export default function ProviderLimits() {
<div className="text-xs text-text-muted italic">{quota.message}</div>
) : quota?.quotas?.length > 0 ? (
quota.quotas.map((q, i) => {
const remainingPercentage = q.unlimited
const remainingPercentageRaw = q.unlimited
? 100
: (q.remainingPercentage ?? calculatePercentage(q.used, q.total));
const remainingPercentage = Math.round(remainingPercentageRaw);
const colors = getBarColor(remainingPercentage);
const cd = formatCountdown(q.resetAt);
const shortName = formatQuotaLabel(q.name);

View File

@@ -945,6 +945,46 @@ test("usage service covers MiniMax usage parsing, documented endpoint fallback a
assert.match(invalid.message, /Token Plan API key/i);
});
test("usage service treats MiniMax token-plan counts as used usage", async () => {
const beforeCall = Date.now();
globalThis.fetch = async (url, init = {}) => {
assert.equal(String(url), "https://www.minimax.io/v1/token_plan/remains");
assert.equal((init as any).headers.Authorization, "Bearer minimax-key");
return new Response(
JSON.stringify({
base_resp: { status_code: 0, status_msg: "ok" },
model_remains: [
{
model_name: "MiniMax-M2.7",
remains_time: 300_000,
current_interval_total_count: 15000,
current_interval_usage_count: 13,
current_weekly_total_count: 150000,
current_weekly_usage_count: 66,
weekly_remains_time: 604_800_000,
},
],
}),
{ status: 200 }
);
};
const usage: any = await usageService.getUsageForProvider({
provider: "minimax",
apiKey: "minimax-key",
});
assert.equal(usage.quotas["session (5h)"].used, 13);
assert.equal(usage.quotas["session (5h)"].remaining, 14987);
assert.equal(usage.quotas["session (5h)"].remainingPercentage, 99.91333333333333);
assert.equal(usage.quotas["weekly (7d)"].used, 66);
assert.equal(usage.quotas["weekly (7d)"].remaining, 149934);
assert.equal(usage.quotas["weekly (7d)"].remainingPercentage, 99.956);
assert.ok(Date.parse(usage.quotas["session (5h)"].resetAt) >= beforeCall + 240_000);
});
test("usage service parses Cursor team quotas and clamps on-demand ratio", async () => {
const calls: any[] = [];
globalThis.fetch = async (url, init = {}) => {