Skip to content

✨ feat: add stable multi-model provider targets - #45

Merged
CodFrm merged 30 commits into
mainfrom
feat/2026-08-11-llm-provider-models
Aug 13, 2026
Merged

✨ feat: add stable multi-model provider targets#45
CodFrm merged 30 commits into
mainfrom
feat/2026-08-11-llm-provider-models

Conversation

@CodFrm

@CodFrm CodFrm commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

变更说明 / Summary

  • 将 LLM Provider 从单模型升级为带稳定 ModelKey 的多模型目录,支持发现、手工导入、默认模型、引用保护与原子删除/导入
  • 为 Backend、Claude Routes、新建会话和已有会话统一引入结构化 ModelTarget { providerKey, modelKey }
  • 会话切换即时原子持久化,但只影响下一轮执行;完整 target 变更会让 Claude Code/Codex 重建 CLI 进程并恢复原生 session/thread
  • 为 agentred Run/Goal wire、capability/catalog 和显式 Provider 凭证/目录同步增加严格远端门控,fixed model 不允许静默降级
  • 增加迁移与 rollback,保留旧 Provider、Backend、Session 和 Claude Route 意图

Server-side account-sync contract guard: agentre-hub/agentre-server#11

关联 Issue / Related Issue

Implements the approved LLM Provider multi-model specification. No GitHub issue number was attached to this round.

截图 / Screenshots

Runtime verification evidence was captured in the ignored verification report, including Provider/model UI, local session switching, and explicit remote sync screenshots. No credentials or session tokens are included in the PR.

验证 / Verification

  • make test
    • all Go packages passed
    • frontend: 241 files / 2522 tests passed
  • affected Claude/Codex runtime package tests passed with -race
  • affected golangci-lint: 0 issues
  • exact-HEAD Spec and Code reviews passed
  • runtime V1–V5 all hold:
    • old-schema migration and rollback
    • local in-flight/current-turn isolation and next-turn ModelTarget switch
    • real agentred capability/catalog and strict invalid-target behavior
    • confirmation-gated credential/model catalog sync without target relocation
    • authorized real Claude Code, Codex, and Pi model switches with native session resume and upstream HTTP 200
    • real remote agentred Codex switch with process rebuild, same native thread, and hidden-context continuity

Final verified HEAD: d57816c43ba4f64dfa25ae2433914d90e737465c.

自检 / Checklist

  • Fixes mentioned issues / 修复已提及的问题
  • Code reviewed through the completed two-axis Spec/Code review workflow / 已完成双轴规格与代码审查
  • Changes tested / 已完成测试

No outstanding findings, blocked tasks, or unobserved requirements remain.

