Skip to content

Provider 模型目录、动态发现与内建 Provider 固化 PR 总结#123

Closed
phantom5099 wants to merge 7 commits into1024XEngineer:mainfrom
phantom5099:main
Closed

Provider 模型目录、动态发现与内建 Provider 固化 PR 总结#123
phantom5099 wants to merge 7 commits into1024XEngineer:mainfrom
phantom5099:main

Conversation

@phantom5099
Copy link
Copy Markdown
Collaborator

变更说明

本轮改动围绕 providerconfig 两个域完成了模型目录、动态发现、模型缓存和配置持久化的收口,目标是把“模型列表获取、模型元数据归一化、模型缓存、模型来源合并、当前 provider/model 的规范化”统一落到当前主链路内:

TUI -> Runtime -> Provider Service/Registry -> Driver

当前实现已经明确以下产品约束:

  • provider 来源固定为代码内建列表,当前仅包含 openaigeminiopenllqiniu
  • config.yaml 只持久化 selected_providercurrent_modelworkdirshell 和工具配置
  • 用户不能通过 YAML 注入新的 provider,也不会再持久化 provider 元数据
  • 模型列表由“默认模型 + /models 动态发现 + 本地缓存”共同组成

本次实现坚持以下边界:

  • 不修改 runtimetui 对外调用方式,ListModels() 仍返回 []ModelDescriptor
  • 不把厂商差异泄漏到 runtimetuiconfig
  • 不恢复用户自定义 provider 注入路径
  • 不为兼容旧路径继续堆叠一层额外迁移分支

当前模型元数据固定为:

  • ID
  • Name
  • Description
  • ContextWindow
  • MaxOutputTokens
  • Capabilities

其中 Capabilities 采用 map[string]bool 表达能力开关,适用于当前“只关心某能力是否支持”的场景。

主要改动

1. 模型元数据结构收敛

  • 扩展 internal/provider/types.go 中的 ModelDescriptor
  • 模型描述统一收敛为 IDNameDescriptionContextWindowMaxOutputTokensCapabilities
  • 将归一化入口命名明确为“从原始模型对象提炼标准字段”,避免语义混淆

2. 动态模型发现下沉到 driver

  • internal/provider/registry.go 对应的 driver 定义中接入可选 discovery 能力
  • 首批由 OpenAI-compatible driver 实现动态发现
  • 通过 GET /models 拉取服务端模型列表
  • driver 只负责协议差异与响应归一化,service 只负责编排、缓存和合并

3. 引入模型目录 JSON 缓存

  • 新增 ModelCatalogStore 抽象
  • 提供 JSON 文件实现,缓存目录位于 ~/.neocode/cache/models/
  • 缓存键按 driver + normalized base_url 计算,不按 provider 名称计算
  • 缓存内容包含 provider 身份、抓取时间、过期时间和归一化后的模型列表
  • 默认缓存 TTL 为 24 小时

4. 模型来源合并策略重构

  • provider.Service 不再只依赖静态模型列表
  • 当前模型目录按以下优先级合并:
    • 动态发现 / 本地缓存
    • 默认模型 Model
  • 首次无缓存时允许同步发现一次
  • 缓存存在但过期时,先返回旧缓存,再后台刷新
  • 切换 provider 后会触发后台预热刷新

5. 调整 config / provider 职责边界

  • ApplyDefaultsFrom() 始终以代码内建 provider 快照作为 Providers 的唯一来源
  • current_model 的合法性校正统一由 provider.Service 基于“当前 provider 的合并模型列表”处理
  • provider 元数据、模型目录和远端发现逻辑统一由 provider 域处理
  • config 只负责选择状态、默认值、校验和 YAML 持久化

6. 配置持久化与启动校正

  • 启动时先加载 YAML,再应用代码内建 provider defaults,再由 provider.Service 校正当前模型选择
  • selected_providercurrent_model 被自动修正时,会立即写回 config.yaml
  • 旧的 providersprovider_overridesworkspace_rootmax_loop 等字段不会再进入运行时配置,并会在后续保存时自然被清理

7. 内建 provider 的唯一性校验

  • provider 名称按规范化后全局唯一
  • provider 端点按 driver + normalized base_url 全局唯一
  • 代码内建 provider 不能指向同一端点
  • 该规则同时避免不同 provider 误用同一份模型缓存

预期收益

  • 模型目录不再依赖硬编码静态列表,服务端新增模型后客户端可通过发现与缓存自动感知
  • provider 层职责更清晰,模型发现属于协议能力,缓存、合并和模型选择校正属于服务编排,不再和 config 混杂
  • 模型元数据结构保持最小必要集,避免无用字段扩散到缓存、测试和后续维护中
  • 在不修改 runtimetui 接口的前提下,为后续基于上下文窗口、能力标记的策略扩展预留了数据基础
  • 内建 provider 的唯一性校验与缓存身份统一,减少配置冲突和缓存污染风险
  • provider 来源、YAML 持久化边界和启动校正行为已经收口,TUI 展示状态与运行时配置保持一致

@phantom5099 phantom5099 closed this Apr 2, 2026
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