diff --git a/CHANGELOG.md b/CHANGELOG.md index e1f9e274b..a71ff88d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and [中文版](CHANGELOG.zh.md) · [README](README.md) · [Contributing](CONTRIBUTING.md) +## [2.2.0] - 2026-10-12 + +### Changed + +- **Token Plan usage window** — `bl usage token-plan` now reports a single monthly quota (usage percentage and reset time) instead of the previous 5-hour and 1-week windows. + ## [2.1.0] - 2026-09-28 ### Added diff --git a/CHANGELOG.zh.md b/CHANGELOG.zh.md index 98ac308a0..7ed339ef8 100644 --- a/CHANGELOG.zh.md +++ b/CHANGELOG.zh.md @@ -6,6 +6,12 @@ [English](CHANGELOG.md) · [README](README.zh.md) · [参与贡献](CONTRIBUTING.zh.md) +## [2.2.0] - 2026-10-12 + +### 变更 + +- **Token Plan 额度窗口** —— `bl usage token-plan` 现在只展示月度额度(使用百分比与重置时间),不再显示此前的 5 小时和 1 周窗口。 + ## [2.1.0] - 2026-09-28 ### 新增 diff --git a/packages/cli/package.json b/packages/cli/package.json index 8cc4be7ff..162bbba0f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "bailian-cli", - "version": "2.1.0", + "version": "2.2.0", "description": "CLI for Aliyun Model Studio (DashScope) AI Platform.", "keywords": [ "agent", diff --git a/packages/commands/package.json b/packages/commands/package.json index ae739d60c..644b67861 100644 --- a/packages/commands/package.json +++ b/packages/commands/package.json @@ -1,6 +1,6 @@ { "name": "bailian-cli-commands", - "version": "2.1.0", + "version": "2.2.0", "description": "Command library for bailian-cli products (knowledge, memory, media, …). See https://www.npmjs.com/package/bailian-cli for usage.", "homepage": "https://bailian.console.aliyun.com/cli", "bugs": { diff --git a/packages/commands/src/commands/usage/token-plan.ts b/packages/commands/src/commands/usage/token-plan.ts index 2716a94bd..9e308850a 100644 --- a/packages/commands/src/commands/usage/token-plan.ts +++ b/packages/commands/src/commands/usage/token-plan.ts @@ -5,24 +5,18 @@ import { printQuotaBox, readNumber } from "./quota-box.ts"; const TOKEN_PLAN_USAGE_API = "zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/usage"; interface TokenPlanUsage { - per5HourPercentage?: number; - per5HourResetTime?: number; - per1WeekPercentage?: number; - per1WeekResetTime?: number; + per1MonthPercentage?: number; + per1MonthResetTime?: number; } function readUsage(result: unknown): TokenPlanUsage { const response = unwrapResponse(result as Record); 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; + const per1MonthPercentage = readNumber(response.per1MonthPercentage); + if (per1MonthPercentage !== undefined) usage.per1MonthPercentage = per1MonthPercentage; + const per1MonthResetTime = readNumber(response.per1MonthResetTime); + if (per1MonthResetTime !== undefined) usage.per1MonthResetTime = per1MonthResetTime; return usage; } @@ -32,18 +26,11 @@ function printView(usage: TokenPlanUsage, generatedAt: number): void { "Token Plan Usage", [ { - label: "5-hour quota", + label: "Monthly quota", emptyMessage: - "The 5-hour limit may be unlimited; verify in the Bailian Token Plan console.", - percentage: usage.per5HourPercentage, - resetTime: usage.per5HourResetTime, - }, - { - label: "1-week quota", - emptyMessage: - "The 1-week limit may be unlimited; verify in the Bailian Token Plan console.", - percentage: usage.per1WeekPercentage, - resetTime: usage.per1WeekResetTime, + "The monthly limit may be unlimited; verify in the Bailian Token Plan console.", + percentage: usage.per1MonthPercentage, + resetTime: usage.per1MonthResetTime, }, ], generatedAt, diff --git a/packages/commands/tests/e2e/usage-token-plan.e2e.test.ts b/packages/commands/tests/e2e/usage-token-plan.e2e.test.ts index 2e2a9a817..63fe287cd 100644 --- a/packages/commands/tests/e2e/usage-token-plan.e2e.test.ts +++ b/packages/commands/tests/e2e/usage-token-plan.e2e.test.ts @@ -50,28 +50,20 @@ describe.skipIf(!isConsoleE2EReady())("e2e: usage token-plan(Console)", () = if (isConsoleAuthFailure(result)) return; expect(result.exitCode, result.stderr).toBe(0); const data = parseStdoutJson<{ - per5HourPercentage?: number; - per5HourResetTime?: number; - per1WeekPercentage?: number; - per1WeekResetTime?: number; + per1MonthPercentage?: number; + per1MonthResetTime?: number; }>(result.stdout); - const fields = [ - data.per5HourPercentage, - data.per5HourResetTime, - data.per1WeekPercentage, - data.per1WeekResetTime, - ]; + const fields = [data.per1MonthPercentage, data.per1MonthResetTime]; for (const field of fields) { if (field !== undefined) expect(field).toBeTypeOf("number"); } }); - test("usage token-plan 默认渲染生成时间与两个额度窗口", async () => { + test("usage token-plan 默认渲染生成时间与月额度窗口", async () => { const result = await runCommandE2e(USAGE_ROUTES, ["usage", "token-plan"]); if (isConsoleAuthFailure(result)) return; expect(result.exitCode, result.stderr).toBe(0); expect(result.stdout).toContain("Generated at:"); - expect(result.stdout).toContain("5-hour quota"); - expect(result.stdout).toContain("1-week quota"); + expect(result.stdout).toContain("Monthly quota"); }); }); diff --git a/packages/commands/tests/token-plan-usage.test.ts b/packages/commands/tests/token-plan-usage.test.ts index 9f144bd27..7335067d0 100644 --- a/packages/commands/tests/token-plan-usage.test.ts +++ b/packages/commands/tests/token-plan-usage.test.ts @@ -32,18 +32,11 @@ async function runTokenPlan(response: Record, output?: string): } as never); } -function makeUsageResponse( - per5HourPercentage?: number, - per1WeekPercentage = per5HourPercentage, -): Record { +function makeUsageResponse(per1MonthPercentage?: number): Record { const usage: Record = {}; - if (per5HourPercentage !== undefined) { - usage.per5HourPercentage = per5HourPercentage; - if (per5HourPercentage !== 0) usage.per5HourResetTime = 1_786_000_000_000; - } - if (per1WeekPercentage !== undefined) { - usage.per1WeekPercentage = per1WeekPercentage; - if (per1WeekPercentage !== 0) usage.per1WeekResetTime = 1_786_100_000_000; + if (per1MonthPercentage !== undefined) { + usage.per1MonthPercentage = per1MonthPercentage; + if (per1MonthPercentage !== 0) usage.per1MonthResetTime = 1_786_000_000_000; } return wrapResponse(usage); @@ -86,7 +79,7 @@ describe("usage token-plan view", () => { expect(renderedOutput).not.toContain("\u2588".repeat(11)); }); - test("accepts missing reset times when the quota usage is zero", async () => { + test("accepts a missing reset time when the quota usage is zero", async () => { const output = captureStdout(); await runTokenPlan(makeUsageResponse(0)); @@ -94,83 +87,54 @@ describe("usage token-plan view", () => { expect(output.join("")).toContain("Resets: not applicable (no usage yet)"); }); - test("allows one unused quota window without masking another reset time", async () => { + test("renders the monthly reset time when usage is present", async () => { const output = captureStdout(); - await runTokenPlan(makeUsageResponse(0, 0.5)); + await runTokenPlan(makeUsageResponse(0.5)); - const renderedOutput = output.join(""); - expect(renderedOutput).toContain("Resets: not applicable (no usage yet)"); - expect(renderedOutput).toMatch(/Resets: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/); + expect(output.join("")).toMatch(/Resets: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/); }); - test("renders missing quota windows as possibly unlimited", async () => { + test("renders a missing monthly quota as possibly unlimited", async () => { const output = captureStdout(); await runTokenPlan(makeUsageResponse()); - const renderedOutput = output.join(""); - expect(renderedOutput).toContain( - "The 5-hour limit may be unlimited; verify in the Bailian Token Plan console.", - ); - expect(renderedOutput).toContain( - "The 1-week limit may be unlimited; verify in the Bailian Token Plan console.", - ); - }); - - test("renders only the missing quota window as possibly unlimited", async () => { - const output = captureStdout(); - - await runTokenPlan(makeUsageResponse(undefined, 0.5)); - - const renderedOutput = output.join(""); - expect(renderedOutput).toContain( - "The 5-hour limit may be unlimited; verify in the Bailian Token Plan console.", - ); - expect(renderedOutput).not.toContain( - "The 1-week limit may be unlimited; verify in the Bailian Token Plan console.", + expect(output.join("")).toContain( + "The monthly limit may be unlimited; verify in the Bailian Token Plan console.", ); - expect(renderedOutput).toMatch(/Resets: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/); }); - test("renders a window with a missing percentage as possibly unlimited even when its reset time is present", async () => { + test("renders the monthly window as possibly unlimited when its percentage is missing even if the reset time is present", async () => { const output = captureStdout(); - await runTokenPlan(wrapResponse({ per5HourResetTime: 1_786_000_000_000 })); + await runTokenPlan(wrapResponse({ per1MonthResetTime: 1_786_000_000_000 })); expect(output.join("")).toContain( - "The 5-hour limit may be unlimited; verify in the Bailian Token Plan console.", + "The monthly limit may be unlimited; verify in the Bailian Token Plan console.", ); }); test("treats non-numeric quota fields as absent instead of failing", async () => { const output = captureStdout(); - await runTokenPlan( - wrapResponse({ per5HourPercentage: "not-a-number", per1WeekPercentage: Number.NaN }), - ); + await runTokenPlan(wrapResponse({ per1MonthPercentage: "not-a-number" })); - const renderedOutput = output.join(""); - expect(renderedOutput).toContain( - "The 5-hour limit may be unlimited; verify in the Bailian Token Plan console.", - ); - expect(renderedOutput).toContain( - "The 1-week limit may be unlimited; verify in the Bailian Token Plan console.", + expect(output.join("")).toContain( + "The monthly limit may be unlimited; verify in the Bailian Token Plan console.", ); }); }); describe("usage token-plan json", () => { - test("outputs the four core usage fields with --output json", async () => { + test("outputs the monthly usage fields with --output json", async () => { const output = captureStdout(); - await runTokenPlan(makeUsageResponse(0.5, 0.25), "json"); + await runTokenPlan(makeUsageResponse(0.5), "json"); expect(JSON.parse(output.join(""))).toEqual({ - per5HourPercentage: 0.5, - per5HourResetTime: 1_786_000_000_000, - per1WeekPercentage: 0.25, - per1WeekResetTime: 1_786_100_000_000, + per1MonthPercentage: 0.5, + per1MonthResetTime: 1_786_000_000_000, }); }); @@ -186,10 +150,10 @@ describe("usage token-plan json", () => { const output = captureStdout(); await runTokenPlan( - wrapResponse({ per5HourPercentage: "not-a-number", per1WeekPercentage: 0 }), + wrapResponse({ per1MonthPercentage: "not-a-number", per1MonthResetTime: 1_786_000_000_000 }), "json", ); - expect(JSON.parse(output.join(""))).toEqual({ per1WeekPercentage: 0 }); + expect(JSON.parse(output.join(""))).toEqual({ per1MonthResetTime: 1_786_000_000_000 }); }); }); diff --git a/packages/core/package.json b/packages/core/package.json index ff459ac6c..af542b123 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "bailian-cli-core", - "version": "2.1.0", + "version": "2.2.0", "description": "Core SDK for bailian-cli. See https://www.npmjs.com/package/bailian-cli for usage.", "homepage": "https://bailian.console.aliyun.com/cli", "bugs": { diff --git a/packages/kscli/package.json b/packages/kscli/package.json index 357b3ec3a..fb4ad05d7 100644 --- a/packages/kscli/package.json +++ b/packages/kscli/package.json @@ -1,6 +1,6 @@ { "name": "knowledge-studio-cli", - "version": "2.1.0", + "version": "2.2.0", "description": "Lightweight RAG CLI for Aliyun Model Studio — focused on knowledge-base retrieval.", "keywords": [ "alibaba-cloud", diff --git a/packages/runtime/package.json b/packages/runtime/package.json index fe723310b..6402e51df 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "bailian-cli-runtime", - "version": "2.1.0", + "version": "2.2.0", "description": "Runtime framework for bailian-cli (createCli, registry, args, output, pipeline). See https://www.npmjs.com/package/bailian-cli for usage.", "homepage": "https://bailian.console.aliyun.com/cli", "bugs": { diff --git a/skills/bailian-cli/SKILL.md b/skills/bailian-cli/SKILL.md index 0e6f8f3b5..da206b307 100644 --- a/skills/bailian-cli/SKILL.md +++ b/skills/bailian-cli/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-cli metadata: - version: "2.1.0" + version: "2.2.0" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-finetune/SKILL.md b/skills/bailian-finetune/SKILL.md index fa0f3be74..dd4991e34 100644 --- a/skills/bailian-finetune/SKILL.md +++ b/skills/bailian-finetune/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-finetune metadata: - version: "2.1.0" + version: "2.2.0" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-gen/SKILL.md b/skills/bailian-gen/SKILL.md index f2761219f..451629250 100644 --- a/skills/bailian-gen/SKILL.md +++ b/skills/bailian-gen/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-gen metadata: - version: "2.1.0" + version: "2.2.0" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-managed-agent/SKILL.md b/skills/bailian-managed-agent/SKILL.md index 5ac26be42..a9f2b6ed1 100644 --- a/skills/bailian-managed-agent/SKILL.md +++ b/skills/bailian-managed-agent/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-managed-agent metadata: - version: "2.1.0" + version: "2.2.0" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-protocol/SKILL.md b/skills/bailian-protocol/SKILL.md index 27d92c21d..46c00253e 100644 --- a/skills/bailian-protocol/SKILL.md +++ b/skills/bailian-protocol/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-protocol metadata: - version: "2.1.0" + version: "2.2.0" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-sandbox/SKILL.md b/skills/bailian-sandbox/SKILL.md index 4cb1bc0a3..33d9e570a 100644 --- a/skills/bailian-sandbox/SKILL.md +++ b/skills/bailian-sandbox/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-sandbox metadata: - version: "2.1.0" + version: "2.2.0" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-web-search/SKILL.md b/skills/bailian-web-search/SKILL.md index 6ba66101d..4948b5126 100644 --- a/skills/bailian-web-search/SKILL.md +++ b/skills/bailian-web-search/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-web-search metadata: - version: "2.1.0" + version: "2.2.0" requires: bins: ["bl"] description: >-