From 0478a6ce3ba46e0dec0dfae11e78ef6464a8214c Mon Sep 17 00:00:00 2001 From: yaway Date: Thu, 18 Jul 2024 17:20:21 +0800 Subject: [PATCH 1/9] Create README_JP.md --- README_JP.md | 286 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 README_JP.md diff --git a/README_JP.md b/README_JP.md new file mode 100644 index 000000000..5400bb276 --- /dev/null +++ b/README_JP.md @@ -0,0 +1,286 @@ +
+预览 + +

NextChat

+ +一键免费部署你的私人 ChatGPT 网页应用,支持 GPT3, GPT4 & Gemini Pro 模型。 + +[演示 Demo](https://chat-gpt-next-web.vercel.app/) / [反馈 Issues](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [加入 Discord](https://discord.gg/zrhvHCr79N) + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web) + +[![Deploy on Zeabur](https://zeabur.com/button.svg)](https://zeabur.com/templates/ZBUEFA) + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) + +![主界面](./docs/images/cover.png) + +
+ +## 开始使用 + +1. 准备好你的 [OpenAI API Key](https://platform.openai.com/account/api-keys); +2. 点击右侧按钮开始部署: + [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&env=GOOGLE_API_KEY&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web),直接使用 Github 账号登录即可,记得在环境变量页填入 API Key 和[页面访问密码](#配置页面访问密码) CODE; +3. 部署完毕后,即可开始使用; +4. (可选)[绑定自定义域名](https://vercel.com/docs/concepts/projects/domains/add-a-domain):Vercel 分配的域名 DNS 在某些区域被污染了,绑定自定义域名即可直连。 + +## 保持更新 + +如果你按照上述步骤一键部署了自己的项目,可能会发现总是提示“存在更新”的问题,这是由于 Vercel 会默认为你创建一个新项目而不是 fork 本项目,这会导致无法正确地检测更新。 +推荐你按照下列步骤重新部署: + +- 删除掉原先的仓库; +- 使用页面右上角的 fork 按钮,fork 本项目; +- 在 Vercel 重新选择并部署,[请查看详细教程](./docs/vercel-cn.md#如何新建项目)。 + +### 打开自动更新 + +> 如果你遇到了 Upstream Sync 执行错误,请手动 Sync Fork 一次! + +当你 fork 项目之后,由于 Github 的限制,需要手动去你 fork 后的项目的 Actions 页面启用 Workflows,并启用 Upstream Sync Action,启用之后即可开启每小时定时自动更新: + +![自动更新](./docs/images/enable-actions.jpg) + +![启用自动更新](./docs/images/enable-actions-sync.jpg) + +### 手动更新代码 + +如果你想让手动立即更新,可以查看 [Github 的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) 了解如何让 fork 的项目与上游代码同步。 + +你可以 star/watch 本项目或者 follow 作者来及时获得新功能更新通知。 + +## 配置页面访问密码 + +> 配置密码后,用户需要在设置页手动填写访问码才可以正常聊天,否则会通过消息提示未授权状态。 + +> **警告**:请务必将密码的位数设置得足够长,最好 7 位以上,否则[会被爆破](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/518)。 + +本项目提供有限的权限控制功能,请在 Vercel 项目控制面板的环境变量页增加名为 `CODE` 的环境变量,值为用英文逗号分隔的自定义密码: + +``` +code1,code2,code3 +``` + +增加或修改该环境变量后,请**重新部署**项目使改动生效。 + +## 环境变量 + +> 本项目大多数配置项都通过环境变量来设置,教程:[如何修改 Vercel 环境变量](./docs/vercel-cn.md)。 + +### `OPENAI_API_KEY` (必填项) + +OpanAI 密钥,你在 openai 账户页面申请的 api key,使用英文逗号隔开多个 key,这样可以随机轮询这些 key。 + +### `CODE` (可选) + +访问密码,可选,可以使用逗号隔开多个密码。 + +**警告**:如果不填写此项,则任何人都可以直接使用你部署后的网站,可能会导致你的 token 被急速消耗完毕,建议填写此选项。 + +### `BASE_URL` (可选) + +> Default: `https://api.openai.com` + +> Examples: `http://your-openai-proxy.com` + +OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填写此选项。 + +> 如果遇到 ssl 证书问题,请将 `BASE_URL` 的协议设置为 http。 + +### `OPENAI_ORG_ID` (可选) + +指定 OpenAI 中的组织 ID。 + +### `AZURE_URL` (可选) + +> 形如:https://{azure-resource-url}/openai/deployments/{deploy-name} +> 如果你已经在`CUSTOM_MODELS`中参考`displayName`的方式配置了{deploy-name},那么可以从`AZURE_URL`中移除`{deploy-name}` + +Azure 部署地址。 + +### `AZURE_API_KEY` (可选) + +Azure 密钥。 + +### `AZURE_API_VERSION` (可选) + +Azure Api 版本,你可以在这里找到:[Azure 文档](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)。 + +### `GOOGLE_API_KEY` (可选) + +Google Gemini Pro 密钥. + +### `GOOGLE_URL` (可选) + +Google Gemini Pro Api Url. + +### `ANTHROPIC_API_KEY` (可选) + +anthropic claude Api Key. + +### `ANTHROPIC_API_VERSION` (可选) + +anthropic claude Api version. + +### `ANTHROPIC_URL` (可选) + +anthropic claude Api Url. + +### `BAIDU_API_KEY` (可选) + +Baidu Api Key. + +### `BAIDU_SECRET_KEY` (可选) + +Baidu Secret Key. + +### `BAIDU_URL` (可选) + +Baidu Api Url. + +### `BYTEDANCE_API_KEY` (可选) + +ByteDance Api Key. + +### `BYTEDANCE_URL` (可选) + +ByteDance Api Url. + +### `ALIBABA_API_KEY` (可选) + +阿里云(千问)Api Key. + +### `ALIBABA_URL` (可选) + +阿里云(千问)Api Url. + +### `HIDE_USER_API_KEY` (可选) + +如果你不想让用户自行填入 API Key,将此环境变量设置为 1 即可。 + +### `DISABLE_GPT4` (可选) + +如果你不想让用户使用 GPT-4,将此环境变量设置为 1 即可。 + +### `ENABLE_BALANCE_QUERY` (可选) + +如果你想启用余额查询功能,将此环境变量设置为 1 即可。 + +### `DISABLE_FAST_LINK` (可选) + +如果你想禁用从链接解析预制设置,将此环境变量设置为 1 即可。 + +### `WHITE_WEBDEV_ENDPOINTS` (可选) + +如果你想增加允许访问的webdav服务地址,可以使用该选项,格式要求: +- 每一个地址必须是一个完整的 endpoint +> `https://xxxx/xxx` +- 多个地址以`,`相连 + +### `CUSTOM_MODELS` (可选) + +> 示例:`+qwen-7b-chat,+glm-6b,-gpt-3.5-turbo,gpt-4-1106-preview=gpt-4-turbo` 表示增加 `qwen-7b-chat` 和 `glm-6b` 到模型列表,而从列表中删除 `gpt-3.5-turbo`,并将 `gpt-4-1106-preview` 模型名字展示为 `gpt-4-turbo`。 +> 如果你想先禁用所有模型,再启用指定模型,可以使用 `-all,+gpt-3.5-turbo`,则表示仅启用 `gpt-3.5-turbo` + +用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。 + +在Azure的模式下,支持使用`modelName@azure=deploymentName`的方式配置模型名称和部署名称(deploy-name) +> 示例:`+gpt-3.5-turbo@azure=gpt35`这个配置会在模型列表显示一个`gpt35(Azure)`的选项 + +在ByteDance的模式下,支持使用`modelName@bytedance=deploymentName`的方式配置模型名称和部署名称(deploy-name) +> 示例: `+Doubao-lite-4k@bytedance=ep-xxxxx-xxx`这个配置会在模型列表显示一个`Doubao-lite-4k(ByteDance)`的选项 + + +### `DEFAULT_MODEL` (可选) + +更改默认模型 + +### `DEFAULT_INPUT_TEMPLATE` (可选) + +自定义默认的 template,用于初始化『设置』中的『用户输入预处理』配置项 + +## 开发 + +点击下方按钮,开始二次开发: + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) + +在开始写代码之前,需要在项目根目录新建一个 `.env.local` 文件,里面填入环境变量: + +``` +OPENAI_API_KEY= + +# 中国大陆用户,可以使用本项目自带的代理进行开发,你也可以自由选择其他代理地址 +BASE_URL=https://b.nextweb.fun/api/proxy +``` + +### 本地开发 + +1. 安装 nodejs 18 和 yarn,具体细节请询问 ChatGPT; +2. 执行 `yarn install && yarn dev` 即可。⚠️ 注意:此命令仅用于本地开发,不要用于部署! +3. 如果你想本地部署,请使用 `yarn install && yarn build && yarn start` 命令,你可以配合 pm2 来守护进程,防止被杀死,详情询问 ChatGPT。 + +## 部署 + +### 容器部署 (推荐) + +> Docker 版本需要在 20 及其以上,否则会提示找不到镜像。 + +> ⚠️ 注意:docker 版本在大多数时间都会落后最新的版本 1 到 2 天,所以部署后会持续出现“存在更新”的提示,属于正常现象。 + +```shell +docker pull yidadaa/chatgpt-next-web + +docker run -d -p 3000:3000 \ + -e OPENAI_API_KEY=sk-xxxx \ + -e CODE=页面访问密码 \ + yidadaa/chatgpt-next-web +``` + +你也可以指定 proxy: + +```shell +docker run -d -p 3000:3000 \ + -e OPENAI_API_KEY=sk-xxxx \ + -e CODE=页面访问密码 \ + --net=host \ + -e PROXY_URL=http://127.0.0.1:7890 \ + yidadaa/chatgpt-next-web +``` + +如果你的本地代理需要账号密码,可以使用: + +```shell +-e PROXY_URL="http://127.0.0.1:7890 user password" +``` + +如果你需要指定其他环境变量,请自行在上述命令中增加 `-e 环境变量=环境变量值` 来指定。 + +### 本地部署 + +在控制台运行下方命令: + +```shell +bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/scripts/setup.sh) +``` + +⚠️ 注意:如果你安装过程中遇到了问题,请使用 docker 部署。 + +## 鸣谢 + +### 捐赠者 + +> 见英文版。 + +### 贡献者 + +[见项目贡献者列表](https://github.com/Yidadaa/ChatGPT-Next-Web/graphs/contributors) + +### 相关项目 + +- [one-api](https://github.com/songquanpeng/one-api): 一站式大模型额度管理平台,支持市面上所有主流大语言模型 + +## 开源协议 + +[MIT](https://opensource.org/license/mit/) From 287fa0a39cf07767630a9cd744f32929357a9aee Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Fri, 19 Jul 2024 13:50:10 +0800 Subject: [PATCH 2/9] feat: 1. using cache storage store image data; 2. get base64image before chat to api #5013 --- app/client/platforms/alibaba.ts | 2 +- app/client/platforms/anthropic.ts | 9 +++- app/client/platforms/google.ts | 10 +++- app/client/platforms/openai.ts | 12 +++-- app/components/chat.tsx | 6 +-- app/constant.ts | 5 +- app/utils/chat.ts | 79 ++++++++++++++++++++++++++++++- public/serviceWorker.js | 46 +++++++++++++++++- public/serviceWorkerRegister.js | 9 +++- 9 files changed, 164 insertions(+), 14 deletions(-) diff --git a/app/client/platforms/alibaba.ts b/app/client/platforms/alibaba.ts index 723ba774b..d5fa3042f 100644 --- a/app/client/platforms/alibaba.ts +++ b/app/client/platforms/alibaba.ts @@ -21,7 +21,7 @@ import { } from "@fortaine/fetch-event-source"; import { prettyObject } from "@/app/utils/format"; import { getClientConfig } from "@/app/config/client"; -import { getMessageTextContent, isVisionModel } from "@/app/utils"; +import { getMessageTextContent } from "@/app/utils"; export interface OpenAIListModelResponse { object: string; diff --git a/app/client/platforms/anthropic.ts b/app/client/platforms/anthropic.ts index bf8faf837..79aaf72b6 100644 --- a/app/client/platforms/anthropic.ts +++ b/app/client/platforms/anthropic.ts @@ -12,6 +12,7 @@ import { import Locale from "../../locales"; import { prettyObject } from "@/app/utils/format"; import { getMessageTextContent, isVisionModel } from "@/app/utils"; +import { preProcessImageContent } from "@/app/utils/chat"; import { cloudflareAIGatewayUrl } from "@/app/utils/cloudflare"; export type MultiBlockContent = { @@ -93,7 +94,12 @@ export class ClaudeApi implements LLMApi { }, }; - const messages = [...options.messages]; + // try get base64image from local cache image_url + const messages = []; + for (const v of options.messages) { + const content = await preProcessImageContent(v.content); + messages.push({ role: v.role, content }); + } const keys = ["system", "user"]; @@ -135,6 +141,7 @@ export class ClaudeApi implements LLMApi { content: content .filter((v) => v.image_url || v.text) .map(({ type, text, image_url }) => { + console.log("process message", type, text, image_url); if (type === "text") { return { type, diff --git a/app/client/platforms/google.ts b/app/client/platforms/google.ts index 8acde1a83..4a23211a3 100644 --- a/app/client/platforms/google.ts +++ b/app/client/platforms/google.ts @@ -14,6 +14,7 @@ import { getMessageImages, isVisionModel, } from "@/app/utils"; +import { preProcessImageContent } from "@/app/utils/chat"; export class GeminiProApi implements LLMApi { path(path: string): string { @@ -56,7 +57,14 @@ export class GeminiProApi implements LLMApi { async chat(options: ChatOptions): Promise { const apiClient = this; let multimodal = false; - const messages = options.messages.map((v) => { + + // try get base64image from local cache image_url + const _messages = []; + for (const v of options.messages) { + const content = await preProcessImageContent(v.content); + _messages.push({ role: v.role, content }); + } + const messages = _messages.map((v) => { let parts: any[] = [{ text: getMessageTextContent(v) }]; if (isVisionModel(options.config.model)) { const images = getMessageImages(v); diff --git a/app/client/platforms/openai.ts b/app/client/platforms/openai.ts index 98851c224..72277575f 100644 --- a/app/client/platforms/openai.ts +++ b/app/client/platforms/openai.ts @@ -11,6 +11,7 @@ import { } from "@/app/constant"; import { useAccessStore, useAppConfig, useChatStore } from "@/app/store"; import { collectModelsWithDefaultModel } from "@/app/utils/model"; +import { preProcessImageContent } from "@/app/utils/chat"; import { cloudflareAIGatewayUrl } from "@/app/utils/cloudflare"; import { @@ -105,10 +106,13 @@ export class ChatGPTApi implements LLMApi { async chat(options: ChatOptions) { const visionModel = isVisionModel(options.config.model); - const messages = options.messages.map((v) => ({ - role: v.role, - content: visionModel ? v.content : getMessageTextContent(v), - })); + const messages = []; + for (const v of options.messages) { + const content = visionModel + ? await preProcessImageContent(v.content) + : getMessageTextContent(v); + messages.push({ role: v.role, content }); + } const modelConfig = { ...useAppConfig.getState().modelConfig, diff --git a/app/components/chat.tsx b/app/components/chat.tsx index f5e6788fa..08bcd04fd 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -61,7 +61,7 @@ import { isVisionModel, } from "../utils"; -import { compressImage } from "@/app/utils/chat"; +import { uploadImage as uploadImageRemote } from "@/app/utils/chat"; import dynamic from "next/dynamic"; @@ -1167,7 +1167,7 @@ function _Chat() { ...(await new Promise((res, rej) => { setUploading(true); const imagesData: string[] = []; - compressImage(file, 256 * 1024) + uploadImageRemote(file) .then((dataUrl) => { imagesData.push(dataUrl); setUploading(false); @@ -1209,7 +1209,7 @@ function _Chat() { const imagesData: string[] = []; for (let i = 0; i < files.length; i++) { const file = event.target.files[i]; - compressImage(file, 256 * 1024) + uploadImageRemote(file) .then((dataUrl) => { imagesData.push(dataUrl); if ( diff --git a/app/constant.ts b/app/constant.ts index ffbcca53f..f5d3c77f4 100644 --- a/app/constant.ts +++ b/app/constant.ts @@ -21,6 +21,9 @@ export const BYTEDANCE_BASE_URL = "https://ark.cn-beijing.volces.com"; export const ALIBABA_BASE_URL = "https://dashscope.aliyuncs.com/api/"; +export const CACHE_URL_PREFIX = "/api/cache"; +export const UPLOAD_URL = `${CACHE_URL_PREFIX}/upload`; + export enum Path { Home = "/", Chat = "/chat", @@ -239,7 +242,7 @@ const baiduModels = [ "ernie-speed-128k", "ernie-speed-8k", "ernie-lite-8k", - "ernie-tiny-8k" + "ernie-tiny-8k", ]; const bytedanceModels = [ diff --git a/app/utils/chat.ts b/app/utils/chat.ts index 991d06b73..69e18920c 100644 --- a/app/utils/chat.ts +++ b/app/utils/chat.ts @@ -1,4 +1,5 @@ -import heic2any from "heic2any"; +import { CACHE_URL_PREFIX, UPLOAD_URL } from "@/app/constant"; +// import heic2any from "heic2any"; export function compressImage(file: File, maxSize: number): Promise { return new Promise((resolve, reject) => { @@ -40,6 +41,7 @@ export function compressImage(file: File, maxSize: number): Promise { reader.onerror = reject; if (file.type.includes("heic")) { + const heic2any = require("heic2any"); heic2any({ blob: file, toType: "image/jpeg" }) .then((blob) => { reader.readAsDataURL(blob as Blob); @@ -52,3 +54,78 @@ export function compressImage(file: File, maxSize: number): Promise { reader.readAsDataURL(file); }); } + +export async function preProcessImageContent( + content: RequestMessage["content"], +) { + if (typeof content === "string") { + return content; + } + const result = []; + for (const part of content) { + if (part?.type == "image_url" && part?.image_url?.url) { + const url = await cacheImageToBase64Image(part?.image_url?.url); + result.push({ type: part.type, image_url: { url } }); + } else { + result.push({ ...part }); + } + } + return result; +} + +const imageCaches = {}; +export function cacheImageToBase64Image(imageUrl: string) { + if (imageUrl.includes(CACHE_URL_PREFIX)) { + if (!imageCaches[imageUrl]) { + const reader = new FileReader(); + return fetch(imageUrl, { + method: "GET", + mode: "cors", + credentials: "include", + }) + .then((res) => res.blob()) + .then( + (blob) => (imageCaches[imageUrl] = compressImage(blob, 256 * 1024)), + ); // compressImage + } + return Promise.resolve(imageCaches[imageUrl]); + } + return imageUrl; +} + +export function base64Image2Blob(base64Data: string, contentType: string) { + const byteCharacters = atob(base64Data); + const byteNumbers = new Array(byteCharacters.length); + for (let i = 0; i < byteCharacters.length; i++) { + byteNumbers[i] = byteCharacters.charCodeAt(i); + } + const byteArray = new Uint8Array(byteNumbers); + return new Blob([byteArray], { type: contentType }); +} + +export function uploadImage(file: File): Promise { + const body = new FormData(); + body.append("file", file); + return fetch(UPLOAD_URL, { + method: "post", + body, + mode: "cors", + credentials: "include", + }) + .then((res) => res.json()) + .then((res) => { + console.log("res", res); + if (res?.code == 0 && res?.data) { + return res?.data; + } + throw Error(`upload Error: ${res?.msg}`); + }); +} + +export function removeImage(imageUrl: string) { + return fetch(imageUrl, { + method: "DELETE", + mode: "cors", + credentials: "include", + }); +} diff --git a/public/serviceWorker.js b/public/serviceWorker.js index f5a24b701..c58b2cc5a 100644 --- a/public/serviceWorker.js +++ b/public/serviceWorker.js @@ -1,10 +1,13 @@ const CHATGPT_NEXT_WEB_CACHE = "chatgpt-next-web-cache"; +const CHATGPT_NEXT_WEB_FILE_CACHE = "chatgpt-next-web-file"; +let a="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";let nanoid=(e=21)=>{let t="",r=crypto.getRandomValues(new Uint8Array(e));for(let n=0;n {}); +async function upload(request, url) { + const formData = await request.formData() + const file = formData.getAll('file')[0] + let ext = file.name.split('.').pop() + if (ext === 'blob') { + ext = file.type.split('/').pop() + } + const fileUrl = `${url.origin}/api/cache/${nanoid()}.${ext}` + // console.debug('file', file, fileUrl, request) + const cache = await caches.open(CHATGPT_NEXT_WEB_FILE_CACHE) + await cache.put(new Request(fileUrl), new Response(file, { + headers: { + 'content-type': file.type, + 'content-length': file.size, + 'cache-control': 'no-cache', // file already store in disk + 'server': 'ServiceWorker', + } + })) + return Response.json({ code: 0, data: fileUrl }) +} + +async function remove(request, url) { + const cache = await caches.open(CHATGPT_NEXT_WEB_FILE_CACHE) + const res = await cache.delete(request.url) + return Response.json({ code: 0 }) +} + +self.addEventListener("fetch", (e) => { + const url = new URL(e.request.url); + if (/^\/api\/cache/.test(url.pathname)) { + if ('GET' == e.request.method) { + e.respondWith(caches.match(e.request)) + } + if ('POST' == e.request.method) { + e.respondWith(upload(e.request, url)) + } + if ('DELETE' == e.request.method) { + e.respondWith(remove(e.request, url)) + } + } +}); + diff --git a/public/serviceWorkerRegister.js b/public/serviceWorkerRegister.js index 8405f21aa..735ab9a13 100644 --- a/public/serviceWorkerRegister.js +++ b/public/serviceWorkerRegister.js @@ -2,8 +2,15 @@ if ('serviceWorker' in navigator) { window.addEventListener('load', function () { navigator.serviceWorker.register('/serviceWorker.js').then(function (registration) { console.log('ServiceWorker registration successful with scope: ', registration.scope); + registration.update().then(res => { + console.log('ServiceWorker registration update: ', res); + }); }, function (err) { console.error('ServiceWorker registration failed: ', err); }); + navigator.serviceWorker.addEventListener('controllerchange', function() { + console.log('ServiceWorker controllerchange '); + window.location.reload(true); + }); }); -} \ No newline at end of file +} From 1610b480af687eca3dfefa4bece28ab339c182e7 Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Fri, 19 Jul 2024 13:54:33 +0800 Subject: [PATCH 3/9] remove console.log --- app/client/platforms/anthropic.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/app/client/platforms/anthropic.ts b/app/client/platforms/anthropic.ts index 79aaf72b6..fd82db202 100644 --- a/app/client/platforms/anthropic.ts +++ b/app/client/platforms/anthropic.ts @@ -141,7 +141,6 @@ export class ClaudeApi implements LLMApi { content: content .filter((v) => v.image_url || v.text) .map(({ type, text, image_url }) => { - console.log("process message", type, text, image_url); if (type === "text") { return { type, From 7237d33be38c1b51fc867d047e9f599429bd8eec Mon Sep 17 00:00:00 2001 From: Dogtiti <499960698@qq.com> Date: Fri, 19 Jul 2024 14:55:47 +0800 Subject: [PATCH 4/9] fix: ts type --- app/client/platforms/anthropic.ts | 3 +-- app/client/platforms/google.ts | 2 +- app/client/platforms/openai.ts | 2 +- app/utils/chat.ts | 14 ++++++++------ 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/app/client/platforms/anthropic.ts b/app/client/platforms/anthropic.ts index 79aaf72b6..0c15bf8b2 100644 --- a/app/client/platforms/anthropic.ts +++ b/app/client/platforms/anthropic.ts @@ -3,7 +3,6 @@ import { ChatOptions, getHeaders, LLMApi, MultimodalContent } from "../api"; import { useAccessStore, useAppConfig, useChatStore } from "@/app/store"; import { getClientConfig } from "@/app/config/client"; import { DEFAULT_API_HOST } from "@/app/constant"; -import { RequestMessage } from "@/app/typing"; import { EventStreamContentType, fetchEventSource, @@ -95,7 +94,7 @@ export class ClaudeApi implements LLMApi { }; // try get base64image from local cache image_url - const messages = []; + const messages: ChatOptions["messages"] = []; for (const v of options.messages) { const content = await preProcessImageContent(v.content); messages.push({ role: v.role, content }); diff --git a/app/client/platforms/google.ts b/app/client/platforms/google.ts index 4a23211a3..753a768c6 100644 --- a/app/client/platforms/google.ts +++ b/app/client/platforms/google.ts @@ -59,7 +59,7 @@ export class GeminiProApi implements LLMApi { let multimodal = false; // try get base64image from local cache image_url - const _messages = []; + const _messages: ChatOptions["messages"] = []; for (const v of options.messages) { const content = await preProcessImageContent(v.content); _messages.push({ role: v.role, content }); diff --git a/app/client/platforms/openai.ts b/app/client/platforms/openai.ts index 72277575f..680125fe6 100644 --- a/app/client/platforms/openai.ts +++ b/app/client/platforms/openai.ts @@ -106,7 +106,7 @@ export class ChatGPTApi implements LLMApi { async chat(options: ChatOptions) { const visionModel = isVisionModel(options.config.model); - const messages = []; + const messages: ChatOptions["messages"] = []; for (const v of options.messages) { const content = visionModel ? await preProcessImageContent(v.content) diff --git a/app/utils/chat.ts b/app/utils/chat.ts index 69e18920c..cde88043e 100644 --- a/app/utils/chat.ts +++ b/app/utils/chat.ts @@ -1,7 +1,8 @@ import { CACHE_URL_PREFIX, UPLOAD_URL } from "@/app/constant"; // import heic2any from "heic2any"; +import { RequestMessage } from "@/app/client/api"; -export function compressImage(file: File, maxSize: number): Promise { +export function compressImage(file: Blob, maxSize: number): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (readerEvent: any) => { @@ -43,10 +44,10 @@ export function compressImage(file: File, maxSize: number): Promise { if (file.type.includes("heic")) { const heic2any = require("heic2any"); heic2any({ blob: file, toType: "image/jpeg" }) - .then((blob) => { - reader.readAsDataURL(blob as Blob); + .then((blob: Blob) => { + reader.readAsDataURL(blob); }) - .catch((e) => { + .catch((e: any) => { reject(e); }); } @@ -73,7 +74,7 @@ export async function preProcessImageContent( return result; } -const imageCaches = {}; +const imageCaches: Record = {}; export function cacheImageToBase64Image(imageUrl: string) { if (imageUrl.includes(CACHE_URL_PREFIX)) { if (!imageCaches[imageUrl]) { @@ -85,7 +86,8 @@ export function cacheImageToBase64Image(imageUrl: string) { }) .then((res) => res.blob()) .then( - (blob) => (imageCaches[imageUrl] = compressImage(blob, 256 * 1024)), + async (blob) => + (imageCaches[imageUrl] = await compressImage(blob, 256 * 1024)), ); // compressImage } return Promise.resolve(imageCaches[imageUrl]); From a765237441e1ac267138d626e5b831a27fa38bdf Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Fri, 19 Jul 2024 15:40:14 +0800 Subject: [PATCH 5/9] reload page when sw installed. --- public/serviceWorkerRegister.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/public/serviceWorkerRegister.js b/public/serviceWorkerRegister.js index 735ab9a13..4d0c5a697 100644 --- a/public/serviceWorkerRegister.js +++ b/public/serviceWorkerRegister.js @@ -1,7 +1,17 @@ if ('serviceWorker' in navigator) { - window.addEventListener('load', function () { + window.addEventListener('DOMContentLoaded', function () { navigator.serviceWorker.register('/serviceWorker.js').then(function (registration) { console.log('ServiceWorker registration successful with scope: ', registration.scope); + const sw = registration.installing || registration.waiting + if (sw) { + sw.onstatechange = function() { + if (sw.state === 'installed') { + // SW installed. Reload for SW intercept serving SW-enabled page. + console.log('ServiceWorker installed reload page'); + window.location.reload(); + } + } + } registration.update().then(res => { console.log('ServiceWorker registration update: ', res); }); From 052004d70ed6702fe7942c85ba766ff11e6ab453 Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Fri, 19 Jul 2024 16:03:22 +0800 Subject: [PATCH 6/9] using compressImage when serviceWorker register error --- app/utils/chat.ts | 4 ++++ public/serviceWorkerRegister.js | 1 + 2 files changed, 5 insertions(+) diff --git a/app/utils/chat.ts b/app/utils/chat.ts index cde88043e..77e9ee69b 100644 --- a/app/utils/chat.ts +++ b/app/utils/chat.ts @@ -106,6 +106,10 @@ export function base64Image2Blob(base64Data: string, contentType: string) { } export function uploadImage(file: File): Promise { + if (!window._SW_ENABLED) { + // if serviceWorker register error, using compressImage + return compressImage(file, 256 * 1024); + } const body = new FormData(); body.append("file", file); return fetch(UPLOAD_URL, { diff --git a/public/serviceWorkerRegister.js b/public/serviceWorkerRegister.js index 4d0c5a697..737205bb8 100644 --- a/public/serviceWorkerRegister.js +++ b/public/serviceWorkerRegister.js @@ -15,6 +15,7 @@ if ('serviceWorker' in navigator) { registration.update().then(res => { console.log('ServiceWorker registration update: ', res); }); + window._SW_ENABLED = true }, function (err) { console.error('ServiceWorker registration failed: ', err); }); From 57831d48806dcb579e86ff66802e60374f90fae1 Mon Sep 17 00:00:00 2001 From: yaway Date: Fri, 19 Jul 2024 16:31:12 +0800 Subject: [PATCH 7/9] Update and rename README_JP.md to README_JA.md --- README_JA.md | 605 +++++++++++++++++++++++++++++++++++++++++++++++++++ README_JP.md | 286 ------------------------ 2 files changed, 605 insertions(+), 286 deletions(-) create mode 100644 README_JA.md delete mode 100644 README_JP.md diff --git a/README_JA.md b/README_JA.md new file mode 100644 index 000000000..f2ac1f286 --- /dev/null +++ b/README_JA.md @@ -0,0 +1,605 @@ +
+プレビュー + +

NextChat

+ +ワンクリックで無料であなた専用の ChatGPT ウェブアプリをデプロイ。GPT3、GPT4 & Gemini Pro モデルをサポート。 + +[企業版](#企業版) / [デモ](https://chat-gpt-next-web.vercel.app/) / [フィードバック](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [Discordに参加](https://discord.gg/zrhvHCr79N) + +[Zeaburでデプロイ](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FChatGPTNextWeb%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&project-name=nextchat&repository-name=NextChat) [Zeaburでデプロイ](https://zeabur.com/templates/ZBUEFA) [Gitpodで開く](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) + + +
+ +## 企業版 + +あなたの会社のプライベートデプロイとカスタマイズのニーズに応える +- **ブランドカスタマイズ**:企業向けに特別に設計された VI/UI、企業ブランドイメージとシームレスにマッチ +- **リソース統合**:企業管理者が数十種類のAIリソースを統一管理、チームメンバーはすぐに使用可能 +- **権限管理**:メンバーの権限、リソースの権限、ナレッジベースの権限を明確にし、企業レベルのAdmin Panelで統一管理 +- **知識の統合**:企業内部のナレッジベースとAI機能を結びつけ、汎用AIよりも企業自身の業務ニーズに近づける +- **セキュリティ監査**:機密質問を自動的にブロックし、すべての履歴対話を追跡可能にし、AIも企業の情報セキュリティ基準に従わせる +- **プライベートデプロイ**:企業レベルのプライベートデプロイ、主要なプライベートクラウドデプロイをサポートし、データのセキュリティとプライバシーを保護 +- **継続的な更新**:マルチモーダル、エージェントなどの最先端機能を継続的に更新し、常に最新であり続ける + +企業版のお問い合わせ: **business@nextchat.dev** + + +## 开始使用 + +1. 准备好你的 [OpenAI API Key](https://platform.openai.com/account/api-keys); +2. 点击右侧按钮开始部署: + [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&env=GOOGLE_API_KEY&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web),直接使用 Github 账号登录即可,记得在环境变量页填入 API Key 和[页面访问密码](#配置页面访问密码) CODE; +3. 部署完毕后,即可开始使用; +4. (可选)[绑定自定义域名](https://vercel.com/docs/concepts/projects/domains/add-a-domain):Vercel 分配的域名 DNS 在某些区域被污染了,绑定自定义域名即可直连。 + + +## 始めに + +1. [OpenAI API Key](https://platform.openai.com/account/api-keys)を準備する; +2. 右側のボタンをクリックしてデプロイを開始: + [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&env=GOOGLE_API_KEY&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web) 、GitHubアカウントで直接ログインし、環境変数ページにAPI Keyと[ページアクセスパスワード](#設定ページアクセスパスワード) CODEを入力してください; +3. デプロイが完了したら、すぐに使用を開始できます; +4. (オプション)[カスタムドメインをバインド](https://vercel.com/docs/concepts/projects/domains/add-a-domain):Vercelが割り当てたドメインDNSは一部の地域で汚染されているため、カスタムドメインをバインドすると直接接続できます。 + +
+ +![メインインターフェース](./docs/images/cover.png) + +
+ + +## 保持更新 + +如果你按照上述步骤一键部署了自己的项目,可能会发现总是提示“存在更新”的问题,这是由于 Vercel 会默认为你创建一个新项目而不是 fork 本项目,这会导致无法正确地检测更新。 +推荐你按照下列步骤重新部署: + +- 删除掉原先的仓库; +- 使用页面右上角的 fork 按钮,fork 本项目; +- 在 Vercel 重新选择并部署,[请查看详细教程](./docs/vercel-cn.md#如何新建项目)。 + + + +## 更新を維持する + +もし上記の手順に従ってワンクリックでプロジェクトをデプロイした場合、「更新があります」というメッセージが常に表示されることがあります。これは、Vercel がデフォルトで新しいプロジェクトを作成するためで、本プロジェクトをフォークしていないことが原因です。そのため、正しく更新を検出できません。 + +以下の手順に従って再デプロイすることをお勧めします: + +- 元のリポジトリを削除する +- ページ右上のフォークボタンを使って、本プロジェクトをフォークする +- Vercel で再度選択してデプロイする、[詳細な手順はこちらを参照してください](./docs/vercel-ja.md)。 + + + + +### 打开自动更新 + +> 如果你遇到了 Upstream Sync 执行错误,请手动 Sync Fork 一次! + +当你 fork 项目之后,由于 Github 的限制,需要手动去你 fork 后的项目的 Actions 页面启用 Workflows,并启用 Upstream Sync Action,启用之后即可开启每小时定时自动更新: + +![自动更新](./docs/images/enable-actions.jpg) + +![启用自动更新](./docs/images/enable-actions-sync.jpg) + + + +### 自動更新を開く + +> Upstream Sync の実行エラーが発生した場合は、手動でフォークを同期してください! + +プロジェクトをフォークした後、GitHub の制限により、フォーク後のプロジェクトの Actions ページで Workflows を手動で有効にし、Upstream Sync Action を有効にする必要があります。有効化後、毎時の定期自動更新が可能になります: + +![自動更新](./docs/images/enable-actions.jpg) + +![自動更新を有効にする](./docs/images/enable-actions-sync.jpg) + + +### 手动更新代码 + +如果你想让手动立即更新,可以查看 [Github 的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) 了解如何让 fork 的项目与上游代码同步。 + +你可以 star/watch 本项目或者 follow 作者来及时获得新功能更新通知。 + + +### 手動でコードを更新する + +手動で即座に更新したい場合は、[GitHub のドキュメント](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork)を参照して、フォークしたプロジェクトを上流のコードと同期する方法を確認してください。 + +このプロジェクトをスターまたはウォッチしたり、作者をフォローすることで、新機能の更新通知をすぐに受け取ることができます。 + + +## 配置页面访问密码 + +> 配置密码后,用户需要在设置页手动填写访问码才可以正常聊天,否则会通过消息提示未授权状态。 + +> **警告**:请务必将密码的位数设置得足够长,最好 7 位以上,否则[会被爆破](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/518)。 + +本项目提供有限的权限控制功能,请在 Vercel 项目控制面板的环境变量页增加名为 `CODE` 的环境变量,值为用英文逗号分隔的自定义密码: + +``` +code1,code2,code3 +``` + +增加或修改该环境变量后,请**重新部署**项目使改动生效。 + + + + +## ページアクセスパスワードを設定する + +> パスワードを設定すると、ユーザーは設定ページでアクセスコードを手動で入力しない限り、通常のチャットができず、未承認の状態であることを示すメッセージが表示されます。 + +> **警告**:パスワードの桁数は十分に長く設定してください。7桁以上が望ましいです。さもないと、[ブルートフォース攻撃を受ける可能性があります](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/518)。 + +このプロジェクトは限られた権限管理機能を提供しています。Vercel プロジェクトのコントロールパネルで、環境変数ページに `CODE` という名前の環境変数を追加し、値をカンマで区切ったカスタムパスワードに設定してください: + +``` +code1,code2,code3 +``` + +この環境変数を追加または変更した後、**プロジェクトを再デプロイ**して変更を有効にしてください。 + + + +## 环境变量 + +> 本项目大多数配置项都通过环境变量来设置,教程:[如何修改 Vercel 环境变量](./docs/vercel-cn.md)。 + +### `OPENAI_API_KEY` (必填项) + +OpanAI 密钥,你在 openai 账户页面申请的 api key,使用英文逗号隔开多个 key,这样可以随机轮询这些 key。 + +### `CODE` (可选) + +访问密码,可选,可以使用逗号隔开多个密码。 + +**警告**:如果不填写此项,则任何人都可以直接使用你部署后的网站,可能会导致你的 token 被急速消耗完毕,建议填写此选项。 + +### `BASE_URL` (可选) + +> Default: `https://api.openai.com` + +> Examples: `http://your-openai-proxy.com` + +OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填写此选项。 + +> 如果遇到 ssl 证书问题,请将 `BASE_URL` 的协议设置为 http。 + +### `OPENAI_ORG_ID` (可选) + +指定 OpenAI 中的组织 ID。 + +### `AZURE_URL` (可选) + +> 形如:https://{azure-resource-url}/openai/deployments/{deploy-name} +> 如果你已经在`CUSTOM_MODELS`中参考`displayName`的方式配置了{deploy-name},那么可以从`AZURE_URL`中移除`{deploy-name}` + +Azure 部署地址。 + +### `AZURE_API_KEY` (可选) + +Azure 密钥。 + +### `AZURE_API_VERSION` (可选) + +Azure Api 版本,你可以在这里找到:[Azure 文档](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)。 + +### `GOOGLE_API_KEY` (可选) + +Google Gemini Pro 密钥. + +### `GOOGLE_URL` (可选) + +Google Gemini Pro Api Url. + +### `ANTHROPIC_API_KEY` (可选) + +anthropic claude Api Key. + +### `ANTHROPIC_API_VERSION` (可选) + +anthropic claude Api version. + +### `ANTHROPIC_URL` (可选) + +anthropic claude Api Url. + +### `BAIDU_API_KEY` (可选) + +Baidu Api Key. + +### `BAIDU_SECRET_KEY` (可选) + +Baidu Secret Key. + +### `BAIDU_URL` (可选) + +Baidu Api Url. + +### `BYTEDANCE_API_KEY` (可选) + +ByteDance Api Key. + +### `BYTEDANCE_URL` (可选) + +ByteDance Api Url. + +### `ALIBABA_API_KEY` (可选) + +阿里云(千问)Api Key. + +### `ALIBABA_URL` (可选) + +阿里云(千问)Api Url. + +### `HIDE_USER_API_KEY` (可选) + +如果你不想让用户自行填入 API Key,将此环境变量设置为 1 即可。 + +### `DISABLE_GPT4` (可选) + +如果你不想让用户使用 GPT-4,将此环境变量设置为 1 即可。 + +### `ENABLE_BALANCE_QUERY` (可选) + +如果你想启用余额查询功能,将此环境变量设置为 1 即可。 + +### `DISABLE_FAST_LINK` (可选) + +如果你想禁用从链接解析预制设置,将此环境变量设置为 1 即可。 + +### `WHITE_WEBDEV_ENDPOINTS` (可选) + +如果你想增加允许访问的webdav服务地址,可以使用该选项,格式要求: +- 每一个地址必须是一个完整的 endpoint +> `https://xxxx/xxx` +- 多个地址以`,`相连 + +### `CUSTOM_MODELS` (可选) + +> 示例:`+qwen-7b-chat,+glm-6b,-gpt-3.5-turbo,gpt-4-1106-preview=gpt-4-turbo` 表示增加 `qwen-7b-chat` 和 `glm-6b` 到模型列表,而从列表中删除 `gpt-3.5-turbo`,并将 `gpt-4-1106-preview` 模型名字展示为 `gpt-4-turbo`。 +> 如果你想先禁用所有模型,再启用指定模型,可以使用 `-all,+gpt-3.5-turbo`,则表示仅启用 `gpt-3.5-turbo` + +用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。 + +在Azure的模式下,支持使用`modelName@azure=deploymentName`的方式配置模型名称和部署名称(deploy-name) +> 示例:`+gpt-3.5-turbo@azure=gpt35`这个配置会在模型列表显示一个`gpt35(Azure)`的选项 + +在ByteDance的模式下,支持使用`modelName@bytedance=deploymentName`的方式配置模型名称和部署名称(deploy-name) +> 示例: `+Doubao-lite-4k@bytedance=ep-xxxxx-xxx`这个配置会在模型列表显示一个`Doubao-lite-4k(ByteDance)`的选项 + + +### `DEFAULT_MODEL` (可选) + +更改默认模型 + +### `DEFAULT_INPUT_TEMPLATE` (可选) + +自定义默认的 template,用于初始化『设置』中的『用户输入预处理』配置项 + + + +## 環境変数 + +> 本プロジェクトのほとんどの設定は環境変数で行います。チュートリアル:[Vercel の環境変数を変更する方法](./docs/vercel-cn.md)。 + +### `OPENAI_API_KEY` (必須) + +OpenAI の API キー。OpenAI アカウントページで申請したキーをカンマで区切って複数設定できます。これにより、ランダムにキーが選択されます。 + +### `CODE` (オプション) + +アクセスパスワード。カンマで区切って複数設定可能。 + +**警告**:この項目を設定しないと、誰でもデプロイしたウェブサイトを利用でき、トークンが急速に消耗する可能性があるため、設定をお勧めします。 + +### `BASE_URL` (オプション) + +> デフォルト: `https://api.openai.com` + +> 例: `http://your-openai-proxy.com` + +OpenAI API のプロキシ URL。手動で OpenAI API のプロキシを設定している場合はこのオプションを設定してください。 + +> SSL 証明書の問題がある場合は、`BASE_URL` のプロトコルを http に設定してください。 + +### `OPENAI_ORG_ID` (オプション) + +OpenAI の組織 ID を指定します。 + +### `AZURE_URL` (オプション) + +> 形式: https://{azure-resource-url}/openai/deployments/{deploy-name} +> `CUSTOM_MODELS` で `displayName` 形式で {deploy-name} を設定した場合、`AZURE_URL` から {deploy-name} を省略できます。 + +Azure のデプロイ URL。 + +### `AZURE_API_KEY` (オプション) + +Azure の API キー。 + +### `AZURE_API_VERSION` (オプション) + +Azure API バージョン。[Azure ドキュメント](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)で確認できます。 + +### `GOOGLE_API_KEY` (オプション) + +Google Gemini Pro API キー。 + +### `GOOGLE_URL` (オプション) + +Google Gemini Pro API の URL。 + +### `ANTHROPIC_API_KEY` (オプション) + +Anthropic Claude API キー。 + +### `ANTHROPIC_API_VERSION` (オプション) + +Anthropic Claude API バージョン。 + +### `ANTHROPIC_URL` (オプション) + +Anthropic Claude API の URL。 + +### `BAIDU_API_KEY` (オプション) + +Baidu API キー。 + +### `BAIDU_SECRET_KEY` (オプション) + +Baidu シークレットキー。 + +### `BAIDU_URL` (オプション) + +Baidu API の URL。 + +### `BYTEDANCE_API_KEY` (オプション) + +ByteDance API キー。 + +### `BYTEDANCE_URL` (オプション) + +ByteDance API の URL。 + +### `ALIBABA_API_KEY` (オプション) + +アリババ(千问)API キー。 + +### `ALIBABA_URL` (オプション) + +アリババ(千问)API の URL。 + +### `HIDE_USER_API_KEY` (オプション) + +ユーザーが API キーを入力できないようにしたい場合は、この環境変数を 1 に設定します。 + +### `DISABLE_GPT4` (オプション) + +ユーザーが GPT-4 を使用できないようにしたい場合は、この環境変数を 1 に設定します。 + +### `ENABLE_BALANCE_QUERY` (オプション) + +バランスクエリ機能を有効にしたい場合は、この環境変数を 1 に設定します。 + +### `DISABLE_FAST_LINK` (オプション) + +リンクからのプリセット設定解析を無効にしたい場合は、この環境変数を 1 に設定します。 + +### `WHITE_WEBDEV_ENDPOINTS` (オプション) + +アクセス許可を与える WebDAV サービスのアドレスを追加したい場合、このオプションを使用します。フォーマット要件: +- 各アドレスは完全なエンドポイントでなければなりません。 +> `https://xxxx/xxx` +- 複数のアドレスは `,` で接続します。 + +### `CUSTOM_MODELS` (オプション) + +> 例:`+qwen-7b-chat,+glm-6b,-gpt-3.5-turbo,gpt-4-1106-preview=gpt-4-turbo` は `qwen-7b-chat` と `glm-6b` をモデルリストに追加し、`gpt-3.5-turbo` を削除し、`gpt-4-1106-preview` のモデル名を `gpt-4-turbo` として表示します。 +> すべてのモデルを無効にし、特定のモデルを有効にしたい場合は、`-all,+gpt-3.5-turbo` を使用します。これは `gpt-3.5-turbo` のみを有効にすることを意味します。 + +モデルリストを管理します。`+` でモデルを追加し、`-` でモデルを非表示にし、`モデル名=表示名` でモデルの表示名をカスタマイズし、カンマで区切ります。 + +Azure モードでは、`modelName@azure=deploymentName` 形式でモデル名とデプロイ名(deploy-name)を設定できます。 +> 例:`+gpt-3.5-turbo@azure=gpt35` この設定でモデルリストに `gpt35(Azure)` のオプションが表示されます。 + +ByteDance モードでは、`modelName@bytedance=deploymentName` 形式でモデル名とデプロイ名(deploy-name)を設定できます。 +> 例: `+Doubao-lite-4k@bytedance=ep-xxxxx-xxx` この設定でモデルリストに `Doubao-lite-4k(ByteDance)` のオプションが表示されます。 + +### `DEFAULT_MODEL` (オプション) + +デフォルトのモデルを変更します。 + +### `DEFAULT_INPUT_TEMPLATE` (オプション) + +『設定』の『ユーザー入力前処理』の初期設定に使用するテンプレートをカスタマイズします。 + + + + +## 开发 + +点击下方按钮,开始二次开发: + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) + +在开始写代码之前,需要在项目根目录新建一个 `.env.local` 文件,里面填入环境变量: + +``` +OPENAI_API_KEY= + +# 中国大陆用户,可以使用本项目自带的代理进行开发,你也可以自由选择其他代理地址 +BASE_URL=https://b.nextweb.fun/api/proxy +``` + +## 開発 + +下のボタンをクリックして二次開発を開始してください: + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) + +コードを書く前に、プロジェクトのルートディレクトリに `.env.local` ファイルを新規作成し、環境変数を記入します: + +``` +OPENAI_API_KEY= +``` + +### 本地开发 + +1. 安装 nodejs 18 和 yarn,具体细节请询问 ChatGPT; +2. 执行 `yarn install && yarn dev` 即可。⚠️ 注意:此命令仅用于本地开发,不要用于部署! +3. 如果你想本地部署,请使用 `yarn install && yarn build && yarn start` 命令,你可以配合 pm2 来守护进程,防止被杀死,详情询问 ChatGPT。 + +### ローカル開発 + +1. Node.js 18 と Yarn をインストールします。具体的な方法は ChatGPT にお尋ねください。 +2. `yarn install && yarn dev` を実行します。⚠️ 注意:このコマンドはローカル開発用であり、デプロイには使用しないでください。 +3. ローカルでデプロイしたい場合は、`yarn install && yarn build && yarn start` コマンドを使用してください。プロセスを守るために pm2 を使用することもできます。詳細は ChatGPT にお尋ねください。 + + +## 部署 + +### 容器部署 (推荐) + +> Docker 版本需要在 20 及其以上,否则会提示找不到镜像。 + +> ⚠️ 注意:docker 版本在大多数时间都会落后最新的版本 1 到 2 天,所以部署后会持续出现“存在更新”的提示,属于正常现象。 + +```shell +docker pull yidadaa/chatgpt-next-web + +docker run -d -p 3000:3000 \ + -e OPENAI_API_KEY=sk-xxxx \ + -e CODE=页面访问密码 \ + yidadaa/chatgpt-next-web +``` + +你也可以指定 proxy: + +```shell +docker run -d -p 3000:3000 \ + -e OPENAI_API_KEY=sk-xxxx \ + -e CODE=页面访问密码 \ + --net=host \ + -e PROXY_URL=http://127.0.0.1:7890 \ + yidadaa/chatgpt-next-web +``` + +如果你的本地代理需要账号密码,可以使用: + +```shell +-e PROXY_URL="http://127.0.0.1:7890 user password" +``` + +如果你需要指定其他环境变量,请自行在上述命令中增加 `-e 环境变量=环境变量值` 来指定。 + + + + +## デプロイ + +### コンテナデプロイ(推奨) + +> Docker バージョンは 20 以上が必要です。それ以下だとイメージが見つからないというエラーが出ます。 + +> ⚠️ 注意:Docker バージョンは最新バージョンより 1~2 日遅れることが多いため、デプロイ後に「更新があります」の通知が出続けることがありますが、正常です。 + +```shell +docker pull yidadaa/chatgpt-next-web + +docker run -d -p 3000:3000 \ + -e OPENAI_API_KEY=sk-xxxx \ + -e CODE=ページアクセスパスワード \ + yidadaa/chatgpt-next-web +``` + +プロキシを指定することもできます: + +```shell +docker run -d -p 3000:3000 \ + -e OPENAI_API_KEY=sk-xxxx \ + -e CODE=ページアクセスパスワード \ + --net=host \ + -e PROXY_URL=http://127.0.0.1:7890 \ + yidadaa/chatgpt-next-web +``` + +ローカルプロキシがアカウントとパスワードを必要とする場合は、以下を使用できます: + +```shell +-e PROXY_URL="http://127.0.0.1:7890 user password" +``` + +他の環境変数を指定する必要がある場合は、上記のコマンドに `-e 環境変数=環境変数値` を追加して指定してください。 + + + + +### 本地部署 + +在控制台运行下方命令: + +```shell +bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/scripts/setup.sh) +``` + +⚠️ 注意:如果你安装过程中遇到了问题,请使用 docker 部署。 + + + +### ローカルデプロイ + +コンソールで以下のコマンドを実行します: + +```shell +bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/scripts/setup.sh) +``` + +⚠️ 注意:インストール中に問題が発生した場合は、Docker を使用してデプロイしてください。 + + + +## 鸣谢 + +### 捐赠者 + +> 见英文版。 + +### 贡献者 + +[见项目贡献者列表](https://github.com/Yidadaa/ChatGPT-Next-Web/graphs/contributors) + +### 相关项目 + +- [one-api](https://github.com/songquanpeng/one-api): 一站式大模型额度管理平台,支持市面上所有主流大语言模型 + + + +## 謝辞 + +### 寄付者 + +> 英語版をご覧ください。 + +### 貢献者 + +[プロジェクトの貢献者リストはこちら](https://github.com/Yidadaa/ChatGPT-Next-Web/graphs/contributors) + +### 関連プロジェクト + +- [one-api](https://github.com/songquanpeng/one-api): 一つのプラットフォームで大規模モデルのクォータ管理を提供し、市場に出回っているすべての主要な大規模言語モデルをサポートします。 + + + + +## 开源协议 + +[MIT](https://opensource.org/license/mit/) + + +## オープンソースライセンス + +[MIT](https://opensource.org/license/mit/) diff --git a/README_JP.md b/README_JP.md deleted file mode 100644 index 5400bb276..000000000 --- a/README_JP.md +++ /dev/null @@ -1,286 +0,0 @@ -
-预览 - -

NextChat

- -一键免费部署你的私人 ChatGPT 网页应用,支持 GPT3, GPT4 & Gemini Pro 模型。 - -[演示 Demo](https://chat-gpt-next-web.vercel.app/) / [反馈 Issues](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [加入 Discord](https://discord.gg/zrhvHCr79N) - -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web) - -[![Deploy on Zeabur](https://zeabur.com/button.svg)](https://zeabur.com/templates/ZBUEFA) - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) - -![主界面](./docs/images/cover.png) - -
- -## 开始使用 - -1. 准备好你的 [OpenAI API Key](https://platform.openai.com/account/api-keys); -2. 点击右侧按钮开始部署: - [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&env=GOOGLE_API_KEY&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web),直接使用 Github 账号登录即可,记得在环境变量页填入 API Key 和[页面访问密码](#配置页面访问密码) CODE; -3. 部署完毕后,即可开始使用; -4. (可选)[绑定自定义域名](https://vercel.com/docs/concepts/projects/domains/add-a-domain):Vercel 分配的域名 DNS 在某些区域被污染了,绑定自定义域名即可直连。 - -## 保持更新 - -如果你按照上述步骤一键部署了自己的项目,可能会发现总是提示“存在更新”的问题,这是由于 Vercel 会默认为你创建一个新项目而不是 fork 本项目,这会导致无法正确地检测更新。 -推荐你按照下列步骤重新部署: - -- 删除掉原先的仓库; -- 使用页面右上角的 fork 按钮,fork 本项目; -- 在 Vercel 重新选择并部署,[请查看详细教程](./docs/vercel-cn.md#如何新建项目)。 - -### 打开自动更新 - -> 如果你遇到了 Upstream Sync 执行错误,请手动 Sync Fork 一次! - -当你 fork 项目之后,由于 Github 的限制,需要手动去你 fork 后的项目的 Actions 页面启用 Workflows,并启用 Upstream Sync Action,启用之后即可开启每小时定时自动更新: - -![自动更新](./docs/images/enable-actions.jpg) - -![启用自动更新](./docs/images/enable-actions-sync.jpg) - -### 手动更新代码 - -如果你想让手动立即更新,可以查看 [Github 的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) 了解如何让 fork 的项目与上游代码同步。 - -你可以 star/watch 本项目或者 follow 作者来及时获得新功能更新通知。 - -## 配置页面访问密码 - -> 配置密码后,用户需要在设置页手动填写访问码才可以正常聊天,否则会通过消息提示未授权状态。 - -> **警告**:请务必将密码的位数设置得足够长,最好 7 位以上,否则[会被爆破](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/518)。 - -本项目提供有限的权限控制功能,请在 Vercel 项目控制面板的环境变量页增加名为 `CODE` 的环境变量,值为用英文逗号分隔的自定义密码: - -``` -code1,code2,code3 -``` - -增加或修改该环境变量后,请**重新部署**项目使改动生效。 - -## 环境变量 - -> 本项目大多数配置项都通过环境变量来设置,教程:[如何修改 Vercel 环境变量](./docs/vercel-cn.md)。 - -### `OPENAI_API_KEY` (必填项) - -OpanAI 密钥,你在 openai 账户页面申请的 api key,使用英文逗号隔开多个 key,这样可以随机轮询这些 key。 - -### `CODE` (可选) - -访问密码,可选,可以使用逗号隔开多个密码。 - -**警告**:如果不填写此项,则任何人都可以直接使用你部署后的网站,可能会导致你的 token 被急速消耗完毕,建议填写此选项。 - -### `BASE_URL` (可选) - -> Default: `https://api.openai.com` - -> Examples: `http://your-openai-proxy.com` - -OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填写此选项。 - -> 如果遇到 ssl 证书问题,请将 `BASE_URL` 的协议设置为 http。 - -### `OPENAI_ORG_ID` (可选) - -指定 OpenAI 中的组织 ID。 - -### `AZURE_URL` (可选) - -> 形如:https://{azure-resource-url}/openai/deployments/{deploy-name} -> 如果你已经在`CUSTOM_MODELS`中参考`displayName`的方式配置了{deploy-name},那么可以从`AZURE_URL`中移除`{deploy-name}` - -Azure 部署地址。 - -### `AZURE_API_KEY` (可选) - -Azure 密钥。 - -### `AZURE_API_VERSION` (可选) - -Azure Api 版本,你可以在这里找到:[Azure 文档](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)。 - -### `GOOGLE_API_KEY` (可选) - -Google Gemini Pro 密钥. - -### `GOOGLE_URL` (可选) - -Google Gemini Pro Api Url. - -### `ANTHROPIC_API_KEY` (可选) - -anthropic claude Api Key. - -### `ANTHROPIC_API_VERSION` (可选) - -anthropic claude Api version. - -### `ANTHROPIC_URL` (可选) - -anthropic claude Api Url. - -### `BAIDU_API_KEY` (可选) - -Baidu Api Key. - -### `BAIDU_SECRET_KEY` (可选) - -Baidu Secret Key. - -### `BAIDU_URL` (可选) - -Baidu Api Url. - -### `BYTEDANCE_API_KEY` (可选) - -ByteDance Api Key. - -### `BYTEDANCE_URL` (可选) - -ByteDance Api Url. - -### `ALIBABA_API_KEY` (可选) - -阿里云(千问)Api Key. - -### `ALIBABA_URL` (可选) - -阿里云(千问)Api Url. - -### `HIDE_USER_API_KEY` (可选) - -如果你不想让用户自行填入 API Key,将此环境变量设置为 1 即可。 - -### `DISABLE_GPT4` (可选) - -如果你不想让用户使用 GPT-4,将此环境变量设置为 1 即可。 - -### `ENABLE_BALANCE_QUERY` (可选) - -如果你想启用余额查询功能,将此环境变量设置为 1 即可。 - -### `DISABLE_FAST_LINK` (可选) - -如果你想禁用从链接解析预制设置,将此环境变量设置为 1 即可。 - -### `WHITE_WEBDEV_ENDPOINTS` (可选) - -如果你想增加允许访问的webdav服务地址,可以使用该选项,格式要求: -- 每一个地址必须是一个完整的 endpoint -> `https://xxxx/xxx` -- 多个地址以`,`相连 - -### `CUSTOM_MODELS` (可选) - -> 示例:`+qwen-7b-chat,+glm-6b,-gpt-3.5-turbo,gpt-4-1106-preview=gpt-4-turbo` 表示增加 `qwen-7b-chat` 和 `glm-6b` 到模型列表,而从列表中删除 `gpt-3.5-turbo`,并将 `gpt-4-1106-preview` 模型名字展示为 `gpt-4-turbo`。 -> 如果你想先禁用所有模型,再启用指定模型,可以使用 `-all,+gpt-3.5-turbo`,则表示仅启用 `gpt-3.5-turbo` - -用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。 - -在Azure的模式下,支持使用`modelName@azure=deploymentName`的方式配置模型名称和部署名称(deploy-name) -> 示例:`+gpt-3.5-turbo@azure=gpt35`这个配置会在模型列表显示一个`gpt35(Azure)`的选项 - -在ByteDance的模式下,支持使用`modelName@bytedance=deploymentName`的方式配置模型名称和部署名称(deploy-name) -> 示例: `+Doubao-lite-4k@bytedance=ep-xxxxx-xxx`这个配置会在模型列表显示一个`Doubao-lite-4k(ByteDance)`的选项 - - -### `DEFAULT_MODEL` (可选) - -更改默认模型 - -### `DEFAULT_INPUT_TEMPLATE` (可选) - -自定义默认的 template,用于初始化『设置』中的『用户输入预处理』配置项 - -## 开发 - -点击下方按钮,开始二次开发: - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) - -在开始写代码之前,需要在项目根目录新建一个 `.env.local` 文件,里面填入环境变量: - -``` -OPENAI_API_KEY= - -# 中国大陆用户,可以使用本项目自带的代理进行开发,你也可以自由选择其他代理地址 -BASE_URL=https://b.nextweb.fun/api/proxy -``` - -### 本地开发 - -1. 安装 nodejs 18 和 yarn,具体细节请询问 ChatGPT; -2. 执行 `yarn install && yarn dev` 即可。⚠️ 注意:此命令仅用于本地开发,不要用于部署! -3. 如果你想本地部署,请使用 `yarn install && yarn build && yarn start` 命令,你可以配合 pm2 来守护进程,防止被杀死,详情询问 ChatGPT。 - -## 部署 - -### 容器部署 (推荐) - -> Docker 版本需要在 20 及其以上,否则会提示找不到镜像。 - -> ⚠️ 注意:docker 版本在大多数时间都会落后最新的版本 1 到 2 天,所以部署后会持续出现“存在更新”的提示,属于正常现象。 - -```shell -docker pull yidadaa/chatgpt-next-web - -docker run -d -p 3000:3000 \ - -e OPENAI_API_KEY=sk-xxxx \ - -e CODE=页面访问密码 \ - yidadaa/chatgpt-next-web -``` - -你也可以指定 proxy: - -```shell -docker run -d -p 3000:3000 \ - -e OPENAI_API_KEY=sk-xxxx \ - -e CODE=页面访问密码 \ - --net=host \ - -e PROXY_URL=http://127.0.0.1:7890 \ - yidadaa/chatgpt-next-web -``` - -如果你的本地代理需要账号密码,可以使用: - -```shell --e PROXY_URL="http://127.0.0.1:7890 user password" -``` - -如果你需要指定其他环境变量,请自行在上述命令中增加 `-e 环境变量=环境变量值` 来指定。 - -### 本地部署 - -在控制台运行下方命令: - -```shell -bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/scripts/setup.sh) -``` - -⚠️ 注意:如果你安装过程中遇到了问题,请使用 docker 部署。 - -## 鸣谢 - -### 捐赠者 - -> 见英文版。 - -### 贡献者 - -[见项目贡献者列表](https://github.com/Yidadaa/ChatGPT-Next-Web/graphs/contributors) - -### 相关项目 - -- [one-api](https://github.com/songquanpeng/one-api): 一站式大模型额度管理平台,支持市面上所有主流大语言模型 - -## 开源协议 - -[MIT](https://opensource.org/license/mit/) From 89b9d3a7f768d0b2ff96d0da9467976d454aec2c Mon Sep 17 00:00:00 2001 From: yaway Date: Fri, 19 Jul 2024 16:41:46 +0800 Subject: [PATCH 8/9] Update README_JA.md --- README_JA.md | 307 +-------------------------------------------------- 1 file changed, 6 insertions(+), 301 deletions(-) diff --git a/README_JA.md b/README_JA.md index f2ac1f286..6b8caadae 100644 --- a/README_JA.md +++ b/README_JA.md @@ -26,15 +26,6 @@ 企業版のお問い合わせ: **business@nextchat.dev** -## 开始使用 - -1. 准备好你的 [OpenAI API Key](https://platform.openai.com/account/api-keys); -2. 点击右侧按钮开始部署: - [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&env=GOOGLE_API_KEY&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web),直接使用 Github 账号登录即可,记得在环境变量页填入 API Key 和[页面访问密码](#配置页面访问密码) CODE; -3. 部署完毕后,即可开始使用; -4. (可选)[绑定自定义域名](https://vercel.com/docs/concepts/projects/domains/add-a-domain):Vercel 分配的域名 DNS 在某些区域被污染了,绑定自定义域名即可直连。 - - ## 始めに 1. [OpenAI API Key](https://platform.openai.com/account/api-keys)を準備する; @@ -50,83 +41,35 @@ -## 保持更新 - -如果你按照上述步骤一键部署了自己的项目,可能会发现总是提示“存在更新”的问题,这是由于 Vercel 会默认为你创建一个新项目而不是 fork 本项目,这会导致无法正确地检测更新。 -推荐你按照下列步骤重新部署: - -- 删除掉原先的仓库; -- 使用页面右上角的 fork 按钮,fork 本项目; -- 在 Vercel 重新选择并部署,[请查看详细教程](./docs/vercel-cn.md#如何新建项目)。 - - - ## 更新を維持する -もし上記の手順に従ってワンクリックでプロジェクトをデプロイした場合、「更新があります」というメッセージが常に表示されることがあります。これは、Vercel がデフォルトで新しいプロジェクトを作成するためで、本プロジェクトをフォークしていないことが原因です。そのため、正しく更新を検出できません。 +もし上記の手順に従ってワンクリックでプロジェクトをデプロイした場合、「更新があります」というメッセージが常に表示されることがあります。これは、Vercel がデフォルトで新しいプロジェクトを作成するためで、本プロジェクトを fork していないことが原因です。そのため、正しく更新を検出できません。 以下の手順に従って再デプロイすることをお勧めします: - 元のリポジトリを削除する -- ページ右上のフォークボタンを使って、本プロジェクトをフォークする +- ページ右上の fork ボタンを使って、本プロジェクトを fork する - Vercel で再度選択してデプロイする、[詳細な手順はこちらを参照してください](./docs/vercel-ja.md)。 - - -### 打开自动更新 - -> 如果你遇到了 Upstream Sync 执行错误,请手动 Sync Fork 一次! - -当你 fork 项目之后,由于 Github 的限制,需要手动去你 fork 后的项目的 Actions 页面启用 Workflows,并启用 Upstream Sync Action,启用之后即可开启每小时定时自动更新: - -![自动更新](./docs/images/enable-actions.jpg) - -![启用自动更新](./docs/images/enable-actions-sync.jpg) - - - ### 自動更新を開く -> Upstream Sync の実行エラーが発生した場合は、手動でフォークを同期してください! +> Upstream Sync の実行エラーが発生した場合は、手動で Sync Fork してください! -プロジェクトをフォークした後、GitHub の制限により、フォーク後のプロジェクトの Actions ページで Workflows を手動で有効にし、Upstream Sync Action を有効にする必要があります。有効化後、毎時の定期自動更新が可能になります: +プロジェクトを fork した後、GitHub の制限により、fork 後のプロジェクトの Actions ページで Workflows を手動で有効にし、Upstream Sync Action を有効にする必要があります。有効化後、毎時の定期自動更新が可能になります: ![自動更新](./docs/images/enable-actions.jpg) ![自動更新を有効にする](./docs/images/enable-actions-sync.jpg) -### 手动更新代码 - -如果你想让手动立即更新,可以查看 [Github 的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) 了解如何让 fork 的项目与上游代码同步。 - -你可以 star/watch 本项目或者 follow 作者来及时获得新功能更新通知。 - - ### 手動でコードを更新する -手動で即座に更新したい場合は、[GitHub のドキュメント](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork)を参照して、フォークしたプロジェクトを上流のコードと同期する方法を確認してください。 +手動で即座に更新したい場合は、[GitHub のドキュメント](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork)を参照して、fork したプロジェクトを上流のコードと同期する方法を確認してください。 このプロジェクトをスターまたはウォッチしたり、作者をフォローすることで、新機能の更新通知をすぐに受け取ることができます。 -## 配置页面访问密码 - -> 配置密码后,用户需要在设置页手动填写访问码才可以正常聊天,否则会通过消息提示未授权状态。 - -> **警告**:请务必将密码的位数设置得足够长,最好 7 位以上,否则[会被爆破](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/518)。 - -本项目提供有限的权限控制功能,请在 Vercel 项目控制面板的环境变量页增加名为 `CODE` 的环境变量,值为用英文逗号分隔的自定义密码: - -``` -code1,code2,code3 -``` - -增加或修改该环境变量后,请**重新部署**项目使改动生效。 - - - ## ページアクセスパスワードを設定する @@ -143,148 +86,9 @@ code1,code2,code3 この環境変数を追加または変更した後、**プロジェクトを再デプロイ**して変更を有効にしてください。 - -## 环境变量 - -> 本项目大多数配置项都通过环境变量来设置,教程:[如何修改 Vercel 环境变量](./docs/vercel-cn.md)。 - -### `OPENAI_API_KEY` (必填项) - -OpanAI 密钥,你在 openai 账户页面申请的 api key,使用英文逗号隔开多个 key,这样可以随机轮询这些 key。 - -### `CODE` (可选) - -访问密码,可选,可以使用逗号隔开多个密码。 - -**警告**:如果不填写此项,则任何人都可以直接使用你部署后的网站,可能会导致你的 token 被急速消耗完毕,建议填写此选项。 - -### `BASE_URL` (可选) - -> Default: `https://api.openai.com` - -> Examples: `http://your-openai-proxy.com` - -OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填写此选项。 - -> 如果遇到 ssl 证书问题,请将 `BASE_URL` 的协议设置为 http。 - -### `OPENAI_ORG_ID` (可选) - -指定 OpenAI 中的组织 ID。 - -### `AZURE_URL` (可选) - -> 形如:https://{azure-resource-url}/openai/deployments/{deploy-name} -> 如果你已经在`CUSTOM_MODELS`中参考`displayName`的方式配置了{deploy-name},那么可以从`AZURE_URL`中移除`{deploy-name}` - -Azure 部署地址。 - -### `AZURE_API_KEY` (可选) - -Azure 密钥。 - -### `AZURE_API_VERSION` (可选) - -Azure Api 版本,你可以在这里找到:[Azure 文档](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)。 - -### `GOOGLE_API_KEY` (可选) - -Google Gemini Pro 密钥. - -### `GOOGLE_URL` (可选) - -Google Gemini Pro Api Url. - -### `ANTHROPIC_API_KEY` (可选) - -anthropic claude Api Key. - -### `ANTHROPIC_API_VERSION` (可选) - -anthropic claude Api version. - -### `ANTHROPIC_URL` (可选) - -anthropic claude Api Url. - -### `BAIDU_API_KEY` (可选) - -Baidu Api Key. - -### `BAIDU_SECRET_KEY` (可选) - -Baidu Secret Key. - -### `BAIDU_URL` (可选) - -Baidu Api Url. - -### `BYTEDANCE_API_KEY` (可选) - -ByteDance Api Key. - -### `BYTEDANCE_URL` (可选) - -ByteDance Api Url. - -### `ALIBABA_API_KEY` (可选) - -阿里云(千问)Api Key. - -### `ALIBABA_URL` (可选) - -阿里云(千问)Api Url. - -### `HIDE_USER_API_KEY` (可选) - -如果你不想让用户自行填入 API Key,将此环境变量设置为 1 即可。 - -### `DISABLE_GPT4` (可选) - -如果你不想让用户使用 GPT-4,将此环境变量设置为 1 即可。 - -### `ENABLE_BALANCE_QUERY` (可选) - -如果你想启用余额查询功能,将此环境变量设置为 1 即可。 - -### `DISABLE_FAST_LINK` (可选) - -如果你想禁用从链接解析预制设置,将此环境变量设置为 1 即可。 - -### `WHITE_WEBDEV_ENDPOINTS` (可选) - -如果你想增加允许访问的webdav服务地址,可以使用该选项,格式要求: -- 每一个地址必须是一个完整的 endpoint -> `https://xxxx/xxx` -- 多个地址以`,`相连 - -### `CUSTOM_MODELS` (可选) - -> 示例:`+qwen-7b-chat,+glm-6b,-gpt-3.5-turbo,gpt-4-1106-preview=gpt-4-turbo` 表示增加 `qwen-7b-chat` 和 `glm-6b` 到模型列表,而从列表中删除 `gpt-3.5-turbo`,并将 `gpt-4-1106-preview` 模型名字展示为 `gpt-4-turbo`。 -> 如果你想先禁用所有模型,再启用指定模型,可以使用 `-all,+gpt-3.5-turbo`,则表示仅启用 `gpt-3.5-turbo` - -用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。 - -在Azure的模式下,支持使用`modelName@azure=deploymentName`的方式配置模型名称和部署名称(deploy-name) -> 示例:`+gpt-3.5-turbo@azure=gpt35`这个配置会在模型列表显示一个`gpt35(Azure)`的选项 - -在ByteDance的模式下,支持使用`modelName@bytedance=deploymentName`的方式配置模型名称和部署名称(deploy-name) -> 示例: `+Doubao-lite-4k@bytedance=ep-xxxxx-xxx`这个配置会在模型列表显示一个`Doubao-lite-4k(ByteDance)`的选项 - - -### `DEFAULT_MODEL` (可选) - -更改默认模型 - -### `DEFAULT_INPUT_TEMPLATE` (可选) - -自定义默认的 template,用于初始化『设置』中的『用户输入预处理』配置项 - - - ## 環境変数 -> 本プロジェクトのほとんどの設定は環境変数で行います。チュートリアル:[Vercel の環境変数を変更する方法](./docs/vercel-cn.md)。 +> 本プロジェクトのほとんどの設定は環境変数で行います。チュートリアル:[Vercel の環境変数を変更する方法](./docs/vercel-ja.md)。 ### `OPENAI_API_KEY` (必須) @@ -418,23 +222,6 @@ ByteDance モードでは、`modelName@bytedance=deploymentName` 形式でモデ 『設定』の『ユーザー入力前処理』の初期設定に使用するテンプレートをカスタマイズします。 - - -## 开发 - -点击下方按钮,开始二次开发: - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web) - -在开始写代码之前,需要在项目根目录新建一个 `.env.local` 文件,里面填入环境变量: - -``` -OPENAI_API_KEY= - -# 中国大陆用户,可以使用本项目自带的代理进行开发,你也可以自由选择其他代理地址 -BASE_URL=https://b.nextweb.fun/api/proxy -``` - ## 開発 下のボタンをクリックして二次開発を開始してください: @@ -447,11 +234,6 @@ BASE_URL=https://b.nextweb.fun/api/proxy OPENAI_API_KEY= ``` -### 本地开发 - -1. 安装 nodejs 18 和 yarn,具体细节请询问 ChatGPT; -2. 执行 `yarn install && yarn dev` 即可。⚠️ 注意:此命令仅用于本地开发,不要用于部署! -3. 如果你想本地部署,请使用 `yarn install && yarn build && yarn start` 命令,你可以配合 pm2 来守护进程,防止被杀死,详情询问 ChatGPT。 ### ローカル開発 @@ -460,45 +242,6 @@ OPENAI_API_KEY= 3. ローカルでデプロイしたい場合は、`yarn install && yarn build && yarn start` コマンドを使用してください。プロセスを守るために pm2 を使用することもできます。詳細は ChatGPT にお尋ねください。 -## 部署 - -### 容器部署 (推荐) - -> Docker 版本需要在 20 及其以上,否则会提示找不到镜像。 - -> ⚠️ 注意:docker 版本在大多数时间都会落后最新的版本 1 到 2 天,所以部署后会持续出现“存在更新”的提示,属于正常现象。 - -```shell -docker pull yidadaa/chatgpt-next-web - -docker run -d -p 3000:3000 \ - -e OPENAI_API_KEY=sk-xxxx \ - -e CODE=页面访问密码 \ - yidadaa/chatgpt-next-web -``` - -你也可以指定 proxy: - -```shell -docker run -d -p 3000:3000 \ - -e OPENAI_API_KEY=sk-xxxx \ - -e CODE=页面访问密码 \ - --net=host \ - -e PROXY_URL=http://127.0.0.1:7890 \ - yidadaa/chatgpt-next-web -``` - -如果你的本地代理需要账号密码,可以使用: - -```shell --e PROXY_URL="http://127.0.0.1:7890 user password" -``` - -如果你需要指定其他环境变量,请自行在上述命令中增加 `-e 环境变量=环境变量值` 来指定。 - - - - ## デプロイ ### コンテナデプロイ(推奨) @@ -536,20 +279,6 @@ docker run -d -p 3000:3000 \ 他の環境変数を指定する必要がある場合は、上記のコマンドに `-e 環境変数=環境変数値` を追加して指定してください。 - - -### 本地部署 - -在控制台运行下方命令: - -```shell -bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/scripts/setup.sh) -``` - -⚠️ 注意:如果你安装过程中遇到了问题,请使用 docker 部署。 - - - ### ローカルデプロイ コンソールで以下のコマンドを実行します: @@ -561,23 +290,6 @@ bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/s ⚠️ 注意:インストール中に問題が発生した場合は、Docker を使用してデプロイしてください。 - -## 鸣谢 - -### 捐赠者 - -> 见英文版。 - -### 贡献者 - -[见项目贡献者列表](https://github.com/Yidadaa/ChatGPT-Next-Web/graphs/contributors) - -### 相关项目 - -- [one-api](https://github.com/songquanpeng/one-api): 一站式大模型额度管理平台,支持市面上所有主流大语言模型 - - - ## 謝辞 ### 寄付者 @@ -593,13 +305,6 @@ bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/s - [one-api](https://github.com/songquanpeng/one-api): 一つのプラットフォームで大規模モデルのクォータ管理を提供し、市場に出回っているすべての主要な大規模言語モデルをサポートします。 - - -## 开源协议 - -[MIT](https://opensource.org/license/mit/) - - ## オープンソースライセンス [MIT](https://opensource.org/license/mit/) From 862c2e881091d99eb0aa0e3dbf2a4155ea70baf8 Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Fri, 19 Jul 2024 17:22:54 +0800 Subject: [PATCH 9/9] hotfix for code review --- app/utils/chat.ts | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/app/utils/chat.ts b/app/utils/chat.ts index 77e9ee69b..24f37d106 100644 --- a/app/utils/chat.ts +++ b/app/utils/chat.ts @@ -1,5 +1,4 @@ import { CACHE_URL_PREFIX, UPLOAD_URL } from "@/app/constant"; -// import heic2any from "heic2any"; import { RequestMessage } from "@/app/client/api"; export function compressImage(file: Blob, maxSize: number): Promise { @@ -42,14 +41,18 @@ export function compressImage(file: Blob, maxSize: number): Promise { reader.onerror = reject; if (file.type.includes("heic")) { - const heic2any = require("heic2any"); - heic2any({ blob: file, toType: "image/jpeg" }) - .then((blob: Blob) => { - reader.readAsDataURL(blob); - }) - .catch((e: any) => { - reject(e); - }); + try { + const heic2any = require("heic2any"); + heic2any({ blob: file, toType: "image/jpeg" }) + .then((blob: Blob) => { + reader.readAsDataURL(blob); + }) + .catch((e: any) => { + reject(e); + }); + } catch (e) { + reject(e); + } } reader.readAsDataURL(file); @@ -65,8 +68,12 @@ export async function preProcessImageContent( const result = []; for (const part of content) { if (part?.type == "image_url" && part?.image_url?.url) { - const url = await cacheImageToBase64Image(part?.image_url?.url); - result.push({ type: part.type, image_url: { url } }); + try { + const url = await cacheImageToBase64Image(part?.image_url?.url); + result.push({ type: part.type, image_url: { url } }); + } catch (error) { + console.error("Error processing image URL:", error); + } } else { result.push({ ...part }); } @@ -92,7 +99,7 @@ export function cacheImageToBase64Image(imageUrl: string) { } return Promise.resolve(imageCaches[imageUrl]); } - return imageUrl; + return Promise.resolve(imageUrl); } export function base64Image2Blob(base64Data: string, contentType: string) {