// desktop/src/stores/providerStore.ts import { create } from 'zustand' import { providersApi } from '../api/providers' import { useSettingsStore } from './settingsStore' import type { SavedProvider, CreateProviderInput, UpdateProviderInput, TestProviderConfigInput, ProviderTestResult, } from '../types/provider' // 与后端 src/server/api/models.ts 的 DEFAULT_MODEL 保持一致: // 切回"官方"时把聊天页的 currentModel 重置到这个,避免残留第三方 provider // 的 model id 在官方模型列表里找不到、ModelSelector 显示但不选中的状态。 const OFFICIAL_DEFAULT_MODEL_ID = 'claude-opus-4-7' type ProviderStore = { providers: SavedProvider[] activeId: string | null isLoading: boolean error: string | null fetchProviders: () => Promise createProvider: (input: CreateProviderInput) => Promise updateProvider: (id: string, input: UpdateProviderInput) => Promise deleteProvider: (id: string) => Promise activateProvider: (id: string) => Promise activateOfficial: () => Promise testProvider: (id: string, overrides?: { baseUrl?: string; modelId?: string; apiFormat?: string }) => Promise testConfig: (input: TestProviderConfigInput) => Promise } export const useProviderStore = create((set, get) => ({ providers: [], activeId: null, isLoading: false, error: null, fetchProviders: async () => { set({ isLoading: true, error: null }) try { const { providers, activeId } = await providersApi.list() set({ providers, activeId, isLoading: false }) } catch (err) { set({ isLoading: false, error: err instanceof Error ? err.message : String(err) }) } }, createProvider: async (input) => { const { provider } = await providersApi.create(input) await get().fetchProviders() return provider }, updateProvider: async (id, input) => { const { provider } = await providersApi.update(id, input) await get().fetchProviders() return provider }, deleteProvider: async (id) => { await providersApi.delete(id) await get().fetchProviders() }, activateProvider: async (id) => { await providersApi.activate(id) await get().fetchProviders() // 联动聊天页:把 currentModel 重置到新 provider 的 main model。 // 不这么做的话,用户在切换前手动选过的 model id (写进了 settings.json 的 // `model` 字段) 会继续被后端当作 explicit 返回,但新 provider 的模型列表 // 里没这个 id, ModelSelector 会卡在"显示旧名字 + radio 不选中"。 const provider = get().providers.find((p) => p.id === id) if (provider) { const settings = useSettingsStore.getState() await settings.setModel(provider.models.main) await settings.fetchAll() } }, activateOfficial: async () => { await providersApi.activateOfficial() await get().fetchProviders() // 切回官方时同样重置 currentModel,避免残留第三方 model id。 const settings = useSettingsStore.getState() await settings.setModel(OFFICIAL_DEFAULT_MODEL_ID) await settings.fetchAll() }, testProvider: async (id, overrides?) => { const { result } = await providersApi.test(id, overrides) return result }, testConfig: async (input) => { const { result } = await providersApi.testConfig(input) return result }, }))