MoonshotAI / MoonshotAI/kimi-code

[Bug]: 重新导入自定义 registry 后,仍有效的 default_model 被清空

Open
#3,739 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

你运行的 Kimi Code 版本是?

核验的是官方 main 源码:ee2cac102b835fcd7adb3d4b9bc3d62b0b71cdfd(2026-09-13 核验)。

本报告来自该提交的真实 handler 与配置辅助函数的隔离复现,不是某个已安装发行版的完整 CLI/TUI 实测。尚未运行完整 CLI 或仓库 Vitest。

你使用的是哪个开放平台/订阅?

不适用。自定义 registry 的响应、API key 和配置存储均使用 fixture/mock,没有调用真实模型服务,也不需要登录或付费额度。

你使用的是哪个模型?

demo/m1(本地验证用的模型别名,不是真实在线模型)。

你的电脑平台是?

Windows / PowerShell,Node.js v24.18.0。尚未验证其他平台;当前证据指向共享的 TypeScript 配置更新逻辑。

你遇到了什么问题?

通过 kimi provider add 重新导入同一个自定义 registry 时,如果原默认模型属于这次重新导入的 provider,即使 registry 仍然包含该模型,保存的 default_model 也会被清空。

典型场景:已经导入某个第三方服务并选好默认模型,之后重新导入该服务的 registry 来更新 API key 或模型列表。模型列表仍然包含原模型,导入也报告成功,但用户原先保存的默认选择丢失,需要重新设置。

本报告只针对显式的自定义 registry CLI 导入,不声称聊天中的模型切换、自动刷新或 TUI 导入也有相同问题,也不声称当前对话会立即中断。

复现步骤?

以下为已执行的隔离源码复现条件。测试边界是 handleProviderAdd,不是完整进程或磁盘持久化测试:

  1. 在内存 harness 中准备已存在的 provider demo、模型 demo/m1,并设置 defaultModel: 'demo/m1'。没有其他层级的默认模型配置覆盖它。
  2. 拦截 registry fetch,使其成功返回下面的固定响应;该响应仍包含相同的 provider 和模型。
  3. 调用当前官方源码的 handleProviderAdd,使用相同的 registry URL 和新的 fixture key。
  4. 读取导入后的内存配置和捕获的输出。

Registry 响应 fixture:

{
  "demo": {
    "id": "demo",
    "name": "Demo",
    "api": "https://provider.example.test/v1",
    "type": "openai",
    "models": {
      "m1": {
        "id": "m1",
        "limit": { "context": 1000 },
        "tool_call": true
      }
    }
  }
}

初始配置的关键内容:

{
  providers: {
    demo: {
      type: 'openai',
      baseUrl: 'https://provider.example.test/v1',
      apiKey: 'fixture-old',
    },
  },
  models: {
    'demo/m1': {
      provider: 'demo',
      model: 'm1',
      maxContextSize: 1000,
      capabilities: ['tool_use'],
    },
  },
  defaultModel: 'demo/m1',
}

复现使用真实的 handleProviderAdd、custom-registry 解析/应用函数,以及 SDK 的 removeProviderFromConfig / planProviderRemoval;fetch 和 harness 存储是 mock。mock 的 removeProvider 委托给上述真实删除辅助函数,setConfig 将提供的字段合并回内存配置,没有修改业务函数来制造结果。

观察结果:

  • 导入前:defaultModel === 'demo/m1'
  • 导入后:defaultModel === undefined,但 models['demo/m1'] 仍存在。
  • 新的 fixture API key 已应用,输出包含导入成功信息。
  • handler 最终传给 setConfig 的字段只有 providersmodels
  • 对照:默认模型属于未重新导入的其他 provider 时,默认选择保留;原本没有默认选择时,仍然没有默认选择。

整个隔离复现没有写入用户配置文件、发起真实 provider 请求或使用真实密钥。

期望的行为是什么?

如果重新导入后原默认模型的别名仍然存在,应保留用户之前的默认选择。

如果原模型确实已被 registry 移除,则不应恢复指向不存在模型的默认选择;原本没有设置默认模型时,也不应擅自选择一个。

补充信息

当前源码证据:

  • handleProviderAdd 先对已存在的 incoming provider 调用 removeProvider,之后重新应用 registry,仅写回 providers / models,没有保留原默认选择。
  • 实际 v2 SDK removeProvider 同样使用 planProviderRemoval,删除包含默认模型的 provider 时会清除对应的 defaultModel 配置。
  • 相邻的 handleCatalogAdd 已明确处理“重新导入后保留仍有效的默认模型”,并有对应回归测试。因此这里更像 custom-registry 导入与已有配置契约不一致,而不是新增默认选择策略。

提交前已搜索所有状态的相关 issue/PR。#313 修复的是 catalog 导入的对应问题,#335 是 TUI 多 provider 导入问题,#3192 / #3284 涉及 secondary_model;这些与本报告的“主默认模型别名仍存在却被清空”不同。未合并的 #736 处理远端已消失的 provider 清理,不是这一行为。开放的宽范围 i18n PR #2092 虽然涉及同文件,但其当前 handler 仍保留此问题。

Contribution
  • 我愿意自己提交修复此 bug 的 PR(请先等待维护者在本 issue 中批准)。

我愿意在维护者确认后修复此问题并补充聚焦的离线回归测试。范围仅限自定义 registry CLI 重新导入时保留仍有效的主默认模型,不扩展到 TUI、SDK/引擎行为、secondary_model 或一般 provider 清理重构。

请维护者确认这个行为是否应当与现有 catalog 导入保持一致;如果可以由我处理,请在本 issue 中以 /approve 批准。我会等待批准后再开始实现,目前未修改仓库代码或创建修复 PR。

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with apps/kimi-code/src/cli/sub/provider.ts, especially handleProviderAdd, then compare its behavior with handleCatalogAdd and the regression coverage in apps/kimi-code/test/cli/provider.test.ts. Review the provider-removal helpers in packages/node-sdk and reproduce the isolated case before adding focused offline coverage. Done means re-importing a registry preserves an existing defaultModel when its model remains available, while not restoring a removed model or inventing a default.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.