Always show all 3 providers, add Kimi fallback key
This commit is contained in:
114
dist/index.js
vendored
114
dist/index.js
vendored
@@ -38,6 +38,11 @@ const CONFIG = {
|
||||
apiKey: process.env.MINIMAX_API_KEY || 'sk-cp-XC8cbgbVBuv1g8mMcao0ABeZu_rGEN_S22EhBUqo4lJbY_UJVqUVO5XF8hVobp8gE_39JbgQggr00TQwNdV9vP458Y_MBC_8GstvzmwhuukEGY4a2I5_L6A',
|
||||
baseUrl: 'api.minimax.io',
|
||||
endpoint: '/v1/api/openplatform/coding_plan/remains'
|
||||
},
|
||||
kimi: {
|
||||
apiKey: process.env.KIMI_API_KEY || 'sk-kimi-dr5bfb3Gz8yOQOJVbLd2iY3kdDPf5MPBp1Ay467FlpAhvKMcTVOyiMH8zuQz1gb2',
|
||||
baseUrl: 'api.kimi.com',
|
||||
endpoint: '/coding/v1/usages'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -141,6 +146,74 @@ async function getMinimaxUsage() {
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Kimi usage
|
||||
async function getKimiUsage() {
|
||||
if (!CONFIG.kimi.apiKey) {
|
||||
return { error: 'No Kimi API key configured' };
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await makeRequest({
|
||||
hostname: CONFIG.kimi.baseUrl,
|
||||
path: CONFIG.kimi.endpoint,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${CONFIG.kimi.apiKey}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
const usage = response?.usage;
|
||||
const limits = response?.limits || [];
|
||||
|
||||
if (!usage) {
|
||||
return { pct: 0, remainingMinutes: 0, error: 'No data' };
|
||||
}
|
||||
|
||||
const pct = parseInt(usage.used) / parseInt(usage.limit) * 100;
|
||||
let remainingMinutes = 0;
|
||||
let weeklyReset = null;
|
||||
|
||||
if (usage.resetTime) {
|
||||
const resetDate = new Date(usage.resetTime);
|
||||
const now = new Date();
|
||||
remainingMinutes = (resetDate - now) / 1000 / 60;
|
||||
weeklyReset = resetDate;
|
||||
}
|
||||
|
||||
const limitInfos = [];
|
||||
for (const l of limits) {
|
||||
if (l.detail?.resetTime) {
|
||||
const resetDate = new Date(l.detail.resetTime);
|
||||
const now = new Date();
|
||||
const limitMins = (resetDate - now) / 1000 / 60;
|
||||
|
||||
if (limitMins > 0) {
|
||||
const limitUsed = parseInt(l.detail.limit) - parseInt(l.detail.remaining);
|
||||
const limitPct = limitUsed / parseInt(l.detail.limit) * 100;
|
||||
const windowDur = l.window?.duration || 0;
|
||||
const windowUnit = l.window?.timeUnit || '';
|
||||
|
||||
let label = '5h';
|
||||
if (windowUnit === 'TIME_UNIT_MINUTE' && windowDur >= 60) {
|
||||
label = `${windowDur / 60}h`;
|
||||
}
|
||||
|
||||
limitInfos.push({
|
||||
pct: limitPct,
|
||||
remainingMinutes: limitMins,
|
||||
label: label
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { pct, remainingMinutes, weeklyReset, limitInfos, error: null };
|
||||
} catch (e) {
|
||||
return { pct: 0, remainingMinutes: 0, error: e.message };
|
||||
}
|
||||
}
|
||||
|
||||
// Get color based on percentage
|
||||
function getColor(pct) {
|
||||
if (pct > 90) return colors.red;
|
||||
@@ -174,35 +247,62 @@ function formatMinimaxStatus(minimax) {
|
||||
return `${colors.purple}MiniMax${colors.reset} ${getColor(minimax.pct)}${minimax.pct.toFixed(0)}%${colors.reset}${timeStr ? ` ${timeStr}` : ''}`;
|
||||
}
|
||||
|
||||
// Format Kimi status
|
||||
function formatKimiStatus(kimi) {
|
||||
if (kimi.error) {
|
||||
return `${colors.orange}Kimi${colors.reset} ${colors.red}offline${colors.reset}`;
|
||||
}
|
||||
|
||||
let status = `${colors.orange}Kimi${colors.reset} ${getColor(kimi.pct)}${kimi.pct.toFixed(0)}%${colors.reset}`;
|
||||
|
||||
if (kimi.remainingMinutes > 0) {
|
||||
status += ` ${formatTime(kimi.remainingMinutes)}`;
|
||||
}
|
||||
|
||||
if (kimi.limitInfos && kimi.limitInfos.length > 0) {
|
||||
for (const lim of kimi.limitInfos) {
|
||||
status += ` ${colors.orange}${lim.label}${colors.reset}${getColor(lim.pct)}${lim.pct.toFixed(0)}%${colors.reset}`;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// Main function
|
||||
async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
const showJson = args.includes('--json');
|
||||
const showOnlyGlm = args.includes('--glm');
|
||||
const showOnlyMinimax = args.includes('--minimax');
|
||||
const showOnlyKimi = args.includes('--kimi');
|
||||
|
||||
try {
|
||||
const [glm, minimax] = await Promise.all([
|
||||
showOnlyMinimax ? Promise.resolve({ error: 'disabled' }) : getGlmUsage(),
|
||||
showOnlyGlm ? Promise.resolve({ error: 'disabled' }) : getMinimaxUsage()
|
||||
const [glm, minimax, kimi] = await Promise.all([
|
||||
getGlmUsage(),
|
||||
getMinimaxUsage(),
|
||||
getKimiUsage()
|
||||
]);
|
||||
|
||||
if (showJson) {
|
||||
console.log(JSON.stringify({ glm, minimax }, null, 2));
|
||||
console.log(JSON.stringify({ glm, minimax, kimi }, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
// Statusline output
|
||||
// Statusline output - always show all 3
|
||||
let parts = [];
|
||||
|
||||
if (!showOnlyMinimax && !glm.error) {
|
||||
if (!showOnlyMinimax && !showOnlyKimi) {
|
||||
parts.push(formatGlmStatus(glm));
|
||||
}
|
||||
|
||||
if (!showOnlyGlm && !minimax.error) {
|
||||
if (!showOnlyGlm && !showOnlyKimi) {
|
||||
parts.push(formatMinimaxStatus(minimax));
|
||||
}
|
||||
|
||||
if (!showOnlyGlm && !showOnlyMinimax) {
|
||||
parts.push(formatKimiStatus(kimi));
|
||||
}
|
||||
|
||||
if (parts.length === 0) {
|
||||
console.log(`${colors.red}No API configured${colors.reset}`);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user