mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
102 lines
3.4 KiB
TypeScript
102 lines
3.4 KiB
TypeScript
// 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<void>
|
|
createProvider: (input: CreateProviderInput) => Promise<SavedProvider>
|
|
updateProvider: (id: string, input: UpdateProviderInput) => Promise<SavedProvider>
|
|
deleteProvider: (id: string) => Promise<void>
|
|
activateProvider: (id: string) => Promise<void>
|
|
activateOfficial: () => Promise<void>
|
|
testProvider: (id: string, overrides?: { baseUrl?: string; modelId?: string; apiFormat?: string }) => Promise<ProviderTestResult>
|
|
testConfig: (input: TestProviderConfigInput) => Promise<ProviderTestResult>
|
|
}
|
|
|
|
export const useProviderStore = create<ProviderStore>((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
|
|
},
|
|
}))
|