phamnazage-jpg 09f7c07de3
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
feat(portal): make provider/batch-import form fields self-explanatory + auto-fill
Problem: provider manifest form had all-empty fields with cryptic
placeholders, users had to know what model IDs to type.

Fix on /portal/admin/providers.html (Provider Manifest 草稿):
- DISPLAY NAME: datalist of common vendors (OpenAI / DeepSeek /
  硅基流动 / Moonshot / 智谱 / Anthropic / 零一万物 / MiniMax / Qwen / Baichuan / 混元)
- PLATFORM: datalist of common platforms (openai / openai-compatible /
  deepseek / anthropic / gemini / zhipu / moonshot / minimax / qwen / ...)
- SMOKE TEST MODEL: datalist of common smoke models + auto-fills with
  first model from MODELS field if user leaves it empty
- BASE URL PLACEHOLDER: datalist of common base URLs (12 presets)
- MODELS: chip-row of 11 common models (gpt-5.4, gpt-5.4-mini,
  deepseek-chat, MiniMax-M2.7-highspeed, kimi-k2.6, glm-4.6,
  claude-sonnet-4-5, gemini-2.5-pro, qwen3-coder-plus, gpt-4o, o4-mini)
  + clear button. Click chip → append to MODELS field (dedup).
- KEYS textarea: 6 rows + example placeholder (sk-example-1/2/3)

Fix on /portal/admin-batch-import.html (发起导入):
- HOST ID: datalist of common host_ids + hint about loading pack first
- ENTRIES textarea: 6 rows + multi-line hint explaining
  base_url|api_key|model1,model2 format, optional model, batch import

JS change: syncDraftHelperState() in providers.html now auto-fills
smoke_test_model with first model if user hasn't filled it yet.
Also fixed: 2 duplicate copies of syncDraftHelperState (from
earlier batch script restoration) — both now have the new logic.

Verification:
- bash scripts/test/test_tksea_portal_assets.sh → PASS
- bash scripts/test/verify_frontend_smoke.sh → PASS
- browser_console click test: gpt-5.4 + deepseek-chat + kimi-k2.6 chips
  → models='gpt-5.4,deepseek-chat,kimi-k2.6' + smoke='gpt-5.4' auto-fill ✓
- screenshot: /tmp/portal-screenshots/admin-providers-v5.png
2026-06-03 11:24:54 +08:00
2026-05-12 21:46:19 +08:00

sub2api-cn-relay-manager

sub2api-cn-relay-manager 是一个独立于 sub2api 宿主仓库的外部伴生安装器 / 控制面项目。

目标不是修改 sub2api,也不是把国产模型能力硬塞进宿主源码,而是通过 sub2api 已有的管理 API把“国产模型 OpenAI 兼容中转能力”以独立交付物的形式安装到任意一台已部署的 sub2api 实例上。

项目定位

  • 宿主:第三方开源系统 sub2api
  • 约束:不修改宿主代码,不 fork 宿主,不要求宿主内置原生插件运行时
  • 交付:一个独立控制面项目 + 一个或多个 model_pack
  • 结果:管理员可一键导入多个国产模型 key普通用户继续只用 sub2api 标准 API

这个项目解决的问题

  • 不同机器部署了 sub2api 后,如何用同一套交付物补齐国产模型中转能力
  • 如何把多个国产模型 key 批量导入为可用的宿主资源
  • 如何在不改宿主的前提下实现热生效、探测、对账和漂移发现
  • 如何让普通用户完全无感,继续走 sub2api 标准接口

非目标

  • 不做宿主原生插件系统
  • 不做任意第三方 Go 代码动态加载
  • 不要求宿主识别“插件”概念
  • 不接管宿主网关流量

目录结构

sub2api-cn-relay-manager/
  cmd/                         # CLI / server 入口
  internal/                    # 控制面核心实现
  packs/                       # provider packs / overlay metadata
  deploy/                      # 部署资产portal 静态页、Nginx 模板)
  scripts/                     # deploy / acceptance / test 三层脚本
  docs/                        # 真相入口、执行板、runbook、目录说明
  tests/                       # 集成测试
  artifacts/                   # 真实验收证据与归档
  web/                         # 预留给未来管理端前端

如果你想看更细的目录职责,而不是只看一级树结构,读:

交付模型

本项目最终会拆成两个可独立发布的产物:

  1. sub2api-cn-relay-manager

    • 外部控制面 / 安装器
    • 连接已有 sub2api
    • 安装模型包
    • 调用宿主管理 API 创建资源
    • 做 smoke test、对账和状态展示
  2. model_pack

    • 只包含 provider 定义、默认模板、导入规则和校验信息
    • 不携带宿主执行代码
    • 可以跨机器复用

当前文档

先读这些:

背景/设计文档:

当前 MVP 能力

当前仓库已经具备一个最小可运行闭环:

  • packs/openai-cn-pack/ 提供真实 pack.json + provider + checksums
  • internal/pack 负责 pack 装载、checksum 校验、provider schema 校验
  • internal/provision 负责多 key 导入编排、账号探测和访问闭环判定
  • cmd/cli import-provider 提供一键导入入口

示例:

go run ./cmd/cli import-provider \
  --host-base-url https://sub2api.example.com \
  --host-api-key <admin-api-key> \
  --pack-dir ./packs/openai-cn-pack \
  --provider-id deepseek \
  --keys sk-a,sk-b \
  --access-mode self_service \
  --access-api-key <user-api-key>

运行方式

服务端:

SUB2API_CRM_ADMIN_TOKEN=replace-me go run ./cmd/server

Docker Compose

cp .env.example .env
# 编辑 .env 中的 SUB2API_CRM_ADMIN_TOKEN
scripts/deploy/build_local_image.sh
docker run --rm -p 8080:8080 \
  --env-file .env \
  -v "$(pwd)/data:/data" \
  sub2api-cn-relay-manager:local
curl -fsS http://127.0.0.1:8080/healthz

真实宿主验收:

CRM_BASE_URL=http://127.0.0.1:8080 \
CRM_ADMIN_TOKEN='<crm-admin-token>' \
HOST_NAME=prod-sub2api \
HOST_BASE_URL=https://sub2api.example.com \
HOST_API_KEY='<sub2api-admin-key>' \
PACK_PATH=/app/packs/openai-cn-pack \
PROVIDER_ID=deepseek \
KEYS=sk-live-1 \
ACCESS_MODE=self_service \
ACCESS_API_KEY='<user-gateway-key>' \
DRY_RUN=1 \
scripts/acceptance/real_host_acceptance.sh
Description
No description provided
Readme 58 MiB
Languages
Go 73.9%
Shell 11.1%
HTML 10.4%
CSS 1.8%
JavaScript 1.1%
Other 1.7%