feat: 增强 Sub2API 错误归因与优先级控制
This commit is contained in:
@@ -83,6 +83,7 @@ bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --target PK01
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --target PK01 --account <name-or-id> --template <template-id> --confirm
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --target PK01 --accounts <id-or-exact-name,...> --template <template-id>
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --target PK01 --accounts <id-or-exact-name,...> --template <template-id> --confirm
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --target PK01 --accounts <id-or-exact-name,...> --kind priority --priority <0-1000> --confirm
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool runtime delete --target PK01 --account <name-or-id> --kind temp-unschedulable
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool runtime apply --target PK01 --account <name-or-id> --kind model-mapping --model <client-model> --upstream-model <upstream-model>
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool runtime delete --target PK01 --account <name-or-id> --kind model-mapping --model <client-model>
|
||||
@@ -135,6 +136,10 @@ bun scripts/cli.ts platform-infra sub2api codex-pool cleanup-probes --target D60
|
||||
- 手工账号需要采用模板时:
|
||||
- 写入使用显式 `runtime apply --account ...` 或 `--accounts ... --template ... --confirm`。
|
||||
- 删除使用相同显式 selector 的 `runtime delete --kind temp-unschedulable --confirm`。
|
||||
- 账号全局 `priority` 使用 `runtime apply --kind priority --priority <0-1000>`:
|
||||
- 数值越小优先级越高,不存在分组级 priority;
|
||||
- 单账号和精准批量都必须先 dry-run,确认写入后逐账号回读并显示 before、desired、actual 与 reconciled;
|
||||
- 只更新账号 priority,不携带 credentials、分组、容量、代理、状态、可调度或临时不可调度字段。
|
||||
- 模型映射先用 `runtime models --account ...` 获取原生配置与实时上游能力:
|
||||
- 只有实时模型列表或真实模型请求证明支持时才确认写入。
|
||||
- 禁止把名称相近的模型猜测为别名。
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { RenderedCliResult } from "../output";
|
||||
import { isRecord, stringValue } from "./config-utils";
|
||||
import { renderTable } from "./render";
|
||||
import type { RuntimeOptions } from "./runtime-options";
|
||||
|
||||
export function renderRuntimeMutationResult(ok: boolean, options: RuntimeOptions, parsed: Record<string, unknown> | null, exitCode: number): RenderedCliResult {
|
||||
const summary = parsed !== null && isRecord(parsed.summary) ? parsed.summary : {};
|
||||
const items = parsed !== null && Array.isArray(parsed.items) ? parsed.items.filter(isRecord) : [];
|
||||
const lines = [[
|
||||
"SUB2API RUNTIME", `operation=${options.action}`, `mode=${stringValue(parsed?.mode) ?? (options.confirm ? "confirmed" : "dry-run")}`,
|
||||
`ok=${ok ? "true" : "false"}`, `selected=${summary.selected ?? items.length}`, `changed=${summary.changed ?? "?"}`,
|
||||
`writeSucceeded=${summary.writeSucceeded ?? "?"}`, `writeFailed=${summary.writeFailed ?? "?"}`,
|
||||
`reconciled=${summary.reconciled ?? "?"}`, `mismatched=${summary.mismatched ?? "?"}`,
|
||||
].join(" ")];
|
||||
if (items.length > 0) {
|
||||
const fields = items.map((item) => ({
|
||||
item,
|
||||
write: isRecord(item.write) ? item.write : {},
|
||||
before: isRecord(item.before) ? item.before : {},
|
||||
desired: isRecord(item.desired) ? item.desired : {},
|
||||
actual: isRecord(item.actual) ? item.actual : {},
|
||||
}));
|
||||
if (options.kind === "priority") lines.push(renderTable([
|
||||
["ACCOUNT", "ID", "CHANGE", "WRITE", "RECONCILED", "BEFORE_PRIORITY", "DESIRED_PRIORITY", "ACTUAL_PRIORITY", "FAILURE"],
|
||||
...fields.map(({ item, write, before, desired, actual }) => [
|
||||
stringValue(item.accountName) ?? "-", String(item.accountId ?? "-"), stringValue(item.change) ?? "-",
|
||||
stringValue(write.status) ?? "-", item.reconciled === true ? "true" : item.reconciled === false ? "false" : "-",
|
||||
String(before.priority ?? "-"), String(desired.priority ?? "-"), String(actual.priority ?? "-"),
|
||||
stringValue(write.error) ?? stringValue(item.reconcileError) ?? "-",
|
||||
]),
|
||||
]));
|
||||
else lines.push(renderTable([
|
||||
["ACCOUNT", "ID", "CHANGE", "WRITE", "RECONCILED", "BEFORE", "DESIRED", "ACTUAL", "BEFORE_CODES", "DESIRED_CODES", "ACTUAL_CODES", "FAILURE"],
|
||||
...fields.map(({ item, write, before, desired, actual }) => {
|
||||
const codes = (value: unknown): string => Array.isArray(value) ? value.join(",") || "-" : "-";
|
||||
return [
|
||||
stringValue(item.accountName) ?? "-", String(item.accountId ?? "-"), stringValue(item.change) ?? "-",
|
||||
stringValue(write.status) ?? "-", item.reconciled === true ? "true" : item.reconciled === false ? "false" : "-",
|
||||
String(before.ruleCount ?? "-"), String(desired.ruleCount ?? "-"), String(actual.ruleCount ?? "-"),
|
||||
codes(before.statusCodes), codes(desired.statusCodes), codes(actual.statusCodes),
|
||||
stringValue(write.error) ?? stringValue(item.reconcileError) ?? "-",
|
||||
];
|
||||
}),
|
||||
]));
|
||||
} else if (parsed !== null && typeof parsed.error === "string") lines.push(`ERROR ${parsed.error}`);
|
||||
else if (parsed === null) lines.push(`ERROR runtime output unavailable remote_exit=${exitCode}`);
|
||||
return { ok, command: "platform-infra sub2api codex-pool runtime", renderedText: lines.join("\n"), contentType: "text/plain", projection: parsed ?? undefined };
|
||||
}
|
||||
@@ -11,7 +11,8 @@ export interface RuntimeOptions {
|
||||
platform: string | null;
|
||||
pageToken: string | null;
|
||||
template: string | null;
|
||||
kind: "temp-unschedulable";
|
||||
kind: "temp-unschedulable" | "priority";
|
||||
priority: number | null;
|
||||
confirm: boolean;
|
||||
full: boolean;
|
||||
raw: boolean;
|
||||
@@ -24,7 +25,7 @@ export interface RuntimeOptions {
|
||||
export function parseRuntimeOptions(args: string[]): RuntimeOptions {
|
||||
const [actionRaw = "list", ...rest] = args;
|
||||
if (!(["list", "get", "errors", "infrastructure", "apply", "delete"] as string[]).includes(actionRaw)) {
|
||||
throw new Error("runtime usage: list|get|errors|infrastructure|apply|delete [--account <name-or-id>|--accounts <selectors>] [--group <name-or-id>|--all-groups] [--platform <name>] [--page-token <token>] [--since 24h] [--tail 50000] [--template <id>] [--kind temp-unschedulable] [--confirm] [--target <id>] [--json|--full|--raw]");
|
||||
throw new Error("runtime usage: list|get|errors|infrastructure|apply|delete [--account <name-or-id>|--accounts <selectors>] [--group <name-or-id>|--all-groups] [--platform <name>] [--page-token <token>] [--since 24h] [--tail 50000] [--template <id>] [--kind temp-unschedulable|priority] [--priority <0-1000>] [--confirm] [--target <id>] [--json|--full|--raw]");
|
||||
}
|
||||
let account: string | null = null;
|
||||
let accounts: string[] = [];
|
||||
@@ -33,7 +34,8 @@ export function parseRuntimeOptions(args: string[]): RuntimeOptions {
|
||||
let platform: string | null = null;
|
||||
let pageToken: string | null = null;
|
||||
let template: string | null = null;
|
||||
let kind = "temp-unschedulable" as const;
|
||||
let kind: "temp-unschedulable" | "priority" = "temp-unschedulable";
|
||||
let priority: number | null = null;
|
||||
let confirm = false;
|
||||
let full = false;
|
||||
let raw = false;
|
||||
@@ -69,6 +71,8 @@ export function parseRuntimeOptions(args: string[]): RuntimeOptions {
|
||||
else if (arg.startsWith("--template=")) template = arg.slice("--template=".length).trim();
|
||||
else if (arg === "--kind") kind = parseRuntimeKind(readValue("--kind"));
|
||||
else if (arg.startsWith("--kind=")) kind = parseRuntimeKind(arg.slice("--kind=".length));
|
||||
else if (arg === "--priority") priority = parsePriority(readValue("--priority"));
|
||||
else if (arg.startsWith("--priority=")) priority = parsePriority(arg.slice("--priority=".length));
|
||||
else if (arg === "--target") targetId = readValue("--target");
|
||||
else if (arg.startsWith("--target=")) targetId = arg.slice("--target=".length).trim();
|
||||
else if (arg === "--since") since = readValue("--since");
|
||||
@@ -91,13 +95,17 @@ export function parseRuntimeOptions(args: string[]): RuntimeOptions {
|
||||
if ((group !== null || platform !== null) && action !== "errors" && action !== "infrastructure") throw new Error(`runtime ${action} does not accept group scope options`);
|
||||
if (pageToken !== null && !allGroups) throw new Error("--page-token requires --all-groups");
|
||||
if (account !== null && allGroups) throw new Error("--account cannot be combined with --all-groups; use --group first");
|
||||
if (action === "apply" && !template) throw new Error("runtime apply requires --template <id>");
|
||||
if (action === "apply" && kind === "temp-unschedulable" && !template) throw new Error("runtime apply --kind temp-unschedulable requires --template <id>");
|
||||
if (kind === "priority" && action !== "apply") throw new Error("runtime --kind priority only supports apply");
|
||||
if (kind === "priority" && priority === null) throw new Error("runtime apply --kind priority requires --priority <0-1000>");
|
||||
if (kind === "priority" && template !== null) throw new Error("runtime apply --kind priority does not accept --template");
|
||||
if (kind !== "priority" && priority !== null) throw new Error("--priority requires --kind priority");
|
||||
if (action !== "apply" && template !== null) throw new Error(`runtime ${action} does not accept --template`);
|
||||
if (action !== "errors" && action !== "infrastructure" && (since !== "24h" || tail !== 50_000)) throw new Error(`runtime ${action} does not accept --since or --tail`);
|
||||
if (!/^\d+[mhd]$/u.test(since)) throw new Error("--since must use <number>m, <number>h, or <number>d");
|
||||
if (["list", "get", "errors", "infrastructure"].includes(action) && confirm) throw new Error(`runtime ${action} does not accept --confirm`);
|
||||
if ([full, raw, json].filter(Boolean).length > 1) throw new Error("use only one of --json, --full, or --raw");
|
||||
return { action, account, accounts, group, allGroups, platform, pageToken, template, kind, confirm, full, raw, json, since, tail, targetId };
|
||||
return { action, account, accounts, group, allGroups, platform, pageToken, template, kind, priority, confirm, full, raw, json, since, tail, targetId };
|
||||
}
|
||||
|
||||
function parseAccountSelectors(value: string): string[] {
|
||||
@@ -108,11 +116,17 @@ function parseAccountSelectors(value: string): string[] {
|
||||
return selectors;
|
||||
}
|
||||
|
||||
function parseRuntimeKind(value: string): "temp-unschedulable" {
|
||||
if (value !== "temp-unschedulable") throw new Error("--kind must be temp-unschedulable");
|
||||
function parseRuntimeKind(value: string): "temp-unschedulable" | "priority" {
|
||||
if (value !== "temp-unschedulable" && value !== "priority") throw new Error("--kind must be temp-unschedulable or priority");
|
||||
return value;
|
||||
}
|
||||
|
||||
function parsePriority(value: string): number {
|
||||
const parsed = Number(value);
|
||||
if (!Number.isInteger(parsed) || parsed < 0 || parsed > 1000) throw new Error("--priority must be an integer from 0 to 1000");
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function parseRuntimeTail(value: string): number {
|
||||
const parsed = Number(value);
|
||||
if (!Number.isInteger(parsed) || parsed < 100 || parsed > 200_000) throw new Error("--tail must be an integer from 100 to 200000");
|
||||
|
||||
@@ -2,18 +2,18 @@ import type { UniDeskConfig } from "../config";
|
||||
import type { RenderedCliResult } from "../output";
|
||||
import { desiredAccountNames } from "./accounts";
|
||||
import { readCodexPoolConfig } from "./config";
|
||||
import { isRecord, stringValue } from "./config-utils";
|
||||
import { protectedManualAccountsForTarget } from "./public-exposure";
|
||||
import { renderSub2ApiTempUnschedulableCredentials } from "./redaction";
|
||||
import { boolField, compactCapture, parseJsonOutput, runRemoteCodexPoolScript } from "./remote";
|
||||
import { renderedCliResult, renderTable } from "./render";
|
||||
import { parseRuntimeOptions, type RuntimeOptions } from "./runtime-options";
|
||||
import { renderRuntimeMutationResult } from "./runtime-mutation-render";
|
||||
import { codexPoolRuntimeTarget } from "./runtime-target";
|
||||
export async function codexPoolRuntime(config: UniDeskConfig, args: string[]): Promise<Record<string, unknown> | RenderedCliResult> {
|
||||
const options = parseRuntimeOptions(args);
|
||||
const pool = readCodexPoolConfig();
|
||||
const target = codexPoolRuntimeTarget(options.targetId);
|
||||
const selectedTemplate = options.template === null ? null : pool.runtime.templatesById[options.template];
|
||||
const selectedTemplate = options.kind === "priority" || options.template === null ? null : pool.runtime.templatesById[options.template];
|
||||
if (options.template !== null && selectedTemplate === undefined) {
|
||||
throw new Error(`unknown runtime template ${options.template}; available: ${pool.runtime.templates.map((item) => item.id).join(", ")}`);
|
||||
}
|
||||
@@ -26,6 +26,7 @@ export async function codexPoolRuntime(config: UniDeskConfig, args: string[]): P
|
||||
platform: options.platform,
|
||||
pageToken: options.pageToken,
|
||||
kind: options.kind,
|
||||
priority: options.priority,
|
||||
confirm: options.confirm,
|
||||
full: options.full,
|
||||
since: options.since,
|
||||
@@ -81,6 +82,7 @@ export async function codexPoolRuntime(config: UniDeskConfig, args: string[]): P
|
||||
pageToken: options.pageToken,
|
||||
template: options.template,
|
||||
kind: options.kind,
|
||||
priority: options.priority,
|
||||
confirm: options.confirm,
|
||||
since: options.action === "errors" || options.action === "infrastructure" ? options.since : undefined,
|
||||
tail: options.action === "errors" || options.action === "infrastructure" ? options.tail : undefined,
|
||||
@@ -290,6 +292,7 @@ function compactCustomerErrors(value: unknown, detailed: boolean): unknown {
|
||||
accountBuckets: detailed ? runtimeRecords(profile.accountBuckets).slice(0, 5) : undefined,
|
||||
statusBuckets: runtimeRecords(profile.statusBuckets).slice(0, 5),
|
||||
streamBuckets: runtimeRecords(profile.streamBuckets).slice(0, 5),
|
||||
messageBuckets: runtimeRecords(profile.messageBuckets).slice(0, detailed ? 10 : 5),
|
||||
};
|
||||
}
|
||||
function compactAccountQuality(value: unknown, detailed: boolean): unknown {
|
||||
@@ -715,60 +718,6 @@ function renderRuntimeMutation(lines: string[], runtime: Record<string, unknown>
|
||||
]));
|
||||
}
|
||||
|
||||
function renderRuntimeMutationResult(ok: boolean, options: RuntimeOptions, parsed: Record<string, unknown> | null, exitCode: number): RenderedCliResult {
|
||||
const summary = parsed !== null && isRecord(parsed.summary) ? parsed.summary : {};
|
||||
const items = parsed !== null && Array.isArray(parsed.items) ? parsed.items.filter(isRecord) : [];
|
||||
const lines = [[
|
||||
"SUB2API RUNTIME",
|
||||
`operation=${options.action}`,
|
||||
`mode=${stringValue(parsed?.mode) ?? (options.confirm ? "confirmed" : "dry-run")}`,
|
||||
`ok=${ok ? "true" : "false"}`,
|
||||
`selected=${summary.selected ?? items.length}`,
|
||||
`changed=${summary.changed ?? "?"}`,
|
||||
`writeSucceeded=${summary.writeSucceeded ?? "?"}`,
|
||||
`writeFailed=${summary.writeFailed ?? "?"}`,
|
||||
`reconciled=${summary.reconciled ?? "?"}`,
|
||||
`mismatched=${summary.mismatched ?? "?"}`,
|
||||
].join(" ")];
|
||||
if (items.length > 0) {
|
||||
lines.push(renderTable([
|
||||
["ACCOUNT", "ID", "CHANGE", "WRITE", "RECONCILED", "BEFORE", "DESIRED", "ACTUAL", "BEFORE_CODES", "DESIRED_CODES", "ACTUAL_CODES", "FAILURE"],
|
||||
...items.map((item) => {
|
||||
const write = isRecord(item.write) ? item.write : {};
|
||||
const before = isRecord(item.before) ? item.before : {};
|
||||
const desired = isRecord(item.desired) ? item.desired : {};
|
||||
const actual = isRecord(item.actual) ? item.actual : {};
|
||||
const codes = (value: unknown): string => Array.isArray(value) ? value.join(",") || "-" : "-";
|
||||
return [
|
||||
stringValue(item.accountName) ?? "-",
|
||||
String(item.accountId ?? "-"),
|
||||
stringValue(item.change) ?? "-",
|
||||
stringValue(write.status) ?? "-",
|
||||
item.reconciled === true ? "true" : item.reconciled === false ? "false" : "-",
|
||||
String(before.ruleCount ?? "-"),
|
||||
String(desired.ruleCount ?? "-"),
|
||||
String(actual.ruleCount ?? "-"),
|
||||
codes(before.statusCodes),
|
||||
codes(desired.statusCodes),
|
||||
codes(actual.statusCodes),
|
||||
stringValue(write.error) ?? stringValue(item.reconcileError) ?? "-",
|
||||
];
|
||||
}),
|
||||
]));
|
||||
} else if (parsed !== null && typeof parsed.error === "string") {
|
||||
lines.push(`ERROR ${parsed.error}`);
|
||||
} else if (parsed === null) {
|
||||
lines.push(`ERROR runtime output unavailable remote_exit=${exitCode}`);
|
||||
}
|
||||
return {
|
||||
ok,
|
||||
command: "platform-infra sub2api codex-pool runtime",
|
||||
renderedText: lines.join("\n"),
|
||||
contentType: "text/plain",
|
||||
projection: parsed ?? undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function pyJson(value: unknown): string {
|
||||
return `json.loads(${JSON.stringify(JSON.stringify(value))})`;
|
||||
}
|
||||
@@ -1918,6 +1867,7 @@ def native_customer_error_profile(token, group_id, platform):
|
||||
"accountBuckets": buckets(lambda row: row.get("account_id")),
|
||||
"statusBuckets": buckets(lambda row: row.get("status_code")),
|
||||
"streamBuckets": buckets(lambda row: "stream" if row.get("stream") is True else "sync" if row.get("stream") is False else "unknown"),
|
||||
"messageBuckets": buckets(lambda row: compact_error(row.get("message") or row.get("error_message"))),
|
||||
"phaseBuckets": buckets(lambda row: row.get("phase")),
|
||||
"endpointBuckets": buckets(lambda row: row.get("inbound_endpoint") or row.get("request_path")),
|
||||
"pathBuckets": buckets(lambda row: row.get("request_path") or row.get("inbound_endpoint")),
|
||||
@@ -2851,13 +2801,26 @@ def selected_account_details(token, accounts):
|
||||
account_id = detail.get("id")
|
||||
if account_id in selected_ids:
|
||||
raise RuntimeError("duplicate-account-selector: " + selector)
|
||||
if detail.get("type") != "apikey":
|
||||
if PAYLOAD.get("kind") == "temp-unschedulable" and detail.get("type") != "apikey":
|
||||
raise RuntimeError("runtime temp-unschedulable policy requires an apikey account: " + selector)
|
||||
selected_ids.add(account_id)
|
||||
details.append(detail)
|
||||
return details
|
||||
|
||||
def mutation_plan(detail, action, include_rules):
|
||||
if PAYLOAD.get("kind") == "priority":
|
||||
before_priority = int(detail.get("priority") or 0)
|
||||
desired_priority = int(PAYLOAD.get("priority"))
|
||||
return {
|
||||
"accountName": detail.get("name"),
|
||||
"accountId": detail.get("id"),
|
||||
"change": "noop" if before_priority == desired_priority else "update",
|
||||
"before": {"priority": before_priority},
|
||||
"desired": {"priority": desired_priority},
|
||||
"template": None,
|
||||
"_kind": "priority",
|
||||
"_desiredPriority": desired_priority,
|
||||
}
|
||||
credentials = dict(detail.get("credentials") or {})
|
||||
before = normalize_policy(credentials)
|
||||
if action == "apply":
|
||||
@@ -2884,13 +2847,15 @@ def mutation_plan(detail, action, include_rules):
|
||||
"template": PAYLOAD.get("selectedTemplate", {}).get("id") if isinstance(PAYLOAD.get("selectedTemplate"), dict) else None,
|
||||
"_desiredCredentials": desired,
|
||||
"_desiredPolicy": desired_policy,
|
||||
"_kind": "temp-unschedulable",
|
||||
}
|
||||
|
||||
def write_mutation_plan(token, plan):
|
||||
if plan["change"] == "noop":
|
||||
return {"attempted": False, "status": "noop", "error": None}
|
||||
try:
|
||||
data_of(curl_api("PUT", f"/api/v1/admin/accounts/{plan['accountId']}", bearer=token, payload={"credentials": plan["_desiredCredentials"]}), "update account runtime config")
|
||||
payload = {"priority": plan["_desiredPriority"]} if plan["_kind"] == "priority" else {"credentials": plan["_desiredCredentials"]}
|
||||
data_of(curl_api("PUT", f"/api/v1/admin/accounts/{plan['accountId']}", bearer=token, payload=payload), "update account runtime config")
|
||||
return {"attempted": True, "status": "succeeded", "error": None}
|
||||
except Exception as exc:
|
||||
return {"attempted": True, "status": "failed", "error": compact_error(str(exc))}
|
||||
@@ -2900,9 +2865,14 @@ def reconcile_mutation_plan(token, plan, write, include_rules):
|
||||
item["write"] = write
|
||||
try:
|
||||
actual_detail = account_detail(token, plan["accountId"])
|
||||
actual_policy = normalize_policy(actual_detail.get("credentials"))
|
||||
item["actual"] = policy_summary(actual_policy, include_rules)
|
||||
item["reconciled"] = actual_policy == plan["_desiredPolicy"]
|
||||
if plan["_kind"] == "priority":
|
||||
actual_priority = int(actual_detail.get("priority") or 0)
|
||||
item["actual"] = {"priority": actual_priority}
|
||||
item["reconciled"] = actual_priority == plan["_desiredPriority"]
|
||||
else:
|
||||
actual_policy = normalize_policy(actual_detail.get("credentials"))
|
||||
item["actual"] = policy_summary(actual_policy, include_rules)
|
||||
item["reconciled"] = actual_policy == plan["_desiredPolicy"]
|
||||
item["reconcileError"] = None
|
||||
except Exception as exc:
|
||||
item["actual"] = None
|
||||
|
||||
@@ -397,6 +397,7 @@ export function codexPoolHelp(): unknown {
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool error-passthrough list|apply|delete [--template <id>] [--target PK01] [--confirm] [--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 apply --accounts <name-or-id,...> --kind priority --priority <0-1000> [--target PK01] [--confirm]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool runtime delete --account <name-or-id> --kind temp-unschedulable [--target PK01] [--confirm]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool runtime delete --accounts <name-or-id,...> --kind temp-unschedulable [--target PK01] [--confirm] [--full|--raw]",
|
||||
"bun scripts/cli.ts platform-infra sub2api codex-pool trace [--target D601] --request-id <requestId> [--since 24h|--tail 20000|--context-seconds 300|--show-lines|--raw]",
|
||||
|
||||
Reference in New Issue
Block a user