Skip to content

fix(model): 国际版槽位旁路模型不被订阅专享闸门误挡 - #6

Open
swysgh wants to merge 1 commit into
misakano7545:mainfrom
swysgh:fix/intl-slot-paid-gate
Open

swysgh wants to merge 1 commit into
misakano7545:mainfrom
swysgh:fix/intl-slot-paid-gate

Conversation

@swysgh

@swysgh swysgh commented Oct 24, 2026

Copy link
Copy Markdown

现象

升级到 db9e30a 之后,国际版唯一能出正文的两个模型(gpt-6-sol / gpt-6-luna,走租户槽位旁路)被 052df84 的订阅专享闸门一起挡成 403。

同一台机、同一批 Free 国际号,只换二进制:

版本 intl:gpt-6-sol
ff67785(052df84 之前) 200 / 2.9s,有正文
db9e30a 403 model_requires_subscription

对应日志:

拒绝订阅专享模型 gpt-6-sol:intl 地区没有订阅档账号(Free 号调它必 1005,不罚号)

intl:gpt-6-luna 表现相同。等于新版把国际版唯一能用的两个模型砍掉了。

根因

internal/server/handler.go 的闸门按目录判:

if h.modelPaidOnly(realm, configName) && !h.realmHasPaidAccount(realm) {
    ... 403
}

paidOnlyByModel 来自上游目录的 identity_list,而 identity_list 描述的是「直调该模型名」这条路的身份。gpt-6-sol / gpt-6-luna 在 Free 号上并不直调,走的是 intlSlotRoutes → 租户槽位 custom_model_gpt-5 里的 openai/gpt-5.6-sol|luna(见 internal/upstream/constants.go 里那段实测记录)。闸门在 setSlotInBody 之前判,于是把槽位那条路一起挡掉了。

计划是按模型给的,槽位旁路又是一条实测可用的 Free 通道,这两件事目录里的 identity_list 都表达不了。

修法

放行条件收紧到「命中 IntlSlotRoute 且 realm == intl」:

_, slotRouted := upstream.IntlSlotRoute(configName)
if h.modelPaidOnly(realm, configName) && !h.realmHasPaidAccount(realm) && !(slotRouted && realm == auth.RealmIntl) {

其余订阅专享模型(cn:kimi-k3.1-pro-max、intl:gpt-6.1-sol 等)照旧 403,仍是一次上游都不打、不罚号、不冷却整号。

验证

新增 TestPaidOnlySlotRoutedIntlModelNotGated:

  • 纯 db9e30a 上 FAIL:intl:gpt-6-sol code=403 ... 槽位旁路模型不该被 403 挡
  • 打上本补丁后 PASS:200,且上游聊天请求正好 1 次(确实走上游,不是空放行)
  • go vet ./... + go test ./... 全绿

线上实测(4 个 Free intl 号 + 2 个 cn 号):

  • intl:gpt-6-sol → 200 / 4.7s;intl:gpt-6-luna → 200 / 3.4s
  • cn:kimi-k3.1-pro-max → 仍 403,state.json 里 6 个号 until 全为 0001-01-01(无冷却)
  • 403 之后紧接着 cn:glm-5.3-flash → 200,号池未受影响

备选方案

如果更希望闸门只认「直调」,也可以在 fetchDynamicModels 里把命中 intlSlotRoutes 的模型排除出 paidOnlyByModel。我选在请求入口加例外,是为了不影响目录缓存的语义:paid_only 仍然如实反映直调身份,/v1/models 的输出不变。

052df84 的入口闸门按目录 identity_list 判「订阅专享 + 本地区全是 Free → 403」,
但 identity_list 描述的是「直调该模型名」那条路。gpt-6-sol / gpt-6-luna 在 Free 号上
走的是租户槽位 custom_model_gpt-5(槽位里挂 openai/gpt-5.6-sol|luna),实测能出正文;
闸门在 setSlotInBody 之前判,把它们一起 403 挡掉了。

实测(同一台机、同一批 intl 号,只换二进制):
  升级前(ff67785):intl:gpt-6-sol → 200 / 2.9s
  升级后(db9e30a):intl:gpt-6-sol → 403 model_requires_subscription
  日志:拒绝订阅专享模型 gpt-6-sol:intl 地区没有订阅档账号(Free 号调它必 1005,不罚号)
即:新版把国际版唯一能出正文的两个模型砍掉了。

放行条件收紧到「命中 IntlSlotRoute 且 realm=intl」,其余订阅专享模型照旧 403、照旧
不烧请求不罚号。补 TestPaidOnlySlotRoutedIntlModelNotGated 守住这条:
在纯 db9e30a 上该测试 FAIL(403),加上本补丁后 PASS(走上游 1 次)。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant