Skip to content

feat: 接入 JieKou.AI 并按 manifest 顺序排列内置模型服务 - #178

Merged
yujiezhang-ops merged 3 commits into
mainfrom
feat/jiekou-provider
Aug 13, 2026
Merged

feat: 接入 JieKou.AI 并按 manifest 顺序排列内置模型服务#178
yujiezhang-ops merged 3 commits into
mainfrom
feat/jiekou-provider

Conversation

@yujiezhang-ops

@yujiezhang-ops yujiezhang-ops commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

变更内容

新增 JieKou.AI 作为内置模型服务,使用其国内直连端点;内置排序改为 JieKou.AI → PPIO → Novita → DeepSeek → Moonshot

端点来源

均取自 JieKou.AI 官方文档 与站内公告的国内直连地址:

OpenAI 兼容 https://api.highwayapi.ai/openai
Anthropic 兼容 https://api.highwayapi.ai/anthropic
Key 管理页 https://jiekou.vip/settings/key-management
默认模型 claude-sonnet-5
探测模型 claude-haiku-4-5-20251001(在售条目中最便宜)

需要留意:API 域名 highwayapi.ai 与控制台域名 jiekou.vip 都不等于品牌域名 jiekou.ai。这是官方文档本身的写法,不是笔误。URL 拼接路径与 PPIO / Novita 同构,OpenAIBaseURLAnthropicMessagesURL 无需改动。

排序为什么要改代码

原先内置服务的排序兜底到 name,列表实际渲染为 DeepSeek、Moonshot、Novita、PPIO —— 字母序被呈现成推荐序,并且它还决定了某个协议第一个匹配到哪家服务。

providers.lock.json 里本就有 order 字段,但只供未入库的站点 explorer 使用,Go 侧刻意不解析。本次让它像 Agent.Rank 一样前后端共用:Go 解析并校验为正数,前端按它排序。校验要求为正,是因为 0 会让「漏填 order」的新服务排到队首而不是队尾 —— 这恰好是评审时最难发现、用户最容易看到的失败方式。

站点专用字段的断言收窄到 relationshipdisclosurereferral_urlprotocols 四项,它们仍然不被解析:这些是编辑性内容,不该出现在用户挑选端点的界面上。order 是展示位次,不属于这一类。

展示顺序与预选服务的解耦(第二个提交)

第一版把两件不同的事挤进了同一个比较器,CI 的 E2E 因此挂掉两条。记录在此,因为它同时纠正了我对既有代码的一处误判。

Store.Public() 会给任何存有 API Key 的服务盖上 created_at。原比较器对内置服务按 created_at 降序,实际效果是把用户已配好 Key 的服务顶到最前,向导和 Profile 编辑器因此预选到它。我起初把这段读成纯粹的排序 bug 并删除了它 —— 但它在承担真实职责,只是透过一个读起来像「最新」的代理来实现。

改按 order 排序对展示是正确的,却顺带移除了那个副作用。后果是向导恒定预选 order=1 的 JieKou.AI,而新机器上它没有 Key,于是:

  • 向导的「测试连接」按钮恒为 disabled,该步骤无法继续(canProbe = providerHasKey
  • Profile 编辑器的模型发现跑不起来,列表为空

真实用户会踩:配好 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 ./... 通过
  • 前端 47 个测试文件 / 371 个测试通过,tsc --noEmitvite build 通过
  • Playwright E2E 6 条全部通过(本地复现了 CI 的两条失败并修复)
  • 新增覆盖:order 会被解析、非正数被拒、内置 order 唯一且为正、内置按 order 而非按名称排序、优先预选持有 Key 的服务、无 Key 时回落到 manifest 首位、无候选时返回空

两点说明

  • internal/catalog/types.go 含 4 行 gofmt 对齐改动,是改名提交遗留的既有欠债(BootAgentVersion 比原字段名长)。gofmt 只能按整文件处理,而我已经在改这个文件,留着未格式化更差。
  • bindings 只手改了 Provider 这一个 interface。本机 wails3 为 beta.4,仓库 pinned 为 beta.7,用旧版生成器重跑会让整棵 bindings 树产生无关 diff。下次在 pinned 工具链上执行 task generate:bindings 时,结果应与手改一致。
  • ai-agent-kit/ 下那套教程以 PPIO 账号为主线,属独立范围,本次未动。

🤖 Generated with Claude Code

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>
@yujiezhang-ops
yujiezhang-ops requested a review from a team August 13, 2026 09:49
yujiezhang-ops and others added 2 commits August 13, 2026 18:03
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>
@yujiezhang-ops
yujiezhang-ops merged commit afac1b7 into main Aug 13, 2026
4 checks passed
@yujiezhang-ops
yujiezhang-ops deleted the feat/jiekou-provider branch August 13, 2026 11:10
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