CodFrm added 28 commits August 11, 2026 13:07
…veTarget 解析,网关 TokenTarget 升级 ProviderKey+ModelKey,runtime 消费解析配置 (#43)
- Test 探测 deps.Model 取 provider 当前默认模型的 ModelID(provider-default)
- piagent 绑定校验要求能解析出非空启用默认模型,缺失/停用即 AgentBackendProviderModelRequired
- 展示 DTO LLMProviderModel 解析默认模型 ID,不透出凭证
- 测试夹具升级为新 Provider/Model 形状(DefaultModelKey + 子模型记录)
…get 校验,共享 ModelTargetPicker 接入编辑器,EffectiveLLMConfig 解析 Backend 固定模型 (#43)

- agent_backend_entity:新增 LLMModelKey 列;model_routes 改为结构化
  {providerKey,modelKey}(Parse/MarshalModelRoutes),生产 parser 只收新形状
- agent_backend_svc:DTO 暴露类型化 RouteTarget + llmModelKey;fixed-model 校验
  (存在/归属/启用,piagent provider-default 或 fixed 都须可解析);toItem 解析
  实际生效模型
- chat_svc:effectiveLLMForTurn 扩展 modelKey,Backend 固定模型经 ResolveTarget
  解析到指定子模型,provider-default 仍跟随当前默认;修复 chat_svc 测试包编译
- httpgateway:tier 路由目标携带完整 ModelKey(typed routes 消费方)
- 前端:共享 model-target-picker(搜索/最近/Provider 分组/default 首项/兼容过滤/
  键盘导航/loading/empty/error/invalid),Backend 编辑器主目标 + Claude 三档路由接入;
  最近使用按执行位置指纹隔离,成功持久化才记录,native/inherit 不进最近
- i18n zh-CN/en 同键集;org-detail-agent 消费方随 DTO 形状更新
…ed-model 切换 notice

- chat_entity.Session 增加 ModelKey 列;chat_repo UpdateModelTarget 同一条原子语句写
  provider_key+model_key,普通 Update 的 Omit 清单同时覆盖两列,轮中切换不被收尾冲回。
- chat_svc.SetChatSessionModelTarget(取代 SetChatSessionProvider):inherit-agent /
  provider-default / fixed-model 三态,完整组合 no-op,provider/model 存在·启用·归属·类型
  兼容校验,modelKey 无 provider 即拒;新建会话 SendRequest 校验并随 Session Create 落库。
- effectiveLLMForNonRemoteTurn 按 sessionModelKeyFor 解析:会话钉 provider 用会话 ModelKey
  (fixed 或 provider-default),inherit-agent/回退时跟随 backend 绑定,回退不误用失效
  provider 的 ModelKey;Send/Regenerate/Edit/Compact/Goal 全入口同源。
- 切换 notice 复用 kind=switch,扩展 modelKey/modelName 负载;ChatBlock 投影透传,前端
  transcript 渲染「固定模型」文案(zh/en i18n)。
- ChatSessionDetail 暴露 modelKey/agentModelKey 供 pill 水合;Wails 绑定改名
  SetChatSessionModelTarget;共享 ModelTargetPicker(scenario=chat)接入 composer 供应商
  pill,provider-default/fixed-model 选择、目标失效态、最近使用与持久化失败回滚。
- 补齐 sqlmock/repo/service 单测与 frontend 测试,全部在既有 ResolveTarget 语义上对齐。
…providerKey/modelKey 对象形状,匹配 task 3 runtime-only-new-format 契约
…自家目录解析 fixed-model 并严格拒绝缺失/停用(绝不静默降级),health.ping 公布 llm-model-target-v1 与 Provider/Model 摘要,同步复制模型目录,Picker 按能力位与 daemon 目录禁用不支持/未同步目标
…ed-model 禁用、desktop 独有目标显式需同步、选中缺失 provider 提示),daemon provider-default 无合法启用默认模型按配置损坏严格阻止(不回落旧单模型宽松行为)
…ixed-model 失效严格阻止/停用 provider-default 回退、LoadSession 与启动命令按会话 ModelKey 解析展示、改默认模型前展示动态影响并二次确认
…ider 名)、远端同步确认界面明确列出 BaseURL/协议/API Key/默认模型/模型目录
- 远端 fixed-model 解析与本地 sessionModelKeyFor 分叉:会话钉 provider-default
  (ModelKey 空)且 backend 同家钉固定模型时,桌面 remoteModelKey/remoteGoalModelKey
  与 daemon resolveTarget 各自把 be.LLMModelKey 重新派生出来,把显式 provider-default
  带偏成 fixed-model。会话是否钉住只有桌面端知道,wire 的 model key 已是解析结果,
  两端都不再自行派生(spec 决策 1 不被 backend 固定模型带偏)。
- builtin/piagent 探针(测试连接)只解析 provider-default,忽略 backend 固定模型:
  改为按 b.LLMModelKey 与执行侧同口径解析,测试连接测 backend 真正会跑的模型。
- 收尾:control.go / 两个 runtime 测试 gofmt,llm_provider_svc 测试多余 nolint:gosec
  清理,make lint 恢复 0 issue。
… 渲染的模型控件(替代常驻 region),command-mode 在 commands.focus 的 requestAnimationFrame 落定后再断言焦点/导航 Clear(vi.waitFor)
冲突 5 处,均为两侧各自新增落在同一位置:

- wire.RunParams:并存 LLMModelKey(决策 11 固定模型)与 SourceDevice /
  SourceDeviceName(R18/R19 来源设备),两者互不相干,都保留。
- i18n zh-CN / en:并存新增顶层键 modelTargetPicker 与 statusBar。
- chat-panel.test.tsx:并存两侧各自追加的 describe 块(远端 ModelTarget 门控 /
  会话加载失败 UX)。
- llm-providers.tsx:本分支已把该文件整体重写并拆进 llm-provider-models/*,
  取本分支版本;main 在该文件里的唯一改动(供应商类型下拉的字母徽标换成
  LlmProviderLogo)改落到接手它的 provider-form-dialog.tsx,随之删掉不再有
  使用者的 badgeToneClass 与 ProviderTypeMeta.tone(badge 另有使用者,保留)。

另有一处 git 能自动合并但编译不过:main 新增的 steer_segmentation_test.go 用
llm_provider_entity.LLMProvider.Model —— 该字段已随 1→N 拆到 Model 实体,夹具改
成本分支既有的 DefaultModelKey + expectProviderResolvable 写法。

验证:go test ./cmd/... ./internal/... ./migrations ./pkg/... . 全绿(125 包,
exit 0);golangci-lint 0 issues;frontend tsc -b --noEmit 干净;vitest 250 文件
2694 用例全绿。
pnpm lint --fix,纯换行与尾逗号,无逻辑改动(Frontend Lint job 在本次合并前
即为红,19 个 prettier 错误全部落在本分支自有文件上)。
@CodFrm
CodFrm merged commit 3db3677 into main Aug 13, 2026
7 checks passed
@CodFrm
CodFrm deleted the feat/2026-08-11-llm-provider-models branch August 13, 2026 02:32
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