feat: support custom s3 service

This commit is contained in:
Hk-Gosuto 2023-12-10 21:02:49 +08:00
parent eb7711f832
commit b84da5e120
6 changed files with 88 additions and 35 deletions

View File

@ -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` 插件时需要配置。
## 部署
### 容器部署 (推荐)

View File

@ -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;

View File

@ -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";

View File

@ -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";

View File

@ -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
View 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.