feat: organize scripts and add portal validation assets
This commit is contained in:
@@ -46,6 +46,24 @@ SUB2API_CRM_ADMIN_TOKEN=change-me-before-production SUB2API_CRM_LISTEN_ADDR=127.
|
||||
| `SUB2API_CRM_LISTEN_ADDR` | 监听地址 | `:18081` |
|
||||
| `SUB2API_CRM_SQLITE_DSN` | SQLite DSN | `file:/tmp/sub2api-cn-relay-manager.db?_foreign_keys=on&_busy_timeout=5000` |
|
||||
|
||||
## 公网 Portal 资产
|
||||
|
||||
如果你还需要同时维护 `sub.tksea.top` 上的用户态 portal,不要再把静态页或 Nginx 规则只放在 `/tmp`:
|
||||
|
||||
- 静态页源码:`deploy/tksea-portal/index.html`
|
||||
- Nginx 示例:`deploy/tksea-portal/nginx.sub.tksea.top.conf.example`
|
||||
- 部署脚本:`scripts/deploy/deploy_tksea_portal.sh`
|
||||
- 资产回归:`scripts/test/test_tksea_portal_assets.sh`
|
||||
|
||||
当前正式入口:
|
||||
|
||||
- `https://sub.tksea.top/portal/`
|
||||
|
||||
兼容入口:
|
||||
|
||||
- `https://sub.tksea.top/kimi-portal/`
|
||||
- 当前应保持跳转到 `/portal/`
|
||||
|
||||
## 上线前验证
|
||||
|
||||
```bash
|
||||
|
||||
@@ -15,6 +15,18 @@
|
||||
- `self_service` 主链路已通过 latest-head 标准 fresh-host 复验:
|
||||
- `artifacts/real-host-acceptance/20260521_210403/05-import.json`
|
||||
- `artifacts/real-host-acceptance/20260521_210403/07-access-status.json`
|
||||
- 2026-05-27 已把公网用户入口从 `kimi-portal` 收口为通用多模型 portal:
|
||||
- 新正式地址:`https://sub.tksea.top/portal/`
|
||||
- 旧地址 `https://sub.tksea.top/kimi-portal/` 当前保留为 `302` 跳转,避免历史分享链接失效
|
||||
- 站点资产与 Nginx 路由不再只存在 `/tmp` 临时文件,已收口进仓库:
|
||||
- `deploy/tksea-portal/index.html`
|
||||
- `deploy/tksea-portal/nginx.sub.tksea.top.conf.example`
|
||||
- `scripts/deploy/deploy_tksea_portal.sh`
|
||||
- 新页面已补齐登录态、用户信息、可绑定分组、活跃订阅、历史 key 列表,以及“新创建 key 对应分组/模型”的即时展示
|
||||
- 线上无副作用验收已确认:
|
||||
- `GET /portal/` 返回 `200`
|
||||
- `GET /kimi-portal/` 返回 `302 -> /portal/`
|
||||
- `GET /portal-proxy/api/v1/keys` 在无效 token 下已命中宿主真实 `INVALID_TOKEN`,说明新的同域代理已生效
|
||||
- 2026-05-26 已把“最终用户 -> 公网域名 -> OpenClaw”这一跳补进正式验证口径:
|
||||
- 公网根地址当前统一为 `https://sub.tksea.top`
|
||||
- OpenClaw 本地 `MiniMax` 运行时故障已定位为 `pi-ai/openai-node` 未继承系统 `HTTP(S)_PROXY`,不是 allowlist 或模型名大小写问题
|
||||
@@ -38,12 +50,12 @@
|
||||
- 旧 artifact `artifacts/real-host-acceptance/20260526_155810_remote43_deepseek_chat_official_multi_model_rootprep/21-summary.json` 停在 `partially_succeeded/degraded`
|
||||
- 2026-05-27 rerun `artifacts/real-host-acceptance/20260527_051655_remote43_deepseek-chat-official_key_import/21-summary.json` 已确认本机经 remote43 patched host 的真实数据面恢复:`direct_models_http200=true`、`direct_models=["deepseek-chat"]`、`direct_chat_status=200`、`latest_access_status=subscription_ready`、`upstream_chat_status=200`
|
||||
- 剩余 `partially_succeeded/degraded` 的唯一原因已定位为宿主 account probe 返回裸 `API returned 404:`,而后续 gateway `/v1/models` + `/v1/chat/completions` 实际都已通过;HEAD 现已把该 404 视为 advisory,不再阻塞最终状态收敛
|
||||
- 同轮还补上 remote43 scripted stack 的真实脚本缺陷:`.env.crm` 里的 SQLite DSN 含 `&_busy_timeout=5000` 时,旧版未做 shell escape,`source .env.crm` 会吞掉 `SUB2API_CRM_SQLITE_DSN`,导致 remote CRM 实际退回默认 DB 路径;`scripts/remote43_patched_stack_lib.sh` 已修复并有回归测试覆盖
|
||||
- 同轮还补上 remote43 scripted stack 的真实脚本缺陷:`.env.crm` 里的 SQLite DSN 含 `&_busy_timeout=5000` 时,旧版未做 shell escape,`source .env.crm` 会吞掉 `SUB2API_CRM_SQLITE_DSN`,导致 remote CRM 实际退回默认 DB 路径;`scripts/deploy/remote43_patched_stack_lib.sh` 已修复并有回归测试覆盖
|
||||
- latest-head relay-manager 已新增宿主 capability 自愈:
|
||||
- 当第三方 OpenAI-compatible upstream 因宿主把 `openai_responses_supported` 误判成 `true` 而导致 host `/v1/chat/completions` 返回 `502 upstream_error` 时,access closure 与后台 reconcile 会自动把相关 account 修正到 raw `/chat/completions` 路径后再重试
|
||||
- 但这条控制面自愈当前仍不足以单独收敛本地 stock `weishaw/sub2api:0.1.129` + `kimi-a7m` 场景;`artifacts/real-host-acceptance/20260525_local_v0129_kimi_a7m_scheme_c_stockhost_rerun/21-summary.json` 已再次证明:在不改宿主源码的前提下,managed `/v1/models` 虽然命中 `kimi-k2.6`,`/v1/chat/completions` 仍会落到 `502 upstream_error`,所以该 case 仍需宿主运行时兼容补丁或 shim
|
||||
- 2026-05-23 remote43 线上验收脚本已继续收口:
|
||||
- `scripts/import_remote43_provider.sh` 现已明确拆分 `CRM_HOST_BASE` 与 `REMOTE_HOST_BASE`
|
||||
- `scripts/acceptance/import_remote43_provider.sh` 现已明确拆分 `CRM_HOST_BASE` 与 `REMOTE_HOST_BASE`
|
||||
- 远端 Postgres / Redis 容器已改成按目标宿主端口自动解析,不再硬编码落到 `sub2api-relaymgr-pg/redis`
|
||||
- 远端 managed probe `/v1/models` 与 `/v1/chat/completions` 已改成只走 `REMOTE_HOST_BASE`
|
||||
- provider status / access status / access preview 末尾查询已补 `host_id`,避免本地 CRM 有多宿主历史时被 `provider exists on multiple hosts` 截断
|
||||
@@ -65,14 +77,14 @@
|
||||
- `artifacts/real-host-acceptance/20260525_remote43_kimi_a7m_patched_overlay_freshhost_remotecrm/21-summary.json` 已确认:`batch_status=succeeded`、`access_status_from_import=subscription_ready`、`provider_status_from_import=active`、`direct_models_http200=true`、`direct_chat_http200=true`、`upstream_chat_status=200`
|
||||
- 同目录 `14-access-status.json` 已确认 `effective_probe_key_source=managed_subscription` 且 `completion_status=200`
|
||||
- remote43 宿主日志也已落到真实 `GET /v1/models = 200`、`POST /v1/chat/completions = 200`,说明这条 patched overlay 路线不只在本地 fresh-host 成功,也已在远端真实环境收敛到 ready
|
||||
- 这轮还顺手修掉了 `scripts/import_remote43_provider.sh` 的一个真实脚本缺陷:查找未分配 `relay-sub-*` 用户时,`NOT EXISTS` 子查询错误引用了无 alias 的 `users.id`,在 PostgreSQL 上会报 `invalid reference to FROM-clause entry for table "users"`
|
||||
- 这轮还顺手修掉了 `scripts/acceptance/import_remote43_provider.sh` 的一个真实脚本缺陷:查找未分配 `relay-sub-*` 用户时,`NOT EXISTS` 子查询错误引用了无 alias 的 `users.id`,在 PostgreSQL 上会报 `invalid reference to FROM-clause entry for table "users"`
|
||||
- 2026-05-25 继续把这套 remote43 patched-host / remote CRM 的启动流程脚本化:
|
||||
- 新增 `scripts/setup_remote43_patched_stack.sh`,把 pack 镜像、二进制上传、remote43 上的 PG/Redis/patched host/临时 CRM 拉起、以及本地 operator env / SSH 隧道提示收口为一个固定入口
|
||||
- 新增 `scripts/remote43_patched_stack_lib.sh`,把远端 host env / CRM env / bootstrap script 渲染逻辑抽成可测试 helper
|
||||
- `scripts/test_real_host_scripts.sh` 已新增对应回归,避免以后再回退到手工 `/tmp/*.sh` 拼装
|
||||
- 新增 `scripts/deploy/setup_remote43_patched_stack.sh`,把 pack 镜像、二进制上传、remote43 上的 PG/Redis/patched host/临时 CRM 拉起、以及本地 operator env / SSH 隧道提示收口为一个固定入口
|
||||
- 新增 `scripts/deploy/remote43_patched_stack_lib.sh`,把远端 host env / CRM env / bootstrap script 渲染逻辑抽成可测试 helper
|
||||
- `scripts/test/test_real_host_scripts.sh` 已新增对应回归,避免以后再回退到手工 `/tmp/*.sh` 拼装
|
||||
- 脚本首轮真实演练暴露出一个运行态细节:patched `sub2api` 二进制实际监听 `8080`,不能沿用旧临时脚本里的 `127.0.0.1:$HOST_PORT:3000` 端口映射;当前 `setup_remote43_patched_stack.sh` 已新增 `HOST_CONTAINER_PORT=8080` 默认值并完成 remote43 二次实跑验证
|
||||
- 用修复后的固定脚本在 remote43 新起的 `sub2api-kimi-patched-auto2-20260525` 栈上,`kimi-a7m` 再次完成真实导入主链路:`artifacts/real-host-acceptance/20260525_remote43_kimi_a7m_patched_overlay_scripted_stack/03-import.body.json` 已确认 `batch_status=succeeded`、`access_status=subscription_ready`、`provider_status=active`,同目录 `10-models.body.json` / `12-chat.body.json` / `18-upstream-models.body.json` / `20-upstream-chat.body.txt` 也已再次证明 managed 与 upstream 双侧都回到 `HTTP 200`
|
||||
- 2026-05-26 继续把 scripted stack 的末尾状态查询收口为稳定契约:`scripts/import_remote43_provider.sh` 末尾不再只传 `host_id`,而是显式拼上 `pack_id=openai-cn-pack&host_id=<create-host 返回值>`;修复原因是 remote43 上同一个 provider 可能存在多个 pack 版本,缺 `pack_id` 时 `/api/providers/{providerID}/status` 会返回 `400 provider exists in multiple packs; pack_id is required`
|
||||
- 2026-05-26 继续把 scripted stack 的末尾状态查询收口为稳定契约:`scripts/acceptance/import_remote43_provider.sh` 末尾不再只传 `host_id`,而是显式拼上 `pack_id=openai-cn-pack&host_id=<create-host 返回值>`;修复原因是 remote43 上同一个 provider 可能存在多个 pack 版本,缺 `pack_id` 时 `/api/providers/{providerID}/status` 会返回 `400 provider exists in multiple packs; pack_id is required`
|
||||
- 修复后,`artifacts/real-host-acceptance/20260526_remote43_kimi_a7m_patched_overlay_scripted_stack_rerun2/13-provider-status.json`、`14-access-status.json`、`21-summary.json` 已全部自动补齐;其中 `21-summary.json` 已再次确认 `batch_status=succeeded`、`provider_status_from_import=active`、`latest_access_status=subscription_ready`、`direct_chat_status=200`、`upstream_chat_status=200`
|
||||
- `artifacts/real-host-acceptance/20260525_local_v0129_kimi_a7m_from_hermes/21-summary.json` 已证明:
|
||||
- Hermes 本机 `A7M_KIMI_API_KEY` 直探 upstream `/v1/models` 与 `/v1/chat/completions` 均为 `200`
|
||||
@@ -133,7 +145,7 @@
|
||||
- 新增 `docs/2026-05-18-PRODUCTION_REMEDIATION_TASK_BOARD.md`
|
||||
- 下调 `DEPLOYMENT.md` 中未实现的 `/metrics` / 限流 / 监控承诺
|
||||
7. current-code remote43 导入链路已补齐 tunnel-aware 验证能力
|
||||
- `scripts/import_remote43_provider.sh` 新增 `CRM_HOST_BASE`,允许把“operator 访问 host 地址”和“CRM 进程访问 host 地址”分离
|
||||
- `scripts/acceptance/import_remote43_provider.sh` 新增 `CRM_HOST_BASE`,允许把“operator 访问 host 地址”和“CRM 进程访问 host 地址”分离
|
||||
- 历史 live model-mapping 关键证据保留在:`artifacts/real-host-acceptance/20260520_222713_crm18100_live_model_mapping_validation`
|
||||
8. current-code remote43 access gate 根因修正已落地
|
||||
- subscription access 改为宿主侧闭环:CRM 不再依赖外部预先给定的宿主普通用户 key,而是按 `subscription_users` selector 在宿主创建/查找托管普通用户、登录创建托管 key、回写 allowed_groups / balance、再执行订阅分配
|
||||
@@ -145,7 +157,7 @@
|
||||
- access closure / import runtime artifact / reconcile rerun payload 都会持久化 `completion_ok/completion_status/completion_type/completion_preview`
|
||||
10. current-code remote43 验收脚本已补 upstream API 证据层
|
||||
|
||||
- `scripts/import_remote43_provider.sh` 会直探 provider `base_url` 对应的 upstream `/models` 与 `/chat/completions`
|
||||
- `scripts/acceptance/import_remote43_provider.sh` 会直探 provider `base_url` 对应的 upstream `/models` 与 `/chat/completions`
|
||||
- 新增 `21-summary.json`,用于把 completion 失败自动分流成 `host_compatibility_gap` 或 `upstream_key_quota_issue`
|
||||
|
||||
11. patched CRM external validation 已完成
|
||||
@@ -191,7 +203,7 @@
|
||||
- `internal/provision`: `79.4%`
|
||||
- `internal/store/sqlite`: `77.9%`
|
||||
- `go test ./tests/integration/... -count=1` ✅
|
||||
- `bash ./scripts/test_real_host_scripts.sh` ✅
|
||||
- `bash ./scripts/test/test_real_host_scripts.sh` ✅
|
||||
|
||||
## 当前保留的最终证据
|
||||
|
||||
@@ -244,7 +256,7 @@
|
||||
|
||||
2. 部署与环境限制
|
||||
- 标准多阶段 Dockerfile 在受限网络环境下仍不稳
|
||||
- 当前推荐 `scripts/build_local_image.sh` + `Dockerfile.local`
|
||||
- 当前推荐 `scripts/deploy/build_local_image.sh` + `Dockerfile.local`
|
||||
|
||||
3. official provider 验证矩阵
|
||||
- official MiniMax 当前 live 样本已证明模板链路可用,但验证 key 命中 upstream `429`
|
||||
|
||||
@@ -19,7 +19,7 @@ This document covers known limitations that operators should be aware of before
|
||||
|
||||
### 3. Standard Multi-stage Docker Build Still Depends on Outbound Module Download
|
||||
- `Dockerfile.local` has been validated as the recommended proxy-safe build path.
|
||||
- `scripts/build_local_image.sh` now prebuilds the Linux binary on the host and produces `sub2api-cn-relay-manager:local` reliably in this environment.
|
||||
- `scripts/deploy/build_local_image.sh` now prebuilds the Linux binary on the host and produces `sub2api-cn-relay-manager:local` reliably in this environment.
|
||||
- The standard multi-stage `Dockerfile` still requires outbound Go module download from inside the container build context; in restricted networks, prefer the local-image path.
|
||||
|
||||
## Accepted Design Trade-offs
|
||||
|
||||
358
docs/OPENCLAW_EXTERNAL_VALIDATION.md
Normal file
358
docs/OPENCLAW_EXTERNAL_VALIDATION.md
Normal file
@@ -0,0 +1,358 @@
|
||||
# OpenClaw 外部真实验证
|
||||
|
||||
日期:2026-05-26
|
||||
|
||||
## 目的
|
||||
|
||||
这份文档补齐两类长期缺口:
|
||||
|
||||
1. `sub2api-cn-relay-manager` 之外的最终使用面验证
|
||||
- 即真实用户拿到宿主 key 后,在本机 `OpenClaw` 上是否真的可用
|
||||
2. OpenClaw 本地运行时补丁的可复用操作流程
|
||||
- 包括 `MiniMax` 的代理兼容补丁
|
||||
- 以及升级后如何自动提醒重新打补丁
|
||||
|
||||
它不替代:
|
||||
|
||||
- `docs/REAL_HOST_ACCEPTANCE_RUNBOOK.md`
|
||||
- 负责 `relay-manager -> host -> upstream` 三段验收
|
||||
- 本文
|
||||
- 负责 `user key -> OpenClaw -> public endpoint` 最后一段真实使用验证
|
||||
|
||||
## 当前结论
|
||||
|
||||
截至 2026-05-27,公网根端点已经切到 patched host,可统一按 OpenAI 兼容根地址使用:
|
||||
|
||||
- `base_url=https://sub.tksea.top`
|
||||
- 若客户端强制要求显式 `/v1`,则使用 `https://sub.tksea.top/v1`
|
||||
|
||||
OpenClaw 当前外部真实验证结论如下:
|
||||
|
||||
| OpenClaw provider | model | base_url | 结果 | 说明 |
|
||||
| ----------------- | ------------------------ | ---------------------------- | ---- | ------------------------------------------------------- |
|
||||
| `tksea` | `kimi-k2.6` | `https://sub.tksea.top/kimi` | PASS | 已在 OpenClaw `agent` 路径验证通过 |
|
||||
| `tksea-gpt` | `gpt-5.4` | `https://sub.tksea.top/v1` | PASS | `openclaw infer model run --local` 返回 `pong` |
|
||||
| `tksea-gpt` | `gpt-5.4-mini` | `https://sub.tksea.top/v1` | PASS | `openclaw infer model run --local` 返回 `pong` |
|
||||
| `tksea-gpt` | `gpt-5.5` | `https://sub.tksea.top/v1` | FAIL | upstream 当前返回 `503 Service temporarily unavailable` |
|
||||
| `tksea-minimax` | `MiniMax-M2.5-highspeed` | `https://sub.tksea.top/v1` | PASS | 对应 remote43 导入 `minimax-53hk` 后的公网消费口径 |
|
||||
| `tksea-minimax` | `MiniMax-M2.7-highspeed` | `https://sub.tksea.top/v1` | PASS | 对应 remote43 导入 `minimax-53hk` 后的公网消费口径 |
|
||||
| `minimax53hk` | `MiniMax-M2.5-highspeed` | `https://api.53hk.cn/v1` | PASS | 本地补丁后恢复的 53hk 直连口径 |
|
||||
| `minimax53hk` | `MiniMax-M2.7-highspeed` | `https://api.53hk.cn/v1` | PASS | 本地补丁后恢复的 53hk 直连口径 |
|
||||
|
||||
与 relay-manager pack 内 `provider_id` 的映射关系当前明确为:
|
||||
|
||||
- `openai-zhongzhuan` → `tksea-gpt`
|
||||
- `minimax-53hk` → `tksea-minimax`
|
||||
- `deepseek-chat-official` → `deepseek-official`(2026-05-27 已补齐 `auth-profiles.json`,`openclaw infer model run --model \"deepseek-official/deepseek-chat\" --prompt 'Reply with exactly OK' --json` 返回 `OK`)
|
||||
|
||||
## 前置条件
|
||||
|
||||
### 远端入口
|
||||
|
||||
- 用户注册页:`https://sub.tksea.top/portal/`
|
||||
- 旧地址:`https://sub.tksea.top/kimi-portal/`
|
||||
- 当前应作为兼容跳转入口保留,而不是继续作为正式主地址
|
||||
- 宿主 OpenAI 兼容入口:`https://sub.tksea.top`
|
||||
|
||||
### OpenClaw 本地要求
|
||||
|
||||
- 已安装 `OpenClaw`
|
||||
- 本机代理环境可用:
|
||||
- `HTTP_PROXY`
|
||||
- `HTTPS_PROXY`
|
||||
- 已写入至少一种测试 key:
|
||||
- `tksea`
|
||||
- `tksea-gpt`
|
||||
- `tksea-minimax`
|
||||
- `minimax53hk`
|
||||
|
||||
### 已存在的本地补丁脚本
|
||||
|
||||
下列脚本当前位于操作者本机,不在本仓库内版本化;本仓库只记录它们的使用方法与验收口径:
|
||||
|
||||
- `~/.openclaw/bin/apply-openclaw-minimax-proxy-fix.sh`
|
||||
- `~/.openclaw/bin/openclaw-minimax-post-upgrade-check.sh`
|
||||
- `~/.openclaw/bin/openclaw-minimax-proxy-reminder.sh`
|
||||
- `~/.openclaw/bin/install-openclaw-minimax-reminder-cron.sh`
|
||||
|
||||
## 根因与补丁范围
|
||||
|
||||
本轮 `MiniMax` 的 OpenClaw 故障,不是模型名大小写,也不是 allowlist 漏配导致。
|
||||
|
||||
真实根因是:
|
||||
|
||||
- `curl` 可以通过系统 `HTTP(S)_PROXY` 正常访问 `53hk` 与 `tksea` 的 `MiniMax`
|
||||
- 但 `OpenClaw -> pi-ai -> openai-node` 默认没有继承同样的代理行为
|
||||
- 因此在本地 one-shot 路径里被吞成:
|
||||
- `No text output returned`
|
||||
- `Connection error`
|
||||
|
||||
当前补丁做法是:
|
||||
|
||||
- 对本机安装的 `pi-ai` 运行时文件注入 `EnvHttpProxyAgent`
|
||||
- 让 OpenAI SDK 使用带系统代理的 `fetch`
|
||||
|
||||
补丁目标文件:
|
||||
|
||||
- `~/.local/lib/node_modules/openclaw/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js`
|
||||
|
||||
注意:
|
||||
|
||||
- 这不是本仓库源码补丁
|
||||
- `OpenClaw` 升级后,这个补丁可能会被覆盖
|
||||
|
||||
## 用例设计
|
||||
|
||||
### 用例 1:提醒任务已安装
|
||||
|
||||
目的:
|
||||
|
||||
- 确保 OpenClaw 升级后,系统会自动提醒是否需要重新打补丁
|
||||
|
||||
执行:
|
||||
|
||||
```bash
|
||||
crontab -l
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- 输出中包含:
|
||||
- `# BEGIN openclaw-minimax-proxy-reminder`
|
||||
- `@reboot sleep 180 && "~/.openclaw/bin/openclaw-minimax-proxy-reminder.sh" ...`
|
||||
- `*/30 * * * * "~/.openclaw/bin/openclaw-minimax-proxy-reminder.sh" ...`
|
||||
|
||||
### 用例 2:补丁状态诊断
|
||||
|
||||
目的:
|
||||
|
||||
- 在升级后先判定当前是否还带着代理补丁
|
||||
|
||||
执行:
|
||||
|
||||
```bash
|
||||
~/.openclaw/bin/apply-openclaw-minimax-proxy-fix.sh doctor
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- 输出 `OpenClaw` 版本
|
||||
- 输出目标 `pi-ai` 文件路径
|
||||
- 输出当前 `patched/not_patched`
|
||||
- 输出 `HTTP_PROXY/HTTPS_PROXY/NO_PROXY`
|
||||
- 输出备份列表
|
||||
|
||||
### 用例 3:升级后一键恢复
|
||||
|
||||
目的:
|
||||
|
||||
- 在 OpenClaw 升级后,自动完成 `doctor -> apply -> verify`
|
||||
|
||||
执行:
|
||||
|
||||
```bash
|
||||
~/.openclaw/bin/openclaw-minimax-post-upgrade-check.sh
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- `doctor` 正常输出
|
||||
- `apply` 在已打补丁时表现为幂等
|
||||
- `verify` 最终四条 `MiniMax` smoke 全部通过
|
||||
|
||||
### 用例 4:53hk MiniMax 直连恢复
|
||||
|
||||
目的:
|
||||
|
||||
- 验证官方宿主之外,老的 `53hk` 线路在 OpenClaw 本地也已恢复
|
||||
|
||||
执行:
|
||||
|
||||
```bash
|
||||
openclaw infer model run --local \
|
||||
--model "minimax53hk/MiniMax-M2.5-highspeed" \
|
||||
--prompt "reply with pong only" \
|
||||
--json
|
||||
|
||||
openclaw infer model run --local \
|
||||
--model "minimax53hk/MiniMax-M2.7-highspeed" \
|
||||
--prompt "reply with pong only" \
|
||||
--json
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- `ok=true`
|
||||
- 输出文本为 `pong`
|
||||
|
||||
### 用例 5:tksea MiniMax 真实调用
|
||||
|
||||
目的:
|
||||
|
||||
- 验证 patched host 暴露的 `MiniMax` 公网入口,已经可被 OpenClaw 正常消费
|
||||
|
||||
执行:
|
||||
|
||||
```bash
|
||||
openclaw infer model run --local \
|
||||
--model "tksea-minimax/MiniMax-M2.5-highspeed" \
|
||||
--prompt "reply with pong only" \
|
||||
--json
|
||||
|
||||
openclaw infer model run --local \
|
||||
--model "tksea-minimax/MiniMax-M2.7-highspeed" \
|
||||
--prompt "reply with pong only" \
|
||||
--json
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- `ok=true`
|
||||
- 输出文本为 `pong`
|
||||
|
||||
### 用例 6:tksea GPT 可用模型验证
|
||||
|
||||
目的:
|
||||
|
||||
- 区分“GPT 配置是否正确”与“某个具体模型当前 upstream 是否可用”
|
||||
|
||||
执行:
|
||||
|
||||
```bash
|
||||
openclaw infer model run --local \
|
||||
--model "tksea-gpt/gpt-5.4" \
|
||||
--prompt "reply with pong only" \
|
||||
--json
|
||||
|
||||
openclaw infer model run --local \
|
||||
--model "tksea-gpt/gpt-5.4-mini" \
|
||||
--prompt "reply with pong only" \
|
||||
--json
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- `gpt-5.4` 返回 `pong`
|
||||
- `gpt-5.4-mini` 返回 `pong`
|
||||
|
||||
### 用例 7:tksea GPT 不稳定模型验证
|
||||
|
||||
目的:
|
||||
|
||||
- 把“不稳定模型”显式记录为当前运行态限制,而不是笼统地宣称 GPT 全量可用
|
||||
|
||||
执行:
|
||||
|
||||
```bash
|
||||
openclaw infer model run --local \
|
||||
--model "tksea-gpt/gpt-5.5" \
|
||||
--prompt "reply with pong only" \
|
||||
--json
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- 当前基线结果是失败
|
||||
- 错误为:
|
||||
- `503 Service temporarily unavailable`
|
||||
|
||||
### 用例 8:DeepSeek 官方 OpenClaw 配置缺口探测
|
||||
|
||||
目的:
|
||||
|
||||
- 区分“remote43 上 `deepseek-chat-official` 已导入并能 completion”与“本机 OpenClaw 已经可直接消费”这两个结论
|
||||
|
||||
执行:
|
||||
|
||||
```bash
|
||||
openclaw infer model run --local \
|
||||
--model "deepseek-official/deepseek-chat" \
|
||||
--prompt "reply with pong only" \
|
||||
--json
|
||||
```
|
||||
|
||||
预期:
|
||||
|
||||
- 当前基线结果是失败
|
||||
- 失败点不是模型推理,而是本机 auth/profile 尚未就绪
|
||||
- 典型错误:
|
||||
- `No API key found for provider "deepseek-official"`
|
||||
|
||||
## 推荐执行顺序
|
||||
|
||||
每次 OpenClaw 升级后,按下面顺序执行:
|
||||
|
||||
1. 检查提醒任务
|
||||
|
||||
```bash
|
||||
crontab -l
|
||||
```
|
||||
|
||||
2. 先诊断当前状态
|
||||
|
||||
```bash
|
||||
~/.openclaw/bin/apply-openclaw-minimax-proxy-fix.sh doctor
|
||||
```
|
||||
|
||||
3. 再执行升级后一键恢复
|
||||
|
||||
```bash
|
||||
~/.openclaw/bin/openclaw-minimax-post-upgrade-check.sh
|
||||
```
|
||||
|
||||
4. 验证 `tksea-gpt` 当前可用模型
|
||||
|
||||
```bash
|
||||
openclaw infer model run --local --model "tksea-gpt/gpt-5.4" --prompt "reply with pong only" --json
|
||||
openclaw infer model run --local --model "tksea-gpt/gpt-5.4-mini" --prompt "reply with pong only" --json
|
||||
```
|
||||
|
||||
5. 验证 `tksea-minimax`
|
||||
|
||||
```bash
|
||||
openclaw infer model run --local --model "tksea-minimax/MiniMax-M2.5-highspeed" --prompt "reply with pong only" --json
|
||||
openclaw infer model run --local --model "tksea-minimax/MiniMax-M2.7-highspeed" --prompt "reply with pong only" --json
|
||||
```
|
||||
|
||||
## 诊断分流
|
||||
|
||||
### `/v1/models` 能出模型,但 OpenClaw 本地仍报 `Connection error`
|
||||
|
||||
优先排查:
|
||||
|
||||
1. `doctor` 是否显示 `patched`
|
||||
2. 当前 shell 是否存在 `HTTP_PROXY` / `HTTPS_PROXY`
|
||||
3. OpenClaw 是否刚升级,导致 `pi-ai` patch 丢失
|
||||
|
||||
### GPT 某个模型失败,但同组其他模型正常
|
||||
|
||||
优先判断为:
|
||||
|
||||
- 特定模型 upstream 不稳定
|
||||
- 不要误判成整个 `tksea-gpt` provider 失效
|
||||
|
||||
当前基线就是:
|
||||
|
||||
- `gpt-5.4`:PASS
|
||||
- `gpt-5.4-mini`:PASS
|
||||
- `gpt-5.5`:FAIL(503)
|
||||
|
||||
### MiniMax API 直连可用,但 OpenClaw 本地失败
|
||||
|
||||
优先判断为:
|
||||
|
||||
- OpenClaw 本地运行时代理兼容问题
|
||||
- 不是宿主 key、也不是 relay-manager 导入问题
|
||||
|
||||
## 结论口径
|
||||
|
||||
截至 2026-05-26,当前可以对外采用下面这套简化口径:
|
||||
|
||||
1. patched host 公网根入口已可直接给 OpenAI 兼容客户端使用:
|
||||
- `https://sub.tksea.top`
|
||||
2. OpenClaw 的 `MiniMax` 本地运行时兼容问题已经通过代理补丁恢复
|
||||
3. `tksea-minimax` 当前可用
|
||||
4. `tksea-gpt` 当前不是“全模型可用”,而是:
|
||||
- `gpt-5.4` 可用
|
||||
- `gpt-5.4-mini` 可用
|
||||
- `gpt-5.5` 当前仍需视 upstream 状态单独观察
|
||||
@@ -19,13 +19,13 @@
|
||||
- 汇总证据:`artifacts/real-host-acceptance/20260521_064910_completion_smoke_calibration.md`
|
||||
- 调通细节与经验沉淀:`docs/REAL_HOST_ACCEPTANCE_LEARNINGS.md`
|
||||
- 2026-05-21 当前代码已关闭“models-only 假 ready”问题:access closure / import / reconcile rerun 现在都会在 `/v1/models` 成功后追加一次最小 `POST /v1/chat/completions` smoke;completion 失败的链路不会再被记成 ready。
|
||||
- `scripts/import_remote43_provider.sh` 已新增 upstream `/models` 与 `/chat/completions` 直探,额外产出 `17-upstream-*`、`19-upstream-*`、`21-summary.json`,用于把失败分流为 `host_compatibility_gap` 或 `upstream_key_quota_issue`。
|
||||
- `scripts/acceptance/import_remote43_provider.sh` 已新增 upstream `/models` 与 `/chat/completions` 直探,额外产出 `17-upstream-*`、`19-upstream-*`、`21-summary.json`,用于把失败分流为 `host_compatibility_gap` 或 `upstream_key_quota_issue`。
|
||||
- patched CRM live rerun 已验证:
|
||||
- MiniMax 最新 `artifacts/real-host-acceptance/20260521_191418_remote43_minimax_key_import` 已提升到 `batch_status=succeeded`、`provider_status=active`
|
||||
- DeepSeek 最新 `artifacts/real-host-acceptance/20260521_201509_remote43_deepseek_key_import` 也已提升到 `batch_status=succeeded`、`provider_status=active`
|
||||
- latest-head `self_service` 标准 fresh-host 验收 `artifacts/real-host-acceptance/20260521_210403` 已落成 `batch_status=succeeded`、`access_status=self_service_ready`、`provider_status=active`,且 `latest_access_status=fully_ready`
|
||||
- 本轮真正收口的根因修复是:账号 probe SSE 错误消息已保留,CRM 会显式向 `/api/v1/admin/accounts/:id/test` 传 `provider.SmokeTestModel`,瞬时 `429` probe 现在会按 advisory 处理,不再把已通过 gateway closure 的账号批次错误降级,同时 self-service 的 gateway probe 已从错误的 `x-api-key` 切到真实宿主要求的 `Authorization: Bearer`
|
||||
- 代码/本地运行态门禁已于 2026-05-21 在这轮补丁后再次独立复跑:`gofmt -l .`、`go vet ./...`、`go test ./... -count=1`、`go test -race ./... -count=1`、`go test -cover ./internal/... -count=1`、`go test ./tests/integration/... -count=1`、`bash ./scripts/test_real_host_scripts.sh` 全通过。
|
||||
- 代码/本地运行态门禁已于 2026-05-21 在这轮补丁后再次独立复跑:`gofmt -l .`、`go vet ./...`、`go test ./... -count=1`、`go test -race ./... -count=1`、`go test -cover ./internal/... -count=1`、`go test ./tests/integration/... -count=1`、`bash ./scripts/test/test_real_host_scripts.sh` 全通过。
|
||||
|
||||
## 当前门控结论
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
| OpenAPI | ✅ SYNCED | `docs/openapi.yaml` 已补当前控制面端点 |
|
||||
| Local runtime smoke | ✅ PASS | `go build ./cmd/{server,cli}`、`GET /healthz`、`GET /api/hosts` |
|
||||
| Local OCI image | ✅ PASS | `docker build -f Dockerfile.local -t sub2api-cn-relay-manager:local .` |
|
||||
| Real-host acceptance tooling | ✅ READY | `docs/REAL_HOST_ACCEPTANCE_RUNBOOK.md` + `scripts/real_host_acceptance.sh` |
|
||||
| Harness regression self-check | ✅ PASS | `bash ./scripts/test_real_host_scripts.sh` |
|
||||
| Real-host acceptance tooling | ✅ READY | `docs/REAL_HOST_ACCEPTANCE_RUNBOOK.md` + `scripts/acceptance/real_host_acceptance.sh` |
|
||||
| Harness regression self-check | ✅ PASS | `bash ./scripts/test/test_real_host_scripts.sh` |
|
||||
| `self_service` 真实宿主 latest-head fresh host 复验 | ✅ PASS | `artifacts/real-host-acceptance/20260521_210403`:`05-import.json` = `succeeded/self_service_ready/active`,`07-access-status.json` = `latest_access_status=fully_ready` |
|
||||
| `subscription` 真实宿主 patched fresh host 复验 | ✅ PASS | MiniMax:`artifacts/real-host-acceptance/20260521_191418_remote43_minimax_key_import`;DeepSeek:`artifacts/real-host-acceptance/20260521_201509_remote43_deepseek_key_import`;两条 provider 都已证明 current-code 在真实 fresh-host 上可闭环到 `batch_status=succeeded`、`provider_status=active` |
|
||||
| stale CRM / channel pricing 缺口 | ✅ CLOSED | 宿主 `GET /api/v1/admin/channels/5` 与 `/channels/4` 已返回非空 `model_pricing` + `model_mapping` |
|
||||
@@ -69,9 +69,9 @@
|
||||
- 本地 HTTP smoke 与 `Dockerfile.local` 容器构建已验证通过
|
||||
|
||||
4. 补齐上线前执行工具
|
||||
- 新增 `scripts/build_local_image.sh`,固化本地/代理环境的镜像构建路径
|
||||
- 新增 `scripts/deploy/build_local_image.sh`,固化本地/代理环境的镜像构建路径
|
||||
- 新增 `docs/REAL_HOST_ACCEPTANCE_RUNBOOK.md`
|
||||
- 新增 `scripts/real_host_acceptance.sh`,把真实宿主验收固化为可落盘 artifact 的流程
|
||||
- 新增 `scripts/acceptance/real_host_acceptance.sh`,把真实宿主验收固化为可落盘 artifact 的流程
|
||||
|
||||
5. 当前代码后的最新事实
|
||||
- 宿主 admin 侧直接复核仍证明 channel `billing_model_source=channel_mapped`、`restrict_models=true`、`model_pricing/model_mapping` 已能被正确写入
|
||||
@@ -93,7 +93,7 @@
|
||||
### P2 已接受技术债务
|
||||
- `internal/worker` 已抽出通用 polling runner,当前 batch-import runtime 与后台 reconcile 都已接入;调度模型仍是固定间隔 polling,而不是完整 jobs/reconcile 平台
|
||||
- CLI `run*` 真实链路函数未做系统性 mock 单测
|
||||
- 标准多阶段 `Dockerfile` 在受限网络下仍依赖容器内联网拉取 Go modules;本地部署默认走 `scripts/build_local_image.sh`
|
||||
- 标准多阶段 `Dockerfile` 在受限网络下仍依赖容器内联网拉取 Go modules;本地部署默认走 `scripts/deploy/build_local_image.sh`
|
||||
- `subscription` 这条 provider matrix 已通过;剩余待补的是 latest-head `self_service` fresh-host 复验,而不是继续替换 provider key
|
||||
|
||||
## 最短上线闭环
|
||||
|
||||
166
docs/PROJECT_STRUCTURE.md
Normal file
166
docs/PROJECT_STRUCTURE.md
Normal file
@@ -0,0 +1,166 @@
|
||||
# 项目目录说明
|
||||
|
||||
日期:2026-05-27
|
||||
|
||||
## 目的
|
||||
|
||||
这份文档用于回答两个问题:
|
||||
|
||||
1. 当前仓库各一级目录分别负责什么
|
||||
2. 新增文件应该放到哪里,避免继续把运行时脚本、部署资产、验收证据混在一起
|
||||
|
||||
它不替代 `README.md`,而是补充更细的目录职责说明。
|
||||
|
||||
## 一级目录
|
||||
|
||||
### `cmd/`
|
||||
|
||||
程序入口:
|
||||
|
||||
- `cmd/server`
|
||||
- 控制面 HTTP 服务入口
|
||||
- `cmd/cli`
|
||||
- 导入、overlay、验证等命令行入口
|
||||
|
||||
### `internal/`
|
||||
|
||||
控制面核心实现,按职责拆分:
|
||||
|
||||
- `internal/access`
|
||||
- access closure、自愈、gateway 验证
|
||||
- `internal/app`
|
||||
- HTTP API、bootstrap、后台任务
|
||||
- `internal/batch`
|
||||
- batch import 请求与状态投影
|
||||
- `internal/config`
|
||||
- 配置装载
|
||||
- `internal/host/sub2api`
|
||||
- 宿主适配器
|
||||
- `internal/overlay`
|
||||
- host overlay 执行器
|
||||
- `internal/pack`
|
||||
- pack 装载、校验、overlay 解析
|
||||
- `internal/probe`
|
||||
- upstream / host smoke probes
|
||||
- `internal/provision`
|
||||
- import / preview / rollback / reconcile 编排
|
||||
- `internal/reconcile`
|
||||
- 后台对账
|
||||
- `internal/store`
|
||||
- SQLite repo 与 migrations
|
||||
- `internal/testutil`
|
||||
- 测试辅助
|
||||
- `internal/worker`
|
||||
- 后台 runner
|
||||
|
||||
### `packs/`
|
||||
|
||||
版本化模型包资产:
|
||||
|
||||
- `packs/openai-cn-pack`
|
||||
- provider manifests
|
||||
- checksums
|
||||
- overlay metadata
|
||||
|
||||
这层只放 pack 资产,不放远端站点静态页。
|
||||
|
||||
### `deploy/`
|
||||
|
||||
面向部署目标的静态资产或配置模板。
|
||||
|
||||
当前已经纳入:
|
||||
|
||||
- `deploy/tksea-portal/index.html`
|
||||
- `sub.tksea.top/portal/` 静态页
|
||||
- `deploy/tksea-portal/nginx.sub.tksea.top.conf.example`
|
||||
- 对应 Nginx 路由示例
|
||||
|
||||
这层的规则是:
|
||||
|
||||
- 放“部署产物模板”
|
||||
- 不放需要编译的 Go 代码
|
||||
- 不放临时 `/tmp` 产物
|
||||
|
||||
### `scripts/`
|
||||
|
||||
运维、验收、部署脚本,当前已经按用途拆成三层目录:
|
||||
|
||||
- `scripts/deploy/`
|
||||
- 部署与环境拉起脚本
|
||||
- 例如 `build_local_image.sh`、`setup_remote43_patched_stack.sh`、`deploy_tksea_portal.sh`
|
||||
- `scripts/acceptance/`
|
||||
- 真实宿主验收与证据处理脚本
|
||||
- 例如 `real_host_acceptance.sh`、`import_remote43_provider.sh`、`check_deepseek_completion_split.sh`
|
||||
- `scripts/test/`
|
||||
- 脚本资产回归
|
||||
- 例如 `test_real_host_scripts.sh`、`test_tksea_portal_assets.sh`
|
||||
|
||||
规则:
|
||||
|
||||
- 只放可执行运维脚本
|
||||
- 新脚本必须先判断属于 `deploy/`、`acceptance/` 还是 `test/`
|
||||
- 脚本依赖的静态模板应尽量放到 `deploy/` 或 `docs/`
|
||||
|
||||
### `docs/`
|
||||
|
||||
所有长期保留文档:
|
||||
|
||||
- 真相入口
|
||||
- 执行板
|
||||
- 验收 runbook
|
||||
- provider 矩阵
|
||||
- 外部 OpenClaw 验证
|
||||
- 目录与部署说明
|
||||
|
||||
### `tests/`
|
||||
|
||||
集成测试套件:
|
||||
|
||||
- `tests/integration`
|
||||
|
||||
### `artifacts/`
|
||||
|
||||
真实验收产物与归档证据。
|
||||
|
||||
规则:
|
||||
|
||||
- `artifacts/real-host-acceptance/`
|
||||
- 当前最终证据
|
||||
- `artifacts/real-host-acceptance-archive/`
|
||||
- 历史调试样本与归档
|
||||
|
||||
不要把部署模板、静态页、脚本说明放到这里。
|
||||
|
||||
### `web/`
|
||||
|
||||
保留给未来管理端前端实现。
|
||||
|
||||
当前公网 portal 已经独立作为 `deploy/tksea-portal/` 静态资产纳管,不应误放进 `web/`,因为它不是控制面管理后台。
|
||||
|
||||
## 当前推荐放置规则
|
||||
|
||||
新增文件时,优先按下面规则归类:
|
||||
|
||||
- 新的 provider / pack 元数据
|
||||
- 放 `packs/`
|
||||
- 新的 Go 业务逻辑
|
||||
- 放 `internal/`
|
||||
- 新的 CLI 或 server 入口
|
||||
- 放 `cmd/`
|
||||
- 新的线上静态部署页 / 反向代理模板
|
||||
- 放 `deploy/`
|
||||
- 新的运维或验收命令脚本
|
||||
- 放 `scripts/deploy`、`scripts/acceptance` 或 `scripts/test`
|
||||
- 新的长期说明文档
|
||||
- 放 `docs/`
|
||||
- 新的验收证据
|
||||
- 放 `artifacts/`
|
||||
|
||||
## 当前整理结果
|
||||
|
||||
截至 2026-05-27,最近一轮目录整理主要做了三件事:
|
||||
|
||||
1. 把原来只存在 `/tmp` 的 `sub.tksea.top` portal 静态页与 Nginx 规则正式纳入仓库
|
||||
2. 把 portal 部署动作收口到 `scripts/deploy/deploy_tksea_portal.sh`
|
||||
3. 把 `scripts/` 从全平铺整理为 `deploy/`、`acceptance/`、`test/` 三层,减少脚本入口混杂
|
||||
4. 把“公网 portal / OpenClaw / remote43 验收”相关说明分别挂回 `deploy/`、`scripts/`、`docs/`
|
||||
@@ -37,33 +37,46 @@
|
||||
- 高频误判点
|
||||
- 推荐诊断顺序
|
||||
|
||||
7. [OPENCLAW_EXTERNAL_VALIDATION.md](./OPENCLAW_EXTERNAL_VALIDATION.md)
|
||||
- OpenClaw 最后一跳真实使用验证
|
||||
- 升级后补丁自检与 cron 提醒
|
||||
- `tksea` / `53hk` 多模型运行态口径
|
||||
|
||||
8. [PROJECT_STRUCTURE.md](./PROJECT_STRUCTURE.md)
|
||||
- 当前仓库目录职责说明
|
||||
- 新增文件该放在哪一层
|
||||
|
||||
9. [../scripts/README.md](../scripts/README.md)
|
||||
- `scripts/deploy`、`scripts/acceptance`、`scripts/test` 的入口说明
|
||||
- 继续整理脚本或追脚本回归时先看这里
|
||||
|
||||
## 背景/设计文档
|
||||
|
||||
6. [PRD.md](./PRD.md)
|
||||
10. [PRD.md](./PRD.md)
|
||||
- PRD 首版范围
|
||||
|
||||
7. [TDD_PLAN.md](./TDD_PLAN.md)
|
||||
11. [TDD_PLAN.md](./TDD_PLAN.md)
|
||||
- 测试设计与实现计划
|
||||
|
||||
8. [2026-05-12-sub2api-cn-relay-manager-solution.md](./2026-05-12-sub2api-cn-relay-manager-solution.md)
|
||||
12. [2026-05-12-sub2api-cn-relay-manager-solution.md](./2026-05-12-sub2api-cn-relay-manager-solution.md)
|
||||
- 早期方案设计与宿主接口理解
|
||||
|
||||
9. [DEPLOYMENT.md](./DEPLOYMENT.md)
|
||||
13. [DEPLOYMENT.md](./DEPLOYMENT.md)
|
||||
- 部署说明
|
||||
|
||||
10. [KNOWN_LIMITATIONS.md](./KNOWN_LIMITATIONS.md)
|
||||
14. [KNOWN_LIMITATIONS.md](./KNOWN_LIMITATIONS.md)
|
||||
- 当前限制项
|
||||
|
||||
11. [plans/2026-05-12-sub2api-cn-relay-manager-implementation-plan.md](./plans/2026-05-12-sub2api-cn-relay-manager-implementation-plan.md)
|
||||
15. [plans/2026-05-12-sub2api-cn-relay-manager-implementation-plan.md](./plans/2026-05-12-sub2api-cn-relay-manager-implementation-plan.md)
|
||||
- 初始实现计划
|
||||
|
||||
## 历史快照文档(只可参考,不可直接当当前真相)
|
||||
|
||||
12. [2026-05-18-PRODUCTION_READINESS_REVIEW.md](./2026-05-18-PRODUCTION_READINESS_REVIEW.md)
|
||||
16. [2026-05-18-PRODUCTION_READINESS_REVIEW.md](./2026-05-18-PRODUCTION_READINESS_REVIEW.md)
|
||||
- 历史审查快照
|
||||
- 用来看当时发现了哪些系统性问题
|
||||
|
||||
13. [2026-05-18-PRODUCTION_REMEDIATION_TASK_BOARD.md](./2026-05-18-PRODUCTION_REMEDIATION_TASK_BOARD.md)
|
||||
17. [2026-05-18-PRODUCTION_REMEDIATION_TASK_BOARD.md](./2026-05-18-PRODUCTION_REMEDIATION_TASK_BOARD.md)
|
||||
- 历史整改任务板
|
||||
- 用来看 2026-05-18 那一轮是如何收口的
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
- 适合快速确认红线、三层证据和最短诊断顺序。
|
||||
5. `docs/REAL_HOST_ACCEPTANCE_LEARNINGS.md`
|
||||
- 看已经调通的细节、典型误判点、推荐诊断顺序。
|
||||
6. `docs/OPENCLAW_EXTERNAL_VALIDATION.md`
|
||||
- 当真实宿主、公网域名与最终用户 key 已经打通后,继续看这份。
|
||||
- 它定义的是 OpenClaw 最后一跳真实使用验证与升级后自检,不再局限于 relay-manager/host 导入层。
|
||||
|
||||
## 目标
|
||||
|
||||
@@ -49,7 +52,7 @@
|
||||
|
||||
```bash
|
||||
cd /path/to/sub2api-cn-relay-manager
|
||||
bash ./scripts/test_real_host_scripts.sh
|
||||
bash ./scripts/test/test_real_host_scripts.sh
|
||||
```
|
||||
|
||||
说明:
|
||||
@@ -60,7 +63,7 @@ bash ./scripts/test_real_host_scripts.sh
|
||||
|
||||
```bash
|
||||
cd /path/to/sub2api-cn-relay-manager
|
||||
scripts/build_local_image.sh
|
||||
scripts/deploy/build_local_image.sh
|
||||
```
|
||||
|
||||
默认输出:
|
||||
@@ -76,7 +79,7 @@ cd /path/to/sub2api-cn-relay-manager
|
||||
|
||||
HOST_BINARY=/path/to/sub2api-patched \
|
||||
CRM_BINARY=./server \
|
||||
bash ./scripts/setup_remote43_patched_stack.sh
|
||||
bash ./scripts/deploy/setup_remote43_patched_stack.sh
|
||||
```
|
||||
|
||||
脚本会:
|
||||
@@ -98,7 +101,7 @@ bash /tmp/remote43-patched-stack-18139.tunnel.sh
|
||||
然后再跑:
|
||||
|
||||
```bash
|
||||
bash ./scripts/import_remote43_provider.sh kimi-a7m kimi-k2.6 A7M_KIMI_API_KEY /path/to/keyfile
|
||||
bash ./scripts/acceptance/import_remote43_provider.sh kimi-a7m kimi-k2.6 A7M_KIMI_API_KEY /path/to/keyfile
|
||||
```
|
||||
|
||||
### 3. 先 dry-run 检查真实验收参数
|
||||
@@ -115,7 +118,7 @@ KEYS=sk-live-1,sk-live-2 \
|
||||
ACCESS_MODE=self_service \
|
||||
ACCESS_API_KEY=user-gateway-key \
|
||||
DRY_RUN=1 \
|
||||
bash ./scripts/real_host_acceptance.sh
|
||||
bash ./scripts/acceptance/real_host_acceptance.sh
|
||||
```
|
||||
|
||||
### 4. 执行真实验收
|
||||
@@ -131,7 +134,7 @@ PROVIDER_ID=deepseek \
|
||||
KEYS=sk-live-1,sk-live-2 \
|
||||
ACCESS_MODE=self_service \
|
||||
ACCESS_API_KEY=user-gateway-key \
|
||||
bash ./scripts/real_host_acceptance.sh
|
||||
bash ./scripts/acceptance/real_host_acceptance.sh
|
||||
```
|
||||
|
||||
### 5. 订阅模式示例
|
||||
@@ -148,7 +151,7 @@ KEYS=sk-live-1 \
|
||||
ACCESS_MODE=subscription \
|
||||
SUBSCRIPTION_USERS=user-a,user-b \
|
||||
SUBSCRIPTION_DAYS=30 \
|
||||
bash ./scripts/real_host_acceptance.sh
|
||||
bash ./scripts/acceptance/real_host_acceptance.sh
|
||||
```
|
||||
|
||||
### 6. 导入后自动补 access 前置(可选)
|
||||
@@ -158,7 +161,7 @@ bash ./scripts/real_host_acceptance.sh
|
||||
```bash
|
||||
AFTER_IMPORT_HOOK_COMMAND='bash /path/to/host-access-hook.sh' \
|
||||
... \
|
||||
scripts/real_host_acceptance.sh
|
||||
scripts/acceptance/real_host_acceptance.sh
|
||||
```
|
||||
|
||||
hook 执行时会额外导出:
|
||||
@@ -176,6 +179,31 @@ hook 执行时会额外导出:
|
||||
- `05b-after-import-hook.stdout.txt`
|
||||
- `05b-after-import-hook.stderr.txt`
|
||||
|
||||
### 7. OpenClaw 最后一跳外部验证
|
||||
|
||||
当你已经确认:
|
||||
|
||||
- remote43 或本地 patched host 验收通过
|
||||
- 公网根地址已暴露
|
||||
- 真实用户可以自助注册并创建 key
|
||||
|
||||
不要在 `21-summary.json` 停止,继续追加一轮 OpenClaw 外部真实验证:
|
||||
|
||||
```bash
|
||||
~/.openclaw/bin/apply-openclaw-minimax-proxy-fix.sh doctor
|
||||
~/.openclaw/bin/openclaw-minimax-post-upgrade-check.sh
|
||||
|
||||
openclaw infer model run --local --model "tksea-gpt/gpt-5.4" --prompt "reply with pong only" --json
|
||||
openclaw infer model run --local --model "tksea-gpt/gpt-5.4-mini" --prompt "reply with pong only" --json
|
||||
openclaw infer model run --local --model "tksea-minimax/MiniMax-M2.5-highspeed" --prompt "reply with pong only" --json
|
||||
openclaw infer model run --local --model "tksea-minimax/MiniMax-M2.7-highspeed" --prompt "reply with pong only" --json
|
||||
```
|
||||
|
||||
当前推荐把这一步的口径记录到:
|
||||
|
||||
- `docs/OPENCLAW_EXTERNAL_VALIDATION.md`
|
||||
- 或对应批次 artifact 的补充说明中
|
||||
|
||||
## 产物
|
||||
|
||||
脚本会把每一步 JSON 响应落到:
|
||||
@@ -229,7 +257,7 @@ remote43 / 本地缩圈脚本若需要额外证据,会在同目录追加:
|
||||
- `21-summary.json` / `99-semantic-summary.json`(推荐长期保留的摘要证据)
|
||||
- 若你是在清理旧目录,而不是生成新验收产物,优先运行:
|
||||
```bash
|
||||
python3 scripts/migrate_historical_artifacts.py artifacts/real-host-acceptance
|
||||
python3 scripts/acceptance/migrate_historical_artifacts.py artifacts/real-host-acceptance
|
||||
```
|
||||
它会把主目录中的历史敏感材料迁到 `artifacts/real-host-acceptance-sensitive/`,并在原目录生成安全摘要版。
|
||||
- 历史目录迁移脚本当前已覆盖两层:
|
||||
@@ -281,7 +309,7 @@ remote43 / 本地缩圈脚本若需要额外证据,会在同目录追加:
|
||||
1. 默认会执行 rollback smoke;若当前环境不允许回滚,设置:
|
||||
|
||||
```bash
|
||||
SKIP_ROLLBACK=1 scripts/real_host_acceptance.sh
|
||||
SKIP_ROLLBACK=1 scripts/acceptance/real_host_acceptance.sh
|
||||
```
|
||||
|
||||
2. `PACK_PATH` 必须是控制面进程可读路径,不是用户本地概念路径。
|
||||
@@ -292,13 +320,13 @@ SKIP_ROLLBACK=1 scripts/real_host_acceptance.sh
|
||||
7. `self_service` 验证除普通用户 key 外,还需要该 key 绑定目标 group;若目标 group 是标准计费组,还需要用户侧具备可用余额,否则 `/v1/models` 可能从“未授权”转为 `INSUFFICIENT_BALANCE`。
|
||||
8. `subscription` 验证需要目标 group 本身是 `subscription` 类型,并且完成“普通用户订阅分配 + 普通用户 key 绑定该 group”;仅有管理员主体或未绑定 key 不足以通过 `/v1/models`。
|
||||
9. 若需要验证 `reconcile` 收敛,优先在干净宿主场景或隔离 group 下执行,避免历史残留资源把结果污染成 `status=drifted` / `extra_count>0`。
|
||||
10. `scripts/import_remote43_provider.sh` 现已内置 remote43 的 subscription 验收补全动作:会根据 import batch 自动解析目标 group,执行“普通用户最低余额补齐 + key/group 绑定 + user_subscriptions upsert + 定向 Redis 缓存失效(auth / balance / subscription)”,并把 SQL / host state 证据写入 artifact 目录。
|
||||
10. `scripts/acceptance/import_remote43_provider.sh` 现已内置 remote43 的 subscription 验收补全动作:会根据 import batch 自动解析目标 group,执行“普通用户最低余额补齐 + key/group 绑定 + user_subscriptions upsert + 定向 Redis 缓存失效(auth / balance / subscription)”,并把 SQL / host state 证据写入 artifact 目录。
|
||||
11. 当 CRM 进程与 operator 到 host 的访问地址不一致时,优先显式设置 `CRM_HOST_BASE`,避免把 CRM 侧探测地址和本地运维隧道地址混用。
|
||||
12. 对 `Upstream service temporarily unavailable` 一类 502,不要先认定是上游聊天链路故障;先看脚本落盘的 `09-models.headers.txt` / `10-models.body.json`。若 `/v1/models` 已返回了别的 provider 模型集(例如 GPT 系列而不是预期的 DeepSeek/Minimax 模型),先检查普通用户 key/group 绑定,也要检查 CRM 导入时是否把 provider 的 `channel_template.model_mapping`、`restrict_models`、`billing_model_source` 一并下发到宿主 channel。
|
||||
13. subscription 场景里,closure 最终用于 gateway probe 的 key 是宿主侧 managed key,不一定是请求体里外部传入的 `ACCESS_API_KEY`。如果你拿原始 key 直打 `/v1/models` 收到 `403 not assigned to any group`,先不要判定 CRM 主链路失败。
|
||||
14. 对“既有 channel 没自动补 `model_pricing`”这类 live 现象,先核对在线 CRM 进程的启动时间与 git 提交时间;之前 MiniMax 的该现象最终被确认是 stale CRM 进程导致,而不是源码缺逻辑。
|
||||
15. 当 CRM 切换到本机运行时,`PACK_PATH` 也必须切换到控制面本机可读路径;继续沿用远端 `/home/ubuntu/...` 会触发 `stat pack path ... no such file or directory`,这是验收 harness 参数问题,不是导入业务逻辑问题。
|
||||
16. 若要把 DeepSeek 的“host `/v1/models`=200 但 host `/v1/chat/completions`=502,而 upstream 直探 `/chat/completions`=200”做成可提 issue 的最小复现,直接运行 `scripts/check_deepseek_completion_split.sh`。它会同时落盘 host `/v1/models`、host `/v1/chat/completions`、upstream `/chat/completions` 三层证据,并在 `summary.json` 里给出 `host_compatibility_gap|upstream_key_quota_issue|unknown` 分类。
|
||||
16. 若要把 DeepSeek 的“host `/v1/models`=200 但 host `/v1/chat/completions`=502,而 upstream 直探 `/chat/completions`=200”做成可提 issue 的最小复现,直接运行 `scripts/acceptance/check_deepseek_completion_split.sh`。它会同时落盘 host `/v1/models`、host `/v1/chat/completions`、upstream `/chat/completions` 三层证据,并在 `summary.json` 里给出 `host_compatibility_gap|upstream_key_quota_issue|unknown` 分类。
|
||||
17. 若 reconcile 面对的是“非 latest batch 的同前缀旧账号”,最新代码会把它们记为 `stale_noise_count` / `stale_noise_accounts` 并保留 `raw_extra_count`,而不是继续把它们算进 `extra_count` 造成 drift 误报;因此应优先看 `extra_count` 是否归零,再看 `probe_failures`/`access_status` 是否仍有真实异常。
|
||||
18. self_service 场景里,普通用户 gateway key 访问宿主 `/v1/models` / `/v1/chat/completions` 时,真实语义是 `Authorization: Bearer <gateway-key>`;若 CRM 的 self_service closure 仍显示 `401/403 broken`,优先排查 gateway probe 是否错误复用了 `x-api-key`。
|
||||
19. fresh-host 管理员 bearer token 过期时,最前面的 `POST /api/hosts` / `probe-host` 可能直接表现成 CRM 侧 `502`。遇到这类现象,先刷新 host bearer token,再继续验收,不要先把它归因为最新代码故障。
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
当历史 `artifacts/real-host-acceptance/` 目录里仍残留旧版敏感材料时,使用:
|
||||
|
||||
```bash
|
||||
python3 scripts/migrate_historical_artifacts.py artifacts/real-host-acceptance
|
||||
python3 scripts/acceptance/migrate_historical_artifacts.py artifacts/real-host-acceptance
|
||||
```
|
||||
|
||||
默认行为:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
当前 gate 升到 `APPROVED` 的原因是:
|
||||
1. 代码侧已关闭“只靠 `/v1/models` 就把 access 标成 ready”的假阳性;当前 ready 必须同时通过 `/v1/models` 与 `/v1/chat/completions` smoke
|
||||
2. `scripts/import_remote43_provider.sh` 已补上 upstream `/models` 与 `/chat/completions` 直探,并落盘 `21-summary.json` 做根因分类
|
||||
2. `scripts/acceptance/import_remote43_provider.sh` 已补上 upstream `/models` 与 `/chat/completions` 直探,并落盘 `21-summary.json` 做根因分类
|
||||
3. account `credentials.model_mapping`、channel `model_mapping/model_pricing`、managed key 视角 `/v1/models` 都已有 live 证据
|
||||
4. completion-gated 补丁已经在 fresh-host 上重跑验证通过:control plane 会把 completion 失败正确落成 `broken`
|
||||
5. MiniMax account probe 假失败也已被最新补丁关闭:
|
||||
|
||||
Reference in New Issue
Block a user