mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-12 20:27:23 +00:00
fix(gateway): AUTO 范围冲突的提示要放在 checkQuota,否则是死代码
上一版把消息加在请求路径的范围检查上,实测才发现它永远走不到: AUTO 请求先经过 checkQuota(ctx, "AUTO")(在链被读取之前),范围不含 AUTO 时它当场返回旧文案「model \"AUTO\" is not allowed for this key」——那句会 把运维引去查配额,而配额并不是原因。 改为在 checkQuota 内对 AUTO 分流,输出说明真实原因与修法。请求路径那处 换成注释说明为何不再重复。 判据 1 条,断言 checkQuota 函数体内必须同时出现 isAuto(model) 与新文案 ——放在别处不算数。变异(删掉该分支)导致编译失败,被捕获。 生产实测(临时把某密钥范围改成不含 AUTO 再恢复): HTTP 403 model_not_allowed model \"AUTO\" is not in this key's model scope, so it cannot use AUTO; add \"AUTO\" to the key's models or remove the scope restriction Co-Authored-By: ModelRouter <noreply@modelrouter.dev>
This commit is contained in:
@ -256,7 +256,17 @@ func (g *Gateway) checkQuota(ctx context.Context, model string) *quotaRejection
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return "aRejection{msg: fmt.Sprintf("model %q is not allowed for this key", model)}
|
||||
// A scope that simply does not list the model is a different problem from
|
||||
// a quota being exhausted, and the message has to say which: telling an
|
||||
// operator "not allowed for this key" when they configured a quota sends
|
||||
// them to the wrong setting. AUTO is checked here before the chain is even
|
||||
// consulted, so this is the message that surfaces for AUTO.
|
||||
if isAuto(model) {
|
||||
return "aRejection{msg: fmt.Sprintf(
|
||||
"model %q is not in this key's model scope, so it cannot use AUTO; "+
|
||||
"add %q to the key's models or remove the scope restriction", model, model)}
|
||||
}
|
||||
return "aRejection{msg: fmt.Sprintf("model %q is not allowed for this key", model)}
|
||||
}
|
||||
|
||||
// quotaWindowSuffix describes a quota's reset window for an error message, so
|
||||
@ -452,19 +462,11 @@ func (g *Gateway) handleChat(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
}
|
||||
// A key whose model scope does not include AUTO cannot use AUTO at all,
|
||||
// even when it has its own AUTO chain configured. That combination is
|
||||
// easy to set up by accident and produced a misleading error: the request
|
||||
// fell through to the generic "model %q is not configured" below, which
|
||||
// claims AUTO does not exist — it does, this key just may not use it. Name
|
||||
// the actual reason so the admin can fix the scope.
|
||||
if isAuto(model) {
|
||||
if allow := g.allowedModels(r.Context()); allow != nil && !g.hasScopeModel(allow, model) {
|
||||
writeError(w, http.StatusForbidden, "model_not_allowed",
|
||||
fmt.Sprintf("model %q is not in this key's model scope, so it cannot use AUTO; add %q to the key's models or remove the scope restriction", model, model))
|
||||
return
|
||||
}
|
||||
}
|
||||
// Note: a key whose scope excludes AUTO is rejected earlier, by
|
||||
// checkQuota(ctx, "AUTO") above, which produces the same message. That
|
||||
// ordering matters — checkQuota runs before the chain is consulted, so it
|
||||
// is the check an AUTO request actually hits. Duplicating it here would be
|
||||
// dead code.
|
||||
cands, effective := g.resolveCands(r.Context(), &req)
|
||||
if len(cands) == 0 {
|
||||
writeError(w, http.StatusNotFound, "model_not_found", fmt.Sprintf("model %q is not configured", model))
|
||||
|
||||
Reference in New Issue
Block a user