Skip to content

Commit d37f4c0

Browse files
committed
feat: update monitor data & quato list
1 parent 1a63fcd commit d37f4c0

3 files changed

Lines changed: 231 additions & 112 deletions

File tree

packages/commands/src/commands/quota/check.ts

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import {
44
detectOutputFormat,
55
type Client,
66
} from "bailian-cli-core";
7-
import { ansi, emitResult } from "bailian-cli-runtime";
8-
import { displayWidth, padEnd } from "bailian-cli-runtime";
7+
import { ansi, emitResult, renderBoxTable } from "bailian-cli-runtime";
98

109
const MODEL_LIST_API = "zeldaHttp.dashscopeModel./zelda/api/v1/modelCenter/listFoundationModels";
1110
const MONITOR_API = "zeldaEasy.bailian-telemetry.monitor.getMonitorData";
@@ -49,24 +48,6 @@ function calculateTPM(item: QpmInfoItem | undefined, fallbackPeriod?: number): n
4948
return Math.floor((item.usage_limit * 60) / period);
5049
}
5150

52-
function formatNumber(num: number): string {
53-
return num.toLocaleString("en-US");
54-
}
55-
56-
function formatRatio(usage: number, limit: number): string {
57-
if (limit <= 0) return "-";
58-
const pct = Math.round((usage / limit) * 100);
59-
return `${formatNumber(usage)}/${formatNumber(limit)} (${pct}%)`;
60-
}
61-
62-
function getStatus(usage: number, limit: number): string {
63-
if (limit <= 0) return "-";
64-
const pct = (usage / limit) * 100;
65-
if (pct >= 100) return "Rate Limited";
66-
if (pct >= 80) return "Near limit";
67-
return "Normal";
68-
}
69-
7051
function getNestedRecord(
7152
obj: Record<string, unknown>,
7253
key: string,
@@ -157,7 +138,11 @@ async function fetchMonitorData(
157138
}
158139

159140
return { rpm, tpm };
160-
} catch {
141+
} catch (error) {
142+
// Re-throw console authentication errors, but catch other errors
143+
if (error instanceof Error && error.message?.includes("Console session")) {
144+
throw error;
145+
}
161146
return { rpm: -1, tpm: -1 };
162147
}
163148
}
@@ -168,56 +153,59 @@ interface CheckRow {
168153
rpmLimit: number;
169154
tpmUsage: number;
170155
tpmLimit: number;
156+
rpmQuotaLeft: number | null;
157+
tpmQuotaLeft: number | null;
158+
rpmQuotaLabel: string | null;
159+
tpmQuotaLabel: string | null;
171160
}
172161

