Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[bug] usage token-plan 对按月计量的 Token Plan 账号返回空:API 返回 per1MonthPercentage,CLI 只读 per5Hour* / per1Week*

Aperta
#231 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
68/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
typescript
Ambito
cli

Direzione di ricerca

Start in packages/commands/src/commands/usage/token-plan.ts by tracing readUsage() from the API response into the usage view, then inspect quota-box.ts for the missing-data behavior. Reproduce the issue with the provided console call and a monthly Token Plan account. Done means monthly usage is represented in the CLI and JSON output, while genuinely missing usage remains distinguishable from unlimited usage.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

环境

bl --version 2.0.1
OS Windows 11
Node.js v24.12.0
站点 国内站(console_site: domestic, console_region: cn-beijing)
套餐 Token Plan 个人版
登录方式 bl auth login --console(登录态有效)

现象

bl usage token-plan 两个窗口都显示为「可能不限量」,--output json 返回空对象:

$ bl usage token-plan
┌────────────────────────────────────────────────────────────────────────────┐
│ Token Plan Usage                                                           │
│ Generated at: 2026-09-26 13:14:40 (local time)                             │
├────────────────────────────────────────────────────────────────────────────┤
│ 5-hour quota                                                               │
│ The 5-hour limit may be unlimited; verify in the Bailian Token Plan console.│
├────────────────────────────────────────────────────────────────────────────┤
│ 1-week quota                                                               │
│ The 1-week limit may be unlimited; verify in the Bailian Token Plan console.│
└────────────────────────────────────────────────────────────────────────────┘

$ bl usage token-plan --output json --quiet
{}

但该账号是有用量的,且控制台能正常显示。 所以这不是「不限量」,而是 CLI 没有读到数据。

根因:API 返回月计量字段,CLI 只声明了 5 小时 / 周字段

直接调用同一条底层 API(bl usage token-plan 内部使用的那个),可以看到返回了真实的用量数据:

$ bl console call --api "zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/usage" --data '{}' --output json
{
  "code": "200",
  "data": {
    "DataV2": {
      "ret": ["SUCCESS::接口调用成功"],
      "data": {
        "msg": "Success.",
        "code": "SUCCESS",
        "data": {
          "per1MonthPercentage": 0.004482845333333333,
          "per1MonthResetTime": 1790784000000
        },
        "requestId": "9dc4ca84-5a41-9f08-b9ae-39832766292f",
        "success": true
      }
    },
    "success": true,
    "httpStatus": 200,
    "errorCode": "",
    "api": "zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/usage",
    "errorMsg": ""
  },
  "httpStatusCode": "200",
  "requestId": "9dc4ca84-5a41-4f08-b9ae-39832766292f",
  "successResponse": true
}

即该账号是按自然月计量的(per1MonthPercentage),当前用量约 0.45%。

而 packages/commands/src/commands/usage/token-plan.ts 只声明并读取 5 小时 / 周两类字段:

interface TokenPlanUsage {
  per5HourPercentage?: number;
  per5HourResetTime?: number;
  per1WeekPercentage?: number;
  per1WeekResetTime?: number;
}

function readUsage(result: unknown): TokenPlanUsage {
  const response = unwrapResponse(result as Record<string, unknown>);
  const usage: TokenPlanUsage = {};

  const per5HourPercentage = readNumber(response.per5HourPercentage);
  if (per5HourPercentage !== undefined) usage.per5HourPercentage = per5HourPercentage;
  const per5HourResetTime = readNumber(response.per5HourResetTime);
  if (per5HourResetTime !== undefined) usage.per5HourResetTime = per5HourResetTime;
  const per1WeekPercentage = readNumber(response.per1WeekPercentage);
  if (per1WeekPercentage !== undefined) usage.per1WeekPercentage = per1WeekPercentage;
  const per1WeekResetTime = readNumber(response.per1WeekResetTime);
  if (per1WeekResetTime !== undefined) usage.per1WeekResetTime = per1WeekResetTime;

  return usage;
}

per1Month* 不在读取范围内,因此四个字段全部为 undefined,readUsage() 返回 {},视图按「字段缺失 = 可能不限量」渲染。

字段对照

API 实际返回(本账号) CLI 读取 是否命中
per1MonthPercentage per5HourPercentage ❌
per1MonthResetTime per5HourResetTime ❌
— per1WeekPercentage ❌
— per1WeekResetTime ❌

对比 #135(该功能的最初请求)中贴出的响应,那种账号返回的是 per5HourPercentage / per1WeekPercentage:

"data": {
  "per5HourPercentage": 0.43565880333333334,
  "per1WeekPercentage": 0.130712521,
  "per5HourResetTime": 1785868560000,
  "per1WeekResetTime": 1786417680000
}

可见 Token Plan 至少存在两种计量形态(5 小时 + 周窗口 / 自然月),当前实现只覆盖了前者。

影响

  • bl usage token-plan 对按月计量的账号恒返回空,即使账号有用量、控制台可见。
  • --output json 返回 {},下游消费者无法区分「真的不限量」与「字段名不匹配」。这一点影响面较大:第三方工具(例如 DSH 插件 dsh-cost-meter 的「百炼 CLI」额度来源)拿到 {} 后会判定为异常数据并报错,用户看到的是「CLI 返回的额度格式无效」,进而被误导去升级 CLI——而 CLI 已是最新版。
  • quota-box.ts 中的注释 /** Usage ratio in [0, 1]; absent means no data (possibly unlimited). */ 以及文案里的 "may be unlimited" 表明作者已意识到该路径存在歧义,但当前无法区分。

建议

  1. 补充月计量字段支持:在 TokenPlanUsage 中增加 per1MonthPercentage / per1MonthResetTime,并在视图中作为第三个窗口渲染(或在 5 小时 / 周缺失时作为回退窗口)。
  2. 或改为按返回字段动态渲染:遍历响应中实际存在的 per*Percentage 字段,按前缀生成对应窗口标签(per5Hour → 5-hour、per1Week → 1-week、per1Month → 1-month),避免为每种新计量形态改一次代码。
  3. 区分「无数据」与「不限量」:当响应成功但无任何 per*Percentage 字段时,JSON 输出建议给出可判别的信号(例如 {"unlimited": true} 或显式 null),而不是裸 {},以便下游区分。
  4. 文档中补充说明 Token Plan 存在多种计量形态。

复现步骤

  1. 使用按月计量的 Token Plan 个人版账号,bl auth login --console 完成登录。
  2. 运行 bl usage token-plan(或加 --output json --quiet)。
  3. 观察两个窗口均显示 "may be unlimited",JSON 为 {}。
  4. 运行 bl console call --api "zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/usage" --data '{}',可见响应中含 per1MonthPercentage 等真实数据。

备注

  • 上述 console call 输出仅含百分比与时间戳,未包含任何凭据。
  • 该账号的 bl token-plan harness-quota 能正常返回 7 项 Harness 工具额度(status 均为 issued),说明订阅本身有效、控制台登录态正常,问题仅限于 usage token-plan 的字段映射。
Lingua principale
TypeScript
Stelle
333
Fork
28
Merge medio
1g 5h
PR unite (30g)
37

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di modelstudioai/cli

Tutte le issue di modelstudioai/cli

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.