Files
sub2api-cn-relay-manager/docs/plans/2026-05-12-sub2api-cn-relay-manager-implementation-plan.md
2026-05-12 21:46:19 +08:00

24 KiB
Raw Blame History

sub2api-cn-relay-manager Implementation Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: 构建一个完全独立于宿主 sub2api 的外部伴生控制面,在不修改宿主代码的前提下,通过安装 model_pack、批量导入国产模型 key、自动创建宿主资源并完成用户访问闭环让普通用户直接通过 sub2api 标准 API 使用国产模型。

Architecture: 采用“外部控制面 + model_pack + 宿主 HTTP API 适配器”架构。控制面只通过 sub2api 公开管理 API 和标准 API 工作,负责模型包安装、宿主能力探测、资源编排、导入回滚、访问闭环验证和持续对账;宿主继续承担标准 API 网关职责,不做任何源码、数据库或运行时注入修改。

Tech Stack: Go 1.24、Chi、database/sql + SQLite 驱动、PostgreSQL 兼容预留、OpenAPI 3.1、Go testing + httptest、前端首版后置MVP 先提供 HTTP API、CLI 和 Docker 交付物。


1. 实施边界

1.1 必须满足

  • 不修改宿主 sub2api 源码
  • 不 fork 宿主并运行自定义二进制
  • 不直接写宿主数据库
  • 不向宿主目录写入运行时代码、插件文件或配置补丁
  • 只通过宿主现有管理 API 和标准 API 工作
  • 首版必须完成从“导入 key”到“普通用户可实际调用”的闭环

1.2 首版不做

  • 宿主原生插件中心
  • 任意后端代码插件加载
  • 代替用户签发宿主最终 API key
  • 多宿主编排联邦
  • 自定义计费、结算或审计系统

2. 目标目录结构

sub2api-cn-relay-manager/
  cmd/
    server/main.go
    cli/main.go
  internal/
    app/
      app.go
      bootstrap.go
    config/
      config.go
    domain/
      host.go
      pack.go
      provider.go
      resource.go
      import_batch.go
      reconcile.go
      access_closure.go
    host/
      sub2api/
        client.go
        capability_probe.go
        groups.go
        channels.go
        plans.go
        accounts.go
        subscriptions.go
        gateway_probe.go
    pack/
      manifest.go
      provider_manifest.go
      checksum.go
      validator.go
      loader.go
    provision/
      preview_service.go
      import_service.go
      rollback_service.go
      naming.go
    access/
      planner.go
      subscription_service.go
      self_service_checker.go
    reconcile/
      runner.go
      drift_checker.go
      probe_runner.go
    store/
      migrations/
      sqlite/
        db.go
        hosts_repo.go
        host_capability_snapshots_repo.go
        packs_repo.go
        providers_repo.go
        installs_repo.go
        import_batches_repo.go
        resources_repo.go
        reconcile_runs_repo.go
        probe_results_repo.go
        access_closure_records_repo.go
    api/
      http/
        router.go
        middleware.go
        hosts_handler.go
        packs_handler.go
        providers_handler.go
        imports_handler.go
        access_handler.go
        reconcile_handler.go
        dto/
          hosts.go
          packs.go
          providers.go
          imports.go
          access.go
          reconcile.go
    worker/
      scheduler.go
      jobs.go
  docs/
    api/openapi.yaml
    plans/
      2026-05-12-sub2api-cn-relay-manager-implementation-plan.md
  packs/
    openai-cn-pack/
      pack.json.example
      providers/
        deepseek.json.example
  tests/
    integration/
      host_stub_test.go
      install_pack_test.go
      import_keys_test.go
      access_closure_test.go
      reconcile_test.go

3. 核心接口与契约

3.1 控制面对外 API

宿主管理

  • POST /api/hosts
  • GET /api/hosts
  • GET /api/hosts/{host_id}
  • POST /api/hosts/{host_id}/probe

模型包管理

  • POST /api/packs/install
  • GET /api/packs
  • GET /api/packs/{pack_id}
  • GET /api/packs/{pack_id}/providers

Provider 导入

  • POST /api/providers/{provider_id}/preview-import
  • POST /api/providers/{provider_id}/import
  • GET /api/providers/{provider_id}/import-batches
  • GET /api/import-batches/{batch_id}
  • POST /api/import-batches/{batch_id}/rollback

