Skip to content

multi2api v1.9.19

Choose a tag to compare

@Practice019 Practice019 released this 21 Oct 12:45
· 76 commits to master since this release

v1.9.19

修一个配好了却拿不到的问题:API key 里给模型配了对外名,/v1/models 却不返回那个名字。


现象

key 里配了 8 个模型、8 条对外名,其中包括

workbuddy/deepseek-v4.1-flash   →   006/deepseek-v4.1-flash

但客户端拿到的模型列表里没有 006/…,只回了 7 条 —— 配置在库里是对的(allow 与 model_map 都在),
是列表组装把它吃掉了。

根因:同一个 id 被改名两遍

/v1/models 的组装是:

filterModelsForRequest  →  appendChannelModels  →  applyPublicNames
      ↑ 已经改成对外名                                    ↑ 又改一遍

第一遍把 workbuddy/… 换成 006/…,第三遍拿着 006/… 再查映射表:

  • 精确匹配不命中 —— 映射表里 006/… 是键(对外名),不是值(内部名)
  • 于是掉进裸名兜底:006/deepseek-v4.1-flash 的裸名是 deepseek-v4.1-flash,
    而 004 / 005 / 006 三个对外名的内部名裸名完全相同 ⇒ 按 map 遍历顺序随机挑一个
  • 006 被改成了 004(或 005),随后 seen[pub] 去重把整条丢掉

所以配了三条同裸名的对外名,列表只剩两条,而且挂着别人的名字。

修法

publicNameFor 两条:

  1. 幂等:传进来的 name 本身就是映射表的键(某个对外名)⇒ 原样返回,不再改名
  2. 裸名兜底只在唯一命中时使用:多个别名共享同一裸名时不猜(返回原值)——
    否则同一个 key 两次请求可能看到不同的名字

判据

  • internal/server/apikey_publicname_test.go(新增 4 条):改前有 3 条红,红的内容与用户现象逐字一致
    (实际只回 004/…、005/…);修后全绿,含幂等、内部名→自己的对外名、裸名多命中不猜、
    以及 filter → applyPublicNames 两遍之后三条一条不少
  • tests/frontend/verify_key_alias_models.js(新增,真机 11 条):起隔离实例 → 建 key(3 个同裸名内部模型 +
    3 个对外名)→ 建渠道声明这 3 个模型 → 用 key 请求 /v1/models ⇒ 恰好 004/005/006 三条;
    再用 006/… 调 /v1/chat/completions ⇒ 不是 403(上游 502,说明权限链路是通的)
  • go test ./internal/server/... 全绿

升级提示

这次改的是服务端列表组装,必须重启进程才生效(页面走 go:embed,重启后 Ctrl+F5)。
已有的 key 与映射不用重配。