docs: keep sub2api capacity YAML-controlled

This commit is contained in:
Codex
2026-06-09 08:47:57 +00:00
parent 8decc7d187
commit a802a953cf
5 changed files with 11 additions and 10 deletions
+4 -4
View File
@@ -58,7 +58,7 @@ bun scripts/cli.ts platform-infra sub2api codex-pool validate
- `pool.minOwnerBalanceUsd`: pool key owner 最低余额,sync/validate 会补齐。
- `pool.defaultTempUnschedulable`: 默认账号级临时下线规则;用于在上游返回容量、限流、overload 或认证状态异常时,让 Sub2API 冷却该账号并切换到同组其他账号。
- `profiles.entries`: 从 master `~/.codex/` 选择上游 profile 并映射到 Sub2API account。
- `profiles.entries[].capacity`: 可选 per-account concurrency override;不写则使用 `pool.defaultAccountCapacity`不要因为某 provider 当前看起来更可用就给 HY 或任一账号写容量钉死;容量 override 必须来自明确 YAML 决策和新鲜 runtime 证据
- `profiles.entries[].capacity`: 可选 per-account concurrency override;不写则使用 `pool.defaultAccountCapacity`具体数值只以 `config/platform-infra/sub2api-codex-pool.yaml` 为准,skill 和长期参考只描述规则,不重复写当前值
- `profiles.entries[].tempUnschedulable`: 可选 per-account 临时下线规则覆盖;字段语义以 `docs/reference/platform-infra.md` 为权威。
- `profiles.entries[].openaiResponsesWebSocketsV2Mode`: 需要 Responses WebSocket v2 的上游才设置,值为 `off``ctx_pool``passthrough`
- `profiles.entries[].upstreamUserAgent`: 少数要求 Codex CLI User-Agent 的上游才设置,不能含换行。
@@ -73,7 +73,7 @@ WebSocket v2 是账号能力集合,不是调度 pin。`openaiResponsesWebSocke
1. 在 master `~/.codex/` 准备 profile 文件,例如 `config.toml.<profile>``auth.json.<profile>`
2.`config/platform-infra/sub2api-codex-pool.yaml` 添加 `profiles.entries` 项,指定 `profile``accountName``configFile``authFile`
3. 如需要,给该项加 `priority``capacity``tempUnschedulable``openaiResponsesWebSocketsV2Mode``upstreamUserAgent`不要用 `capacity` 把 HY 或任一账号变成硬编码 fallback
3. 如需要,给该项加 `priority``capacity``tempUnschedulable``openaiResponsesWebSocketsV2Mode``upstreamUserAgent`capacity 的具体数值只写在 YAML
4.`codex-pool plan`,确认 profile 可读、`base_url` 和 API key 来源有效,且 stdout 未泄露完整 key。
5.`codex-pool sync --confirm`
6.`codex-pool validate`
@@ -136,11 +136,11 @@ bun scripts/cli.ts platform-infra sub2api codex-pool configure-local --confirm
- pool key 401:跑 `codex-pool sync --confirm` 重建 Sub2API key 与 k3s Secret 绑定,再跑 `codex-pool validate`
- FRP 不通:先看 `codex-pool expose --confirm` 输出的 `masterFrps``sub2api-frpc` 和 public 401 probe;需要低层证据时只用 `trans G14:k3s` 做 bounded 查询。
- default profile 递归:检查 YAML default entry 是否使用 `*.pre-sub2api` 备份文件;必要时恢复备份后重新 `configure-local --confirm`
- 上游需要 WebSocket v2:只给该 profile 配 `openaiResponsesWebSocketsV2Mode: ctx_pool|passthrough`,跑 `sync --confirm`;把它当 capability candidate不要同时把它写成唯一/最高容量调度目标
- 上游需要 WebSocket v2:只给该 profile 配 `openaiResponsesWebSocketsV2Mode: ctx_pool|passthrough`,跑 `sync --confirm`;把它当 capability candidate容量仍以 YAML 中的 `capacity` 或默认值为准
- 上游要求 Codex User-Agent:只给该 profile 配 `upstreamUserAgent`,跑 `sync --confirm`
- 上游报 capacity/rate-limit/overload 后没有切号:先确认 `codex-pool validate``tempUnschedulable.ok=true` 且目标 account `runtimeEnabled=true`、规则数符合 YAML;若 mismatch,跑 `codex-pool sync --confirm`,不要手工 patch Sub2API credentials。
- Codex auto compact 后丢上下文:先确认本机 `~/.codex/config.toml` 是否有 `supports_websockets = true``responses_websockets_v2 = true`,再看 `codex-pool validate` 的 WSv2 candidate 和 Sub2API 日志里的 `transport=responses_websockets_v2`
- Codex smoke 有 reconnect/1013:这是上游并发/可用性问题,和 HTTP-only compact context-loss 分开处理;记录 session/log 证据并关联专项 issue,不要用 HY 容量钉死掩盖
- Codex smoke 有 reconnect/1013:这是上游并发/可用性问题,和 HTTP-only compact context-loss 分开处理;记录 session/log 证据并关联专项 issue,不要用运行时手补覆盖 YAML 容量
## 禁止事项
+1 -1
View File
@@ -10,7 +10,7 @@ UniDesk 是一个以主 server 为统一入口的分布式工作平台;本文
## P0 最高优先级:G14 platform-infra 规则
- P0: `platform-infra` 是 G14 k3s 上 UniDesk 运维的平台基础设施 namespaceSub2API、Codex pool、FRP 暴露、统一消费 API key 和后续平台基础设施迁移的长期边界、路由与探针口径统一见 `docs/reference/platform-infra.md`Sub2API 日常操作统一见 `$unidesk-sub2api``.agents/skills/unidesk-sub2api/SKILL.md`)。
- P0: Codex pool 账号容量与调度候选必须从 `config/platform-infra/sub2api-codex-pool.yaml` 进入受控 CLI禁止把 HY 或任一 provider 硬编码为“最可用”对象、容量钉死对象或旧测试断言
- P0: Codex pool 账号容量与调度候选必须从 `config/platform-infra/sub2api-codex-pool.yaml` 进入受控 CLI当前数值以 YAML 为准,禁止用代码常量、Secret、运行时手补或长期参考文档里的硬编码数值覆盖 YAML
- P0: `devops-infra` 仅作为既有控制面基础设施逐步迁移来源,不再作为新增平台服务的默认 namespace;新增/迁移必须优先落到 `platform-infra`,并通过 `config/platform-infra/*.yaml``bun scripts/cli.ts platform-infra ...` 受控。
## P0 最高优先级:CaseRun 无服务与单步调试规则
@@ -51,6 +51,7 @@ profiles:
configFile: config.toml.HY
authFile: auth.json.HY
openaiResponsesWebSocketsV2Mode: passthrough
capacity: 20
priority: 1
- profile: gptclub
accountName: unidesk-codex-gptclub
+2 -2
View File
@@ -27,7 +27,7 @@
- `pool.apiKeySecretName` and `pool.apiKeySecretKey` name the k3s Secret that stores the single consumer API key.
- `pool.defaultTempUnschedulable` declares Sub2API account-level temporary unschedulable rules. Keep 429/overload/capacity failures in this YAML policy so the scheduler can cool down a failing account and choose another candidate instead of hard-pinning one provider.
- `profiles.entries` selects local Codex profile files from `~/.codex/` and maps them to Sub2API account names.
- `profiles.entries[].capacity` optionally overrides `pool.defaultAccountCapacity` for one account. Capacity is a YAML-controlled routing input; omit it unless that account needs a deliberate per-account concurrency override. Code constants, Secrets, ad-hoc runtime patches, or stale tests must not override YAML source of truth.
- `profiles.entries[].capacity` optionally overrides `pool.defaultAccountCapacity` for one account. Capacity is a YAML-controlled routing input; concrete current values belong only in `config/platform-infra/sub2api-codex-pool.yaml` and runtime validation output, not in long-term reference prose. Code constants, Secrets, ad-hoc runtime patches, or stale tests must not override YAML source of truth.
- `profiles.entries[].tempUnschedulable` may override the pool default for one account. The CLI renders it into Sub2API credentials as `temp_unschedulable_enabled` and `temp_unschedulable_rules`; rules match HTTP status plus response-body keywords and place only that account into a temporary unschedulable cooldown.
- `profiles.entries[].openaiResponsesWebSocketsV2Mode` is the account-level Responses WebSocket v2 switch for OpenAI-compatible upstreams that require WebSocket transport. Allowed values are `off`, `ctx_pool`, and `passthrough`; omit the field unless that upstream needs it.
- `profiles.entries[].upstreamUserAgent` is an optional account-level upstream request User-Agent override. Use it only for upstreams that require a Codex CLI compatible User-Agent; keep the value YAML-controlled and newline-free.
@@ -36,7 +36,7 @@
Enable account-level WebSocket v2 only for upstream profiles that have passed a direct Codex WSv2 probe. Treat this as a YAML-declared capability set, not a hard scheduling pin to one profile; `codex-pool validate` must show at least one current `webSocketsV2.schedulableEnabled` account, and runtime smoke remains the availability proof. The same validation reports each managed account's runtime WebSocket v2 mode and whether it matches YAML, so stale `ctx_pool` settings cannot silently keep routing Codex WS sessions to an upstream that closes with `no available account`.
Do not encode current availability assumptions as account capacity or tests. HY is a WSv2-capable candidate in the current pool, not a privileged fallback target; if an account needs higher concurrency, that must be a deliberate YAML override backed by fresh runtime evidence and a test that still preserves multi-account scheduling.
Do not encode current availability assumptions in long-term reference prose. If an account needs a higher concurrency than `pool.defaultAccountCapacity`, make that a deliberate YAML override and verify it with `codex-pool validate`; the reference document should describe the rule, not repeat the current numeric value.
Do not enable Sub2API `pool_mode` for UniDesk-managed Codex accounts. `pool_mode` retries the same selected account path, while UniDesk's desired failover behavior is to mark the failing account temporarily unschedulable and let Sub2API choose another account from the group. `codex-pool validate` reports each managed account's temporary-unschedulable runtime alignment and should be used after `codex-pool sync --confirm`.
@@ -24,8 +24,8 @@ const rules = parsed.pool?.defaultTempUnschedulable?.rules ?? [];
const overload429 = rules.find((rule) => rule.statusCode === 429);
assertCondition(parsed.pool?.defaultAccountCapacity === 5, "Codex pool default capacity should remain explicit YAML", parsed.pool);
assertCondition(hy !== undefined, "HY profile should remain declared as a candidate, not a special scheduler target", entries);
assertCondition(hy?.capacity === undefined, "HY must not carry a hard-coded capacity override", hy);
assertCondition(hy !== undefined, "HY profile should remain declared as a YAML-managed pool candidate", entries);
assertCondition(hy?.capacity === 20, "HY capacity must remain explicitly YAML-controlled at the current configured value", hy);
assertCondition(wsEnabled.length >= 2, "Responses WSv2 should be a capability set with multiple candidates", wsEnabled);
assertCondition(parsed.pool?.defaultTempUnschedulable?.enabled === true, "temporary unschedulable policy must be enabled from YAML", parsed.pool?.defaultTempUnschedulable);
assertCondition(overload429 !== undefined, "temporary unschedulable policy must include 429 handling", rules);
@@ -35,7 +35,7 @@ assertCondition((overload429?.durationMinutes ?? 0) > 0, "429 handling must cool
console.log(JSON.stringify({
ok: true,
checks: [
"HY is not capacity-pinned",
"HY capacity is YAML-controlled",
"WSv2 routing is represented as a multi-account capability set",
"temporary unschedulable rules are YAML-controlled",
],