mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-05-22 21:50:16 +09:00
feat: support custom s3 service
This commit is contained in:
parent
eb7711f832
commit
b84da5e120
22
README.md
22
README.md
@ -37,6 +37,8 @@
|
||||
|
||||
- 除插件工具外,与原项目保持一致 [ChatGPT-Next-Web 主要功能](https://github.com/Yidadaa/ChatGPT-Next-Web#主要功能)
|
||||
- 支持 GPT-4V(视觉) 模型
|
||||
- 需要配置对象存储服务,请参考 [对象存储服务配置指南](./docs/s3-oss.md) 配置
|
||||
|
||||
- 基于 [LangChain](https://github.com/hwchase17/langchainjs) 实现的插件功能,目前支持以下插件,未来会添加更多
|
||||
- 搜索
|
||||
- [SerpAPI](https://js.langchain.com/docs/api/tools/classes/SerpAPI)
|
||||
@ -51,11 +53,11 @@
|
||||
- 其它
|
||||
- [Wiki](https://js.langchain.com/docs/api/tools/classes/WikipediaQueryRun)
|
||||
- DALL-E 3
|
||||
- DALL-E 3 插件需要配置 R2 存储,请参考 [Cloudflare R2 服务配置指南](./docs/cloudflare-r2-cn.md) 配置
|
||||
- DALL-E 3 插件需要配置对象存储服务,请参考 [对象存储服务配置指南](./docs/s3-oss.md) 配置
|
||||
- StableDiffusion
|
||||
- 本插件目前为测试版本,后续可能会有较大的变更,请谨慎使用
|
||||
- 使用本插件需要一定的专业知识,Stable Diffusion 本身的相关问题不在本项目的解答范围内,如果您确定要使用本插件请参考 [Stable Diffusion 插件配置指南](./docs/stable-diffusion-plugin-cn.md) 文档进行配置
|
||||
- StableDiffusion 插件需要配置 R2 存储,请参考 [Cloudflare R2 服务配置指南](./docs/cloudflare-r2-cn.md) 配置
|
||||
- StableDiffusion 插件需要配置对象存储服务,请参考 [对象存储服务配置指南](./docs/s3-oss.md) 配置
|
||||
- Arxiv
|
||||
|
||||
## 开发计划
|
||||
@ -181,22 +183,6 @@ OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填
|
||||
|
||||
如果你不想让用户查询余额,将此环境变量设置为 1 即可。
|
||||
|
||||
### `R2_ACCOUNT_ID` (可选)
|
||||
|
||||
Cloudflare R2 帐户 ID,使用 `DALL-E` 插件时需要配置。
|
||||
|
||||
### `R2_ACCESS_KEY_ID` (可选)
|
||||
|
||||
Cloudflare R2 访问密钥 ID,使用 `DALL-E` 插件时需要配置。
|
||||
|
||||
### `R2_SECRET_ACCESS_KEY` (可选)
|
||||
|
||||
Cloudflare R2 机密访问密钥,使用 `DALL-E` 插件时需要配置。
|
||||
|
||||
### `R2_BUCKET` (可选)
|
||||
|
||||
Cloudflare R2 Bucket 名称,使用 `DALL-E` 插件时需要配置。
|
||||
|
||||
## 部署
|
||||
|
||||
### 容器部署 (推荐)
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { auth } from "../../auth";
|
||||
import S3FileStorage from "../../../utils/r2_file_storage";
|
||||
import S3FileStorage from "../../../utils/s3_file_storage";
|
||||
|
||||
async function handle(
|
||||
req: NextRequest,
|
||||
@ -10,13 +9,6 @@ async function handle(
|
||||
return NextResponse.json({ body: "OK" }, { status: 200 });
|
||||
}
|
||||
|
||||
// const authResult = auth(req);
|
||||
// if (authResult.error) {
|
||||
// return NextResponse.json(authResult, {
|
||||
// status: 401,
|
||||
// });
|
||||
// }
|
||||
|
||||
try {
|
||||
var file = await S3FileStorage.get(params.path[0]);
|
||||
return new Response(file?.transformToWebStream(), {
|
||||
@ -34,3 +26,4 @@ async function handle(
|
||||
export const GET = handle;
|
||||
|
||||
export const runtime = "edge";
|
||||
export const revalidate = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { StructuredTool } from "langchain/tools";
|
||||
import { z } from "zod";
|
||||
import S3FileStorage from "../../utils/r2_file_storage";
|
||||
import S3FileStorage from "../../utils/s3_file_storage";
|
||||
|
||||
export class DallEAPIWrapper extends StructuredTool {
|
||||
name = "dalle_image_generator";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Tool } from "langchain/tools";
|
||||
import S3FileStorage from "../../utils/r2_file_storage";
|
||||
import S3FileStorage from "../../utils/s3_file_storage";
|
||||
|
||||
export class StableDiffusionWrapper extends Tool {
|
||||
name = "stable_diffusion_image_generator";
|
||||
|
@ -12,13 +12,19 @@ const R2_ACCESS_KEY_ID = process.env.R2_ACCESS_KEY_ID;
|
||||
const R2_SECRET_ACCESS_KEY = process.env.R2_SECRET_ACCESS_KEY;
|
||||
const R2_BUCKET = process.env.R2_BUCKET;
|
||||
|
||||
const S3_ENDPOINT = process.env.S3_ENDPOINT;
|
||||
const S3_ACCESS_KEY_ID = process.env.S3_ACCESS_KEY_ID;
|
||||
const S3_SECRET_ACCESS_KEY = process.env.S3_SECRET_ACCESS_KEY;
|
||||
const S3_BUCKET = process.env.S3_BUCKET;
|
||||
|
||||
const getR2Client = () => {
|
||||
return new S3Client({
|
||||
region: "auto",
|
||||
endpoint: `https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
||||
endpoint:
|
||||
S3_ENDPOINT ?? `https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
||||
credentials: {
|
||||
accessKeyId: R2_ACCESS_KEY_ID!,
|
||||
secretAccessKey: R2_SECRET_ACCESS_KEY!,
|
||||
accessKeyId: S3_ACCESS_KEY_ID ?? R2_ACCESS_KEY_ID!,
|
||||
secretAccessKey: S3_SECRET_ACCESS_KEY ?? R2_SECRET_ACCESS_KEY!,
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -27,7 +33,7 @@ export default class S3FileStorage {
|
||||
static async get(fileName: string) {
|
||||
const file = await getR2Client().send(
|
||||
new GetObjectCommand({
|
||||
Bucket: R2_BUCKET,
|
||||
Bucket: S3_BUCKET ?? R2_BUCKET,
|
||||
Key: fileName,
|
||||
}),
|
||||
);
|
||||
@ -43,7 +49,7 @@ export default class S3FileStorage {
|
||||
const signedUrl = await getSignedUrl(
|
||||
getR2Client(),
|
||||
new PutObjectCommand({
|
||||
Bucket: R2_BUCKET,
|
||||
Bucket: S3_BUCKET ?? R2_BUCKET,
|
||||
Key: fileName,
|
||||
}),
|
||||
{ expiresIn: 60 },
|
||||
@ -59,7 +65,7 @@ export default class S3FileStorage {
|
||||
|
||||
return `/api/file/${fileName}`;
|
||||
} catch (e) {
|
||||
console.error("[R2]", e);
|
||||
console.error("[S3]", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
68
docs/s3-oss.md
Normal file
68
docs/s3-oss.md
Normal file
@ -0,0 +1,68 @@
|
||||
# 对象存储服务配置指南
|
||||
|
||||
请根据自身网络情况,选择 S3 或 R2 来作为对象存储服务,两个服务配置其一即可。
|
||||
|
||||
由于国内网络使用 R2 经常抽风,这边推荐选择一家支持 S3 协议的对象存储服务提供商。
|
||||
|
||||
## 配置 S3 对象存储服务
|
||||
|
||||
这边以 `又拍云` 做为演示,其它运营商请查询对应文档。
|
||||
|
||||
1. 登录 [又拍云 - 加速在线业务 - CDN加速 - 云存储 (upyun.com)](https://www.upyun.com/)
|
||||
2. 注册账户
|
||||
3. 进入”云存储“控制台[又拍云控制台 (upyun.com)](https://console.upyun.com/services/file/)
|
||||
4. 创建一个服务,记录你的服务名
|
||||
5. 进入"用户管理","操作员"创建一个"操作员"并赋予相应权限
|
||||
6. 编辑"操作员"复制"AccessKey"和"SecretAccessKey"
|
||||
7. 如果读写权限未勾选则选中后确定
|
||||
8. 回到 ChatGPT-Next-Web-LangChain 项目修改环境变量。按照以下信息填写:
|
||||
- `S3_ENDPOINT=http://s3.api.upyun.com`
|
||||
- `S3_ACCESS_KEY_ID=AccessKey`
|
||||
- `S3_SECRET_ACCESS_KEY=SecretAccessKey`
|
||||
- `S3_BUCKET=服务名`
|
||||
9. Enjoy.
|
||||
|
||||
## 配置 R2 服务
|
||||
登录到 dash.cloudflare.com 并在左侧菜单进入 R2。
|
||||
|
||||
1. 复制右侧 "账户ID"
|
||||
|
||||
2. 点击 "创建存储桶"。
|
||||
|
||||
3. 自定义配置一个存储桶名称,记录下来用于后面配置环境变量,点击 "创建存储桶"。
|
||||
|
||||
4. 进入 "设置",点击 "添加 CORS 策略",将下面内容粘贴上去并点击 "保存"。
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"AllowedOrigins": [
|
||||
"*"
|
||||
],
|
||||
"AllowedMethods": [
|
||||
"PUT",
|
||||
"DELETE",
|
||||
"GET"
|
||||
],
|
||||
"AllowedHeaders": [
|
||||
"content-type"
|
||||
],
|
||||
"MaxAgeSeconds": 3000
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
5. 回到 R2 主菜单,点击右侧 "管理 R2 API 令牌"。
|
||||
|
||||
6. 点击 "创建 API 令牌",权限选择为 "管理员读和写",TTL 选择为 "永久",点击 "创建 API 令牌"。
|
||||
|
||||
7. 复制 "访问密钥 ID" 和 "机密访问密钥",点击 "完成"。
|
||||
|
||||
8. 回到 ChatGPT-Next-Web-LangChain 项目修改环境变量。按照以下信息填写:
|
||||
|
||||
- `R2_ACCOUNT_ID=账户ID`
|
||||
- `R2_ACCESS_KEY_ID=访问密钥 ID`
|
||||
- `R2_SECRET_ACCESS_KEY=机密访问密钥`
|
||||
- `R2_BUCKET=存储桶名称`
|
||||
|
||||
9. Enjoy.
|
Loading…
Reference in New Issue
Block a user