feat(routing): add canonical shadow provider pack

This commit is contained in:
phamnazage-jpg
2026-05-29 12:29:05 +08:00
parent b88aac7f79
commit 3c061f3ddb
8 changed files with 173 additions and 0 deletions

View File

@@ -108,6 +108,14 @@
- 前端只看到一个逻辑分组
- 插件层先做 route 级 sticky再把请求稳定转发到某个宿主 shadow group
- 宿主继续只做单线路 group 内的 account sticky / 调度
- 2026-05-29 已基于上述结论新增 canonical shadow pack
- `packs/openai-cn-pack-shadow-asxs/`
- provider`gpt-asxs-shadow-lab`
- 当前约束是:
- 一个 route 对应一个独立宿主 shadow group
- 宿主 shadow group 只承载 canonical upstream model`gpt-5.4``gpt-5.4-mini`
- alias/public model 的抽象只保留在插件 `logical_group -> route -> shadow_model` 层,不再下沉到宿主 channel
- 设计与验收路径已单独沉淀到 `docs/SHADOW_PROVIDER_VALIDATION.md`
- 2026-05-28 已新增插件整体需求盘点 `docs/PLUGIN_REQUIREMENTS_OVERVIEW_2026-05-28.md`
- 已把“增加模型、维护逻辑分组、智能路由、供应商帐号导入与停启用、普通用户前端”五大功能域统一收口
- 并明确区分 `已完成 / 待优化 / 待完成 / 未来规划`

View File

@@ -1,5 +1,8 @@
# Route Lab Validation
> 该文档现在只保留“同 group 多 channel + alias 下沉”失败实验的历史记录。
> 针对插件前置路由架构的当前正确方向,请改看 [docs/SHADOW_PROVIDER_VALIDATION.md](/home/long/project/sub2api-cn-relay-manager/docs/SHADOW_PROVIDER_VALIDATION.md)。
本文件记录 `asxs + codex2api` 同组双线路实验的最小验证路径。
## 目标

View File

@@ -0,0 +1,70 @@
# Shadow Provider Validation
本文件记录插件前置路由架构下,`shadow provider` 的最小正确验证路径。
## 目标
验证以下结论是否成立:
1. 插件层可以继续维护 `logical_group/public_model`
2. 宿主层的 `shadow group` 只承载 canonical upstream model
3. 真实 managed key 能通过宿主 `/v1/models``/v1/chat/completions`
4. 旧的 alias/public model 不再下沉到 stock host 的 `channel_mapped + restrict_models` 组合
## 设计结论
旧的 `route-lab` 已证明两件事:
1. 当前宿主不支持“多个 channel 复用同一个 group”
2.`weishaw/sub2api:0.1.129` 上,把 alias 继续下沉到宿主 shadow group会触发 `channel pricing restriction`
因此新的 shadow provider 约束是:
```text
plugin logical group
-> route
-> shadow group (host)
-> canonical models only
```
## 当前实验 pack
- pack 目录:`packs/openai-cn-pack-shadow-asxs`
- provider`gpt-asxs-shadow-lab`
## 实验建模
```text
Shadow Group: GPT ASXS Shadow 实验
Channel: GPT ASXS Shadow
Models:
- gpt-5.4
- gpt-5.4-mini
```
关键点:
- shadow group 不再暴露 `gpt-5.4-asxs`
- 插件 route 层如果需要 alias必须在 `logical_group_route_models.shadow_model` 之外处理
- stock host 只看到 canonical 模型
## 建议验证顺序
1. 导入 `gpt-asxs-shadow-lab`
2. 记录 `group_id / channel_id / account_id`
3. 用宿主订阅 key 直接验证:
- `GET /v1/models`
- `POST /v1/chat/completions`
4. 再用插件管理面创建临时 `logical_group / route`
5.`POST /api/routing/proxy/chat/completions`
6. 核对:
- `effective_gateway_key_source=managed_subscription`
- `forward.upstream_status=200`
- `route_decision_logs` 已写回同一 `request_id`
## 成功标准
- managed key `/v1/models` 返回 canonical model
- managed key `/v1/chat/completions` 返回 `200`
- 插件 `route proxy` 走真实 shadow group 时返回 `200`
- 不再出现 `channel pricing restriction`

