fix(llm-pi-ai): 目录路由的模型发现改为合并线上清单 - #309
Open
FudanSE-Nick wants to merge 1 commit into
Open
Conversation
「获取可用模型」对 pi-ai 内置目录路由(如 OpenCode Go)永远不发网络请求, 只回放打包时的静态快照,因此订阅网关在 pi-ai 两次发版之间新增的模型永远 无法出现——而这正是用户点这个按钮的目的。实测 opencode-go 快照为 23 个模型 (pi-ai 0.84.3,生成于 2026-08-24),而 https://opencode.ai/zen/go/v1/models 实时返回 35 个,缺 glm-5.3-flash、grok-4.6、omen-alpha、qwen3.8-flash 等 13 个,同时还保留了线上已下架的 ox-alpha-free。 即便手动把新模型写进 settings.yaml 也无法使用:resolveRouteModels 依赖 sharedCatalogApi 的「全体一致」判断来为快照外的模型补 api,而 opencode-go 横跨三种协议,该判断返回 undefined,于是整条路由解析失败并报 「model "…" needs an api」。唯一的出路是设置路由级 api,但它会覆盖所有同级 模型,反而弄坏另外两种协议的模型。 两层一起修: - 目录路由现在同时读取快照与自身端点,二者合并。快照携带清单不披露的容量, 因此在两边都描述某模型时快照优先;端点顺序决定新模型的位置。端点不可达、 凭据被拒、协议无可读清单时仍回落到快照——离线可用是这个动作原有的能力。 调用方主动取消(ABORTED)不会被回落成陈旧列表。 - sharedCatalogApi 换成 catalogEndpoint,按「多数」而非「全体一致」得出协议 及其配套 baseUrl。多数协议下的新模型因此能自动继承端点,而少数协议的同级 模型仍各自保留自己的 api/baseUrl,不会被拖到多数协议上。 按多数推断有猜错的可能,但备选是路由无法添加任何新模型,除非设路由级 api 弄坏同级模型;猜错的代价是该模型首次使用时被端点明确拒绝、有名有姓、可恢复。 草稿值、路由级 api/baseURL、以及目录未描述的自定义路由行为均保持不变。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
设置页「获取可用模型」对 pi-ai 内置目录路由(如 OpenCode Go)永远不发网络请求,只回放打包时烤死的静态快照。订阅网关在 pi-ai 两次发版之间新增的模型因此永远无法出现 —— 而这正是用户点这个按钮的目的。
实测对比(本机 pi-ai 0.84.3,快照生成于 2026-08-24):
https://opencode.ai/zen/go/v1/models实时缺
glm-5.3-flash、grok-4.6、omen-alpha、qwen3.8-flash、muse-spark-1.3-contributor等 13 个,同时还保留着线上已下架的ox-alpha-free。升级 pi-ai 治不了根:0.84.4 是 25 个、0.85.0 是 27 个,仍落后线上。静态快照跟 npm 发版走,而网关随时上新,结构上追不上。
第二层问题更隐蔽:即便用户手动把新模型写进
settings.yaml也用不了。resolveRouteModels依赖sharedCatalogApi的「全体一致」判断为快照外模型补api,而 opencode-go 横跨三种协议(Completions 19 / Responses 3 / Anthropic Messages 1),该判断返回undefined,整条路由解析失败:唯一出路是设路由级
api,但它覆盖所有同级模型,反而弄坏另外两种协议的。改动
两层一起修,均在
patches/@deepseek-ai+dsh-llm-pi-ai+0.1.2-rc.1.patch(沿用仓库既有的 patch-package 约定,与原有的 401/403 分类 hunk 合并在同一文件)。发现(
discoverModels):目录路由现在同时读快照与自身端点并合并。快照携带清单不披露的容量,因此两边都描述某模型时快照优先;端点顺序决定新模型的位置。端点不可达、凭据被拒、协议无可读清单时仍回落到快照 —— 离线可用是这个动作原有的能力。调用方主动取消(ABORTED)不会被回落成陈旧列表。解析(
resolveRouteModels):sharedCatalogApi换成catalogEndpoint,按多数而非全体一致得出协议及其配套baseUrl。多数协议下的新模型自动继承端点;少数协议的同级模型仍各自保留自己的api/baseUrl。一处需要评审关注的取舍
按多数推断协议有猜错的可能。但备选方案是「路由无法添加任何新模型,除非设路由级
api弄坏同级模型」。猜错的代价是该模型首次使用时被端点明确拒绝、有名有姓、可恢复;两害相权取其轻。如果维护者倾向别的方案(例如给models条目增加 per-modelapi字段),我乐意改。草稿值、路由级
api/baseURL、以及目录未描述的自定义路由行为均保持不变。测试
修改前先在未改动的源码上验证 bug 真实存在(发现返回 5 个 / 0 次网络调用 / 0 个线上新模型;解析抛
needs an api),确认修复后行为反转。新增
test/model-discovery-catalog-patch.test.ts(4 项,已精简至只覆盖核心行为与上述取舍的护栏):验证结果:
npx vitest run→ 85 文件 / 704 项全通过npx tsc --noEmit -p tsconfig.node.json→ 通过npx patch-package→ 20 个补丁全部干净应用catalogEndpoint/listEndpointModels就位、sharedCatalogApi已移除备注
未改动
package.json的overrides。package-lock.json把 pi-ai 锁在 0.84.4,钉版本只能把差距从 13 个缩到 8 个,本 PR 之后版本落差已不再影响此功能。与 #284(0.7.1 后点击无反应)不是同一问题,未做关联。