访问闭环

  • POST /api/providers/{provider_id}/access/preview
  • POST /api/providers/{provider_id}/access/assign-subscriptions
  • GET /api/providers/{provider_id}/access/status

对账与状态

  • POST /api/providers/{provider_id}/reconcile
  • GET /api/providers/{provider_id}/status
  • GET /api/providers/{provider_id}/resources

3.2 宿主适配器接口

internal/host/sub2api/client.go 中定义单一适配接口:

type HostAdapter interface {
    GetHostVersion(ctx context.Context) (string, error)
    ProbeCapabilities(ctx context.Context) (HostCapabilities, error)
    CreateGroup(ctx context.Context, req CreateGroupRequest) (GroupRef, error)
    CreateChannel(ctx context.Context, req CreateChannelRequest) (ChannelRef, error)
    CreatePlan(ctx context.Context, req CreatePlanRequest) (PlanRef, error)
    CreateAccount(ctx context.Context, req CreateAccountRequest) (AccountRef, error)
    BatchCreateAccounts(ctx context.Context, req BatchCreateAccountsRequest) ([]AccountRef, error)
    TestAccount(ctx context.Context, accountID string) (ProbeResult, error)
    GetAccountModels(ctx context.Context, accountID string) ([]string, error)
    AssignSubscription(ctx context.Context, req AssignSubscriptionRequest) (SubscriptionRef, error)
    CheckGatewayAccess(ctx context.Context, req GatewayAccessCheckRequest) (GatewayAccessResult, error)
    DeleteGroup(ctx context.Context, groupID string) error
    DeleteChannel(ctx context.Context, channelID string) error
    DeletePlan(ctx context.Context, planID string) error
    DeleteAccount(ctx context.Context, accountID string) error
    ListManagedResources(ctx context.Context, req ListManagedResourcesRequest) (ManagedResourceSnapshot, error)
}

约束:

  • 所有宿主调用都必须通过该接口进入
  • 任何绕过该接口的 HTTP 调用都视为实现缺陷
  • 所有宿主 API 路径、请求体和响应体在 internal/host/sub2api/ 内部封装,不向业务层泄漏

4. 状态机

4.1 Provider 安装状态

discovered -> validated -> installed -> active
                           |            |
                           v            v
                         failed <-> degraded <-> drifted
                                      |
                                      v
                                   disabled

状态定义:

  • discovered:模型包已上传,尚未完成结构校验
  • validated:包结构、校验和、版本兼容、宿主能力探测通过
  • installedprovider 元数据和模板已写入控制面状态库
  • active:宿主资源存在,账号探测成功,至少一种用户访问模式已验证可用
  • degraded:核心资源存在但 smoke test、模型探测或访问闭环部分失败
  • drifted:宿主资源与控制面记录不一致,例如资源被人工改动或删除
  • failed:安装、导入、回滚、对账任一关键步骤失败
  • disabledprovider 被显式停用,不再调度对账任务

4.2 导入批次状态

pending -> previewed -> running -> succeeded
                         |  |         |
                         |  |         v
                         |  -> partially_succeeded
                         v
                       failed -> rollback_running -> rolled_back

4.3 访问闭环状态

  • not_configured
  • subscription_ready
  • self_service_ready
  • fully_ready
  • broken

判定规则:

  • subscription 模式可用:subscription_ready
  • self-service 模式可用:self_service_ready
  • 两者都可用:fully_ready
  • 两者都不可用:broken

5. 校验流程

5.1 宿主接入校验

请求:POST /api/hosts

流程:

  1. 校验 base_url、认证信息格式
  2. 拉取宿主版本
  3. 探测宿主管理 API 能力:
    • group 创建
    • channel 创建
    • plan 创建
    • account 创建 / 测试 / 模型列举
    • subscription 分配
  4. 生成能力矩阵并落库
  5. 若任一关键能力缺失,宿主状态标记为 unsupported

通过条件:

  • 宿主版本在 pack.json 兼容区间内
  • 所有首版硬依赖 API 均可调用

5.2 模型包装载校验

请求:POST /api/packs/install