View File

@@ -49,6 +49,26 @@ func TestLoadPathIncludesFirstBatchOfficialProviders(t *testing.T) {
}
}
func TestLoadPathSupportsShadowASXSPack(t *testing.T) {
loaded, err := LoadPath(filepath.Join("..", "..", "packs", "openai-cn-pack-shadow-asxs"))
if err != nil {
t.Fatalf("LoadPath(shadow-asxs-pack) error = %v", err)
}
if loaded.Manifest.PackID != "openai-cn-pack-shadow-asxs" {
t.Fatalf("PackID = %q, want %q", loaded.Manifest.PackID, "openai-cn-pack-shadow-asxs")
}
if len(loaded.Providers) != 1 {
t.Fatalf("Providers len = %d, want 1", len(loaded.Providers))
}
provider := loaded.Providers[0]
if provider.ProviderID != "gpt-asxs-shadow-lab" {
t.Fatalf("ProviderID = %q, want %q", provider.ProviderID, "gpt-asxs-shadow-lab")
}
if len(provider.DefaultModels) != 2 || provider.DefaultModels[0] != "gpt-5.4" {
t.Fatalf("DefaultModels = %v, want canonical gpt-5.4 models", provider.DefaultModels)
}
}
func TestLoadPathSupportsZipArchive(t *testing.T) {
tempDir := t.TempDir()
archivePath := filepath.Join(tempDir, "openai-cn-pack.zip")

View File

@@ -0,0 +1,29 @@
# openai-cn-pack-shadow-asxs
这是一个面向插件前置路由架构的 **shadow provider** 实验 pack。
它与旧的 `openai-cn-pack-route-lab` 有两个关键差异:
- 不再尝试让多个 route 复用同一个宿主 group
- 不再把 route alias 下沉到宿主 shadow group
当前 pack 只包含一条 canonical shadow provider
- `gpt-asxs-shadow-lab`
它的设计约束是:
- 一个 route 对应一个独立的宿主 shadow group
- 宿主 shadow group 只承载 canonical upstream model
- 插件层负责 `logical_group/public_model -> route -> shadow_model` 映射
- 宿主层只负责该 shadow group 内的账号调度与 managed key 验证
当前期望模型:
- `gpt-5.4`
- `gpt-5.4-mini`
注意:
- `public model alias` 的抽象要保留在插件 `logical_group` 层,不要再写进宿主 shadow provider
- 后续如果要增加 `codex2api` shadow route应新增独立 shadow provider / shadow group而不是与 `asxs` 共用同一个宿主 group

View File

@@ -0,0 +1,2 @@
ea12d19da5281c593b3710b9ea9e9fd3ebd3e092ad0f738b4a2e87e65a0f8fc7 pack.json
b2f1765709a4aefc9d5d77896fb6f00ce5e11fe70cc8a80c5d09eb0135ce9dfb providers/gpt-asxs-shadow-lab.json

View File

@@ -0,0 +1,10 @@
{
"pack_id": "openai-cn-pack-shadow-asxs",
"version": "0.1.0",
"vendor": "YourTeam",
"target_host": "sub2api",
"min_host_version": "0.1.126",
"max_host_version": "0.2.x",
"providers_dir": "providers",
"checksum_file": "checksums.txt"
}

View File

@@ -0,0 +1,31 @@
{
"provider_id": "gpt-asxs-shadow-lab",
"display_name": "GPT asxs shadow 实验",
"base_url": "https://api.asxs.top/v1",
"platform": "openai",
"account_type": "apikey",
"default_models": ["gpt-5.4", "gpt-5.4-mini"],
"smoke_test_model": "gpt-5.4",
"group_template": {
"name": "GPT ASXS Shadow 实验",
"rate_multiplier": 1.0
},
"channel_template": {
"name": "GPT ASXS Shadow",
"model_mapping": {
"gpt-5.4": "gpt-5.4",
"gpt-5.4-mini": "gpt-5.4-mini"
}
},
"plan_template": {
"name": "GPT ASXS Shadow 实验套餐",
"price": 19.9,
"validity_days": 30,
"validity_unit": "day"
},
"import": {
"supports_multi_key": true,
"supports_strict": true,
"supports_partial": true
}
}