173162
function printTable(rows: CheckRow[]): void {
174163
const color = ansi(process.stdout);
164+
const headers = ["Model", "RPM Used/Limit", "TPM Used/Limit", "Status", "RPM Left", "TPM Left"];
175165

176-
const headers = ["Model", "RPM Usage/Limit", "TPM Usage/Limit", "Status"];
166+
const rpmPercents = rows.map((r) => r.rpmQuotaLeft);
167+
const rpmLabels = rows.map((r) => r.rpmQuotaLabel);
168+
const tpmPercents = rows.map((r) => r.tpmQuotaLeft);
169+
const tpmLabels = rows.map((r) => r.tpmQuotaLabel);
177170

178171
const tableRows = rows.map((r) => {
179-
const rpmStr = r.rpmUsage < 0 ? "-" : formatRatio(r.rpmUsage, r.rpmLimit);
180-
const tpmStr = r.tpmUsage < 0 ? "-" : formatRatio(r.tpmUsage, r.tpmLimit);
172+
const rpmStr = r.rpmUsage < 0 ? "-" : `${r.rpmUsage}/${r.rpmLimit}`;
173+
const tpmStr = r.tpmUsage < 0 ? "-" : `${r.tpmUsage}/${r.tpmLimit}`;
181174
const maxPct = Math.max(
182175
r.rpmLimit > 0 ? (r.rpmUsage / r.rpmLimit) * 100 : 0,
183176
r.tpmLimit > 0 ? (r.tpmUsage / r.tpmLimit) * 100 : 0,
184177
);
185178
const status =
186179
r.rpmUsage < 0
187180
? "-"
188-
: getStatus(Math.max(r.rpmUsage, r.tpmUsage), Math.max(r.rpmLimit, r.tpmLimit));
189-
return { cells: [r.model, rpmStr, tpmStr, status], maxPct };
181+
: maxPct >= 100
182+
? "Rate Limited"
183+
: maxPct >= 80
184+
? "Near limit"
185+
: "Normal";
186+
return [r.model, rpmStr, tpmStr, status, "", ""];
190187
});
191188

192-
if (tableRows.length === 0) {
193-
process.stdout.write("No models found.\n");
194-
return;
195-
}
196-
197-
const widths = headers.map((label, col) =>
198-
Math.max(displayWidth(label), ...tableRows.map((r) => displayWidth(r.cells[col]))),
199-
);
200-
201-
const headerLine = headers.map((label, col) => color.bold(padEnd(label, widths[col]))).join(" ");
202-
const separator = widths.map((w) => color.dim("─".repeat(w))).join("──");
203-
204-
process.stdout.write(headerLine + "\n");
205-
process.stdout.write(separator + "\n");
206-
207-
const statusCol = 3;
208-
for (const r of tableRows) {
209-
const cells = r.cells.map((cell, col) => {
210-
if (col === statusCol) {
211-
if (cell === "Rate Limited") return color.red(padEnd(cell, widths[col]));
212-
if (cell === "Near limit") return color.yellow(padEnd(cell, widths[col]));
213-
if (cell === "Normal") return color.green(padEnd(cell, widths[col]));
189+
const lines = renderBoxTable({
190+
headers,
191+
rows: tableRows,
192+
align: ["left", "right", "right", "left", "left", "left"],
193+
barColumns: [
194+
{ index: 4, percents: rpmPercents, labels: rpmLabels, width: 15 },
195+
{ index: 5, percents: tpmPercents, labels: tpmLabels, width: 15 },
196+
],
197+
cellColor: (rowIndex, colIndex, value) => {
198+
if (colIndex === 3) {
199+
// Status 列着色
200+
if (value === "Rate Limited") return color.red(value);
201+
if (value === "Near limit") return color.yellow(value);
202+
if (value === "Normal") return color.green(value);
214203
}
215-
return padEnd(cell, widths[col]);
216-
});
217-
process.stdout.write(cells.join(" ") + "\n");
218-
}
204+
return undefined;
205+
},
206+
});
219207

220-
process.stdout.write(color.dim(`\nTotal: ${rows.length} models`) + "\n");
208+
for (const line of lines) process.stdout.write(line + "\n");
221209
}
222210

223211
export default defineCommand({
@@ -295,12 +283,35 @@ export default defineCommand({
295283
const tpmLimit =
296284
calculateTPM(userSpec, modelDefault?.usage_limit_period) || calculateTPM(modelDefault);
297285

286+
const rpmUsage = monitorResults[idx].rpm;
287+
const tpmUsage = monitorResults[idx].tpm;
288+
289+
// RPM Quota Left = 1 - (rpmUsage / rpmLimit) in percentage
290+
let rpmQuotaPercent: number | null = null;
291+
let rpmQuotaLabel: string | null = null;
292+
if (rpmUsage >= 0 && rpmLimit > 0) {
293+
rpmQuotaPercent = Math.max(0, 100 - (rpmUsage / rpmLimit) * 100);
294+
rpmQuotaLabel = rpmQuotaPercent.toFixed(1) + "%";
295+
}
296+
297+
// TPM Quota Left = 1 - (tpmUsage / tpmLimit) in percentage
298+
let tpmQuotaPercent: number | null = null;
299+
let tpmQuotaLabel: string | null = null;
300+
if (tpmUsage >= 0 && tpmLimit > 0) {
301+
tpmQuotaPercent = Math.max(0, 100 - (tpmUsage / tpmLimit) * 100);
302+
tpmQuotaLabel = tpmQuotaPercent.toFixed(1) + "%";
303+
}
304+
298305
return {
299306
model: m.model,
300-
rpmUsage: monitorResults[idx].rpm,
307+
rpmUsage,
301308
rpmLimit,
302-
tpmUsage: monitorResults[idx].tpm,
309+
tpmUsage,
303310
tpmLimit,
311+
rpmQuotaLeft: rpmQuotaPercent,
312+
tpmQuotaLeft: tpmQuotaPercent,
313+
rpmQuotaLabel,
314+
tpmQuotaLabel,
304315
};
305316
});
306317

0 commit comments

Comments
 (0)