V4.8.15 feature (#3331)
* feat: add customize toolkit (#3205) * chaoyang * fix-auth * add toolkit * add order * plugin usage * fix * delete console: * Fix: Fix fullscreen preview top positioning and improve Markdown rendering logic (#3247) * 完成任务:修复全屏预览顶部固定问题,优化 Markdown 渲染逻辑 * 有问题修改 * 问题再修改 * 修正问题 * fix: plugin standalone display issue (#3254) * 4.8.15 test (#3246) * o1 config * perf: system plugin code * 调整系统插件代码。增加html 渲染安全配置。 (#3258) * perf: base64 picker * perf: list app or dataset * perf: plugin config code * 小窗适配等问题 (#3257) * 小窗适配等问题 * git问题 * 小窗剩余问题 * feat: system plugin auth and lock version (#3265) * feat: system plugin auth and lock version * update comment * 4.8.15 test (#3267) * tmp log * perf: login direct * perf: iframe html code * remove log * fix: plugin standalone display (#3277) * refactor: 页面拆分&i18n拆分 (#3281) * refactor: account组件拆成独立页面 * script: 新增i18n json文件创建脚本 * refactor: 页面i18n拆分 * i18n: add en&hant * 4.8.15 test (#3285) * tmp log * remove log * fix: watch avatar refresh * perf: i18n code * fix(plugin): use intro instead of userguide (#3290) * Universal SSO (#3292) * tmp log * remove log * feat: common oauth * readme * perf: sso provider * remove sso code * perf: refresh plugins * feat: add api dataset (#3272) * add api-dataset * fix api-dataset * fix api dataset * fix ts * perf: create collection code (#3301) * tmp log * remove log * perf: i18n change * update version doc * feat: question guide from chatId * perf: create collection code * fix: request api * fix: request api * fix: tts auth and response type (#3303) * perf: md splitter * fix: tts auth and response type * fix: api file dataset (#3307) * perf: api dataset init (#3310) * perf: collection schema * perf: api dataset init * refactor: 团队管理独立页面 (#3302) * ui: 团队管理独立页面 * 代码优化 * fix * perf: sync collection and ui check (#3314) * perf: sync collection * remove script * perf: update api server * perf: api dataset parent * perf: team ui * perf: team 18n * update team ui * perf: ui check * perf: i18n * fix: debug variables & cronjob & system plugin callback load (#3315) * fix: debug variables & cronjob & system plugin callback load * fix type * fix * fix * fix: plugin dataset quote;perf: system variables init (#3316) * fix: plugin dataset quote * perf: system variables init * perf: node templates ui;fix: dataset import ui (#3318) * fix: dataset import ui * perf: node templates ui * perf: ui refresh * feat:套餐改名和套餐跳转配置 (#3309) * fixing:except Sidebar * 去除了多余的代码 * 修正了套餐说明的代码 * 修正了误删除的show_git代码 * 修正了名字部分等代码 * 修正了问题,遗留了其他和ui讨论不一致的部分 * 4.8.15 test (#3319) * remove log * pref: bill ui * pref: bill ui * perf: log * html渲染文档 (#3270) * html渲染文档 * 文档有点小问题 * feat: doc (#3322) * 集合重训练 (#3282) * rebaser * 一点补充 * 小问题 * 其他问题修正,删除集合保留文件的参数还没找到... * reTraining * delete uesless * 删除了一行错误代码 * 集合重训练部分 * fixing * 删除console代码 * feat: navbar item config (#3326) * perf: custom navbar code;perf: retraining code;feat: api dataset and dataset api doc (#3329) * feat: api dataset and dataset api doc * perf: retraining code * perf: custom navbar code * fix: ts (#3330) * fix: ts * fix: ts * retraining ui * perf: api collection filter * perf: retrining button --------- Co-authored-by: heheer <heheer@sealos.io> Co-authored-by: Jiangween <145003935+Jiangween@users.noreply.github.com> Co-authored-by: papapatrick <109422393+Patrickill@users.noreply.github.com>
@@ -128,7 +128,7 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b
|
||||
|
||||
## 🏘️ 加入我们
|
||||
|
||||
我们正在寻找志同道合的小伙伴,加速 FastGPT 的发展。你可以通过 [FastGPT 2025 招聘](https://fael3z0zfze.feishu.cn/wiki/P7FOwEmPziVcaYkvVaacnVX1nvg) 了解 FastGPT 的招聘信息。
|
||||
我们正在寻找志同道合的小伙伴,加速 FastGPT 的发展。你可以通过 [FastGPT 2025 招聘](https://fael3z0zfze.feishu.cn/wiki/P7FOwEmPziVcaYkvVaacnVX1nvg)了解 FastGPT 的招聘信息。
|
||||
|
||||
|
||||
## 💪 相关项目
|
||||
|
BIN
docSite/assets/imgs/api-dataset-1.png
Normal file
After Width: | Height: | Size: 97 KiB |
BIN
docSite/assets/imgs/htmlRendering1.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
docSite/assets/imgs/htmlRendering2.png
Normal file
After Width: | Height: | Size: 92 KiB |
BIN
docSite/assets/imgs/htmlRendering3.png
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
docSite/assets/imgs/image-10.png
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
docSite/assets/imgs/image-11.png
Normal file
After Width: | Height: | Size: 819 KiB |
BIN
docSite/assets/imgs/image-12.png
Normal file
After Width: | Height: | Size: 179 KiB |
BIN
docSite/assets/imgs/image-13.png
Normal file
After Width: | Height: | Size: 172 KiB |
BIN
docSite/assets/imgs/image-14.png
Normal file
After Width: | Height: | Size: 599 KiB |
BIN
docSite/assets/imgs/image-15.png
Normal file
After Width: | Height: | Size: 258 KiB |
BIN
docSite/assets/imgs/image-16.png
Normal file
After Width: | Height: | Size: 139 KiB |
BIN
docSite/assets/imgs/image-17.png
Normal file
After Width: | Height: | Size: 222 KiB |
BIN
docSite/assets/imgs/image-18.png
Normal file
After Width: | Height: | Size: 158 KiB |
BIN
docSite/assets/imgs/image-19.png
Normal file
After Width: | Height: | Size: 167 KiB |
@@ -43,7 +43,7 @@ weight: 708
|
||||
"usedInExtractFields": true, // 是否用于内容提取(务必保证至少有一个为true)
|
||||
"usedInToolCall": true, // 是否用于工具调用(务必保证至少有一个为true)
|
||||
"usedInQueryExtension": true, // 是否用于问题优化(务必保证至少有一个为true)
|
||||
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。目前只有gpt支持)
|
||||
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。)
|
||||
"functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式)
|
||||
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
|
||||
"customExtractPrompt": "", // 自定义内容提取提示词
|
||||
@@ -95,9 +95,7 @@ weight: 708
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"defaultConfig": {
|
||||
"temperature": 1,
|
||||
"max_tokens": null,
|
||||
"stream": false
|
||||
"temperature": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -122,9 +120,7 @@ weight: 708
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"defaultConfig": {
|
||||
"temperature": 1,
|
||||
"max_tokens": null,
|
||||
"stream": false
|
||||
"temperature": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@@ -0,0 +1,64 @@
|
||||
---
|
||||
title: '接入 Marker PDF 文档解析'
|
||||
description: '使用 Marker 解析 PDF 文档,可实现图片提取和布局识别'
|
||||
icon: 'api'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 909
|
||||
---
|
||||
|
||||
## 背景
|
||||
|
||||
PDF 是一个相对复杂的文件格式,在 FastGPT 内置的 pdf 解析器中,依赖的是 pdfjs 库解析,该库基于逻辑解析,无法有效的理解复杂的 pdf 文件。所以我们在解析 pdf 时候,如果遇到图片、表格、公式等非简单文本内容,会发现解析效果不佳。
|
||||
|
||||
市面上目前有多种解析 PDF 的方法,比如使用 [Marker](https://github.com/VikParuchuri/marker),该项目使用了 Surya 模型,基于视觉解析,可以有效提取图片、表格、公式等复杂内容。为了可以让 Marker 快速接入 FastGPT,我们做了一个自定义解析的拓展 Demo。
|
||||
|
||||
在 FastGPT 4.8.15 版本中,你可以通过增加一个环境变量,来替换掉 FastGPT 系统内置解析器,实现自定义的文档解析服务。该功能只是 Demo 阶段,后期配置模式和交互规则会发生改动。
|
||||
|
||||
## 使用教程
|
||||
|
||||
### 1. 按照 Marker
|
||||
|
||||
参考文档 [Marker 安装教程](https://github.com/labring/FastGPT/tree/main/python/pdf-marker),安装 Marker 模型。封装的 API 已经适配了 FastGPT 自定义解析服务。
|
||||
|
||||
这里介绍快速 Docker 按照的方法:
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
### 2. 添加 FastGPT 环境变量
|
||||
|
||||
```
|
||||
CUSTOM_READ_FILE_URL=http://xxxx.com/v1/parse/file
|
||||
CUSTOM_READ_FILE_EXTENSION=pdf
|
||||
```
|
||||
|
||||
* CUSTOM_READ_FILE_URL - 自定义解析服务的地址, host改成解析服务的访问地址,path 不能变动。
|
||||
* CUSTOM_READ_FILE_EXTENSION - 支持的文件后缀,多个文件类型,可用逗号隔开。
|
||||
|
||||
### 3. 测试效果
|
||||
|
||||
通过知识库上传一个 pdf 文件,并确认上传,可以在日志中看到 LOG (LOG_LEVEL需要设置 info 或者 debug):
|
||||
|
||||
```
|
||||
[Info] 2024-12-05 15:04:42 Parsing files from an external service
|
||||
[Info] 2024-12-05 15:07:08 Custom file parsing is complete, time: 1316ms
|
||||
```
|
||||
|
||||
然后你就可以发现,通过 Marker 解析出来的 pdf 会携带图片链接:
|
||||
|
||||

|
||||
|
||||
|
||||
## 效果展示
|
||||
|
||||
以清华的 [ChatDev Communicative Agents for Software Develop.pdf](https://arxiv.org/abs/2307.07924) 为例,展示 Marker 解析的效果:
|
||||
|
||||
| | | |
|
||||
| --- | --- | --- |
|
||||
|  |  |  |
|
||||
|  |  |  |
|
||||
|
||||
上图是分块后的结果,下图是 pdf 原文。整体图片、公式、表格都可以提取出来,效果还是杠杠的。
|
||||
|
||||
不过要注意的是,[Marker](https://github.com/VikParuchuri/marker) 的协议是`GPL-3.0 license`,请在遵守协议的前提下使用。
|
@@ -145,7 +145,7 @@ curl --location --request POST 'https://<oneapi_url>/v1/chat/completions' \
|
||||
"usedInExtractFields": true, // 是否用于内容提取(务必保证至少有一个为true)
|
||||
"usedInToolCall": true, // 是否用于工具调用(务必保证至少有一个为true)
|
||||
"usedInQueryExtension": true, // 是否用于问题优化(务必保证至少有一个为true)
|
||||
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。目前只有gpt支持)
|
||||
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。)
|
||||
"functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式)
|
||||
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
|
||||
"customExtractPrompt": "", // 自定义内容提取提示词
|
||||
|
@@ -407,9 +407,7 @@ curl --location --request POST 'http://localhost:3000/api/core/dataset/collectio
|
||||
- parentId: 父级ID,不填则默认为根目录
|
||||
- name: 集合名称(必填)
|
||||
- metadata: 元数据(暂时没啥用)
|
||||
- trainingType:(必填)
|
||||
- chunk: 按文本长度进行分割
|
||||
- qa: QA拆分
|
||||
- trainingType: 训练模式(必填)
|
||||
- chunkSize: 每个 chunk 的长度(可选). chunk模式:100~3000; qa模式: 4000~模型最大token(16k模型通常建议不超过10000)
|
||||
- chunkSplitter: 自定义最高优先分割符号(可选)
|
||||
- qaPrompt: qa拆分自定义提示词(可选)
|
||||
@@ -483,9 +481,7 @@ curl --location --request POST 'http://localhost:3000/api/core/dataset/collectio
|
||||
- datasetId: 知识库的ID(必填)
|
||||
- parentId: 父级ID,不填则默认为根目录
|
||||
- metadata.webPageSelector: 网页选择器,用于指定网页中的哪个元素作为文本(可选)
|
||||
- trainingType:(必填)
|
||||
- chunk: 按文本长度进行分割
|
||||
- qa: QA拆分
|
||||
- trainingType:训练模式(必填)
|
||||
- chunkSize: 每个 chunk 的长度(可选). chunk模式:100~3000; qa模式: 4000~模型最大token(16k模型通常建议不超过10000)
|
||||
- chunkSplitter: 自定义最高优先分割符号(可选)
|
||||
- qaPrompt: qa拆分自定义提示词(可选)
|
||||
@@ -505,7 +501,13 @@ data 为集合的 ID。
|
||||
"statusText": "",
|
||||
"message": "",
|
||||
"data": {
|
||||
"collectionId": "65abd0ad9d1448617cba6031"
|
||||
"collectionId": "65abd0ad9d1448617cba6031",
|
||||
"results": {
|
||||
"insertLen": 1,
|
||||
"overToken": [],
|
||||
"repeat": [],
|
||||
"error": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -544,9 +546,7 @@ curl --location --request POST 'http://localhost:3000/api/core/dataset/collectio
|
||||
- data: 知识库相关信息(json序列化后传入)
|
||||
- datasetId: 知识库的ID(必填)
|
||||
- parentId: 父级ID,不填则默认为根目录
|
||||
- trainingType:(必填)
|
||||
- chunk: 按文本长度进行分割
|
||||
- qa: QA拆分
|
||||
- trainingType:训练模式(必填)
|
||||
- chunkSize: 每个 chunk 的长度(可选). chunk模式:100~3000; qa模式: 4000~模型最大token(16k模型通常建议不超过10000)
|
||||
- chunkSplitter: 自定义最高优先分割符号(可选)
|
||||
- qaPrompt: qa拆分自定义提示词(可选)
|
||||
@@ -581,6 +581,82 @@ data 为集合的 ID。
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
### 创建一个API集合
|
||||
|
||||
传入一个文件的 id,创建一个集合,会读取文件内容进行分割。目前支持:pdf, docx, md, txt, html, csv。
|
||||
|
||||
{{< tabs tabTotal="3" >}}
|
||||
{{< tab tabName="请求示例" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
使用代码上传时,请注意中文 filename 需要进行 encode 处理,否则容易乱码。
|
||||
|
||||
```bash
|
||||
curl --location --request POST 'http://localhost:3000/api/core/dataset/collection/create/apiCollection' \
|
||||
--header 'Authorization: Bearer fastgpt-xxx' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"name": "A Quick Guide to Building a Discord Bot.pdf",
|
||||
"apiFileId":"A Quick Guide to Building a Discord Bot.pdf",
|
||||
|
||||
"datasetId": "674e9e479c3503c385495027",
|
||||
"parentId": null,
|
||||
|
||||
"trainingType": "chunk",
|
||||
"chunkSize":512,
|
||||
"chunkSplitter":"",
|
||||
"qaPrompt":""
|
||||
}'
|
||||
```
|
||||
|
||||
{{< /markdownify >}}
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab tabName="参数说明" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
需要使用 POST form-data 的格式上传。包含 file 和 data 两个字段。
|
||||
|
||||
{{% alert icon=" " context="success" %}}
|
||||
- name: 集合名,建议就用文件名,必填。
|
||||
- apiFileId: 文件的ID,必填。
|
||||
- datasetId: 知识库的ID(必填)
|
||||
- parentId: 父级ID,不填则默认为根目录
|
||||
- trainingType:训练模式(必填)
|
||||
- chunkSize: 每个 chunk 的长度(可选). chunk模式:100~3000; qa模式: 4000~模型最大token(16k模型通常建议不超过10000)
|
||||
- chunkSplitter: 自定义最高优先分割符号(可选)
|
||||
- qaPrompt: qa拆分自定义提示词(可选)
|
||||
{{% /alert %}}
|
||||
|
||||
{{< /markdownify >}}
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab tabName="响应示例" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
data 为集合的 ID。
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"statusText": "",
|
||||
"message": "",
|
||||
"data": {
|
||||
"collectionId": "65abc044e4704bac793fbd81",
|
||||
"results": {
|
||||
"insertLen": 1,
|
||||
"overToken": [],
|
||||
"repeat": [],
|
||||
"error": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< /markdownify >}}
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
### 创建一个外部文件库集合(商业版)
|
||||
|
||||
{{< tabs tabTotal="3" >}}
|
||||
@@ -637,7 +713,12 @@ data 为集合的 ID。
|
||||
"message": "",
|
||||
"data": {
|
||||
"collectionId": "6646fcedfabd823cdc6de746",
|
||||
"insertLen": 3
|
||||
"results": {
|
||||
"insertLen": 1,
|
||||
"overToken": [],
|
||||
"repeat": [],
|
||||
"error": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1017,9 +1098,7 @@ curl --location --request POST 'https://api.fastgpt.in/api/core/dataset/data/pus
|
||||
|
||||
{{% alert icon=" " context="success" %}}
|
||||
- collectionId: 集合ID(必填)
|
||||
- trainingType:(必填)
|
||||
- chunk: 按文本长度进行分割
|
||||
- qa: QA拆分
|
||||
- trainingType:训练模式(必填)
|
||||
- prompt: 自定义 QA 拆分提示词,需严格按照模板,建议不要传入。(选填)
|
||||
- data:(具体数据)
|
||||
- q: 主要数据(必填)
|
||||
|
@@ -38,11 +38,7 @@ weight: 813
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"defaultConfig": {
|
||||
"temperature": 1,
|
||||
"stream": false
|
||||
},
|
||||
"fieldMap": {
|
||||
"max_tokens": "max_completion_tokens"
|
||||
"temperature": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -67,11 +63,7 @@ weight: 813
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"defaultConfig": {
|
||||
"temperature": 1,
|
||||
"stream": false
|
||||
},
|
||||
"fieldMap": {
|
||||
"max_tokens": "max_completion_tokens"
|
||||
"temperature": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
27
docSite/content/zh-cn/docs/development/upgrading/4815.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: 'V4.8.15(进行中)'
|
||||
description: 'FastGPT V4.8.15 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 809
|
||||
---
|
||||
|
||||
|
||||
## 完整更新内容
|
||||
|
||||
1. 新增 - API 知识库, 见 [API 知识库介绍](/docs/guide/knowledge_base/api_dataset/),外部文件库会被弃用。
|
||||
2. 新增 - 工具箱页面,展示所有可用的系统资源。商业版后台可更便捷的配置系统插件和自定义分类。
|
||||
3. 新增 - Markdown 中,HTML代码会被额外渲染,可以选择预览模式,会限制所有 script 脚本,仅做展示。
|
||||
4. 新增 - 自定义系统级文件解析服务, 见 [接入 Marker PDF 文档解析](/docs/development/custom-models/marker/)
|
||||
5. 新增 - 集合直接重新调整参数,无需删除再导入。
|
||||
6. 新增 - 商业版后台支持配置侧边栏跳转链接。
|
||||
7. 优化 - base64 图片截取判断。
|
||||
8. 优化 - i18n cookie 判断。
|
||||
9. 优化 - 支持 Markdown 文本分割时,只有标题,无内容。
|
||||
10. 优化 - 字符串变量替换,未赋值的变量会转成 undefined,而不是保留原来 id 串。
|
||||
11. 优化 - 全局变量默认值在 API 生效,并且自定义变量支持默认值。
|
||||
12. 修复 - 分享链接点赞鉴权问题。
|
||||
13. 修复 - 对话页面切换自动执行应用时,会误触发非自动执行应用。
|
||||
14. 修复 - 语言播放鉴权问题。
|
||||
15. 修复 - 插件应用知识库引用上限始终为 3000
|
9
docSite/content/zh-cn/docs/guide/DialogBoxes/_index.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
weight: 470
|
||||
title: '对话框'
|
||||
description: '对话框组件,支持多种交互方式,提升用户在应用中的交互体验。'
|
||||
icon: 'chat_bubble'
|
||||
draft: false
|
||||
images: []
|
||||
---
|
||||
<!-- 470 ~ 500 -->
|
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: "对话框与HTML渲染"
|
||||
description: "如何在FastGPT中通过Markdown嵌入HTML代码块,并提供全屏、源代码切换等交互功能"
|
||||
icon: "group"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 470
|
||||
---
|
||||
|
||||
| 源码模式 | 预览模式 | 全屏模式 |
|
||||
| --- | --- | --- |
|
||||
|  |  |  |
|
||||
|
||||
|
||||
### 1. **设计背景**
|
||||
|
||||
尽管Markdown本身支持嵌入HTML标签,但由于安全问题,许多平台和环境对HTML的渲染进行了限制,特别是在渲染动态内容、交互式元素以及外部资源时。这些限制大大降低了用户在撰写和展示复杂文档时的灵活性,尤其是当需要嵌入外部HTML内容时。为了应对这一问题,我们通过使用 `iframe` 来嵌入和渲染HTML内容,并结合 `sandbox` 属性,保障了外部HTML的安全渲染。
|
||||
|
||||
### 2. 功能简介
|
||||
|
||||
该功能模块的主要目的是扩展FastGPT在Markdown渲染中的能力,支持嵌入和渲染HTML内容。由于是利用 Iframe 渲染,所以无法确认内容的高度,FastGPT 中会给 Iframe 设置一个固定高度来进行渲染。并且不支持 HTML 中执行 js 脚本。
|
||||
|
||||
### 3. 技术实现
|
||||
|
||||
本模块通过以下方式实现了HTML渲染和互动功能:
|
||||
|
||||
- **组件设计**:该模块通过渲染 `iframe` 类型的代码块展示HTML内容。使用自定义的 `IframeBlock` 组件,结合 `sandbox` 属性来保障嵌入内容的安全性。`sandbox` 限制了外部HTML中的行为,如禁用脚本执行、限制表单提交等,确保HTML内容的安全性。通过辅助函数与渲染Markdown内容的部分结合,处理 `iframe` 嵌入的HTML内容。
|
||||
- **安全机制**:通过 `iframe` 的 `sandbox` 属性和 `referrerPolicy` 来防止潜在的安全风险。`sandbox` 属性提供了细粒度的控制,允许特定的功能(如脚本、表单、弹出窗口等)在受限的环境中执行,以确保渲染的HTML内容不会对系统造成威胁。
|
||||
- **展示与互动功能**:用户可以通过不同的展示模式(如全屏、预览、源代码模式)自由切换,以便更灵活地查看和控制嵌入的HTML内容。嵌入的 `iframe` 自适应父容器的宽度,同时保证 `iframe`嵌入的内容能够适当显示。
|
||||
|
||||
### 4. 如何使用
|
||||
|
||||
你只需要通过 Markdown 代码块格式,并标记语言为 `html` 即可。例如:
|
||||
|
||||
```md
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>欢迎使用FastGPT</title>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="#home">首页</a></li>
|
||||
<li><a href="#about">关于我们</a></li>
|
||||
<li><a href="#contact">联系我们</a></li>
|
||||
<li><a href="#gallery">图库</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
```
|
183
docSite/content/zh-cn/docs/guide/knowledge_base/api_dataset.md
Normal file
@@ -0,0 +1,183 @@
|
||||
---
|
||||
title: 'API 文件库'
|
||||
description: 'FastGPT API 文件库功能介绍和使用方式'
|
||||
icon: 'language'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 405
|
||||
---
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
|  |  |
|
||||
|
||||
## 背景
|
||||
|
||||
目前 FastGPT 支持本地文件导入,但是很多时候,用户自身已经有了一套文档库,如果把文件重复导入一遍,会造成二次存储,并且不方便管理。因为 FastGPT 提供了一个 API 文件库的概念,可以通过简单的 API 接口,去拉取已有的文档库,并且可以灵活配置是否导入。
|
||||
|
||||
API 文件库能够让用户轻松对接已有的文档库,只需要按照 FastGPT 的 API 文件库规范,提供相应文件接口,然后将服务接口的 baseURL 和 token 填入知识库创建参数中,就能直接在页面上拿到文件库的内容,并选择性导入
|
||||
|
||||
## 如何使用 API 文件库
|
||||
|
||||
创建知识库时,选择 API 文件库类型,然后需要配置两个关键参数:文件服务接口的 baseURL 和用于身份验证的请求头信息。只要提供的接口规范符合 FastGPT 的要求,系统就能自动获取并展示完整的文件列表,可以根据需要选择性地将文件导入到知识库中。
|
||||
|
||||
你需要提供两个参数:
|
||||
- baseURL: 文件服务接口的 baseURL
|
||||
- authorization: 用于身份验证的请求头信息,实际请求格式为 `Authorization: Bearer <token>`
|
||||
|
||||
## 接口规范
|
||||
|
||||
接口响应格式:
|
||||
|
||||
```ts
|
||||
type ResponseType = {
|
||||
success: boolean;
|
||||
message: string;
|
||||
data: any;
|
||||
}
|
||||
```
|
||||
|
||||
数据类型:
|
||||
|
||||
```ts
|
||||
// 文件列表中,单项的文件类型
|
||||
type FileListItem = {
|
||||
id: string;
|
||||
parentId: string | null;
|
||||
name: string;
|
||||
type: 'file' | 'folder';
|
||||
updateTime: Date;
|
||||
createTime: Date;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### 1. 获取文件树
|
||||
|
||||
{{< tabs tabTotal="2" >}}
|
||||
{{< tab tabName="请求示例" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
{{% alert icon=" " context="success" %}}
|
||||
- parentId - 父级 id,可选,或者 null。
|
||||
- searchKey - 检索词,可选
|
||||
{{% /alert %}}
|
||||
|
||||
```bash
|
||||
curl --location --request POST '{{baseURL}}/v1/file/list' \
|
||||
--header 'Authorization: Bearer {{authorization}}' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"parentId": null,
|
||||
"searchKey": ""
|
||||
}'
|
||||
```
|
||||
|
||||
{{< /markdownify >}}
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab tabName="响应示例" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": [
|
||||
{
|
||||
"id": "xxxx",
|
||||
"parentId": "xxxx",
|
||||
"type": "file", // file | folder
|
||||
"name":"test.json",
|
||||
"updateTime":"2024-11-26T03:05:24.759Z",
|
||||
"createTime":"2024-11-26T03:05:24.759Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
{{< /markdownify >}}
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
### 2. 获取单个文件内容(文本内容或访问链接)
|
||||
|
||||
{{< tabs tabTotal="3" >}}
|
||||
{{< tab tabName="请求示例" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
```bash
|
||||
curl --location --request GET '{{baseURL}}/v1/file/content?id=xx' \
|
||||
--header 'Authorization: Bearer {{authorization}}'
|
||||
```
|
||||
|
||||
{{< /markdownify >}}
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab tabName="响应示例" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"content": "FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的问答场景!\n",
|
||||
"previewUrl": "xxxx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{% alert icon=" " context="success" %}}
|
||||
二选一返回,如果同时返回则 content 优先级更高。
|
||||
|
||||
- content - 文件内容,直接拿来用。
|
||||
- previewUrl - 文件链接,系统会请求该地址获取文件内容。
|
||||
{{% /alert %}}
|
||||
|
||||
{{< /markdownify >}}
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
### 3. 获取文件阅读链接(用于查看原文)
|
||||
|
||||
{{< tabs tabTotal="2" >}}
|
||||
{{< tab tabName="请求示例" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
id 为文件的 id。
|
||||
|
||||
```bash
|
||||
curl --location --request GET '{{baseURL}}/v1/file/read?id=xx' \
|
||||
--header 'Authorization: Bearer {{authorization}}'
|
||||
```
|
||||
|
||||
{{< /markdownify >}}
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab tabName="响应示例" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"url": "xxxx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{% alert icon=" " context="success" %}}
|
||||
- url - 文件访问链接,拿到后会自动打开。
|
||||
{{% /alert %}}
|
||||
|
||||
{{< /markdownify >}}
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
|
@@ -23,4 +23,17 @@ weight: 408
|
||||
- 文件阅读ID:通常情况下,文件访问URL是临时的。如果希望永久可以访问,你需要使用该文件阅读ID,并配合上“外部预览地址”,跳转至新的阅读地址进行原文件访问。
|
||||
- 文件名:默认会自动解析文件访问URL上的文件名。如果你手动填写,将会以手动填写的值为准。
|
||||
|
||||
[点击查看API导入文档](/docs/development/openapi/dataset/#创建一个外部文件库集合商业版)
|
||||
[点击查看API导入文档](/docs/development/openapi/dataset/#创建一个外部文件库集合商业版)
|
||||
|
||||
## API 文件库替代方案
|
||||
|
||||
4.8.15 提供了新的知识库类型 - API 文件库,对外部文件知识库做了进一步的拓展
|
||||
|
||||
通过对接口进行简单的调整,就能使用 API 文件库代替外部文件知识库的功能
|
||||
|
||||
你可以直接将外部文件知识库中的外部预览地址,作为 API 文件库接口规范中获取文件阅读链接的接口返回
|
||||
|
||||
然后再以相同的 baseURL 实现获取文件列表和获取单个文件内容这两个接口
|
||||
|
||||
这样就能轻松地使用 API 文件库替代原有的外部文件知识库,更多详细的内容见 API 文件库的文档
|
||||
|
||||
|
@@ -10,7 +10,8 @@
|
||||
"postinstall": "sh ./scripts/postinstall.sh",
|
||||
"initIcon": "node ./scripts/icon/init.js",
|
||||
"previewIcon": "node ./scripts/icon/index.js",
|
||||
"api:gen": "tsc ./scripts/openapi/index.ts && node ./scripts/openapi/index.js && npx @redocly/cli build-docs ./scripts/openapi/openapi.json -o ./projects/app/public/openapi/index.html"
|
||||
"api:gen": "tsc ./scripts/openapi/index.ts && node ./scripts/openapi/index.js && npx @redocly/cli build-docs ./scripts/openapi/openapi.json -o ./projects/app/public/openapi/index.html",
|
||||
"create:i18n": "node ./scripts/i18n/index.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@chakra-ui/cli": "^2.4.1",
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
import { ErrType } from '../errorCode';
|
||||
|
||||
/* dataset: 501000 */
|
||||
@@ -9,9 +10,19 @@ export enum DatasetErrEnum {
|
||||
unAuthDatasetData = 'unAuthDatasetData',
|
||||
unAuthDatasetFile = 'unAuthDatasetFile',
|
||||
unLinkCollection = 'unLinkCollection',
|
||||
invalidVectorModelOrQAModel = 'invalidVectorModelOrQAModel'
|
||||
invalidVectorModelOrQAModel = 'invalidVectorModelOrQAModel',
|
||||
notSupportSync = 'notSupportSync',
|
||||
sameApiCollection = 'sameApiCollection'
|
||||
}
|
||||
const datasetErr = [
|
||||
{
|
||||
statusText: DatasetErrEnum.sameApiCollection,
|
||||
message: i18nT('dataset:same_api_collection')
|
||||
},
|
||||
{
|
||||
statusText: DatasetErrEnum.notSupportSync,
|
||||
message: i18nT('dataset:collection_not_support_sync')
|
||||
},
|
||||
{
|
||||
statusText: DatasetErrEnum.unExist,
|
||||
message: 'core.dataset.error.unExistDataset'
|
||||
|
@@ -5,7 +5,8 @@ export enum UserErrEnum {
|
||||
unAuthUser = 'unAuthUser',
|
||||
unAuthRole = 'unAuthRole',
|
||||
binVisitor = 'binVisitor',
|
||||
balanceNotEnough = 'balanceNotEnough'
|
||||
balanceNotEnough = 'balanceNotEnough',
|
||||
unAuthSso = 'unAuthSso'
|
||||
}
|
||||
const errList = [
|
||||
{
|
||||
@@ -23,6 +24,10 @@ const errList = [
|
||||
{
|
||||
statusText: UserErrEnum.balanceNotEnough,
|
||||
message: i18nT('common:code_error.user_error.balance_not_enough')
|
||||
},
|
||||
{
|
||||
statusText: UserErrEnum.unAuthSso,
|
||||
message: i18nT('user:sso_auth_failed')
|
||||
}
|
||||
];
|
||||
export default errList.reduce((acc, cur, index) => {
|
||||
|
@@ -95,20 +95,23 @@ export const markdownProcess = async ({
|
||||
};
|
||||
|
||||
export const matchMdImgTextAndUpload = (text: string) => {
|
||||
const base64Regex = /"(data:image\/[^;]+;base64[^"]+)"/g;
|
||||
const base64Regex = /!\[([^\]]*)\]\((data:image\/[^;]+;base64[^)]+)\)/g;
|
||||
const imageList: ImageType[] = [];
|
||||
const images = Array.from(text.match(base64Regex) || []);
|
||||
for (const image of images) {
|
||||
|
||||
text = text.replace(base64Regex, (match, altText, base64Url) => {
|
||||
const uuid = `IMAGE_${getNanoid(12)}_IMAGE`;
|
||||
const mime = image.split(';')[0].split(':')[1];
|
||||
const base64 = image.split(',')[1];
|
||||
text = text.replace(image, uuid);
|
||||
const mime = base64Url.split(';')[0].split(':')[1];
|
||||
const base64 = base64Url.split(',')[1];
|
||||
|
||||
imageList.push({
|
||||
uuid,
|
||||
base64,
|
||||
mime
|
||||
});
|
||||
}
|
||||
|
||||
// 保持原有的 alt 文本,只替换 base64 部分
|
||||
return ``;
|
||||
});
|
||||
|
||||
return {
|
||||
text,
|
||||
|
@@ -182,7 +182,7 @@ const commonSplit = (props: SplitProps): SplitResponse => {
|
||||
title: matchTitle
|
||||
};
|
||||
})
|
||||
.filter((item) => item.text?.trim());
|
||||
.filter((item) => !!item.title || !!item.text?.trim());
|
||||
};
|
||||
|
||||
/* Gets the overlap at the end of a text as the beginning of the next block */
|
||||
@@ -267,8 +267,10 @@ const commonSplit = (props: SplitProps): SplitResponse => {
|
||||
parentTitle: parentTitle + item.title
|
||||
});
|
||||
|
||||
const lastChunk = innerChunks[innerChunks.length - 1];
|
||||
if (!lastChunk) continue;
|
||||
if (innerChunks.length === 0) {
|
||||
chunks.push(`${parentTitle}${item.title}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
chunks.push(
|
||||
...innerChunks.map(
|
||||
|
10
packages/global/common/system/types/index.d.ts
vendored
@@ -10,6 +10,14 @@ import type {
|
||||
} from '../../../core/ai/model.d';
|
||||
import { SubTypeEnum } from '../../../support/wallet/sub/constants';
|
||||
|
||||
export type NavbarItemType = {
|
||||
id: string;
|
||||
name: string;
|
||||
avatar: string;
|
||||
url: string;
|
||||
isActive: boolean;
|
||||
};
|
||||
|
||||
/* fastgpt main */
|
||||
export type FastGPTConfigFileType = {
|
||||
feConfigs: FastGPTFeConfigsType;
|
||||
@@ -38,7 +46,6 @@ export type FastGPTFeConfigsType = {
|
||||
concatMd?: string;
|
||||
|
||||
docUrl?: string;
|
||||
chatbotUrl?: string;
|
||||
openAPIDocUrl?: string;
|
||||
systemPluginCourseUrl?: string;
|
||||
appTemplateCourse?: string;
|
||||
@@ -74,6 +81,7 @@ export type FastGPTFeConfigsType = {
|
||||
uploadFileMaxAmount?: number;
|
||||
uploadFileMaxSize?: number;
|
||||
lafEnv?: string;
|
||||
navbarItems?: NavbarItemType[];
|
||||
};
|
||||
|
||||
export type SystemEnvType = {
|
||||
|
@@ -48,3 +48,5 @@ export enum AppTemplateTypeEnum {
|
||||
roleplay = 'roleplay',
|
||||
officeServices = 'office-services'
|
||||
}
|
||||
|
||||
export const defaultDatasetMaxTokens = 16000;
|
||||
|
6
packages/global/core/app/type.d.ts
vendored
@@ -170,3 +170,9 @@ export type AppFileSelectConfigType = {
|
||||
canSelectImg: boolean;
|
||||
maxFiles: number;
|
||||
};
|
||||
|
||||
export type SystemPluginListItemType = {
|
||||
_id: string;
|
||||
name: string;
|
||||
avatar: string;
|
||||
};
|
||||
|
18
packages/global/core/dataset/api.d.ts
vendored
@@ -16,6 +16,7 @@ export type DatasetUpdateBody = {
|
||||
websiteConfig?: DatasetSchemaType['websiteConfig'];
|
||||
externalReadUrl?: DatasetSchemaType['externalReadUrl'];
|
||||
defaultPermission?: DatasetSchemaType['defaultPermission'];
|
||||
apiServer?: DatasetSchemaType['apiServer'];
|
||||
};
|
||||
|
||||
/* ================= collection ===================== */
|
||||
@@ -34,15 +35,18 @@ export type CreateDatasetCollectionParams = DatasetCollectionChunkMetadataType &
|
||||
name: string;
|
||||
type: DatasetCollectionTypeEnum;
|
||||
|
||||
tags?: string[];
|
||||
|
||||
fileId?: string;
|
||||
rawLink?: string;
|
||||
externalFileId?: string;
|
||||
|
||||
externalFileUrl?: string;
|
||||
apiFileId?: string;
|
||||
|
||||
rawTextLength?: number;
|
||||
hashRawText?: string;
|
||||
|
||||
tags?: string[];
|
||||
|
||||
createTime?: Date;
|
||||
};
|
||||
|
||||
export type ApiCreateDatasetCollectionParams = DatasetCollectionChunkMetadataType & {
|
||||
@@ -56,9 +60,17 @@ export type TextCreateDatasetCollectionParams = ApiCreateDatasetCollectionParams
|
||||
export type LinkCreateDatasetCollectionParams = ApiCreateDatasetCollectionParams & {
|
||||
link: string;
|
||||
};
|
||||
export type ApiDatasetCreateDatasetCollectionParams = ApiCreateDatasetCollectionParams & {
|
||||
name: string;
|
||||
apiFileId: string;
|
||||
};
|
||||
export type FileIdCreateDatasetCollectionParams = ApiCreateDatasetCollectionParams & {
|
||||
fileId: string;
|
||||
};
|
||||
export type reTrainingDatasetFileCollectionParams = DatasetCollectionChunkMetadataType & {
|
||||
datasetId: string;
|
||||
collectionId: string;
|
||||
};
|
||||
export type FileCreateDatasetCollectionParams = ApiCreateDatasetCollectionParams & {
|
||||
fileMetadata?: Record<string, any>;
|
||||
collectionMetadata?: Record<string, any>;
|
||||
|
24
packages/global/core/dataset/apiDataset.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
export type APIFileItem = {
|
||||
id: string;
|
||||
parentId: string | null;
|
||||
name: string;
|
||||
type: 'file' | 'folder';
|
||||
updateTime: Date;
|
||||
createTime: Date;
|
||||
};
|
||||
|
||||
export type APIFileServer = {
|
||||
baseUrl: string;
|
||||
authorization: string;
|
||||
};
|
||||
|
||||
export type APIFileListResponse = APIFileItem[];
|
||||
|
||||
export type APIFileContentResponse = {
|
||||
content?: string;
|
||||
previewUrl?: string;
|
||||
};
|
||||
|
||||
export type APIFileReadResponse = {
|
||||
url: string;
|
||||
};
|
@@ -9,7 +9,8 @@ export const getCollectionSourceData = (
|
||||
collection?.fileId ||
|
||||
collection?.rawLink ||
|
||||
collection?.externalFileId ||
|
||||
collection?.externalFileUrl,
|
||||
collection?.externalFileUrl ||
|
||||
collection?.apiFileId,
|
||||
sourceName: collection?.name || ''
|
||||
};
|
||||
};
|
||||
|
@@ -1,9 +1,12 @@
|
||||
import { i18nT } from '../../../web/i18n/utils';
|
||||
|
||||
/* ------------ dataset -------------- */
|
||||
export enum DatasetTypeEnum {
|
||||
folder = 'folder',
|
||||
dataset = 'dataset',
|
||||
websiteDataset = 'websiteDataset', // depp link
|
||||
externalFile = 'externalFile'
|
||||
externalFile = 'externalFile',
|
||||
apiDataset = 'apiDataset'
|
||||
}
|
||||
export const DatasetTypeMap = {
|
||||
[DatasetTypeEnum.folder]: {
|
||||
@@ -25,6 +28,11 @@ export const DatasetTypeMap = {
|
||||
icon: 'core/dataset/externalDatasetOutline',
|
||||
label: 'external_file',
|
||||
collectionLabel: 'common.File'
|
||||
},
|
||||
[DatasetTypeEnum.apiDataset]: {
|
||||
icon: 'core/dataset/externalDatasetOutline',
|
||||
label: 'api_file',
|
||||
collectionLabel: 'common.File'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -34,10 +42,10 @@ export enum DatasetStatusEnum {
|
||||
}
|
||||
export const DatasetStatusMap = {
|
||||
[DatasetStatusEnum.active]: {
|
||||
label: 'core.dataset.status.active'
|
||||
label: i18nT('common:core.dataset.status.active')
|
||||
},
|
||||
[DatasetStatusEnum.syncing]: {
|
||||
label: 'core.dataset.status.syncing'
|
||||
label: i18nT('common:core.dataset.status.syncing')
|
||||
}
|
||||
};
|
||||
|
||||
@@ -48,23 +56,27 @@ export enum DatasetCollectionTypeEnum {
|
||||
|
||||
file = 'file',
|
||||
link = 'link', // one link
|
||||
externalFile = 'externalFile'
|
||||
externalFile = 'externalFile',
|
||||
apiFile = 'apiFile'
|
||||
}
|
||||
export const DatasetCollectionTypeMap = {
|
||||
[DatasetCollectionTypeEnum.folder]: {
|
||||
name: 'core.dataset.folder'
|
||||
name: i18nT('common:core.dataset.folder')
|
||||
},
|
||||
[DatasetCollectionTypeEnum.file]: {
|
||||
name: 'core.dataset.file'
|
||||
name: i18nT('common:core.dataset.file')
|
||||
},
|
||||
[DatasetCollectionTypeEnum.externalFile]: {
|
||||
name: 'core.dataset.externalFile'
|
||||
name: i18nT('common:core.dataset.externalFile')
|
||||
},
|
||||
[DatasetCollectionTypeEnum.link]: {
|
||||
name: 'core.dataset.link'
|
||||
name: i18nT('common:core.dataset.link')
|
||||
},
|
||||
[DatasetCollectionTypeEnum.virtual]: {
|
||||
name: 'core.dataset.Manual collection'
|
||||
name: i18nT('common:core.dataset.Manual collection')
|
||||
},
|
||||
[DatasetCollectionTypeEnum.apiFile]: {
|
||||
name: i18nT('common:core.dataset.apiFile')
|
||||
}
|
||||
};
|
||||
|
||||
@@ -74,10 +86,10 @@ export enum DatasetCollectionSyncResultEnum {
|
||||
}
|
||||
export const DatasetCollectionSyncResultMap = {
|
||||
[DatasetCollectionSyncResultEnum.sameRaw]: {
|
||||
label: 'core.dataset.collection.sync.result.sameRaw'
|
||||
label: i18nT('common:core.dataset.collection.sync.result.sameRaw')
|
||||
},
|
||||
[DatasetCollectionSyncResultEnum.success]: {
|
||||
label: 'core.dataset.collection.sync.result.success'
|
||||
label: i18nT('common:core.dataset.collection.sync.result.success')
|
||||
}
|
||||
};
|
||||
|
||||
@@ -89,7 +101,9 @@ export enum ImportDataSourceEnum {
|
||||
fileLink = 'fileLink',
|
||||
fileCustom = 'fileCustom',
|
||||
csvTable = 'csvTable',
|
||||
externalFile = 'externalFile'
|
||||
externalFile = 'externalFile',
|
||||
apiDataset = 'apiDataset',
|
||||
reTraining = 'reTraining'
|
||||
}
|
||||
|
||||
export enum TrainingModeEnum {
|
||||
@@ -100,18 +114,18 @@ export enum TrainingModeEnum {
|
||||
|
||||
export const TrainingTypeMap = {
|
||||
[TrainingModeEnum.chunk]: {
|
||||
label: 'core.dataset.training.Chunk mode',
|
||||
tooltip: 'core.dataset.import.Chunk Split Tip',
|
||||
label: i18nT('common:core.dataset.training.Chunk mode'),
|
||||
tooltip: i18nT('common:core.dataset.import.Chunk Split Tip'),
|
||||
openSource: true
|
||||
},
|
||||
[TrainingModeEnum.auto]: {
|
||||
label: 'core.dataset.training.Auto mode',
|
||||
tooltip: 'core.dataset.training.Auto mode Tip',
|
||||
label: i18nT('common:core.dataset.training.Auto mode'),
|
||||
tooltip: i18nT('common:core.dataset.training.Auto mode Tip'),
|
||||
openSource: false
|
||||
},
|
||||
[TrainingModeEnum.qa]: {
|
||||
label: 'core.dataset.training.QA mode',
|
||||
tooltip: 'core.dataset.import.QA Import Tip',
|
||||
label: i18nT('common:core.dataset.training.QA mode'),
|
||||
tooltip: i18nT('common:core.dataset.import.QA Import Tip'),
|
||||
openSource: true
|
||||
}
|
||||
};
|
||||
@@ -126,20 +140,20 @@ export enum DatasetSearchModeEnum {
|
||||
export const DatasetSearchModeMap = {
|
||||
[DatasetSearchModeEnum.embedding]: {
|
||||
icon: 'core/dataset/modeEmbedding',
|
||||
title: 'core.dataset.search.mode.embedding',
|
||||
desc: 'core.dataset.search.mode.embedding desc',
|
||||
title: i18nT('common:core.dataset.search.mode.embedding'),
|
||||
desc: i18nT('common:core.dataset.search.mode.embedding desc'),
|
||||
value: DatasetSearchModeEnum.embedding
|
||||
},
|
||||
[DatasetSearchModeEnum.fullTextRecall]: {
|
||||
icon: 'core/dataset/fullTextRecall',
|
||||
title: 'core.dataset.search.mode.fullTextRecall',
|
||||
desc: 'core.dataset.search.mode.fullTextRecall desc',
|
||||
title: i18nT('common:core.dataset.search.mode.fullTextRecall'),
|
||||
desc: i18nT('common:core.dataset.search.mode.fullTextRecall desc'),
|
||||
value: DatasetSearchModeEnum.fullTextRecall
|
||||
},
|
||||
[DatasetSearchModeEnum.mixedRecall]: {
|
||||
icon: 'core/dataset/mixedRecall',
|
||||
title: 'core.dataset.search.mode.mixedRecall',
|
||||
desc: 'core.dataset.search.mode.mixedRecall desc',
|
||||
title: i18nT('common:core.dataset.search.mode.mixedRecall'),
|
||||
desc: i18nT('common:core.dataset.search.mode.mixedRecall desc'),
|
||||
value: DatasetSearchModeEnum.mixedRecall
|
||||
}
|
||||
};
|
||||
@@ -152,23 +166,23 @@ export enum SearchScoreTypeEnum {
|
||||
}
|
||||
export const SearchScoreTypeMap = {
|
||||
[SearchScoreTypeEnum.embedding]: {
|
||||
label: 'core.dataset.search.score.embedding',
|
||||
desc: 'core.dataset.search.score.embedding desc',
|
||||
label: i18nT('common:core.dataset.search.score.embedding'),
|
||||
desc: i18nT('common:core.dataset.search.score.embedding desc'),
|
||||
showScore: true
|
||||
},
|
||||
[SearchScoreTypeEnum.fullText]: {
|
||||
label: 'core.dataset.search.score.fullText',
|
||||
desc: 'core.dataset.search.score.fullText desc',
|
||||
label: i18nT('common:core.dataset.search.score.fullText'),
|
||||
desc: i18nT('common:core.dataset.search.score.fullText desc'),
|
||||
showScore: false
|
||||
},
|
||||
[SearchScoreTypeEnum.reRank]: {
|
||||
label: 'core.dataset.search.score.reRank',
|
||||
desc: 'core.dataset.search.score.reRank desc',
|
||||
label: i18nT('common:core.dataset.search.score.reRank'),
|
||||
desc: i18nT('common:core.dataset.search.score.reRank desc'),
|
||||
showScore: true
|
||||
},
|
||||
[SearchScoreTypeEnum.rrf]: {
|
||||
label: 'core.dataset.search.score.rrf',
|
||||
desc: 'core.dataset.search.score.rrf desc',
|
||||
label: i18nT('common:core.dataset.search.score.rrf'),
|
||||
desc: i18nT('common:core.dataset.search.score.rrf desc'),
|
||||
showScore: false
|
||||
}
|
||||
};
|
||||
@@ -180,5 +194,7 @@ export const LinkCollectionIcon = 'common/linkBlue';
|
||||
export enum DatasetSourceReadTypeEnum {
|
||||
fileLocal = 'fileLocal',
|
||||
link = 'link',
|
||||
externalFile = 'externalFile'
|
||||
externalFile = 'externalFile',
|
||||
apiFile = 'apiFile',
|
||||
reTraining = 'reTraining'
|
||||
}
|
||||
|
@@ -1,14 +0,0 @@
|
||||
import { DatasetSourceReadTypeEnum, ImportDataSourceEnum } from './constants';
|
||||
|
||||
export const importType2ReadType = (type: ImportDataSourceEnum) => {
|
||||
if (type === ImportDataSourceEnum.csvTable || type === ImportDataSourceEnum.fileLocal) {
|
||||
return DatasetSourceReadTypeEnum.fileLocal;
|
||||
}
|
||||
if (type === ImportDataSourceEnum.fileLink) {
|
||||
return DatasetSourceReadTypeEnum.link;
|
||||
}
|
||||
if (type === ImportDataSourceEnum.externalFile) {
|
||||
return DatasetSourceReadTypeEnum.externalFile;
|
||||
}
|
||||
return DatasetSourceReadTypeEnum.link;
|
||||
};
|
5
packages/global/core/dataset/type.d.ts
vendored
@@ -10,6 +10,7 @@ import {
|
||||
} from './constants';
|
||||
import { DatasetPermission } from '../../support/permission/dataset/controller';
|
||||
import { Permission } from '../../support/permission/controller';
|
||||
import { APIFileServer } from './apiDataset';
|
||||
|
||||
export type DatasetSchemaType = {
|
||||
_id: string;
|
||||
@@ -30,10 +31,11 @@ export type DatasetSchemaType = {
|
||||
url: string;
|
||||
selector: string;
|
||||
};
|
||||
externalReadUrl?: string;
|
||||
inheritPermission: boolean;
|
||||
apiServer?: APIFileServer;
|
||||
|
||||
// abandon
|
||||
externalReadUrl?: string;
|
||||
defaultPermission?: number;
|
||||
};
|
||||
|
||||
@@ -64,6 +66,7 @@ export type DatasetCollectionSchemaType = {
|
||||
rawTextLength?: number;
|
||||
hashRawText?: string;
|
||||
externalFileUrl?: string; // external import url
|
||||
apiFileId?: string; // api file id
|
||||
metadata?: {
|
||||
webPageSelector?: string;
|
||||
relatedImgId?: string; // The id of the associated image collections
|
||||
|
3
packages/global/core/plugin/type.d.ts
vendored
@@ -39,6 +39,7 @@ export type PluginTemplateType = PluginRuntimeType & {
|
||||
};
|
||||
|
||||
export type PluginRuntimeType = {
|
||||
id: string;
|
||||
teamId?: string;
|
||||
name: string;
|
||||
avatar: string;
|
||||
@@ -46,4 +47,6 @@ export type PluginRuntimeType = {
|
||||
isTool?: boolean;
|
||||
nodes: StoreNodeItemType[];
|
||||
edges: StoreEdgeItemType[];
|
||||
currentCost?: number;
|
||||
hasTokenFee?: boolean;
|
||||
};
|
||||
|
11
packages/global/core/workflow/runtime/type.d.ts
vendored
@@ -82,17 +82,6 @@ export type RuntimeNodeItemType = {
|
||||
version: string;
|
||||
};
|
||||
|
||||
export type PluginRuntimeType = {
|
||||
id: string;
|
||||
teamId?: string;
|
||||
name: string;
|
||||
avatar: string;
|
||||
showStatus?: boolean;
|
||||
currentCost?: number;
|
||||
nodes: StoreNodeItemType[];
|
||||
edges: StoreEdgeItemType[];
|
||||
};
|
||||
|
||||
export type RuntimeEdgeItemType = StoreEdgeItemType & {
|
||||
status: 'waiting' | 'active' | 'skipped';
|
||||
};
|
||||
|
@@ -283,68 +283,47 @@ export const getReferenceVariableValue = ({
|
||||
export function replaceEditorVariable({
|
||||
text,
|
||||
nodes,
|
||||
variables,
|
||||
runningNode
|
||||
variables
|
||||
}: {
|
||||
text: any;
|
||||
nodes: RuntimeNodeItemType[];
|
||||
variables: Record<string, any>; // global variables
|
||||
runningNode: RuntimeNodeItemType;
|
||||
}) {
|
||||
if (typeof text !== 'string') return text;
|
||||
|
||||
const globalVariables = Object.keys(variables).map((key) => {
|
||||
return {
|
||||
nodeId: VARIABLE_NODE_ID,
|
||||
id: key,
|
||||
value: variables[key]
|
||||
};
|
||||
});
|
||||
const variablePattern = /\{\{\$([^.]+)\.([^$]+)\$\}\}/g;
|
||||
const matches = [...text.matchAll(variablePattern)];
|
||||
if (matches.length === 0) return text;
|
||||
|
||||
// Upstream node outputs
|
||||
const nodeVariables = nodes
|
||||
.map((node) => {
|
||||
return node.outputs.map((output) => {
|
||||
return {
|
||||
nodeId: node.nodeId,
|
||||
id: output.id,
|
||||
value: output.value
|
||||
};
|
||||
});
|
||||
})
|
||||
.flat();
|
||||
matches.forEach((match) => {
|
||||
const nodeId = match[1];
|
||||
const id = match[2];
|
||||
|
||||
// Get runningNode inputs(Will be replaced with reference)
|
||||
const customInputs = runningNode.inputs.flatMap((item) => {
|
||||
return [
|
||||
{
|
||||
id: item.key,
|
||||
value: getReferenceVariableValue({
|
||||
value: item.value,
|
||||
nodes,
|
||||
variables
|
||||
}),
|
||||
nodeId: runningNode.nodeId
|
||||
const variableVal = (() => {
|
||||
if (nodeId === VARIABLE_NODE_ID) {
|
||||
return variables[id];
|
||||
}
|
||||
];
|
||||
});
|
||||
// Find upstream node input/output
|
||||
const node = nodes.find((node) => node.nodeId === nodeId);
|
||||
if (!node) return;
|
||||
|
||||
const allVariables = [...globalVariables, ...nodeVariables, ...customInputs];
|
||||
const output = node.outputs.find((output) => output.id === id);
|
||||
if (output) return output.value;
|
||||
|
||||
// Replace {{$xxx.xxx$}} to value
|
||||
for (const key in allVariables) {
|
||||
const variable = allVariables[key];
|
||||
const val = variable.value;
|
||||
const formatVal = (() => {
|
||||
if (val === undefined) return '';
|
||||
if (val === null) return 'null';
|
||||
|
||||
return typeof val === 'object' ? JSON.stringify(val) : String(val);
|
||||
const input = node.inputs.find((input) => input.key === id);
|
||||
if (input) return getReferenceVariableValue({ value: input.value, nodes, variables });
|
||||
})();
|
||||
|
||||
const regex = new RegExp(`\\{\\{\\$(${variable.nodeId}\\.${variable.id})\\$\\}\\}`, 'g');
|
||||
const formatVal = (() => {
|
||||
if (variableVal === undefined) return 'undefined';
|
||||
if (variableVal === null) return 'null';
|
||||
return typeof variableVal === 'object' ? JSON.stringify(variableVal) : String(variableVal);
|
||||
})();
|
||||
|
||||
const regex = new RegExp(`\\{\\{\\$(${nodeId}\\.${id})\\$\\}\\}`, 'g');
|
||||
text = text.replace(regex, formatVal);
|
||||
}
|
||||
});
|
||||
|
||||
return text || '';
|
||||
}
|
||||
|
||||
|
@@ -63,15 +63,20 @@ export type TemplateMarketListItemType = {
|
||||
// system plugin
|
||||
export type SystemPluginTemplateItemType = WorkflowTemplateType & {
|
||||
customWorkflow?: string;
|
||||
associatedPluginId?: string;
|
||||
userGuide?: string;
|
||||
|
||||
templateType: FlowNodeTemplateTypeEnum;
|
||||
templateType: string;
|
||||
isTool?: boolean;
|
||||
|
||||
// commercial plugin config
|
||||
originCost: number; // n points/one time
|
||||
currentCost: number;
|
||||
hasTokenFee: boolean;
|
||||
pluginOrder: number;
|
||||
|
||||
isActive?: boolean;
|
||||
isOfficial?: boolean;
|
||||
inputConfig?: {
|
||||
// Render config input form. Find the corresponding node and replace the variable directly
|
||||
key: string;
|
||||
|
8
packages/global/core/workflow/type/node.d.ts
vendored
@@ -54,7 +54,7 @@ type HandleType = {
|
||||
// system template
|
||||
export type FlowNodeTemplateType = FlowNodeCommonType & {
|
||||
id: string; // node id, unique
|
||||
templateType: FlowNodeTemplateTypeEnum;
|
||||
templateType: string;
|
||||
|
||||
// show handle
|
||||
sourceHandle?: HandleType;
|
||||
@@ -76,7 +76,7 @@ export type NodeTemplateListItemType = {
|
||||
flowNodeType: FlowNodeTypeEnum; // render node card
|
||||
parentId?: ParentIdType;
|
||||
isFolder?: boolean;
|
||||
templateType: FlowNodeTemplateTypeEnum;
|
||||
templateType: string;
|
||||
avatar?: string;
|
||||
name: string;
|
||||
intro?: string; // template list intro
|
||||
@@ -85,10 +85,12 @@ export type NodeTemplateListItemType = {
|
||||
author?: string;
|
||||
unique?: boolean; // 唯一的
|
||||
currentCost?: number; // 当前积分消耗
|
||||
hasTokenFee?: boolean; // 是否配置积分
|
||||
instructions?: string; // 使用说明
|
||||
};
|
||||
|
||||
export type NodeTemplateListType = {
|
||||
type: FlowNodeTemplateTypeEnum;
|
||||
type: string;
|
||||
label: string;
|
||||
list: NodeTemplateListItemType[];
|
||||
}[];
|
||||
|
@@ -15,5 +15,6 @@ export enum OAuthEnum {
|
||||
github = 'github',
|
||||
google = 'google',
|
||||
wechat = 'wechat',
|
||||
microsoft = 'microsoft'
|
||||
microsoft = 'microsoft',
|
||||
sso = 'sso'
|
||||
}
|
||||
|
1
packages/global/support/wallet/sub/api.d.ts
vendored
@@ -12,6 +12,7 @@ export type StandardSubPlanUpdateResponse = {
|
||||
payPrice?: number;
|
||||
planPrice: number;
|
||||
planPointPrice: number;
|
||||
name?: string;
|
||||
|
||||
currentMode: `${SubModeEnum}`;
|
||||
nextMode: `${SubModeEnum}`;
|
||||
|
2
packages/global/support/wallet/sub/type.d.ts
vendored
@@ -2,6 +2,7 @@ import { StandardSubLevelEnum, SubModeEnum, SubTypeEnum } from './constants';
|
||||
|
||||
// Content of plan
|
||||
export type TeamStandardSubPlanItemType = {
|
||||
name?: string;
|
||||
price: number; // read price / month
|
||||
pointPrice: number; // read price/ one thousand
|
||||
totalPoints: number; // n
|
||||
@@ -24,6 +25,7 @@ export type StandSubPlanLevelMapType = Record<
|
||||
|
||||
export type SubPlanType = {
|
||||
[SubTypeEnum.standard]: StandSubPlanLevelMapType;
|
||||
planDescriptionUrl?: string;
|
||||
[SubTypeEnum.extraDatasetSize]: {
|
||||
price: number;
|
||||
};
|
||||
|
@@ -40,7 +40,8 @@ export const getCommunityPlugins = () => {
|
||||
id: `${PluginSourceEnum.community}-${name}`,
|
||||
isFolder,
|
||||
parentId,
|
||||
isActive: true
|
||||
isActive: true,
|
||||
isOfficial: true
|
||||
};
|
||||
});
|
||||
};
|
||||
|
2
packages/plugins/type.d.ts
vendored
@@ -1,6 +1,7 @@
|
||||
import { PluginTemplateType } from '@fastgpt/global/core/plugin/type.d';
|
||||
import { systemPluginResponseEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
|
||||
import { PluginGroupSchemaType } from '@fastgpt/service/core/app/plugin/type';
|
||||
|
||||
export type SystemPluginResponseType = Promise<Record<string, any>>;
|
||||
export type SystemPluginSpecialResponse = {
|
||||
@@ -10,6 +11,7 @@ export type SystemPluginSpecialResponse = {
|
||||
};
|
||||
|
||||
declare global {
|
||||
var pluginGroups: PluginGroupSchemaType[];
|
||||
var systemPlugins: SystemPluginTemplateItemType[];
|
||||
var systemPluginCb: Record<string, (e: any) => SystemPluginResponseType>;
|
||||
}
|
||||
|
@@ -83,8 +83,8 @@ export function request(url: string, data: any, config: ConfigType, method: Meth
|
||||
baseURL: serverRequestBaseUrl,
|
||||
url,
|
||||
method,
|
||||
data: ['POST', 'PUT'].includes(method) ? data : null,
|
||||
params: !['POST', 'PUT'].includes(method) ? data : null,
|
||||
data: ['POST', 'PUT'].includes(method) ? data : undefined,
|
||||
params: !['POST', 'PUT'].includes(method) ? data : undefined,
|
||||
...config // custom config
|
||||
})
|
||||
.then((res) => checkRes(res.data))
|
||||
|
@@ -66,6 +66,7 @@ export const readRawContentByFileBuffer = async ({
|
||||
return;
|
||||
|
||||
const start = Date.now();
|
||||
addLog.info('Parsing files from an external service');
|
||||
|
||||
const data = new FormData();
|
||||
data.append('file', buffer, {
|
||||
@@ -88,7 +89,7 @@ export const readRawContentByFileBuffer = async ({
|
||||
}
|
||||
});
|
||||
|
||||
addLog.info(`Use custom read file service, time: ${Date.now() - start}ms`);
|
||||
addLog.info(`Custom file parsing is complete, time: ${Date.now() - start}ms`);
|
||||
|
||||
const rawText = response.data.markdown;
|
||||
const { text, imageList } = matchMdImgTextAndUpload(rawText);
|
||||
|
@@ -31,6 +31,8 @@ export const jsonRes = <T = any>(
|
||||
clearCookie(res);
|
||||
}
|
||||
|
||||
addLog.error(`Api response error: ${url}`, ERROR_RESPONSE[errResponseKey]);
|
||||
|
||||
return res.json(ERROR_RESPONSE[errResponseKey]);
|
||||
}
|
||||
|
||||
|
@@ -5,6 +5,7 @@ import { countGptMessagesTokens } from '../../../common/string/tiktoken/index';
|
||||
import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
|
||||
import { getLLMModel } from '../model';
|
||||
import { llmCompletionsBodyFormat } from '../utils';
|
||||
import { addLog } from '../../../common/system/log';
|
||||
|
||||
/*
|
||||
query extension - 问题扩展
|
||||
@@ -183,7 +184,7 @@ A: ${chatBg}
|
||||
tokens: await countGptMessagesTokens(messages)
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
addLog.error(`Query extension error`, error);
|
||||
return {
|
||||
rawQuery: query,
|
||||
extensionQueries: [],
|
||||
|
@@ -51,7 +51,6 @@ export function reRankRecall({
|
||||
}));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
addLog.error('rerank error', err);
|
||||
|
||||
return [];
|
||||
|
@@ -5,39 +5,44 @@ import { getLLMModel } from '../ai/model';
|
||||
import { MongoApp } from './schema';
|
||||
|
||||
export const beforeUpdateAppFormat = <T extends AppSchema['modules'] | undefined>({
|
||||
nodes
|
||||
nodes,
|
||||
isPlugin
|
||||
}: {
|
||||
nodes: T;
|
||||
isPlugin: boolean;
|
||||
}) => {
|
||||
if (nodes) {
|
||||
let maxTokens = 3000;
|
||||
// Check dataset maxTokens
|
||||
if (isPlugin) {
|
||||
let maxTokens = 16000;
|
||||
|
||||
nodes.forEach((item) => {
|
||||
if (
|
||||
item.flowNodeType === FlowNodeTypeEnum.chatNode ||
|
||||
item.flowNodeType === FlowNodeTypeEnum.tools
|
||||
) {
|
||||
const model =
|
||||
item.inputs.find((item) => item.key === NodeInputKeyEnum.aiModel)?.value || '';
|
||||
const chatModel = getLLMModel(model);
|
||||
const quoteMaxToken = chatModel.quoteMaxToken || 3000;
|
||||
nodes.forEach((item) => {
|
||||
if (
|
||||
item.flowNodeType === FlowNodeTypeEnum.chatNode ||
|
||||
item.flowNodeType === FlowNodeTypeEnum.tools
|
||||
) {
|
||||
const model =
|
||||
item.inputs.find((item) => item.key === NodeInputKeyEnum.aiModel)?.value || '';
|
||||
const chatModel = getLLMModel(model);
|
||||
const quoteMaxToken = chatModel.quoteMaxToken || 16000;
|
||||
|
||||
maxTokens = Math.max(maxTokens, quoteMaxToken);
|
||||
}
|
||||
});
|
||||
maxTokens = Math.max(maxTokens, quoteMaxToken);
|
||||
}
|
||||
});
|
||||
|
||||
nodes.forEach((item) => {
|
||||
if (item.flowNodeType === FlowNodeTypeEnum.datasetSearchNode) {
|
||||
item.inputs.forEach((input) => {
|
||||
if (input.key === NodeInputKeyEnum.datasetMaxTokens) {
|
||||
const val = input.value as number;
|
||||
if (val > maxTokens) {
|
||||
input.value = maxTokens;
|
||||
nodes.forEach((item) => {
|
||||
if (item.flowNodeType === FlowNodeTypeEnum.datasetSearchNode) {
|
||||
item.inputs.forEach((input) => {
|
||||
if (input.key === NodeInputKeyEnum.datasetMaxTokens) {
|
||||
const val = input.value as number;
|
||||
if (val > maxTokens) {
|
||||
input.value = maxTokens;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
@@ -2,7 +2,6 @@ import { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/node.d'
|
||||
import { FlowNodeTypeEnum, defaultNodeVersion } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { appData2FlowNodeIO, pluginData2FlowNodeIO } from '@fastgpt/global/core/workflow/utils';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
import type { PluginRuntimeType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { getHandleConfig } from '@fastgpt/global/core/workflow/template/utils';
|
||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||
@@ -11,6 +10,9 @@ import { MongoApp } from '../schema';
|
||||
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
|
||||
import { getSystemPluginTemplates } from '../../../../plugins/register';
|
||||
import { getAppLatestVersion, getAppVersionById } from '../version/controller';
|
||||
import { PluginRuntimeType } from '@fastgpt/global/core/plugin/type';
|
||||
import { MongoSystemPlugin } from './systemPluginSchema';
|
||||
import { PluginErrEnum } from '@fastgpt/global/common/error/code/plugin';
|
||||
|
||||
/*
|
||||
plugin id rule:
|
||||
@@ -37,15 +39,45 @@ export async function splitCombinePluginId(id: string) {
|
||||
|
||||
type ChildAppType = SystemPluginTemplateItemType & { teamId?: string };
|
||||
const getSystemPluginTemplateById = async (
|
||||
pluginId: string
|
||||
pluginId: string,
|
||||
versionId?: string
|
||||
): Promise<SystemPluginTemplateItemType> => {
|
||||
const item = getSystemPluginTemplates().find((plugin) => plugin.id === pluginId);
|
||||
if (!item) return Promise.reject('plugin not found');
|
||||
if (!item) return Promise.reject(PluginErrEnum.unAuth);
|
||||
|
||||
return cloneDeep(item);
|
||||
const plugin = cloneDeep(item);
|
||||
|
||||
if (plugin.associatedPluginId) {
|
||||
// The verification plugin is set as a system plugin
|
||||
const systemPlugin = await MongoSystemPlugin.findOne(
|
||||
{ pluginId: plugin.id, 'customConfig.associatedPluginId': plugin.associatedPluginId },
|
||||
'associatedPluginId'
|
||||
).lean();
|
||||
if (!systemPlugin) return Promise.reject(PluginErrEnum.unAuth);
|
||||
|
||||
const app = await MongoApp.findById(plugin.associatedPluginId).lean();
|
||||
if (!app) return Promise.reject(PluginErrEnum.unAuth);
|
||||
|
||||
const version = versionId
|
||||
? await getAppVersionById({
|
||||
appId: plugin.associatedPluginId,
|
||||
versionId,
|
||||
app
|
||||
})
|
||||
: await getAppLatestVersion(plugin.associatedPluginId, app);
|
||||
if (!version.versionId) return Promise.reject('App version not found');
|
||||
|
||||
plugin.workflow = {
|
||||
nodes: version.nodes,
|
||||
edges: version.edges,
|
||||
chatConfig: version.chatConfig
|
||||
};
|
||||
plugin.version = versionId || String(version.versionId);
|
||||
}
|
||||
return plugin;
|
||||
};
|
||||
|
||||
/* format plugin modules to plugin preview module */
|
||||
/* Format plugin to workflow preview node data */
|
||||
export async function getChildAppPreviewNode({
|
||||
id
|
||||
}: {
|
||||
@@ -77,7 +109,9 @@ export async function getChildAppPreviewNode({
|
||||
templateType: FlowNodeTemplateTypeEnum.teamApp,
|
||||
version: version.versionId,
|
||||
originCost: 0,
|
||||
currentCost: 0
|
||||
currentCost: 0,
|
||||
hasTokenFee: false,
|
||||
pluginOrder: 0
|
||||
};
|
||||
} else {
|
||||
return getSystemPluginTemplateById(pluginId);
|
||||
@@ -147,10 +181,12 @@ export async function getChildAppRuntimeById(
|
||||
// 用不到
|
||||
version: item?.pluginData?.nodeVersion || defaultNodeVersion,
|
||||
originCost: 0,
|
||||
currentCost: 0
|
||||
currentCost: 0,
|
||||
hasTokenFee: false,
|
||||
pluginOrder: 0
|
||||
};
|
||||
} else {
|
||||
return getSystemPluginTemplateById(pluginId);
|
||||
return getSystemPluginTemplateById(pluginId, versionId);
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -162,6 +198,7 @@ export async function getChildAppRuntimeById(
|
||||
showStatus: app.showStatus,
|
||||
currentCost: app.currentCost,
|
||||
nodes: app.workflow.nodes,
|
||||
edges: app.workflow.edges
|
||||
edges: app.workflow.edges,
|
||||
hasTokenFee: app.hasTokenFee
|
||||
};
|
||||
}
|
||||
|
35
packages/service/core/app/plugin/pluginGroupSchema.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { connectionMongo, getMongoModel } from '../../../common/mongo/index';
|
||||
import { PluginGroupSchemaType, TGroupType } from './type';
|
||||
const { Schema } = connectionMongo;
|
||||
|
||||
export const collectionName = 'app_plugin_groups';
|
||||
|
||||
const PluginGroupSchema = new Schema({
|
||||
groupId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
groupAvatar: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
groupName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
groupTypes: {
|
||||
type: Array<TGroupType>,
|
||||
default: []
|
||||
},
|
||||
groupOrder: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
|
||||
PluginGroupSchema.index({ groupId: 1 }, { unique: true });
|
||||
|
||||
export const MongoPluginGroups = getMongoModel<PluginGroupSchemaType>(
|
||||
collectionName,
|
||||
PluginGroupSchema
|
||||
);
|
@@ -25,12 +25,20 @@ const SystemPluginSchema = new Schema({
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
hasTokenFee: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
pluginOrder: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
customConfig: Object
|
||||
});
|
||||
|
||||
SystemPluginSchema.index({ pluginId: 1 });
|
||||
|
||||
export const MongoSystemPluginSchema = getMongoModel<SystemPluginConfigSchemaType>(
|
||||
export const MongoSystemPlugin = getMongoModel<SystemPluginConfigSchemaType>(
|
||||
collectionName,
|
||||
SystemPluginSchema
|
||||
);
|
||||
|
20
packages/service/core/app/plugin/type.d.ts
vendored
@@ -1,3 +1,4 @@
|
||||
import { SystemPluginListItemType } from '@fastgpt/global/core/app/type';
|
||||
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import {
|
||||
SystemPluginTemplateItemType,
|
||||
@@ -9,7 +10,9 @@ export type SystemPluginConfigSchemaType = {
|
||||
|
||||
originCost: number; // n points/one time
|
||||
currentCost: number;
|
||||
hasTokenFee: boolean;
|
||||
isActive: boolean;
|
||||
pluginOrder: number;
|
||||
inputConfig: SystemPluginTemplateItemType['inputConfig'];
|
||||
|
||||
customConfig?: {
|
||||
@@ -19,6 +22,21 @@ export type SystemPluginConfigSchemaType = {
|
||||
version: string;
|
||||
weight?: number;
|
||||
workflow: WorkflowTemplateBasicType;
|
||||
templateType: FlowNodeTemplateTypeEnum;
|
||||
templateType: string;
|
||||
associatedPluginId: string;
|
||||
userGuide: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type TGroupType = {
|
||||
typeName: string;
|
||||
typeId: string;
|
||||
};
|
||||
|
||||
export type PluginGroupSchemaType = {
|
||||
groupId: string;
|
||||
groupAvatar: string;
|
||||
groupName: string;
|
||||
groupTypes: TGroupType[];
|
||||
groupOrder: number;
|
||||
};
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import { PluginRuntimeType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type';
|
||||
import { splitCombinePluginId } from './controller';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
import { PluginRuntimeType } from '@fastgpt/global/core/plugin/type';
|
||||
|
||||
/*
|
||||
1. Commercial plugin: n points per times
|
||||
2. Other plugin: sum of children points
|
||||
Plugin points calculation:
|
||||
1. Return 0 if error
|
||||
2. Add configured points if commercial plugin
|
||||
3. Add sum of child nodes points
|
||||
*/
|
||||
export const computedPluginUsage = async ({
|
||||
plugin,
|
||||
@@ -16,13 +16,13 @@ export const computedPluginUsage = async ({
|
||||
childrenUsage: ChatNodeUsageType[];
|
||||
error?: boolean;
|
||||
}) => {
|
||||
const { source } = await splitCombinePluginId(plugin.id);
|
||||
|
||||
// Commercial plugin: n points per times
|
||||
if (source === PluginSourceEnum.commercial) {
|
||||
if (error) return 0;
|
||||
return plugin.currentCost ?? 0;
|
||||
if (error) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return childrenUsage.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
|
||||
const childrenIUsages = childrenUsage.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
|
||||
|
||||
const pluginCurrentCose = plugin.currentCost ?? 0;
|
||||
|
||||
return plugin.hasTokenFee ? pluginCurrentCose + childrenIUsages : pluginCurrentCose;
|
||||
};
|
||||
|
143
packages/service/core/dataset/apiDataset/api.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import type {
|
||||
APIFileContentResponse,
|
||||
APIFileListResponse,
|
||||
APIFileReadResponse,
|
||||
APIFileServer
|
||||
} from '@fastgpt/global/core/dataset/apiDataset';
|
||||
import axios, { Method } from 'axios';
|
||||
import { addLog } from '../../../common/system/log';
|
||||
import { readFileRawTextByUrl } from '../read';
|
||||
import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
|
||||
|
||||
type ResponseDataType = {
|
||||
success: boolean;
|
||||
message: string;
|
||||
data: any;
|
||||
};
|
||||
|
||||
export const useApiDatasetRequest = ({ apiServer }: { apiServer: APIFileServer }) => {
|
||||
const instance = axios.create({
|
||||
baseURL: apiServer.baseUrl,
|
||||
timeout: 60000, // 超时时间
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
Authorization: `Bearer ${apiServer.authorization}`
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 响应数据检查
|
||||
*/
|
||||
const checkRes = (data: ResponseDataType) => {
|
||||
if (data === undefined) {
|
||||
addLog.info('Api dataset data is empty');
|
||||
return Promise.reject('服务器异常');
|
||||
} else if (!data.success) {
|
||||
return Promise.reject(data);
|
||||
}
|
||||
return data.data;
|
||||
};
|
||||
const responseError = (err: any) => {
|
||||
console.log('error->', '请求错误', err);
|
||||
|
||||
if (!err) {
|
||||
return Promise.reject({ message: '未知错误' });
|
||||
}
|
||||
if (typeof err === 'string') {
|
||||
return Promise.reject({ message: err });
|
||||
}
|
||||
if (typeof err.message === 'string') {
|
||||
return Promise.reject({ message: err.message });
|
||||
}
|
||||
if (typeof err.data === 'string') {
|
||||
return Promise.reject({ message: err.data });
|
||||
}
|
||||
if (err?.response?.data) {
|
||||
return Promise.reject(err?.response?.data);
|
||||
}
|
||||
return Promise.reject(err);
|
||||
};
|
||||
|
||||
const request = <T>(url: string, data: any, method: Method): Promise<T> => {
|
||||
/* 去空 */
|
||||
for (const key in data) {
|
||||
if (data[key] === undefined) {
|
||||
delete data[key];
|
||||
}
|
||||
}
|
||||
|
||||
return instance
|
||||
.request({
|
||||
url,
|
||||
method,
|
||||
data: ['POST', 'PUT'].includes(method) ? data : undefined,
|
||||
params: !['POST', 'PUT'].includes(method) ? data : undefined
|
||||
})
|
||||
.then((res) => checkRes(res.data))
|
||||
.catch((err) => responseError(err));
|
||||
};
|
||||
|
||||
const listFiles = async ({
|
||||
searchKey,
|
||||
parentId
|
||||
}: {
|
||||
searchKey?: string;
|
||||
parentId?: ParentIdType;
|
||||
}) => {
|
||||
const files = await request<APIFileListResponse>(
|
||||
`/v1/file/list`,
|
||||
{
|
||||
searchKey,
|
||||
parentId
|
||||
},
|
||||
'POST'
|
||||
);
|
||||
|
||||
if (!Array.isArray(files)) {
|
||||
return Promise.reject('Invalid file list format');
|
||||
}
|
||||
if (files.some((file) => !file.id || !file.name || typeof file.type === 'undefined')) {
|
||||
return Promise.reject('Invalid file data format');
|
||||
}
|
||||
return files;
|
||||
};
|
||||
|
||||
const getFileContent = async ({ teamId, apiFileId }: { teamId: string; apiFileId: string }) => {
|
||||
const data = await request<APIFileContentResponse>(
|
||||
`/v1/file/content`,
|
||||
{ id: apiFileId },
|
||||
'GET'
|
||||
);
|
||||
const content = data.content;
|
||||
const previewUrl = data.previewUrl;
|
||||
|
||||
if (content) {
|
||||
return content;
|
||||
}
|
||||
if (previewUrl) {
|
||||
const rawText = await readFileRawTextByUrl({
|
||||
teamId,
|
||||
url: previewUrl,
|
||||
relatedId: apiFileId
|
||||
});
|
||||
return rawText;
|
||||
}
|
||||
return Promise.reject('Invalid content type: content or previewUrl is required');
|
||||
};
|
||||
|
||||
const getFilePreviewUrl = async ({ apiFileId }: { apiFileId: string }) => {
|
||||
const { url } = await request<APIFileReadResponse>(`/v1/file/read`, { id: apiFileId }, 'GET');
|
||||
|
||||
if (!url || typeof url !== 'string') {
|
||||
return Promise.reject('Invalid response url');
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
return {
|
||||
getFileContent,
|
||||
listFiles,
|
||||
getFilePreviewUrl
|
||||
};
|
||||
};
|
@@ -3,7 +3,8 @@ import type { CreateDatasetCollectionParams } from '@fastgpt/global/core/dataset
|
||||
import { MongoDatasetCollection } from './schema';
|
||||
import {
|
||||
CollectionWithDatasetType,
|
||||
DatasetCollectionSchemaType
|
||||
DatasetCollectionSchemaType,
|
||||
DatasetSchemaType
|
||||
} from '@fastgpt/global/core/dataset/type';
|
||||
import { MongoDatasetTraining } from '../training/schema';
|
||||
import { MongoDatasetData } from '../data/schema';
|
||||
@@ -13,7 +14,132 @@ import { delFileByFileIdList } from '../../../common/file/gridfs/controller';
|
||||
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import { ClientSession } from '../../../common/mongo';
|
||||
import { createOrGetCollectionTags } from './utils';
|
||||
import { rawText2Chunks } from '../read';
|
||||
import { checkDatasetLimit } from '../../../support/permission/teamLimit';
|
||||
import { predictDataLimitLength } from '../../../../global/core/dataset/utils';
|
||||
import { mongoSessionRun } from '../../../common/mongo/sessionRun';
|
||||
import { createTrainingUsage } from '../../../support/wallet/usage/controller';
|
||||
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
import { getLLMModel, getVectorModel } from '../../ai/model';
|
||||
import { pushDataListToTrainingQueue } from '../training/controller';
|
||||
import { MongoImage } from '../../../common/file/image/schema';
|
||||
import { hashStr } from '@fastgpt/global/common/string/tools';
|
||||
|
||||
export const createCollectionAndInsertData = async ({
|
||||
dataset,
|
||||
rawText,
|
||||
relatedId,
|
||||
createCollectionParams,
|
||||
isQAImport = false,
|
||||
session
|
||||
}: {
|
||||
dataset: DatasetSchemaType;
|
||||
rawText: string;
|
||||
relatedId?: string;
|
||||
createCollectionParams: CreateOneCollectionParams;
|
||||
|
||||
isQAImport?: boolean;
|
||||
session?: ClientSession;
|
||||
}) => {
|
||||
const teamId = createCollectionParams.teamId;
|
||||
const tmbId = createCollectionParams.tmbId;
|
||||
// Chunk split params
|
||||
const trainingType = createCollectionParams.trainingType || TrainingModeEnum.chunk;
|
||||
const chunkSize = createCollectionParams.chunkSize;
|
||||
const chunkSplitter = createCollectionParams.chunkSplitter;
|
||||
const qaPrompt = createCollectionParams.qaPrompt;
|
||||
const usageName = createCollectionParams.name;
|
||||
|
||||
// 1. split chunks
|
||||
const chunks = rawText2Chunks({
|
||||
rawText,
|
||||
chunkLen: chunkSize,
|
||||
overlapRatio: trainingType === TrainingModeEnum.chunk ? 0.2 : 0,
|
||||
customReg: chunkSplitter ? [chunkSplitter] : [],
|
||||
isQAImport
|
||||
});
|
||||
|
||||
// 2. auth limit
|
||||
await checkDatasetLimit({
|
||||
teamId,
|
||||
insertLen: predictDataLimitLength(trainingType, chunks)
|
||||
});
|
||||
|
||||
const fn = async (session: ClientSession) => {
|
||||
// 3. create collection
|
||||
const { _id: collectionId } = await createOneCollection({
|
||||
...createCollectionParams,
|
||||
|
||||
hashRawText: hashStr(rawText),
|
||||
rawTextLength: rawText.length,
|
||||
session
|
||||
});
|
||||
|
||||
// 4. create training bill
|
||||
const { billId } = await createTrainingUsage({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName: usageName,
|
||||
billSource: UsageSourceEnum.training,
|
||||
vectorModel: getVectorModel(dataset.vectorModel)?.name,
|
||||
agentModel: getLLMModel(dataset.agentModel)?.name,
|
||||
session
|
||||
});
|
||||
|
||||
// 5. insert to training queue
|
||||
const insertResults = await pushDataListToTrainingQueue({
|
||||
teamId,
|
||||
tmbId,
|
||||
datasetId: dataset._id,
|
||||
collectionId,
|
||||
agentModel: dataset.agentModel,
|
||||
vectorModel: dataset.vectorModel,
|
||||
trainingMode: trainingType,
|
||||
prompt: qaPrompt,
|
||||
billId,
|
||||
data: chunks.map((item, index) => ({
|
||||
...item,
|
||||
chunkIndex: index
|
||||
})),
|
||||
session
|
||||
});
|
||||
|
||||
// 6. remove related image ttl
|
||||
if (relatedId) {
|
||||
await MongoImage.updateMany(
|
||||
{
|
||||
teamId,
|
||||
'metadata.relatedId': relatedId
|
||||
},
|
||||
{
|
||||
// Remove expiredTime to avoid ttl expiration
|
||||
$unset: {
|
||||
expiredTime: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
session
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
collectionId,
|
||||
insertResults
|
||||
};
|
||||
};
|
||||
|
||||
if (session) {
|
||||
return fn(session);
|
||||
}
|
||||
return mongoSessionRun(fn);
|
||||
};
|
||||
|
||||
export type CreateOneCollectionParams = CreateDatasetCollectionParams & {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
session?: ClientSession;
|
||||
};
|
||||
export async function createOneCollection({
|
||||
teamId,
|
||||
tmbId,
|
||||
@@ -33,18 +159,15 @@ export async function createOneCollection({
|
||||
externalFileId,
|
||||
externalFileUrl,
|
||||
|
||||
apiFileId,
|
||||
|
||||
hashRawText,
|
||||
rawTextLength,
|
||||
metadata = {},
|
||||
session,
|
||||
tags,
|
||||
...props
|
||||
}: CreateDatasetCollectionParams & {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
[key: string]: any;
|
||||
session?: ClientSession;
|
||||
}) {
|
||||
createTime
|
||||
}: CreateOneCollectionParams) {
|
||||
// Create collection tags
|
||||
const collectionTags = await createOrGetCollectionTags({ tags, teamId, datasetId, session });
|
||||
|
||||
@@ -52,7 +175,6 @@ export async function createOneCollection({
|
||||
const [collection] = await MongoDatasetCollection.create(
|
||||
[
|
||||
{
|
||||
...props,
|
||||
teamId,
|
||||
tmbId,
|
||||
parentId: parentId || null,
|
||||
@@ -64,16 +186,18 @@ export async function createOneCollection({
|
||||
chunkSize,
|
||||
chunkSplitter,
|
||||
qaPrompt,
|
||||
metadata,
|
||||
|
||||
fileId,
|
||||
rawLink,
|
||||
...(fileId ? { fileId } : {}),
|
||||
...(rawLink ? { rawLink } : {}),
|
||||
...(externalFileId ? { externalFileId } : {}),
|
||||
externalFileUrl,
|
||||
...(externalFileUrl ? { externalFileUrl } : {}),
|
||||
...(apiFileId ? { apiFileId } : {}),
|
||||
|
||||
rawTextLength,
|
||||
hashRawText,
|
||||
metadata,
|
||||
tags: collectionTags
|
||||
tags: collectionTags,
|
||||
createTime
|
||||
}
|
||||
],
|
||||
{ session }
|
||||
@@ -116,7 +240,68 @@ export const delCollectionRelatedSource = async ({
|
||||
/**
|
||||
* delete collection and it related data
|
||||
*/
|
||||
export async function delCollectionAndRelatedSources({
|
||||
export async function delCollection({
|
||||
collections,
|
||||
session,
|
||||
delRelatedSource
|
||||
}: {
|
||||
collections: (CollectionWithDatasetType | DatasetCollectionSchemaType)[];
|
||||
session: ClientSession;
|
||||
delRelatedSource: boolean;
|
||||
}) {
|
||||
if (collections.length === 0) return;
|
||||
|
||||
const teamId = collections[0].teamId;
|
||||
|
||||
if (!teamId) return Promise.reject('teamId is not exist');
|
||||
|
||||
const datasetIds = Array.from(
|
||||
new Set(
|
||||
collections.map((item) => {
|
||||
if (typeof item.datasetId === 'string') {
|
||||
return String(item.datasetId);
|
||||
}
|
||||
return String(item.datasetId._id);
|
||||
})
|
||||
)
|
||||
);
|
||||
const collectionIds = collections.map((item) => String(item._id));
|
||||
|
||||
// delete training data
|
||||
await MongoDatasetTraining.deleteMany({
|
||||
teamId,
|
||||
datasetIds: { $in: datasetIds },
|
||||
collectionId: { $in: collectionIds }
|
||||
});
|
||||
|
||||
/* file and imgs */
|
||||
if (delRelatedSource) {
|
||||
await delCollectionRelatedSource({ collections, session });
|
||||
}
|
||||
|
||||
// delete dataset.datas
|
||||
await MongoDatasetData.deleteMany(
|
||||
{ teamId, datasetIds: { $in: datasetIds }, collectionId: { $in: collectionIds } },
|
||||
{ session }
|
||||
);
|
||||
|
||||
// delete collections
|
||||
await MongoDatasetCollection.deleteMany(
|
||||
{
|
||||
teamId,
|
||||
_id: { $in: collectionIds }
|
||||
},
|
||||
{ session }
|
||||
);
|
||||
|
||||
// no session delete: delete files, vector data
|
||||
await deleteDatasetDataVector({ teamId, datasetIds, collectionIds });
|
||||
}
|
||||
|
||||
/**
|
||||
* delete delOnlyCollection
|
||||
*/
|
||||
export async function delOnlyCollection({
|
||||
collections,
|
||||
session
|
||||
}: {
|
||||
@@ -148,9 +333,6 @@ export async function delCollectionAndRelatedSources({
|
||||
collectionId: { $in: collectionIds }
|
||||
});
|
||||
|
||||
/* file and imgs */
|
||||
await delCollectionRelatedSource({ collections, session });
|
||||
|
||||
// delete dataset.datas
|
||||
await MongoDatasetData.deleteMany(
|
||||
{ teamId, datasetIds: { $in: datasetIds }, collectionId: { $in: collectionIds } },
|
||||
|
@@ -10,90 +10,100 @@ import {
|
||||
|
||||
export const DatasetColCollectionName = 'dataset_collections';
|
||||
|
||||
const DatasetCollectionSchema = new Schema({
|
||||
parentId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: DatasetColCollectionName,
|
||||
default: null
|
||||
},
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
required: true
|
||||
},
|
||||
tmbId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamMemberCollectionName,
|
||||
required: true
|
||||
},
|
||||
datasetId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: DatasetCollectionName,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
enum: Object.keys(DatasetCollectionTypeMap),
|
||||
required: true
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
createTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
updateTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
forbid: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
const DatasetCollectionSchema = new Schema(
|
||||
{
|
||||
parentId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: DatasetColCollectionName,
|
||||
default: null
|
||||
},
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
required: true
|
||||
},
|
||||
tmbId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamMemberCollectionName,
|
||||
required: true
|
||||
},
|
||||
datasetId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: DatasetCollectionName,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
enum: Object.keys(DatasetCollectionTypeMap),
|
||||
required: true
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
createTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
updateTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
forbid: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
// chunk filed
|
||||
trainingType: {
|
||||
type: String,
|
||||
enum: Object.keys(TrainingTypeMap)
|
||||
},
|
||||
chunkSize: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
chunkSplitter: {
|
||||
type: String
|
||||
},
|
||||
qaPrompt: {
|
||||
type: String
|
||||
},
|
||||
ocrParse: Boolean,
|
||||
// chunk filed
|
||||
trainingType: {
|
||||
type: String,
|
||||
enum: Object.keys(TrainingTypeMap)
|
||||
},
|
||||
chunkSize: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
chunkSplitter: {
|
||||
type: String
|
||||
},
|
||||
qaPrompt: {
|
||||
type: String
|
||||
},
|
||||
ocrParse: Boolean,
|
||||
|
||||
tags: {
|
||||
type: [String],
|
||||
default: []
|
||||
},
|
||||
tags: {
|
||||
type: [String],
|
||||
default: []
|
||||
},
|
||||
|
||||
// local file collection
|
||||
fileId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'dataset.files'
|
||||
},
|
||||
// web link collection
|
||||
rawLink: String,
|
||||
// external collection
|
||||
externalFileId: String,
|
||||
// local file collection
|
||||
fileId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'dataset.files'
|
||||
},
|
||||
// web link collection
|
||||
rawLink: String,
|
||||
// api collection
|
||||
apiFileId: String,
|
||||
// external collection
|
||||
externalFileId: String,
|
||||
externalFileUrl: String, // external import url
|
||||
|
||||
// metadata
|
||||
rawTextLength: Number,
|
||||
hashRawText: String,
|
||||
externalFileUrl: String, // external import url
|
||||
metadata: {
|
||||
type: Object,
|
||||
default: {}
|
||||
// metadata
|
||||
rawTextLength: Number,
|
||||
hashRawText: String,
|
||||
metadata: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
{
|
||||
// Auto update updateTime
|
||||
timestamps: {
|
||||
updatedAt: 'updateTime'
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
try {
|
||||
// auth file
|
||||
|
@@ -1,17 +1,19 @@
|
||||
import type { CollectionWithDatasetType } from '@fastgpt/global/core/dataset/type.d';
|
||||
import { MongoDatasetCollection } from './schema';
|
||||
import { splitText2Chunks } from '@fastgpt/global/common/string/textSplitter';
|
||||
import { MongoDatasetTraining } from '../training/schema';
|
||||
import { urlsFetch } from '../../../common/string/cheerio';
|
||||
import {
|
||||
DatasetCollectionTypeEnum,
|
||||
TrainingModeEnum
|
||||
} from '@fastgpt/global/core/dataset/constants';
|
||||
import { hashStr } from '@fastgpt/global/common/string/tools';
|
||||
import { ClientSession } from '../../../common/mongo';
|
||||
import { PushDatasetDataResponse } from '@fastgpt/global/core/dataset/api';
|
||||
import { MongoDatasetCollectionTags } from '../tag/schema';
|
||||
import { readFromSecondary } from '../../../common/mongo/utils';
|
||||
import { CollectionWithDatasetType } from '@fastgpt/global/core/dataset/type';
|
||||
import {
|
||||
DatasetCollectionSyncResultEnum,
|
||||
DatasetCollectionTypeEnum,
|
||||
DatasetSourceReadTypeEnum,
|
||||
DatasetTypeEnum
|
||||
} from '@fastgpt/global/core/dataset/constants';
|
||||
import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset';
|
||||
import { readDatasetSourceRawText } from '../read';
|
||||
import { hashStr } from '@fastgpt/global/common/string/tools';
|
||||
import { mongoSessionRun } from '../../../common/mongo/sessionRun';
|
||||
import { createCollectionAndInsertData, delCollection } from './controller';
|
||||
|
||||
/**
|
||||
* get all collection by top collectionId
|
||||
@@ -61,148 +63,6 @@ export function getCollectionUpdateTime({ name, time }: { time?: Date; name: str
|
||||
return new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection raw text by Collection or collectionId
|
||||
*/
|
||||
export const getCollectionAndRawText = async ({
|
||||
collectionId,
|
||||
collection,
|
||||
newRawText
|
||||
}: {
|
||||
collectionId?: string;
|
||||
collection?: CollectionWithDatasetType;
|
||||
newRawText?: string;
|
||||
}) => {
|
||||
const col = await (async () => {
|
||||
if (collection) return collection;
|
||||
if (collectionId) {
|
||||
return (await MongoDatasetCollection.findById(collectionId).populate(
|
||||
'datasetId'
|
||||
)) as CollectionWithDatasetType;
|
||||
}
|
||||
|
||||
return null;
|
||||
})();
|
||||
|
||||
if (!col) {
|
||||
return Promise.reject('Collection not found');
|
||||
}
|
||||
|
||||
const { title, rawText } = await (async () => {
|
||||
if (newRawText)
|
||||
return {
|
||||
title: '',
|
||||
rawText: newRawText
|
||||
};
|
||||
// link
|
||||
if (col.type === DatasetCollectionTypeEnum.link && col.rawLink) {
|
||||
// crawl new data
|
||||
const result = await urlsFetch({
|
||||
urlList: [col.rawLink],
|
||||
selector: col.datasetId?.websiteConfig?.selector || col?.metadata?.webPageSelector
|
||||
});
|
||||
|
||||
return {
|
||||
title: result[0]?.title,
|
||||
rawText: result[0]?.content
|
||||
};
|
||||
}
|
||||
|
||||
// file
|
||||
|
||||
return {
|
||||
title: '',
|
||||
rawText: ''
|
||||
};
|
||||
})();
|
||||
|
||||
const hashRawText = hashStr(rawText);
|
||||
const isSameRawText = rawText && col.hashRawText === hashRawText;
|
||||
|
||||
return {
|
||||
collection: col,
|
||||
title,
|
||||
rawText,
|
||||
isSameRawText
|
||||
};
|
||||
};
|
||||
|
||||
/* link collection start load data */
|
||||
export const reloadCollectionChunks = async ({
|
||||
collection,
|
||||
tmbId,
|
||||
billId,
|
||||
rawText,
|
||||
session
|
||||
}: {
|
||||
collection: CollectionWithDatasetType;
|
||||
tmbId: string;
|
||||
billId?: string;
|
||||
rawText?: string;
|
||||
session: ClientSession;
|
||||
}): Promise<PushDatasetDataResponse> => {
|
||||
const {
|
||||
title,
|
||||
rawText: newRawText,
|
||||
collection: col,
|
||||
isSameRawText
|
||||
} = await getCollectionAndRawText({
|
||||
collection,
|
||||
newRawText: rawText
|
||||
});
|
||||
|
||||
if (isSameRawText)
|
||||
return {
|
||||
insertLen: 0
|
||||
};
|
||||
|
||||
// split data
|
||||
const { chunks } = splitText2Chunks({
|
||||
text: newRawText,
|
||||
chunkLen: col.chunkSize || 512,
|
||||
customReg: col.chunkSplitter ? [col.chunkSplitter] : []
|
||||
});
|
||||
|
||||
// insert to training queue
|
||||
const model = await (() => {
|
||||
if (col.trainingType === TrainingModeEnum.chunk) return col.datasetId.vectorModel;
|
||||
if (col.trainingType === TrainingModeEnum.qa) return col.datasetId.agentModel;
|
||||
return Promise.reject('Training model error');
|
||||
})();
|
||||
|
||||
const result = await MongoDatasetTraining.insertMany(
|
||||
chunks.map((item, i) => ({
|
||||
teamId: col.teamId,
|
||||
tmbId,
|
||||
datasetId: col.datasetId._id,
|
||||
collectionId: col._id,
|
||||
billId,
|
||||
mode: col.trainingType,
|
||||
prompt: '',
|
||||
model,
|
||||
q: item,
|
||||
a: '',
|
||||
chunkIndex: i
|
||||
})),
|
||||
{ session }
|
||||
);
|
||||
|
||||
// update raw text
|
||||
await MongoDatasetCollection.findByIdAndUpdate(
|
||||
col._id,
|
||||
{
|
||||
...(title && { name: title }),
|
||||
rawTextLength: newRawText.length,
|
||||
hashRawText: hashStr(newRawText)
|
||||
},
|
||||
{ session }
|
||||
);
|
||||
|
||||
return {
|
||||
insertLen: result.length
|
||||
};
|
||||
};
|
||||
|
||||
export const createOrGetCollectionTags = async ({
|
||||
tags,
|
||||
datasetId,
|
||||
@@ -268,3 +128,88 @@ export const collectionTagsToTagLabel = async ({
|
||||
})
|
||||
.filter(Boolean);
|
||||
};
|
||||
|
||||
export const syncCollection = async (collection: CollectionWithDatasetType) => {
|
||||
const dataset = collection.datasetId;
|
||||
|
||||
if (
|
||||
collection.type !== DatasetCollectionTypeEnum.link &&
|
||||
dataset.type !== DatasetTypeEnum.apiDataset
|
||||
) {
|
||||
return Promise.reject(DatasetErrEnum.notSupportSync);
|
||||
}
|
||||
|
||||
// Get new text
|
||||
const sourceReadType = await (async () => {
|
||||
if (collection.type === DatasetCollectionTypeEnum.link) {
|
||||
if (!collection.rawLink) return Promise.reject('rawLink is missing');
|
||||
return {
|
||||
type: DatasetSourceReadTypeEnum.link,
|
||||
sourceId: collection.rawLink,
|
||||
selector: collection.metadata?.webPageSelector
|
||||
};
|
||||
}
|
||||
|
||||
if (!collection.apiFileId) return Promise.reject('apiFileId is missing');
|
||||
if (!dataset.apiServer) return Promise.reject('apiServer not found');
|
||||
return {
|
||||
type: DatasetSourceReadTypeEnum.apiFile,
|
||||
sourceId: collection.apiFileId,
|
||||
apiServer: dataset.apiServer
|
||||
};
|
||||
})();
|
||||
const rawText = await readDatasetSourceRawText({
|
||||
teamId: collection.teamId,
|
||||
...sourceReadType
|
||||
});
|
||||
|
||||
// Check if the original text is the same: skip if same
|
||||
const hashRawText = hashStr(rawText);
|
||||
if (collection.hashRawText && hashRawText === collection.hashRawText) {
|
||||
return DatasetCollectionSyncResultEnum.sameRaw;
|
||||
}
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
// Create new collection
|
||||
await createCollectionAndInsertData({
|
||||
session,
|
||||
dataset,
|
||||
rawText: rawText,
|
||||
createCollectionParams: {
|
||||
teamId: collection.teamId,
|
||||
tmbId: collection.tmbId,
|
||||
datasetId: collection.datasetId._id,
|
||||
name: collection.name,
|
||||
type: collection.type,
|
||||
|
||||
fileId: collection.fileId,
|
||||
rawLink: collection.rawLink,
|
||||
externalFileId: collection.externalFileId,
|
||||
externalFileUrl: collection.externalFileUrl,
|
||||
apiFileId: collection.apiFileId,
|
||||
|
||||
rawTextLength: rawText.length,
|
||||
hashRawText,
|
||||
|
||||
tags: collection.tags,
|
||||
createTime: collection.createTime,
|
||||
|
||||
parentId: collection.parentId,
|
||||
trainingType: collection.trainingType,
|
||||
chunkSize: collection.chunkSize,
|
||||
chunkSplitter: collection.chunkSplitter,
|
||||
qaPrompt: collection.qaPrompt,
|
||||
metadata: collection.metadata
|
||||
}
|
||||
});
|
||||
|
||||
// Delete old collection
|
||||
await delCollection({
|
||||
collections: [collection],
|
||||
delRelatedSource: false,
|
||||
session
|
||||
});
|
||||
});
|
||||
|
||||
return DatasetCollectionSyncResultEnum.success;
|
||||
};
|
||||
|
@@ -7,6 +7,8 @@ import { TextSplitProps, splitText2Chunks } from '@fastgpt/global/common/string/
|
||||
import axios from 'axios';
|
||||
import { readRawContentByFileBuffer } from '../../common/file/read/utils';
|
||||
import { parseFileExtensionFromUrl } from '@fastgpt/global/common/string/tools';
|
||||
import { APIFileServer } from '@fastgpt/global/core/dataset/apiDataset';
|
||||
import { useApiDatasetRequest } from './apiDataset/api';
|
||||
|
||||
export const readFileRawTextByUrl = async ({
|
||||
teamId,
|
||||
@@ -15,7 +17,7 @@ export const readFileRawTextByUrl = async ({
|
||||
}: {
|
||||
teamId: string;
|
||||
url: string;
|
||||
relatedId?: string;
|
||||
relatedId: string; // externalFileId / apiFileId
|
||||
}) => {
|
||||
const response = await axios({
|
||||
method: 'get',
|
||||
@@ -40,9 +42,9 @@ export const readFileRawTextByUrl = async ({
|
||||
};
|
||||
|
||||
/*
|
||||
fileId - local file, read from mongo
|
||||
link - request
|
||||
externalFile = request read
|
||||
fileId - local file, read from mongo
|
||||
link - request
|
||||
externalFile/apiFile = request read
|
||||
*/
|
||||
export const readDatasetSourceRawText = async ({
|
||||
teamId,
|
||||
@@ -50,14 +52,17 @@ export const readDatasetSourceRawText = async ({
|
||||
sourceId,
|
||||
isQAImport,
|
||||
selector,
|
||||
relatedId
|
||||
externalFileId,
|
||||
apiServer
|
||||
}: {
|
||||
teamId: string;
|
||||
type: DatasetSourceReadTypeEnum;
|
||||
sourceId: string;
|
||||
isQAImport?: boolean;
|
||||
selector?: string;
|
||||
relatedId?: string;
|
||||
|
||||
isQAImport?: boolean; // csv data
|
||||
selector?: string; // link selector
|
||||
externalFileId?: string; // external file dataset
|
||||
apiServer?: APIFileServer; // api dataset
|
||||
}): Promise<string> => {
|
||||
if (type === DatasetSourceReadTypeEnum.fileLocal) {
|
||||
const { rawText } = await readFileContentFromMongo({
|
||||
@@ -75,10 +80,19 @@ export const readDatasetSourceRawText = async ({
|
||||
|
||||
return result[0]?.content || '';
|
||||
} else if (type === DatasetSourceReadTypeEnum.externalFile) {
|
||||
if (!externalFileId) return Promise.reject('FileId not found');
|
||||
const rawText = await readFileRawTextByUrl({
|
||||
teamId,
|
||||
url: sourceId,
|
||||
relatedId
|
||||
relatedId: externalFileId
|
||||
});
|
||||
return rawText;
|
||||
} else if (type === DatasetSourceReadTypeEnum.apiFile) {
|
||||
if (!apiServer) return Promise.reject('apiServer not found');
|
||||
const rawText = await readApiServerFileContent({
|
||||
apiServer,
|
||||
apiFileId: sourceId,
|
||||
teamId
|
||||
});
|
||||
return rawText;
|
||||
}
|
||||
@@ -86,6 +100,18 @@ export const readDatasetSourceRawText = async ({
|
||||
return '';
|
||||
};
|
||||
|
||||
export const readApiServerFileContent = async ({
|
||||
apiServer,
|
||||
apiFileId,
|
||||
teamId
|
||||
}: {
|
||||
apiServer: APIFileServer;
|
||||
apiFileId: string;
|
||||
teamId: string;
|
||||
}) => {
|
||||
return useApiDatasetRequest({ apiServer }).getFileContent({ teamId, apiFileId });
|
||||
};
|
||||
|
||||
export const rawText2Chunks = ({
|
||||
rawText,
|
||||
isQAImport,
|
||||
|
@@ -83,15 +83,18 @@ const DatasetSchema = new Schema({
|
||||
}
|
||||
}
|
||||
},
|
||||
externalReadUrl: {
|
||||
type: String
|
||||
},
|
||||
inheritPermission: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
apiServer: {
|
||||
type: Object
|
||||
},
|
||||
|
||||
// abandoned
|
||||
externalReadUrl: {
|
||||
type: String
|
||||
},
|
||||
defaultPermission: Number
|
||||
});
|
||||
|
||||
|
@@ -28,8 +28,7 @@ export const checkInvalidChunkAndLock = async ({
|
||||
err?.type === 'invalid_request_error' ||
|
||||
err?.code === 500
|
||||
) {
|
||||
addLog.info('Lock training data');
|
||||
console.log(err);
|
||||
addLog.error('Lock training data', err);
|
||||
|
||||
try {
|
||||
await MongoDatasetTraining.findByIdAndUpdate(data._id, {
|
||||
|
@@ -72,7 +72,6 @@ import { dispatchLoopEnd } from './loop/runLoopEnd';
|
||||
import { dispatchLoopStart } from './loop/runLoopStart';
|
||||
import { dispatchFormInput } from './interactive/formInput';
|
||||
import { dispatchToolParams } from './agent/runTool/toolParams';
|
||||
import { responseWrite } from '../../../common/response';
|
||||
|
||||
const callbackMap: Record<FlowNodeTypeEnum, Function> = {
|
||||
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
|
||||
@@ -500,8 +499,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
value = replaceEditorVariable({
|
||||
text: value,
|
||||
nodes: runtimeNodes,
|
||||
variables,
|
||||
runningNode: node
|
||||
variables
|
||||
});
|
||||
|
||||
// replace reference variables
|
||||
@@ -693,9 +691,17 @@ export function getSystemVariable({
|
||||
chatId,
|
||||
responseChatItemId,
|
||||
histories = [],
|
||||
uid
|
||||
uid,
|
||||
chatConfig
|
||||
}: Props): SystemVariablesType {
|
||||
const variables = chatConfig?.variables || [];
|
||||
const variablesMap = variables.reduce<Record<string, any>>((acc, item) => {
|
||||
acc[item.key] = valueTypeFormat(item.defaultValue, item.valueType);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return {
|
||||
...variablesMap,
|
||||
userId: uid,
|
||||
appId: String(runningAppInfo.id),
|
||||
chatId,
|
||||
|
@@ -23,7 +23,6 @@ type RunPluginProps = ModuleDispatchProps<{
|
||||
[key: string]: any;
|
||||
}>;
|
||||
type RunPluginResponse = DispatchNodeResultType<{}>;
|
||||
|
||||
export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPluginResponse> => {
|
||||
const {
|
||||
node: { pluginId, version },
|
||||
@@ -31,7 +30,6 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
|
||||
query,
|
||||
params: { system_forbid_stream = false, ...data } // Plugin input
|
||||
} = props;
|
||||
|
||||
if (!pluginId) {
|
||||
return Promise.reject('pluginId can not find');
|
||||
}
|
||||
@@ -54,7 +52,6 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
|
||||
acc[cur.key] = cur.isToolOutput === false ? false : true;
|
||||
return acc;
|
||||
}, {}) ?? {};
|
||||
|
||||
const runtimeNodes = storeNodes2RuntimeNodes(
|
||||
plugin.nodes,
|
||||
getWorkflowEntryNodeIds(plugin.nodes)
|
||||
@@ -79,7 +76,6 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
|
||||
...filterSystemVariables(props.variables),
|
||||
appId: String(plugin.id)
|
||||
};
|
||||
|
||||
const { flowResponses, flowUsages, assistantResponses, runTimes } = await dispatchWorkFlow({
|
||||
...props,
|
||||
// Rewrite stream mode
|
||||
@@ -105,9 +101,7 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
|
||||
runtimeNodes,
|
||||
runtimeEdges: initWorkflowEdgeStatus(plugin.edges)
|
||||
});
|
||||
|
||||
const output = flowResponses.find((item) => item.moduleType === FlowNodeTypeEnum.pluginOutput);
|
||||
|
||||
if (output) {
|
||||
output.moduleLogo = plugin.avatar;
|
||||
}
|
||||
@@ -117,7 +111,6 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
|
||||
childrenUsage: flowUsages,
|
||||
error: !!output?.pluginOutput?.error
|
||||
});
|
||||
|
||||
return {
|
||||
// 嵌套运行时,如果 childApp stream=false,实际上不会有任何内容输出给用户,所以不需要存储
|
||||
assistantResponses: system_forbid_stream ? [] : assistantResponses,
|
||||
|
@@ -20,7 +20,7 @@ export const dispatchAnswer = (props: Record<string, any>): AnswerResponse => {
|
||||
} = props as AnswerProps;
|
||||
|
||||
const formatText = typeof text === 'string' ? text : JSON.stringify(text, null, 2);
|
||||
const responseText = `\n${formatText}`.replaceAll('\\n', '\n');
|
||||
const responseText = `\n${formatText}`;
|
||||
|
||||
workflowStreamResponse?.({
|
||||
event: SseResponseEventEnum.fastAnswer,
|
||||
|
@@ -110,8 +110,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
||||
replaceEditorVariable({
|
||||
text,
|
||||
nodes: runtimeNodes,
|
||||
variables: allVariables,
|
||||
runningNode: node
|
||||
variables: allVariables
|
||||
}),
|
||||
allVariables
|
||||
);
|
||||
|
@@ -12,6 +12,7 @@ import { readRawContentByFileBuffer } from '../../../../common/file/read/utils';
|
||||
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { ChatItemType, UserChatItemValueItemType } from '@fastgpt/global/core/chat/type';
|
||||
import { parseFileExtensionFromUrl } from '@fastgpt/global/common/string/tools';
|
||||
import { addLog } from '../../../../common/system/log';
|
||||
|
||||
type Props = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.fileUrlList]: string[];
|
||||
@@ -138,7 +139,7 @@ export const getFileContentFromLinks = async ({
|
||||
|
||||
return url;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
addLog.warn(`Parse url error`, { error });
|
||||
return '';
|
||||
}
|
||||
})
|
||||
|
@@ -47,8 +47,7 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
|
||||
? replaceEditorVariable({
|
||||
text: formatValue,
|
||||
nodes: runtimeNodes,
|
||||
variables,
|
||||
runningNode: node
|
||||
variables
|
||||
})
|
||||
: formatValue;
|
||||
} else {
|
||||
|
@@ -134,7 +134,7 @@ export const checkQuoteQAValue = (quoteQA?: SearchDataResponseItemType[]) => {
|
||||
if (quoteQA.length === 0) {
|
||||
return [];
|
||||
}
|
||||
if (quoteQA.some((item) => !item.q || !item.datasetId)) {
|
||||
if (quoteQA.some((item) => !item.q)) {
|
||||
return undefined;
|
||||
}
|
||||
return quoteQA;
|
||||
|
@@ -34,6 +34,8 @@ export const authPluginByTmbId = async ({
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
// commercial custom plugin already checked in "getSystemPluginTemplateById"
|
||||
};
|
||||
|
||||
export const authAppByTmbId = async ({
|
||||
|
@@ -25,6 +25,7 @@ export const MemberGroupSchema = new Schema(
|
||||
}
|
||||
},
|
||||
{
|
||||
// Auto update updateTime
|
||||
timestamps: {
|
||||
updatedAt: 'updateTime'
|
||||
}
|
||||
|
@@ -48,7 +48,7 @@ function DndDrag<T>({ children, renderClone, onDragEndCb, dataList }: Props<T>)
|
||||
return (
|
||||
<Box {...provided.droppableProps} ref={provided.innerRef}>
|
||||
{children(provided, snapshot)}
|
||||
{snapshot.isDraggingOver && <Box height={draggingItemHeight} />}
|
||||
{snapshot.isDraggingOver && <Box height={`${draggingItemHeight}px`} />}
|
||||
</Box>
|
||||
);
|
||||
}}
|
||||
|
@@ -14,9 +14,11 @@ export const iconPaths = {
|
||||
'common/addCircleLight': () => import('./icons/common/addCircleLight.svg'),
|
||||
'common/addLight': () => import('./icons/common/addLight.svg'),
|
||||
'common/addUser': () => import('./icons/common/addUser.svg'),
|
||||
'common/administrator': () => import('./icons/common/administrator.svg'),
|
||||
'common/arrowLeft': () => import('./icons/common/arrowLeft.svg'),
|
||||
'common/backFill': () => import('./icons/common/backFill.svg'),
|
||||
'common/backLight': () => import('./icons/common/backLight.svg'),
|
||||
'common/billing': () => import('./icons/common/billing.svg'),
|
||||
'common/check': () => import('./icons/common/check.svg'),
|
||||
'common/clearLight': () => import('./icons/common/clearLight.svg'),
|
||||
'common/closeLight': () => import('./icons/common/closeLight.svg'),
|
||||
@@ -52,7 +54,10 @@ export const iconPaths = {
|
||||
'common/loading': () => import('./icons/common/loading.svg'),
|
||||
'common/logLight': () => import('./icons/common/logLight.svg'),
|
||||
'common/microsoft': () => import('./icons/common/microsoft.svg'),
|
||||
'common/modal': () => import('./icons/common/modal.svg'),
|
||||
'common/monitor': () => import('./icons/common/monitor.svg'),
|
||||
'common/more': () => import('./icons/common/more.svg'),
|
||||
'common/moreFill': () => import('./icons/common/moreFill.svg'),
|
||||
'common/navbar/pluginFill': () => import('./icons/common/navbar/pluginFill.svg'),
|
||||
'common/navbar/pluginLight': () => import('./icons/common/navbar/pluginLight.svg'),
|
||||
'common/openai': () => import('./icons/common/openai.svg'),
|
||||
@@ -74,20 +79,27 @@ export const iconPaths = {
|
||||
'common/selectLight': () => import('./icons/common/selectLight.svg'),
|
||||
'common/setting': () => import('./icons/common/setting.svg'),
|
||||
'common/settingLight': () => import('./icons/common/settingLight.svg'),
|
||||
'common/solidChevronRight': () => import('./icons/common/solidChevronRight.svg'),
|
||||
'common/subtract': () => import('./icons/common/subtract.svg'),
|
||||
'common/text/t': () => import('./icons/common/text/t.svg'),
|
||||
'common/tickFill': () => import('./icons/common/tickFill.svg'),
|
||||
'common/toolkit': () => import('./icons/common/toolkit.svg'),
|
||||
'common/trash': () => import('./icons/common/trash.svg'),
|
||||
'common/upRightArrowLight': () => import('./icons/common/upRightArrowLight.svg'),
|
||||
'common/uploadFileFill': () => import('./icons/common/uploadFileFill.svg'),
|
||||
'common/userInfo': () => import('./icons/common/userInfo.svg'),
|
||||
'common/viewLight': () => import('./icons/common/viewLight.svg'),
|
||||
'common/voiceLight': () => import('./icons/common/voiceLight.svg'),
|
||||
'common/warn': () => import('./icons/common/warn.svg'),
|
||||
'common/wechatFill': () => import('./icons/common/wechatFill.svg'),
|
||||
configmap: () => import('./icons/configmap.svg'),
|
||||
copy: () => import('./icons/copy.svg'),
|
||||
code: () => import('./icons/code.svg'),
|
||||
preview: () => import('./icons/preview.svg'),
|
||||
fullScreen: () => import('./icons/fullScreen.svg'),
|
||||
'core/app/aiFill': () => import('./icons/core/app/aiFill.svg'),
|
||||
'core/app/aiLight': () => import('./icons/core/app/aiLight.svg'),
|
||||
'core/app/aiLightSmall': () => import('./icons/core/app/aiLightSmall.svg'),
|
||||
'core/app/appApiLight': () => import('./icons/core/app/appApiLight.svg'),
|
||||
'core/app/customFeedback': () => import('./icons/core/app/customFeedback.svg'),
|
||||
'core/app/headphones': () => import('./icons/core/app/headphones.svg'),
|
||||
@@ -153,6 +165,7 @@ export const iconPaths = {
|
||||
import('./icons/core/dataset/commonDatasetOutline.svg'),
|
||||
'core/dataset/datasetFill': () => import('./icons/core/dataset/datasetFill.svg'),
|
||||
'core/dataset/datasetLight': () => import('./icons/core/dataset/datasetLight.svg'),
|
||||
'core/dataset/datasetLightSmall': () => import('./icons/core/dataset/datasetLightSmall.svg'),
|
||||
'core/dataset/externalDataset': () => import('./icons/core/dataset/externalDataset.svg'),
|
||||
'core/dataset/externalDatasetColor': () =>
|
||||
import('./icons/core/dataset/externalDatasetColor.svg'),
|
||||
@@ -361,6 +374,9 @@ export const iconPaths = {
|
||||
'support/user/informLight': () => import('./icons/support/user/informLight.svg'),
|
||||
'support/user/userFill': () => import('./icons/support/user/userFill.svg'),
|
||||
'support/user/userLight': () => import('./icons/support/user/userLight.svg'),
|
||||
'support/user/userLightSmall': () => import('./icons/support/user/userLightSmall.svg'),
|
||||
'support/user/usersFill': () => import('./icons/support/user/usersFill.svg'),
|
||||
'support/user/usersLight': () => import('./icons/support/user/usersLight.svg'),
|
||||
text: () => import('./icons/text.svg'),
|
||||
union: () => import('./icons/union.svg'),
|
||||
user: () => import('./icons/user.svg'),
|
||||
|
@@ -1,3 +1,3 @@
|
||||
<svg viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.18118 2.74428L4.49007 2.74428C5.17179 2.74427 5.72618 2.74427 6.17608 2.78102C6.64077 2.81899 7.0558 2.89966 7.44194 3.09642C7.85435 3.30655 8.21445 3.60159 8.50012 3.95943C8.78579 3.60159 9.14588 3.30655 9.55829 3.09642C9.94444 2.89966 10.3595 2.81899 10.8242 2.78102C11.2741 2.74427 11.8284 2.74427 12.5102 2.74428L12.8191 2.74428C13.1499 2.74426 13.4396 2.74425 13.6792 2.76382C13.9333 2.78459 14.1925 2.83086 14.4436 2.95881C14.8139 3.14753 15.1151 3.44864 15.3038 3.81901C15.4317 4.07013 15.478 4.32926 15.4988 4.58343C15.5183 4.82296 15.5183 5.11271 15.5183 5.44351V11.5565C15.5183 11.8873 15.5183 12.177 15.4988 12.4166C15.478 12.6707 15.4317 12.9299 15.3038 13.181C15.1151 13.5514 14.8139 13.8525 14.4436 14.0412C14.1925 14.1691 13.9333 14.2154 13.6792 14.2362C13.4396 14.2557 13.1499 14.2557 12.819 14.2557H4.18119C3.85038 14.2557 3.56062 14.2557 3.32108 14.2362C3.06691 14.2154 2.80778 14.1691 2.55666 14.0412C2.1863 13.8525 1.88518 13.5514 1.69647 13.181C1.56852 12.9299 1.52225 12.6707 1.50148 12.4166C1.48191 12.177 1.48192 11.8873 1.48193 11.5565V5.44352C1.48192 5.11272 1.48191 4.82296 1.50148 4.58343C1.52225 4.32926 1.56852 4.07013 1.69647 3.81901C1.88518 3.44864 2.1863 3.14753 2.55666 2.95881C2.80778 2.83086 3.06691 2.78459 3.32108 2.76382C3.56062 2.74425 3.85037 2.74426 4.18118 2.74428ZM7.79425 7.49003C7.79425 6.77134 7.7937 6.27477 7.76219 5.88914C7.73136 5.51176 7.67443 5.3032 7.59598 5.14924C7.42158 4.80696 7.1433 4.52869 6.80103 4.35429C6.64706 4.27584 6.43851 4.21891 6.06112 4.18808C5.6755 4.15657 5.17893 4.15602 4.46024 4.15602H4.20775C3.84258 4.15602 3.61115 4.15657 3.43604 4.17088C3.26918 4.18451 3.21652 4.20704 3.19758 4.21669C3.09285 4.27005 3.0077 4.3552 2.95434 4.45993C2.94469 4.47886 2.92217 4.53152 2.90853 4.69839C2.89423 4.87349 2.89368 5.10492 2.89368 5.47009V11.5299C2.89368 11.8951 2.89423 12.1265 2.90853 12.3016C2.92217 12.4685 2.94469 12.5211 2.95434 12.5401C3.0077 12.6448 3.09285 12.73 3.19758 12.7833C3.21652 12.793 3.26918 12.8155 3.43604 12.8291C3.61115 12.8434 3.84258 12.844 4.20775 12.844H7.79425V7.49003ZM9.20599 12.844V7.49003C9.20599 6.77134 9.20654 6.27477 9.23805 5.88914C9.26888 5.51176 9.32581 5.3032 9.40425 5.14924C9.57865 4.80696 9.85693 4.52869 10.1992 4.35429C10.3532 4.27584 10.5617 4.21891 10.9391 4.18808C11.3247 4.15657 11.8213 4.15602 12.54 4.15602H12.7925C13.1577 4.15602 13.3891 4.15657 13.5642 4.17088C13.7311 4.18451 13.7837 4.20704 13.8027 4.21669C13.9074 4.27005 13.9925 4.3552 14.0459 4.45993C14.0555 4.47886 14.0781 4.53152 14.0917 4.69839C14.106 4.87349 14.1066 5.10492 14.1066 5.47009V11.5299C14.1066 11.8951 14.106 12.1265 14.0917 12.3016C14.0781 12.4685 14.0555 12.5211 14.0459 12.5401C13.9925 12.6448 13.9074 12.73 13.8027 12.7833C13.7837 12.793 13.7311 12.8155 13.5642 12.8291C13.3891 12.8434 13.1577 12.844 12.7925 12.844H9.20599Z" />
|
||||
</svg>
|
||||
<svg viewBox="0 0 18 19">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.1412 2.7749L4.48871 2.7749C5.25564 2.77489 5.87933 2.77489 6.38547 2.81624C6.90825 2.85895 7.37515 2.94971 7.80957 3.17106C8.27353 3.40746 8.67864 3.73938 9.00001 4.14195C9.32139 3.73938 9.7265 3.40746 10.1905 3.17106C10.6249 2.94971 11.0918 2.85895 11.6145 2.81624C12.1207 2.77489 12.7444 2.77489 13.5113 2.7749L13.8588 2.7749C14.231 2.77489 14.5569 2.77487 14.8264 2.79689C15.1124 2.82025 15.4039 2.87231 15.6864 3.01626C16.1031 3.22856 16.4418 3.56731 16.6541 3.98397C16.7981 4.26648 16.8501 4.558 16.8735 4.84395C16.8955 5.11342 16.8955 5.43939 16.8955 5.81153V12.6886C16.8955 13.0608 16.8955 13.3868 16.8735 13.6562C16.8501 13.9422 16.7981 14.2337 16.6541 14.5162C16.4418 14.9329 16.1031 15.2716 15.6864 15.4839C15.4039 15.6279 15.1124 15.6799 14.8264 15.7033C14.5569 15.7253 14.231 15.7253 13.8588 15.7253H4.14122C3.76906 15.7253 3.44308 15.7253 3.1736 15.7033C2.88765 15.6799 2.59614 15.6279 2.31362 15.4839C1.89696 15.2716 1.55821 14.9329 1.34591 14.5162C1.20196 14.2337 1.1499 13.9422 1.12654 13.6562C1.10452 13.3868 1.10454 13.0608 1.10455 12.6886V5.81155C1.10454 5.43939 1.10452 5.11342 1.12654 4.84395C1.1499 4.558 1.20196 4.26648 1.34591 3.98397C1.55821 3.56731 1.89696 3.22856 2.31362 3.01626C2.59614 2.87231 2.88765 2.82025 3.1736 2.79689C3.44308 2.77487 3.76905 2.77489 4.1412 2.7749ZM8.20591 8.11387C8.20591 7.30534 8.20529 6.74671 8.16984 6.31288C8.13516 5.88832 8.07111 5.65369 7.98286 5.48049C7.78666 5.09543 7.47359 4.78236 7.08853 4.58616C6.91533 4.49791 6.6807 4.43386 6.25614 4.39918C5.82231 4.36373 5.26368 4.36311 4.45515 4.36311H4.17109C3.76028 4.36311 3.49992 4.36373 3.30293 4.37983C3.1152 4.39516 3.05596 4.42051 3.03466 4.43136C2.91684 4.49139 2.82105 4.58719 2.76101 4.70501C2.75016 4.72631 2.72482 4.78555 2.70948 4.97328C2.69338 5.17027 2.69276 5.43062 2.69276 5.84144V12.6587C2.69276 13.0696 2.69338 13.3299 2.70948 13.5269C2.72482 13.7146 2.75016 13.7739 2.76101 13.7952C2.82105 13.913 2.91684 14.0088 3.03466 14.0688C3.05596 14.0797 3.1152 14.105 3.30293 14.1204C3.49992 14.1364 3.76028 14.1371 4.17109 14.1371H8.20591V8.11387ZM9.79412 14.1371V8.11387C9.79412 7.30534 9.79473 6.74671 9.83018 6.31288C9.86487 5.88832 9.92891 5.65369 10.0172 5.48049C10.2134 5.09543 10.5264 4.78236 10.9115 4.58616C11.0847 4.49791 11.3193 4.43386 11.7439 4.39918C12.1777 4.36373 12.7363 4.36311 13.5449 4.36311H13.8289C14.2397 4.36311 14.5001 4.36373 14.6971 4.37983C14.8848 4.39516 14.9441 4.42051 14.9654 4.43136C15.0832 4.49139 15.179 4.58719 15.239 4.70501C15.2499 4.72631 15.2752 4.78555 15.2905 4.97328C15.3066 5.17027 15.3073 5.43062 15.3073 5.84144V12.6587C15.3073 13.0696 15.3066 13.3299 15.2905 13.5269C15.2752 13.7146 15.2499 13.7739 15.239 13.7952C15.179 13.913 15.0832 14.0088 14.9654 14.0688C14.9441 14.0797 14.8848 14.105 14.6971 14.1204C14.5001 14.1364 14.2397 14.1371 13.8289 14.1371H9.79412Z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.8 KiB |
4
packages/web/components/common/Icon/icons/code.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg viewBox="0 0 14 12" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.29337 0.18052C8.60787 0.250407 8.80616 0.562011 8.73627 0.876505L6.40294 11.3765C6.33305 11.691 6.02145 11.8893 5.70695 11.8194C5.39246 11.7495 5.19417 11.4379 5.26405 11.1234L7.59739 0.623419C7.66728 0.308925 7.97888 0.110632 8.29337 0.18052ZM4.49598 2.67082C4.72378 2.89862 4.72378 3.26797 4.49598 3.49577L1.99179 5.99996L4.49598 8.50415C4.72378 8.73196 4.72378 9.1013 4.49598 9.32911C4.26817 9.55691 3.89882 9.55691 3.67102 9.32911L0.75435 6.41244C0.526545 6.18464 0.526545 5.81529 0.75435 5.58748L3.67102 2.67082C3.89882 2.44301 4.26817 2.44301 4.49598 2.67082ZM9.50435 2.67082C9.73216 2.44301 10.1015 2.44301 10.3293 2.67082L13.246 5.58748C13.4738 5.81529 13.4738 6.18464 13.246 6.41244L10.3293 9.32911C10.1015 9.55691 9.73216 9.55691 9.50435 9.32911C9.27655 9.1013 9.27655 8.73196 9.50435 8.50415L12.0085 5.99996L9.50435 3.49577C9.27655 3.26797 9.27655 2.89862 9.50435 2.67082Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1011 B |
@@ -0,0 +1,5 @@
|
||||
<svg viewBox="0 0 18 19" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 9.29733C11.0064 9.29733 12.6329 7.67081 12.6329 5.66441C12.6329 3.65801 11.0064 2.03149 9 2.03149C6.99359 2.03149 5.36708 3.65801 5.36708 5.66441C5.36708 7.67081 6.99359 9.29733 9 9.29733ZM9 7.79733C10.178 7.79733 11.1329 6.84239 11.1329 5.66441C11.1329 4.48643 10.178 3.53149 9 3.53149C7.82202 3.53149 6.86708 4.48643 6.86708 5.66441C6.86708 6.84239 7.82202 7.79733 9 7.79733Z" />
|
||||
<path d="M7.20532 10.6246C4.72004 10.6246 2.70532 12.6393 2.70532 15.1246V15.5312C2.70532 15.9868 3.07469 16.3562 3.53032 16.3562H9.94582C10.36 16.3562 10.6958 16.0204 10.6958 15.6062C10.6958 15.192 10.36 14.8562 9.94582 14.8562H4.21716C4.3529 13.3251 5.63892 12.1246 7.20532 12.1246H9.94582C10.36 12.1246 10.6958 11.7888 10.6958 11.3746C10.6958 10.9603 10.36 10.6246 9.94582 10.6246H7.20532Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.287 11.1297C13.4884 10.3469 14.6 10.3469 14.8014 11.1297C14.9106 11.5537 15.3467 11.8055 15.7685 11.688C16.5471 11.4711 17.1029 12.4338 16.5257 12.9996C16.213 13.3061 16.213 13.8097 16.5257 14.1162C17.1029 14.682 16.5471 15.6447 15.7685 15.4278C15.3467 15.3103 14.9106 15.5621 14.8014 15.9861C14.6 16.7689 13.4884 16.7689 13.287 15.9861C13.1778 15.5621 12.7417 15.3103 12.3199 15.4278C11.5413 15.6447 10.9855 14.682 11.5627 14.1162C11.8754 13.8097 11.8754 13.3061 11.5627 12.9996C10.9855 12.4338 11.5413 11.4711 12.3199 11.688C12.7417 11.8055 13.1778 11.5537 13.287 11.1297ZM15.0197 13.5579C15.0197 14.0966 14.5829 14.5334 14.0442 14.5334C13.5055 14.5334 13.0687 14.0966 13.0687 13.5579C13.0687 13.0192 13.5055 12.5824 14.0442 12.5824C14.5829 12.5824 15.0197 13.0192 15.0197 13.5579Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 19">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.97078 2.10866C2.97079 1.97552 3.13133 1.90838 3.22612 2.00188L4.02721 2.79207C4.14403 2.9073 4.33174 2.9073 4.44856 2.79207L5.29433 1.9578C5.41114 1.84258 5.59882 1.84257 5.71565 1.95776L6.56155 2.79187C6.67837 2.90706 6.86604 2.90705 6.98284 2.79186L7.82866 1.95774C7.94546 1.84255 8.13313 1.84254 8.24994 1.95771L9.09601 2.7919C9.21282 2.90707 9.40048 2.90706 9.51728 2.79187L10.3631 1.95773C10.4799 1.84255 10.6676 1.84254 10.7844 1.95771L11.6305 2.7919C11.7473 2.90707 11.935 2.90706 12.0518 2.79187L12.8976 1.95774C13.0144 1.84255 13.2021 1.84254 13.3189 1.95771L14.165 2.7919C14.2818 2.90707 14.4694 2.90706 14.5862 2.79187L15.3874 2.00181C15.4822 1.90833 15.6427 1.97548 15.6427 2.10861L15.6428 13.7625C15.6428 15.4193 14.2997 16.7625 12.6428 16.7625H3.646C1.98914 16.7625 0.645996 15.4193 0.645996 13.7625V12.3927C0.645996 11.9785 0.981783 11.6427 1.396 11.6427H2.97047L2.97078 2.10866ZM4.49934 4.63823C4.38504 4.75097 4.32069 4.90482 4.32069 5.06537L4.32043 12.9927H1.996V13.7625C1.996 14.6738 2.73473 15.4125 3.646 15.4125H12.6428C13.5541 15.4125 14.2928 14.6738 14.2928 13.7625L14.2927 5.06471C14.2927 4.90411 14.2283 4.75021 14.114 4.63746L13.319 3.85364C13.2022 3.73847 13.0145 3.73848 12.8977 3.85367L12.0519 4.68779C11.9351 4.80298 11.7474 4.80299 11.6306 4.68782L10.7845 3.85362C10.6677 3.73845 10.48 3.73846 10.3632 3.85365L9.51739 4.6878C9.40059 4.80299 9.21293 4.803 9.09611 4.68783L8.25004 3.85364C8.13323 3.73847 7.94557 3.73848 7.82877 3.85367L6.9829 4.68784C6.86609 4.80303 6.67842 4.80304 6.56161 4.68785L5.71581 3.85385C5.59899 3.73865 5.4113 3.73867 5.2945 3.85388L4.49934 4.63823Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.29602 12.9927C2.13033 12.9927 1.99602 13.127 1.99602 13.2927L1.996 13.7625C1.996 14.6738 2.73473 15.4125 3.646 15.4125L9.62587 15.4125C9.74704 15.4125 9.81982 15.275 9.75995 15.1696C9.49976 14.7118 9.35116 14.1823 9.35116 13.6181V13.2927C9.35116 13.127 9.21685 12.9927 9.05116 12.9927H2.29602ZM1.396 11.6427C0.981783 11.6427 0.645996 11.9785 0.645996 12.3927V13.7625C0.645996 15.4193 1.98914 16.7625 3.646 16.7625H12.6428C14.2997 16.7625 15.6428 15.4193 15.6428 13.7625L15.6429 11.6427H14.2907V13.6181C14.2907 14.5976 13.5059 15.3939 12.5307 15.4125C12.5192 15.4127 12.5076 15.4128 12.4959 15.4128C12.4843 15.4128 12.4727 15.4127 12.4611 15.4125C11.4859 15.3939 10.7012 14.5976 10.7012 13.6181V12.3927C10.7012 11.9785 10.3654 11.6427 9.95116 11.6427L1.396 11.6427Z"/>
|
||||
<path d="M5.69378 6.88024C5.69378 6.46602 6.02957 6.13024 6.44378 6.13024H9.95116C10.3654 6.13024 10.7012 6.46602 10.7012 6.88024C10.7012 7.29445 10.3654 7.63024 9.95116 7.63024H6.44378C6.02957 7.63024 5.69378 7.29445 5.69378 6.88024Z"/>
|
||||
<path d="M5.69378 9.45584C5.69378 9.04163 6.02957 8.70584 6.44378 8.70584H9.95116C10.3654 8.70584 10.7012 9.04163 10.7012 9.45584C10.7012 9.87006 10.3654 10.2058 9.95116 10.2058H6.44378C6.02957 10.2058 5.69378 9.87006 5.69378 9.45584Z" />
|
||||
<path d="M12.9198 6.89159C12.9198 7.3058 12.584 7.64159 12.1698 7.64159C11.7555 7.64159 11.4198 7.3058 11.4198 6.89159C11.4198 6.47738 11.7555 6.14159 12.1698 6.14159C12.584 6.14159 12.9198 6.47738 12.9198 6.89159Z"/>
|
||||
<path d="M12.9198 9.45584C12.9198 9.87006 12.584 10.2058 12.1698 10.2058C11.7555 10.2058 11.4198 9.87006 11.4198 9.45584C11.4198 9.04163 11.7555 8.70584 12.1698 8.70584C12.584 8.70584 12.9198 9.04163 12.9198 9.45584Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 19">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.125 1.32219L12.338 2.5999L12.3352 2.60477C12.3609 2.61529 12.386 2.62759 12.4103 2.64161C12.9529 2.95488 12.7422 3.9133 12.1395 4.0845C11.4626 4.27675 10.8202 4.55086 10.2236 4.89544C11.8306 6.37237 12.9525 8.36892 13.3227 10.6187C13.9485 10.2478 14.5226 9.79882 15.0315 9.28519C15.4705 8.84214 16.4281 9.13471 16.4281 9.75841V12.2396C16.4281 13.0435 15.9993 13.7863 15.3031 14.1882L12.5732 15.7643L12.5634 15.7472C12.0488 15.8808 11.4381 15.2344 11.6004 14.6924C11.7758 14.1064 11.8896 13.4938 11.9343 12.8622C11.0063 13.1469 10.0208 13.3002 8.99945 13.3002C7.95186 13.3002 6.94193 13.1389 5.99311 12.8399C6.03565 13.4636 6.14552 14.0687 6.31551 14.6481C6.47779 15.2012 5.84624 15.854 5.32581 15.6907L5.31913 15.7022L2.69678 14.1882C2.00062 13.7863 1.57178 13.0435 1.57178 12.2396V9.75944C1.57178 9.13571 2.52928 8.84311 2.96834 9.28611C3.45974 9.78192 4.01185 10.2175 4.6126 10.5807C4.98922 8.34641 6.10744 6.36404 7.70535 4.89544C7.12138 4.55814 6.4935 4.28837 5.83239 4.0968C5.23035 3.92233 5.02374 2.96834 5.56658 2.65493C5.57875 2.64791 5.59111 2.64132 5.60365 2.63516L5.60295 2.63394L7.87496 1.32219C8.57111 0.920271 9.42881 0.920271 10.125 1.32219ZM7.65539 3.18102C8.1114 3.39201 8.54881 3.63637 8.9645 3.91097C9.39217 3.62846 9.84283 3.37795 10.3131 3.16286L9.37496 2.62123C9.14291 2.48726 8.85701 2.48726 8.62496 2.62123L7.65539 3.18102ZM3.07178 11.3526V12.2396C3.07178 12.5076 3.21473 12.7552 3.44678 12.8891L4.55373 13.5282C4.50058 13.1108 4.47318 12.6853 4.47318 12.2535L4.47324 12.2185C3.98117 11.968 3.51262 11.678 3.07178 11.3526ZM13.3695 13.5725L14.5531 12.8891C14.7852 12.7552 14.9281 12.5076 14.9281 12.2396V11.3518C14.4662 11.6929 13.9738 11.9952 13.4558 12.2537C13.4558 12.7008 13.4264 13.141 13.3695 13.5725ZM11.9019 11.2912C10.9963 11.6205 10.0189 11.8002 8.99945 11.8002C7.95482 11.8002 6.95424 11.6115 6.02993 11.2665C6.28342 9.07669 7.36999 7.14081 8.9645 5.78396C10.565 7.14591 11.6537 9.09126 11.9019 11.2912Z" />
|
||||
<path d="M13.1851 3.95376C12.9773 4.31254 13.1 4.7719 13.4591 4.97922L14.5531 5.61086C14.7852 5.74483 14.9281 5.99243 14.9281 6.26038V7.77864C14.9281 8.19285 15.2639 8.52864 15.6781 8.52864C16.0924 8.52864 16.4281 8.19285 16.4281 7.77864V6.26038C16.4281 5.45653 15.9993 4.71374 15.3031 4.31182L14.2091 3.68018C13.8508 3.47329 13.3926 3.59571 13.1851 3.95376Z" />
|
||||
<path d="M11.2717 15.6497C11.4788 16.0084 11.3559 16.4671 10.9972 16.6742L10.125 17.1778C9.4288 17.5797 8.57111 17.5797 7.87496 17.1778L6.99477 16.6696C6.63568 16.4623 6.51295 16.0029 6.72079 15.6442C6.92821 15.2861 7.38642 15.1637 7.74477 15.3706L8.62496 15.8788C8.85701 16.0127 9.14291 16.0127 9.37496 15.8788L10.2472 15.3752C10.6059 15.1681 11.0646 15.291 11.2717 15.6497Z" />
|
||||
<path d="M2.32178 8.53702C1.90756 8.53702 1.57178 8.20123 1.57178 7.78702V6.26037C1.57178 5.45653 2.00063 4.71374 2.69678 4.31182L3.77356 3.69014C4.13228 3.48303 4.59097 3.60594 4.79808 3.96466C5.00518 4.32338 4.88228 4.78207 4.52356 4.98918L3.44678 5.61086C3.21473 5.74483 3.07178 5.99243 3.07178 6.26037V7.78702C3.07178 8.20123 2.73599 8.53702 2.32178 8.53702Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 18" >
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.100128 1.2C0.100128 0.537258 0.637387 0 1.30013 0H6.90013C7.56287 0 8.10013 0.537258 8.10013 1.2V6.8C8.10013 7.46274 7.56287 8 6.90013 8H1.30013C0.637386 8 0.100128 7.46274 0.100128 6.8V1.2ZM2.10013 6V2H6.10013V6H2.10013Z" fill="#8A95A7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.1001 1.2C10.1001 0.537258 10.6374 0 11.3001 0H16.9001C17.5629 0 18.1001 0.537258 18.1001 1.2V6.8C18.1001 7.46274 17.5629 8 16.9001 8H11.3001C10.6374 8 10.1001 7.46274 10.1001 6.8V1.2ZM12.1001 6V2H16.1001V6H12.1001Z" fill="#8A95A7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3001 10C10.6374 10 10.1001 10.5373 10.1001 11.2V16.8C10.1001 17.4627 10.6374 18 11.3001 18H16.9001C17.5629 18 18.1001 17.4627 18.1001 16.8V11.2C18.1001 10.5373 17.5629 10 16.9001 10H11.3001ZM12.1001 12V16H16.1001V12H12.1001Z" fill="#8A95A7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.100128 11.2C0.100128 10.5373 0.637387 10 1.30013 10H6.90013C7.56287 10 8.10013 10.5373 8.10013 11.2V16.8C8.10013 17.4627 7.56287 18 6.90013 18H1.30013C0.637386 18 0.100128 17.4627 0.100128 16.8V11.2ZM2.10013 16V12H6.10013V16H2.10013Z" fill="#8A95A7"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M4.30013 3C3.63739 3 3.10013 3.53726 3.10013 4.2V9.8C3.10013 10.4627 3.63739 11 4.30013 11H9.90013C10.5629 11 11.1001 10.4627 11.1001 9.8V4.2C11.1001 3.53726 10.5629 3 9.90013 3H4.30013Z" />
|
||||
<path d="M14.3001 3C13.6374 3 13.1001 3.53726 13.1001 4.2V9.8C13.1001 10.4627 13.6374 11 14.3001 11H19.9001C20.5629 11 21.1001 10.4627 21.1001 9.8V4.2C21.1001 3.53726 20.5629 3 19.9001 3H14.3001Z" />
|
||||
<path d="M13.1001 14.2C13.1001 13.5373 13.6374 13 14.3001 13H19.9001C20.5629 13 21.1001 13.5373 21.1001 14.2V19.8C21.1001 20.4627 20.5629 21 19.9001 21H14.3001C13.6374 21 13.1001 20.4627 13.1001 19.8V14.2Z" />
|
||||
<path d="M4.30013 13C3.63739 13 3.10013 13.5373 3.10013 14.2V19.8C3.10013 20.4627 3.63739 21 4.30013 21H9.90013C10.5629 21 11.1001 20.4627 11.1001 19.8V14.2C11.1001 13.5373 10.5629 13 9.90013 13H4.30013Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 905 B |
@@ -1,4 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M9.96137 5.58301L9.90952 3.63626C9.88557 2.73711 9.14799 2.01469 8.24232 2.01469C7.33664 2.01469 6.59906 2.73712 6.57511 3.63626L6.52327 5.58301H2.5C2.22386 5.58301 2 5.80687 2 6.08301V8.37278C3.86427 8.4434 5.35394 9.97702 5.35394 11.8586C5.35394 13.7401 3.86427 15.2737 2 15.3444V17.51C2 17.7862 2.22386 18.01 2.5 18.01H4.85111C4.97393 16.2442 6.44528 14.8499 8.24229 14.8499C10.0393 14.8499 11.5106 16.2442 11.6335 18.01H13.9269C14.2031 18.01 14.4269 17.7862 14.4269 17.51V13.6073L16.3634 13.5457C17.2691 13.5169 17.9954 12.7723 17.9954 11.8588C17.9954 10.9452 17.2691 10.2006 16.3634 10.1718L14.4269 10.1102V6.08301C14.4269 5.80687 14.2031 5.58301 13.9269 5.58301H9.96137ZM9.64176 20.01V18.2494C9.64176 17.4765 9.0152 16.8499 8.24229 16.8499C7.46938 16.8499 6.84281 17.4765 6.84281 18.2494V20.01H2.5C1.11929 20.01 0 18.8907 0 17.51V13.3469H1.8656C2.68759 13.3469 3.35394 12.6806 3.35394 11.8586C3.35394 11.0366 2.68759 10.3702 1.8656 10.3702L0 10.3702V6.08301C0 4.7023 1.11929 3.58301 2.5 3.58301H4.57582C4.62855 1.60333 6.24991 0.0146942 8.24232 0.0146942C10.2347 0.0146942 11.8561 1.60333 11.9088 3.58301H13.9269C15.3077 3.58301 16.4269 4.7023 16.4269 6.08301V8.17278C18.4084 8.2358 19.9954 9.86195 19.9954 11.8588C19.9954 13.8556 18.4084 15.4817 16.4269 15.5447V17.51C16.4269 18.8907 15.3077 20.01 13.9269 20.01H9.64176Z" />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9614 7.58301L11.9095 5.63625C11.8856 4.73711 11.148 4.01469 10.2423 4.01469C9.33664 4.01469 8.59906 4.73711 8.57511 5.63625L8.52327 7.58301H4.5C4.22386 7.58301 4 7.80687 4 8.08301V10.3728C5.86427 10.4434 7.35394 11.977 7.35394 13.8586C7.35394 15.7401 5.86427 17.2737 4 17.3444V19.51C4 19.7862 4.22386 20.01 4.5 20.01H6.85111C6.97393 18.2442 8.44528 16.8499 10.2423 16.8499C12.0393 16.8499 13.5106 18.2442 13.6335 20.01H15.9269C16.2031 20.01 16.4269 19.7862 16.4269 19.51V15.6073L18.3634 15.5457C19.2691 15.5169 19.9954 14.7723 19.9954 13.8587C19.9954 12.9452 19.2691 12.2006 18.3634 12.1718L16.4269 12.1102V8.08301C16.4269 7.80687 16.2031 7.58301 15.9269 7.58301H11.9614ZM11.6418 22.01V20.2494C11.6418 19.4765 11.0152 18.8499 10.2423 18.8499C9.46938 18.8499 8.84281 19.4765 8.84281 20.2494V22.01H4.5C3.11929 22.01 2 20.8907 2 19.51V15.3469H3.8656C4.68759 15.3469 5.35394 14.6806 5.35394 13.8586C5.35394 13.0366 4.68759 12.3702 3.8656 12.3702L2 12.3702V8.08301C2 6.7023 3.11929 5.58301 4.5 5.58301H6.57582C6.62855 3.60333 8.24991 2.01469 10.2423 2.01469C12.2347 2.01469 13.8561 3.60333 13.9088 5.58301H15.9269C17.3077 5.58301 18.4269 6.7023 18.4269 8.08301V10.1728C20.4084 10.2358 21.9954 11.8619 21.9954 13.8587C21.9954 15.8556 20.4084 17.4817 18.4269 17.5447V19.51C18.4269 20.8907 17.3077 22.01 15.9269 22.01H11.6418Z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 16" fill="none">
|
||||
<path d="M6.06201 4.59968C6.06201 3.41181 7.4982 2.81692 8.33815 3.65687L11.7382 7.05696C12.2589 7.57766 12.2589 8.42188 11.7382 8.94258L8.33815 12.3427C7.4982 13.1826 6.06201 12.5877 6.06201 11.3999V4.59968Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 294 B |
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.0801 5.93839H17.0763C18.9296 5.93845 19.8659 5.94338 20.5834 6.30896C21.2231 6.63493 21.7432 7.15507 22.0692 7.79482C22.4398 8.52212 22.4398 9.47421 22.4398 11.3784V16.56C22.4398 18.4642 22.4398 19.4163 22.0692 20.1436C21.7432 20.7833 21.2231 21.3035 20.5834 21.6294C19.8561 22 18.904 22 16.9998 22H6.99999C5.09582 22 4.14373 22 3.41643 21.6294C2.77668 21.3035 2.25654 20.7833 1.93058 20.1436C1.56 19.4163 1.56 18.4642 1.56 16.56V11.3784C1.56 9.47421 1.56 8.52212 1.93058 7.79482C2.25654 7.15507 2.77668 6.63493 3.41643 6.30896C4.14373 5.93839 5.09582 5.93839 7 5.93839H7.15442V5.59991C7.15442 3.61168 8.76619 1.99991 10.7544 1.99991H13.4801C15.4683 1.99991 17.0801 3.61168 17.0801 5.59991V5.93839ZM10.7544 3.99991H13.4801C14.3637 3.99991 15.0801 4.71625 15.0801 5.59991V5.93839H9.15442V5.59991C9.15442 4.71625 9.87076 3.99991 10.7544 3.99991ZM16.9998 7.93839H7C6.01491 7.93839 5.39637 7.93994 4.92975 7.97807C4.48647 8.01428 4.35913 8.07329 4.32441 8.09098C4.06098 8.2252 3.84681 8.43937 3.71259 8.7028C3.6949 8.73751 3.63589 8.86486 3.59968 9.30814C3.5786 9.56613 3.5687 9.87057 3.56406 10.2577H20.4357C20.4311 9.87057 20.4212 9.56613 20.4001 9.30814C20.3639 8.86486 20.3049 8.73751 20.2872 8.7028C20.153 8.43937 19.9388 8.2252 19.6754 8.09098C19.6407 8.07329 19.5133 8.01428 19.07 7.97807C18.6034 7.93994 17.9849 7.93839 16.9998 7.93839ZM20.4398 12.0577H14.6354V15.1893C14.6354 15.5207 14.3668 15.7893 14.0354 15.7893H9.96427C9.6329 15.7893 9.36427 15.5207 9.36427 15.1893V12.0577H3.56V16.56C3.56 17.5451 3.56155 18.1636 3.59968 18.6302C3.63589 19.0735 3.6949 19.2009 3.71259 19.2356C3.84681 19.499 4.06098 19.7132 4.32441 19.8474C4.35913 19.8651 4.48647 19.9241 4.92975 19.9603C5.39637 19.9984 6.0149 20 6.99999 20H16.9998C17.9849 20 18.6034 19.9984 19.07 19.9603C19.5133 19.9241 19.6407 19.8651 19.6754 19.8474C19.9388 19.7132 20.153 19.499 20.2872 19.2356C20.3049 19.2009 20.3639 19.0735 20.4001 18.6302C20.4382 18.1636 20.4398 17.5451 20.4398 16.56V12.0577ZM12.8354 12.0577H11.1643V13.9893H12.8354V12.0577Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 19">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.61352 3.25H11.3865C12.2232 3.25 12.759 3.25121 13.1655 3.28496C13.5541 3.31723 13.6883 3.37131 13.7473 3.40199C13.9939 3.53007 14.195 3.73112 14.323 3.97768C14.3537 4.03674 14.4078 4.17096 14.4401 4.5595C14.4738 4.96599 14.475 5.5018 14.475 6.3385V12.1615C14.475 12.9982 14.4738 13.534 14.4401 13.9405C14.4078 14.329 14.3537 14.4633 14.323 14.5223C14.195 14.7689 13.9939 14.9699 13.7473 15.098C13.6883 15.1287 13.5541 15.1828 13.1655 15.215C12.759 15.2488 12.2232 15.25 11.3865 15.25H6.61353C5.77682 15.25 5.24102 15.2488 4.83452 15.215C4.44598 15.1828 4.31177 15.1287 4.25271 15.098C4.00614 14.9699 3.8051 14.7689 3.67702 14.5223C3.64634 14.4633 3.59225 14.329 3.55999 13.9405C3.52623 13.534 3.52502 12.9982 3.52502 12.1615V6.3385C3.52502 5.5018 3.52623 4.96599 3.55999 4.5595C3.59225 4.17096 3.64634 4.03674 3.67702 3.97768C3.8051 3.73112 4.00614 3.53007 4.25271 3.40199C4.31177 3.37131 4.44598 3.31723 4.83452 3.28496C5.24102 3.25121 5.77682 3.25 6.61352 3.25ZM2.02502 6.3385C2.02502 4.71545 2.02502 3.90393 2.3459 3.28622C2.61629 2.76569 3.04071 2.34127 3.56125 2.07087C4.17895 1.75 4.99048 1.75 6.61352 1.75H11.3865C13.0096 1.75 13.8211 1.75 14.4388 2.07087C14.9593 2.34127 15.3838 2.76569 15.6542 3.28622C15.975 3.90393 15.975 4.71545 15.975 6.3385V12.1615C15.975 13.7845 15.975 14.5961 15.6542 15.2138C15.3838 15.7343 14.9593 16.1587 14.4388 16.4291C13.8211 16.75 13.0096 16.75 11.3865 16.75H6.61353C4.99048 16.75 4.17895 16.75 3.56125 16.4291C3.04071 16.1587 2.61629 15.7343 2.3459 15.2138C2.02502 14.5961 2.02502 13.7845 2.02502 12.1615V6.3385ZM5.73614 5.47485C5.32192 5.47485 4.98614 5.81063 4.98614 6.22485C4.98614 6.63906 5.32192 6.97485 5.73614 6.97485L12.2639 6.97485C12.6781 6.97485 13.0139 6.63906 13.0139 6.22485C13.0139 5.81063 12.6781 5.47485 12.2639 5.47485H5.73614ZM5.73614 8.59967C5.32192 8.59967 4.98614 8.93545 4.98614 9.34967C4.98614 9.76388 5.32192 10.0997 5.73614 10.0997L12.2639 10.0997C12.6781 10.0997 13.0139 9.76388 13.0139 9.34967C13.0139 8.93545 12.6781 8.59967 12.2639 8.59967L5.73614 8.59967ZM4.98614 12.4187C4.98614 12.0045 5.32192 11.6687 5.73614 11.6687L9.84723 11.6687C10.2614 11.6687 10.5972 12.0045 10.5972 12.4187C10.5972 12.8329 10.2614 13.1687 9.84723 13.1687L5.73614 13.1687C5.32192 13.1687 4.98614 12.8329 4.98614 12.4187Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 19" fill="none">
|
||||
<path d="M5.17969 8.7299C5.17969 8.26547 5.55618 7.88899 6.0206 7.88899C6.48502 7.88899 6.86151 8.26547 6.86151 8.7299V9.46909C6.86151 9.93352 6.48502 10.31 6.0206 10.31C5.55618 10.31 5.17969 9.93352 5.17969 9.46909V8.7299Z" />
|
||||
<path d="M11.9819 7.88899C11.5175 7.88899 11.141 8.26547 11.141 8.7299V9.46909C11.141 9.93352 11.5175 10.31 11.9819 10.31C12.4463 10.31 12.8228 9.93352 12.8228 9.46909V8.7299C12.8228 8.26547 12.4463 7.88899 11.9819 7.88899Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.49654 1.74089C5.03897 1.81742 4.73009 2.25039 4.80662 2.70796L5.14411 4.72566H4.275C2.74241 4.72566 1.5 5.96807 1.5 7.50066V11.3842C1.5 12.9168 2.74241 14.1592 4.275 14.1592H13.725C15.2576 14.1592 16.5 12.9168 16.5 11.3842V7.50066C16.5 5.96807 15.2576 4.72566 13.725 4.72566H12.8509L13.1884 2.70796C13.265 2.25039 12.9561 1.81742 12.4985 1.74089C12.041 1.66436 11.608 1.97324 11.5315 2.4308L11.1476 4.72566H6.84745L6.4636 2.4308C6.38707 1.97324 5.9541 1.66436 5.49654 1.74089ZM4.275 6.22566H13.725C14.4292 6.22566 15 6.79649 15 7.50066V11.3842C15 12.0884 14.4292 12.6592 13.725 12.6592H4.275C3.57084 12.6592 3 12.0884 3 11.3842V7.50066C3 6.79649 3.57084 6.22566 4.275 6.22566Z"/>
|
||||
<path d="M13.5888 16C13.5888 16.4142 13.253 16.75 12.8388 16.75H5.16519C4.75097 16.75 4.41519 16.4142 4.41519 16C4.41519 15.5858 4.75097 15.25 5.16519 15.25H12.8388C13.253 15.25 13.5888 15.5858 13.5888 16Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 18 19">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.07507 4C3.07507 4 3.07521 4.00439 3.07736 4.01147C3.07991 4.01983 3.08619 4.03634 3.10138 4.06107C3.13321 4.11293 3.19813 4.1909 3.31975 4.28674C3.56739 4.4819 3.97219 4.69045 4.53927 4.87948C5.66559 5.25492 7.26929 5.5 9.07507 5.5C10.8809 5.5 12.4846 5.25492 13.6109 4.87948C14.178 4.69045 14.5828 4.4819 14.8304 4.28674C14.952 4.1909 15.0169 4.11293 15.0488 4.06107C15.064 4.03634 15.0702 4.01983 15.0728 4.01147C15.075 4.00429 15.0751 4.00017 15.0751 4.00017V4.00017C15.0751 4.00017 15.0751 3.99629 15.0728 3.98853C15.0702 3.98017 15.064 3.96366 15.0488 3.93893C15.0169 3.88707 14.952 3.8091 14.8304 3.71326C14.5828 3.5181 14.178 3.30955 13.6109 3.12052C12.4846 2.74508 10.8809 2.5 9.07507 2.5C7.26929 2.5 5.66559 2.74508 4.53927 3.12052C3.97219 3.30955 3.56739 3.5181 3.31975 3.71326C3.19813 3.8091 3.13321 3.88707 3.10138 3.93893C3.08619 3.96366 3.07991 3.98017 3.07736 3.98853C3.07506 3.99609 3.07507 4 3.07507 4ZM15.0751 5.89495C14.7742 6.04883 14.4401 6.18421 14.0852 6.3025C12.7685 6.7414 10.9972 7 9.07507 7C7.15293 7 5.38163 6.7414 4.06493 6.3025C3.71007 6.18421 3.37599 6.04883 3.07507 5.89495V9.25C3.07507 9.25 3.07513 9.25527 3.07762 9.26351C3.08029 9.27232 3.08666 9.28907 3.10175 9.31385C3.13336 9.36571 3.19768 9.44347 3.31821 9.53898C3.56376 9.73355 3.96598 9.94173 4.53132 10.1305C5.65426 10.5054 7.25765 10.75 9.07507 10.75C10.8925 10.75 12.4959 10.5054 13.6188 10.1305C14.1842 9.94173 14.5864 9.73355 14.8319 9.53898C14.9525 9.44347 15.0168 9.36571 15.0484 9.31385C15.0635 9.28907 15.0699 9.27232 15.0725 9.26351C15.075 9.25527 15.0751 9.25 15.0751 9.25V5.89495ZM16.5751 4C16.5751 3.36104 16.1859 2.87169 15.7589 2.53514C15.3234 2.19192 14.7396 1.91564 14.0852 1.6975C12.7685 1.2586 10.9972 1 9.07507 1C7.15293 1 5.38163 1.2586 4.06493 1.6975C3.4105 1.91564 2.8268 2.19192 2.39129 2.53514C1.96424 2.87169 1.57507 3.36104 1.57507 4V14.5C1.57507 15.137 1.95997 15.6265 2.38662 15.9646C2.82076 16.3086 3.40292 16.5851 4.05632 16.8033C5.37089 17.2421 7.1425 17.5 9.07507 17.5C11.0076 17.5 12.7793 17.2421 14.0938 16.8033C14.7472 16.5851 15.3294 16.3086 15.7635 15.9646C16.1902 15.6265 16.5751 15.137 16.5751 14.5V4ZM15.0751 11.1489C14.7766 11.3015 14.4455 11.4359 14.0938 11.5533C12.7793 11.9921 11.0076 12.25 9.07507 12.25C7.1425 12.25 5.37089 11.9921 4.05632 11.5533C3.7046 11.4359 3.37353 11.3015 3.07507 11.1489V14.5C3.07507 14.5 3.07513 14.5053 3.07762 14.5135C3.08029 14.5223 3.08666 14.5391 3.10175 14.5638C3.13336 14.6157 3.19768 14.6935 3.31821 14.789C3.56376 14.9836 3.96598 15.1917 4.53132 15.3805C5.65426 15.7554 7.25765 16 9.07507 16C10.8925 16 12.4959 15.7554 13.6188 15.3805C14.1842 15.1917 14.5864 14.9836 14.8319 14.789C14.9525 14.6935 15.0168 14.6157 15.0484 14.5638C15.0635 14.5391 15.0699 14.5223 15.0725 14.5135C15.075 14.5053 15.0751 14.5 15.0751 14.5V11.1489Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
3
packages/web/components/common/Icon/icons/fullScreen.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.74984 1.33335C7.42767 1.33335 7.1665 1.07219 7.1665 0.75002C7.1665 0.427854 7.42767 0.166687 7.74984 0.166687H11.2498C11.572 0.166687 11.8332 0.427854 11.8332 0.75002V4.25002C11.8332 4.57219 11.572 4.83335 11.2498 4.83335C10.9277 4.83335 10.6665 4.57219 10.6665 4.25002V2.15831L7.57898 5.24583C7.35118 5.47364 6.98183 5.47364 6.75402 5.24583C6.52622 5.01803 6.52622 4.64868 6.75402 4.42087L9.84154 1.33335H7.74984ZM5.24565 6.75421C5.47345 6.98201 5.47345 7.35136 5.24565 7.57917L2.15813 10.6667H4.24984C4.572 10.6667 4.83317 10.9279 4.83317 11.25C4.83317 11.5722 4.572 11.8334 4.24984 11.8334H0.749837C0.595128 11.8334 0.446754 11.7719 0.337358 11.6625C0.227962 11.5531 0.166504 11.4047 0.166504 11.25L0.166504 7.75002C0.166504 7.42785 0.427671 7.16669 0.749837 7.16669C1.072 7.16669 1.33317 7.42785 1.33317 7.75002L1.33317 9.84173L4.42069 6.75421C4.6485 6.5264 5.01784 6.5264 5.24565 6.75421Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1017 B |
6
packages/web/components/common/Icon/icons/preview.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg viewBox="0 0 14 12" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.865723 2.36035C0.865723 1.39385 1.64922 0.610352 2.61572 0.610352H11.3846C12.3511 0.610352 13.1346 1.39385 13.1346 2.36035V9.63974C13.1346 10.6062 12.3511 11.3897 11.3846 11.3897H2.61572C1.64922 11.3897 0.865723 10.6062 0.865723 9.63974V2.36035ZM2.61572 1.77702C2.29356 1.77702 2.03239 2.03819 2.03239 2.36035V9.63974C2.03239 9.9619 2.29356 10.2231 2.61572 10.2231H11.3846C11.7067 10.2231 11.9679 9.9619 11.9679 9.63974V2.36035C11.9679 2.03819 11.7067 1.77702 11.3846 1.77702H2.61572Z"/>
|
||||
<path d="M4.78348 3.69055C4.78348 4.10936 4.44396 4.44888 4.02514 4.44888C3.60633 4.44888 3.26681 4.10936 3.26681 3.69055C3.26681 3.27173 3.60633 2.93221 4.02514 2.93221C4.44396 2.93221 4.78348 3.27173 4.78348 3.69055Z"/>
|
||||
<path d="M6.88348 3.69055C6.88348 4.10936 6.54396 4.44888 6.12514 4.44888C5.70633 4.44888 5.36681 4.10936 5.36681 3.69055C5.36681 3.27173 5.70633 2.93221 6.12514 2.93221C6.54396 2.93221 6.88348 3.27173 6.88348 3.69055Z"/>
|
||||
<path d="M8.98348 3.69055C8.98348 4.10936 8.64396 4.44888 8.22514 4.44888C7.80633 4.44888 7.46681 4.10936 7.46681 3.69055C7.46681 3.27173 7.80633 2.93221 8.22514 2.93221C8.64396 2.93221 8.98348 3.27173 8.98348 3.69055Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@@ -1,5 +1,5 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.4622 17.4792C15.9398 17.4524 16.2747 17.3901 16.5593 17.245C16.9984 17.0213 17.3553 16.6644 17.579 16.2253C17.8334 15.7262 17.8334 15.0728 17.8334 13.766V6.23268C17.8334 4.92589 17.8334 4.2725 17.579 3.77337C17.3553 3.33433 16.9984 2.97737 16.5593 2.75367C16.2747 2.60862 15.9398 2.5463 15.4622 2.51952C15.4647 2.72072 15.4647 2.94567 15.4647 3.19935V4.02265C15.4802 4.02376 15.4954 4.02493 15.5104 4.02616C15.8016 4.04995 15.873 4.08738 15.8781 4.09007C16.0349 4.16996 16.1626 4.29756 16.2425 4.45436C16.2452 4.45947 16.2828 4.53114 16.3065 4.8223C16.3322 5.13614 16.3334 5.55454 16.3334 6.23268V13.766C16.3334 14.4442 16.3322 14.8626 16.3065 15.1764C16.2828 15.4676 16.2453 15.539 16.2426 15.5441C16.1627 15.7009 16.0351 15.8286 15.8783 15.9085C15.8732 15.9112 15.8015 15.9488 15.5104 15.9725C15.4954 15.9738 15.4802 15.9749 15.4647 15.976V16.7993C15.4647 17.053 15.4647 17.278 15.4622 17.4792Z" fill="#111824"/>
|
||||
<path d="M4.53531 17.479C4.05904 17.4522 3.72487 17.3898 3.44071 17.245C3.00166 17.0213 2.64471 16.6644 2.421 16.2253C2.16669 15.7262 2.16669 15.0728 2.16669 13.766V6.23268C2.16669 4.92589 2.16669 4.2725 2.421 3.77337C2.64471 3.33433 3.00166 2.97737 3.44071 2.75367C3.72487 2.60888 4.05904 2.54652 4.53531 2.51966V4.02265C4.51984 4.02376 4.50462 4.02493 4.48964 4.02616C4.19848 4.04994 4.12702 4.08738 4.12191 4.09007C3.9651 4.16996 3.83741 4.29755 3.75752 4.45436C3.75483 4.45947 3.71728 4.53114 3.69349 4.8223C3.66785 5.13614 3.66669 5.55454 3.66669 6.23268V13.766C3.66669 14.4442 3.66785 14.8626 3.69349 15.1764C3.71728 15.4676 3.75472 15.539 3.75741 15.5441C3.8373 15.7009 3.96489 15.8286 4.12169 15.9085C4.12682 15.9112 4.1985 15.9488 4.48964 15.9725C4.50462 15.9738 4.51984 15.9749 4.53531 15.976V17.479Z" fill="#111824"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.4577 3.33268H8.5423C7.95474 3.33268 7.61431 3.33398 7.36442 3.3544C7.25432 3.36339 7.19609 3.37413 7.17186 3.37955C7.12412 3.40795 7.08423 3.44784 7.05583 3.49558C7.05041 3.51981 7.03967 3.57804 7.03068 3.68814C7.01026 3.93803 7.00896 4.27846 7.00896 4.86602V15.1327C7.00896 15.7202 7.01026 16.0607 7.03068 16.3106C7.03967 16.4207 7.05041 16.4789 7.05583 16.5031C7.08423 16.5509 7.12412 16.5907 7.17187 16.6192C7.19609 16.6246 7.25432 16.6353 7.36442 16.6443C7.61431 16.6647 7.95474 16.666 8.5423 16.666H11.4577C12.0453 16.666 12.3857 16.6647 12.6356 16.6443C12.7457 16.6353 12.8039 16.6246 12.8282 16.6191C12.8759 16.5907 12.9158 16.5509 12.9442 16.5031C12.9496 16.4789 12.9604 16.4207 12.9694 16.3106C12.9898 16.0607 12.9911 15.7202 12.9911 15.1327V4.86602C12.9911 4.27846 12.9898 3.93803 12.9694 3.68814C12.9604 3.57804 12.9496 3.51981 12.9442 3.49558C12.9158 3.44784 12.8759 3.40795 12.8282 3.37955C12.8039 3.37413 12.7457 3.36339 12.6356 3.3544C12.3857 3.33398 12.0453 3.33268 11.4577 3.33268ZM12.8421 3.38304L12.8408 3.38266L12.8421 3.38304ZM12.9407 16.517L12.9411 16.5157L12.9407 16.517ZM7.15797 16.6157L7.15924 16.616L7.15797 16.6157ZM5.56028 2.75803C5.3423 3.18586 5.3423 3.74591 5.3423 4.86602V15.1327C5.3423 16.2528 5.3423 16.8128 5.56028 17.2407C5.75203 17.617 6.05799 17.9229 6.43432 18.1147C6.86214 18.3327 7.42219 18.3327 8.5423 18.3327H11.4577C12.5778 18.3327 13.1379 18.3327 13.5657 18.1147C13.942 17.9229 14.248 17.617 14.4397 17.2407C14.6577 16.8128 14.6577 16.2528 14.6577 15.1327V4.86602C14.6577 3.74591 14.6577 3.18586 14.4397 2.75803C14.248 2.38171 13.942 2.07575 13.5657 1.884C13.1379 1.66602 12.5778 1.66602 11.4577 1.66602H8.5423C7.42219 1.66602 6.86214 1.66602 6.43432 1.884C6.05799 2.07575 5.75203 2.38171 5.56028 2.75803Z" fill="#111824"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 19">
|
||||
<path d="M13.916 15.9818C14.3458 15.9577 14.6472 15.9017 14.9034 15.7711C15.2985 15.5698 15.6198 15.2485 15.8211 14.8534C16.05 14.4042 16.05 13.8161 16.05 12.64V5.86C16.05 4.68389 16.05 4.09583 15.8211 3.64662C15.6198 3.25148 15.2985 2.93022 14.9034 2.72889C14.6472 2.59835 14.3458 2.54226 13.916 2.51816C13.9182 2.69923 13.9182 2.90169 13.9182 3.13V3.87097C13.9322 3.87197 13.9459 3.87303 13.9594 3.87413C14.2214 3.89554 14.2857 3.92923 14.2903 3.93165C14.4314 4.00355 14.5464 4.11839 14.6183 4.25951C14.6207 4.26411 14.6545 4.32861 14.6759 4.59066C14.699 4.87311 14.7 5.24967 14.7 5.86V12.64C14.7 13.2503 14.699 13.6269 14.6759 13.9093C14.6545 14.1714 14.6208 14.2357 14.6184 14.2403C14.5465 14.3814 14.4316 14.4963 14.2905 14.5683C14.2859 14.5707 14.2214 14.6045 13.9594 14.6259C13.9459 14.627 13.9322 14.628 13.9182 14.629V15.37C13.9182 15.5983 13.9182 15.8008 13.916 15.9818Z"/>
|
||||
<path d="M4.08178 15.9817C3.65313 15.9575 3.35238 15.9014 3.09663 15.7711C2.70149 15.5698 2.38023 15.2485 2.1789 14.8534C1.95001 14.4042 1.95001 13.8161 1.95001 12.64V5.86C1.95001 4.68389 1.95001 4.09583 2.1789 3.64662C2.38023 3.25148 2.70149 2.93022 3.09663 2.72889C3.35238 2.59858 3.65313 2.54245 4.08178 2.51828V3.87097C4.06785 3.87197 4.05415 3.87302 4.04067 3.87413C3.77863 3.89554 3.71432 3.92923 3.70971 3.93165C3.56859 4.00355 3.45366 4.11838 3.38176 4.25951C3.37934 4.26411 3.34555 4.32861 3.32414 4.59066C3.30106 4.87311 3.30001 5.24967 3.30001 5.86V12.64C3.30001 13.2503 3.30106 13.6269 3.32414 13.9093C3.34555 14.1714 3.37925 14.2357 3.38166 14.2403C3.45356 14.3814 3.5684 14.4963 3.70952 14.5683C3.71413 14.5707 3.77864 14.6045 4.04067 14.6259C4.05415 14.627 4.06785 14.628 4.08178 14.629V15.9817Z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.312 3.25H7.68806C7.15926 3.25 6.85288 3.25117 6.62797 3.26954C6.52888 3.27764 6.47648 3.2873 6.45467 3.29218C6.4117 3.31774 6.3758 3.35364 6.35024 3.39661C6.34536 3.41842 6.3357 3.47082 6.3276 3.56991C6.30923 3.79481 6.30806 4.1012 6.30806 4.63V13.87C6.30806 14.3988 6.30923 14.7052 6.3276 14.9301C6.3357 15.0292 6.34536 15.0816 6.35024 15.1034C6.3758 15.1464 6.41171 15.1823 6.45467 15.2078C6.47648 15.2127 6.52888 15.2224 6.62797 15.2305C6.85288 15.2488 7.15926 15.25 7.68806 15.25H10.312C10.8408 15.25 11.1471 15.2488 11.372 15.2305C11.4711 15.2224 11.5235 15.2127 11.5453 15.2078C11.5883 15.1823 11.6242 15.1464 11.6498 15.1034C11.6547 15.0816 11.6643 15.0292 11.6724 14.9301C11.6908 14.7052 11.692 14.3988 11.692 13.87V4.63C11.692 4.1012 11.6908 3.79481 11.6724 3.56991C11.6643 3.47082 11.6547 3.41841 11.6498 3.39661C11.6242 3.35364 11.5883 3.31774 11.5453 3.29218C11.5235 3.2873 11.4711 3.27764 11.372 3.26954C11.1471 3.25117 10.8408 3.25 10.312 3.25ZM11.5578 3.29532L11.5567 3.29498ZM11.6466 15.1159L11.647 15.1148ZM6.44217 15.2047L6.44331 15.205ZM5.00425 2.73282C4.80806 3.11786 4.80806 3.62191 4.80806 4.63V13.87C4.80806 14.8781 4.80806 15.3821 5.00425 15.7672C5.17682 16.1059 5.45219 16.3812 5.79088 16.5538C6.17592 16.75 6.67997 16.75 7.68806 16.75H10.312C11.3201 16.75 11.8241 16.75 12.2091 16.5538C12.5478 16.3812 12.8232 16.1059 12.9958 15.7672C13.192 15.3821 13.192 14.8781 13.192 13.87V4.63C13.192 3.62191 13.192 3.11786 12.9958 2.73282C12.8232 2.39413 12.5478 2.11876 12.2091 1.94619C11.8241 1.75 11.3201 1.75 10.312 1.75H7.68806C6.67997 1.75 6.17592 1.75 5.79088 1.94619C5.45219 2.11876 5.17682 2.39413 5.00425 2.73282Z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.4 KiB |
@@ -1,11 +1,3 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1703750094429"
|
||||
class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4262"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128">
|
||||
<path
|
||||
d="M512 0C229.312 0 0 229.312 0 512s229.312 512 512 512 512-229.312 512-512-229.312-512-512-512z m311.04 823.04a437.76 437.76 0 0 1-139.84 94.336c-54.208 23.04-111.808 34.624-171.2 34.624a439.36 439.36 0 0 1-311.04-128.896 437.76 437.76 0 0 1-94.336-139.904A435.776 435.776 0 0 1 72 512a439.36 439.36 0 0 1 128.896-311.04 437.76 437.76 0 0 1 139.904-94.336A435.776 435.776 0 0 1 512 72a439.36 439.36 0 0 1 311.04 128.896 437.76 437.76 0 0 1 94.336 139.904c23.04 54.208 34.624 111.808 34.624 171.2 0 59.392-11.584 116.992-34.56 171.2a436.096 436.096 0 0 1-94.336 139.904z"
|
||||
p-id="4263"></path>
|
||||
<path
|
||||
d="M701.824 436.992h-167.04c0.704 0 1.408-0.32 2.112-1.024l118.208-117.76a35.904 35.904 0 0 0-50.816-50.56L511.872 360.064l-92.864-92.8a36.16 36.16 0 0 0-51.136 0.192 36.16 36.16 0 0 0-0.064 51.072l118.208 118.08c0.64 0.704 1.408 1.728 2.112 1.728H321.6a34.688 34.688 0 0 0-34.304 34.56v3.2c0 18.816 15.488 33.856 34.304 33.856h154.368v64H353.536c-18.752 0-33.472 16.256-33.472 35.072v4.032c0 18.752 14.72 32.896 33.472 32.896h122.56v149.184a35.968 35.968 0 1 0 72 0v-149.184h121.792c18.752 0 35.2-14.08 35.2-32.896v-4.032a35.968 35.968 0 0 0-35.2-35.072H548.032v-64h153.792c18.752 0 35.2-14.208 35.2-33.088v-4.032a36.672 36.672 0 0 0-35.2-35.84z"
|
||||
p-id="4264"></path>
|
||||
<svg viewBox="0 0 18 19" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.99998 3.11133C5.60976 3.11133 2.86145 5.85964 2.86145 9.24986C2.86145 12.6401 5.60976 15.3884 8.99998 15.3884C12.3902 15.3884 15.1385 12.6401 15.1385 9.24986C15.1385 5.85964 12.3902 3.11133 8.99998 3.11133ZM1.36145 9.24986C1.36145 5.03121 4.78134 1.61133 8.99998 1.61133C13.2186 1.61133 16.6385 5.03121 16.6385 9.24986C16.6385 13.4685 13.2186 16.8884 8.99998 16.8884C4.78134 16.8884 1.36145 13.4685 1.36145 9.24986ZM5.77605 5.21994C6.09949 4.96118 6.57146 5.01363 6.83022 5.33707L8.99998 8.04927L11.1697 5.33707C11.4285 5.01363 11.9005 4.96118 12.2239 5.21994C12.5474 5.4787 12.5998 5.95067 12.341 6.27411L10.5604 8.49986H11.7554C12.1696 8.49986 12.5054 8.83564 12.5054 9.24986C12.5054 9.66407 12.1696 9.99986 11.7554 9.99986H9.74998V10.5664H11.411C11.8252 10.5664 12.161 10.9022 12.161 11.3164C12.161 11.7306 11.8252 12.0664 11.411 12.0664H9.74998V13.383C9.74998 13.7972 9.41419 14.133 8.99998 14.133C8.58577 14.133 8.24998 13.7972 8.24998 13.383V12.0664H6.58899C6.17478 12.0664 5.83899 11.7306 5.83899 11.3164C5.83899 10.9022 6.17478 10.5664 6.58899 10.5664H8.24998V9.99986H6.24457C5.83035 9.99986 5.49457 9.66407 5.49457 9.24986C5.49457 8.83564 5.83035 8.49986 6.24457 8.49986H7.43951L5.65892 6.27411C5.40016 5.95067 5.4526 5.4787 5.77605 5.21994Z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 19" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.00001 3.25C7.55026 3.25 6.37501 4.42525 6.37501 5.875C6.37501 7.32475 7.55026 8.5 9.00001 8.5C10.4498 8.5 11.625 7.32475 11.625 5.875C11.625 4.42525 10.4498 3.25 9.00001 3.25ZM4.87501 5.875C4.87501 3.59683 6.72184 1.75 9.00001 1.75C11.2782 1.75 13.125 3.59683 13.125 5.875C13.125 8.15317 11.2782 10 9.00001 10C6.72184 10 4.87501 8.15317 4.87501 5.875ZM9.00001 12.25C6.87074 12.25 4.97288 13.277 3.76039 14.8816C3.68622 14.9798 3.62945 15.055 3.58224 15.1211C3.54639 15.1713 3.52192 15.2081 3.50489 15.2361C3.61636 15.2488 3.77519 15.25 4.07044 15.25H13.9296C14.2248 15.25 14.3837 15.2488 14.4951 15.2361C14.4781 15.2081 14.4536 15.1713 14.4178 15.1211C14.3706 15.055 14.3138 14.9798 14.2396 14.8816C13.0271 13.277 11.1293 12.25 9.00001 12.25ZM2.56362 13.9773C4.04334 12.019 6.37417 10.75 9.00001 10.75C11.6259 10.75 13.9567 12.019 15.4364 13.9773C15.4431 13.9862 15.4498 13.9951 15.4566 14.004C15.5838 14.1722 15.7202 14.3526 15.8177 14.5267C15.9357 14.7373 16.0231 14.981 16.0177 15.2774C16.0134 15.5157 15.9412 15.7387 15.8535 15.9148C15.7659 16.0909 15.6315 16.2829 15.444 16.43C15.194 16.6262 14.9218 16.6957 14.68 16.7247C14.4679 16.7501 14.2165 16.7501 13.9638 16.75C13.9524 16.75 13.941 16.75 13.9296 16.75H4.07044C4.05904 16.75 4.04765 16.75 4.03626 16.75C3.78351 16.7501 3.53212 16.7501 3.31999 16.7247C3.0782 16.6957 2.80602 16.6262 2.55603 16.43C2.36857 16.2829 2.23415 16.0909 2.14649 15.9148C2.05884 15.7387 1.98665 15.5157 1.98229 15.2774C1.97687 14.981 2.06433 14.7373 2.18233 14.5267C2.27982 14.3526 2.41624 14.1722 2.54346 14.004C2.55021 13.9951 2.55693 13.9862 2.56362 13.9773Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,4 @@
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.0149 3.68687C6.72097 3.68687 5.67204 4.7358 5.67204 6.02973C5.67204 7.32366 6.72097 8.37259 8.0149 8.37259C9.30883 8.37259 10.3578 7.32366 10.3578 6.02973C10.3578 4.7358 9.30883 3.68687 8.0149 3.68687ZM4.00537 6.02973C4.00537 3.81533 5.8005 2.0202 8.0149 2.0202C10.2293 2.0202 12.0244 3.81533 12.0244 6.02973C12.0244 8.24413 10.2293 10.0393 8.0149 10.0393C5.8005 10.0393 4.00537 8.24413 4.00537 6.02973ZM12.0067 2.77173C12.1794 2.34512 12.6653 2.13928 13.0919 2.31196C14.5597 2.90614 15.5976 4.34573 15.5976 6.02973C15.5976 7.71373 14.5597 9.15332 13.0919 9.7475C12.6653 9.92019 12.1794 9.71434 12.0067 9.28773C11.8341 8.86112 12.0399 8.37529 12.4665 8.2026C13.3267 7.85443 13.931 7.01165 13.931 6.02973C13.931 5.04781 13.3267 4.20504 12.4665 3.85686C12.0399 3.68417 11.8341 3.19834 12.0067 2.77173ZM6.79443 11.5488H9.23537C9.95037 11.5488 10.5291 11.5488 11.0006 11.5809C11.4859 11.6141 11.9181 11.684 12.3284 11.854C13.3109 12.2609 14.0914 13.0415 14.4984 14.0239C14.6683 14.4343 14.7383 14.8664 14.7714 15.3518C14.8036 15.8232 14.8036 16.402 14.8036 17.117V17.1464C14.8036 17.6067 14.4305 17.9798 13.9703 17.9798C13.51 17.9798 13.1369 17.6067 13.1369 17.1464C13.1369 16.3951 13.1365 15.8733 13.1086 15.4653C13.0813 15.0648 13.0304 14.8351 12.9586 14.6617C12.7208 14.0877 12.2647 13.6316 11.6906 13.3938C11.5173 13.322 11.2876 13.2711 10.8871 13.2437C10.4791 13.2159 9.95733 13.2155 9.20597 13.2155H6.82382C6.07246 13.2155 5.55067 13.2159 5.14268 13.2437C4.74216 13.2711 4.51253 13.322 4.33915 13.3938C3.76508 13.6316 3.30899 14.0877 3.0712 14.6617C2.99939 14.8351 2.94848 15.0648 2.92115 15.4653C2.89331 15.8733 2.89286 16.3951 2.89286 17.1464C2.89286 17.6067 2.51977 17.9798 2.05953 17.9798C1.59929 17.9798 1.2262 17.6067 1.2262 17.1464L1.2262 17.117C1.22619 16.402 1.22619 15.8233 1.25835 15.3518C1.29147 14.8664 1.36145 14.4343 1.5314 14.0239C1.93835 13.0415 2.7189 12.2609 3.70135 11.854C4.11166 11.684 4.54385 11.6141 5.02922 11.5809C5.50067 11.5488 6.07942 11.5488 6.79443 11.5488ZM14.7513 12.2745C14.8661 11.8288 15.3204 11.5604 15.7661 11.6752C17.4952 12.1202 18.7738 13.6889 18.7738 15.5583V17.1464C18.7738 17.6067 18.4007 17.9798 17.9405 17.9798C17.4803 17.9798 17.1072 17.6067 17.1072 17.1464V15.5583C17.1072 14.4678 16.3613 13.5493 15.3506 13.2892C14.9049 13.1745 14.6366 12.7202 14.7513 12.2745Z" fill="#3370FF"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.0149 3.6869C6.72097 3.6869 5.67204 4.73584 5.67204 6.02976C5.67204 7.32369 6.72097 8.37263 8.0149 8.37263C9.30883 8.37263 10.3578 7.32369 10.3578 6.02976C10.3578 4.73584 9.30883 3.6869 8.0149 3.6869ZM4.00537 6.02976C4.00537 3.81536 5.8005 2.02023 8.0149 2.02023C10.2293 2.02023 12.0244 3.81536 12.0244 6.02976C12.0244 8.24416 10.2293 10.0393 8.0149 10.0393C5.8005 10.0393 4.00537 8.24416 4.00537 6.02976ZM12.0067 2.77176C12.1794 2.34515 12.6653 2.13931 13.0919 2.31199C14.5597 2.90617 15.5976 4.34576 15.5976 6.02976C15.5976 7.71376 14.5597 9.15335 13.0919 9.74753C12.6653 9.92022 12.1794 9.71437 12.0067 9.28776C11.8341 8.86115 12.0399 8.37532 12.4665 8.20263C13.3267 7.85446 13.931 7.01168 13.931 6.02976C13.931 5.04784 13.3267 4.20507 12.4665 3.85689C12.0399 3.6842 11.8341 3.19838 12.0067 2.77176ZM6.79443 11.5488H9.23537C9.95037 11.5488 10.5291 11.5488 11.0006 11.581C11.4859 11.6141 11.9181 11.6841 12.3284 11.854C13.3109 12.261 14.0914 13.0415 14.4984 14.024C14.6683 14.4343 14.7383 14.8665 14.7714 15.3518C14.8036 15.8233 14.8036 16.402 14.8036 17.117V17.1464C14.8036 17.6067 14.4305 17.9798 13.9703 17.9798C13.51 17.9798 13.1369 17.6067 13.1369 17.1464C13.1369 16.3951 13.1365 15.8733 13.1086 15.4653C13.0813 15.0648 13.0304 14.8352 12.9586 14.6618C12.7208 14.0877 12.2647 13.6316 11.6906 13.3938C11.5173 13.322 11.2876 13.2711 10.8871 13.2438C10.4791 13.2159 9.95733 13.2155 9.20597 13.2155H6.82382C6.07246 13.2155 5.55067 13.2159 5.14268 13.2438C4.74216 13.2711 4.51253 13.322 4.33915 13.3938C3.76508 13.6316 3.30899 14.0877 3.0712 14.6618C2.99939 14.8352 2.94848 15.0648 2.92115 15.4653C2.89331 15.8733 2.89286 16.3951 2.89286 17.1464C2.89286 17.6067 2.51977 17.9798 2.05953 17.9798C1.59929 17.9798 1.2262 17.6067 1.2262 17.1464L1.2262 17.117C1.22619 16.402 1.22619 15.8233 1.25835 15.3518C1.29147 14.8665 1.36145 14.4343 1.5314 14.024C1.93835 13.0415 2.7189 12.261 3.70135 11.854C4.11166 11.6841 4.54385 11.6141 5.02922 11.581C5.50067 11.5488 6.07942 11.5488 6.79443 11.5488ZM14.7513 12.2745C14.8661 11.8288 15.3204 11.5605 15.7661 11.6752C17.4952 12.1202 18.7738 13.6889 18.7738 15.5584V17.1464C18.7738 17.6067 18.4007 17.9798 17.9405 17.9798C17.4803 17.9798 17.1072 17.6067 17.1072 17.1464V15.5584C17.1072 14.4678 16.3613 13.5494 15.3506 13.2892C14.9049 13.1745 14.6366 12.7202 14.7513 12.2745Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
@@ -26,8 +26,9 @@ const MyNumberInput = (props: Props) => {
|
||||
{...restProps}
|
||||
onChange={(e) => {
|
||||
if (!onChange) return;
|
||||
if (isNaN(Number(e))) {
|
||||
onChange();
|
||||
if (e === '') {
|
||||
// @ts-ignore
|
||||
onChange('');
|
||||
} else {
|
||||
onChange(Number(e));
|
||||
}
|
||||
|
230
packages/web/components/common/MySelect/CronSelector.tsx
Normal file
@@ -0,0 +1,230 @@
|
||||
import React, { useCallback, useRef } from 'react';
|
||||
import MultipleRowSelect from './MultipleRowSelect';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { MultipleSelectProps } from './type';
|
||||
import { cronParser2Fields } from '@fastgpt/global/common/string/time';
|
||||
|
||||
type CronType = 'month' | 'week' | 'day' | 'interval';
|
||||
|
||||
type CronFieldType = [CronType, number, number];
|
||||
|
||||
enum CronJobTypeEnum {
|
||||
month = 'month',
|
||||
week = 'week',
|
||||
day = 'day',
|
||||
interval = 'interval'
|
||||
}
|
||||
|
||||
export const defaultCronString = '0 0 * * *';
|
||||
|
||||
export const defaultValue = [CronJobTypeEnum.day, 0, 0];
|
||||
|
||||
export const cronString2Fields = (cronString?: string) => {
|
||||
if (!cronString) {
|
||||
return undefined;
|
||||
}
|
||||
const cronField = cronParser2Fields(cronString);
|
||||
|
||||
if (!cronField) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
if (cronField.dayOfMonth.length !== 31) {
|
||||
return [CronJobTypeEnum.month, cronField.dayOfMonth[0], cronField.hour[0]];
|
||||
}
|
||||
if (cronField.dayOfWeek.length !== 8) {
|
||||
return [CronJobTypeEnum.week, cronField.dayOfWeek[0], cronField.hour[0]];
|
||||
}
|
||||
if (cronField.hour.length === 1) {
|
||||
return [CronJobTypeEnum.day, cronField.hour[0], 0];
|
||||
}
|
||||
return [CronJobTypeEnum.interval, 24 / cronField.hour.length, 0];
|
||||
};
|
||||
|
||||
export const cronString2Label = (
|
||||
cronString: string,
|
||||
t: any // i18nT
|
||||
) => {
|
||||
const cronField = cronString2Fields(cronString);
|
||||
if (!cronField) {
|
||||
return t('common:common.Not open');
|
||||
}
|
||||
|
||||
if (cronField[0] === 'month') {
|
||||
return t('common:core.app.schedule.Every month', {
|
||||
day: cronField[1],
|
||||
hour: cronField[2]
|
||||
});
|
||||
}
|
||||
if (cronField[0] === 'week') {
|
||||
const weekMap = {
|
||||
0: t('app:week.Sunday'),
|
||||
1: t('app:week.Monday'),
|
||||
2: t('app:week.Tuesday'),
|
||||
3: t('app:week.Wednesday'),
|
||||
4: t('app:week.Thursday'),
|
||||
5: t('app:week.Friday'),
|
||||
6: t('app:week.Saturday')
|
||||
};
|
||||
return t('common:core.app.schedule.Every week', {
|
||||
day: weekMap[cronField[1] as keyof typeof weekMap],
|
||||
hour: cronField[2]
|
||||
});
|
||||
}
|
||||
if (cronField[0] === 'day') {
|
||||
return t('common:core.app.schedule.Every day', {
|
||||
hour: cronField[1]
|
||||
});
|
||||
}
|
||||
if (cronField[0] === 'interval') {
|
||||
return t('common:core.app.schedule.Interval', {
|
||||
interval: cronField[1]
|
||||
});
|
||||
}
|
||||
|
||||
return t('common:common.Not open');
|
||||
};
|
||||
|
||||
const CronSelector = ({
|
||||
cronString,
|
||||
onChange
|
||||
}: {
|
||||
cronString?: string;
|
||||
onChange: (e: string) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const get24HoursOptions = () => {
|
||||
return Array.from({ length: 24 }, (_, i) => ({
|
||||
label: `${i < 10 ? '0' : ''}${i}:00`,
|
||||
value: i
|
||||
}));
|
||||
};
|
||||
const getRoute = (i: number) => {
|
||||
const { t } = useTranslation();
|
||||
switch (i) {
|
||||
case 0:
|
||||
return t('app:week.Sunday');
|
||||
case 1:
|
||||
return t('app:week.Monday');
|
||||
case 2:
|
||||
return t('app:week.Tuesday');
|
||||
case 3:
|
||||
return t('app:week.Wednesday');
|
||||
case 4:
|
||||
return t('app:week.Thursday');
|
||||
case 5:
|
||||
return t('app:week.Friday');
|
||||
case 6:
|
||||
return t('app:week.Saturday');
|
||||
default:
|
||||
return t('app:week.Sunday');
|
||||
}
|
||||
};
|
||||
const getWeekOptions = () => {
|
||||
return Array.from({ length: 7 }, (_, i) => {
|
||||
return {
|
||||
label: getRoute(i),
|
||||
value: i,
|
||||
children: get24HoursOptions()
|
||||
};
|
||||
});
|
||||
};
|
||||
const getMonthOptions = () => {
|
||||
return Array.from({ length: 28 }, (_, i) => ({
|
||||
label: i + 1 + t('app:month.unit'),
|
||||
value: i + 1,
|
||||
children: get24HoursOptions()
|
||||
}));
|
||||
};
|
||||
const getInterValOptions = () => {
|
||||
// 每n小时
|
||||
return [
|
||||
{
|
||||
label: t('app:interval.per_hour'),
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: t('app:interval.2_hours'),
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
label: t('app:interval.3_hours'),
|
||||
value: 3
|
||||
},
|
||||
{
|
||||
label: t('app:interval.4_hours'),
|
||||
value: 4
|
||||
},
|
||||
{
|
||||
label: t('app:interval.6_hours'),
|
||||
value: 6
|
||||
},
|
||||
{
|
||||
label: t('app:interval.12_hours'),
|
||||
value: 12
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
const cronField = cronString2Fields(cronString) as CronFieldType;
|
||||
|
||||
const formatLabel = cronString2Label(cronString ?? '', t);
|
||||
|
||||
const cronConfig2cronString = useCallback(
|
||||
(e: CronFieldType) => {
|
||||
const str = (() => {
|
||||
if (e[0] === CronJobTypeEnum.month) {
|
||||
return `0 ${e[2]} ${e[1]} * *`;
|
||||
} else if (e[0] === CronJobTypeEnum.week) {
|
||||
return `0 ${e[2]} * * ${e[1]}`;
|
||||
} else if (e[0] === CronJobTypeEnum.day) {
|
||||
return `0 ${e[1]} * * *`;
|
||||
} else if (e[0] === CronJobTypeEnum.interval) {
|
||||
return `0 */${e[1]} * * *`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
})();
|
||||
onChange(str);
|
||||
},
|
||||
[onChange]
|
||||
);
|
||||
|
||||
const cronSelectList = useRef<MultipleSelectProps['list']>([
|
||||
{
|
||||
label: t('app:cron.every_day'),
|
||||
value: CronJobTypeEnum.day,
|
||||
children: get24HoursOptions()
|
||||
},
|
||||
{
|
||||
label: t('app:cron.every_week'),
|
||||
value: CronJobTypeEnum.week,
|
||||
children: getWeekOptions()
|
||||
},
|
||||
{
|
||||
label: t('app:cron.every_month'),
|
||||
value: CronJobTypeEnum.month,
|
||||
children: getMonthOptions()
|
||||
},
|
||||
{
|
||||
label: t('app:cron.interval'),
|
||||
value: CronJobTypeEnum.interval,
|
||||
children: getInterValOptions()
|
||||
}
|
||||
]);
|
||||
|
||||
return (
|
||||
<MultipleRowSelect
|
||||
label={formatLabel}
|
||||
value={cronField}
|
||||
list={cronSelectList.current}
|
||||
onSelect={(e) => {
|
||||
cronConfig2cronString(e as CronFieldType);
|
||||
}}
|
||||
changeOnEverySelect
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(CronSelector);
|