Skip to content

编辑模型配置会重置模型配置的预览图标 #10689

Open

Description

@MeerukYang
Image

Activity

  1. LIghtJUNction commented on Oct 23, 2026

    @LIghtJUNction
    Contributor

    我查看了附件,并按当前默认分支 master@0cd42bd 追了 WebUI 与后端保存链。仅凭 GIF 还不能确认是“source 图标字段被写坏”还是“编辑后的预览状态回退”,但当前代码里确实存在一个与现象高度相关的整项覆盖问题。

    已确认的代码行为

    • astrbot/dashboard/services/config_service.py::ProviderConfigService.list_providers() 对带 provider_source_id 的模型调用 ProviderManager.get_merged_provider_config()。
    • astrbot/core/provider/manager.py::get_merged_provider_config() 用 {**provider_source, **provider} 返回生效配置,因此列表对象同时包含 source 字段和模型自己的覆盖字段。
    • dashboard/src/composables/useProviderModelConfigDialog.ts::openProviderEdit() 直接深拷贝这个列表对象;saveEditedProvider() 又把整个对象交给 providerApi.update()。
    • 后端 ProviderConfigService.update_provider() / ProviderManager.update_provider() 采用整项替换,并不会把 source 继承字段剥离后再保存。
    • 图标映射由 dashboard/src/composables/useProviderSources.ts::resolveSourceIcon() 读取 source.provider,最终交给 dashboard/src/utils/providerUtils.js::getProviderIcon()。

    因此可确认的原因链是:读取时的合并结果被当成可编辑原始配置,再整项写回,一次普通模型编辑会把 provider/type/key/api_base 等本应由 source 继承的值固化到模型项中。附件中的图标重置是否正由 provider 字段在这一过程中变化导致,目前仍是合理推断;当前 master 的 source 卡片图标本身不应由模型更新接口直接修改。

    建议的修改位置:

    1. 编辑模型时不要使用列表里的 merged 对象作为保存基准。可以在打开对话框时请求 GET /providers/{id}?merged=false(或等价 by-id 接口)获取原始模型覆盖项;展示需要的继承值可以单独合并为只读视图。
    2. 保存端再做一道保护:对于含 provider_source_id 的模型,只持久化模型拥有的字段/相对 source 的显式 override;至少不能把 source 的 provider/key/api_base/type 因“读时合并”自动写回。若 API 仍是整项替换,应使用原始配置 + 明确 patch,而不是 merged config。
    3. 保存成功后的 loadConfig() 应按 source id 重新选中 source,并重新计算 resolveSourceIcon,不要依赖对话框内的临时对象。

    为确认附件对应哪一条路径,请补最少这几项(密钥可完全删除):

    • AstrBot 版本、Launcher 版本和 WebUI 版本;
    • 保存时 Network 中实际请求 URL及 JSON 里的 id/provider_source_id/provider/type/api_base;
    • 保存前后 /api/v1/provider-sources 中该 source 的上述字段,以及 /api/v1/providers?source_id=... 中该模型的上述字段;
    • 刷新页面后图标是否仍错误。

    这些信息分别用于区分 source 被修改、模型项被继承字段污染、以及仅前端选中状态/图标缓存失效。

    建议回归测试覆盖:编辑仅修改 model-owned 字段后 source 配置字节级不变、模型 raw config 不新增 source 密钥/地址、source 后续换 key/api_base 时模型继续继承、保存后图标立即与刷新后一致,以及旧的已扁平化配置仍能加载并可迁移。修改后用户观察到的效果应是“编辑模型参数不会改变预览图标,也不会切断该模型对 provider source 后续更新的继承”。

  2. MeerukYang commented on Oct 23, 2026

    @MeerukYang
    Author

    补充信息如下:

    • 昨天上报此问题,今天重启PC后仍能复现。

    • 浏览器刷新页面到 http://localhost:22068/#/providers 后,页面并未保持展开,需要重新点击相应的提供商源。重新查看提供商源后图标显示正确,但仍能复现此问题。

    • WebUI版本:4.29.1

    Image
    • astrlauncher版本:v0.3.12
    Image
    • 浏览器打开http://localhost:22068/#/providers,页面加载后F12,然后按照步骤复现,network选项卡中新产生的文件如下:(by-id和schema)

    Compressed.zip

    另外因能力所限,我对下面两句话十分困惑。我按照下面的步骤做了。如果这样做不对,希望您能提供操作方法,我会尽快完成:

    保存时 Network 中实际请求 URL及 JSON 里的 id/provider_source_id/provider/type/api_base;
    保存前后 /api/v1/provider-sources 中该 source 的上述字段,以及 /api/v1/providers?source_id=... 中该模型的上述字段;

    复现前,用浏览器访问http://localhost:22068/api/v1/providers_source_id/provider/type/api_base,查看内容;复现后,用浏览器访问http://localhost:22068/api/v1/providers_source_id/provider/type/api_base,查看内容。内容均为:

    {"status":"error","message":"Not Found"}

    复现前,用浏览器访问http://localhost:22068/api/v1/provider-sources,查看内容;复现后,用浏览器访问http://localhost:22068/api/v1/provider-sources,查看内容。内容均为:

    {"status":"ok","message":null,"data":{"provider_sources":[{"provider":"deepseek","type":"openai_chat_completion","provider_type":"chat_completion","key":["sk-k3n7uck1fr13dch1ck3ncraz7hur5da1v1v050"],"api_base":"https://api.deepseek.com/v1","timeout":120,"proxy":"","custom_headers":{},"id":"deepseek","enable":true}]}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions