ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ClawX Provider 模型 ID 不可变机制解析:禁止编辑已有 Provider 的模型 ID,避免运行时模型错位

ClawX Provider 模型 ID 不可变机制解析:禁止编辑已有 Provider 的模型 ID,避免运行时模型错位 人工智能AI 应用桌面应用交互助手【免费下载链接】ClawXClawX is a desktop app that provides a graphical interface for OpenClaw AI agents. It turns CLI-based AI orchestration into a desktop experience without using the terminal. China website is https://clawx.com.cn.项目地址https://gitcode.com/gh_mirrors/cl/ClawX点击查看免费下载本篇文章围绕 ClawXOpenClaw AI Agent 的桌面图形界面客户端中的一条核心运行时约束展开通过 ClawX 设置界面创建的 Provider其模型 IDmodel ID一旦创建即为不可变immutable。文章将结合仓库中的任务规范harness/specs/tasks/disable-provider-model-id-edit.md、配套规则provider-model-selection-authority、渲染进程源码src/components/settings/ProvidersSettings.tsx、src/lib/model-options.ts与单元/E2E 测试完整还原该机制的设计动机、UI 行为、保存路径防护、底层模型选择权威规则与验证方法帮助开发者理解为何不可编辑、如何实现、如何验证。一、设计动机为什么已有 Provider 的模型 ID 必须不可变ClawX 桌面客户端通过 electron/services/providers/provider-service.ts 等模块将 UI 中的 Provider 配置同步到 OpenClaw 运行时。OpenClaw 侧的 Provider 同步机制有意保留已有的模型行model rows以维持能力元数据capability metadata而 Provider 账户快照会把那些历史模型行复制进metadata.customModels。这带来一个实际问题用户在设置界面修改一个既有 Provider 的模型 ID 后旧的模型 ID 并不会从运行时消失历史 ID 仍可能通过同步的metadata.customModels重新出现在模型选择器中造成界面保存了新 ID聊天模型选择器却仍显示/选中旧 ID的错位stale ID。配套任务 fix-api-key-model-picker-stale-id.md 对此有明确描述Provider account snapshots copy those rows intometadata.customModels. The chat picker already ignores stale metadata for browser OAuth accounts, but API-key and device-OAuth built-in accounts still allow historical IDs to override the explicit model saved by the user.Provider 账户快照将那些行复制进metadata.customModels聊天选择器对 browser OAuth 账户已忽略过期元数据但 API-key 与 device-OAuth 的内置账户仍允许历史 ID 覆盖用户显式保存的模型。既然编辑后覆盖会产生历史 ID 残留与权威冲突最干净的方案不是做迁移而是从源头禁止编辑让模型 ID 在 Provider 创建后成为不可变字段用户需要换模型时删除并重建 Provider。这正是 disable-provider-model-id-edit.md 的核心意图Prevent stale runtime model IDs by making an existing providers model ID immutable and telling users to recreate the provider when they need a different ID.通过让既有 Provider 的模型 ID 不可变并引导用户在需要不同 ID 时重建 Provider从而防止过期的运行时模型 ID。二、行为契约期望的用户体验与验收标准任务规范在expectedUserBehavior中定义了四条必须满足的用户行为它们是整个实现与测试的验收基线期望行为说明添加 Provider 时模型 ID 仍可配置新增流程AddProviderDialog中的模型 ID 输入框保持可编辑编辑既有 Provider 时模型 ID 字段被禁用编辑表单中的模型 ID 输入框呈 disabled 状态提供本地化提示以多语言文案告知用户需删除并重建 Provider 才能更换模型 ID保存其他字段的编辑绝不提交模型 ID 变更编辑保存的 payload 中不允许携带 model 更新acceptance进一步给出可验证的验收条件所有 Provider 类型的既有模型 ID 输入框均被禁用Code Plan 编辑控件无法间接改变模型 ID编辑保存 payload 不能包含模型更新解释性提示具备完整的 en / zh / ja / ru 四种语言翻译聚焦测试与 harness 校验通过。同时规范明确了Scope范围内禁用既有 Provider 编辑表单中的模型 ID 字段阻止编辑保存逻辑与 Code Plan 控件改变模型 ID显示简短的本地化重建提示新增 Provider 流程中的模型 ID 输入保持原样。以及Out Of Scope范围外不迁移已写入 OpenClaw 的历史模型 ID不改变 Provider 的创建/删除行为不新增模型 ID 迁移工作流。三、UI 实现编辑表单中的禁用字段与重建提示核心实现位于 src/components/settings/ProvidersSettings.tsx 的ProviderCard编辑分支。当用户点击某个 Provider 卡片上的编辑按钮后编辑区域按以下逻辑渲染模型 ID 字段{showModelIdField ( div classNamespace-y-1.5 pt-2 Label className{currentLabelClasses}{t(aiProviders.dialog.modelId)}/Label Input >button typebutton >button typebutton >const payload: { newApiKey?: string; updates?: PartialProviderConfig } {}; // ... { const updates: PartialProviderConfig {}; if (typeInfo?.showBaseUrl (baseUrl.trim() || undefined) ! (account.baseUrl || undefined)) { updates.baseUrl baseUrl.trim() || undefined; } if ((account.vendorId custom || account.vendorId ollama) apiProtocol ! account.apiProtocol) { updates.apiProtocol apiProtocol; } // ... userAgent / fallbackModels / fallbackProviderIds 的差异比较与写入 if (Object.keys(updates).length 0) { payload.updates updates; } }可见handleSaveEdits只允许提交baseUrl、apiProtocol、headersUser-Agent、fallbackModels、fallbackProviderIds以及newApiKey——model字段不在其中。即使渲染进程侧出现任何绕过 UI 的状态篡改保存链路也不会把模型 ID 写入账户。再向下追一层ProvidersSettings顶层的onSaveEdits回调ProvidersSettings.tsx同样只透传baseUrl、apiProtocol、headers、model来自 payload.updates而 payload 里根本没有 model、fallbackModels、fallbackProviderIds随后调用updateAccount(item.account.id, updates, payload.newApiKey)。而 src/stores/providers.ts 中的updateAccount再通过hostApi.providers.updateAccount把补丁发给主进程。整条链路从 UI 到存储都不存在编辑时修改 model的合法入口。值得注意ProviderCard 进入编辑模式时会调用onValidateKey进行 API key 校验该校验可以携带modelId: modelId.trim() || undefined仅用于服务端校验上下文但这同样不会改变已保存的账户模型仅是校验参数。五、底层权威规则单模型内置 Provider 的显式 model 优先级最高不可编辑只是表面约束其背后是一整套模型选择权威性Model Selection Authority规则定义于 harness/specs/rules/provider-model-selection-authority.md通过 ClawX 设置界面创建的 Provider 模型 ID 不可变。既有 Provider 的编辑表单不得提交模型变更并应引导用户删除重建单模型内置 Provider 账户的显式model在交互式模型选择器中具有权威性无论其认证方式是 API key、device OAuth 还是 browser OAuth历史运行时模型行可以保留用于能力维护但不得通过同步的metadata.customModels重新作为内置备选项出现写入 OpenClaw 前剥离恰好匹配运行时 Provider key 的一个前缀只剥离一个其余斜杠保留因为斜杠可能是合法模型 ID 的一部分自定义与本地多模型账户可以继续投影所有配置的metadata.customModels不得把它们的列表折叠成所选模型。model-options.ts 中的实现印证src/lib/model-options.ts 用纯函数落实上述规则resolveRuntimeProviderKey(account)model-options.ts把账户解析为运行时 Provider key——oauth_browser的 openai 账户归一到openaicustom/ollama 账户生成{vendorId}-{8位后缀}形式minimax-portal-cn归一到minimax-portal其余直接返回vendorIdnormalizeModelIdForRuntimeProvider(modelId, runtimeProviderKey)model-options.ts仅剥离{runtimeProviderKey}/这一个前缀与规则第 4 条严格对应export function normalizeModelIdForRuntimeProvider( modelId: string | null | undefined, runtimeProviderKey: string, ): string { const value (modelId || ).trim(); const prefix ${runtimeProviderKey}/; return value.startsWith(prefix) ? value.slice(prefix.length) : value; }buildConfiguredModelOptionsmodel-options.ts对单模型内置账户vendorId不是 custom/ollama只投影显式model归一化后的唯一选项对 custom/ollama 多模型账户才展开metadata.customModels的全部配置。这与规则第 3、5 条完全一致——历史 ID 被排除在聊天模型选择器之外同时自定义多模型列表不受影响。配合 src/lib/model-options.ts 的resolveConfiguredModelRef当偏好或默认 modelRef 已失效如指向已删除 Provider 的过期 ID时自动回退到默认或第一个已配置模型进一步兜底 stale ID 场景。六、多语言提示四语言完整翻译按 ui-i18n-design-tokens 规则 的要求所有新增用户可见字符串必须经react-i18next路由并具备 en/zh/ja/ru 四种语言覆盖重建提示以aiProviders.dialog.modelIdEditDisabled键写入四份 locale 文件语言文件文案英语shared/i18n/locales/en/settings.jsonThe model ID cannot be changed after creation. Delete this provider and add it again to use a different model ID.中文shared/i18n/locales/zh/settings.json模型 ID 创建后不可修改。如需使用其他模型 ID请删除此 Provider 后重新添加。日语shared/i18n/locales/ja/settings.jsonモデル ID は作成後に変更できません。別のモデル ID を使用するには、このプロバイダーを削除して再度追加してください。俄语shared/i18n/locales/ru/settings.jsonID модели нельзя изменить после создания. Чтобы использовать другой ID, удалите этого провайдера и добавьте его снова.同时字段级标签modelIdModel ID/模型 ID/モデル ID/ID модели也已四语言齐备配合placeholder的provider/model-id格式提示保证不同语言环境下禁用字段的语义完整可读。七、测试验证单元测试与 E2E 测试如何锁定该机制单元测试模型选择权威逻辑tests/unit/model-options.test.ts 对上述模型选择逻辑做了针对性覆盖仅剥离一个前缀normalizeModelIdForRuntimeProvider(openai/gpt-5.6, openai)得到gpt-5.6而对openrouter/openai/gpt-5.6只剥离openrouter/保留openai/gpt-5.6——证实其余斜杠可能是合法模型 ID 的一部分单模型内置账户权威性用it.each覆盖api_key/oauth_device/oauth_browser三种认证模式即使账户metadata.customModels中残留gpt-5.5等历史 IDbuildConfiguredModelOptions也只投影显式 modelopenai/gpt-5.6且resolveConfiguredModelRef(openai/gpt-5.5, ...)会正确回退到openai/gpt-5.6多模型账户完整投影custom 账户通过metadata.customModels配置多个模型时全部选项去重后都会出现在选择器中malformed 快照防御非法 Provider 快照返回空选项数组不会崩溃。E2E 测试禁用状态与保存行为tests/e2e/provider-lifecycle.spec.ts 中针对 moonshot Provider 的编辑流程断言了三个关键点provider-lifecycle.spec.tsawait expect(page.getByTestId(provider-edit-model-id-moonshot-edit)).toBeDisabled(); await expect(page.getByTestId(provider-edit-model-id-moonshot-edit)).toHaveValue(kimi-k2.6); await expect(page.getByTestId(provider-edit-model-id-help-moonshot-edit)).toContainText( The model ID cannot be changed after creation., );模型 ID 输入框处于disabled状态输入框仍正确回显既有值kimi-k2.6可见不可改帮助文案包含创建后不可修改语义。随后该测试还继续填写一个无效 API key 并点击保存断言出现 Invalid API key 校验错误——即编辑保存只处理 API key 校验模型字段全程不参与变更。tests/e2e/chat-model-picker.spec.ts 则从聊天模型选择器侧验证权威性通过模拟agents/providers快照断言选择器菜单只展示显式保存的gpt-5.6、kimi-k2.7等当前模型而不展示历史残留的gpt-5.5、kimi-k2.6也不展示带 provider 前缀的冗余形式如openai/gpt-5.6并确认切换模型只产生/api/agents/main/model的 PUT 请求、不触发 gateway 重启或配置 patchchat-model-picker.spec.ts。八、机制全景与运维建议把上述层次串起来ClawX 的模型 ID 不可变是一个纵深防御体系UI 层编辑表单中模型 ID 输入框disabled并展示四语言重建提示控件层Code Plan 模式切换按钮在编辑场景下同样disabled堵死间接修改路径保存层handleSaveEdits与onSaveEdits的 payload 构造完全不包含model即使前端状态被篡改也无法提交选择器层buildConfiguredModelOptions让单模型内置账户的显式 model 成为唯一权威来源历史metadata.customModels不会重新成为备选项回退层resolveConfiguredModelRef在偏好 modelRef 失效时自动回退到默认/首个已配置模型测试层单元测试锁定前缀剥离与多/单模型差异E2E 测试锁定禁用 UI、文案与选择器展示。使用建议针对 ClawX 用户换模型请走删除重建流程在设置 → AI Providers 中编辑某个 Provider 时如需更换模型 ID请删除该 Provider 再重新添加并在添加表单中填入新的模型 ID不要在编辑表单中期待模型 ID 可改API key 与模型 ID 解耦编辑表单中的Replace API Key仅更新密钥不影响已保存的模型 ID适合密钥轮换场景自定义/Ollama 多模型账户通过账户配置的多个模型会全部出现在聊天模型选择器中不受不可变约束影响——该约束针对的是单模型内置 Provider 的显式 model 字段。开发者延伸阅读任务规范harness/specs/tasks/disable-provider-model-id-edit.md关联任务stale ID 背景harness/specs/tasks/fix-api-key-model-picker-stale-id.md权威规则harness/specs/rules/provider-model-selection-authority.md渲染实现src/components/settings/ProvidersSettings.tsx 与 src/lib/providers.ts模型选项构建src/lib/model-options.ts账户存储层src/stores/providers.ts测试tests/unit/model-options.test.ts、tests/e2e/provider-lifecycle.spec.ts、tests/e2e/chat-model-picker.spec.ts赞分享人工智能AI 应用桌面应用交互助手【免费下载链接】ClawXClawX is a desktop app that provides a graphical interface for OpenClaw AI agents. It turns CLI-based AI orchestration into a desktop experience without using the terminal. China website is https://clawx.com.cn.项目地址https://gitcode.com/gh_mirrors/cl/ClawX点击查看免费下载相关推荐ClawX Provider 默认账号不变量删除 Provider 时保持账号存储与 OpenClaw 运行时默认模型对齐的工程规范ClawX Provider 默认账号不变量删除 Provider 时保持账号存储与 OpenClaw 运行时默认模型对齐的工程规范 导读 ClawX 作为人工智能AI 应用桌面应用交互助手oh-my-openagent 模型能力解析在 Provider 元数据查找之前先归一化模型 ID 后缀oh my openagent 模型能力解析在 Provider 元数据查找之前先归一化模型 ID 后缀 本文基于 oh my openagent 仓库中一份人工智能AI Agent代码智能体多智能体MCP ClientsAgent 编排Cherry Studio provider-registry 源码解析AI 提供商与模型目录的生成与运行时机制Cherry Studio provider registry 源码解析AI 提供商与模型目录的生成与运行时机制 Cherry Studio 是一个支持多个人工智能大模型AI 应用交互助手本地部署上一篇Windows屏幕标注神器ppInk让演示教学更高效的专业工具下一篇在屏幕标注中如何实现专业级演示ppInk深度应用探索创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表