From f29c5bf4bf416c0fcab3f6d757eb9528154c4e8a Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 14 Jul 2026 17:42:55 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8=E7=A8=B3=E5=AE=9A?= =?UTF-8?q?=E5=88=A9=E6=B6=A6=E8=B4=A6=E5=8F=B7=E5=88=86=E9=A1=B5=E4=BB=A4?= =?UTF-8?q?=E7=89=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unidesk-sub2api/references/codex-pool.md | 2 +- .../src/platform-infra-sub2api-codex/profit.ts | 17 +++++++++++++---- .../src/platform-infra-sub2api-codex/types.ts | 2 +- scripts/src/platform-infra/entry.ts | 4 ++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.agents/skills/unidesk-sub2api/references/codex-pool.md b/.agents/skills/unidesk-sub2api/references/codex-pool.md index 13665de8..0562bb2a 100644 --- a/.agents/skills/unidesk-sub2api/references/codex-pool.md +++ b/.agents/skills/unidesk-sub2api/references/codex-pool.md @@ -103,7 +103,7 @@ bun scripts/cli.ts platform-infra sub2api codex-pool cleanup-probes --target D60 - 原生 `actual_cost` 是标准 API 美元计费基数;`saleRateCnyPerApiUsd` 和账号名称末尾成本都表示每 1 美元标准 API 计费对应的人民币单价,不做汇率换算; - 默认 Kubernetes 风格输出优先给出总收入、已确认成本、已确认利润、未知成本对应的 API USD 基数、完整性和参数化利润公式; - 显式 `--json` 返回同一份稳定紧凑汇总,不携带完整账号数组,避免大窗口触发全局输出保护; - - `--accounts` 固定返回一页完整账号名称、账号 ID、请求数、Token、标准 API 美元计费基数、人民币采购单价、人民币收入、人民币上游成本和人民币利润贡献;存在后续页时返回基于账号 ID 的 `--page-token` 命令,不提供手工 `limit`; + - `--accounts` 固定返回一页完整账号名称、账号 ID、请求数、Token、标准 API 美元计费基数、人民币采购单价、人民币收入、人民币上游成本和人民币利润贡献;存在后续页时返回由分类、分组、账号 ID 和名称生成的 opaque `--page-token` 命令,不提供手工 `limit`; - `--missing-costs` 单独返回缺失成本账号的完整名称、账号 ID、分组、分类和未知成本 API USD 基数,避免与账号分页叠加后再次触发全局输出保护; - 汇总同时给出“不扣自用成本”和“扣除自用成本”两种口径,自用分组不计收入;缺失成本时已确认利润只表示待扣未知成本前的已知部分,最终利润必须按输出公式继续扣除未知账号成本,禁止把未知成本当作 0; - 账号名称末尾缺少采购成本系数,或存在未分类流量时,相关口径必须显示 `partial`,禁止把缺失值当作零; diff --git a/scripts/src/platform-infra-sub2api-codex/profit.ts b/scripts/src/platform-infra-sub2api-codex/profit.ts index 0e2b3b33..81375d90 100644 --- a/scripts/src/platform-infra-sub2api-codex/profit.ts +++ b/scripts/src/platform-infra-sub2api-codex/profit.ts @@ -97,12 +97,12 @@ function renderProfitHelp(defaultWindow: string): RenderedCliResult { renderedText: [ "SUB2API CODEX-POOL PROFIT", "Usage:", - " bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token ]|--missing-costs] [--json]", + " bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token ]|--missing-costs] [--json]", "Options:", ` --since Native usage window; YAML default is ${defaultWindow}.`, " --target ", " --accounts Include one fixed-size account page with complete names and IDs.", - " --page-token Continue after the account ID returned by the previous page.", + " --page-token Continue from the opaque token returned by the previous account page.", " --missing-costs Include the missing-cost account list and API USD bases.", " --json Emit exact structured values.", "Notes:", @@ -207,13 +207,13 @@ function projectProfitReport(report: Record | null, options: Pr if (!options.accounts) return compactReport; let startIndex = 0; if (options.pageToken !== null) { - const tokenIndex = accounts.findIndex((row) => text(row.accountId) === options.pageToken); + const tokenIndex = accounts.findIndex((row) => encodeProfitAccountPageToken(row) === options.pageToken); if (tokenIndex < 0) throw new Error(`profit account page token not found: ${options.pageToken}`); startIndex = tokenIndex + 1; } const pageAccounts = accounts.slice(startIndex, startIndex + PROFIT_ACCOUNT_PAGE_SIZE); const hasNext = startIndex + pageAccounts.length < accounts.length; - const nextPageToken = hasNext ? text(pageAccounts.at(-1)?.accountId) : null; + const nextPageToken = hasNext && pageAccounts.length > 0 ? encodeProfitAccountPageToken(pageAccounts.at(-1)!) : null; return { ...compactReport, accounts: pageAccounts, @@ -225,6 +225,15 @@ function projectProfitReport(report: Record | null, options: Pr }; } +function encodeProfitAccountPageToken(account: Record): string { + return Buffer.from(JSON.stringify([ + account.class ?? null, + account.groupId ?? null, + account.accountId ?? null, + account.accountName ?? null, + ]), "utf8").toString("base64url"); +} + function renderProfitJson(response: Record): RenderedCliResult { return { ok: response.ok === true, diff --git a/scripts/src/platform-infra-sub2api-codex/types.ts b/scripts/src/platform-infra-sub2api-codex/types.ts index d20f6fb2..63b669be 100644 --- a/scripts/src/platform-infra-sub2api-codex/types.ts +++ b/scripts/src/platform-infra-sub2api-codex/types.ts @@ -374,7 +374,7 @@ export function codexPoolHelp(): unknown { "bun scripts/cli.ts platform-infra sub2api codex-pool runtime get --account [--target PK01] [--json|--full|--raw]", "bun scripts/cli.ts platform-infra sub2api codex-pool runtime errors [--group |--all-groups] [--platform ] [--page-token ] [--account ] [--since 24h] [--tail 50000] [--target PK01] [--json|--full|--raw]", "bun scripts/cli.ts platform-infra sub2api codex-pool faults [--level P0|P1|P2] [--group ] [--account ] [--model ] [--stream sync|stream] [--endpoint ] [--request-id ] [--page-token ] [--target PK01] [--json]", - "bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token ]|--missing-costs] [--json]", + "bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token ]|--missing-costs] [--json]", "bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --account --template [--target PK01] [--confirm]", "bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --accounts --template [--target PK01] [--confirm] [--full|--raw]", "bun scripts/cli.ts platform-infra sub2api codex-pool runtime delete --account --kind temp-unschedulable [--target PK01] [--confirm]", diff --git a/scripts/src/platform-infra/entry.ts b/scripts/src/platform-infra/entry.ts index 0e980894..e690c7fc 100644 --- a/scripts/src/platform-infra/entry.ts +++ b/scripts/src/platform-infra/entry.ts @@ -424,7 +424,7 @@ export function platformInfraHelp(): unknown { "bun scripts/cli.ts platform-infra sub2api codex-pool validate", "bun scripts/cli.ts platform-infra sub2api codex-pool trace --request-id ", "bun scripts/cli.ts platform-infra sub2api codex-pool feedback --user [--window 30m] [--page-token |--request-id ] [--json]", - "bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token ]|--missing-costs] [--json]", + "bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token ]|--missing-costs] [--json]", "bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-image status", "bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-probe --account unidesk-codex-hy --confirm", "bun scripts/cli.ts platform-infra sub2rank plan [--target NC01]", @@ -508,7 +508,7 @@ export function platformInfraHelp(): unknown { "bun scripts/cli.ts platform-infra sub2api codex-pool validate", "bun scripts/cli.ts platform-infra sub2api codex-pool trace --request-id ", "bun scripts/cli.ts platform-infra sub2api codex-pool feedback --user [--window 30m] [--page-token |--request-id ] [--json]", - "bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token ]|--missing-costs] [--json]", + "bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token ]|--missing-costs] [--json]", "bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-image status", ], module: "scripts/src/platform-infra-sub2api-codex.ts",