Merge pull request #2048 from pikasTech/feat/sub2api-profit-summary
feat: 优化 Sub2API 利润汇总与渐进披露
This commit is contained in:
@@ -88,6 +88,8 @@ bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --target PK01
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool runtime delete --target PK01 --account <name-or-id> --kind model-mapping --model <client-model>
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool profit --target PK01 --since 24h
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool profit --target PK01 --since 24h --json
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool profit --target PK01 --since 24h --accounts
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool profit --target PK01 --since 24h --missing-costs
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool trace --request-id <requestId>
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-image status --target D601
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-image build --target D601 --confirm
|
||||
@@ -99,8 +101,11 @@ bun scripts/cli.ts platform-infra sub2api codex-pool cleanup-probes --target D60
|
||||
- `profit` 只读聚合 Sub2API 原生 `/api/v1/admin/usage`:
|
||||
- 默认窗口、盈利分组、自用分组、排除分组、人民币售价和账号采购成本来源由 `config/platform-infra/sub2api-codex-pool.yaml#profit` 声明;
|
||||
- 原生 `actual_cost` 是标准 API 美元计费基数;`saleRateCnyPerApiUsd` 和账号名称末尾成本都表示每 1 美元标准 API 计费对应的人民币单价,不做汇率换算;
|
||||
- 默认 Kubernetes 列表按完整账号名称显示请求数、Token、标准 API 美元计费基数、人民币采购单价、人民币收入、人民币上游成本和人民币利润贡献;
|
||||
- 汇总同时给出“不扣自用成本”和“扣除自用成本”两种口径,自用分组不计收入;
|
||||
- 默认 Kubernetes 风格输出优先给出总收入、已确认成本、扣除已知成本后的待定利润基数、未知成本对应的 API USD 基数、完整性和参数化利润公式;
|
||||
- 显式 `--json` 返回同一份稳定紧凑汇总,不携带完整账号数组,避免大窗口触发全局输出保护;
|
||||
- `--accounts` 固定返回一页完整账号名称、账号 ID、请求数、Token、标准 API 美元计费基数、人民币采购单价、人民币收入、人民币上游成本和人民币利润贡献;存在后续页时返回由分类、分组、账号 ID 和名称生成的 opaque `--page-token` 命令,不提供手工 `limit`;
|
||||
- `--missing-costs` 单独返回缺失成本账号的完整名称、账号 ID、分组、分类和未知成本 API USD 基数,避免与账号分页叠加后再次触发全局输出保护;
|
||||
- 汇总同时给出“不扣自用成本”和“扣除自用成本”两种口径,自用分组不计收入;缺失成本时 `profitBeforeUnknownCostsCny` 只表示扣除已知成本后的待定利润基数,最终利润必须按输出公式继续扣除未知账号成本,禁止把未知成本当作 0;完整状态下该基数才等于最终利润;
|
||||
- 账号名称末尾缺少采购成本系数,或存在未分类流量时,相关口径必须显示 `partial`,禁止把缺失值当作零;
|
||||
- `--json` 保留精确十进制字符串、原生来源、时间窗、分页数和完整性明细;命令不修改 runtime。
|
||||
|
||||
|
||||
@@ -10,8 +10,13 @@ interface ProfitOptions {
|
||||
since: string;
|
||||
targetId: string;
|
||||
json: boolean;
|
||||
accounts: boolean;
|
||||
missingCosts: boolean;
|
||||
pageToken: string | null;
|
||||
}
|
||||
|
||||
const PROFIT_ACCOUNT_PAGE_SIZE = 8;
|
||||
|
||||
export async function codexPoolProfit(config: UniDeskConfig, args: string[]): Promise<Record<string, unknown> | RenderedCliResult> {
|
||||
const pool = readCodexPoolConfig();
|
||||
if (args.includes("--help")) return renderProfitHelp(pool.profit.defaultWindow);
|
||||
@@ -21,6 +26,9 @@ export async function codexPoolProfit(config: UniDeskConfig, args: string[]): Pr
|
||||
const remote = await runRemoteCodexPoolScript(config, "profit", profitScript(payload, pool, target), target);
|
||||
const report = parseJsonOutput(remote.stdout);
|
||||
const ok = remote.exitCode === 0 && boolField(report, "ok", false);
|
||||
const projectedReport = projectProfitReport(report, options);
|
||||
const baseCommand = `bun scripts/cli.ts platform-infra sub2api codex-pool profit --target ${target.id} --since ${options.since}`;
|
||||
const accountPage = record(record(projectedReport).accountPage);
|
||||
const response = {
|
||||
ok,
|
||||
action: "platform-infra-sub2api-codex-pool-profit",
|
||||
@@ -30,7 +38,16 @@ export async function codexPoolProfit(config: UniDeskConfig, args: string[]): Pr
|
||||
mutation: false,
|
||||
configPath: "config/platform-infra/sub2api-codex-pool.yaml#profit",
|
||||
},
|
||||
report,
|
||||
report: projectedReport,
|
||||
disclosure: {
|
||||
accountsIncluded: options.accounts,
|
||||
missingCostsIncluded: options.missingCosts,
|
||||
accountCount: arrayOfRecords(record(report).accounts).length,
|
||||
accounts: `${baseCommand} --accounts`,
|
||||
accountsNext: accountPage.nextPageToken ? `${baseCommand} --accounts --page-token ${text(accountPage.nextPageToken)}` : null,
|
||||
missingCosts: `${baseCommand} --missing-costs`,
|
||||
json: `${baseCommand} --json`,
|
||||
},
|
||||
remote: compactCapture(remote, { full: !ok || report === null }),
|
||||
valuesPrinted: false,
|
||||
};
|
||||
@@ -41,6 +58,9 @@ function parseProfitOptions(args: string[], defaultWindow: string): ProfitOption
|
||||
let since = defaultWindow;
|
||||
let targetId = defaultCodexPoolRuntimeTargetId();
|
||||
let json = false;
|
||||
let accounts = false;
|
||||
let missingCosts = false;
|
||||
let pageToken: string | null = null;
|
||||
const readValue = (index: number, option: string): [string, number] => {
|
||||
const value = args[index + 1];
|
||||
if (value === undefined || value.startsWith("--")) throw new Error(`${option} requires a value`);
|
||||
@@ -49,6 +69,11 @@ function parseProfitOptions(args: string[], defaultWindow: string): ProfitOption
|
||||
for (let index = 0; index < args.length; index += 1) {
|
||||
const arg = args[index]!;
|
||||
if (arg === "--json") json = true;
|
||||
else if (arg === "--accounts") accounts = true;
|
||||
else if (arg === "--missing-costs") missingCosts = true;
|
||||
else if (arg === "--page-token") {
|
||||
[pageToken, index] = readValue(index, "--page-token");
|
||||
} else if (arg.startsWith("--page-token=")) pageToken = arg.slice("--page-token=".length).trim();
|
||||
else if (arg === "--since") {
|
||||
[since, index] = readValue(index, "--since");
|
||||
} else if (arg.startsWith("--since=")) since = arg.slice("--since=".length).trim();
|
||||
@@ -59,7 +84,10 @@ function parseProfitOptions(args: string[], defaultWindow: string): ProfitOption
|
||||
}
|
||||
if (!/^[1-9][0-9]*(?:s|m|h|d)$/u.test(since)) throw new Error("--since must be a duration such as 24h, 90m, or 7d");
|
||||
if (!targetId || /[\r\n\0]/u.test(targetId)) throw new Error("--target has an unsupported format");
|
||||
return { since, targetId, json };
|
||||
if (accounts && missingCosts) throw new Error("--accounts and --missing-costs are separate semantic disclosures");
|
||||
if (pageToken !== null && !accounts) throw new Error("--page-token requires --accounts");
|
||||
if (pageToken !== null && (!pageToken || /[\r\n\0\s]/u.test(pageToken))) throw new Error("--page-token has an unsupported format");
|
||||
return { since, targetId, json, accounts, missingCosts, pageToken };
|
||||
}
|
||||
|
||||
function renderProfitHelp(defaultWindow: string): RenderedCliResult {
|
||||
@@ -69,13 +97,16 @@ 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] [--json]",
|
||||
" bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token <token>]|--missing-costs] [--json]",
|
||||
"Options:",
|
||||
` --since <duration> Native usage window; YAML default is ${defaultWindow}.`,
|
||||
" --target <id>",
|
||||
" --accounts Include one fixed-size account page with complete names and IDs.",
|
||||
" --page-token <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:",
|
||||
" Default output is a Kubernetes-style account list plus both profit scopes.",
|
||||
" Default output is a compact summary; use --accounts or --missing-costs for semantic disclosure.",
|
||||
" This command is read-only and does not change Sub2API runtime state.",
|
||||
].join("\n"),
|
||||
contentType: "text/plain",
|
||||
@@ -88,37 +119,57 @@ function renderProfit(response: Record<string, unknown>): RenderedCliResult {
|
||||
const policy = record(report.policy);
|
||||
const summary = record(report.summary);
|
||||
const completeness = record(report.completeness);
|
||||
const confirmedCosts = record(summary.confirmedCostsCny);
|
||||
const profitBeforeUnknownCosts = record(summary.profitBeforeUnknownCostsCny);
|
||||
const unknownBasis = record(summary.unknownCostBasisApiUsd);
|
||||
const formulas = record(summary.profitFormula);
|
||||
const disclosure = record(response.disclosure);
|
||||
const lines = [
|
||||
`SUB2API PROFIT status=${text(report.status)} target=${text(record(response.target).id)} window=${text(window.since)}`,
|
||||
`WINDOW ${text(window.startAt)} -> ${text(window.endAt)} SOURCE native-admin-usage/${text(record(report.source).usageCostField)}`,
|
||||
`POLICY sale-rate=${text(policy.saleRateCnyPerApiUsd)}CNY/API_USD account-cost=${text(policy.accountCostSource)}`,
|
||||
"",
|
||||
"ACCOUNTS",
|
||||
"SUMMARY",
|
||||
];
|
||||
const accounts = arrayOfRecords(report.accounts);
|
||||
lines.push(table(
|
||||
["GROUP", "CLASS", "ACCOUNT", "ID", "REQ", "TOKENS", "API_USD", "COST_CNY/USD", "REVENUE_CNY", "UPSTREAM_CNY", "PROFIT_CNY", "STATUS"],
|
||||
accounts.map((row) => [
|
||||
text(row.groupName), text(row.class), text(row.accountName), text(row.accountId), text(row.requestCount), compactTokens(row.tokenCount),
|
||||
apiUsd(row.apiAmountUsd), text(row.costRateCnyPerApiUsd), cny(row.revenueCny), cny(row.upstreamCostCny), cny(row.profitContributionCny), text(row.completeness),
|
||||
]),
|
||||
));
|
||||
lines.push("", "PROFIT");
|
||||
lines.push(table(
|
||||
["SCOPE", "STATUS", "REVENUE_CNY", "PROFIT_POOL_CNY", "SELF_USE_CNY", "PROFIT_CNY"],
|
||||
["SCOPE", "STATUS", "REVENUE_CNY", "PROFIT_POOL_COST_CNY", "SELF_USE_COST_CNY", "PROFIT_BEFORE_UNKNOWN_COSTS_CNY", "UNKNOWN_API_USD"],
|
||||
[
|
||||
["不扣自用", text(record(summary.withoutSelfUse).status), cny(summary.revenueCny), cny(summary.profitPoolCostCny), "-", cny(record(summary.withoutSelfUse).profitCny)],
|
||||
["扣除自用", text(record(summary.withSelfUse).status), cny(summary.revenueCny), cny(summary.profitPoolCostCny), cny(summary.selfUseCostCny), cny(record(summary.withSelfUse).profitCny)],
|
||||
["不扣自用", text(record(summary.withoutSelfUse).status), cny(summary.revenueCny), cny(confirmedCosts.profitPool), "-", cny(profitBeforeUnknownCosts.withoutSelfUse), apiUsd(unknownBasis.profitPool)],
|
||||
["扣除自用", text(record(summary.withSelfUse).status), cny(summary.revenueCny), cny(confirmedCosts.profitPool), cny(confirmedCosts.selfUse), cny(profitBeforeUnknownCosts.withSelfUse), apiUsd(unknownBasis.total)],
|
||||
],
|
||||
));
|
||||
lines.push("", "FORMULA");
|
||||
lines.push(`- 不扣自用: ${text(formulas.withoutSelfUse)}`);
|
||||
lines.push(`- 扣除自用: ${text(formulas.withSelfUse)}`);
|
||||
lines.push("", `COMPLETENESS status=${text(report.status)} missing-cost=${text(completeness.missingCostAccountCount)} unclassified=${text(completeness.unclassifiedTrafficCount)} missing-groups=${text(completeness.configuredGroupMissingCount)}`);
|
||||
lines.push(`NEXT accounts: ${text(disclosure.accounts)}`);
|
||||
lines.push(`NEXT missing-costs: ${text(disclosure.missingCosts)}`);
|
||||
const accounts = arrayOfRecords(report.accounts);
|
||||
if (accounts.length > 0) {
|
||||
lines.push("", "ACCOUNTS");
|
||||
lines.push(table(
|
||||
["GROUP", "CLASS", "ACCOUNT", "ID", "REQ", "TOKENS", "API_USD", "COST_CNY/USD", "REVENUE_CNY", "UPSTREAM_CNY", "PROFIT_CNY", "STATUS"],
|
||||
accounts.map((row) => [
|
||||
text(row.groupName), text(row.class), text(row.accountName), text(row.accountId), text(row.requestCount), compactTokens(row.tokenCount),
|
||||
apiUsd(row.apiAmountUsd), text(row.costRateCnyPerApiUsd), cny(row.revenueCny), cny(row.upstreamCostCny), cny(row.profitContributionCny), text(row.completeness),
|
||||
]),
|
||||
));
|
||||
const accountPage = record(report.accountPage);
|
||||
if (accountPage.nextPageToken) lines.push(`NEXT account-page: ${text(disclosure.accountsNext)}`);
|
||||
}
|
||||
const missingCosts = arrayOfRecords(completeness.missingCostAccounts);
|
||||
const unclassified = arrayOfRecords(completeness.unclassifiedTraffic);
|
||||
const missingGroups = Array.isArray(completeness.configuredGroupsMissingAtRuntime) ? completeness.configuredGroupsMissingAtRuntime : [];
|
||||
if (missingCosts.length || unclassified.length || missingGroups.length) {
|
||||
lines.push("", "COMPLETENESS");
|
||||
for (const row of missingCosts) lines.push(`- missing-cost group=${text(row.groupName)} account=${text(row.accountName)} id=${text(row.accountId)}`);
|
||||
for (const row of unclassified) lines.push(`- unclassified-traffic group=${text(row.groupName)} account=${text(row.accountName)} requests=${text(row.requestCount)}`);
|
||||
for (const group of missingGroups) lines.push(`- configured-group-missing ${text(group)}`);
|
||||
if (missingCosts.length > 0) {
|
||||
lines.push("", "MISSING COST ACCOUNTS");
|
||||
for (const row of missingCosts) lines.push(`- class=${text(row.class)} group=${text(row.groupName)} account=${text(row.accountName)} id=${text(row.accountId)} api-usd=${text(row.apiAmountUsd)}`);
|
||||
}
|
||||
if (accounts.length > 0 || missingCosts.length > 0) {
|
||||
const unclassified = arrayOfRecords(completeness.unclassifiedTraffic);
|
||||
const missingGroups = Array.isArray(completeness.configuredGroupsMissingAtRuntime) ? completeness.configuredGroupsMissingAtRuntime : [];
|
||||
if (unclassified.length || missingGroups.length) {
|
||||
lines.push("", "COMPLETENESS DETAILS");
|
||||
for (const row of unclassified) lines.push(`- unclassified-traffic group=${text(row.groupName)} account=${text(row.accountName)} requests=${text(row.requestCount)}`);
|
||||
for (const group of missingGroups) lines.push(`- configured-group-missing ${text(group)}`);
|
||||
}
|
||||
}
|
||||
return {
|
||||
ok: response.ok === true,
|
||||
@@ -129,6 +180,60 @@ function renderProfit(response: Record<string, unknown>): RenderedCliResult {
|
||||
};
|
||||
}
|
||||
|
||||
function projectProfitReport(report: Record<string, unknown> | null, options: ProfitOptions): Record<string, unknown> | null {
|
||||
if (report === null) return null;
|
||||
const { accounts: rawAccounts, completeness: rawCompleteness, ...summaryReport } = report;
|
||||
const accounts = arrayOfRecords(rawAccounts);
|
||||
const completeness = record(rawCompleteness);
|
||||
const compactCompleteness = {
|
||||
missingCostAccountCount: arrayOfRecords(completeness.missingCostAccounts).length,
|
||||
unclassifiedTrafficCount: arrayOfRecords(completeness.unclassifiedTraffic).length,
|
||||
configuredGroupMissingCount: Array.isArray(completeness.configuredGroupsMissingAtRuntime) ? completeness.configuredGroupsMissingAtRuntime.length : 0,
|
||||
};
|
||||
const compactReport = {
|
||||
...summaryReport,
|
||||
accountCount: accounts.length,
|
||||
completeness: compactCompleteness,
|
||||
};
|
||||
if (options.missingCosts) {
|
||||
return {
|
||||
...compactReport,
|
||||
completeness: {
|
||||
...compactCompleteness,
|
||||
missingCostAccounts: arrayOfRecords(completeness.missingCostAccounts),
|
||||
},
|
||||
};
|
||||
}
|
||||
if (!options.accounts) return compactReport;
|
||||
let startIndex = 0;
|
||||
if (options.pageToken !== null) {
|
||||
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 && pageAccounts.length > 0 ? encodeProfitAccountPageToken(pageAccounts.at(-1)!) : null;
|
||||
return {
|
||||
...compactReport,
|
||||
accounts: pageAccounts,
|
||||
accountPage: {
|
||||
pageSize: PROFIT_ACCOUNT_PAGE_SIZE,
|
||||
returned: pageAccounts.length,
|
||||
nextPageToken,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function encodeProfitAccountPageToken(account: Record<string, unknown>): 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<string, unknown>): RenderedCliResult {
|
||||
return {
|
||||
ok: response.ok === true,
|
||||
|
||||
@@ -178,11 +178,13 @@ def run_profit_report():
|
||||
revenue = sum((profit_decimal(row["revenueCny"]) for row in profit_accounts), profit_decimal(0))
|
||||
profit_cost = sum((profit_decimal(row["upstreamCostCny"]) for row in profit_accounts if row["upstreamCostCny"] is not None), profit_decimal(0))
|
||||
self_cost = sum((profit_decimal(row["upstreamCostCny"]) for row in self_accounts if row["upstreamCostCny"] is not None), profit_decimal(0))
|
||||
without_self = revenue - profit_cost
|
||||
with_self = without_self - self_cost
|
||||
unknown_profit_api_usd = sum((profit_decimal(row["apiAmountUsd"]) for row in missing_profit), profit_decimal(0))
|
||||
unknown_self_api_usd = sum((profit_decimal(row["apiAmountUsd"]) for row in missing_self), profit_decimal(0))
|
||||
profit_before_unknown_without_self = revenue - profit_cost
|
||||
profit_before_unknown_with_self = profit_before_unknown_without_self - self_cost
|
||||
without_complete = not missing_profit and not unclassified
|
||||
with_complete = without_complete and not missing_self
|
||||
account_rows.sort(key=lambda row: (row["class"], row["groupName"], -profit_decimal(row["apiAmountUsd"]), str(row["accountName"])))
|
||||
account_rows.sort(key=lambda row: (row["class"], row["groupName"], str(row["accountId"]), str(row["accountName"])))
|
||||
return {
|
||||
"ok": True,
|
||||
"mode": "profit",
|
||||
@@ -194,13 +196,29 @@ def run_profit_report():
|
||||
"accounts": account_rows,
|
||||
"summary": {
|
||||
"revenueCny": profit_decimal_text(revenue),
|
||||
"profitPoolCostCny": profit_decimal_text(profit_cost),
|
||||
"selfUseCostCny": profit_decimal_text(self_cost),
|
||||
"withoutSelfUse": {"status": "complete" if without_complete else "partial", "profitCny": profit_decimal_text(without_self) if without_complete else None},
|
||||
"withSelfUse": {"status": "complete" if with_complete else "partial", "profitCny": profit_decimal_text(with_self) if with_complete else None},
|
||||
"confirmedCostsCny": {
|
||||
"profitPool": profit_decimal_text(profit_cost),
|
||||
"selfUse": profit_decimal_text(self_cost),
|
||||
"total": profit_decimal_text(profit_cost + self_cost),
|
||||
},
|
||||
"profitBeforeUnknownCostsCny": {
|
||||
"withoutSelfUse": profit_decimal_text(profit_before_unknown_without_self),
|
||||
"withSelfUse": profit_decimal_text(profit_before_unknown_with_self),
|
||||
},
|
||||
"unknownCostBasisApiUsd": {
|
||||
"profitPool": profit_decimal_text(unknown_profit_api_usd),
|
||||
"selfUse": profit_decimal_text(unknown_self_api_usd),
|
||||
"total": profit_decimal_text(unknown_profit_api_usd + unknown_self_api_usd),
|
||||
},
|
||||
"profitFormula": {
|
||||
"withoutSelfUse": "profitBeforeUnknownCostsCny.withoutSelfUse - sum(missing profit account apiAmountUsd * unknown costRateCnyPerApiUsd)",
|
||||
"withSelfUse": "profitBeforeUnknownCostsCny.withSelfUse - sum(all missing account apiAmountUsd * unknown costRateCnyPerApiUsd)",
|
||||
},
|
||||
"withoutSelfUse": {"status": "complete" if without_complete else "partial", "profitCny": profit_decimal_text(profit_before_unknown_without_self) if without_complete else None},
|
||||
"withSelfUse": {"status": "complete" if with_complete else "partial", "profitCny": profit_decimal_text(profit_before_unknown_with_self) if with_complete else None},
|
||||
},
|
||||
"completeness": {
|
||||
"missingCostAccounts": [{"groupName": row["groupName"], "accountId": row["accountId"], "accountName": row["accountName"]} for row in missing_profit + missing_self],
|
||||
"missingCostAccounts": [{"class": row["class"], "groupName": row["groupName"], "accountId": row["accountId"], "accountName": row["accountName"], "apiAmountUsd": row["apiAmountUsd"]} for row in missing_profit + missing_self],
|
||||
"unclassifiedTraffic": [{"groupName": row["groupName"], "accountId": row["accountId"], "accountName": row["accountName"], "requestCount": row["requestCount"]} for row in unclassified],
|
||||
"configuredGroupsMissingAtRuntime": sorted(configured_names - runtime_names),
|
||||
},
|
||||
|
||||
@@ -374,7 +374,7 @@ export function codexPoolHelp(): unknown {
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool runtime get --account <name-or-id> [--target PK01] [--json|--full|--raw]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool runtime errors [--group <name-or-id>|--all-groups] [--platform <name>] [--page-token <group-id>] [--account <name-or-id>] [--since 24h] [--tail 50000] [--target PK01] [--json|--full|--raw]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool faults [--level P0|P1|P2] [--group <name-or-id>] [--account <name-or-id>] [--model <model>] [--stream sync|stream] [--endpoint <path>] [--request-id <id>] [--page-token <token>] [--target PK01] [--json]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--json]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token <token>]|--missing-costs] [--json]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --account <name-or-id> --template <id> [--target PK01] [--confirm]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --accounts <name-or-id,...> --template <id> [--target PK01] [--confirm] [--full|--raw]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool runtime delete --account <name-or-id> --kind temp-unschedulable [--target PK01] [--confirm]",
|
||||
|
||||
@@ -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 <requestId>",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool feedback --user <email-or-id> [--window 30m] [--page-token <token>|--request-id <client-or-internal-id>] [--json]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--json]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token <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 <requestId>",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool feedback --user <email-or-id> [--window 30m] [--page-token <token>|--request-id <client-or-internal-id>] [--json]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--json]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool profit [--since 24h] [--target PK01] [--accounts [--page-token <token>]|--missing-costs] [--json]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-image status",
|
||||
],
|
||||
module: "scripts/src/platform-infra-sub2api-codex.ts",
|
||||
|
||||
Reference in New Issue
Block a user