diff --git a/src/renderer/src/aiCore/provider/providerConfig.ts b/src/renderer/src/aiCore/provider/providerConfig.ts index 33b03a997..dabcd14ef 100644 --- a/src/renderer/src/aiCore/provider/providerConfig.ts +++ b/src/renderer/src/aiCore/provider/providerConfig.ts @@ -9,6 +9,7 @@ import { } from '@renderer/hooks/useAwsBedrock' import { createVertexProvider, isVertexAIConfigured } from '@renderer/hooks/useVertexAI' import { getProviderByModel } from '@renderer/services/AssistantService' +import { getProviderById } from '@renderer/services/ProviderService' import store from '@renderer/store' import { isSystemProvider, type Model, type Provider, SystemProviderIds } from '@renderer/types' import type { OpenAICompletionsStreamOptions } from '@renderer/types/aiCoreTypes' @@ -250,6 +251,12 @@ export function providerToAiSdkConfig(actualProvider: Provider, model: Model): A if (model.endpoint_type) { extraOptions.endpointType = model.endpoint_type } + // CherryIN API Host + const cherryinProvider = getProviderById(SystemProviderIds.cherryin) + if (cherryinProvider) { + extraOptions.anthropicBaseURL = cherryinProvider.anthropicApiHost + extraOptions.geminiBaseURL = cherryinProvider.apiHost + '/gemini/v1beta' + } } if (hasProviderConfig(aiSdkProviderId) && aiSdkProviderId !== 'openai-compatible') { diff --git a/src/renderer/src/pages/settings/ProviderSettings/CherryINSettings.tsx b/src/renderer/src/pages/settings/ProviderSettings/CherryINSettings.tsx new file mode 100644 index 000000000..7b2902417 --- /dev/null +++ b/src/renderer/src/pages/settings/ProviderSettings/CherryINSettings.tsx @@ -0,0 +1,74 @@ +import { useProvider } from '@renderer/hooks/useProvider' +import { Select } from 'antd' +import type { FC } from 'react' +import { useCallback, useMemo } from 'react' +import { useTranslation } from 'react-i18next' + +interface CherryINSettingsProps { + providerId: string + apiHost: string + setApiHost: (host: string) => void +} + +const API_HOST_OPTIONS = [ + { + value: 'https://open.cherryin.cc', + labelKey: '加速域名', + description: 'open.cherryin.cc' + }, + { + value: 'https://open.cherryin.net', + labelKey: '国际域名', + description: 'open.cherryin.net' + }, + { + value: 'https://open.cherryin.ai', + labelKey: '备用域名', + description: 'open.cherryin.ai' + } +] + +const CherryINSettings: FC = ({ providerId, apiHost, setApiHost }) => { + const { updateProvider } = useProvider(providerId) + const { t } = useTranslation() + + const getCurrentHost = useMemo(() => { + const matchedOption = API_HOST_OPTIONS.find((option) => apiHost?.includes(option.value.replace('https://', ''))) + return matchedOption?.value ?? API_HOST_OPTIONS[0].value + }, [apiHost]) + + const handleHostChange = useCallback( + (value: string) => { + setApiHost(value) + updateProvider({ apiHost: value, anthropicApiHost: value }) + }, + [setApiHost, updateProvider] + ) + + const options = useMemo( + () => + API_HOST_OPTIONS.map((option) => ({ + value: option.value, + label: ( +
+ {t(option.labelKey)} + {t(option.description)} +
+ ) + })), + [t] + ) + + return ( + setApiHost(e.target.value)} - onBlur={onUpdateApiHost} - /> - {isApiHostResettable && ( - - )} - + {isCherryIN && isChineseUser ? ( + + ) : ( + + setApiHost(e.target.value)} + onBlur={onUpdateApiHost} + /> + {isApiHostResettable && ( + + )} + + )} {isVertexProvider(provider) && ( {t('settings.provider.vertex_ai.api_host_help')} diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts index 8d9176be1..30b6b7212 100644 --- a/src/renderer/src/store/index.ts +++ b/src/renderer/src/store/index.ts @@ -67,7 +67,7 @@ const persistedReducer = persistReducer( { key: 'cherry-studio', storage, - version: 182, + version: 183, blacklist: ['runtime', 'messages', 'messageBlocks', 'tabs', 'toolPermissions'], migrate }, diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index a80336e69..8559a39e2 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -2976,6 +2976,22 @@ const migrateConfig = { logger.error('migrate 182 error', error as Error) return state } + }, + '183': (state: RootState) => { + try { + state.llm.providers.forEach((provider) => { + if (provider.id === SystemProviderIds.cherryin) { + provider.apiHost = 'https://open.cherryin.cc' + provider.anthropicApiHost = 'https://open.cherryin.cc' + } + }) + state.llm.providers = moveProvider(state.llm.providers, SystemProviderIds.poe, 10) + logger.info('migrate 183 success') + return state + } catch (error) { + logger.error('migrate 183 error', error as Error) + return state + } } }