Skip to content

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

Description

@Naayi

环境

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 的字段映射。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions