Skip to content

Commit 2d0a86c

Browse files
committed
Add supplementary documents and optimize the upload interface
1 parent 7a3cc80 commit 2d0a86c

File tree

17 files changed

+250
-125
lines changed

17 files changed

+250
-125
lines changed

docSite/assets/imgs/plugins/entry.png

513 KB
Loading

docSite/assets/imgs/plugins/file.png

49.3 KB
Loading

docSite/content/zh-cn/docs/guide/plugins/google_search_plugin_guide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: "FastGPT Google 搜索插件配置指南"
44
icon: "google_search"
55
draft: false
66
toc: true
7-
weight: 304
7+
weight: 305
88
---
99

1010
1. # 创建Google Custom Search Engine

docSite/content/zh-cn/docs/guide/plugins/searxng_plugin_guide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: "FastGPT SearXNG 搜索插件配置指南"
44
icon: "search"
55
draft: false
66
toc: true
7-
weight: 303
7+
weight: 304
88
---
99

1010
[SearXNG](https://github.com/searxng/searxng)是一款免费的互联网元搜索引擎,它汇总了来自各种搜索服务和数据库的结果。它不会跟踪或分析用户。用户可以自行部署它进行使用。本文介绍 Searxng 的部署以及接入 FastGPT 插件。
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: "如何在线上传系统工具"
3+
description: "FastGPT 系统工具在线上传指南"
4+
icon: "cloud_upload"
5+
draft: false
6+
toc: true
7+
weight: 303
8+
---
9+
10+
## 介绍
11+
12+
从 FastGPT 4.10.0 版本开始,系统管理员可以通过 Web 界面直接上传和更新系统工具,无需重新部署服务。本文档将指导您如何使用在线上传功能来管理系统工具。
13+
14+
## 权限要求
15+
16+
⚠️ **重要提示**:只有 **root 用户** 才能使用在线上传系统工具功能。
17+
18+
- 确保您已使用 `root` 账户登录 FastGPT
19+
- 普通用户无法看到"导入/更新"按钮和删除功能
20+
21+
## 支持的文件格式
22+
23+
- **文件类型**`.js` 文件
24+
- **文件大小**:最大 10MB
25+
- **文件数量**:每次只能上传一个文件
26+
27+
## 上传步骤
28+
29+
### 1. 进入系统工具页面
30+
31+
1. 登录 FastGPT 管理后台
32+
2. 导航到:**工作台****系统工具**
33+
3. 确认页面右上角显示"导入/更新"按钮(只有 root 用户可见)
34+
35+
![](/imgs/plugins/entry.png)
36+
37+
### 2. 准备工具文件
38+
39+
在上传之前,请确保您的 `.js` 文件是从 fastgpt-plugin 项目中通过 `bun run build` 命令打包后的 dist/tools/built-in 文件夹下得到的
40+
41+
![](/imgs/plugins/file.png)
42+
43+
### 3. 执行上传
44+
45+
1. 点击 **"导入/更新"** 按钮
46+
2. 在弹出的对话框中,点击文件选择区域
47+
3. 选择您准备好的 `.js` 工具文件
48+
4. 确认文件信息无误后,点击 **"确认导入"**
49+
50+
### 4. 上传过程
51+
52+
- 上传成功后会显示成功提示
53+
- 页面自动刷新,新工具会出现在工具列表中
54+
55+
## 功能特点
56+
57+
### 工具管理
58+
59+
- **查看工具**:所有用户都可以查看已安装的系统工具
60+
- **上传工具**:仅 root 用户可以上传新工具或更新现有工具
61+
- **删除工具**:仅 root 用户可以删除已上传的工具
62+
63+
### 工具类型识别
64+
65+
系统会根据工具的配置自动识别工具类型:
66+
67+
- 🔧 **工具 (tools)**
68+
- 🔍 **搜索 (search)**
69+
- 🎨 **多模态 (multimodal)**
70+
- 💬 **通讯 (communication)**
71+
- 📦 **其他 (other)**
72+
73+
## 常见问题
74+
75+
### Q: 上传失败,提示"文件内容存在错误"
76+
77+
**可能原因:**
78+
- fastgpt-plugin 项目不是最新的,导致打包的 `.js` 文件缺少正确的内容
79+
- 工具配置格式不正确
80+
81+
**解决方案:**
82+
1. 拉取最新的 fastgpt-plugin 项目重新进行 `bun run build` 获得打包后的 `.js` 文件
83+
2. 检查本地插件运行是否成功
84+
85+
### Q: 无法看到"导入/更新"按钮
86+
87+
**原因:** 当前用户不是 root 用户
88+
89+
**解决方案:** 使用 root 账户重新登录
90+
91+
### Q: 文件上传超时
92+
93+
**可能原因:**
94+
- 文件过大(超过 10MB)
95+
- 网络连接不稳定
96+
97+
**解决方案:**
98+
1. 确认文件大小在限制范围内
99+
2. 检查网络连接
100+
3. 尝试重新上传
101+
102+
## 最佳实践
103+
104+
### 上传前检查
105+
106+
1. **代码测试**:在本地环境测试工具功能
107+
2. **格式验证**:确保符合 FastGPT 工具规范
108+
3. **文件大小**:保持文件在合理大小范围内
109+
110+
### 版本管理
111+
112+
- 建议为工具添加版本号注释
113+
- 更新工具时,先备份原有版本
114+
- 记录更新日志和功能变更
115+
116+
### 安全考虑
117+
118+
- 仅上传来源可信的工具文件
119+
- 避免包含敏感信息或凭据
120+
- 定期审查已安装的工具
121+
122+
### 存储方式
123+
124+
- 工具文件存储在 MinIO 中
125+
- 工具元数据保存在 MongoDB 中
126+
127+
---
128+
129+
通过在线上传功能,您可以快速部署和管理系统工具,提高 FastGPT 的扩展性和灵活性。如遇到问题,请参考上述常见问题或联系技术支持。

packages/service/common/file/plugin/controller.ts

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,32 +41,12 @@ export const generateDownloadUrl = (objectName: string, config: UploadFileConfig
4141
return `${config.bucket}/${encodedObjectName}`;
4242
};
4343

44-
const validatePresignedInput = (input: PresignedUrlInput, config: UploadFileConfig): void => {
45-
if (!input.filename) {
46-
throw new Error('Filename is required');
47-
}
48-
49-
const maxSize = input.maxSize || config.maxFileSize;
50-
if (maxSize > config.maxFileSize) {
51-
throw new Error(`Max size exceeds limit of ${config.maxFileSize} bytes`);
52-
}
53-
54-
const ext = path.extname(input.filename).toLowerCase();
55-
if (config.allowedExtensions && !config.allowedExtensions.includes(ext)) {
56-
throw new Error(
57-
`File extension ${ext} is not allowed. Supported extensions: ${config.allowedExtensions.join(', ')}`
58-
);
59-
}
60-
};
61-
6244
//Generate a pre-signed URL for direct file upload
6345
export const generatePresignedUrl = async (
6446
input: PresignedUrlInput
6547
): Promise<PresignedUrlResponse> => {
6648
const currentConfig = { ...globalConfig };
6749

68-
validatePresignedInput(input, currentConfig);
69-
7050
const fileId = generateFileId();
7151
const pluginType = input.pluginType || PluginTypeEnum.tool;
7252
const pluginPath = PLUGIN_TYPE_TO_PATH_MAP[pluginType];
@@ -76,13 +56,11 @@ export const generatePresignedUrl = async (
7656

7757
try {
7858
const policy = connectionMinio.newPostPolicy();
59+
7960
policy.setBucket(currentConfig.bucket);
8061
policy.setKey(objectName);
81-
8262
policy.setContentType(contentType);
83-
8463
policy.setContentLengthRange(1, maxSize);
85-
8664
policy.setExpires(new Date(Date.now() + 10 * 60 * 1000));
8765

8866
const metadata = {
@@ -102,8 +80,6 @@ export const generatePresignedUrl = async (
10280
formData
10381
};
10482

105-
console.log('Generated presigned URL successfully', response);
106-
10783
return response;
10884
} catch (error) {
10985
addLog.error('Failed to generate presigned URL', error);
@@ -119,6 +95,7 @@ export const confirmPresignedUpload = async (objectName: string, size: string):
11995
const stat = await connectionMinio.statObject(currentConfig.bucket, objectName);
12096

12197
if (stat.size !== Number(size)) {
98+
addLog.error(`File size mismatch. Expected: ${size}, Actual: ${stat.size}`);
12299
return Promise.reject(`File size mismatch. Expected: ${size}, Actual: ${stat.size}`);
123100
}
124101

@@ -134,7 +111,6 @@ export const confirmPresignedUpload = async (objectName: string, size: string):
134111
return result.url;
135112
} catch (error) {
136113
addLog.error('Failed to confirm presigned upload', error);
137-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
138-
return Promise.reject(`Failed to confirm presigned upload: ${errorMessage}`);
114+
return Promise.reject(`Failed to confirm presigned upload: ${error}`);
139115
}
140116
};

packages/service/common/minio/init.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ export const initMinio = async () => {
66
try {
77
addLog.info('Connecting to MinIO...');
88

9-
// Test connection by listing buckets
10-
await connectionMinio.listBuckets();
11-
129
addLog.info('MinIO connected successfully');
1310
return true;
1411
} catch (error) {
@@ -52,13 +49,3 @@ export const ensureBucket = async (bucketName: string, isPublic: boolean = false
5249
}
5350
}, 3);
5451
};
55-
56-
export const listBuckets = async () => {
57-
try {
58-
const buckets = await connectionMinio.listBuckets();
59-
return buckets;
60-
} catch (error) {
61-
addLog.error('Failed to list buckets:', error);
62-
throw error;
63-
}
64-
};

packages/service/core/app/plugin/controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ export const getSystemPlugins = async (): Promise<SystemPluginTemplateItemType[]
443443
...item,
444444
isFolder: tools.some((tool) => tool.parentId === item.id),
445445
showStatus: true,
446-
toolSource: (item.toolSource as 'uploaded' | 'built-in') || 'built-in',
446+
toolSource: item.toolSource || 'built-in',
447447

448448
workflow: {
449449
nodes: [],

packages/web/i18n/en/common.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,7 @@
12021202
"support.wallet.usage.Total points": "AI Points Consumption",
12031203
"support.wallet.usage.Usage Detail": "Usage Details",
12041204
"support.wallet.usage.Whisper": "Voice Input",
1205+
"sure_delete_tool_cannot_undo": "Are you sure to delete the tool? \nThis operation cannot be withdrawn",
12051206
"sync_link": "Sync Link",
12061207
"sync_success": "Synced Successfully",
12071208
"system.Concat us": "Contact Us",

packages/web/i18n/en/file.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
"Only_support_uploading_one_image": "Only support uploading one image",
1414
"Please select the image to upload": "Please select the image to upload",
1515
"Please wait for all files to upload": "Please wait for all files to be uploaded to complete",
16+
"Upload_system_tools": "Upload system tools",
1617
"bucket_chat": "Conversation Files",
1718
"bucket_file": "Dataset Documents",
1819
"click_to_view_raw_source": "Click to View Original Source",
1920
"common.Some images failed to process": "Some images failed to process",
2021
"common.dataset_data_input_image_support_format": "Support .jpg, .jpeg, .png, .gif, .webp formats",
22+
"common.import_update": "Import/Update",
2123
"count.core.dataset.collection.Create Success": "{{count}} picture successfully imported",
2224
"delete_image": "Delete pictures",
2325
"file_name": "Filename",

0 commit comments

Comments
 (0)