diff --git a/README.md b/README.md index e810e65c8..be1d3e594 100644 --- a/README.md +++ b/README.md @@ -292,12 +292,19 @@ anthropic claude Api Url. - 多个地址以`,`相连 ### `DEFAULT_INPUT_TEMPLATE` (可选) + 自定义默认的 template,用于初始化『设置』中的『用户输入预处理』配置项 ### `EDGE_TTS_VOICE_NAME` (可选) + 配置 Edge TTS 使用的语音声音,默认为:zh-CN-YunxiNeural 可访问 https://learn.microsoft.com/zh-cn/azure/ai-services/speech-service/language-support?tabs=tts#supported-languages 查看支持的参数 +### `NEXT_PUBLIC_USE_OPENAI_ENDPOINT_FOR_ALL_MODELS` (可选) + +配置所有模型都使用 OpenAI 路由,在使用类似 `one-api` 的中转项目时会很有用 +将此环境变量设置为 1 即可 + ## 部署 ### 容器部署 (推荐) diff --git a/app/api/common.ts b/app/api/common.ts index d1cd169d4..3a5929664 100644 --- a/app/api/common.ts +++ b/app/api/common.ts @@ -108,7 +108,7 @@ export async function requestOpenai(req: NextRequest) { fetchOptions.body = clonedBody; // not undefined and is false - if (modelTable[jsonBody?.model ?? ""].available === false) { + if (modelTable[jsonBody?.model ?? ""]?.available === false) { return NextResponse.json( { error: true, diff --git a/app/client/api.ts b/app/client/api.ts index 68a8e7dbf..6aaf9461b 100644 --- a/app/client/api.ts +++ b/app/client/api.ts @@ -216,7 +216,9 @@ export function getHeaders(ignoreHeaders?: boolean) { const accessStore = useAccessStore.getState(); let headers: Record = {}; const modelConfig = useChatStore.getState().currentSession().mask.modelConfig; - const isGoogle = modelConfig.model.startsWith("gemini"); + const isGoogle = + modelConfig.model.startsWith("gemini") && + !!!process.env.NEXT_PUBLIC_USE_OPENAI_ENDPOINT_FOR_ALL_MODELS; if (!ignoreHeaders && !isGoogle) { headers = { "Content-Type": "application/json", diff --git a/app/components/exporter.tsx b/app/components/exporter.tsx index cc70af460..940322a73 100644 --- a/app/components/exporter.tsx +++ b/app/components/exporter.tsx @@ -15,6 +15,7 @@ import { IconButton } from "./button"; import { copyToClipboard, downloadAs, + getClientApi, getMessageImages, useMobileScreen, } from "../utils"; @@ -313,14 +314,7 @@ export function PreviewActions(props: { const onRenderMsgs = (msgs: ChatMessage[]) => { setShouldExport(false); - var api: ClientApi; - if (config.modelConfig.model.startsWith("gemini")) { - api = new ClientApi(ModelProvider.GeminiPro); - } else if (identifyDefaultClaudeModel(config.modelConfig.model)) { - api = new ClientApi(ModelProvider.Claude); - } else { - api = new ClientApi(ModelProvider.GPT); - } + var api: ClientApi = getClientApi(config.modelConfig.model); api .share(msgs) diff --git a/app/components/home.tsx b/app/components/home.tsx index 88f25593b..30d1aad8e 100644 --- a/app/components/home.tsx +++ b/app/components/home.tsx @@ -9,7 +9,7 @@ import styles from "./home.module.scss"; import BotIcon from "../icons/bot.svg"; import LoadingIcon from "../icons/three-dots.svg"; -import { useMobileScreen } from "../utils"; +import { getClientApi, useMobileScreen } from "../utils"; import dynamic from "next/dynamic"; import { ModelProvider, Path, SlotID } from "../constant"; @@ -178,14 +178,8 @@ function Screen() { export function useLoadData() { const config = useAppConfig(); - var api: ClientApi; - if (config.modelConfig.model.startsWith("gemini")) { - api = new ClientApi(ModelProvider.GeminiPro); - } else if (identifyDefaultClaudeModel(config.modelConfig.model)) { - api = new ClientApi(ModelProvider.Claude); - } else { - api = new ClientApi(ModelProvider.GPT); - } + var api: ClientApi = getClientApi(config.modelConfig.model); + useEffect(() => { (async () => { const models = await api.llm.models(); diff --git a/app/store/chat.ts b/app/store/chat.ts index 9e3675205..aa8193d43 100644 --- a/app/store/chat.ts +++ b/app/store/chat.ts @@ -1,4 +1,4 @@ -import { trimTopic, getMessageTextContent } from "../utils"; +import { trimTopic, getMessageTextContent, getClientApi } from "../utils"; import Locale, { getLang } from "../locales"; import { showToast } from "../components/ui-lib"; @@ -484,13 +484,6 @@ export const useChatStore = createPersistStore( agentCall(); } } else { - if (modelConfig.model.startsWith("gemini")) { - api = new ClientApi(ModelProvider.GeminiPro); - } else if (identifyDefaultClaudeModel(modelConfig.model)) { - api = new ClientApi(ModelProvider.Claude); - } else { - api = new ClientApi(ModelProvider.GPT); - } // make request api.llm.chat({ messages: sendMessages, @@ -667,14 +660,7 @@ export const useChatStore = createPersistStore( const session = get().currentSession(); const modelConfig = session.mask.modelConfig; - var api: ClientApi; - if (modelConfig.model.startsWith("gemini")) { - api = new ClientApi(ModelProvider.GeminiPro); - } else if (identifyDefaultClaudeModel(modelConfig.model)) { - api = new ClientApi(ModelProvider.Claude); - } else { - api = new ClientApi(ModelProvider.GPT); - } + var api: ClientApi = getClientApi(config.modelConfig.model); // remove error messages if any const messages = session.messages; diff --git a/app/utils.ts b/app/utils.ts index f3a8edac4..f229fa6ff 100644 --- a/app/utils.ts +++ b/app/utils.ts @@ -1,8 +1,9 @@ import { useEffect, useState } from "react"; import { showToast } from "./components/ui-lib"; import Locale from "./locales"; -import { RequestMessage } from "./client/api"; -import { DEFAULT_MODELS } from "./constant"; +import { ClientApi, RequestMessage } from "./client/api"; +import { DEFAULT_MODELS, ModelProvider } from "./constant"; +import { identifyDefaultClaudeModel } from "./utils/checkers"; export function trimTopic(topic: string) { // Fix an issue where double quotes still show in the Indonesian language @@ -279,3 +280,17 @@ export function isSupportRAGModel(modelName: string) { (model) => model.name === modelName, ); } + +export function getClientApi(modelName: string): ClientApi { + if (!!process.env.NEXT_PUBLIC_USE_OPENAI_ENDPOINT_FOR_ALL_MODELS) + return new ClientApi(ModelProvider.GPT); + var api: ClientApi; + if (modelName.startsWith("gemini")) { + api = new ClientApi(ModelProvider.GeminiPro); + } else if (identifyDefaultClaudeModel(modelName)) { + api = new ClientApi(ModelProvider.Claude); + } else { + api = new ClientApi(ModelProvider.GPT); + } + return api; +}