From 9cb889c34f2653c812b044c1e6ebd264d98067a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E5=BF=86?= Date: Wed, 8 Nov 2023 07:09:52 +0800 Subject: [PATCH 1/7] docs: up to date --- .env.template | 8 ++++---- app/api/common.ts | 11 +++++++---- docker-compose.yml | 12 +++++++++--- docs/cloudflare-pages-cn.md | 7 +++++-- docs/cloudflare-pages-en.md | 13 +++++++++---- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/.env.template b/.env.template index 1ff575f116a..5e73e6d850a 100644 --- a/.env.template +++ b/.env.template @@ -24,10 +24,10 @@ HIDE_USER_API_KEY= # (optional) # Default: Empty -# If you do not want users to use GPT-4, set this value to 1. -DISABLE_GPT4= +# If you do want users to query balance, set this value to 1. +ENABLE_BALANCE_QUERY= # (optional) # Default: Empty -# If you do not want users to query balance, set this value to 1. -HIDE_BALANCE_QUERY= +# If you want to disable parse settings from url, set this value to 1. +DISABLE_FAST_LINK= diff --git a/app/api/common.ts b/app/api/common.ts index cd2936ee39f..0af7761d88c 100644 --- a/app/api/common.ts +++ b/app/api/common.ts @@ -20,7 +20,7 @@ export async function requestOpenai(req: NextRequest) { baseUrl = `${PROTOCOL}://${baseUrl}`; } - if (baseUrl.endsWith('/')) { + if (baseUrl.endsWith("/")) { baseUrl = baseUrl.slice(0, -1); } @@ -31,9 +31,12 @@ export async function requestOpenai(req: NextRequest) { console.log("[Org ID]", process.env.OPENAI_ORG_ID); } - const timeoutId = setTimeout(() => { - controller.abort(); - }, 10 * 60 * 1000); + const timeoutId = setTimeout( + () => { + controller.abort(); + }, + 10 * 60 * 1000, + ); const fetchUrl = `${baseUrl}/${openaiPath}`; const fetchOptions: RequestInit = { diff --git a/docker-compose.yml b/docker-compose.yml index c4312cfe3f3..57ca12e03f6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ -version: '3.9' +version: "3.9" services: - chatgpt-next-web: + chatgpt-next-web: profiles: ["no-proxy"] container_name: chatgpt-next-web image: yidadaa/chatgpt-next-web @@ -13,8 +13,11 @@ services: - OPENAI_ORG_ID=$OPENAI_ORG_ID - HIDE_USER_API_KEY=$HIDE_USER_API_KEY - DISABLE_GPT4=$DISABLE_GPT4 + - ENABLE_BALANCE_QUERY=$ENABLE_BALANCE_QUERY + - DISABLE_FAST_LINK=$DISABLE_FAST_LINK + - OPENAI_SB=$OPENAI_SB - chatgpt-next-web-proxy: + chatgpt-next-web-proxy: profiles: ["proxy"] container_name: chatgpt-next-web-proxy image: yidadaa/chatgpt-next-web @@ -28,3 +31,6 @@ services: - OPENAI_ORG_ID=$OPENAI_ORG_ID - HIDE_USER_API_KEY=$HIDE_USER_API_KEY - DISABLE_GPT4=$DISABLE_GPT4 + - ENABLE_BALANCE_QUERY=$ENABLE_BALANCE_QUERY + - DISABLE_FAST_LINK=$DISABLE_FAST_LINK + - OPENAI_SB=$OPENAI_SB diff --git a/docs/cloudflare-pages-cn.md b/docs/cloudflare-pages-cn.md index 2f9a99f2d41..e1567af03a7 100644 --- a/docs/cloudflare-pages-cn.md +++ b/docs/cloudflare-pages-cn.md @@ -1,6 +1,7 @@ # Cloudflare Pages 部署指南 ## 如何新建项目 + 在 Github 上 fork 本项目,然后登录到 dash.cloudflare.com 并进入 Pages。 1. 点击 "Create a project"。 @@ -30,10 +31,12 @@ - `OPENAI_ORG_ID= 可选填,指定 OpenAI 中的组织 ID` - `HIDE_USER_API_KEY=1 可选,不让用户自行填入 API Key` - `DISABLE_GPT4=1 可选,不让用户使用 GPT-4` - + - `ENABLE_BALANCE_QUERY=1 可选,启用余额查询功能` + - `DISABLE_FAST_LINK=1 可选,禁用从链接解析预制设置` + 12. 点击 "Save and Deploy"。 13. 点击 "Cancel deployment",因为需要填写 Compatibility flags。 14. 前往 "Build settings"、"Functions",找到 "Compatibility flags"。 15. 在 "Configure Production compatibility flag" 和 "Configure Preview compatibility flag" 中填写 "nodejs_compat"。 16. 前往 "Deployments",点击 "Retry deployment"。 -17. Enjoy. \ No newline at end of file +17. Enjoy. diff --git a/docs/cloudflare-pages-en.md b/docs/cloudflare-pages-en.md index 2279ff232a4..c5d55043872 100644 --- a/docs/cloudflare-pages-en.md +++ b/docs/cloudflare-pages-en.md @@ -1,6 +1,7 @@ # Cloudflare Pages Deployment Guide ## How to create a new project + Fork this project on GitHub, then log in to dash.cloudflare.com and go to Pages. 1. Click "Create a project". @@ -11,12 +12,13 @@ Fork this project on GitHub, then log in to dash.cloudflare.com and go to Pages. 6. For "Project name" and "Production branch", use the default values or change them as needed. 7. In "Build Settings", choose the "Framework presets" option and select "Next.js". 8. Do not use the default "Build command" due to a node:buffer bug. Instead, use the following command: - ``` - npx @cloudflare/next-on-pages --experimental-minify - ``` + ``` + npx @cloudflare/next-on-pages --experimental-minify + ``` 9. For "Build output directory", use the default value and do not modify it. 10. Do not modify "Root Directory". 11. For "Environment variables", click ">" and then "Add variable". Fill in the following information: + - `NODE_VERSION=20.1` - `NEXT_TELEMETRY_DISABLE=1` - `OPENAI_API_KEY=your_own_API_key` @@ -29,7 +31,10 @@ Fork this project on GitHub, then log in to dash.cloudflare.com and go to Pages. - `OPENAI_ORG_ID= Optional, specify the organization ID in OpenAI` - `HIDE_USER_API_KEY=1 Optional, do not allow users to enter their own API key` - `DISABLE_GPT4=1 Optional, do not allow users to use GPT-4` - + - `ENABLE_BALANCE_QUERY=1 Optional, allow users to query balance` + - `DISABLE_FAST_LINK=1 Optional, disable parse settings from url` + - `OPENAI_SB=1 Optional,use the third-party OpenAI-SB API` + 12. Click "Save and Deploy". 13. Click "Cancel deployment" because you need to fill in Compatibility flags. 14. Go to "Build settings", "Functions", and find "Compatibility flags". From 3a519612a0fcd7a05fe3d5d01cb9f88c0caa2a9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E5=BF=86?= Date: Wed, 8 Nov 2023 15:53:45 +0800 Subject: [PATCH 2/7] docs: fix typo in #3171 --- .env.template | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.env.template b/.env.template index 5e73e6d850a..3e32903695c 100644 --- a/.env.template +++ b/.env.template @@ -17,6 +17,11 @@ BASE_URL= # Default: Empty OPENAI_ORG_ID= +# (optional) +# Default: Empty +# If you do not want users to use GPT-4, set this value to 1. +DISABLE_GPT4= + # (optional) # Default: Empty # If you do not want users to input their own API key, set this value to 1. From 6ab4c9be2e66ebb203d7dc50a1ecf4ab30fa6885 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 8 Nov 2023 17:40:28 +0800 Subject: [PATCH 3/7] Update cloudflare-pages-cn.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cloudflare 构建命令 --- docs/cloudflare-pages-cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cloudflare-pages-cn.md b/docs/cloudflare-pages-cn.md index e1567af03a7..137bb9dc328 100644 --- a/docs/cloudflare-pages-cn.md +++ b/docs/cloudflare-pages-cn.md @@ -13,7 +13,7 @@ 7. 在 "Build Settings" 中,选择 "Framework presets" 选项并选择 "Next.js"。 8. 由于 node:buffer 的 bug,暂时不要使用默认的 "Build command"。请使用以下命令: ``` - npx https://prerelease-registry.devprod.cloudflare.dev/next-on-pages/runs/4930842298/npm-package-next-on-pages-230 --experimental-minify + npx @cloudflare/next-on-pages@1.5.0 ``` 9. 对于 "Build output directory",使用默认值并且不要修改。 10. 不要修改 "Root Directory"。 From 8c0ba1aee24f2f076c48e89a5e872466684afc85 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Thu, 9 Nov 2023 01:51:33 +0800 Subject: [PATCH 4/7] feat: close #2954 chat summary should be copyable --- app/components/chat.tsx | 1 + app/styles/globals.scss | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 18353e8fcab..a0b7307c298 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -143,6 +143,7 @@ export function SessionConfigModel(props: { onClose: () => void }) { extraListItems={ session.mask.modelConfig.sendMemory ? ( diff --git a/app/styles/globals.scss b/app/styles/globals.scss index def28680c1a..aa22b7d4fd6 100644 --- a/app/styles/globals.scss +++ b/app/styles/globals.scss @@ -357,3 +357,7 @@ pre { overflow: hidden; text-overflow: ellipsis; } + +.copyable { + user-select: text; +} From fbc02367484416a98d20b86d9994d019869d78a8 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Thu, 9 Nov 2023 02:03:05 +0800 Subject: [PATCH 5/7] fix: #3174 should prompt to confirm to delete chat --- app/components/chat-list.tsx | 10 ++++++++-- app/components/sidebar.tsx | 5 +++-- app/store/chat.ts | 27 --------------------------- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/app/components/chat-list.tsx b/app/components/chat-list.tsx index 7ba55585239..f76b369f12d 100644 --- a/app/components/chat-list.tsx +++ b/app/components/chat-list.tsx @@ -18,6 +18,7 @@ import { MaskAvatar } from "./mask"; import { Mask } from "../store/mask"; import { useRef, useEffect } from "react"; import { showConfirm } from "./ui-lib"; +import { useMobileScreen } from "../utils"; export function ChatItem(props: { onClick?: () => void; @@ -80,7 +81,11 @@ export function ChatItem(props: {
{ + props.onDelete?.(); + e.preventDefault(); + e.stopPropagation(); + }} >
@@ -101,6 +106,7 @@ export function ChatList(props: { narrow?: boolean }) { ); const chatStore = useChatStore(); const navigate = useNavigate(); + const isMobileScreen = useMobileScreen(); const onDragEnd: OnDragEndResponder = (result) => { const { destination, source } = result; @@ -142,7 +148,7 @@ export function ChatList(props: { narrow?: boolean }) { }} onDelete={async () => { if ( - !props.narrow || + (!props.narrow && !isMobileScreen) || (await showConfirm(Locale.Home.DeleteChat)) ) { chatStore.deleteSession(i); diff --git a/app/components/sidebar.tsx b/app/components/sidebar.tsx index 85af3ed2e98..beeee865afe 100644 --- a/app/components/sidebar.tsx +++ b/app/components/sidebar.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useCallback, useMemo } from "react"; +import { useEffect, useRef, useMemo } from "react"; import styles from "./home.module.scss"; @@ -8,6 +8,7 @@ import GithubIcon from "../icons/github.svg"; import ChatGptIcon from "../icons/chatgpt.svg"; import AddIcon from "../icons/add.svg"; import CloseIcon from "../icons/close.svg"; +import DeleteIcon from "../icons/delete.svg"; import MaskIcon from "../icons/mask.svg"; import PluginIcon from "../icons/plugin.svg"; import DragIcon from "../icons/drag.svg"; @@ -202,7 +203,7 @@ export function SideBar(props: { className?: string }) {
} + icon={} onClick={async () => { if (await showConfirm(Locale.Home.DeleteChat)) { chatStore.deleteSession(chatStore.currentSessionIndex); diff --git a/app/store/chat.ts b/app/store/chat.ts index 95822c19186..ff7eb51b5c1 100644 --- a/app/store/chat.ts +++ b/app/store/chat.ts @@ -85,33 +85,6 @@ function getSummarizeModel(currentModel: string) { return currentModel.startsWith("gpt") ? SUMMARIZE_MODEL : currentModel; } -interface ChatStore { - sessions: ChatSession[]; - currentSessionIndex: number; - clearSessions: () => void; - moveSession: (from: number, to: number) => void; - selectSession: (index: number) => void; - newSession: (mask?: Mask) => void; - deleteSession: (index: number) => void; - currentSession: () => ChatSession; - nextSession: (delta: number) => void; - onNewMessage: (message: ChatMessage) => void; - onUserInput: (content: string) => Promise; - summarizeSession: () => void; - updateStat: (message: ChatMessage) => void; - updateCurrentSession: (updater: (session: ChatSession) => void) => void; - updateMessage: ( - sessionIndex: number, - messageIndex: number, - updater: (message?: ChatMessage) => void, - ) => void; - resetSession: () => void; - getMessagesWithMemory: () => ChatMessage[]; - getMemoryPrompt: () => ChatMessage; - - clearAllData: () => void; -} - function countMessages(msgs: ChatMessage[]) { return msgs.reduce((pre, cur) => pre + estimateTokenLength(cur.content), 0); } From d93f05f51163488525b3957bedfa0ed8a6167b8c Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Thu, 9 Nov 2023 03:01:29 +0800 Subject: [PATCH 6/7] feat: close #3187 use CUSTOM_MODELS to control model list --- README.md | 7 ++++++ README_CN.md | 6 +++++ app/api/common.ts | 31 ++++++++++++------------- app/api/config/route.ts | 1 + app/components/chat.tsx | 12 ++++------ app/components/model-config.tsx | 7 +++--- app/config/server.ts | 17 +++++++++++++- app/store/access.ts | 7 +----- app/store/config.ts | 10 +-------- app/utils/hooks.ts | 16 +++++++++++++ app/utils/model.ts | 40 +++++++++++++++++++++++++++++++++ 11 files changed, 112 insertions(+), 42 deletions(-) create mode 100644 app/utils/hooks.ts create mode 100644 app/utils/model.ts diff --git a/README.md b/README.md index 91e03d80049..3973c84bfde 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,13 @@ If you do want users to query balance, set this value to 1, or you should set it If you want to disable parse settings from url, set this to 1. +### `CUSTOM_MODELS` (optional) + +> Default: Empty +> Example: `+llama,+claude-2,-gpt-3.5-turbo` means add `llama, claude-2` to model list, and remove `gpt-3.5-turbo` from list. + +To control custom models, use `+` to add a custom model, use `-` to hide a model, separated by comma. + ## Requirements NodeJS >= 18, Docker >= 20 diff --git a/README_CN.md b/README_CN.md index 13b97417d40..d8e9553e183 100644 --- a/README_CN.md +++ b/README_CN.md @@ -106,6 +106,12 @@ OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填 如果你想禁用从链接解析预制设置,将此环境变量设置为 1 即可。 +### `CUSTOM_MODELS` (可选) + +> 示例:`+qwen-7b-chat,+glm-6b,-gpt-3.5-turbo` 表示增加 `qwen-7b-chat` 和 `glm-6b` 到模型列表,而从列表中删除 `gpt-3.5-turbo`。 + +用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,用英文逗号隔开。 + ## 开发 点击下方按钮,开始二次开发: diff --git a/app/api/common.ts b/app/api/common.ts index 0af7761d88c..a1decd42f5b 100644 --- a/app/api/common.ts +++ b/app/api/common.ts @@ -1,10 +1,9 @@ import { NextRequest, NextResponse } from "next/server"; +import { getServerSideConfig } from "../config/server"; +import { DEFAULT_MODELS, OPENAI_BASE_URL } from "../constant"; +import { collectModelTable, collectModels } from "../utils/model"; -export const OPENAI_URL = "api.openai.com"; -const DEFAULT_PROTOCOL = "https"; -const PROTOCOL = process.env.PROTOCOL || DEFAULT_PROTOCOL; -const BASE_URL = process.env.BASE_URL || OPENAI_URL; -const DISABLE_GPT4 = !!process.env.DISABLE_GPT4; +const serverConfig = getServerSideConfig(); export async function requestOpenai(req: NextRequest) { const controller = new AbortController(); @@ -14,10 +13,10 @@ export async function requestOpenai(req: NextRequest) { "", ); - let baseUrl = BASE_URL; + let baseUrl = serverConfig.baseUrl ?? OPENAI_BASE_URL; if (!baseUrl.startsWith("http")) { - baseUrl = `${PROTOCOL}://${baseUrl}`; + baseUrl = `https://${baseUrl}`; } if (baseUrl.endsWith("/")) { @@ -26,10 +25,7 @@ export async function requestOpenai(req: NextRequest) { console.log("[Proxy] ", openaiPath); console.log("[Base Url]", baseUrl); - - if (process.env.OPENAI_ORG_ID) { - console.log("[Org ID]", process.env.OPENAI_ORG_ID); - } + console.log("[Org ID]", serverConfig.openaiOrgId); const timeoutId = setTimeout( () => { @@ -58,18 +54,23 @@ export async function requestOpenai(req: NextRequest) { }; // #1815 try to refuse gpt4 request - if (DISABLE_GPT4 && req.body) { + if (serverConfig.customModels && req.body) { try { + const modelTable = collectModelTable( + DEFAULT_MODELS, + serverConfig.customModels, + ); const clonedBody = await req.text(); fetchOptions.body = clonedBody; - const jsonBody = JSON.parse(clonedBody); + const jsonBody = JSON.parse(clonedBody) as { model?: string }; - if ((jsonBody?.model ?? "").includes("gpt-4")) { + // not undefined and is false + if (modelTable[jsonBody?.model ?? ""] === false) { return NextResponse.json( { error: true, - message: "you are not allowed to use gpt-4 model", + message: `you are not allowed to use ${jsonBody?.model} model`, }, { status: 403, diff --git a/app/api/config/route.ts b/app/api/config/route.ts index 44af8d3b9dd..db84fba175a 100644 --- a/app/api/config/route.ts +++ b/app/api/config/route.ts @@ -12,6 +12,7 @@ const DANGER_CONFIG = { disableGPT4: serverConfig.disableGPT4, hideBalanceQuery: serverConfig.hideBalanceQuery, disableFastLink: serverConfig.disableFastLink, + customModels: serverConfig.customModels, }; declare global { diff --git a/app/components/chat.tsx b/app/components/chat.tsx index a0b7307c298..9afb49f7a66 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -88,6 +88,7 @@ import { ChatCommandPrefix, useChatCommand, useCommand } from "../command"; import { prettyObject } from "../utils/format"; import { ExportMessageModal } from "./exporter"; import { getClientConfig } from "../config/client"; +import { useAllModels } from "../utils/hooks"; const Markdown = dynamic(async () => (await import("./markdown")).Markdown, { loading: () => , @@ -430,14 +431,9 @@ export function ChatActions(props: { // switch model const currentModel = chatStore.currentSession().mask.modelConfig.model; - const models = useMemo( - () => - config - .allModels() - .filter((m) => m.available) - .map((m) => m.name), - [config], - ); + const models = useAllModels() + .filter((m) => m.available) + .map((m) => m.name); const [showModelSelector, setShowModelSelector] = useState(false); return ( diff --git a/app/components/model-config.tsx b/app/components/model-config.tsx index 63950a40d04..6e4c9bcb17b 100644 --- a/app/components/model-config.tsx +++ b/app/components/model-config.tsx @@ -1,14 +1,15 @@ -import { ModalConfigValidator, ModelConfig, useAppConfig } from "../store"; +import { ModalConfigValidator, ModelConfig } from "../store"; import Locale from "../locales"; import { InputRange } from "./input-range"; import { ListItem, Select } from "./ui-lib"; +import { useAllModels } from "../utils/hooks"; export function ModelConfigList(props: { modelConfig: ModelConfig; updateConfig: (updater: (config: ModelConfig) => void) => void; }) { - const config = useAppConfig(); + const allModels = useAllModels(); return ( <> @@ -24,7 +25,7 @@ export function ModelConfigList(props: { ); }} > - {config.allModels().map((v, i) => ( + {allModels.map((v, i) => ( diff --git a/app/config/server.ts b/app/config/server.ts index 2df806fed41..007c3973863 100644 --- a/app/config/server.ts +++ b/app/config/server.ts @@ -1,4 +1,5 @@ import md5 from "spark-md5"; +import { DEFAULT_MODELS } from "../constant"; declare global { namespace NodeJS { @@ -7,6 +8,7 @@ declare global { CODE?: string; BASE_URL?: string; PROXY_URL?: string; + OPENAI_ORG_ID?: string; VERCEL?: string; HIDE_USER_API_KEY?: string; // disable user's api key input DISABLE_GPT4?: string; // allow user to use gpt-4 or not @@ -14,6 +16,7 @@ declare global { BUILD_APP?: string; // is building desktop app ENABLE_BALANCE_QUERY?: string; // allow user to query balance or not DISABLE_FAST_LINK?: string; // disallow parse settings from url or not + CUSTOM_MODELS?: string; // to control custom models } } } @@ -38,6 +41,16 @@ export const getServerSideConfig = () => { ); } + let disableGPT4 = !!process.env.DISABLE_GPT4; + let customModels = process.env.CUSTOM_MODELS ?? ""; + + if (disableGPT4) { + if (customModels) customModels += ","; + customModels += DEFAULT_MODELS.filter((m) => m.name.startsWith("gpt-4")) + .map((m) => "-" + m.name) + .join(","); + } + return { apiKey: process.env.OPENAI_API_KEY, code: process.env.CODE, @@ -45,10 +58,12 @@ export const getServerSideConfig = () => { needCode: ACCESS_CODES.size > 0, baseUrl: process.env.BASE_URL, proxyUrl: process.env.PROXY_URL, + openaiOrgId: process.env.OPENAI_ORG_ID, isVercel: !!process.env.VERCEL, hideUserApiKey: !!process.env.HIDE_USER_API_KEY, - disableGPT4: !!process.env.DISABLE_GPT4, + disableGPT4, hideBalanceQuery: !process.env.ENABLE_BALANCE_QUERY, disableFastLink: !!process.env.DISABLE_FAST_LINK, + customModels, }; }; diff --git a/app/store/access.ts b/app/store/access.ts index 3d889f6e72e..f87e44a2ac4 100644 --- a/app/store/access.ts +++ b/app/store/access.ts @@ -17,6 +17,7 @@ const DEFAULT_ACCESS_STATE = { hideBalanceQuery: false, disableGPT4: false, disableFastLink: false, + customModels: "", openaiUrl: DEFAULT_OPENAI_URL, }; @@ -52,12 +53,6 @@ export const useAccessStore = createPersistStore( .then((res: DangerConfig) => { console.log("[Config] got config from server", res); set(() => ({ ...res })); - - if (res.disableGPT4) { - DEFAULT_MODELS.forEach( - (m: any) => (m.available = !m.name.startsWith("gpt-4")), - ); - } }) .catch(() => { console.error("[Config] failed to fetch config"); diff --git a/app/store/config.ts b/app/store/config.ts index 0fbc26dfe0e..5fcd6ff514c 100644 --- a/app/store/config.ts +++ b/app/store/config.ts @@ -128,15 +128,7 @@ export const useAppConfig = createPersistStore( })); }, - allModels() { - const customModels = get() - .customModels.split(",") - .filter((v) => !!v && v.length > 0) - .map((m) => ({ name: m, available: true })); - const allModels = get().models.concat(customModels); - allModels.sort((a, b) => (a.name < b.name ? -1 : 1)); - return allModels; - }, + allModels() {}, }), { name: StoreKey.Config, diff --git a/app/utils/hooks.ts b/app/utils/hooks.ts new file mode 100644 index 00000000000..f6bfae67323 --- /dev/null +++ b/app/utils/hooks.ts @@ -0,0 +1,16 @@ +import { useMemo } from "react"; +import { useAccessStore, useAppConfig } from "../store"; +import { collectModels } from "./model"; + +export function useAllModels() { + const accessStore = useAccessStore(); + const configStore = useAppConfig(); + const models = useMemo(() => { + return collectModels( + configStore.models, + [accessStore.customModels, configStore.customModels].join(","), + ); + }, [accessStore.customModels, configStore.customModels, configStore.models]); + + return models; +} diff --git a/app/utils/model.ts b/app/utils/model.ts new file mode 100644 index 00000000000..23090f9d2f3 --- /dev/null +++ b/app/utils/model.ts @@ -0,0 +1,40 @@ +import { LLMModel } from "../client/api"; + +export function collectModelTable( + models: readonly LLMModel[], + customModels: string, +) { + const modelTable: Record = {}; + + // default models + models.forEach((m) => (modelTable[m.name] = m.available)); + + // server custom models + customModels + .split(",") + .filter((v) => !!v && v.length > 0) + .map((m) => { + if (m.startsWith("+")) { + modelTable[m.slice(1)] = true; + } else if (m.startsWith("-")) { + modelTable[m.slice(1)] = false; + } else modelTable[m] = true; + }); + return modelTable; +} + +/** + * Generate full model table. + */ +export function collectModels( + models: readonly LLMModel[], + customModels: string, +) { + const modelTable = collectModelTable(models, customModels); + const allModels = Object.keys(modelTable).map((m) => ({ + name: m, + available: modelTable[m], + })); + + return allModels; +} From d0a1d910d4dae62351ae0273562cc6067e3e6ed9 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Thu, 9 Nov 2023 03:19:13 +0800 Subject: [PATCH 7/7] fix: #3186 enable max_tokens in chat payload --- app/client/platforms/openai.ts | 1 + app/components/model-config.tsx | 4 ++-- app/store/config.ts | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/client/platforms/openai.ts b/app/client/platforms/openai.ts index fd4eb59ce77..97392a004c9 100644 --- a/app/client/platforms/openai.ts +++ b/app/client/platforms/openai.ts @@ -70,6 +70,7 @@ export class ChatGPTApi implements LLMApi { presence_penalty: modelConfig.presence_penalty, frequency_penalty: modelConfig.frequency_penalty, top_p: modelConfig.top_p, + max_tokens: Math.max(modelConfig.max_tokens, 1024), }; console.log("[Request] openai payload: ", requestPayload); diff --git a/app/components/model-config.tsx b/app/components/model-config.tsx index 6e4c9bcb17b..1c730e1449f 100644 --- a/app/components/model-config.tsx +++ b/app/components/model-config.tsx @@ -76,8 +76,8 @@ export function ModelConfigList(props: { > props.updateConfig( diff --git a/app/store/config.ts b/app/store/config.ts index 5fcd6ff514c..17eb88c30ed 100644 --- a/app/store/config.ts +++ b/app/store/config.ts @@ -49,7 +49,7 @@ export const DEFAULT_CONFIG = { model: "gpt-3.5-turbo" as ModelType, temperature: 0.5, top_p: 1, - max_tokens: 2000, + max_tokens: 8192, presence_penalty: 0, frequency_penalty: 0, sendMemory: true, @@ -82,7 +82,7 @@ export const ModalConfigValidator = { return x as ModelType; }, max_tokens(x: number) { - return limitNumber(x, 0, 100000, 2000); + return limitNumber(x, 0, 512000, 1024); }, presence_penalty(x: number) { return limitNumber(x, -2, 2, 0);