import { getHeaders } from '../client/api'; import { getClientConfig } from '../config/client'; import { ALIBABA_BASE_URL, ANTHROPIC_BASE_URL, ApiPath, BAIDU_BASE_URL, BYTEDANCE_BASE_URL, CHATGLM_BASE_URL, GEMINI_BASE_URL, GoogleSafetySettingsThreshold, IFLYTEK_BASE_URL, MOONSHOT_BASE_URL, OPENAI_BASE_URL, ServiceProvider, STABILITY_BASE_URL, StoreKey, TENCENT_BASE_URL, XAI_BASE_URL, } from '../constant'; import { ensure } from '../utils/clone'; import { getModelProvider } from '../utils/model'; import { createPersistStore } from '../utils/store'; import { DEFAULT_CONFIG } from './config'; let fetchState = 0; // 0 not fetch, 1 fetching, 2 done const isApp = getClientConfig()?.buildMode === 'export'; const DEFAULT_OPENAI_URL = isApp ? OPENAI_BASE_URL : ApiPath.OpenAI; const DEFAULT_GOOGLE_URL = isApp ? GEMINI_BASE_URL : ApiPath.Google; const DEFAULT_ANTHROPIC_URL = isApp ? ANTHROPIC_BASE_URL : ApiPath.Anthropic; const DEFAULT_BAIDU_URL = isApp ? BAIDU_BASE_URL : ApiPath.Baidu; const DEFAULT_BYTEDANCE_URL = isApp ? BYTEDANCE_BASE_URL : ApiPath.ByteDance; const DEFAULT_ALIBABA_URL = isApp ? ALIBABA_BASE_URL : ApiPath.Alibaba; const DEFAULT_TENCENT_URL = isApp ? TENCENT_BASE_URL : ApiPath.Tencent; const DEFAULT_MOONSHOT_URL = isApp ? MOONSHOT_BASE_URL : ApiPath.Moonshot; const DEFAULT_STABILITY_URL = isApp ? STABILITY_BASE_URL : ApiPath.Stability; const DEFAULT_IFLYTEK_URL = isApp ? IFLYTEK_BASE_URL : ApiPath.Iflytek; const DEFAULT_XAI_URL = isApp ? XAI_BASE_URL : ApiPath.XAI; const DEFAULT_CHATGLM_URL = isApp ? CHATGLM_BASE_URL : ApiPath.ChatGLM; const DEFAULT_ACCESS_STATE = { accessCode: '', useCustomConfig: false, provider: ServiceProvider.OpenAI, // openai openaiUrl: DEFAULT_OPENAI_URL, openaiApiKey: '', // azure azureUrl: '', azureApiKey: '', azureApiVersion: '2023-08-01-preview', // google ai studio googleUrl: DEFAULT_GOOGLE_URL, googleApiKey: '', googleApiVersion: 'v1', googleSafetySettings: GoogleSafetySettingsThreshold.BLOCK_ONLY_HIGH, // anthropic anthropicUrl: DEFAULT_ANTHROPIC_URL, anthropicApiKey: '', anthropicApiVersion: '2023-06-01', // baidu baiduUrl: DEFAULT_BAIDU_URL, baiduApiKey: '', baiduSecretKey: '', // bytedance bytedanceUrl: DEFAULT_BYTEDANCE_URL, bytedanceApiKey: '', // alibaba alibabaUrl: DEFAULT_ALIBABA_URL, alibabaApiKey: '', // moonshot moonshotUrl: DEFAULT_MOONSHOT_URL, moonshotApiKey: '', // stability stabilityUrl: DEFAULT_STABILITY_URL, stabilityApiKey: '', // tencent tencentUrl: DEFAULT_TENCENT_URL, tencentSecretKey: '', tencentSecretId: '', // iflytek iflytekUrl: DEFAULT_IFLYTEK_URL, iflytekApiKey: '', iflytekApiSecret: '', // xai xaiUrl: DEFAULT_XAI_URL, xaiApiKey: '', // chatglm chatglmUrl: DEFAULT_CHATGLM_URL, chatglmApiKey: '', // server config needCode: true, hideUserApiKey: false, hideBalanceQuery: false, disableGPT4: false, disableFastLink: false, customModels: '', defaultModel: '', // tts config edgeTTSVoiceName: 'zh-CN-YunxiNeural', }; export const useAccessStore = createPersistStore( { ...DEFAULT_ACCESS_STATE }, (set, get) => ({ enabledAccessControl() { this.fetch(); return get().needCode; }, edgeVoiceName() { this.fetch(); return get().edgeTTSVoiceName; }, isValidOpenAI() { return ensure(get(), ['openaiApiKey']); }, isValidAzure() { return ensure(get(), ['azureUrl', 'azureApiKey', 'azureApiVersion']); }, isValidGoogle() { return ensure(get(), ['googleApiKey']); }, isValidAnthropic() { return ensure(get(), ['anthropicApiKey']); }, isValidBaidu() { return ensure(get(), ['baiduApiKey', 'baiduSecretKey']); }, isValidByteDance() { return ensure(get(), ['bytedanceApiKey']); }, isValidAlibaba() { return ensure(get(), ['alibabaApiKey']); }, isValidTencent() { return ensure(get(), ['tencentSecretKey', 'tencentSecretId']); }, isValidMoonshot() { return ensure(get(), ['moonshotApiKey']); }, isValidIflytek() { return ensure(get(), ['iflytekApiKey']); }, isValidXAI() { return ensure(get(), ['xaiApiKey']); }, isValidChatGLM() { return ensure(get(), ['chatglmApiKey']); }, isAuthorized() { this.fetch(); // has token or has code or disabled access control return ( this.isValidOpenAI() || this.isValidAzure() || this.isValidGoogle() || this.isValidAnthropic() || this.isValidBaidu() || this.isValidByteDance() || this.isValidAlibaba() || this.isValidTencent() || this.isValidMoonshot() || this.isValidIflytek() || this.isValidXAI() || this.isValidChatGLM() || !this.enabledAccessControl() || (this.enabledAccessControl() && ensure(get(), ['accessCode'])) ); }, fetch() { if (fetchState > 0 || getClientConfig()?.buildMode === 'export') { return; } fetchState = 1; fetch('/api/config', { method: 'post', body: null, headers: { ...getHeaders(), }, }) .then(res => res.json()) .then((res) => { const defaultModel = res.defaultModel ?? ''; if (defaultModel !== '') { const [model, providerName] = getModelProvider(defaultModel); DEFAULT_CONFIG.modelConfig.model = model; DEFAULT_CONFIG.modelConfig.providerName = providerName as any; } return res; }) .then((res: DangerConfig) => { console.log('[Config] got config from server', res); set(() => ({ ...res })); }) .catch(() => { console.error('[Config] failed to fetch config'); }) .finally(() => { fetchState = 2; }); }, }), { name: StoreKey.Access, version: 2, migrate(persistedState, version) { if (version < 2) { const state = persistedState as { token: string; openaiApiKey: string; azureApiVersion: string; googleApiKey: string; }; state.openaiApiKey = state.token; state.azureApiVersion = '2023-08-01-preview'; } return persistedState as any; }, }, );