fix: support PK01 Codex pool sync

This commit is contained in:
Codex
2026-07-02 02:43:01 +00:00
parent 18b6b93390
commit 3a8681f458
11 changed files with 258 additions and 48 deletions
@@ -1,6 +1,8 @@
## Codex Pool
当前 codex-pool sync/validate/report/trace 适配器主要覆盖 k3s target。若 YAML 默认 targetPK01 host-Docker,不要直接把无 `--target` 的 codex-pool 命令当成验收入口;先使用 `sub2api status --target PK01``sub2api validate --target PK01` 和最小 public `/v1/responses` smoke。host-Docker codex-pool adapter 补齐前,k3s 账号池操作必须显式选择 k3s target
`codex-pool plan|sync|validate` 同时覆盖 k3s target 和 PK01 host-Docker targetPK01 host-Docker`sync --confirm` 通过 Sub2API admin API 对齐 group、YAML-managed accounts、统一消费 API key、capacity/loadFactor、WebSocket v2 标记和内置 `temp_unschedulable` 规则;统一消费 key 写入 YAML 声明的 `targets[PK01].hostDocker.envPath`,不创建 k8s Secret,不部署 sentinel 资源,也不触发 `sub2api apply`、Docker compose、Caddy reload 或容器重启。`sentinel-report``sentinel-probe``sentinel-image` 和部分 `trace` 能力仍以 k3s target 为主;需要这些能力时显式选择对应 k3s target
k3s 账号池操作示例:
```bash
bun scripts/cli.ts platform-infra sub2api codex-pool plan --target D601
@@ -17,7 +19,7 @@ bun scripts/cli.ts platform-infra sub2api codex-pool cleanup-probes --target D60
`config/platform-infra/sub2api-codex-pool.yaml` 控制:
- `pool.groupName`: Sub2API group 名称。
- `pool.apiKeySecretName` / `pool.apiKeySecretKey`: 统一消费 API key 的 k3s Secret 位置,默认 `platform-infra/sub2api-codex-pool-api-key.API_KEY`
- `pool.apiKeySecretName` / `pool.apiKeySecretKey`: 统一消费 API key 的 key 名。k3s target 写入对应 namespace 下的 k3s SecretPK01 host-Docker target 写入 `config/platform-infra/sub2api.yaml``targets[PK01].hostDocker.envPath` 声明的 env 文件
- `pool.minOwnerBalanceUsd`: pool key owner 最低余额,sync/validate 会补齐。
- `pool.minOwnerConcurrency`: 可选统一消费 API key owner 最低并发;省略时 CLI 自动使用所有已解析账号 capacity 的总和,sync/validate 会补齐。显式 YAML 值只作为 override,仍必须不小于账号 capacity 总和;未显式写 `profiles.entries[].capacity` 的账号会使用 `pool.defaultAccountCapacity` 参与求和,不要用提高某个 provider capacity 来掩盖用户并发层 WS 1013。
- `pool.defaultTempUnschedulable`: Sub2API 内置请求路径临时不可调度开关和 YAML 规则列表。当前要求是按 YAML 开启通用规则;sync 把 `temp_unschedulable_enabled` / `temp_unschedulable_rules` 渲染到 managed accounts,让匹配的 400/5xx/超时/模型路由/加密内容错误短暂冷却当前账号并触发同组 failover。
@@ -38,7 +40,7 @@ bun scripts/cli.ts platform-infra sub2api codex-pool cleanup-probes --target D60
- `manualAccounts.protected`: 已在 Sub2API 手动创建/维护、且必须排除在 UniDesk-managed Codex pool credentials 和 sentinel 控制之外的账号。默认不得改 credentials/status/schedulable/priority/capacity/loadFactor;只有显式声明 `proxyBinding` 时,`sync --confirm` 才允许把该账号的 `proxy_id` 对齐到 YAML 目标的 egress proxy;只有显式声明 `groupBinding.source: pool-group` 时,才允许把该账号加入统一消费 API key 使用的 pool group。`targetIds` 可选;省略表示所有 target 都保护该账号,设置后只在匹配 target 上纳入 proxy/group 窄同步和 sentinel-probe 拒绝列表,避免 PK01-only 手动账号漂移卡住 JD01 pool。
- Sentinel 配置、marker-only 判定、镜像、report/probe 和远端 job/poll 边界见 [sentinel.md](sentinel.md)。
对已支持的 k3s target`sync --confirm` 会登录 Sub2API admin、创建/更新 group、创建/更新 YAML 中的 `unidesk-codex-*` accounts创建/复用统一 API key Secret并部署/更新哨兵资源;不把既有 managed account 直接恢复为 `schedulable=true`。恢复只由哨兵在读取 Sub2API runtime `schedulable=false` 后触发 recovery probe,并在 marker 命中时执行。`sync` 默认不删除 YAML 中缺席的 managed account。只有明确退役上游时才使用 `sync --confirm --prune-removed` 删除缺席且 `extra.unidesk_managed=true``unidesk-codex-*` account。对 `manualAccounts.protected``sync` 只执行 YAML 显式允许的窄同步;当前允许项是从目标 `egressProxy` 创建/更新 Sub2API internal proxy 记录并绑定 `proxy_id`,以及把受保护手动账号加入当前 `pool.groupName`。它仍不接管该账号凭据、status、schedulable、priority/capacity/loadFactor 或哨兵状态。PK01 host-Docker target 在 codex-pool adapter 补齐前不具备这条完整 sync 路径
`sync --confirm` 会登录 Sub2API admin、创建/更新 group、创建/更新 YAML 中的 `unidesk-codex-*` accounts,并创建/复用统一 API key。k3s target 还会写入统一 API key Secret 并部署/更新哨兵资源;PK01 host-Docker target 只写 Sub2API runtime 和 host-Docker env 文件。`sync` 不把既有 managed account 直接恢复为 `schedulable=true`。恢复只由哨兵在读取 Sub2API runtime `schedulable=false` 后触发 recovery probe,并在 marker 命中时执行。`sync` 默认不删除 YAML 中缺席的 managed account。只有明确退役上游时才使用 `sync --confirm --prune-removed` 删除缺席且 `extra.unidesk_managed=true``unidesk-codex-*` account。对 `manualAccounts.protected``sync` 只执行 YAML 显式允许的窄同步;当前允许项是从目标 `egressProxy` 创建/更新 Sub2API internal proxy 记录并绑定 `proxy_id`,以及把受保护手动账号加入当前 `pool.groupName`。它仍不接管该账号凭据、status、schedulable、priority/capacity/loadFactor 或哨兵状态。若受保护手动账号在运行面缺失,`sync`/`validate` 会报告 manual account drift;不要自动创建、删除、接管或从 YAML 移除该账号
`trace --request-id <requestId>` 是只读 request 追溯报表,不触发 probe、不修改账号。默认输出请求开始/最终状态、failover、`account_select_failed`、窗口内 `account_temp_unschedulable`、admin schedulable 写入计数和当前账号快照;`reason=failover-attempted-no-candidate` 表示 Sub2API 已进入自动切号,但排除当前失败账号后没有可用候选。需要机器处理时使用 `--raw`,需要原始匹配行时加 `--show-lines`
@@ -7,7 +7,7 @@ bun scripts/cli.ts platform-infra sub2api codex-pool configure-local --confirm
`configure-local --confirm` 会:
-`platform-infra/<apiKeySecretName>.<apiKeySecretKey>` 读取统一 API key
- active target 的统一 API key 位置读取 keyk3s target 读取 `platform-infra/<apiKeySecretName>.<apiKeySecretKey>`PK01 host-Docker target 读取 YAML `hostDocker.envPath` 中的 `<apiKeySecretKey>`
- 把当前 `~/.codex/config.toml``~/.codex/auth.json` 备份为 `.<backupSuffix>`,默认 `.pre-sub2api`
- 重写默认 `~/.codex` 消费端,固定指向 `https://sub2api.74-48-78-17.nip.io/`provider 名称和 wire API 来自 `localCodex`
-`localCodex.modelContextWindow` / `localCodex.modelAutoCompactTokenLimit` 写入 `model_context_window` / `model_auto_compact_token_limit`,用于统一控制 Codex auto compact 触发窗口,避免 GPT-5.5 消费端生成过大的 `/responses/compact` 长请求。
@@ -63,7 +63,7 @@ bun scripts/cli.ts platform-infra sub2api status --target PK01
bun scripts/cli.ts platform-infra sub2api validate --target PK01
```
PK01 没有 k3s control plane。当前 `codex-pool sync``codex-pool validate``sentinel-report` `trace` 的部分实现仍依赖 k8s/kubectl 远端脚本;在 PK01 host-Docker target 上看到 `kubectl` 缺失时,应归类为 CLI host-Docker adapter 缺口,不要误判为 Sub2API app、Caddy、上游或账号池故障。正式修复应补 host-Docker 版 codex-pool sync/validate/report/trace临时排障只能做只读 admin API、DB join 表和最小公网 `/v1/responses` smoke,并且不得打印 admin password、API key 或账号凭据。
PK01 没有 k3s control plane。`codex-pool sync --target PK01 --confirm``codex-pool validate --target PK01` 走 host-Docker adapter:通过本机 Sub2API admin API 和 YAML `hostDocker.envPath` 对齐账号池,不使用 k8s Secret/CronJob,也不重启容器。`sentinel-report``sentinel-probe``sentinel-image` 和部分 `trace` 能力仍可能依赖 k8s/kubectl;在这些命令上看到 `kubectl` 缺失时,应归类为 CLI host-Docker adapter 缺口,不要误判为 Sub2API app、Caddy、上游或账号池故障。临时排障只能做只读 admin API、DB join 表和最小公网 `/v1/responses` smoke,并且不得打印 admin password、API key 或账号凭据。
PK01 host-Docker apply 仍必须由 `platform-infra sub2api apply --target PK01 --confirm` 受控执行。若 dry-run 或 apply 输出显示 `docker compose is absent; apply will use raw docker run fallback`,这表示 CLI 选择了 host-Docker fallback,不是裸手工 Docker 操作;只要 YAML image、env、ports、Caddy managed block 和 `status/validate` 最终对齐,可作为受控滚动升级证据。不要改用手工 `docker run`、手工 compose 文件或直接编辑 PK01 Caddyfile。