From af95a9ec67d211148c9eea339008769f7a212794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=95=85=E7=92=83?= Date: Mon, 17 Aug 2026 20:25:56 +0800 Subject: [PATCH] fix(usage): allow disabling auto-stop regardless of quota and fix Auto-Stop column display - Remove client-side check that blocked 'freetier --off' when quota remains; align with web behavior (switch is always operable) - Prioritize stopMap ON/OFF over quotaStatus UNKNOWN in rendering - Query auto-stop status only for filtered models to avoid server-side batch limit error (TRAIN_INTERNAL_ERROR_EXP with 494 models) --- packages/commands/src/commands/usage/free.ts | 30 +++++++++++-------- .../commands/src/commands/usage/freetier.ts | 21 ++----------- .../commands/src/commands/usage/shared.ts | 12 ++++---- 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/packages/commands/src/commands/usage/free.ts b/packages/commands/src/commands/usage/free.ts index 98154da0..5bf90a1d 100644 --- a/packages/commands/src/commands/usage/free.ts +++ b/packages/commands/src/commands/usage/free.ts @@ -104,12 +104,7 @@ export default defineCommand({ } } - const [quotaResult, stopResult] = await Promise.all([ - ctx.client.console(FREE_TIER_API, requestData), - ctx.client.console(FREE_TIER_ONLY_STATUS_API, { - queryFreeTierOnlyStatusRequest: { models }, - }), - ]); + const quotaResult = await ctx.client.console(FREE_TIER_API, requestData); const allQuotas = extractQuotas(quotaResult); let quotas = modelFlag @@ -137,7 +132,16 @@ export default defineCommand({ ); } - const stopStatuses = extractFreeTierOnlyStatuses(stopResult); + // Query auto-stop status only for the filtered models (the full catalog can + // exceed the status API's batch limit and trigger a server-side error). + const filteredModels = quotas.map((quota) => quota.model); + const stopResult = filteredModels.length + ? await ctx.client.console(FREE_TIER_ONLY_STATUS_API, { + queryFreeTierOnlyStatusRequest: { models: filteredModels }, + }) + : null; + + const stopStatuses = stopResult ? extractFreeTierOnlyStatuses(stopResult) : []; const stopMap = new Map(stopStatuses.map((status) => [status.model, status.freeTierOnly])); if (format === "json") { @@ -146,12 +150,12 @@ export default defineCommand({ const used = hasQuota ? quota.quotaInitTotal - quota.quotaTotal : 0; const stopStatus = stopMap.get(quota.model); const autoStop = - quota.quotaStatus === "UNKNOWN" - ? "unsupported" - : stopStatus === true - ? true - : stopStatus === false - ? false + stopStatus === true + ? true + : stopStatus === false + ? false + : quota.quotaStatus === "UNKNOWN" + ? "unsupported" : null; return { model: quota.model, diff --git a/packages/commands/src/commands/usage/freetier.ts b/packages/commands/src/commands/usage/freetier.ts index e503d6d7..913f711e 100644 --- a/packages/commands/src/commands/usage/freetier.ts +++ b/packages/commands/src/commands/usage/freetier.ts @@ -1,10 +1,8 @@ import { defineCommand, detectOutputFormat, unwrapResponse } from "bailian-cli-core"; import { emitResult } from "bailian-cli-runtime"; import { - FREE_TIER_API, FREE_TIER_ONLY_STATUS_API, extractFreeTierOnlyStatuses, - extractQuotas, fetchAllModels, pollFreeTierBatch, } from "./shared.ts"; @@ -92,15 +90,9 @@ export default defineCommand({ } if (off) { - const [quotaResult, stopResult] = await Promise.all([ - ctx.client.console(FREE_TIER_API, { queryFreeTierQuotaRequest: { models } }), - ctx.client.console(FREE_TIER_ONLY_STATUS_API, { - queryFreeTierOnlyStatusRequest: { models }, - }), - ]); - - const quotas = extractQuotas(quotaResult); - const quotaMap = new Map(quotas.map((quota) => [quota.model, quota])); + const stopResult = await ctx.client.console(FREE_TIER_ONLY_STATUS_API, { + queryFreeTierOnlyStatusRequest: { models }, + }); const stopStatuses = extractFreeTierOnlyStatuses(stopResult); const stopMap = new Map(stopStatuses.map((status) => [status.model, status.freeTierOnly])); @@ -110,13 +102,6 @@ export default defineCommand({ process.stderr.write(`Auto-stop is already disabled for "${name}".\n`); continue; } - const quota = quotaMap.get(name); - if (quota && quota.quotaTotal > 0 && stopMap.get(name) === true) { - process.stderr.write( - `Cannot disable auto-stop for "${name}": free-tier quota has not been fully consumed. Please disable auto-stop after the quota is exhausted.\n`, - ); - continue; - } await pollFreeTierBatch(ctx.client, api, requestKey, [name]); process.stdout.write(`Disabled auto-stop for "${name}".\n`); } diff --git a/packages/commands/src/commands/usage/shared.ts b/packages/commands/src/commands/usage/shared.ts index 5b4fa934..ccb3fa8c 100644 --- a/packages/commands/src/commands/usage/shared.ts +++ b/packages/commands/src/commands/usage/shared.ts @@ -187,12 +187,12 @@ export function printFreeTierTable(options: FreeTierTableOptions): void { const stopStatus = stopMap.get(quota.model); const autoStop = - quota.quotaStatus === "UNKNOWN" - ? "Unsupported" - : stopStatus === true - ? "ON" - : stopStatus === false - ? "OFF" + stopStatus === true + ? "ON" + : stopStatus === false + ? "OFF" + : quota.quotaStatus === "UNKNOWN" + ? "Unsupported" : "-"; return [quota.model, typeMap.get(quota.model) || "-", remaining, total, "", autoStop];