// MiniMax's usage_percent / usagePercent fields report the remaining quota // as a percentage, not the consumed quota. Treat them as "remaining percent" // and invert to get usedPercent. Count-based fromCounts always takes priority. const REMAINING_PERCENT_KEYS = ["usage_percent", "usagePercent"] as const;
function deriveUsedPercent(payload: Record<string, unknown>): number | null { const total = pickNumber(payload, TOTAL_KEYS);
let used = pickNumber(payload, USED_KEYS); const remaining = pickNumber(payload, REMAINING_KEYS); if (used === undefined && remaining !== undefined && total !== undefined) {
used = total - remaining;
}
const fromCounts =
total && total > 0 && used !== undefined && Number.isFinite(used)
? clampPercent((used / total) * 100)
: null;
// Count-derived usage is more stable across provider percent field variations. if (fromCounts !== null) { return fromCounts;
}
// usage_percent / usagePercent in MiniMax's API represents remaining quota, // not consumed quota. Invert to get usedPercent. const remainingPercentRaw = pickNumber(payload, REMAINING_PERCENT_KEYS); if (remainingPercentRaw !== undefined) { const remainingNormalized = clampPercent(
remainingPercentRaw <= 1 ? remainingPercentRaw * 100 : remainingPercentRaw,
); return clampPercent(100 - remainingNormalized);
}
returnnull;
}
// Prefer the entry whose model_name matches a chat/text model (e.g. "MiniMax-M*") // and that has a non-zero current_interval_total_count. Models with total_count === 0 // (speech, video, image) are not relevant to the coding-plan budget. function pickChatModelRemains(modelRemains: unknown[]): Record<string, unknown> | undefined { const records = modelRemains.filter(isRecord); if (records.length === 0) { return undefined;
}
const chatRecord = records.find((r) => { const name = typeof r.model_name === "string" ? r.model_name : ""; const total = parseFiniteNumber(r.current_interval_total_count); return (
normalizeLowercaseStringOrEmpty(name).startsWith("minimax-m") &&
total !== undefined &&
total > 0
);
});
if (chatRecord) { return chatRecord;
}
return records.find((r) => { const total = parseFiniteNumber(r.current_interval_total_count); return total !== undefined && total > 0;
});
}
// Handle the model_remains array structure returned by the coding-plan // endpoint. Pick the chat-model entry so that speech/video/image quotas // (which often have total_count === 0) don't shadow the relevant budget. const modelRemains = Array.isArray(payload.model_remains) ? payload.model_remains : null; const chatRemains = modelRemains ? pickChatModelRemains(modelRemains) : undefined;
const usageSource = chatRemains ?? payload; const candidates = collectUsageCandidates(usageSource);
let usageRecord: Record<string, unknown> = usageSource;
let usedPercent: number | null = null; for (const candidate of candidates) { const candidatePercent = deriveUsedPercent(candidate); if (candidatePercent !== null) {
usageRecord = candidate;
usedPercent = candidatePercent; break;
}
} if (usedPercent === null) {
usedPercent = deriveUsedPercent(usageSource);
} if (usedPercent === null) { return {
provider: "minimax",
displayName: PROVIDER_LABELS.minimax,
windows: [],
error: "Unsupported response shape",
};
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.