流程:

  1. 解压上传包到临时目录
  2. 校验 pack.json 存在且字段完整
  3. 校验 providers/*.json 至少存在一个 provider
  4. 校验 checksums.txt
  5. 校验 provider schema
  6. 校验模型包声明的宿主版本兼容性
  7. 将包元数据、provider 元数据写入状态库

拒绝条件:

  • 缺少 pack.json
  • provider 文件重复或 provider_id 冲突
  • base_url 非 HTTPS
  • default_models 为空
  • smoke_test_model 不在 default_models

5.3 导入预检

请求:POST /api/providers/{provider_id}/preview-import

流程:

  1. 规范化 key 列表:去空白、去重、去 BOM、过滤空行
  2. 校验导入模式是否允许:strictpartial
  3. 生成建议资源名
  4. 检查宿主是否已有同名 group / channel / plan
  5. 检查当前 provider 是否已有历史导入资源
  6. 计算执行计划:
    • create
    • reuse
    • conflict
  7. 输出预检报告,不落宿主资源

5.4 导入执行

请求:POST /api/providers/{provider_id}/import

流程:

  1. 创建批次记录,状态 pending
  2. 执行预检,成功后切换为 previewed
  3. 创建或复用 group
  4. 创建或复用 channel
  5. 按访问模式决定是否创建或复用 plan
  6. 批量创建 accounts
  7. 对每个 account 执行:
    • 宿主 /test
    • 宿主 /models
    • 关键模型 smoke probe
  8. 若访问模式为 subscription
    • 预览待分配用户列表
    • 调用宿主分配接口
  9. 执行网关访问探测
  10. 写入资源映射、探测结果、访问闭环状态
  11. 根据模式决定成功、部分成功或回滚

5.5 回滚校验

触发条件:

  • strict 模式下任一关键步骤失败
  • 管理员主动回滚批次

流程:

  1. 读取批次关联资源
  2. 按依赖逆序删除:
    • subscriptions
    • accounts
    • channel
    • plan
    • group
  3. 删除成功后标记 rolled_back
  4. 若部分删除失败,批次状态标记 failedprovider 状态标记 drifted

5.6 对账校验

请求:POST /api/providers/{provider_id}/reconcile

流程:

  1. 读取控制面记录的宿主资源快照
  2. 拉取宿主实际资源
  3. 核对 group / channel / plan / account 是否仍存在
  4. 对 active account 重新执行 /test/models
  5. 重新执行至少一种用户访问模式探测
  6. 汇总为:
    • active
    • degraded
    • drifted
    • failed

6. API 请求与响应最小契约

6.1 POST /api/hosts

请求体:

{
  "name": "prod-sub2api",
  "base_url": "https://sub2api.example.com",
  "auth": {
    "type": "bearer",
    "token": "xxxx"
  }
}

成功响应:

{
  "host_id": "host_01",
  "version": "0.1.126",
  "status": "supported",
  "capabilities": {
    "groups": true,
    "channels": true,
    "plans": true,
    "accounts": true,
    "account_test": true,
    "account_models": true,
    "subscriptions": true
  }
}

6.2 POST /api/providers/{provider_id}/import

请求体:

{
  "host_id": "host_01",
  "mode": "partial",
  "access_mode": "subscription",
  "keys": [
    "sk-1",
    "sk-2"
  ],
  "subscription_targets": [
    {
      "user_id": "user_01",
      "duration_days": 30
    }
  ]
}

成功响应:

{
  "batch_id": "batch_01",
  "status": "succeeded",
  "provider_status": "active",
  "access_closure_status": "subscription_ready",
  "created": {
    "group_id": "g_01",
    "channel_id": "c_01",
    "plan_id": "p_01",
    "account_ids": ["a_01", "a_02"]
  }
}

7. 数据库与迁移计划

7.1 必建表

  • hosts
  • host_capability_snapshots
  • packs
  • providers
  • provider_installs
  • import_batches
  • import_batch_items
  • managed_resources
  • probe_results
  • access_closure_records
  • reconcile_runs

7.2 约束

  • providers.provider_id 在同一 pack_id 下唯一
  • managed_resourceshost_id + provider_id + resource_type + logical_key 唯一
  • import_batch_items.raw_key_hash 唯一约束只用于同一批次内去重
  • 密钥明文不落库,只存掩码、哈希和宿主侧 account ID

8. 测试策略

8.1 单元测试

  • internal/pack/validator.go
  • internal/provision/naming.go
  • internal/access/planner.go
  • internal/reconcile/drift_checker.go

8.2 宿主适配器契约测试

  • 使用 httptest.Server 模拟 sub2api 管理 API
  • 覆盖成功、鉴权失败、字段缺失、版本不兼容、接口漂移

8.3 集成测试

  • 安装模型包
  • 多 key 导入
  • strict 失败回滚
  • partial 部分成功
  • subscription 访问闭环
  • 对账发现漂移

8.4 验收测试

  • 真实连接一套测试版 sub2api
  • 导入 deepseek 两个 key
  • 为测试用户分配 subscription
  • 使用该用户实际标准 API key 发起一次 /v1/chat/completions
  • 验证请求成功进入目标 provider

9. 分阶段里程碑

Milestone 1项目骨架与状态库

验收标准:

  • 控制面可启动
  • SQLite 可自动迁移
  • POST /api/hostsGET /api/hosts 可用
  • 宿主能力探测结果可持久化

Milestone 2模型包安装与校验

验收标准:

  • 可安装 openai-cn-pack
  • 可列出 provider
  • 版本兼容和 checksum 校验有效
  • 非法 provider 包会被拒绝

Milestone 3多 key 导入与资源编排

验收标准:

  • 可对单个 provider 执行预检
  • 可批量导入多个 key
  • 可创建 group / channel / plan / account
  • strict / partial 两种模式行为正确

Milestone 4访问闭环

验收标准:

  • subscription 模式打通
  • 至少一个测试用户可通过宿主标准 API 调用目标国产模型
  • 控制面可返回 subscription_readyfully_ready

Milestone 5对账、漂移与回滚

验收标准:

  • 定时对账可运行
  • 宿主资源被人工删除时provider 状态变为 drifted
  • 可对批次执行回滚
  • 回滚后状态库与宿主资源一致

Milestone 6独立交付与部署文档

验收标准:

  • 可生成单二进制和 Docker 镜像
  • 提供 .env.example 和最小部署说明
  • 可通过 CLI 完成宿主接入、模型包装载和导入
  • 文档明确宿主零改动边界和支持矩阵

10. 逐任务实施清单

Task 1: 建立项目骨架与配置加载

Files:

  • Create: cmd/server/main.go
  • Create: cmd/cli/main.go
  • Create: internal/app/app.go
  • Create: internal/app/bootstrap.go
  • Create: internal/config/config.go

Step 1: 写配置加载单元测试

  • Test: tests/integration/config_bootstrap_test.go
  • 覆盖环境变量、默认值、缺失必填项

Step 2: 运行测试验证失败

Run: go test ./tests/integration -run TestConfigBootstrap -v Expected: FAIL提示配置加载尚未实现

Step 3: 写最小实现

  • 完成配置结构、启动参数、默认 SQLite DSN

Step 4: 运行测试验证通过

Run: go test ./tests/integration -run TestConfigBootstrap -v Expected: PASS

Step 5: Commit

git add cmd internal tests
git commit -m "feat: bootstrap control plane app skeleton"

Task 2: 建立状态库与迁移

Files:

  • Create: internal/store/migrations/0001_init.sql
  • Create: internal/store/sqlite/db.go
  • Create: internal/store/sqlite/hosts_repo.go
  • Create: internal/store/sqlite/packs_repo.go
  • Create: internal/store/sqlite/providers_repo.go

Step 1: 写迁移与仓储测试

  • Test: tests/integration/store_init_test.go
  • 覆盖建表、唯一约束、事务回滚

Step 2: 跑失败测试

Run: go test ./tests/integration -run TestStoreInit -v Expected: FAIL表不存在

Step 3: 实现最小迁移与仓储

  • 先实现 hostspacksproviders

Step 4: 跑测试

Run: go test ./tests/integration -run TestStoreInit -v Expected: PASS

Step 5: Commit

git add internal/store tests
git commit -m "feat: add state store migrations and repositories"

Task 3: 实现宿主适配器与能力探测

Files:

  • Create: internal/host/sub2api/client.go
  • Create: internal/host/sub2api/capability_probe.go
  • Create: internal/host/sub2api/groups.go
  • Create: internal/host/sub2api/channels.go
  • Create: internal/host/sub2api/plans.go
  • Create: internal/host/sub2api/accounts.go
  • Create: internal/host/sub2api/subscriptions.go

Step 1: 写 httptest 宿主桩和适配器测试

  • Test: tests/integration/host_stub_test.go
  • 覆盖版本获取、能力探测、错误映射

Step 2: 先跑失败

Run: go test ./tests/integration -run TestSub2APIHostAdapter -v Expected: FAIL适配器未实现

Step 3: 写最小适配器实现

  • 只支持首版必需 API

Step 4: 跑测试

Run: go test ./tests/integration -run TestSub2APIHostAdapter -v Expected: PASS

Step 5: Commit

git add internal/host tests
git commit -m "feat: add sub2api host adapter and capability probe"

Task 4: 实现模型包协议与安装校验

Files:

  • Create: internal/pack/manifest.go
  • Create: internal/pack/provider_manifest.go
  • Create: internal/pack/checksum.go
  • Create: internal/pack/validator.go
  • Create: internal/pack/loader.go

Step 1: 写模型包校验测试

  • Test: tests/integration/install_pack_test.go
  • 覆盖合法包、缺失字段、坏 checksum、版本不兼容

Step 2: 跑失败

Run: go test ./tests/integration -run TestInstallPack -v Expected: FAIL包解析和校验未实现

Step 3: 实现最小装载器

  • 支持从 zip 和目录读取

Step 4: 跑测试

Run: go test ./tests/integration -run TestInstallPack -v Expected: PASS

Step 5: Commit

git add internal/pack tests
git commit -m "feat: add model pack loader and validator"

Task 5: 实现导入预检与命名策略

Files:

  • Create: internal/provision/preview_service.go
  • Create: internal/provision/naming.go
  • Create: internal/domain/import_batch.go

Step 1: 写预检测试

  • Test: tests/integration/import_preview_test.go
  • 覆盖 key 规范化、冲突判定、create/reuse/conflict 输出

Step 2: 跑失败

Run: go test ./tests/integration -run TestImportPreview -v Expected: FAIL

Step 3: 实现预检逻辑

  • 只做只读分析,不写宿主

Step 4: 跑测试

Run: go test ./tests/integration -run TestImportPreview -v Expected: PASS

Step 5: Commit

git add internal/provision internal/domain tests
git commit -m "feat: add provider import preview flow"

Task 6: 实现多 key 导入、探测与回滚

Files:

  • Create: internal/provision/import_service.go
  • Create: internal/provision/rollback_service.go
  • Create: internal/store/sqlite/import_batches_repo.go
  • Create: internal/store/sqlite/resources_repo.go
  • Create: internal/store/sqlite/probe_results_repo.go

Step 1: 写导入测试

  • Test: tests/integration/import_keys_test.go
  • 覆盖 strict 成功、strict 回滚、partial 部分成功

Step 2: 跑失败

Run: go test ./tests/integration -run TestImportKeys -v Expected: FAIL

Step 3: 实现导入与回滚服务

  • 创建宿主资源
  • 记录资源映射
  • 运行账号测试和模型探测

Step 4: 跑测试

Run: go test ./tests/integration -run TestImportKeys -v Expected: PASS

Step 5: Commit

git add internal/provision internal/store tests
git commit -m "feat: add multi-key import and rollback flow"

Task 7: 实现访问闭环

Files:

  • Create: internal/access/planner.go
  • Create: internal/access/subscription_service.go
  • Create: internal/access/self_service_checker.go
  • Create: internal/domain/access_closure.go

Step 1: 写访问闭环测试

  • Test: tests/integration/access_closure_test.go
  • 覆盖 subscription_readyself_service_readybroken

Step 2: 跑失败

Run: go test ./tests/integration -run TestAccessClosure -v Expected: FAIL

Step 3: 实现最小闭环服务

  • 首版先保证 subscription 模式打通
  • self-service 只做绑定状态检查,不代用户签发 key

Step 4: 跑测试

Run: go test ./tests/integration -run TestAccessClosure -v Expected: PASS

Step 5: Commit

git add internal/access internal/domain tests
git commit -m "feat: add access closure services"

Task 8: 实现对账与漂移检测

Files:

  • Create: internal/reconcile/runner.go
  • Create: internal/reconcile/drift_checker.go
  • Create: internal/reconcile/probe_runner.go
  • Create: internal/store/sqlite/reconcile_runs_repo.go

Step 1: 写对账测试

  • Test: tests/integration/reconcile_test.go
  • 覆盖正常、资源丢失、账号失效、访问闭环破坏

Step 2: 跑失败

Run: go test ./tests/integration -run TestReconcile -v Expected: FAIL

Step 3: 实现对账器

  • 拉取宿主资源快照
  • 比对状态库
  • 重新执行探测

Step 4: 跑测试

Run: go test ./tests/integration -run TestReconcile -v Expected: PASS

Step 5: Commit

git add internal/reconcile internal/store tests
git commit -m "feat: add provider reconcile and drift detection"

Task 9: 暴露 HTTP API 与 OpenAPI 文档

Files:

  • Create: internal/api/http/router.go
  • Create: internal/api/http/middleware.go
  • Create: internal/api/http/hosts_handler.go
  • Create: internal/api/http/packs_handler.go
  • Create: internal/api/http/providers_handler.go
  • Create: internal/api/http/imports_handler.go
  • Create: internal/api/http/access_handler.go
  • Create: internal/api/http/reconcile_handler.go
  • Create: docs/api/openapi.yaml

Step 1: 写 handler 测试

  • Test: tests/integration/http_api_test.go
  • 覆盖主要成功与失败路径

Step 2: 跑失败

Run: go test ./tests/integration -run TestHTTPAPI -v Expected: FAIL

Step 3: 实现路由和 DTO

  • 保持 handler 只做参数解析和错误映射

Step 4: 跑测试

Run: go test ./tests/integration -run TestHTTPAPI -v Expected: PASS

Step 5: Commit

git add internal/api docs/api tests
git commit -m "feat: add control plane HTTP API"

Task 10: 增加调度器、CLI 和端到端验收脚本

Files:

  • Create: internal/worker/scheduler.go
  • Create: internal/worker/jobs.go
  • Modify: cmd/cli/main.go
  • Create: scripts/e2e/verify_with_host_stub.sh

Step 1: 写调度与 CLI 测试

  • Test: tests/integration/cli_scheduler_test.go
  • 覆盖手动 reconcile 和定时调度

Step 2: 跑失败

Run: go test ./tests/integration -run TestCLIScheduler -v Expected: FAIL

Step 3: 实现最小调度与 CLI

  • 支持 host addpack installprovider importreconcile run

Step 4: 跑全量测试

Run: go test ./... Expected: PASS

Step 5: Commit

git add cmd internal scripts tests
git commit -m "feat: add scheduler cli and e2e verification script"

Task 11: 补齐独立交付物与部署文档

Files:

  • Create: Dockerfile
  • Create: .env.example
  • Create: deploy/docker-compose.yml
  • Create: docs/deployment.md
  • Modify: README.md

Step 1: 写交付物检查测试

  • Test: tests/integration/distribution_smoke_test.go
  • 覆盖配置样例、镜像启动参数、CLI 帮助输出

Step 2: 跑失败

Run: go test ./tests/integration -run TestDistributionSmoke -v Expected: FAIL

Step 3: 实现最小交付物

  • 提供可运行镜像
  • 提供本地 SQLite 默认部署
  • 文档明确对接宿主所需环境变量

Step 4: 跑测试

Run: go test ./tests/integration -run TestDistributionSmoke -v Expected: PASS

Step 5: Commit

git add Dockerfile .env.example deploy docs README.md tests
git commit -m "docs: add distribution artifacts and deployment guide"

11. 最终验收清单

  • 从空状态启动控制面
  • 连接一套兼容版本的 sub2api
  • 安装 openai-cn-pack
  • 导入 deepseek 两个 key
  • 成功创建宿主资源并记录映射
  • 至少一个账号通过测试与模型探测
  • 至少一种用户访问模式验证成功
  • 使用宿主标准 API 成功调用国产模型
  • 人工删除一个宿主 account 后,对账将 provider 状态标记为 drifted
  • 执行批次回滚后,宿主残留资源清理完成

12. 风险与收敛策略

  • 宿主管理 API 漂移风险:所有 HTTP 路径和字段通过 HostAdapter 封装,并为版本差异保留适配层
  • 宿主权限模型不稳定:在 POST /api/hosts 阶段强制能力探测,不满足即拒绝接入
  • 不同 provider 规则差异:统一约束到 providers/*.json,首版只支持 OpenAI-compatible provider
  • 访问闭环误判:首版必须落真实标准 API 探测,不能只以资源存在判定成功