feat: 接入 JieKou.AI 并按 manifest 顺序排列内置模型服务 - #178
Merged
Conversation
JieKou.AI ships as a built-in Provider using its China-direct endpoints, and the built-in list now reads JieKou.AI, PPIO, Novita, DeepSeek, Moonshot. Ordering previously fell through to `name`, so the list rendered DeepSeek, Moonshot, Novita, PPIO -- alphabetical order presented as a recommendation, which also decided which Provider a protocol matched first. `order` already existed in providers.lock.json for the site explorer; parsing it here makes one manifest answer the ordering question, the way Agent.Rank already does. It is validated positive because zero would sort an omitted value to the head of the list rather than the tail. Also fixes an ordering bug this exposed: Store.Public stamps created_at onto any Provider holding a saved key, built-in ones included, so comparing created_at before order let saving a key reorder the built-in list -- and only on machines where someone had done so. created_at is now consulted for custom Providers only. The site-only field assertion narrows to relationship, disclosure, referral_url and protocols, which stay unparsed: those are editorial, and `order` is not. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ordering built-in Providers by the manifest silently took Provider pre-selection with it, breaking both E2E journeys: the wizard's connection test and the Profile editor's model discovery are gated on `has_key`, so landing on a keyless Provider left a disabled button and an empty model list with no way forward. Pre-selection had been riding on byProviderCreatedAt's created_at comparison. Store.Public stamps created_at onto any Provider holding a key, so sorting built-ins by it descending floated the configured one to the top -- the right outcome reached through a proxy that read as "newest". Ordering by the manifest is correct for display and removed that side effect. preferProviderWithKey now states the rule where the four pre-selection sites can share it, leaving byProviderCreatedAt to answer display order only. The list views keep pure display order. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
变更内容
新增 JieKou.AI 作为内置模型服务,使用其国内直连端点;内置排序改为 JieKou.AI → PPIO → Novita → DeepSeek → Moonshot。
端点来源
均取自 JieKou.AI 官方文档 与站内公告的国内直连地址:
https://api.highwayapi.ai/openaihttps://api.highwayapi.ai/anthropichttps://jiekou.vip/settings/key-managementclaude-sonnet-5claude-haiku-4-5-20251001(在售条目中最便宜)需要留意:API 域名
highwayapi.ai与控制台域名jiekou.vip都不等于品牌域名jiekou.ai。这是官方文档本身的写法,不是笔误。URL 拼接路径与 PPIO / Novita 同构,OpenAIBaseURL与AnthropicMessagesURL无需改动。排序为什么要改代码
原先内置服务的排序兜底到
name,列表实际渲染为 DeepSeek、Moonshot、Novita、PPIO —— 字母序被呈现成推荐序,并且它还决定了某个协议第一个匹配到哪家服务。providers.lock.json里本就有order字段,但只供未入库的站点 explorer 使用,Go 侧刻意不解析。本次让它像Agent.Rank一样前后端共用:Go 解析并校验为正数,前端按它排序。校验要求为正,是因为 0 会让「漏填 order」的新服务排到队首而不是队尾 —— 这恰好是评审时最难发现、用户最容易看到的失败方式。站点专用字段的断言收窄到
relationship、disclosure、referral_url、protocols四项,它们仍然不被解析:这些是编辑性内容,不该出现在用户挑选端点的界面上。order是展示位次,不属于这一类。展示顺序与预选服务的解耦(第二个提交)
第一版把两件不同的事挤进了同一个比较器,CI 的 E2E 因此挂掉两条。记录在此,因为它同时纠正了我对既有代码的一处误判。
Store.Public()会给任何存有 API Key 的服务盖上created_at。原比较器对内置服务按created_at降序,实际效果是把用户已配好 Key 的服务顶到最前,向导和 Profile 编辑器因此预选到它。我起初把这段读成纯粹的排序 bug 并删除了它 —— 但它在承担真实职责,只是透过一个读起来像「最新」的代理来实现。改按
order排序对展示是正确的,却顺带移除了那个副作用。后果是向导恒定预选 order=1 的 JieKou.AI,而新机器上它没有 Key,于是:canProbe = providerHasKey)真实用户会踩:配好 PPIO 后进引导流程,卡在连不通的那一步。
修法是把两个关注点分开,而不是回退排序:
byProviderCreatedAt只回答展示顺序,新增的preferProviderWithKey只回答「该落在哪个服务上」,并显式要求has_key。四处预选点共用它(向导、Profile 编辑器的新建与协议切换、Agent Profile 页),三处展示列表(模型服务页、迁移页、ProviderSegment)保持纯展示序。这比原先的隐式行为更清晰:意图写在代码里,而不是依赖created_at恰好只在存了 Key 时出现。ranking.test.ts补了三条单测覆盖这个行为,下次这类回归会在单测层就暴露,不必等 E2E。顺带修复
README 中「内置 PPIO 和 Novita」一句在 DeepSeek、Moonshot 加入时就未同步,已改为与 manifest 一致。
测试
go vet ./...、go test ./...通过tsc --noEmit与vite build通过order会被解析、非正数被拒、内置 order 唯一且为正、内置按 order 而非按名称排序、优先预选持有 Key 的服务、无 Key 时回落到 manifest 首位、无候选时返回空两点说明
internal/catalog/types.go含 4 行 gofmt 对齐改动,是改名提交遗留的既有欠债(BootAgentVersion比原字段名长)。gofmt 只能按整文件处理,而我已经在改这个文件,留着未格式化更差。Provider这一个 interface。本机wails3为 beta.4,仓库 pinned 为 beta.7,用旧版生成器重跑会让整棵 bindings 树产生无关 diff。下次在 pinned 工具链上执行task generate:bindings时,结果应与手改一致。ai-agent-kit/下那套教程以 PPIO 账号为主线,属独立范围,本次未动。🤖 Generated with Claude Code