diff --git a/apps/desktop/src/renderer/src/components/settings/AgentLabSection.tsx b/apps/desktop/src/renderer/src/components/settings/AgentLabSection.tsx index f477479..2b75d17 100644 --- a/apps/desktop/src/renderer/src/components/settings/AgentLabSection.tsx +++ b/apps/desktop/src/renderer/src/components/settings/AgentLabSection.tsx @@ -102,6 +102,16 @@ export function AgentLabSection(): ReactElement { setEditing(true); } + function mergeTemplateModels(currentModels: ModelForm[], vendor: string): ModelForm[] { + const entry = catalog.data?.find((item) => item.vendor === vendor); + if (!entry?.models.length) return currentModels; + const seen = new Set(currentModels.map((m) => m.id)); + const extra = entry.models + .filter((m) => !seen.has(m.id)) + .map((m) => ({ id: m.id, label: m.label ?? '', capabilities: m.capabilities as Capability[] })); + return extra.length > 0 ? [...currentModels, ...extra] : currentModels; + } + function applyVendor(vendor: string): void { const entry = catalog.data?.find((item) => item.vendor === vendor); setForm((current) => ({ @@ -109,21 +119,25 @@ export function AgentLabSection(): ReactElement { vendor, baseUrl: current.baseUrl.trim() || entry?.baseUrl || current.baseUrl, name: current.name.trim() || entry?.label?.replace(/(.*?)/g, '') || current.name, + models: mergeTemplateModels(current.models, vendor), })); } function importTemplateModels(): void { - const entry = catalog.data?.find((item) => item.vendor === form.vendor); - if (!entry?.models.length) return; - setForm((current) => { - const seen = new Set(current.models.map((m) => m.id)); - const extra = entry.models - .filter((m) => !seen.has(m.id)) - .map((m) => ({ id: m.id, label: m.label ?? '', capabilities: m.capabilities as Capability[] })); - return { ...current, models: [...current.models, ...extra] }; - }); + setForm((current) => ({ + ...current, + models: mergeTemplateModels(current.models, form.vendor), + })); } + /** 模板中有多少个模型尚未添加(用于按钮 badge)。 */ + const newModelCount = useMemo(() => { + const entry = catalog.data?.find((item) => item.vendor === form.vendor); + if (!entry?.models.length) return 0; + const seen = new Set(form.models.map((m) => m.id)); + return entry.models.filter((m) => !seen.has(m.id)).length; + }, [catalog.data, form.vendor, form.models]); + function addModel(): void { setForm((c) => ({ ...c, models: [...c.models, { id: '', label: '', capabilities: ['chat'] }] })); } @@ -320,7 +334,7 @@ export function AgentLabSection(): ReactElement {
可用模型
diff --git a/packages/service/src/bootstrap/agentlab_config.ts b/packages/service/src/bootstrap/agentlab_config.ts index 3281bf4..7f1c158 100644 --- a/packages/service/src/bootstrap/agentlab_config.ts +++ b/packages/service/src/bootstrap/agentlab_config.ts @@ -14,8 +14,21 @@ import type { UserConfigService } from './user_config'; export class AgentLabConfigService { constructor(private readonly userConfig: UserConfigService) {} + /** + * 用厂商模板自动补全缺失的模型(仅追加,不覆盖已有)。 + * 解决了用户早前保存的 provider 不包含 catalog 后续新增模型的问题。 + */ + private enrichProvider(p: AgentLabProviderConfig): AgentLabProviderConfig { + const entry = AGENTLAB_PROVIDER_CATALOG.find((c) => c.vendor === p.vendor); + if (!entry?.models?.length) return p; + const existingIds = new Set(p.models.map((m) => m.id)); + const extra = entry.models.filter((m) => !existingIds.has(m.id)); + if (extra.length === 0) return p; + return { ...p, models: [...p.models, ...extra] }; + } + listProviders(): AgentLabProviderConfig[] { - return this.userConfig.getSettings().agentLab.providers; + return this.userConfig.getSettings().agentLab.providers.map((p) => this.enrichProvider(p)); } getProvider(providerId: string): AgentLabProviderConfig | null {