Compare commits
38 Commits
v4.8.20-fi
...
v4.8.22-al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09205e4666 | ||
|
|
ccf28d83b8 | ||
|
|
420aaad48e | ||
|
|
8ba2339890 | ||
|
|
e7b8934367 | ||
|
|
3e13397614 | ||
|
|
b14674cc6f | ||
|
|
4d20274a97 | ||
|
|
4447e40364 | ||
|
|
23949230ee | ||
|
|
cd7a897304 | ||
|
|
18aff8b8db | ||
|
|
d2b60ec785 | ||
|
|
1226fe42a1 | ||
|
|
abd375cdec | ||
|
|
7aacce8b0b | ||
|
|
686b09afd1 | ||
|
|
3cfec37e9d | ||
|
|
d3641c877c | ||
|
|
1094c65f2b | ||
|
|
abe082b9ab | ||
|
|
132cf69372 | ||
|
|
06a8a5e23d | ||
|
|
c42deab63b | ||
|
|
58f715e878 | ||
|
|
116936ffa9 | ||
|
|
f5d045eece | ||
|
|
8ac6494e60 | ||
|
|
f002896a24 | ||
|
|
8738c32fb0 | ||
|
|
896a3f1472 | ||
|
|
4284b78707 | ||
|
|
fac5b6b50d | ||
|
|
51e17a47fa | ||
|
|
42b2046f96 | ||
|
|
bb82b515e0 | ||
|
|
fe688cdf2d | ||
|
|
0d35326909 |
@@ -13,8 +13,8 @@ weight: 707
|
||||
|
||||
下面配置文件示例中包含了系统参数和各个模型配置:
|
||||
|
||||
## 4.6.8+ 版本新配置文件示例
|
||||
|
||||
## 4.8.20+ 版本新配置文件示例
|
||||
> 从4.8.20版本开始,模型在页面中进行配置。
|
||||
```json
|
||||
{
|
||||
"feConfigs": {
|
||||
@@ -27,4 +27,4 @@ weight: 707
|
||||
"pgHNSWEfSearch": 100 // 向量搜索参数。越大,搜索越精确,但是速度越慢。设置为100,有99%+精度。
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
@@ -11,7 +11,7 @@ weight: 707
|
||||
|
||||
1. 基础的网络知识:端口,防火墙……
|
||||
2. Docker 和 Docker Compose 基础知识
|
||||
3. 大模型相关接口和参数
|
||||
3. 大模型相关接口和参数
|
||||
4. RAG 相关知识:向量模型,向量数据库,向量检索
|
||||
|
||||
## 部署架构图
|
||||
@@ -211,6 +211,8 @@ docker restart oneapi
|
||||
|
||||
### 6. 配置模型
|
||||
|
||||
务必先配置至少一组模型,否则系统无法正常使用。
|
||||
|
||||
[点击查看模型配置教程](/docs/development/modelConfig/intro/)
|
||||
|
||||
## FAQ
|
||||
|
||||
@@ -9,17 +9,31 @@ images: []
|
||||
|
||||
## 一、错误排查方式
|
||||
|
||||
遇到问题先按下面方式排查。
|
||||
可以先找找[Issue](https://github.com/labring/FastGPT/issues),或新提 Issue,私有部署错误,务必提供详细的操作步骤、日志、截图,否则很难排查。
|
||||
|
||||
### 获取后端错误
|
||||
|
||||
1. `docker ps -a` 查看所有容器运行状态,检查是否全部 running,如有异常,尝试`docker logs 容器名`查看对应日志。
|
||||
2. 容器都运行正常的,`docker logs 容器名` 查看报错日志
|
||||
3. 带有`requestId`的,都是 OneAPI 提示错误,大部分都是因为模型接口报错。
|
||||
4. 无法解决时,可以找找[Issue](https://github.com/labring/FastGPT/issues),或新提 Issue,私有部署错误,务必提供详细的日志,否则很难排查。
|
||||
|
||||
### 前端错误
|
||||
|
||||
前端报错时,页面会出现崩溃,并提示检查控制台日志。可以打开浏览器控制台,并查看`console`中的 log 日志。还可以点击对应 log 的超链接,会提示到具体错误文件,可以把这些详细错误信息提供,方便排查。
|
||||
|
||||
### OneAPI 错误
|
||||
|
||||
带有`requestId`的,都是 OneAPI 提示错误,大部分都是因为模型接口报错。可以参考 [OneAPI 常见错误](/docs/development/faq/#三常见的-oneapi-错误)
|
||||
|
||||
## 二、通用问题
|
||||
|
||||
### 前端页面崩溃
|
||||
|
||||
1. 90% 情况是模型配置不正确:确保每类模型都至少有一个启用;检查模型中一些`对象`参数是否异常(数组和对象),如果为空,可以尝试给个空数组或空对象。
|
||||
2. 少部分是由于浏览器兼容问题,由于项目中包含一些高阶语法,可能低版本浏览器不兼容,可以将具体操作步骤和控制台中错误信息提供 issue。
|
||||
3. 关闭浏览器翻译功能,如果浏览器开启了翻译,可能会导致页面崩溃。
|
||||
|
||||
### 通过sealos部署的话,是否没有本地部署的一些限制?
|
||||
|
||||

|
||||
这是索引模型的长度限制,通过任何方式部署都一样的,但不同索引模型的配置不一样,可以在后台修改参数。
|
||||
|
||||
@@ -130,7 +144,7 @@ OneAPI 的 API Key 配置错误,需要修改`OPENAI_API_KEY`环境变量,并
|
||||
|
||||
## 四、常见模型问题
|
||||
|
||||
### 如何检查模型问题
|
||||
### 如何检查模型可用性问题
|
||||
|
||||
1. 私有部署模型,先确认部署的模型是否正常。
|
||||
2. 通过 CURL 请求,直接测试上游模型是否正常运行(云端模型或私有模型均进行测试)
|
||||
@@ -403,3 +417,7 @@ curl --location --request POST 'https://oneapi.xxxx/v1/chat/completions' \
|
||||
"tool_choice": "auto"
|
||||
}'
|
||||
```
|
||||
|
||||
### 向量检索得分大于 1
|
||||
|
||||
由于模型没有归一化导致的。目前仅支持归一化的模型。
|
||||
@@ -15,8 +15,8 @@ weight: 705
|
||||
|
||||
- [Git](http://git-scm.com/)
|
||||
- [Docker](https://www.docker.com/)(构建镜像)
|
||||
- [Node.js v18.17 / v20.x](http://nodejs.org)(版本尽量一样,可以使用nvm管理node版本)
|
||||
- [pnpm](https://pnpm.io/) 版本 8.6.0 (目前官方的开发环境)
|
||||
- [Node.js v20.14.0](http://nodejs.org)(版本尽量一样,可以使用nvm管理node版本)
|
||||
- [pnpm](https://pnpm.io/) 推荐版本 9.4.0 (目前官方的开发环境)
|
||||
- make命令: 根据不同平台,百度安装 (官方是GNU Make 4.3)
|
||||
|
||||
## 开始本地开发
|
||||
@@ -77,8 +77,6 @@ Mongo 数据库需要注意,需要注意在连接地址中增加 `directConnec
|
||||
可参考项目根目录下的 `dev.md`,第一次编译运行可能会有点慢,需要点耐心哦
|
||||
|
||||
```bash
|
||||
# 给自动化脚本代码执行权限(非 linux 系统, 可以手动执行里面的 postinstall.sh 文件内容)
|
||||
chmod -R +x ./scripts/
|
||||
# 代码根目录下执行,会安装根 package、projects 和 packages 内所有依赖
|
||||
# 如果提示 isolate-vm 安装失败,可以参考:https://github.com/laverdet/isolated-vm?tab=readme-ov-file#requirements
|
||||
pnpm i
|
||||
|
||||
@@ -43,7 +43,7 @@ weight: 744
|
||||
{{% alert icon="🤖 " context="success" %}}
|
||||
注意:
|
||||
1. 目前语音识别模型和重排模型仅会生效一个,所以配置时候,只需要配置一个即可。
|
||||
2. 用于知识库文件处理的语言模型,至少需要开启一个,否则知识库会报错。
|
||||
2. 系统至少需要一个语言模型和一个索引模型才能正常使用。
|
||||
{{% /alert %}}
|
||||
|
||||
#### 核心配置
|
||||
|
||||
@@ -672,7 +672,7 @@ curl --location --request POST 'http://localhost:3000/api/core/chat/getHistories
|
||||
"appId": "appId",
|
||||
"offset": 0,
|
||||
"pageSize": 20,
|
||||
"source: "api"
|
||||
"source": "api"
|
||||
}'
|
||||
```
|
||||
|
||||
|
||||
@@ -735,7 +735,7 @@ data 为集合的 ID。
|
||||
|
||||
**4.8.19+**
|
||||
```bash
|
||||
curl --location --request POST 'http://localhost:3000/api/core/dataset/collection/listv2' \
|
||||
curl --location --request POST 'http://localhost:3000/api/core/dataset/collection/listV2' \
|
||||
--header 'Authorization: Bearer {{authorization}}' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
|
||||
@@ -11,7 +11,7 @@ weight: 860
|
||||
|
||||
在 FastGPT V4.6.4 中,我们修改了分享链接的数据读取方式,为每个用户生成一个 localId,用于标识用户,从云端拉取对话记录。但是这种方式仅能保障用户在同一设备同一浏览器中使用,如果切换设备或者清空浏览器缓存则会丢失这些记录。这种方式存在一定的风险,因此我们仅允许用户拉取近`30天`的`20条`记录。
|
||||
|
||||
分享链接身份鉴权设计的目的在于,将 FastGPT 的对话框快速、安全的接入到你现有的系统中,仅需 2 个接口即可实现。
|
||||
分享链接身份鉴权设计的目的在于,将 FastGPT 的对话框快速、安全的接入到你现有的系统中,仅需 2 个接口即可实现。该功能目前只在商业版中提供。
|
||||
|
||||
## 使用说明
|
||||
|
||||
|
||||
@@ -60,6 +60,10 @@ FastGPT 使用了 one-api 项目来管理模型池,其可以兼容 OpenAI 、A
|
||||
|
||||
### 3. 配置模型
|
||||
|
||||
### 4. 配置模型
|
||||
|
||||
务必先配置至少一组模型,否则系统无法正常使用。
|
||||
|
||||
[点击查看模型配置教程](/docs/development/modelConfig/intro/)
|
||||
|
||||
## 收费
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: 'V4.8.18'
|
||||
title: 'V4.8.18(包含升级脚本)'
|
||||
description: 'FastGPT V4.8.18 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
|
||||
@@ -17,8 +17,8 @@ weight: 804
|
||||
|
||||
### 3. 更新镜像:
|
||||
|
||||
- 更新 fastgpt 镜像 tag: v4.8.20-fix
|
||||
- 更新 fastgpt-pro 商业版镜像 tag: v4.8.20-fix
|
||||
- 更新 fastgpt 镜像 tag: v4.8.20-fix2
|
||||
- 更新 fastgpt-pro 商业版镜像 tag: v4.8.20-fix2
|
||||
- Sandbox 镜像无需更新
|
||||
|
||||
### 4. 运行升级脚本
|
||||
@@ -35,7 +35,7 @@ curl --location --request POST 'https://{{host}}/api/admin/initv4820' \
|
||||
|
||||
## 完整更新内容
|
||||
|
||||
1. 新增 - 可视化模型参数配置。预设超过 100 个模型配置。同时支持所有类型模型的一键测试。(预计下个版本会完全支持在页面上配置渠道)。
|
||||
1. 新增 - 可视化模型参数配置,取代原配置文件配置模型。预设超过 100 个模型配置。同时支持所有类型模型的一键测试。(预计下个版本会完全支持在页面上配置渠道)。
|
||||
2. 新增 - DeepSeek resoner 模型支持输出思考过程。
|
||||
3. 新增 - 使用记录导出和仪表盘。
|
||||
4. 新增 - markdown 语法扩展,支持音视频(代码块 audio 和 video)。
|
||||
|
||||
39
docSite/content/zh-cn/docs/development/upgrading/4821.md
Normal file
39
docSite/content/zh-cn/docs/development/upgrading/4821.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: 'V4.8.21'
|
||||
description: 'FastGPT V4.8.21 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 803
|
||||
---
|
||||
|
||||
## 更新指南
|
||||
|
||||
### 1. 做好数据库备份
|
||||
|
||||
### 2. 更新镜像:
|
||||
|
||||
- 更新 fastgpt 镜像 tag: v4.8.21-fix
|
||||
- 更新 fastgpt-pro 商业版镜像 tag: v4.8.21-fix
|
||||
- Sandbox 镜像无需更新
|
||||
|
||||
## 完整更新内容
|
||||
|
||||
1. 新增 - 弃用/已删除的插件提示。
|
||||
2. 新增 - 对话日志按来源分类、标题检索、导出功能。
|
||||
3. 新增 - 全局变量支持拖拽排序。
|
||||
4. 新增 - LLM 模型支持 top_p, response_format, json_schema 参数。
|
||||
5. 新增 - Doubao1.5 模型预设。阿里 embedding3 预设。
|
||||
6. 新增 - 向量模型支持归一化配置,以便适配未归一化的向量模型,例如 Doubao 的 embedding 模型。
|
||||
6. 新增 - AI 对话节点,支持输出思考过程结果,可用于其他节点引用。
|
||||
7. 优化 - 网站嵌入式聊天窗口,增加窗口位置适配。
|
||||
8. 优化 - 模型未配置时错误提示。
|
||||
9. 优化 - 适配非 Stream 模式思考输出。
|
||||
10. 优化 - 增加 TTS voice 未配置时的空指针保护。
|
||||
11. 优化 - Markdown 链接解析分割规则,改成严格匹配模式,牺牲兼容多种情况,减少误解析。
|
||||
12. 优化 - 减少未登录用户的数据获取范围,提高系统隐私性。
|
||||
13. 修复 - 简易模式,切换到其他非视觉模型时候,会强制关闭图片识别。
|
||||
14. 修复 - o1,o3 模型,在测试时候字段映射未生效导致报错。
|
||||
15. 修复 - 公众号对话空指针异常。
|
||||
16. 修复 - 多个音频/视频文件展示异常。
|
||||
17. 修复 - 分享链接鉴权报错后无限循环。
|
||||
23
docSite/content/zh-cn/docs/development/upgrading/4822.md
Normal file
23
docSite/content/zh-cn/docs/development/upgrading/4822.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: 'V4.8.22(进行中)'
|
||||
description: 'FastGPT V4.8.22 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 802
|
||||
---
|
||||
|
||||
|
||||
## 完整更新内容
|
||||
|
||||
1. 新增 - AI 对话节点解析 <think></think> 标签内容,便于各类模型进行思考链输出。
|
||||
2. 优化 - 模型未配置时提示,减少冲突提示。
|
||||
3. 优化 - 使用记录代码。
|
||||
4. 修复 - 思考内容未进入到输出 Tokens.
|
||||
5. 修复 - 思考链流输出时,有时与正文顺序偏差。
|
||||
6. 修复 - API 调用工作流,如果传递的图片不支持 Head 检测时,图片会被过滤。已增加该类错误检测,避免被错误过滤。
|
||||
7. 修复 - 模板市场部分模板错误。
|
||||
8. 修复 - 免登录窗口无法正常判断语言识别是否开启。
|
||||
9. 修复 - 对话日志导出,未兼容 sub path。
|
||||
10. 修复 - list 接口在联查 member 时,存在空指针可能性。
|
||||
11. 修复 - 工作流基础节点无法升级。
|
||||
@@ -7,7 +7,7 @@ toc: true
|
||||
weight: 234
|
||||
---
|
||||
|
||||
知识库搜索具体参数说明,以及内部逻辑请移步:[FastGPT知识库搜索方案](/docs/course/data_search/)
|
||||
知识库搜索具体参数说明,以及内部逻辑请移步:[FastGPT知识库搜索方案](/docs/guide/knowledge_base/rag/)
|
||||
|
||||
## 特点
|
||||
|
||||
@@ -27,7 +27,7 @@ weight: 234
|
||||
|
||||
### 输入 - 搜索参数
|
||||
|
||||
[点击查看参数介绍](/docs/course/data_search/#搜索参数)
|
||||
[点击查看参数介绍](/docs/guide/knowledge_base/dataset_engine/#搜索参数)
|
||||
|
||||
### 输出 - 引用内容
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ weight: 502
|
||||

|
||||
|
||||
{{% alert icon="🍅" context="success" %}}
|
||||
Tips: 安全起见,你可以设置一个额度或者过期时间,放置 key 被滥用。
|
||||
Tips: 安全起见,你可以设置一个额度或者过期时间,防止 key 被滥用。
|
||||
{{% /alert %}}
|
||||
|
||||
|
||||
|
||||
@@ -114,15 +114,15 @@ services:
|
||||
# fastgpt
|
||||
sandbox:
|
||||
container_name: sandbox
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.8.20-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.20-fix # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.8.21-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.21-fix # 阿里云
|
||||
networks:
|
||||
- fastgpt
|
||||
restart: always
|
||||
fastgpt:
|
||||
container_name: fastgpt
|
||||
image: ghcr.io/labring/fastgpt:v4.8.20-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.20-fix # 阿里云
|
||||
image: ghcr.io/labring/fastgpt:v4.8.21-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.21-fix # 阿里云
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
|
||||
@@ -72,15 +72,15 @@ services:
|
||||
# fastgpt
|
||||
sandbox:
|
||||
container_name: sandbox
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.8.20-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.20-fix # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.8.21-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.21-fix # 阿里云
|
||||
networks:
|
||||
- fastgpt
|
||||
restart: always
|
||||
fastgpt:
|
||||
container_name: fastgpt
|
||||
image: ghcr.io/labring/fastgpt:v4.8.20-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.20-fix # 阿里云
|
||||
image: ghcr.io/labring/fastgpt:v4.8.21-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.21-fix # 阿里云
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
|
||||
@@ -53,15 +53,15 @@ services:
|
||||
wait $$!
|
||||
sandbox:
|
||||
container_name: sandbox
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.8.20-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.20-fix # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.8.21-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.21-fix # 阿里云
|
||||
networks:
|
||||
- fastgpt
|
||||
restart: always
|
||||
fastgpt:
|
||||
container_name: fastgpt
|
||||
image: ghcr.io/labring/fastgpt:v4.8.20-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.20-fix # 阿里云
|
||||
image: ghcr.io/labring/fastgpt:v4.8.21-fix # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.21-fix # 阿里云
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"format-code": "prettier --config \"./.prettierrc.js\" --write \"./**/src/**/*.{ts,tsx,scss}\"",
|
||||
"format-doc": "zhlint --dir ./docSite *.md --fix",
|
||||
"gen:theme-typings": "chakra-cli tokens packages/web/styles/theme.ts --out node_modules/.pnpm/node_modules/@chakra-ui/styled-system/dist/theming.types.d.ts",
|
||||
"postinstall": "sh ./scripts/postinstall.sh",
|
||||
"postinstall": "pnpm gen:theme-typings",
|
||||
"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",
|
||||
|
||||
@@ -16,8 +16,8 @@ export const bucketNameMap = {
|
||||
}
|
||||
};
|
||||
|
||||
export const ReadFileBaseUrl = `${process.env.FE_DOMAIN || ''}${process.env.NEXT_PUBLIC_BASE_URL || ''}/api/common/file/read`;
|
||||
export const ReadFileBaseUrl = `${process.env.FILE_DOMAIN || process.env.FE_DOMAIN || ''}${process.env.NEXT_PUBLIC_BASE_URL || ''}/api/common/file/read`;
|
||||
|
||||
export const documentFileType = '.txt, .docx, .csv, .xlsx, .pdf, .md, .html, .pptx';
|
||||
export const imageFileType =
|
||||
'.jpg, .jpeg, .png, .gif, .bmp, .webp, .svg, .tiff, .tif, .ico, .heic, .heif, .avif';
|
||||
'.jpg, .jpeg, .png, .gif, .bmp, .webp, .svg, .tiff, .tif, .ico, .heic, .heif, .avif, .raw, .cr2, .nef, .arw, .dng, .psd, .ai, .eps, .emf, .wmf, .jfif, .exif, .pgm, .ppm, .pbm, .jp2, .j2k, .jpf, .jpx, .jpm, .mj2, .xbm, .pcx';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { detect } from 'jschardet';
|
||||
import { documentFileType, imageFileType } from './constants';
|
||||
import { documentFileType } from './constants';
|
||||
import { ChatFileTypeEnum } from '../../core/chat/constants';
|
||||
import { UserChatItemValueItemType } from '../../core/chat/type';
|
||||
import * as fs from 'fs';
|
||||
@@ -25,6 +25,7 @@ export const detectFileEncodingByPath = async (path: string) => {
|
||||
const fd = await fs.promises.open(path, 'r');
|
||||
try {
|
||||
// Read file head
|
||||
// @ts-ignore
|
||||
const { bytesRead } = await fd.read(buffer, 0, MAX_BYTES, 0);
|
||||
const actualBuffer = buffer.slice(0, bytesRead);
|
||||
|
||||
@@ -37,40 +38,49 @@ export const detectFileEncodingByPath = async (path: string) => {
|
||||
// Url => user upload file type
|
||||
export const parseUrlToFileType = (url: string): UserChatItemValueItemType['file'] | undefined => {
|
||||
if (typeof url !== 'string') return;
|
||||
const parseUrl = new URL(url, 'https://locaohost:3000');
|
||||
|
||||
const filename = (() => {
|
||||
// Check base64 image
|
||||
if (url.startsWith('data:image/')) {
|
||||
const mime = url.split(',')[0].split(':')[1].split(';')[0];
|
||||
return `image.${mime.split('/')[1]}`;
|
||||
}
|
||||
// Old version file url: https://xxx.com/file/read?filename=xxx.pdf
|
||||
const filenameQuery = parseUrl.searchParams.get('filename');
|
||||
if (filenameQuery) return filenameQuery;
|
||||
// Handle base64 image
|
||||
if (url.startsWith('data:')) {
|
||||
const matches = url.match(/^data:([^;]+);base64,/);
|
||||
if (!matches) return;
|
||||
|
||||
// Common file: https://xxx.com/xxx.pdf?xxxx=xxx
|
||||
const pathname = parseUrl.pathname;
|
||||
if (pathname) return pathname.split('/').pop();
|
||||
})();
|
||||
const mimeType = matches[1].toLowerCase();
|
||||
if (!mimeType.startsWith('image/')) return;
|
||||
|
||||
if (!filename) return;
|
||||
|
||||
const extension = filename.split('.').pop()?.toLowerCase() || '';
|
||||
|
||||
if (!extension) return;
|
||||
|
||||
if (documentFileType.includes(extension)) {
|
||||
const extension = mimeType.split('/')[1];
|
||||
return {
|
||||
type: ChatFileTypeEnum.file,
|
||||
name: filename,
|
||||
type: ChatFileTypeEnum.image,
|
||||
name: `image.${extension}`,
|
||||
url
|
||||
};
|
||||
}
|
||||
if (imageFileType.includes(extension)) {
|
||||
|
||||
try {
|
||||
const parseUrl = new URL(url, 'https://localhost:3000');
|
||||
|
||||
// Get filename from URL
|
||||
const filename = parseUrl.searchParams.get('filename') || parseUrl.pathname.split('/').pop();
|
||||
const extension = filename?.split('.').pop()?.toLowerCase() || '';
|
||||
|
||||
// If it's a document type, return as file, otherwise treat as image
|
||||
if (extension && documentFileType.includes(extension)) {
|
||||
return {
|
||||
type: ChatFileTypeEnum.file,
|
||||
name: filename || 'null',
|
||||
url
|
||||
};
|
||||
}
|
||||
|
||||
// Default to image type for non-document files
|
||||
return {
|
||||
type: ChatFileTypeEnum.image,
|
||||
name: filename,
|
||||
name: filename || 'null.png',
|
||||
url
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
type: ChatFileTypeEnum.image,
|
||||
name: 'invalid.png',
|
||||
url
|
||||
};
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ export const simpleText = (text = '') => {
|
||||
};
|
||||
|
||||
export const valToStr = (val: any) => {
|
||||
if (val === undefined) return 'undefined';
|
||||
if (val === undefined) return '';
|
||||
if (val === null) return 'null';
|
||||
|
||||
if (typeof val === 'object') return JSON.stringify(val);
|
||||
|
||||
6
packages/global/core/ai/model.d.ts
vendored
6
packages/global/core/ai/model.d.ts
vendored
@@ -26,11 +26,16 @@ type BaseModelItemType = {
|
||||
export type LLMModelItemType = PriceType &
|
||||
BaseModelItemType & {
|
||||
type: ModelTypeEnum.llm;
|
||||
// Model params
|
||||
maxContext: number;
|
||||
maxResponse: number;
|
||||
quoteMaxToken: number;
|
||||
maxTemperature?: number;
|
||||
|
||||
showTopP?: boolean;
|
||||
responseFormatList?: string[];
|
||||
showStopSign?: boolean;
|
||||
|
||||
censor?: boolean;
|
||||
vision?: boolean;
|
||||
reasoning?: boolean;
|
||||
@@ -59,6 +64,7 @@ export type EmbeddingModelItemType = PriceType &
|
||||
maxToken: number; // model max token
|
||||
weight: number; // training weight
|
||||
hidden?: boolean; // Disallow creation
|
||||
normalization?: boolean; // normalization processing
|
||||
defaultConfig?: Record<string, any>; // post request config
|
||||
dbConfig?: Record<string, any>; // Custom parameters for storage
|
||||
queryConfig?: Record<string, any>; // Custom parameters for query
|
||||
|
||||
@@ -22,6 +22,7 @@ export type ModelProviderIdType =
|
||||
| 'StepFun'
|
||||
| 'Yi'
|
||||
| 'Siliconflow'
|
||||
| 'PPIO'
|
||||
| 'Ollama'
|
||||
| 'BAAI'
|
||||
| 'FishAudio'
|
||||
@@ -167,6 +168,11 @@ export const ModelProviderList: ModelProviderType[] = [
|
||||
name: i18nT('common:model_siliconflow'),
|
||||
avatar: 'model/siliconflow'
|
||||
},
|
||||
{
|
||||
id: 'PPIO',
|
||||
name: i18nT('common:model_ppio'),
|
||||
avatar: 'model/ppio'
|
||||
},
|
||||
{
|
||||
id: 'Other',
|
||||
name: i18nT('common:model_other'),
|
||||
|
||||
8
packages/global/core/ai/type.d.ts
vendored
8
packages/global/core/ai/type.d.ts
vendored
@@ -1,14 +1,12 @@
|
||||
import openai from 'openai';
|
||||
import type {
|
||||
ChatCompletionMessageToolCall,
|
||||
ChatCompletionChunk,
|
||||
ChatCompletionMessageParam as SdkChatCompletionMessageParam,
|
||||
ChatCompletionToolMessageParam,
|
||||
ChatCompletionContentPart as SdkChatCompletionContentPart,
|
||||
ChatCompletionUserMessageParam as SdkChatCompletionUserMessageParam,
|
||||
ChatCompletionToolMessageParam as SdkChatCompletionToolMessageParam,
|
||||
ChatCompletionAssistantMessageParam as SdkChatCompletionAssistantMessageParam,
|
||||
ChatCompletionContentPartText
|
||||
ChatCompletionAssistantMessageParam as SdkChatCompletionAssistantMessageParam
|
||||
} from 'openai/resources';
|
||||
import { ChatMessageTypeEnum } from './constants';
|
||||
import { WorkflowInteractiveResponseType } from '../workflow/template/system/interactive/type';
|
||||
@@ -48,6 +46,7 @@ export type ChatCompletionMessageParam = (
|
||||
| CustomChatCompletionToolMessageParam
|
||||
| CustomChatCompletionAssistantMessageParam
|
||||
) & {
|
||||
reasoning_text?: string;
|
||||
dataId?: string;
|
||||
hideInUI?: boolean;
|
||||
};
|
||||
@@ -71,7 +70,8 @@ export type ChatCompletionMessageFunctionCall =
|
||||
};
|
||||
|
||||
// Stream response
|
||||
export type StreamChatType = Stream<ChatCompletionChunk>;
|
||||
export type StreamChatType = Stream<openai.Chat.Completions.ChatCompletionChunk>;
|
||||
export type UnStreamChatType = openai.Chat.Completions.ChatCompletion;
|
||||
|
||||
export default openai;
|
||||
export * from 'openai';
|
||||
|
||||
20
packages/global/core/app/type.d.ts
vendored
20
packages/global/core/app/type.d.ts
vendored
@@ -74,13 +74,17 @@ export type AppDetailType = AppSchema & {
|
||||
export type AppSimpleEditFormType = {
|
||||
// templateId: string;
|
||||
aiSettings: {
|
||||
model: string;
|
||||
systemPrompt?: string | undefined;
|
||||
temperature?: number;
|
||||
maxToken?: number;
|
||||
isResponseAnswerText: boolean;
|
||||
[NodeInputKeyEnum.aiModel]: string;
|
||||
[NodeInputKeyEnum.aiSystemPrompt]?: string | undefined;
|
||||
[NodeInputKeyEnum.aiChatTemperature]?: number;
|
||||
[NodeInputKeyEnum.aiChatMaxToken]?: number;
|
||||
[NodeInputKeyEnum.aiChatIsResponseText]: boolean;
|
||||
maxHistories: number;
|
||||
[NodeInputKeyEnum.aiChatReasoning]?: boolean;
|
||||
[NodeInputKeyEnum.aiChatReasoning]?: boolean; // Is open reasoning mode
|
||||
[NodeInputKeyEnum.aiChatTopP]?: number;
|
||||
[NodeInputKeyEnum.aiChatStopSign]?: string;
|
||||
[NodeInputKeyEnum.aiChatResponseFormat]?: string;
|
||||
[NodeInputKeyEnum.aiChatJsonSchema]?: string;
|
||||
};
|
||||
dataset: {
|
||||
datasets: SelectedDatasetType;
|
||||
@@ -119,6 +123,10 @@ export type SettingAIDataType = {
|
||||
maxHistories?: number;
|
||||
[NodeInputKeyEnum.aiChatVision]?: boolean; // Is open vision mode
|
||||
[NodeInputKeyEnum.aiChatReasoning]?: boolean; // Is open reasoning mode
|
||||
[NodeInputKeyEnum.aiChatTopP]?: number;
|
||||
[NodeInputKeyEnum.aiChatStopSign]?: string;
|
||||
[NodeInputKeyEnum.aiChatResponseFormat]?: string;
|
||||
[NodeInputKeyEnum.aiChatJsonSchema]?: string;
|
||||
};
|
||||
|
||||
// variable
|
||||
|
||||
@@ -7,6 +7,8 @@ import { StoreNodeItemType } from '../workflow/type/node';
|
||||
import { DatasetSearchModeEnum } from '../dataset/constants';
|
||||
import { WorkflowTemplateBasicType } from '../workflow/type';
|
||||
import { AppTypeEnum } from './constants';
|
||||
import { AppErrEnum } from '../../common/error/code/app';
|
||||
import { PluginErrEnum } from '../../common/error/code/plugin';
|
||||
|
||||
export const getDefaultAppForm = (): AppSimpleEditFormType => {
|
||||
return {
|
||||
@@ -117,7 +119,8 @@ export const appWorkflow2Form = ({
|
||||
version: node.version,
|
||||
inputs: node.inputs,
|
||||
outputs: node.outputs,
|
||||
templateType: FlowNodeTemplateTypeEnum.other
|
||||
templateType: FlowNodeTemplateTypeEnum.other,
|
||||
pluginData: node.pluginData
|
||||
});
|
||||
} else if (node.flowNodeType === FlowNodeTypeEnum.systemConfig) {
|
||||
defaultAppForm.chatConfig = getAppChatConfig({
|
||||
@@ -147,3 +150,18 @@ export const getAppType = (config?: WorkflowTemplateBasicType | AppSimpleEditFor
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
export const checkAppUnExistError = (error?: string) => {
|
||||
const unExistError: Array<string> = [
|
||||
AppErrEnum.unAuthApp,
|
||||
AppErrEnum.unExist,
|
||||
PluginErrEnum.unAuth,
|
||||
PluginErrEnum.unExist
|
||||
];
|
||||
|
||||
if (!!error && unExistError.includes(error)) {
|
||||
return error;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,7 +46,16 @@ export const chats2GPTMessages = ({
|
||||
|
||||
messages.forEach((item) => {
|
||||
const dataId = reserveId ? item.dataId : undefined;
|
||||
if (item.obj === ChatRoleEnum.Human) {
|
||||
if (item.obj === ChatRoleEnum.System) {
|
||||
const content = item.value?.[0]?.text?.content;
|
||||
if (content) {
|
||||
results.push({
|
||||
dataId,
|
||||
role: ChatCompletionRequestMessageRoleEnum.System,
|
||||
content
|
||||
});
|
||||
}
|
||||
} else if (item.obj === ChatRoleEnum.Human) {
|
||||
const value = item.value
|
||||
.map((item) => {
|
||||
if (item.type === ChatItemValueTypeEnum.text) {
|
||||
@@ -80,15 +89,6 @@ export const chats2GPTMessages = ({
|
||||
role: ChatCompletionRequestMessageRoleEnum.User,
|
||||
content: simpleUserContentPart(value)
|
||||
});
|
||||
} else if (item.obj === ChatRoleEnum.System) {
|
||||
const content = item.value?.[0]?.text?.content;
|
||||
if (content) {
|
||||
results.push({
|
||||
dataId,
|
||||
role: ChatCompletionRequestMessageRoleEnum.System,
|
||||
content
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const aiResults: ChatCompletionMessageParam[] = [];
|
||||
|
||||
@@ -349,7 +349,7 @@ export const chatValue2RuntimePrompt = (value: ChatItemValueItemType[]): Runtime
|
||||
};
|
||||
value.forEach((item) => {
|
||||
if (item.type === 'file' && item.file) {
|
||||
prompt.files?.push(item.file);
|
||||
prompt.files.push(item.file);
|
||||
} else if (item.text) {
|
||||
prompt.text += item.text.content;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,10 @@ export enum WorkflowIOValueTypeEnum {
|
||||
dynamic = 'dynamic',
|
||||
|
||||
// plugin special type
|
||||
selectApp = 'selectApp',
|
||||
selectDataset = 'selectDataset'
|
||||
selectDataset = 'selectDataset',
|
||||
|
||||
// abandon
|
||||
selectApp = 'selectApp'
|
||||
}
|
||||
|
||||
export const toolValueTypeList = [
|
||||
@@ -142,6 +144,10 @@ export enum NodeInputKeyEnum {
|
||||
aiChatVision = 'aiChatVision',
|
||||
stringQuoteText = 'stringQuoteText',
|
||||
aiChatReasoning = 'aiChatReasoning',
|
||||
aiChatTopP = 'aiChatTopP',
|
||||
aiChatStopSign = 'aiChatStopSign',
|
||||
aiChatResponseFormat = 'aiChatResponseFormat',
|
||||
aiChatJsonSchema = 'aiChatJsonSchema',
|
||||
|
||||
// dataset
|
||||
datasetSelectList = 'datasets',
|
||||
@@ -154,6 +160,10 @@ export enum NodeInputKeyEnum {
|
||||
datasetSearchExtensionBg = 'datasetSearchExtensionBg',
|
||||
collectionFilterMatch = 'collectionFilterMatch',
|
||||
authTmbId = 'authTmbId',
|
||||
datasetDeepSearch = 'datasetDeepSearch',
|
||||
datasetDeepSearchModel = 'datasetDeepSearchModel',
|
||||
datasetDeepSearchMaxTimes = 'datasetDeepSearchMaxTimes',
|
||||
datasetDeepSearchBg = 'datasetDeepSearchBg',
|
||||
|
||||
// concat dataset
|
||||
datasetQuoteList = 'system_datasetQuoteList',
|
||||
|
||||
@@ -140,7 +140,14 @@ export enum FlowNodeTypeEnum {
|
||||
}
|
||||
|
||||
// node IO value type
|
||||
export const FlowValueTypeMap = {
|
||||
export const FlowValueTypeMap: Record<
|
||||
WorkflowIOValueTypeEnum,
|
||||
{
|
||||
label: string;
|
||||
value: WorkflowIOValueTypeEnum;
|
||||
abandon?: boolean;
|
||||
}
|
||||
> = {
|
||||
[WorkflowIOValueTypeEnum.string]: {
|
||||
label: 'String',
|
||||
value: WorkflowIOValueTypeEnum.string
|
||||
@@ -189,10 +196,6 @@ export const FlowValueTypeMap = {
|
||||
label: i18nT('common:core.workflow.Dataset quote'),
|
||||
value: WorkflowIOValueTypeEnum.datasetQuote
|
||||
},
|
||||
[WorkflowIOValueTypeEnum.selectApp]: {
|
||||
label: i18nT('common:plugin.App'),
|
||||
value: WorkflowIOValueTypeEnum.selectApp
|
||||
},
|
||||
[WorkflowIOValueTypeEnum.selectDataset]: {
|
||||
label: i18nT('common:core.chat.Select dataset'),
|
||||
value: WorkflowIOValueTypeEnum.selectDataset
|
||||
@@ -200,6 +203,11 @@ export const FlowValueTypeMap = {
|
||||
[WorkflowIOValueTypeEnum.dynamic]: {
|
||||
label: i18nT('common:core.workflow.dynamic_input'),
|
||||
value: WorkflowIOValueTypeEnum.dynamic
|
||||
},
|
||||
[WorkflowIOValueTypeEnum.selectApp]: {
|
||||
label: 'selectApp',
|
||||
value: WorkflowIOValueTypeEnum.selectApp,
|
||||
abandon: true
|
||||
}
|
||||
};
|
||||
|
||||
@@ -219,3 +227,6 @@ export const datasetQuoteValueDesc = `{
|
||||
q: string;
|
||||
a: string
|
||||
}[]`;
|
||||
export const datasetSelectValueDesc = `{
|
||||
datasetId: string;
|
||||
}[]`;
|
||||
|
||||
24
packages/global/core/workflow/runtime/type.d.ts
vendored
24
packages/global/core/workflow/runtime/type.d.ts
vendored
@@ -123,6 +123,7 @@ export type DispatchNodeResponseType = {
|
||||
temperature?: number;
|
||||
maxToken?: number;
|
||||
quoteList?: SearchDataResponseItemType[];
|
||||
reasoningText?: string;
|
||||
historyPreview?: {
|
||||
obj: `${ChatRoleEnum}`;
|
||||
value: string;
|
||||
@@ -133,9 +134,17 @@ export type DispatchNodeResponseType = {
|
||||
limit?: number;
|
||||
searchMode?: `${DatasetSearchModeEnum}`;
|
||||
searchUsingReRank?: boolean;
|
||||
extensionModel?: string;
|
||||
extensionResult?: string;
|
||||
extensionTokens?: number;
|
||||
queryExtensionResult?: {
|
||||
model: string;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
query: string;
|
||||
};
|
||||
deepSearchResult?: {
|
||||
model: string;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
};
|
||||
|
||||
// dataset concat
|
||||
concatLength?: number;
|
||||
@@ -198,6 +207,11 @@ export type DispatchNodeResponseType = {
|
||||
|
||||
// tool params
|
||||
toolParamsResult?: Record<string, any>;
|
||||
|
||||
// abandon
|
||||
extensionModel?: string;
|
||||
extensionResult?: string;
|
||||
extensionTokens?: number;
|
||||
};
|
||||
|
||||
export type DispatchNodeResultType<T = {}> = {
|
||||
@@ -221,6 +235,10 @@ export type AIChatNodeProps = {
|
||||
[NodeInputKeyEnum.aiChatIsResponseText]: boolean;
|
||||
[NodeInputKeyEnum.aiChatVision]?: boolean;
|
||||
[NodeInputKeyEnum.aiChatReasoning]?: boolean;
|
||||
[NodeInputKeyEnum.aiChatTopP]?: number;
|
||||
[NodeInputKeyEnum.aiChatStopSign]?: string;
|
||||
[NodeInputKeyEnum.aiChatResponseFormat]?: string;
|
||||
[NodeInputKeyEnum.aiChatJsonSchema]?: string;
|
||||
|
||||
[NodeInputKeyEnum.aiChatQuoteRole]?: AiChatQuoteRoleType;
|
||||
[NodeInputKeyEnum.aiChatQuoteTemplate]?: string;
|
||||
|
||||
@@ -10,6 +10,7 @@ import { FlowNodeOutputItemType, ReferenceValueType } from '../type/io';
|
||||
import { ChatItemType, NodeOutputItemType } from '../../../core/chat/type';
|
||||
import { ChatItemValueTypeEnum, ChatRoleEnum } from '../../../core/chat/constants';
|
||||
import { replaceVariable, valToStr } from '../../../common/string/tools';
|
||||
import { ChatCompletionChunk } from 'openai/resources';
|
||||
|
||||
export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number => {
|
||||
let limit = 10;
|
||||
@@ -292,13 +293,12 @@ export const getReferenceVariableValue = ({
|
||||
|
||||
export const formatVariableValByType = (val: any, valueType?: WorkflowIOValueTypeEnum) => {
|
||||
if (!valueType) return val;
|
||||
if (val === undefined || val === null) return;
|
||||
// Value type check, If valueType invalid, return undefined
|
||||
if (valueType.startsWith('array') && !Array.isArray(val)) return undefined;
|
||||
if (valueType === WorkflowIOValueTypeEnum.boolean) return Boolean(val);
|
||||
if (valueType === WorkflowIOValueTypeEnum.number) return Number(val);
|
||||
if (valueType === WorkflowIOValueTypeEnum.string) {
|
||||
if (val === undefined) return 'undefined';
|
||||
if (val === null) return 'null';
|
||||
return typeof val === 'object' ? JSON.stringify(val) : String(val);
|
||||
}
|
||||
if (
|
||||
@@ -420,3 +420,137 @@ export function rewriteNodeOutputByHistories(
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// Parse <think></think> tags to think and answer - unstream response
|
||||
export const parseReasoningContent = (text: string): [string, string] => {
|
||||
const regex = /<think>([\s\S]*?)<\/think>/;
|
||||
const match = text.match(regex);
|
||||
|
||||
if (!match) {
|
||||
return ['', text];
|
||||
}
|
||||
|
||||
const thinkContent = match[1].trim();
|
||||
|
||||
// Add answer (remaining text after think tag)
|
||||
const answerContent = text.slice(match.index! + match[0].length);
|
||||
|
||||
return [thinkContent, answerContent];
|
||||
};
|
||||
|
||||
// Parse <think></think> tags to think and answer - stream response
|
||||
export const parseReasoningStreamContent = () => {
|
||||
let isInThinkTag: boolean | undefined;
|
||||
|
||||
const startTag = '<think>';
|
||||
let startTagBuffer = '';
|
||||
|
||||
const endTag = '</think>';
|
||||
let endTagBuffer = '';
|
||||
|
||||
/*
|
||||
parseReasoning - 只控制是否主动解析 <think></think>,如果接口已经解析了,仍然会返回 think 内容。
|
||||
*/
|
||||
const parsePart = (
|
||||
part: {
|
||||
choices: {
|
||||
delta: {
|
||||
content?: string;
|
||||
reasoning_content?: string;
|
||||
};
|
||||
}[];
|
||||
},
|
||||
parseReasoning = false
|
||||
): [string, string] => {
|
||||
const content = part.choices?.[0]?.delta?.content || '';
|
||||
|
||||
// @ts-ignore
|
||||
const reasoningContent = part.choices?.[0]?.delta?.reasoning_content || '';
|
||||
if (reasoningContent || !parseReasoning) {
|
||||
isInThinkTag = false;
|
||||
return [reasoningContent, content];
|
||||
}
|
||||
|
||||
if (!content) {
|
||||
return ['', ''];
|
||||
}
|
||||
|
||||
// 如果不在 think 标签中,或者有 reasoningContent(接口已解析),则返回 reasoningContent 和 content
|
||||
if (isInThinkTag === false) {
|
||||
return ['', content];
|
||||
}
|
||||
|
||||
// 检测是否为 think 标签开头的数据
|
||||
if (isInThinkTag === undefined) {
|
||||
// Parse content think and answer
|
||||
startTagBuffer += content;
|
||||
// 太少内容时候,暂时不解析
|
||||
if (startTagBuffer.length < startTag.length) {
|
||||
return ['', ''];
|
||||
}
|
||||
|
||||
if (startTagBuffer.startsWith(startTag)) {
|
||||
isInThinkTag = true;
|
||||
return [startTagBuffer.slice(startTag.length), ''];
|
||||
}
|
||||
|
||||
// 如果未命中 think 标签,则认为不在 think 标签中,返回 buffer 内容作为 content
|
||||
isInThinkTag = false;
|
||||
return ['', startTagBuffer];
|
||||
}
|
||||
|
||||
// 确认是 think 标签内容,开始返回 think 内容,并实时检测 </think>
|
||||
/*
|
||||
检测 </think> 方案。
|
||||
存储所有疑似 </think> 的内容,直到检测到完整的 </think> 标签或超出 </think> 长度。
|
||||
content 返回值包含以下几种情况:
|
||||
abc - 完全未命中尾标签
|
||||
abc<th - 命中一部分尾标签
|
||||
abc</think> - 完全命中尾标签
|
||||
abc</think>abc - 完全命中尾标签
|
||||
</think>abc - 完全命中尾标签
|
||||
k>abc - 命中一部分尾标签
|
||||
*/
|
||||
// endTagBuffer 专门用来记录疑似尾标签的内容
|
||||
if (endTagBuffer) {
|
||||
endTagBuffer += content;
|
||||
if (endTagBuffer.includes(endTag)) {
|
||||
isInThinkTag = false;
|
||||
const answer = endTagBuffer.slice(endTag.length);
|
||||
return ['', answer];
|
||||
} else if (endTagBuffer.length >= endTag.length) {
|
||||
// 缓存内容超出尾标签长度,且仍未命中 </think>,则认为本次猜测 </think> 失败,仍处于 think 阶段。
|
||||
const tmp = endTagBuffer;
|
||||
endTagBuffer = '';
|
||||
return [tmp, ''];
|
||||
}
|
||||
return ['', ''];
|
||||
} else if (content.includes(endTag)) {
|
||||
// 返回内容,完整命中</think>,直接结束
|
||||
isInThinkTag = false;
|
||||
const [think, answer] = content.split(endTag);
|
||||
return [think, answer];
|
||||
} else {
|
||||
// 无 buffer,且未命中 </think>,开始疑似 </think> 检测。
|
||||
for (let i = 1; i < endTag.length; i++) {
|
||||
const partialEndTag = endTag.slice(0, i);
|
||||
// 命中一部分尾标签
|
||||
if (content.endsWith(partialEndTag)) {
|
||||
const think = content.slice(0, -partialEndTag.length);
|
||||
endTagBuffer += partialEndTag;
|
||||
return [think, ''];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 完全未命中尾标签,还是 think 阶段。
|
||||
return [content, ''];
|
||||
};
|
||||
|
||||
const getStartTagBuffer = () => startTagBuffer;
|
||||
|
||||
return {
|
||||
parsePart,
|
||||
getStartTagBuffer
|
||||
};
|
||||
};
|
||||
|
||||
@@ -63,14 +63,12 @@ export const AiChatModule: FlowNodeTemplateType = {
|
||||
key: NodeInputKeyEnum.aiChatTemperature,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden], // Set in the pop-up window
|
||||
label: '',
|
||||
value: undefined,
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatMaxToken,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden], // Set in the pop-up window
|
||||
label: '',
|
||||
value: undefined,
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
|
||||
@@ -98,6 +96,30 @@ export const AiChatModule: FlowNodeTemplateType = {
|
||||
valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
value: true
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatTopP,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatStopSign,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatResponseFormat,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatJsonSchema,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
// settings modal ---
|
||||
{
|
||||
...Input_Template_System_Prompt,
|
||||
@@ -108,7 +130,6 @@ export const AiChatModule: FlowNodeTemplateType = {
|
||||
Input_Template_History,
|
||||
Input_Template_Dataset_Quote,
|
||||
Input_Template_File_Link_Prompt,
|
||||
|
||||
{ ...Input_Template_UserChatInput, toolDescription: i18nT('workflow:user_question') }
|
||||
],
|
||||
outputs: [
|
||||
@@ -130,6 +151,20 @@ export const AiChatModule: FlowNodeTemplateType = {
|
||||
description: i18nT('common:core.module.output.description.Ai response content'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.reasoningText,
|
||||
key: NodeOutputKeyEnum.reasoningText,
|
||||
required: false,
|
||||
label: i18nT('workflow:reasoning_text'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static,
|
||||
invalid: true,
|
||||
invalidCondition: ({ inputs, llmModelList }) => {
|
||||
const model = inputs.find((item) => item.key === NodeInputKeyEnum.aiModel)?.value;
|
||||
const modelItem = llmModelList.find((item) => item.model === model);
|
||||
return modelItem?.reasoning !== true;
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
datasetQuoteValueDesc,
|
||||
datasetSelectValueDesc,
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
@@ -38,7 +39,8 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
|
||||
label: i18nT('common:core.module.input.label.Select dataset'),
|
||||
value: [],
|
||||
valueType: WorkflowIOValueTypeEnum.selectDataset,
|
||||
required: true
|
||||
required: true,
|
||||
valueDesc: datasetSelectValueDesc
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSimilarity,
|
||||
|
||||
@@ -43,14 +43,12 @@ export const ToolModule: FlowNodeTemplateType = {
|
||||
key: NodeInputKeyEnum.aiChatTemperature,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden], // Set in the pop-up window
|
||||
label: '',
|
||||
value: undefined,
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatMaxToken,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden], // Set in the pop-up window
|
||||
label: '',
|
||||
value: undefined,
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
{
|
||||
@@ -60,6 +58,30 @@ export const ToolModule: FlowNodeTemplateType = {
|
||||
valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
value: true
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatTopP,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatStopSign,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatResponseFormat,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.aiChatJsonSchema,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
|
||||
{
|
||||
...Input_Template_System_Prompt,
|
||||
|
||||
7
packages/global/core/workflow/type/io.d.ts
vendored
7
packages/global/core/workflow/type/io.d.ts
vendored
@@ -1,3 +1,4 @@
|
||||
import { LLMModelItemType } from '../../ai/model.d';
|
||||
import { LLMModelTypeEnum } from '../../ai/constants';
|
||||
import { WorkflowIOValueTypeEnum, NodeInputKeyEnum, NodeOutputKeyEnum } from '../constants';
|
||||
import { FlowNodeInputTypeEnum, FlowNodeOutputTypeEnum } from '../node/constant';
|
||||
@@ -77,6 +78,12 @@ export type FlowNodeOutputItemType = {
|
||||
defaultValue?: any;
|
||||
required?: boolean;
|
||||
|
||||
invalid?: boolean;
|
||||
invalidCondition?: (e: {
|
||||
inputs: FlowNodeInputItemType[];
|
||||
llmModelList: LLMModelItemType[];
|
||||
}) => boolean;
|
||||
|
||||
// component params
|
||||
customFieldConfig?: CustomFieldConfigType;
|
||||
};
|
||||
|
||||
11
packages/global/core/workflow/type/node.d.ts
vendored
11
packages/global/core/workflow/type/node.d.ts
vendored
@@ -43,6 +43,17 @@ export type FlowNodeCommonType = {
|
||||
pluginId?: string;
|
||||
isFolder?: boolean;
|
||||
// pluginType?: AppTypeEnum;
|
||||
pluginData?: PluginDataType;
|
||||
};
|
||||
|
||||
export type PluginDataType = {
|
||||
version: string;
|
||||
diagram?: string;
|
||||
userGuide?: string;
|
||||
courseUrl?: string;
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
type HandleType = {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ClientSession, Types } from '../../../common/mongo';
|
||||
import { guessBase64ImageType } from '../utils';
|
||||
import { readFromSecondary } from '../../mongo/utils';
|
||||
import { addHours } from 'date-fns';
|
||||
import { imageFileType } from '@fastgpt/global/common/file/constants';
|
||||
|
||||
export const maxImgSize = 1024 * 1024 * 12;
|
||||
const base64MimeRegex = /data:image\/([^\)]+);base64/;
|
||||
@@ -25,12 +26,19 @@ export async function uploadMongoImg({
|
||||
const [base64Mime, base64Data] = base64Img.split(',');
|
||||
// Check if mime type is valid
|
||||
if (!base64MimeRegex.test(base64Mime)) {
|
||||
return Promise.reject('Invalid image mime type');
|
||||
return Promise.reject('Invalid image base64');
|
||||
}
|
||||
|
||||
const mime = `image/${base64Mime.match(base64MimeRegex)?.[1] ?? 'image/jpeg'}`;
|
||||
const binary = Buffer.from(base64Data, 'base64');
|
||||
const extension = mime.split('/')[1];
|
||||
let extension = mime.split('/')[1];
|
||||
if (extension.startsWith('x-')) {
|
||||
extension = extension.substring(2); // Remove 'x-' prefix
|
||||
}
|
||||
|
||||
if (!extension || !imageFileType.includes(`.${extension}`)) {
|
||||
return Promise.reject(`Invalid image file type: ${mime}`);
|
||||
}
|
||||
|
||||
const { _id } = await MongoImage.create({
|
||||
teamId,
|
||||
|
||||
@@ -25,7 +25,7 @@ export const countGptMessagesTokens = async (
|
||||
number
|
||||
>({
|
||||
name: WorkerNameEnum.countGptMessagesTokens,
|
||||
maxReservedThreads: global.systemEnv?.tokenWorkers || 50
|
||||
maxReservedThreads: global.systemEnv?.tokenWorkers || 30
|
||||
});
|
||||
|
||||
const total = await workerController.run({ messages, tools, functionCall });
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import OpenAI from '@fastgpt/global/core/ai';
|
||||
import {
|
||||
ChatCompletionCreateParamsNonStreaming,
|
||||
ChatCompletionCreateParamsStreaming
|
||||
ChatCompletionCreateParamsStreaming,
|
||||
StreamChatType,
|
||||
UnStreamChatType
|
||||
} from '@fastgpt/global/core/ai/type';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { addLog } from '../../common/system/log';
|
||||
@@ -38,29 +40,30 @@ export const getAxiosConfig = (props?: { userKey?: OpenaiAccountType }) => {
|
||||
};
|
||||
};
|
||||
|
||||
type CompletionsBodyType =
|
||||
| ChatCompletionCreateParamsNonStreaming
|
||||
| ChatCompletionCreateParamsStreaming;
|
||||
type InferResponseType<T extends CompletionsBodyType> =
|
||||
T extends ChatCompletionCreateParamsStreaming
|
||||
? OpenAI.Chat.Completions.ChatCompletionChunk
|
||||
: OpenAI.Chat.Completions.ChatCompletion;
|
||||
|
||||
export const createChatCompletion = async <T extends CompletionsBodyType>({
|
||||
export const createChatCompletion = async ({
|
||||
body,
|
||||
userKey,
|
||||
timeout,
|
||||
options
|
||||
}: {
|
||||
body: T;
|
||||
body: ChatCompletionCreateParamsNonStreaming | ChatCompletionCreateParamsStreaming;
|
||||
userKey?: OpenaiAccountType;
|
||||
timeout?: number;
|
||||
options?: OpenAI.RequestOptions;
|
||||
}): Promise<{
|
||||
response: InferResponseType<T>;
|
||||
isStreamResponse: boolean;
|
||||
getEmptyResponseTip: () => string;
|
||||
}> => {
|
||||
}): Promise<
|
||||
{
|
||||
getEmptyResponseTip: () => string;
|
||||
} & (
|
||||
| {
|
||||
response: StreamChatType;
|
||||
isStreamResponse: true;
|
||||
}
|
||||
| {
|
||||
response: UnStreamChatType;
|
||||
isStreamResponse: false;
|
||||
}
|
||||
)
|
||||
> => {
|
||||
try {
|
||||
const modelConstantsData = getLLMModel(body.model);
|
||||
|
||||
@@ -96,9 +99,17 @@ export const createChatCompletion = async <T extends CompletionsBodyType>({
|
||||
return i18nT('chat:LLM_model_response_empty');
|
||||
};
|
||||
|
||||
if (isStreamResponse) {
|
||||
return {
|
||||
response,
|
||||
isStreamResponse: true,
|
||||
getEmptyResponseTip
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
response: response as InferResponseType<T>,
|
||||
isStreamResponse,
|
||||
response,
|
||||
isStreamResponse: false,
|
||||
getEmptyResponseTip
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 120000,
|
||||
"maxTemperature": 0.99,
|
||||
"showTopP": true,
|
||||
"responseFormatList": [
|
||||
"text",
|
||||
"json_object"
|
||||
],
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -30,6 +36,12 @@
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 120000,
|
||||
"maxTemperature": 0.99,
|
||||
"showTopP": true,
|
||||
"responseFormatList": [
|
||||
"text",
|
||||
"json_object"
|
||||
],
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -52,6 +64,12 @@
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 900000,
|
||||
"maxTemperature": 0.99,
|
||||
"showTopP": true,
|
||||
"responseFormatList": [
|
||||
"text",
|
||||
"json_object"
|
||||
],
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": false,
|
||||
"functionCall": false,
|
||||
@@ -74,6 +92,12 @@
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 120000,
|
||||
"maxTemperature": 0.99,
|
||||
"showTopP": true,
|
||||
"responseFormatList": [
|
||||
"text",
|
||||
"json_object"
|
||||
],
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -96,6 +120,8 @@
|
||||
"maxResponse": 1000,
|
||||
"quoteMaxToken": 6000,
|
||||
"maxTemperature": 0.99,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": true,
|
||||
"toolChoice": false,
|
||||
"functionCall": false,
|
||||
@@ -118,6 +144,8 @@
|
||||
"maxResponse": 1000,
|
||||
"quoteMaxToken": 6000,
|
||||
"maxTemperature": 0.99,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": true,
|
||||
"toolChoice": false,
|
||||
"functionCall": false,
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"maxResponse": 8000,
|
||||
"quoteMaxToken": 100000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -30,6 +32,8 @@
|
||||
"maxResponse": 8000,
|
||||
"quoteMaxToken": 100000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": true,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -52,6 +56,8 @@
|
||||
"maxResponse": 8000,
|
||||
"quoteMaxToken": 100000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": true,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -74,6 +80,8 @@
|
||||
"maxResponse": 4096,
|
||||
"quoteMaxToken": 100000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": true,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
"model": "deepseek-chat",
|
||||
"name": "Deepseek-chat",
|
||||
"maxContext": 64000,
|
||||
"maxResponse": 4096,
|
||||
"maxResponse": 8000,
|
||||
"quoteMaxToken": 60000,
|
||||
"maxTemperature": 1.5,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"responseFormatList": ["text", "json_object"],
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -25,7 +28,7 @@
|
||||
"model": "deepseek-reasoner",
|
||||
"name": "Deepseek-reasoner",
|
||||
"maxContext": 64000,
|
||||
"maxResponse": 4096,
|
||||
"maxResponse": 8000,
|
||||
"quoteMaxToken": 60000,
|
||||
"maxTemperature": null,
|
||||
"vision": false,
|
||||
@@ -42,7 +45,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,102 @@
|
||||
{
|
||||
"provider": "Doubao",
|
||||
"list": [
|
||||
{
|
||||
"model": "Doubao-1.5-lite-32k",
|
||||
"name": "Doubao-1.5-lite-32k",
|
||||
"maxContext": 32000,
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 32000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
"defaultSystemChatPrompt": "",
|
||||
"datasetProcess": true,
|
||||
"usedInClassify": true,
|
||||
"customCQPrompt": "",
|
||||
"usedInExtractFields": true,
|
||||
"usedInQueryExtension": true,
|
||||
"customExtractPrompt": "",
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
},
|
||||
{
|
||||
"model": "Doubao-1.5-pro-32k",
|
||||
"name": "Doubao-1.5-pro-32k",
|
||||
"maxContext": 32000,
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 32000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
"defaultSystemChatPrompt": "",
|
||||
"datasetProcess": true,
|
||||
"usedInClassify": true,
|
||||
"customCQPrompt": "",
|
||||
"usedInExtractFields": true,
|
||||
"usedInQueryExtension": true,
|
||||
"customExtractPrompt": "",
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
},
|
||||
{
|
||||
"model": "Doubao-1.5-pro-256k",
|
||||
"name": "Doubao-1.5-pro-256k",
|
||||
"maxContext": 256000,
|
||||
"maxResponse": 12000,
|
||||
"quoteMaxToken": 256000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
"defaultSystemChatPrompt": "",
|
||||
"datasetProcess": true,
|
||||
"usedInClassify": true,
|
||||
"customCQPrompt": "",
|
||||
"usedInExtractFields": true,
|
||||
"usedInQueryExtension": true,
|
||||
"customExtractPrompt": "",
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
},
|
||||
{
|
||||
"model": "Doubao-1.5-vision-pro-32k",
|
||||
"name": "Doubao-1.5-vision-pro-32k",
|
||||
"maxContext": 32000,
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 32000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": true,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
"defaultSystemChatPrompt": "",
|
||||
"datasetProcess": true,
|
||||
"usedInClassify": true,
|
||||
"customCQPrompt": "",
|
||||
"usedInExtractFields": true,
|
||||
"usedInQueryExtension": true,
|
||||
"customExtractPrompt": "",
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
},
|
||||
{
|
||||
"model": "Doubao-lite-4k",
|
||||
"name": "Doubao-lite-4k",
|
||||
@@ -8,6 +104,8 @@
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 4000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -30,6 +128,8 @@
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 32000,
|
||||
"maxTemperature": 1,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -65,7 +165,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "Doubao-vision-lite-32k",
|
||||
@@ -87,7 +189,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "Doubao-pro-4k",
|
||||
@@ -109,7 +213,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "Doubao-pro-32k",
|
||||
@@ -131,7 +237,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "Doubao-pro-128k",
|
||||
@@ -153,7 +261,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "Doubao-vision-pro-32k",
|
||||
@@ -175,21 +285,25 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "Doubao-embedding-large",
|
||||
"name": "Doubao-embedding-large",
|
||||
"defaultToken": 512,
|
||||
"maxToken": 4096,
|
||||
"type": "embedding"
|
||||
"type": "embedding",
|
||||
"normalization": true
|
||||
},
|
||||
{
|
||||
"model": "Doubao-embedding",
|
||||
"name": "Doubao-embedding",
|
||||
"defaultToken": 512,
|
||||
"maxToken": 4096,
|
||||
"type": "embedding"
|
||||
"type": "embedding",
|
||||
"normalization": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "ERNIE-4.0-Turbo-8K",
|
||||
@@ -43,7 +45,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "ERNIE-Lite-8K",
|
||||
@@ -65,7 +69,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "ERNIE-Speed-128K",
|
||||
@@ -87,7 +93,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "Embedding-V1",
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "gemini-1.5-pro",
|
||||
@@ -43,7 +45,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "gemini-2.0-flash-exp",
|
||||
@@ -65,7 +69,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "gemini-2.0-flash-thinking-exp-1219",
|
||||
@@ -87,7 +93,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "gemini-2.0-flash-thinking-exp-01-21",
|
||||
@@ -109,7 +117,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "gemini-exp-1206",
|
||||
@@ -131,7 +141,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "text-embedding-004",
|
||||
@@ -141,4 +153,4 @@
|
||||
"type": "embedding"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,9 @@
|
||||
"customExtractPrompt": "",
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "llama-3.3-70b-versatile",
|
||||
@@ -41,7 +43,9 @@
|
||||
"customExtractPrompt": "",
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,7 +21,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "hunyuan-lite",
|
||||
@@ -43,7 +45,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "hunyuan-pro",
|
||||
@@ -65,7 +69,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "hunyuan-standard",
|
||||
@@ -87,7 +93,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "hunyuan-turbo-vision",
|
||||
@@ -109,7 +117,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "hunyuan-turbo",
|
||||
@@ -131,7 +141,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "hunyuan-vision",
|
||||
@@ -153,7 +165,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "hunyuan-embedding",
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "internlm3-8b-instruct",
|
||||
@@ -43,7 +45,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,7 +21,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "abab6.5s-chat",
|
||||
@@ -43,7 +45,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "speech-01-turbo",
|
||||
@@ -237,4 +241,4 @@
|
||||
"type": "tts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "ministral-8b-latest",
|
||||
@@ -43,7 +45,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "mistral-large-latest",
|
||||
@@ -65,7 +69,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "mistral-small-latest",
|
||||
@@ -87,7 +93,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,7 +21,10 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
},
|
||||
{
|
||||
"model": "moonshot-v1-32k",
|
||||
@@ -43,7 +46,10 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
},
|
||||
{
|
||||
"model": "moonshot-v1-128k",
|
||||
@@ -65,7 +71,10 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
"maxResponse": 16000,
|
||||
"quoteMaxToken": 60000,
|
||||
"maxTemperature": 1.2,
|
||||
"showTopP": true,
|
||||
"responseFormatList": [
|
||||
"text",
|
||||
"json_object",
|
||||
"json_schema"
|
||||
],
|
||||
"showStopSign": true,
|
||||
"vision": true,
|
||||
"toolChoice": true,
|
||||
"functionCall": true,
|
||||
@@ -29,6 +36,13 @@
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 60000,
|
||||
"maxTemperature": 1.2,
|
||||
"showTopP": true,
|
||||
"responseFormatList": [
|
||||
"text",
|
||||
"json_object",
|
||||
"json_schema"
|
||||
],
|
||||
"showStopSign": true,
|
||||
"vision": true,
|
||||
"toolChoice": true,
|
||||
"functionCall": true,
|
||||
@@ -68,7 +82,9 @@
|
||||
"fieldMap": {
|
||||
"max_tokens": "max_completion_tokens"
|
||||
},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "o1-mini",
|
||||
@@ -94,7 +110,9 @@
|
||||
"fieldMap": {
|
||||
"max_tokens": "max_completion_tokens"
|
||||
},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "o1",
|
||||
@@ -120,7 +138,9 @@
|
||||
"fieldMap": {
|
||||
"max_tokens": "max_completion_tokens"
|
||||
},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "o1-preview",
|
||||
@@ -146,7 +166,9 @@
|
||||
"fieldMap": {
|
||||
"max_tokens": "max_completion_tokens"
|
||||
},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "gpt-3.5-turbo",
|
||||
@@ -155,6 +177,8 @@
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 13000,
|
||||
"maxTemperature": 1.2,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": true,
|
||||
@@ -175,6 +199,8 @@
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 60000,
|
||||
"maxTemperature": 1.2,
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"vision": true,
|
||||
"toolChoice": true,
|
||||
"functionCall": true,
|
||||
@@ -249,4 +275,4 @@
|
||||
"type": "stt"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
4
packages/service/core/ai/config/provider/PPIO.json
Normal file
4
packages/service/core/ai/config/provider/PPIO.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"provider": "PPIO",
|
||||
"list": []
|
||||
}
|
||||
@@ -21,7 +21,10 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
},
|
||||
{
|
||||
"model": "qwen-plus",
|
||||
@@ -43,7 +46,10 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
},
|
||||
{
|
||||
"model": "qwen-vl-plus",
|
||||
@@ -63,7 +69,9 @@
|
||||
"usedInQueryExtension": true,
|
||||
"customExtractPrompt": "",
|
||||
"usedInToolCall": true,
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "qwen-max",
|
||||
@@ -85,7 +93,10 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
},
|
||||
{
|
||||
"model": "qwen-vl-max",
|
||||
@@ -107,7 +118,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "qwen-coder-turbo",
|
||||
@@ -129,7 +142,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "qwen2.5-7b-instruct",
|
||||
@@ -151,7 +166,10 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
},
|
||||
{
|
||||
"model": "qwen2.5-14b-instruct",
|
||||
@@ -173,7 +191,10 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
},
|
||||
{
|
||||
"model": "qwen2.5-32b-instruct",
|
||||
@@ -195,7 +216,10 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
},
|
||||
{
|
||||
"model": "qwen2.5-72b-instruct",
|
||||
@@ -217,7 +241,17 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true,
|
||||
"responseFormatList": ["text", "json_object"]
|
||||
},
|
||||
{
|
||||
"model": "text-embedding-v3",
|
||||
"name": "text-embedding-v3",
|
||||
"defaultToken": 512,
|
||||
"maxToken": 8000,
|
||||
"type": "embedding"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "Qwen/Qwen2-VL-72B-Instruct",
|
||||
@@ -42,7 +44,9 @@
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"defaultConfig": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "deepseek-ai/DeepSeek-V2.5",
|
||||
@@ -64,7 +68,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "BAAI/bge-m3",
|
||||
@@ -201,4 +207,4 @@
|
||||
"type": "rerank"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "generalv3",
|
||||
@@ -39,7 +41,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "pro-128k",
|
||||
@@ -59,7 +63,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "generalv3.5",
|
||||
@@ -79,7 +85,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "max-32k",
|
||||
@@ -101,7 +109,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "4.0Ultra",
|
||||
@@ -123,7 +133,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-1-8k",
|
||||
@@ -39,7 +41,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-1-32k",
|
||||
@@ -59,7 +63,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-1-128k",
|
||||
@@ -79,7 +85,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-1-256k",
|
||||
@@ -99,7 +107,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-1o-vision-32k",
|
||||
@@ -119,7 +129,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-1v-8k",
|
||||
@@ -139,7 +151,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-1v-32k",
|
||||
@@ -159,7 +173,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-2-mini",
|
||||
@@ -179,7 +195,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-2-16k",
|
||||
@@ -199,7 +217,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-2-16k-exp",
|
||||
@@ -219,7 +239,9 @@
|
||||
"customCQPrompt": "",
|
||||
"customExtractPrompt": "",
|
||||
"defaultSystemChatPrompt": "",
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "step-tts-mini",
|
||||
@@ -305,4 +327,4 @@
|
||||
"type": "tts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
},
|
||||
{
|
||||
"model": "yi-vision-v2",
|
||||
@@ -43,7 +45,9 @@
|
||||
"usedInToolCall": true,
|
||||
"defaultConfig": {},
|
||||
"fieldMap": {},
|
||||
"type": "llm"
|
||||
"type": "llm",
|
||||
"showTopP": true,
|
||||
"showStopSign": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -31,7 +31,12 @@ import { delay } from '@fastgpt/global/common/system/utils';
|
||||
export const loadSystemModels = async (init = false) => {
|
||||
const getProviderList = () => {
|
||||
const currentFileUrl = new URL(import.meta.url);
|
||||
const modelsPath = path.join(path.dirname(currentFileUrl.pathname), 'provider');
|
||||
const filePath = decodeURIComponent(
|
||||
process.platform === 'win32'
|
||||
? currentFileUrl.pathname.substring(1) // Remove leading slash on Windows
|
||||
: currentFileUrl.pathname
|
||||
);
|
||||
const modelsPath = path.join(path.dirname(filePath), 'provider');
|
||||
|
||||
return fs.readdirSync(modelsPath) as string[];
|
||||
};
|
||||
@@ -147,6 +152,7 @@ export const loadSystemModels = async (init = false) => {
|
||||
console.error('Load models error', error);
|
||||
// @ts-ignore
|
||||
global.systemModelList = undefined;
|
||||
return Promise.reject(error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -56,7 +56,14 @@ export async function getVectorsByText({ model, input, type }: GetVectorProps) {
|
||||
|
||||
const [tokens, vectors] = await Promise.all([
|
||||
countPromptTokens(input),
|
||||
Promise.all(res.data.map((item) => unityDimensional(item.embedding)))
|
||||
Promise.all(
|
||||
res.data
|
||||
.map((item) => unityDimensional(item.embedding))
|
||||
.map((item) => {
|
||||
if (model.normalization) return normalization(item);
|
||||
return item;
|
||||
})
|
||||
)
|
||||
]);
|
||||
|
||||
return {
|
||||
@@ -87,3 +94,15 @@ function unityDimensional(vector: number[]) {
|
||||
|
||||
return resultVector.concat(zeroVector);
|
||||
}
|
||||
// normalization processing
|
||||
function normalization(vector: number[]) {
|
||||
if (vector.some((item) => item > 1)) {
|
||||
// Calculate the Euclidean norm (L2 norm)
|
||||
const norm = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
|
||||
|
||||
// Normalize the vector by dividing each component by the norm
|
||||
return vector.map((val) => val / norm);
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ export function reRankRecall({
|
||||
if (!model) {
|
||||
return Promise.reject('no rerank model');
|
||||
}
|
||||
if (documents.length === 0) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
const { baseUrl, authorization } = getAxiosConfig();
|
||||
|
||||
|
||||
@@ -42,17 +42,27 @@ type CompletionsBodyType =
|
||||
| ChatCompletionCreateParamsStreaming;
|
||||
type InferCompletionsBody<T> = T extends { stream: true }
|
||||
? ChatCompletionCreateParamsStreaming
|
||||
: ChatCompletionCreateParamsNonStreaming;
|
||||
: T extends { stream: false }
|
||||
? ChatCompletionCreateParamsNonStreaming
|
||||
: ChatCompletionCreateParamsNonStreaming | ChatCompletionCreateParamsStreaming;
|
||||
|
||||
export const llmCompletionsBodyFormat = <T extends CompletionsBodyType>(
|
||||
body: T,
|
||||
body: T & {
|
||||
response_format?: any;
|
||||
json_schema?: string;
|
||||
stop?: string;
|
||||
},
|
||||
model: string | LLMModelItemType
|
||||
): InferCompletionsBody<T> => {
|
||||
const modelData = typeof model === 'string' ? getLLMModel(model) : model;
|
||||
if (!modelData) {
|
||||
return body as InferCompletionsBody<T>;
|
||||
return body as unknown as InferCompletionsBody<T>;
|
||||
}
|
||||
|
||||
const response_format = body.response_format;
|
||||
const json_schema = body.json_schema ?? undefined;
|
||||
const stop = body.stop ?? undefined;
|
||||
|
||||
const requestBody: T = {
|
||||
...body,
|
||||
temperature:
|
||||
@@ -62,7 +72,14 @@ export const llmCompletionsBodyFormat = <T extends CompletionsBodyType>(
|
||||
temperature: body.temperature
|
||||
})
|
||||
: undefined,
|
||||
...modelData?.defaultConfig
|
||||
...modelData?.defaultConfig,
|
||||
response_format: response_format
|
||||
? {
|
||||
type: response_format,
|
||||
json_schema
|
||||
}
|
||||
: undefined,
|
||||
stop: stop?.split('|')
|
||||
};
|
||||
|
||||
// field map
|
||||
@@ -75,9 +92,7 @@ export const llmCompletionsBodyFormat = <T extends CompletionsBodyType>(
|
||||
});
|
||||
}
|
||||
|
||||
// console.log(requestBody);
|
||||
|
||||
return requestBody as InferCompletionsBody<T>;
|
||||
return requestBody as unknown as InferCompletionsBody<T>;
|
||||
};
|
||||
|
||||
export const llmStreamResponseToText = async (response: StreamChatType) => {
|
||||
|
||||
@@ -88,7 +88,7 @@ try {
|
||||
ChatSchema.index({ appId: 1, chatId: 1 });
|
||||
|
||||
// get chat logs;
|
||||
ChatSchema.index({ teamId: 1, appId: 1, updateTime: -1 });
|
||||
ChatSchema.index({ teamId: 1, appId: 1, updateTime: -1, sources: 1 });
|
||||
// get share chat history
|
||||
ChatSchema.index({ shareId: 1, outLinkUid: 1, updateTime: -1 });
|
||||
|
||||
|
||||
@@ -197,7 +197,11 @@ export const loadRequestMessages = async ({
|
||||
addLog.info(`Filter invalid image: ${imgUrl}`);
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
if (error?.response?.status === 405) {
|
||||
return item;
|
||||
}
|
||||
addLog.warn(`Filter invalid image: ${imgUrl}`, { error });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
} from '@fastgpt/global/core/dataset/constants';
|
||||
import { recallFromVectorStore } from '../../../common/vectorStore/controller';
|
||||
import { getVectorsByText } from '../../ai/embedding';
|
||||
import { getEmbeddingModel, getDefaultRerankModel } from '../../ai/model';
|
||||
import { getEmbeddingModel, getDefaultRerankModel, getLLMModel } from '../../ai/model';
|
||||
import { MongoDatasetData } from '../data/schema';
|
||||
import {
|
||||
DatasetDataTextSchemaType,
|
||||
@@ -23,18 +23,24 @@ import json5 from 'json5';
|
||||
import { MongoDatasetCollectionTags } from '../tag/schema';
|
||||
import { readFromSecondary } from '../../../common/mongo/utils';
|
||||
import { MongoDatasetDataText } from '../data/dataTextSchema';
|
||||
import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
||||
import { POST } from '../../../common/api/plusRequest';
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { datasetSearchQueryExtension } from './utils';
|
||||
|
||||
type SearchDatasetDataProps = {
|
||||
export type SearchDatasetDataProps = {
|
||||
histories: ChatItemType[];
|
||||
teamId: string;
|
||||
model: string;
|
||||
similarity?: number; // min distance
|
||||
limit: number; // max Token limit
|
||||
datasetIds: string[];
|
||||
searchMode?: `${DatasetSearchModeEnum}`;
|
||||
usingReRank?: boolean;
|
||||
reRankQuery: string;
|
||||
queries: string[];
|
||||
|
||||
[NodeInputKeyEnum.datasetSimilarity]?: number; // min distance
|
||||
[NodeInputKeyEnum.datasetMaxTokens]: number; // max Token limit
|
||||
[NodeInputKeyEnum.datasetSearchMode]?: `${DatasetSearchModeEnum}`;
|
||||
[NodeInputKeyEnum.datasetSearchUsingReRank]?: boolean;
|
||||
|
||||
/*
|
||||
{
|
||||
tags: {
|
||||
@@ -50,7 +56,96 @@ type SearchDatasetDataProps = {
|
||||
collectionFilterMatch?: string;
|
||||
};
|
||||
|
||||
export async function searchDatasetData(props: SearchDatasetDataProps) {
|
||||
export type SearchDatasetDataResponse = {
|
||||
searchRes: SearchDataResponseItemType[];
|
||||
tokens: number;
|
||||
searchMode: `${DatasetSearchModeEnum}`;
|
||||
limit: number;
|
||||
similarity: number;
|
||||
usingReRank: boolean;
|
||||
usingSimilarityFilter: boolean;
|
||||
|
||||
queryExtensionResult?: {
|
||||
model: string;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
query: string;
|
||||
};
|
||||
deepSearchResult?: { model: string; inputTokens: number; outputTokens: number };
|
||||
};
|
||||
|
||||
export const datasetDataReRank = async ({
|
||||
data,
|
||||
query
|
||||
}: {
|
||||
data: SearchDataResponseItemType[];
|
||||
query: string;
|
||||
}): Promise<SearchDataResponseItemType[]> => {
|
||||
const results = await reRankRecall({
|
||||
query,
|
||||
documents: data.map((item) => ({
|
||||
id: item.id,
|
||||
text: `${item.q}\n${item.a}`
|
||||
}))
|
||||
});
|
||||
|
||||
if (results.length === 0) {
|
||||
return Promise.reject('Rerank error');
|
||||
}
|
||||
|
||||
// add new score to data
|
||||
const mergeResult = results
|
||||
.map((item, index) => {
|
||||
const target = data.find((dataItem) => dataItem.id === item.id);
|
||||
if (!target) return null;
|
||||
const score = item.score || 0;
|
||||
|
||||
return {
|
||||
...target,
|
||||
score: [{ type: SearchScoreTypeEnum.reRank, value: score, index }]
|
||||
};
|
||||
})
|
||||
.filter(Boolean) as SearchDataResponseItemType[];
|
||||
|
||||
return mergeResult;
|
||||
};
|
||||
export const filterDatasetDataByMaxTokens = async (
|
||||
data: SearchDataResponseItemType[],
|
||||
maxTokens: number
|
||||
) => {
|
||||
const filterMaxTokensResult = await (async () => {
|
||||
// Count tokens
|
||||
const tokensScoreFilter = await Promise.all(
|
||||
data.map(async (item) => ({
|
||||
...item,
|
||||
tokens: await countPromptTokens(item.q + item.a)
|
||||
}))
|
||||
);
|
||||
|
||||
const results: SearchDataResponseItemType[] = [];
|
||||
let totalTokens = 0;
|
||||
|
||||
for await (const item of tokensScoreFilter) {
|
||||
totalTokens += item.tokens;
|
||||
|
||||
if (totalTokens > maxTokens + 500) {
|
||||
break;
|
||||
}
|
||||
results.push(item);
|
||||
if (totalTokens > maxTokens) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return results.length === 0 ? data.slice(0, 1) : results;
|
||||
})();
|
||||
|
||||
return filterMaxTokensResult;
|
||||
};
|
||||
|
||||
export async function searchDatasetData(
|
||||
props: SearchDatasetDataProps
|
||||
): Promise<SearchDatasetDataResponse> {
|
||||
let {
|
||||
teamId,
|
||||
reRankQuery,
|
||||
@@ -455,47 +550,6 @@ export async function searchDatasetData(props: SearchDatasetDataProps) {
|
||||
tokenLen: 0
|
||||
};
|
||||
};
|
||||
const reRankSearchResult = async ({
|
||||
data,
|
||||
query
|
||||
}: {
|
||||
data: SearchDataResponseItemType[];
|
||||
query: string;
|
||||
}): Promise<SearchDataResponseItemType[]> => {
|
||||
try {
|
||||
const results = await reRankRecall({
|
||||
query,
|
||||
documents: data.map((item) => ({
|
||||
id: item.id,
|
||||
text: `${item.q}\n${item.a}`
|
||||
}))
|
||||
});
|
||||
|
||||
if (results.length === 0) {
|
||||
usingReRank = false;
|
||||
return [];
|
||||
}
|
||||
|
||||
// add new score to data
|
||||
const mergeResult = results
|
||||
.map((item, index) => {
|
||||
const target = data.find((dataItem) => dataItem.id === item.id);
|
||||
if (!target) return null;
|
||||
const score = item.score || 0;
|
||||
|
||||
return {
|
||||
...target,
|
||||
score: [{ type: SearchScoreTypeEnum.reRank, value: score, index }]
|
||||
};
|
||||
})
|
||||
.filter(Boolean) as SearchDataResponseItemType[];
|
||||
|
||||
return mergeResult;
|
||||
} catch (error) {
|
||||
usingReRank = false;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
const multiQueryRecall = async ({
|
||||
embeddingLimit,
|
||||
fullTextLimit
|
||||
@@ -580,10 +634,15 @@ export async function searchDatasetData(props: SearchDatasetDataProps) {
|
||||
set.add(str);
|
||||
return true;
|
||||
});
|
||||
return reRankSearchResult({
|
||||
query: reRankQuery,
|
||||
data: filterSameDataResults
|
||||
});
|
||||
try {
|
||||
return await datasetDataReRank({
|
||||
query: reRankQuery,
|
||||
data: filterSameDataResults
|
||||
});
|
||||
} catch (error) {
|
||||
usingReRank = false;
|
||||
return [];
|
||||
}
|
||||
})();
|
||||
|
||||
// embedding recall and fullText recall rrf concat
|
||||
@@ -628,31 +687,7 @@ export async function searchDatasetData(props: SearchDatasetDataProps) {
|
||||
})();
|
||||
|
||||
// token filter
|
||||
const filterMaxTokensResult = await (async () => {
|
||||
const tokensScoreFilter = await Promise.all(
|
||||
scoreFilter.map(async (item) => ({
|
||||
...item,
|
||||
tokens: await countPromptTokens(item.q + item.a)
|
||||
}))
|
||||
);
|
||||
|
||||
const results: SearchDataResponseItemType[] = [];
|
||||
let totalTokens = 0;
|
||||
|
||||
for await (const item of tokensScoreFilter) {
|
||||
totalTokens += item.tokens;
|
||||
|
||||
if (totalTokens > maxTokens + 500) {
|
||||
break;
|
||||
}
|
||||
results.push(item);
|
||||
if (totalTokens > maxTokens) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return results.length === 0 ? scoreFilter.slice(0, 1) : results;
|
||||
})();
|
||||
const filterMaxTokensResult = await filterDatasetDataByMaxTokens(scoreFilter, maxTokens);
|
||||
|
||||
return {
|
||||
searchRes: filterMaxTokensResult,
|
||||
@@ -664,3 +699,53 @@ export async function searchDatasetData(props: SearchDatasetDataProps) {
|
||||
usingSimilarityFilter
|
||||
};
|
||||
}
|
||||
|
||||
export type DefaultSearchDatasetDataProps = SearchDatasetDataProps & {
|
||||
[NodeInputKeyEnum.datasetSearchUsingExtensionQuery]?: boolean;
|
||||
[NodeInputKeyEnum.datasetSearchExtensionModel]?: string;
|
||||
[NodeInputKeyEnum.datasetSearchExtensionBg]?: string;
|
||||
};
|
||||
export const defaultSearchDatasetData = async ({
|
||||
datasetSearchUsingExtensionQuery,
|
||||
datasetSearchExtensionModel,
|
||||
datasetSearchExtensionBg,
|
||||
...props
|
||||
}: DefaultSearchDatasetDataProps): Promise<SearchDatasetDataResponse> => {
|
||||
const query = props.queries[0];
|
||||
|
||||
const extensionModel = datasetSearchUsingExtensionQuery
|
||||
? getLLMModel(datasetSearchExtensionModel)
|
||||
: undefined;
|
||||
|
||||
const { concatQueries, rewriteQuery, aiExtensionResult } = await datasetSearchQueryExtension({
|
||||
query,
|
||||
extensionModel,
|
||||
extensionBg: datasetSearchExtensionBg
|
||||
});
|
||||
|
||||
const result = await searchDatasetData({
|
||||
...props,
|
||||
reRankQuery: rewriteQuery,
|
||||
queries: concatQueries
|
||||
});
|
||||
|
||||
return {
|
||||
...result,
|
||||
queryExtensionResult: aiExtensionResult
|
||||
? {
|
||||
model: aiExtensionResult.model,
|
||||
inputTokens: aiExtensionResult.inputTokens,
|
||||
outputTokens: aiExtensionResult.outputTokens,
|
||||
query: concatQueries.join('\n')
|
||||
}
|
||||
: undefined
|
||||
};
|
||||
};
|
||||
|
||||
export type DeepRagSearchProps = SearchDatasetDataProps & {
|
||||
[NodeInputKeyEnum.datasetDeepSearchModel]?: string;
|
||||
[NodeInputKeyEnum.datasetDeepSearchMaxTimes]?: number;
|
||||
[NodeInputKeyEnum.datasetDeepSearchBg]?: string;
|
||||
};
|
||||
export const deepRagSearch = (data: DeepRagSearchProps) =>
|
||||
POST<SearchDatasetDataResponse>('/core/dataset/deepRag', data);
|
||||
|
||||
@@ -1,45 +1,5 @@
|
||||
import { DatasetTrainingSchemaType } from '@fastgpt/global/core/dataset/type';
|
||||
import { addLog } from '../../../common/system/log';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { MongoDatasetTraining } from './schema';
|
||||
import Papa from 'papaparse';
|
||||
|
||||
export const checkInvalidChunkAndLock = async ({
|
||||
err,
|
||||
errText,
|
||||
data
|
||||
}: {
|
||||
err: any;
|
||||
errText: string;
|
||||
data: DatasetTrainingSchemaType;
|
||||
}) => {
|
||||
if (err?.response) {
|
||||
addLog.error(`openai error: ${errText}`, {
|
||||
status: err.response?.status,
|
||||
statusText: err.response?.statusText,
|
||||
data: err.response?.data
|
||||
});
|
||||
} else {
|
||||
addLog.error(getErrText(err, errText), err);
|
||||
}
|
||||
|
||||
if (
|
||||
err?.message === 'invalid message format' ||
|
||||
err?.type === 'invalid_request_error' ||
|
||||
err?.code === 500
|
||||
) {
|
||||
addLog.error('Lock training data', err);
|
||||
|
||||
try {
|
||||
await MongoDatasetTraining.findByIdAndUpdate(data._id, {
|
||||
lockTime: new Date('2998/5/5')
|
||||
});
|
||||
} catch (error) {}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const parseCsvTable2Chunks = (rawText: string) => {
|
||||
const csvArr = Papa.parse(rawText).data as string[][];
|
||||
|
||||
|
||||
@@ -46,7 +46,15 @@ export const runToolWithFunctionCall = async (
|
||||
externalProvider,
|
||||
stream,
|
||||
workflowStreamResponse,
|
||||
params: { temperature, maxToken, aiChatVision }
|
||||
params: {
|
||||
temperature,
|
||||
maxToken,
|
||||
aiChatVision,
|
||||
aiChatTopP,
|
||||
aiChatStopSign,
|
||||
aiChatResponseFormat,
|
||||
aiChatJsonSchema
|
||||
}
|
||||
} = workflowProps;
|
||||
|
||||
// Interactive
|
||||
@@ -204,12 +212,18 @@ export const runToolWithFunctionCall = async (
|
||||
const requestBody = llmCompletionsBodyFormat(
|
||||
{
|
||||
model: toolModel.model,
|
||||
temperature,
|
||||
max_tokens,
|
||||
|
||||
stream,
|
||||
messages: requestMessages,
|
||||
functions,
|
||||
function_call: 'auto'
|
||||
function_call: 'auto',
|
||||
|
||||
temperature,
|
||||
max_tokens,
|
||||
top_p: aiChatTopP,
|
||||
stop: aiChatStopSign,
|
||||
response_format: aiChatResponseFormat,
|
||||
json_schema: aiChatJsonSchema
|
||||
},
|
||||
toolModel
|
||||
);
|
||||
|
||||
@@ -334,7 +334,7 @@ const getMultiInput = async ({
|
||||
|
||||
return {
|
||||
documentQuoteText: text,
|
||||
userFiles: fileLinks.map((url) => parseUrlToFileType(url))
|
||||
userFiles: fileLinks.map((url) => parseUrlToFileType(url)).filter(Boolean)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -54,7 +54,15 @@ export const runToolWithPromptCall = async (
|
||||
externalProvider,
|
||||
stream,
|
||||
workflowStreamResponse,
|
||||
params: { temperature, maxToken, aiChatVision }
|
||||
params: {
|
||||
temperature,
|
||||
maxToken,
|
||||
aiChatVision,
|
||||
aiChatTopP,
|
||||
aiChatStopSign,
|
||||
aiChatResponseFormat,
|
||||
aiChatJsonSchema
|
||||
}
|
||||
} = workflowProps;
|
||||
|
||||
if (interactiveEntryToolParams) {
|
||||
@@ -215,10 +223,14 @@ export const runToolWithPromptCall = async (
|
||||
const requestBody = llmCompletionsBodyFormat(
|
||||
{
|
||||
model: toolModel.model,
|
||||
stream,
|
||||
messages: requestMessages,
|
||||
temperature,
|
||||
max_tokens,
|
||||
stream,
|
||||
messages: requestMessages
|
||||
top_p: aiChatTopP,
|
||||
stop: aiChatStopSign,
|
||||
response_format: aiChatResponseFormat,
|
||||
json_schema: aiChatJsonSchema
|
||||
},
|
||||
toolModel
|
||||
);
|
||||
|
||||
@@ -93,7 +93,15 @@ export const runToolWithToolChoice = async (
|
||||
stream,
|
||||
externalProvider,
|
||||
workflowStreamResponse,
|
||||
params: { temperature, maxToken, aiChatVision }
|
||||
params: {
|
||||
temperature,
|
||||
maxToken,
|
||||
aiChatVision,
|
||||
aiChatTopP,
|
||||
aiChatStopSign,
|
||||
aiChatResponseFormat,
|
||||
aiChatJsonSchema
|
||||
}
|
||||
} = workflowProps;
|
||||
|
||||
if (maxRunToolTimes <= 0 && response) {
|
||||
@@ -263,12 +271,16 @@ export const runToolWithToolChoice = async (
|
||||
const requestBody = llmCompletionsBodyFormat(
|
||||
{
|
||||
model: toolModel.model,
|
||||
temperature,
|
||||
max_tokens,
|
||||
stream,
|
||||
messages: requestMessages,
|
||||
tools,
|
||||
tool_choice: 'auto'
|
||||
tool_choice: 'auto',
|
||||
temperature,
|
||||
max_tokens,
|
||||
top_p: aiChatTopP,
|
||||
stop: aiChatStopSign,
|
||||
response_format: aiChatResponseFormat,
|
||||
json_schema: aiChatJsonSchema
|
||||
},
|
||||
toolModel
|
||||
);
|
||||
|
||||
@@ -16,12 +16,16 @@ export type DispatchToolModuleProps = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.history]?: ChatItemType[];
|
||||
[NodeInputKeyEnum.userChatInput]: string;
|
||||
|
||||
[NodeInputKeyEnum.fileUrlList]?: string[];
|
||||
[NodeInputKeyEnum.aiModel]: string;
|
||||
[NodeInputKeyEnum.aiSystemPrompt]: string;
|
||||
[NodeInputKeyEnum.aiChatTemperature]: number;
|
||||
[NodeInputKeyEnum.aiChatMaxToken]: number;
|
||||
[NodeInputKeyEnum.aiChatVision]?: boolean;
|
||||
[NodeInputKeyEnum.fileUrlList]?: string[];
|
||||
[NodeInputKeyEnum.aiChatTopP]?: number;
|
||||
[NodeInputKeyEnum.aiChatStopSign]?: string;
|
||||
[NodeInputKeyEnum.aiChatResponseFormat]?: string;
|
||||
[NodeInputKeyEnum.aiChatJsonSchema]?: string;
|
||||
}> & {
|
||||
messages: ChatCompletionMessageParam[];
|
||||
toolNodes: ToolNodeItemType[];
|
||||
|
||||
@@ -3,13 +3,13 @@ import { filterGPTMessageByMaxContext, loadRequestMessages } from '../../../chat
|
||||
import type { ChatItemType, UserChatItemValueItemType } from '@fastgpt/global/core/chat/type.d';
|
||||
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import { textAdaptGptResponse } from '@fastgpt/global/core/workflow/runtime/utils';
|
||||
import {
|
||||
parseReasoningContent,
|
||||
parseReasoningStreamContent,
|
||||
textAdaptGptResponse
|
||||
} from '@fastgpt/global/core/workflow/runtime/utils';
|
||||
import { createChatCompletion } from '../../../ai/config';
|
||||
import type {
|
||||
ChatCompletion,
|
||||
ChatCompletionMessageParam,
|
||||
StreamChatType
|
||||
} from '@fastgpt/global/core/ai/type.d';
|
||||
import type { ChatCompletionMessageParam, StreamChatType } from '@fastgpt/global/core/ai/type.d';
|
||||
import { formatModelChars2Points } from '../../../../support/wallet/usage/utils';
|
||||
import type { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||
import { postTextCensor } from '../../../../common/api/requestPlusApi';
|
||||
@@ -51,7 +51,7 @@ import { ModelTypeEnum } from '@fastgpt/global/core/ai/model';
|
||||
|
||||
export type ChatProps = ModuleDispatchProps<
|
||||
AIChatNodeProps & {
|
||||
[NodeInputKeyEnum.userChatInput]: string;
|
||||
[NodeInputKeyEnum.userChatInput]?: string;
|
||||
[NodeInputKeyEnum.history]?: ChatItemType[] | number;
|
||||
[NodeInputKeyEnum.aiChatDatasetQuote]?: SearchDataResponseItemType[];
|
||||
}
|
||||
@@ -81,7 +81,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
maxToken,
|
||||
history = 6,
|
||||
quoteQA,
|
||||
userChatInput,
|
||||
userChatInput = '',
|
||||
isResponseAnswerText = true,
|
||||
systemPrompt = '',
|
||||
aiChatQuoteRole = 'system',
|
||||
@@ -89,6 +89,11 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
quotePrompt,
|
||||
aiChatVision,
|
||||
aiChatReasoning = true,
|
||||
aiChatTopP,
|
||||
aiChatStopSign,
|
||||
aiChatResponseFormat,
|
||||
aiChatJsonSchema,
|
||||
|
||||
fileUrlList: fileLinks, // node quote file links
|
||||
stringQuoteText //abandon
|
||||
}
|
||||
@@ -100,7 +105,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
return Promise.reject('The chat model is undefined, you need to select a chat model.');
|
||||
}
|
||||
|
||||
stream = stream && isResponseAnswerText;
|
||||
aiChatVision = modelConstantsData.vision && aiChatVision;
|
||||
aiChatReasoning = !!aiChatReasoning && !!modelConstantsData.reasoning;
|
||||
|
||||
const chatHistories = getHistories(history, histories);
|
||||
@@ -160,17 +165,21 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
|
||||
const requestMessages = await loadRequestMessages({
|
||||
messages: filterMessages,
|
||||
useVision: modelConstantsData.vision && aiChatVision,
|
||||
useVision: aiChatVision,
|
||||
origin: requestOrigin
|
||||
});
|
||||
|
||||
const requestBody = llmCompletionsBodyFormat(
|
||||
{
|
||||
model: modelConstantsData.model,
|
||||
stream,
|
||||
messages: requestMessages,
|
||||
temperature,
|
||||
max_tokens,
|
||||
stream,
|
||||
messages: requestMessages
|
||||
top_p: aiChatTopP,
|
||||
stop: aiChatStopSign,
|
||||
response_format: aiChatResponseFormat as any,
|
||||
json_schema: aiChatJsonSchema
|
||||
},
|
||||
modelConstantsData
|
||||
);
|
||||
@@ -186,12 +195,19 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
});
|
||||
|
||||
const { answerText, reasoningText } = await (async () => {
|
||||
if (res && isStreamResponse) {
|
||||
if (isStreamResponse) {
|
||||
if (!res) {
|
||||
return {
|
||||
answerText: '',
|
||||
reasoningText: ''
|
||||
};
|
||||
}
|
||||
// sse response
|
||||
const { answer, reasoning } = await streamResponse({
|
||||
res,
|
||||
stream: response,
|
||||
aiChatReasoning,
|
||||
isResponseAnswerText,
|
||||
workflowStreamResponse
|
||||
});
|
||||
|
||||
@@ -200,26 +216,49 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
reasoningText: reasoning
|
||||
};
|
||||
} else {
|
||||
const unStreamResponse = response as ChatCompletion;
|
||||
const answer = unStreamResponse.choices?.[0]?.message?.content || '';
|
||||
const reasoning = aiChatReasoning
|
||||
? // @ts-ignore
|
||||
unStreamResponse.choices?.[0]?.message?.reasoning_content || ''
|
||||
: '';
|
||||
const { content, reasoningContent } = (() => {
|
||||
const content = response.choices?.[0]?.message?.content || '';
|
||||
// @ts-ignore
|
||||
const reasoningContent: string = response.choices?.[0]?.message?.reasoning_content || '';
|
||||
|
||||
// API already parse reasoning content
|
||||
if (reasoningContent || !aiChatReasoning) {
|
||||
return {
|
||||
content,
|
||||
reasoningContent
|
||||
};
|
||||
}
|
||||
|
||||
const [think, answer] = parseReasoningContent(content);
|
||||
return {
|
||||
content: answer,
|
||||
reasoningContent: think
|
||||
};
|
||||
})();
|
||||
|
||||
// Some models do not support streaming
|
||||
if (stream) {
|
||||
// Some models do not support streaming
|
||||
workflowStreamResponse?.({
|
||||
event: SseResponseEventEnum.fastAnswer,
|
||||
data: textAdaptGptResponse({
|
||||
text: answer,
|
||||
reasoning_content: reasoning
|
||||
})
|
||||
});
|
||||
if (aiChatReasoning && reasoningContent) {
|
||||
workflowStreamResponse?.({
|
||||
event: SseResponseEventEnum.fastAnswer,
|
||||
data: textAdaptGptResponse({
|
||||
reasoning_content: reasoningContent
|
||||
})
|
||||
});
|
||||
}
|
||||
if (isResponseAnswerText && content) {
|
||||
workflowStreamResponse?.({
|
||||
event: SseResponseEventEnum.fastAnswer,
|
||||
data: textAdaptGptResponse({
|
||||
text: content
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
answerText: answer,
|
||||
reasoningText: reasoning
|
||||
answerText: content,
|
||||
reasoningText: reasoningContent
|
||||
};
|
||||
}
|
||||
})();
|
||||
@@ -231,7 +270,8 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
const AIMessages: ChatCompletionMessageParam[] = [
|
||||
{
|
||||
role: ChatCompletionRequestMessageRoleEnum.Assistant,
|
||||
content: answerText
|
||||
content: answerText,
|
||||
reasoning_text: reasoningText // reasoning_text is only recorded for response, but not for request
|
||||
}
|
||||
];
|
||||
|
||||
@@ -249,7 +289,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
});
|
||||
|
||||
return {
|
||||
answerText,
|
||||
answerText: answerText.trim(),
|
||||
reasoningText,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
totalPoints: externalProvider.openaiAccount?.key ? 0 : totalPoints,
|
||||
@@ -259,11 +299,8 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
outputTokens: outputTokens,
|
||||
query: `${userChatInput}`,
|
||||
maxToken: max_tokens,
|
||||
historyPreview: getHistoryPreview(
|
||||
chatCompleteMessages,
|
||||
10000,
|
||||
modelConstantsData.vision && aiChatVision
|
||||
),
|
||||
reasoningText,
|
||||
historyPreview: getHistoryPreview(chatCompleteMessages, 10000, aiChatVision),
|
||||
contextTotalLen: completeMessages.length
|
||||
},
|
||||
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
|
||||
@@ -371,7 +408,7 @@ async function getMultiInput({
|
||||
|
||||
return {
|
||||
documentQuoteText: text,
|
||||
userFiles: fileLinks.map((url) => parseUrlToFileType(url))
|
||||
userFiles: fileLinks.map((url) => parseUrlToFileType(url)).filter(Boolean)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -470,12 +507,14 @@ async function streamResponse({
|
||||
res,
|
||||
stream,
|
||||
workflowStreamResponse,
|
||||
aiChatReasoning
|
||||
aiChatReasoning,
|
||||
isResponseAnswerText
|
||||
}: {
|
||||
res: NextApiResponse;
|
||||
stream: StreamChatType;
|
||||
workflowStreamResponse?: WorkflowResponseType;
|
||||
aiChatReasoning?: boolean;
|
||||
isResponseAnswerText?: boolean;
|
||||
}) {
|
||||
const write = responseWriteController({
|
||||
res,
|
||||
@@ -483,28 +522,42 @@ async function streamResponse({
|
||||
});
|
||||
let answer = '';
|
||||
let reasoning = '';
|
||||
const { parsePart, getStartTagBuffer } = parseReasoningStreamContent();
|
||||
|
||||
for await (const part of stream) {
|
||||
if (res.closed) {
|
||||
stream.controller?.abort();
|
||||
break;
|
||||
}
|
||||
|
||||
const content = part.choices?.[0]?.delta?.content || '';
|
||||
const [reasoningContent, content] = parsePart(part, aiChatReasoning);
|
||||
answer += content;
|
||||
|
||||
const reasoningContent = aiChatReasoning
|
||||
? part.choices?.[0]?.delta?.reasoning_content || ''
|
||||
: '';
|
||||
reasoning += reasoningContent;
|
||||
|
||||
workflowStreamResponse?.({
|
||||
write,
|
||||
event: SseResponseEventEnum.answer,
|
||||
data: textAdaptGptResponse({
|
||||
text: content,
|
||||
reasoning_content: reasoningContent
|
||||
})
|
||||
});
|
||||
if (aiChatReasoning && reasoningContent) {
|
||||
workflowStreamResponse?.({
|
||||
write,
|
||||
event: SseResponseEventEnum.answer,
|
||||
data: textAdaptGptResponse({
|
||||
reasoning_content: reasoningContent
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (isResponseAnswerText && content) {
|
||||
workflowStreamResponse?.({
|
||||
write,
|
||||
event: SseResponseEventEnum.answer,
|
||||
data: textAdaptGptResponse({
|
||||
text: content
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// if answer is empty, try to get value from startTagBuffer. (Cause: The response content is too short to exceed the minimum parse length)
|
||||
if (answer === '') {
|
||||
answer = getStartTagBuffer();
|
||||
}
|
||||
|
||||
return { answer, reasoning };
|
||||
|
||||
@@ -6,13 +6,11 @@ import { formatModelChars2Points } from '../../../../support/wallet/usage/utils'
|
||||
import type { SelectedDatasetType } from '@fastgpt/global/core/workflow/api.d';
|
||||
import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
|
||||
import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { getLLMModel, getEmbeddingModel } from '../../../ai/model';
|
||||
import { searchDatasetData } from '../../../dataset/search/controller';
|
||||
import { getEmbeddingModel } from '../../../ai/model';
|
||||
import { deepRagSearch, defaultSearchDatasetData } from '../../../dataset/search/controller';
|
||||
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
import { getHistories } from '../utils';
|
||||
import { datasetSearchQueryExtension } from '../../../dataset/search/utils';
|
||||
import { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type';
|
||||
import { checkTeamReRankPermission } from '../../../../support/permission/teamLimit';
|
||||
import { MongoDataset } from '../../../dataset/schema';
|
||||
@@ -25,13 +23,19 @@ type DatasetSearchProps = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.datasetSimilarity]: number;
|
||||
[NodeInputKeyEnum.datasetMaxTokens]: number;
|
||||
[NodeInputKeyEnum.datasetSearchMode]: `${DatasetSearchModeEnum}`;
|
||||
[NodeInputKeyEnum.userChatInput]: string;
|
||||
[NodeInputKeyEnum.userChatInput]?: string;
|
||||
[NodeInputKeyEnum.datasetSearchUsingReRank]: boolean;
|
||||
[NodeInputKeyEnum.collectionFilterMatch]: string;
|
||||
[NodeInputKeyEnum.authTmbId]?: boolean;
|
||||
|
||||
[NodeInputKeyEnum.datasetSearchUsingExtensionQuery]: boolean;
|
||||
[NodeInputKeyEnum.datasetSearchExtensionModel]: string;
|
||||
[NodeInputKeyEnum.datasetSearchExtensionBg]: string;
|
||||
[NodeInputKeyEnum.collectionFilterMatch]: string;
|
||||
[NodeInputKeyEnum.authTmbId]: boolean;
|
||||
|
||||
[NodeInputKeyEnum.datasetDeepSearch]?: boolean;
|
||||
[NodeInputKeyEnum.datasetDeepSearchModel]?: string;
|
||||
[NodeInputKeyEnum.datasetDeepSearchMaxTimes]?: number;
|
||||
[NodeInputKeyEnum.datasetDeepSearchBg]?: string;
|
||||
}>;
|
||||
export type DatasetSearchResponse = DispatchNodeResultType<{
|
||||
[NodeOutputKeyEnum.datasetQuoteQA]: SearchDataResponseItemType[];
|
||||
@@ -51,13 +55,18 @@ export async function dispatchDatasetSearch(
|
||||
limit = 1500,
|
||||
usingReRank,
|
||||
searchMode,
|
||||
userChatInput,
|
||||
userChatInput = '',
|
||||
authTmbId = false,
|
||||
collectionFilterMatch,
|
||||
|
||||
datasetSearchUsingExtensionQuery,
|
||||
datasetSearchExtensionModel,
|
||||
datasetSearchExtensionBg,
|
||||
collectionFilterMatch,
|
||||
authTmbId = false
|
||||
|
||||
datasetDeepSearch,
|
||||
datasetDeepSearchModel,
|
||||
datasetDeepSearchMaxTimes,
|
||||
datasetDeepSearchBg
|
||||
}
|
||||
} = props as DatasetSearchProps;
|
||||
|
||||
@@ -85,25 +94,12 @@ export async function dispatchDatasetSearch(
|
||||
return emptyResult;
|
||||
}
|
||||
|
||||
// query extension
|
||||
const extensionModel = datasetSearchUsingExtensionQuery
|
||||
? getLLMModel(datasetSearchExtensionModel)
|
||||
: undefined;
|
||||
|
||||
const [{ concatQueries, rewriteQuery, aiExtensionResult }, datasetIds] = await Promise.all([
|
||||
datasetSearchQueryExtension({
|
||||
query: userChatInput,
|
||||
extensionModel,
|
||||
extensionBg: datasetSearchExtensionBg,
|
||||
histories: getHistories(6, histories)
|
||||
}),
|
||||
authTmbId
|
||||
? filterDatasetsByTmbId({
|
||||
datasetIds: datasets.map((item) => item.datasetId),
|
||||
tmbId
|
||||
})
|
||||
: Promise.resolve(datasets.map((item) => item.datasetId))
|
||||
]);
|
||||
const datasetIds = authTmbId
|
||||
? await filterDatasetsByTmbId({
|
||||
datasetIds: datasets.map((item) => item.datasetId),
|
||||
tmbId
|
||||
})
|
||||
: await Promise.resolve(datasets.map((item) => item.datasetId));
|
||||
|
||||
if (datasetIds.length === 0) {
|
||||
return emptyResult;
|
||||
@@ -116,15 +112,11 @@ export async function dispatchDatasetSearch(
|
||||
);
|
||||
|
||||
// start search
|
||||
const {
|
||||
searchRes,
|
||||
tokens,
|
||||
usingSimilarityFilter,
|
||||
usingReRank: searchUsingReRank
|
||||
} = await searchDatasetData({
|
||||
const searchData = {
|
||||
histories,
|
||||
teamId,
|
||||
reRankQuery: `${rewriteQuery}`,
|
||||
queries: concatQueries,
|
||||
reRankQuery: userChatInput,
|
||||
queries: [userChatInput],
|
||||
model: vectorModel.model,
|
||||
similarity,
|
||||
limit,
|
||||
@@ -132,59 +124,106 @@ export async function dispatchDatasetSearch(
|
||||
searchMode,
|
||||
usingReRank: usingReRank && (await checkTeamReRankPermission(teamId)),
|
||||
collectionFilterMatch
|
||||
});
|
||||
};
|
||||
const {
|
||||
searchRes,
|
||||
tokens,
|
||||
usingSimilarityFilter,
|
||||
usingReRank: searchUsingReRank,
|
||||
queryExtensionResult,
|
||||
deepSearchResult
|
||||
} = datasetDeepSearch
|
||||
? await deepRagSearch({
|
||||
...searchData,
|
||||
datasetDeepSearchModel,
|
||||
datasetDeepSearchMaxTimes,
|
||||
datasetDeepSearchBg
|
||||
})
|
||||
: await defaultSearchDatasetData({
|
||||
...searchData,
|
||||
datasetSearchUsingExtensionQuery,
|
||||
datasetSearchExtensionModel,
|
||||
datasetSearchExtensionBg
|
||||
});
|
||||
|
||||
// count bill results
|
||||
const nodeDispatchUsages: ChatNodeUsageType[] = [];
|
||||
// vector
|
||||
const { totalPoints, modelName } = formatModelChars2Points({
|
||||
model: vectorModel.model,
|
||||
inputTokens: tokens,
|
||||
modelType: ModelTypeEnum.embedding
|
||||
const { totalPoints: embeddingTotalPoints, modelName: embeddingModelName } =
|
||||
formatModelChars2Points({
|
||||
model: vectorModel.model,
|
||||
inputTokens: tokens,
|
||||
modelType: ModelTypeEnum.embedding
|
||||
});
|
||||
nodeDispatchUsages.push({
|
||||
totalPoints: embeddingTotalPoints,
|
||||
moduleName: node.name,
|
||||
model: embeddingModelName,
|
||||
inputTokens: tokens
|
||||
});
|
||||
// Query extension
|
||||
const { totalPoints: queryExtensionTotalPoints } = (() => {
|
||||
if (queryExtensionResult) {
|
||||
const { totalPoints, modelName } = formatModelChars2Points({
|
||||
model: queryExtensionResult.model,
|
||||
inputTokens: queryExtensionResult.inputTokens,
|
||||
outputTokens: queryExtensionResult.outputTokens,
|
||||
modelType: ModelTypeEnum.llm
|
||||
});
|
||||
nodeDispatchUsages.push({
|
||||
totalPoints,
|
||||
moduleName: i18nT('common:core.module.template.Query extension'),
|
||||
model: modelName,
|
||||
inputTokens: queryExtensionResult.inputTokens,
|
||||
outputTokens: queryExtensionResult.outputTokens
|
||||
});
|
||||
return {
|
||||
totalPoints
|
||||
};
|
||||
}
|
||||
return {
|
||||
totalPoints: 0
|
||||
};
|
||||
})();
|
||||
// Deep search
|
||||
const { totalPoints: deepSearchTotalPoints } = (() => {
|
||||
if (deepSearchResult) {
|
||||
const { totalPoints, modelName } = formatModelChars2Points({
|
||||
model: deepSearchResult.model,
|
||||
inputTokens: deepSearchResult.inputTokens,
|
||||
outputTokens: deepSearchResult.outputTokens,
|
||||
modelType: ModelTypeEnum.llm
|
||||
});
|
||||
nodeDispatchUsages.push({
|
||||
totalPoints,
|
||||
moduleName: i18nT('common:deep_rag_search'),
|
||||
model: modelName,
|
||||
inputTokens: deepSearchResult.inputTokens,
|
||||
outputTokens: deepSearchResult.outputTokens
|
||||
});
|
||||
return {
|
||||
totalPoints
|
||||
};
|
||||
}
|
||||
return {
|
||||
totalPoints: 0
|
||||
};
|
||||
})();
|
||||
const totalPoints = embeddingTotalPoints + queryExtensionTotalPoints + deepSearchTotalPoints;
|
||||
|
||||
const responseData: DispatchNodeResponseType & { totalPoints: number } = {
|
||||
totalPoints,
|
||||
query: concatQueries.join('\n'),
|
||||
model: modelName,
|
||||
query: userChatInput,
|
||||
model: vectorModel.model,
|
||||
inputTokens: tokens,
|
||||
similarity: usingSimilarityFilter ? similarity : undefined,
|
||||
limit,
|
||||
searchMode,
|
||||
searchUsingReRank: searchUsingReRank,
|
||||
quoteList: searchRes
|
||||
quoteList: searchRes,
|
||||
queryExtensionResult,
|
||||
deepSearchResult
|
||||
};
|
||||
const nodeDispatchUsages: ChatNodeUsageType[] = [
|
||||
{
|
||||
totalPoints,
|
||||
moduleName: node.name,
|
||||
model: modelName,
|
||||
inputTokens: tokens
|
||||
}
|
||||
];
|
||||
|
||||
if (aiExtensionResult) {
|
||||
const { totalPoints, modelName } = formatModelChars2Points({
|
||||
model: aiExtensionResult.model,
|
||||
inputTokens: aiExtensionResult.inputTokens,
|
||||
outputTokens: aiExtensionResult.outputTokens,
|
||||
modelType: ModelTypeEnum.llm
|
||||
});
|
||||
|
||||
responseData.totalPoints += totalPoints;
|
||||
responseData.inputTokens = aiExtensionResult.inputTokens;
|
||||
responseData.outputTokens = aiExtensionResult.outputTokens;
|
||||
responseData.extensionModel = modelName;
|
||||
responseData.extensionResult =
|
||||
aiExtensionResult.extensionQueries?.join('\n') ||
|
||||
JSON.stringify(aiExtensionResult.extensionQueries);
|
||||
|
||||
nodeDispatchUsages.push({
|
||||
totalPoints,
|
||||
moduleName: 'core.module.template.Query extension',
|
||||
model: modelName,
|
||||
inputTokens: aiExtensionResult.inputTokens,
|
||||
outputTokens: aiExtensionResult.outputTokens
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
quoteQA: searchRes,
|
||||
|
||||
@@ -232,9 +232,14 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
chatNodeUsages = chatNodeUsages.concat(nodeDispatchUsages);
|
||||
}
|
||||
|
||||
if (toolResponses !== undefined) {
|
||||
if (toolResponses !== undefined && toolResponses !== null) {
|
||||
if (Array.isArray(toolResponses) && toolResponses.length === 0) return;
|
||||
if (typeof toolResponses === 'object' && Object.keys(toolResponses).length === 0) return;
|
||||
if (
|
||||
!Array.isArray(toolResponses) &&
|
||||
typeof toolResponses === 'object' &&
|
||||
Object.keys(toolResponses).length === 0
|
||||
)
|
||||
return;
|
||||
toolRunResponse = toolResponses;
|
||||
}
|
||||
|
||||
@@ -243,12 +248,17 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
chatAssistantResponse = chatAssistantResponse.concat(assistantResponses);
|
||||
} else {
|
||||
if (reasoningText) {
|
||||
chatAssistantResponse.push({
|
||||
type: ChatItemValueTypeEnum.reasoning,
|
||||
reasoning: {
|
||||
content: reasoningText
|
||||
}
|
||||
});
|
||||
const isResponseReasoningText = inputs.find(
|
||||
(item) => item.key === NodeInputKeyEnum.aiChatReasoning
|
||||
)?.value;
|
||||
if (isResponseReasoningText) {
|
||||
chatAssistantResponse.push({
|
||||
type: ChatItemValueTypeEnum.reasoning,
|
||||
reasoning: {
|
||||
content: reasoningText
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (answerText) {
|
||||
// save assistant text response
|
||||
|
||||
@@ -53,7 +53,7 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
|
||||
|
||||
const userInputFiles = (() => {
|
||||
if (fileUrlList) {
|
||||
return fileUrlList.map((url) => parseUrlToFileType(url));
|
||||
return fileUrlList.map((url) => parseUrlToFileType(url)).filter(Boolean);
|
||||
}
|
||||
// Adapt version 4.8.13 upgrade
|
||||
return files;
|
||||
|
||||
@@ -38,10 +38,10 @@ type HttpRequestProps = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.abandon_httpUrl]: string;
|
||||
[NodeInputKeyEnum.httpMethod]: string;
|
||||
[NodeInputKeyEnum.httpReqUrl]: string;
|
||||
[NodeInputKeyEnum.httpHeaders]: PropsArrType[];
|
||||
[NodeInputKeyEnum.httpParams]: PropsArrType[];
|
||||
[NodeInputKeyEnum.httpJsonBody]: string;
|
||||
[NodeInputKeyEnum.httpFormBody]: PropsArrType[];
|
||||
[NodeInputKeyEnum.httpHeaders]?: PropsArrType[];
|
||||
[NodeInputKeyEnum.httpParams]?: PropsArrType[];
|
||||
[NodeInputKeyEnum.httpJsonBody]?: string;
|
||||
[NodeInputKeyEnum.httpFormBody]?: PropsArrType[];
|
||||
[NodeInputKeyEnum.httpContentType]: ContentTypes;
|
||||
[NodeInputKeyEnum.addInputParam]: Record<string, any>;
|
||||
[NodeInputKeyEnum.httpTimeout]?: number;
|
||||
@@ -76,10 +76,10 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
||||
params: {
|
||||
system_httpMethod: httpMethod = 'POST',
|
||||
system_httpReqUrl: httpReqUrl,
|
||||
system_httpHeader: httpHeader,
|
||||
system_httpHeader: httpHeader = [],
|
||||
system_httpParams: httpParams = [],
|
||||
system_httpJsonBody: httpJsonBody,
|
||||
system_httpFormBody: httpFormBody,
|
||||
system_httpJsonBody: httpJsonBody = '',
|
||||
system_httpFormBody: httpFormBody = [],
|
||||
system_httpContentType: httpContentType = ContentTypes.json,
|
||||
system_httpTimeout: httpTimeout = 60,
|
||||
[NodeInputKeyEnum.addInputParam]: dynamicInput,
|
||||
@@ -398,41 +398,6 @@ async function fetchData({
|
||||
};
|
||||
}
|
||||
|
||||
// function replaceVariable(text: string, obj: Record<string, any>) {
|
||||
// for (const [key, value] of Object.entries(obj)) {
|
||||
// if (value === undefined) {
|
||||
// text = text.replace(new RegExp(`{{(${key})}}`, 'g'), UNDEFINED_SIGN);
|
||||
// } else {
|
||||
// const replacement = JSON.stringify(value);
|
||||
// const unquotedReplacement =
|
||||
// replacement.startsWith('"') && replacement.endsWith('"')
|
||||
// ? replacement.slice(1, -1)
|
||||
// : replacement;
|
||||
// text = text.replace(new RegExp(`{{(${key})}}`, 'g'), () => unquotedReplacement);
|
||||
// }
|
||||
// }
|
||||
// return text || '';
|
||||
// }
|
||||
// function removeUndefinedSign(obj: Record<string, any>) {
|
||||
// for (const key in obj) {
|
||||
// if (obj[key] === UNDEFINED_SIGN) {
|
||||
// obj[key] = undefined;
|
||||
// } else if (Array.isArray(obj[key])) {
|
||||
// obj[key] = obj[key].map((item: any) => {
|
||||
// if (item === UNDEFINED_SIGN) {
|
||||
// return undefined;
|
||||
// } else if (typeof item === 'object') {
|
||||
// removeUndefinedSign(item);
|
||||
// }
|
||||
// return item;
|
||||
// });
|
||||
// } else if (typeof obj[key] === 'object') {
|
||||
// removeUndefinedSign(obj[key]);
|
||||
// }
|
||||
// }
|
||||
// return obj;
|
||||
// }
|
||||
|
||||
// Replace some special response from system plugin
|
||||
async function replaceSystemPluginResponse({
|
||||
response,
|
||||
|
||||
@@ -142,7 +142,7 @@ export const checkQuoteQAValue = (quoteQA?: SearchDataResponseItemType[]) => {
|
||||
if (quoteQA.length === 0) {
|
||||
return [];
|
||||
}
|
||||
if (quoteQA.some((item) => !item.q)) {
|
||||
if (quoteQA.some((item) => typeof item !== 'object' || !item.q)) {
|
||||
return undefined;
|
||||
}
|
||||
return quoteQA;
|
||||
|
||||
@@ -86,9 +86,12 @@ export async function addSourceMember<T extends { tmbId: string }>({
|
||||
}): Promise<Array<T & { sourceMember: SourceMemberType }>> {
|
||||
if (!Array.isArray(list)) return [];
|
||||
|
||||
const tmbIdList = list
|
||||
.map((item) => (item.tmbId ? String(item.tmbId) : undefined))
|
||||
.filter(Boolean);
|
||||
const tmbList = await MongoTeamMember.find(
|
||||
{
|
||||
_id: { $in: list.map((item) => String(item.tmbId)) }
|
||||
_id: { $in: tmbIdList }
|
||||
},
|
||||
'tmbId name avatar status',
|
||||
{
|
||||
|
||||
@@ -1,6 +1,114 @@
|
||||
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
import { MongoUsage } from './schema';
|
||||
import { ClientSession } from '../../../common/mongo';
|
||||
import { ClientSession, Types } from '../../../common/mongo';
|
||||
import { addLog } from '../../../common/system/log';
|
||||
import { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type';
|
||||
import { ConcatUsageProps, CreateUsageProps } from '@fastgpt/global/support/wallet/usage/api';
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
import { pushConcatBillTask, pushReduceTeamAiPointsTask } from './utils';
|
||||
|
||||
import { POST } from '../../../common/api/plusRequest';
|
||||
import { FastGPTProUrl } from '../../../common/system/constants';
|
||||
|
||||
export async function createUsage(data: CreateUsageProps) {
|
||||
try {
|
||||
// In FastGPT server
|
||||
if (FastGPTProUrl) {
|
||||
await POST('/support/wallet/usage/createUsage', data);
|
||||
} else if (global.reduceAiPointsQueue) {
|
||||
// In FastGPT pro server
|
||||
await MongoUsage.create(data);
|
||||
pushReduceTeamAiPointsTask({ teamId: data.teamId, totalPoints: data.totalPoints });
|
||||
|
||||
if (data.totalPoints === 0) {
|
||||
addLog.info('0 totalPoints', data);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
addLog.error('createUsage error', error);
|
||||
}
|
||||
}
|
||||
export async function concatUsage(data: ConcatUsageProps) {
|
||||
try {
|
||||
// In FastGPT server
|
||||
if (FastGPTProUrl) {
|
||||
await POST('/support/wallet/usage/concatUsage', data);
|
||||
} else if (global.reduceAiPointsQueue) {
|
||||
const {
|
||||
teamId,
|
||||
billId,
|
||||
totalPoints = 0,
|
||||
listIndex,
|
||||
inputTokens = 0,
|
||||
outputTokens = 0
|
||||
} = data;
|
||||
|
||||
// billId is required and valid
|
||||
if (!billId || !Types.ObjectId.isValid(billId)) return;
|
||||
|
||||
// In FastGPT pro server
|
||||
pushConcatBillTask([
|
||||
{
|
||||
billId,
|
||||
listIndex,
|
||||
inputTokens,
|
||||
outputTokens,
|
||||
totalPoints
|
||||
}
|
||||
]);
|
||||
pushReduceTeamAiPointsTask({ teamId, totalPoints });
|
||||
|
||||
if (data.totalPoints === 0) {
|
||||
addLog.info('0 totalPoints', data);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
addLog.error('concatUsage error', error);
|
||||
}
|
||||
}
|
||||
|
||||
export const createChatUsage = ({
|
||||
appName,
|
||||
appId,
|
||||
pluginId,
|
||||
teamId,
|
||||
tmbId,
|
||||
source,
|
||||
flowUsages
|
||||
}: {
|
||||
appName: string;
|
||||
appId?: string;
|
||||
pluginId?: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
source: UsageSourceEnum;
|
||||
flowUsages: ChatNodeUsageType[];
|
||||
}) => {
|
||||
const totalPoints = flowUsages.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
|
||||
|
||||
createUsage({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName,
|
||||
appId,
|
||||
pluginId,
|
||||
totalPoints,
|
||||
source,
|
||||
list: flowUsages.map((item) => ({
|
||||
moduleName: item.moduleName,
|
||||
amount: item.totalPoints || 0,
|
||||
model: item.model,
|
||||
inputTokens: item.inputTokens,
|
||||
outputTokens: item.outputTokens
|
||||
}))
|
||||
});
|
||||
addLog.debug(`Create chat usage`, {
|
||||
source,
|
||||
teamId,
|
||||
totalPoints
|
||||
});
|
||||
return { totalPoints };
|
||||
};
|
||||
|
||||
export const createTrainingUsage = async ({
|
||||
teamId,
|
||||
@@ -29,21 +137,21 @@ export const createTrainingUsage = async ({
|
||||
totalPoints: 0,
|
||||
list: [
|
||||
{
|
||||
moduleName: 'support.wallet.moduleName.index',
|
||||
moduleName: i18nT('common:support.wallet.moduleName.index'),
|
||||
model: vectorModel,
|
||||
amount: 0,
|
||||
inputTokens: 0,
|
||||
outputTokens: 0
|
||||
},
|
||||
{
|
||||
moduleName: 'support.wallet.moduleName.qa',
|
||||
moduleName: i18nT('common:support.wallet.moduleName.qa'),
|
||||
model: agentModel,
|
||||
amount: 0,
|
||||
inputTokens: 0,
|
||||
outputTokens: 0
|
||||
},
|
||||
{
|
||||
moduleName: 'core.dataset.training.Auto mode',
|
||||
moduleName: i18nT('common:core.dataset.training.Auto mode'),
|
||||
model: agentModel,
|
||||
amount: 0,
|
||||
inputTokens: 0,
|
||||
|
||||
12
packages/service/support/wallet/usage/type.d.ts
vendored
Normal file
12
packages/service/support/wallet/usage/type.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export type ConcatBillQueueItemType = {
|
||||
billId: string;
|
||||
listIndex?: number;
|
||||
totalPoints: number;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
};
|
||||
|
||||
declare global {
|
||||
var reduceAiPointsQueue: { teamId: string; totalPoints: number }[];
|
||||
var concatBillQueue: ConcatBillQueueItemType[];
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { findAIModel } from '../../../core/ai/model';
|
||||
import { ModelTypeEnum } from '@fastgpt/global/core/ai/model';
|
||||
import { ConcatBillQueueItemType } from './type';
|
||||
|
||||
export const formatModelChars2Points = ({
|
||||
model,
|
||||
@@ -34,3 +35,20 @@ export const formatModelChars2Points = ({
|
||||
totalPoints
|
||||
};
|
||||
};
|
||||
|
||||
export const pushReduceTeamAiPointsTask = ({
|
||||
teamId,
|
||||
totalPoints
|
||||
}: {
|
||||
teamId: string;
|
||||
totalPoints: number;
|
||||
}) => {
|
||||
global.reduceAiPointsQueue.push({
|
||||
teamId: String(teamId),
|
||||
totalPoints
|
||||
});
|
||||
};
|
||||
|
||||
export const pushConcatBillTask = (data: ConcatBillQueueItemType[]) => {
|
||||
global.concatBillQueue.push(...data);
|
||||
};
|
||||
|
||||
@@ -72,7 +72,7 @@ parentPort?.on(
|
||||
};
|
||||
|
||||
const total =
|
||||
messages.reduce((sum, item) => {
|
||||
messages.reduce((sum, item, index) => {
|
||||
// Evaluates the text of toolcall and functioncall
|
||||
const functionCallPrompt = (() => {
|
||||
let prompt = '';
|
||||
@@ -100,7 +100,13 @@ parentPort?.on(
|
||||
.join('');
|
||||
})();
|
||||
|
||||
return sum + countPromptTokens(`${contentPrompt}${functionCallPrompt}`, item.role);
|
||||
// Only the last message computed reasoning_text
|
||||
const reasoningText = index === messages.length - 1 ? item.reasoning_text || '' : '';
|
||||
|
||||
return (
|
||||
sum +
|
||||
countPromptTokens(`${reasoningText}${contentPrompt}${functionCallPrompt}`, item.role)
|
||||
);
|
||||
}, 0) +
|
||||
countToolsTokens(tools) +
|
||||
countToolsTokens(functionCall);
|
||||
|
||||
@@ -56,14 +56,15 @@ export const readPdfFile = async ({ buffer }: ReadRawTextByBuffer): Promise<Read
|
||||
}
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
const loadingTask = pdfjs.getDocument(buffer.buffer);
|
||||
const doc = await loadingTask.promise;
|
||||
|
||||
// Avoid OOM.
|
||||
let result = '';
|
||||
const pageArr = Array.from({ length: doc.numPages }, (_, i) => i + 1);
|
||||
for await (const pageNo of pageArr) {
|
||||
result += await readPDFPage(doc, pageNo);
|
||||
for (let i = 0; i < pageArr.length; i++) {
|
||||
result += await readPDFPage(doc, i + 1);
|
||||
}
|
||||
|
||||
loadingTask.destroy();
|
||||
|
||||
@@ -120,7 +120,7 @@ export class WorkerPool<Props = Record<string, any>, Response = any> {
|
||||
|
||||
run(data: Props) {
|
||||
// watch memory
|
||||
addLog.debug(`${this.name} worker queueLength: ${this.workerQueue.length}`);
|
||||
// addLog.debug(`${this.name} worker queueLength: ${this.workerQueue.length}`);
|
||||
|
||||
return new Promise<Response>((resolve, reject) => {
|
||||
/*
|
||||
|
||||
@@ -7,7 +7,12 @@ import { AppTemplateSchemaType } from '@fastgpt/global/core/app/type';
|
||||
|
||||
const getTemplateNameList = () => {
|
||||
const currentFileUrl = new URL(import.meta.url);
|
||||
const templatesPath = path.join(path.dirname(currentFileUrl.pathname), 'src');
|
||||
const filePath = decodeURIComponent(
|
||||
process.platform === 'win32'
|
||||
? currentFileUrl.pathname.substring(1) // Remove leading slash on Windows
|
||||
: currentFileUrl.pathname
|
||||
);
|
||||
const templatesPath = path.join(path.dirname(filePath), 'src');
|
||||
|
||||
return fs.readdirSync(templatesPath) as string[];
|
||||
};
|
||||
|
||||
@@ -1,23 +1,31 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import React, { useState } from 'react';
|
||||
import { Box, Tbody } from '@chakra-ui/react';
|
||||
import React, { ReactElement, ReactNode, useState } from 'react';
|
||||
import {
|
||||
DragDropContext,
|
||||
DroppableProps,
|
||||
Droppable,
|
||||
DraggableChildrenFn,
|
||||
DragStart,
|
||||
DropResult
|
||||
DropResult,
|
||||
DroppableProvided,
|
||||
DroppableStateSnapshot
|
||||
} from 'react-beautiful-dnd';
|
||||
export * from 'react-beautiful-dnd';
|
||||
|
||||
type Props<T = any> = {
|
||||
onDragEndCb: (result: T[]) => void;
|
||||
renderClone?: DraggableChildrenFn;
|
||||
children: DroppableProps['children'];
|
||||
children: ({
|
||||
provided,
|
||||
snapshot
|
||||
}: {
|
||||
provided: DroppableProvided;
|
||||
snapshot: DroppableStateSnapshot;
|
||||
}) => ReactElement<HTMLElement, string>;
|
||||
dataList: T[];
|
||||
zoom?: number;
|
||||
};
|
||||
|
||||
function DndDrag<T>({ children, renderClone, onDragEndCb, dataList }: Props<T>) {
|
||||
function DndDrag<T>({ children, renderClone, onDragEndCb, dataList, zoom = 1 }: Props<T>) {
|
||||
const [draggingItemHeight, setDraggingItemHeight] = useState(0);
|
||||
|
||||
const onDragStart = (start: DragStart) => {
|
||||
@@ -44,14 +52,12 @@ function DndDrag<T>({ children, renderClone, onDragEndCb, dataList }: Props<T>)
|
||||
return (
|
||||
<DragDropContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
||||
<Droppable droppableId="droppable" renderClone={renderClone}>
|
||||
{(provided, snapshot) => {
|
||||
return (
|
||||
<Box {...provided.droppableProps} ref={provided.innerRef}>
|
||||
{children(provided, snapshot)}
|
||||
{snapshot.isDraggingOver && <Box height={`${draggingItemHeight}px`} />}
|
||||
</Box>
|
||||
);
|
||||
}}
|
||||
{(provided, snapshot) => (
|
||||
<>
|
||||
{children({ provided, snapshot })}
|
||||
{snapshot.isDraggingOver && <Box height={`${draggingItemHeight / zoom}px`} />}
|
||||
</>
|
||||
)}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
);
|
||||
|
||||
@@ -389,6 +389,7 @@ export const iconPaths = {
|
||||
'model/openai': () => import('./icons/model/openai.svg'),
|
||||
'model/qwen': () => import('./icons/model/qwen.svg'),
|
||||
'model/siliconflow': () => import('./icons/model/siliconflow.svg'),
|
||||
'model/ppio': () => import('./icons/model/ppio.svg'),
|
||||
'model/sparkDesk': () => import('./icons/model/sparkDesk.svg'),
|
||||
'model/stepfun': () => import('./icons/model/stepfun.svg'),
|
||||
'model/yi': () => import('./icons/model/yi.svg'),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<svg t="1705054369902" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3174"
|
||||
width="128" height="128">
|
||||
<path
|
||||
d="M512 0C229.205333 0 0 229.205333 0 512s229.205333 512 512 512 512-229.205333 512-512S794.794667 0 512 0z m0 796.458667A56.917333 56.917333 0 1 1 511.957333 682.666667 56.917333 56.917333 0 0 1 512 796.458667z m54.186667-227.797334h0.128a60.501333 60.501333 0 0 1-53.802667 55.893334c2.048 0.256 3.882667 1.152 5.973333 1.152h-11.818666c2.048 0 3.84-0.981333 5.845333-1.109334a59.093333 59.093333 0 0 1-53.162667-55.893333l-13.056-284.16a54.314667 54.314667 0 0 1 54.613334-57.045333h26.282666a52.992 52.992 0 0 1 54.186667 57.002666l-15.146667 284.16z"
|
||||
fill="#D92D20" p-id="3175"></path>
|
||||
</svg>
|
||||
<svg viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.187134" width="16" height="16" rx="8" fill="#F04438"/>
|
||||
<path d="M8.18717 4.78638C7.81898 4.78638 7.52051 5.08485 7.52051 5.45304V8.44501C7.52051 8.8132 7.81898 9.11168 8.18717 9.11168C8.55536 9.11168 8.85384 8.8132 8.85384 8.44501V5.45304C8.85384 5.08485 8.55536 4.78638 8.18717 4.78638Z" fill="white"/>
|
||||
<path d="M8.18717 9.76652C7.81898 9.76652 7.52051 10.065 7.52051 10.4332C7.52051 10.8014 7.81898 11.0998 8.18717 11.0998C8.55536 11.0998 8.85384 10.8014 8.85384 10.4332C8.85384 10.065 8.55536 9.76652 8.18717 9.76652Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 774 B After Width: | Height: | Size: 628 B |
3
packages/web/components/common/Icon/icons/model/ppio.svg
Normal file
3
packages/web/components/common/Icon/icons/model/ppio.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M49.6479 0.359833C22.2415 0.359833 0 22.5703 0 49.9767C0 63.4861 5.41303 75.7546 14.1918 84.7039V50.0233C14.1918 40.5621 17.8832 31.6283 24.568 24.9434C31.2839 18.2275 40.1867 14.5671 49.6634 14.5671H49.9581L49.6479 14.5981C69.2372 14.5981 85.1196 30.4805 85.1196 50.0543C85.1196 51.7604 84.9955 53.4355 84.7628 55.0951L64.7238 34.9939C60.7221 30.9923 55.3556 28.7744 49.6789 28.7744C44.0022 28.7744 38.6512 30.9923 34.6341 34.9939C30.6015 39.0266 28.399 44.3621 28.399 50.0543C28.399 55.7465 30.617 61.082 34.6341 65.1146C38.6357 69.1162 44.0022 71.3342 49.6789 71.3342C55.3556 71.3342 60.7066 69.1162 64.7238 65.1146C68.4617 61.3767 70.6176 56.491 70.9123 51.2641L82.669 63.0673C77.4731 76.2199 64.6617 85.5415 49.6634 85.5415C41.8929 85.5415 34.479 83.0598 28.3835 78.4533V94.863C34.8357 97.934 42.0324 99.6402 49.6324 99.6402C77.0388 99.6402 99.2803 77.4297 99.2803 50.0233C99.3113 22.5858 77.0853 0.375343 49.6634 0.375343L49.6479 0.359833Z" fill="#0062E2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1,17 +1,17 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import type { IconProps } from '@chakra-ui/react';
|
||||
import { Box, Icon } from '@chakra-ui/react';
|
||||
import { iconPaths } from './constants';
|
||||
import type { IconNameType } from './type.d';
|
||||
import { useRefresh } from '../../../hooks/useRefresh';
|
||||
|
||||
const iconCache: Record<string, any> = {};
|
||||
|
||||
const MyIcon = ({ name, w = 'auto', h = 'auto', ...props }: { name: IconNameType } & IconProps) => {
|
||||
const [IconComponent, setIconComponent] = useState<any>(null);
|
||||
const { refresh } = useRefresh();
|
||||
|
||||
useEffect(() => {
|
||||
if (iconCache[name]) {
|
||||
setIconComponent(iconCache[name]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -20,11 +20,13 @@ const MyIcon = ({ name, w = 'auto', h = 'auto', ...props }: { name: IconNameType
|
||||
const component = { as: icon.default };
|
||||
// Store in cache
|
||||
iconCache[name] = component;
|
||||
setIconComponent(component);
|
||||
refresh();
|
||||
})
|
||||
.catch((error) => console.log(error));
|
||||
}, [name]);
|
||||
|
||||
const IconComponent = iconCache[name];
|
||||
|
||||
return !!IconComponent ? (
|
||||
<Icon
|
||||
{...IconComponent}
|
||||
@@ -40,4 +42,4 @@ const MyIcon = ({ name, w = 'auto', h = 'auto', ...props }: { name: IconNameType
|
||||
);
|
||||
};
|
||||
|
||||
export default MyIcon;
|
||||
export default React.memo(MyIcon);
|
||||
|
||||
@@ -27,7 +27,7 @@ const InputSlider = ({
|
||||
valLen * 0.8 + min,
|
||||
valLen * 0.985 + min
|
||||
];
|
||||
}, []);
|
||||
}, [max, min]);
|
||||
|
||||
return (
|
||||
<HStack zIndex={10} spacing={3}>
|
||||
|
||||
@@ -66,12 +66,6 @@ const NodeInputSelect = ({
|
||||
|
||||
title: t('common:core.workflow.inputType.dynamicTargetInput')
|
||||
},
|
||||
{
|
||||
type: FlowNodeInputTypeEnum.selectApp,
|
||||
icon: FlowNodeInputMap[FlowNodeInputTypeEnum.selectApp].icon,
|
||||
|
||||
title: t('common:core.workflow.inputType.Manual select')
|
||||
},
|
||||
{
|
||||
type: FlowNodeInputTypeEnum.selectLLMModel,
|
||||
icon: FlowNodeInputMap[FlowNodeInputTypeEnum.selectLLMModel].icon,
|
||||
|
||||
@@ -53,7 +53,7 @@ export function usePagination<DataT, ResT = {}>(
|
||||
const isEmpty = total === 0 && !isLoading;
|
||||
const noMore = data.length >= totalDataLength;
|
||||
|
||||
const fetchData = useLockFn(
|
||||
const fetchData = useMemoizedFn(
|
||||
async (num: number = pageNum, ScrollContainerRef?: RefObject<HTMLDivElement>) => {
|
||||
if (noMore && num !== 1) return;
|
||||
setTrue();
|
||||
@@ -99,11 +99,12 @@ export function usePagination<DataT, ResT = {}>(
|
||||
|
||||
onChange?.(num);
|
||||
} catch (error: any) {
|
||||
toast({
|
||||
title: getErrText(error, t('common:core.chat.error.data_error')),
|
||||
status: 'error'
|
||||
});
|
||||
console.log(error);
|
||||
if (error.code !== 'ERR_CANCELED') {
|
||||
toast({
|
||||
title: getErrText(error, t('common:core.chat.error.data_error')),
|
||||
status: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setFalse();
|
||||
@@ -246,7 +247,6 @@ export function usePagination<DataT, ResT = {}>(
|
||||
// Reload data
|
||||
const { runAsync: refresh } = useRequest(
|
||||
async () => {
|
||||
setData([]);
|
||||
defaultRequest && fetchData(1);
|
||||
},
|
||||
{
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
"model.max_temperature": "Max temperature",
|
||||
"model.model_id": "Model ID",
|
||||
"model.model_id_tip": "The unique identifier of the model, that is, the value of the actual request to the service provider model, needs to correspond to the model in the OneAPI channel.",
|
||||
"model.normalization": "Normalization processing",
|
||||
"model.normalization_tip": "If the Embedding API does not normalize vector values, the switch can be enabled and the system will normalize.\n\nUnnormalized APIs, which are represented by the vector search score greater than 1.",
|
||||
"model.output_price": "Output price",
|
||||
"model.output_price_tip": "The language model output price. If this item is configured, the model comprehensive price will be invalid.",
|
||||
"model.param_name": "Parameter name",
|
||||
@@ -55,6 +57,9 @@
|
||||
"model.request_auth_tip": "When making a request to a custom request address, carry the request header: Authorization: Bearer xxx to make the request.",
|
||||
"model.request_url": "Custom url",
|
||||
"model.request_url_tip": "If you fill in this value, you will initiate a request directly without passing. \nYou need to follow the API format of Openai and fill in the full request address, such as\n\nLLM: {Host}}/v1/Chat/Completions\n\nEmbedding: {host}}/v1/embeddings\n\nSTT: {Host}/v1/Audio/Transcriptions\n\nTTS: {Host}}/v1/Audio/Speech\n\nRERARARARARARARANK: {Host}}/v1/RERARARARARARARARARARANK",
|
||||
"model.response_format": "Response format",
|
||||
"model.show_stop_sign": "Display stop sequence parameters",
|
||||
"model.show_top_p": "Show Top-p parameters",
|
||||
"model.test_model": "Model testing",
|
||||
"model.tool_choice": "Tool choice",
|
||||
"model.tool_choice_tag": "ToolCall",
|
||||
|
||||
@@ -7,8 +7,12 @@
|
||||
"ai_settings": "AI Configuration",
|
||||
"all_apps": "All Applications",
|
||||
"app.Version name": "Version Name",
|
||||
"app.error.publish_unExist_app": "Release failed, please check whether the tool call is normal",
|
||||
"app.error.unExist_app": "Some components are missing, please delete them",
|
||||
"app.modules.click to update": "Click to Refresh",
|
||||
"app.modules.has new version": "New Version Available",
|
||||
"app.modules.not_found": "Not Found",
|
||||
"app.modules.not_found_tips": "This component cannot be found in the system, please delete it, otherwise the process will not run normally",
|
||||
"app.version_current": "Current Version",
|
||||
"app.version_initial": "Initial Version",
|
||||
"app.version_name_tips": "Version name cannot be empty",
|
||||
@@ -77,7 +81,10 @@
|
||||
"llm_use_vision_tip": "After clicking on the model selection, you can see whether the model supports image recognition and the ability to control whether to start image recognition. \nAfter starting image recognition, the model will read the image content in the file link, and if the user question is less than 500 words, it will automatically parse the image in the user question.",
|
||||
"logs_chat_user": "user",
|
||||
"logs_empty": "No logs yet~",
|
||||
"logs_export_confirm_tip": "There are a total of {{total}} dialogue records, confirm the export?",
|
||||
"logs_export_title": "Time, source, user, title, total number of messages, user feedback, custom feedback, number of labeled answers, conversation details",
|
||||
"logs_message_total": "Total Messages",
|
||||
"logs_source": "source",
|
||||
"logs_title": "Title",
|
||||
"look_ai_point_price": "View all model billing standards",
|
||||
"mark_count": "Number of Marked Answers",
|
||||
@@ -110,12 +117,16 @@
|
||||
"publish_success": "Publish Successful",
|
||||
"question_guide_tip": "After the conversation, 3 guiding questions will be generated for you.",
|
||||
"reasoning_response": "Output thinking",
|
||||
"response_format": "Response format",
|
||||
"saved_success": "Saved successfully! \nTo use this version externally, click Save and Publish",
|
||||
"search_app": "Search apps",
|
||||
"setting_app": "Workflow",
|
||||
"setting_plugin": "Workflow",
|
||||
"show_top_p_tip": "An alternative method of temperature sampling, called Nucleus sampling, the model considers the results of tokens with TOP_P probability mass quality. \nTherefore, 0.1 means that only tokens containing the highest probability quality are considered. \nThe default is 1.",
|
||||
"simple_tool_tips": "This plugin contains special inputs and is not currently supported for invocation by simple applications.",
|
||||
"source_updateTime": "Update time",
|
||||
"stop_sign": "Stop",
|
||||
"stop_sign_placeholder": "Multiple serial numbers are separated by |, for example: aaa|stop",
|
||||
"stream_response": "Stream",
|
||||
"stream_response_tip": "Turning this switch off forces the model to use non-streaming mode and will not output content directly. \nIn the output of the AI reply, the content output by this model can be obtained for secondary processing.",
|
||||
"temperature": "Temperature",
|
||||
|
||||
@@ -37,7 +37,10 @@
|
||||
"not_query": "Missing query content",
|
||||
"not_select_file": "No file selected",
|
||||
"plugins_output": "Plugin Output",
|
||||
"query_extension_IO_tokens": "Problem Optimization Input/Output Tokens",
|
||||
"query_extension_result": "Problem optimization results",
|
||||
"question_tip": "From top to bottom, the response order of each module",
|
||||
"reasoning_text": "Thinking process",
|
||||
"response.child total points": "Sub-workflow point consumption",
|
||||
"response.dataset_concat_length": "Combined total",
|
||||
"response.node_inputs": "Node Inputs",
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
"Move": "Move",
|
||||
"Name": "Name",
|
||||
"None": "None",
|
||||
"Operation": "Operation",
|
||||
"Rename": "Rename",
|
||||
"Required_input": "Required",
|
||||
"Resume": "Resume",
|
||||
"Running": "Running",
|
||||
"Select_all": "Select all",
|
||||
@@ -165,7 +167,6 @@
|
||||
"common.Not open": "Not Open",
|
||||
"common.OK": "OK",
|
||||
"common.Open": "Open",
|
||||
"common.Operation": "Operation",
|
||||
"common.Other": "Other",
|
||||
"common.Output": "Output",
|
||||
"common.Params": "Parameters",
|
||||
@@ -179,7 +180,6 @@
|
||||
"common.Remove": "Remove",
|
||||
"common.Rename": "Rename",
|
||||
"common.Request Error": "Request Error",
|
||||
"common.Require Input": "Required",
|
||||
"common.Reset": "Reset",
|
||||
"common.Restart": "Restart",
|
||||
"common.Role": "Permission",
|
||||
@@ -369,7 +369,7 @@
|
||||
"core.app.tip.Add a intro to app": "Give the app an introduction",
|
||||
"core.app.tip.chatNodeSystemPromptTip": "Enter a prompt here",
|
||||
"core.app.tip.systemPromptTip": "Fixed guide words for the model. By adjusting this content, you can guide the model's chat direction. This content will be fixed at the beginning of the context. You can use / to insert variables.\nIf a Dataset is associated, you can also guide the model when to call the Dataset search by appropriate description. For example:\nYou are an assistant for the movie 'Interstellar'. When users ask about content related to 'Interstellar', please search the Dataset and answer based on the search results.",
|
||||
"core.app.tip.variableTip": "Before the conversation starts, you can ask the user to fill in some content as specific variables for this round of conversation. This module is located after the opening guide.\nVariables can be injected into other modules' string type inputs in the form of {{variable key}}, such as prompts, delimiters, etc.",
|
||||
"core.app.tip.variableTip": "Before the conversation begins, users can be asked to fill in some content as specific variables for this round of conversation. \nThis module is located after the opening boot.\n\nIn the input box, you can select variables through / activation, such as: prompt words, qualifiers, etc.",
|
||||
"core.app.tip.welcomeTextTip": "Before each conversation starts, send an initial content. Supports standard Markdown syntax. Additional tags that can be used:\n[Quick Key]: Users can directly send the question by clicking",
|
||||
"core.app.tool_label.doc": "Documentation",
|
||||
"core.app.tool_label.github": "GitHub Address",
|
||||
@@ -448,6 +448,7 @@
|
||||
"core.chat.markdown.Edit Question": "Edit Question",
|
||||
"core.chat.markdown.Quick Question": "Click to Ask Immediately",
|
||||
"core.chat.markdown.Send Question": "Send Question",
|
||||
"core.chat.module_unexist": "Running failed: Application missing components",
|
||||
"core.chat.quote.Quote Tip": "Only the actual quoted content is displayed here. If the data is updated, it will not be updated in real-time here.",
|
||||
"core.chat.quote.Read Quote": "View Quote",
|
||||
"core.chat.response.Complete Response": "Complete Response",
|
||||
@@ -787,7 +788,7 @@
|
||||
"core.view_chat_detail": "View Chat Details",
|
||||
"core.workflow.Can not delete node": "This Node Cannot Be Deleted",
|
||||
"core.workflow.Change input type tip": "Changing the input type will clear the filled values, please confirm!",
|
||||
"core.workflow.Check Failed": "Workflow Validation Failed, Please Check If the Nodes Are Correctly Filled and the Connections Are Normal",
|
||||
"core.workflow.Check Failed": "Workflow verification failed, please check whether the value is missing, and whether the connection is normal.",
|
||||
"core.workflow.Confirm stop debug": "Confirm to Stop Debugging? Debug Information Will Not Be Retained.",
|
||||
"core.workflow.Copy node": "Node Copied",
|
||||
"core.workflow.Custom inputs": "Custom Inputs",
|
||||
@@ -875,13 +876,16 @@
|
||||
"dataset.dataset_name": "Dataset Name",
|
||||
"dataset.deleteFolderTips": "Confirm to Delete This Folder and All Its Contained Datasets? Data Cannot Be Recovered After Deletion, Please Confirm!",
|
||||
"dataset.test.noResult": "No Search Results",
|
||||
"deep_rag_search": "In-depth search",
|
||||
"delete_api": "Are you sure you want to delete this API key? \nAfter deletion, the key will become invalid immediately and the corresponding conversation log will not be deleted. Please confirm!",
|
||||
"embedding_model_not_config": "No index model is detected",
|
||||
"error.Create failed": "Create failed",
|
||||
"error.code_error": "Verification code error",
|
||||
"error.fileNotFound": "File not found~",
|
||||
"error.inheritPermissionError": "Inherit permission Error",
|
||||
"error.invalid_params": "Invalid parameter",
|
||||
"error.missingParams": "Insufficient parameters",
|
||||
"error.send_auth_code_too_frequently": "Please do not obtain verification code frequently",
|
||||
"error.too_many_request": "Too many request",
|
||||
"error.upload_file_error_filename": "{{name}} Upload Failed",
|
||||
"error.upload_image_error": "File upload failed",
|
||||
@@ -911,6 +915,7 @@
|
||||
"item_name": "Field Name",
|
||||
"just_now": "just",
|
||||
"key_repetition": "Key Repetition",
|
||||
"llm_model_not_config": "No language model was detected",
|
||||
"max_quote_tokens": "Quote cap",
|
||||
"max_quote_tokens_tips": "The maximum number of tokens in a single search, about 1 character in Chinese = 1.7 tokens, and about 1 character in English = 1 token",
|
||||
"min_similarity": "lowest correlation",
|
||||
@@ -936,6 +941,7 @@
|
||||
"model_moka": "Moka-AI",
|
||||
"model_moonshot": "Moonshot",
|
||||
"model_other": "Other",
|
||||
"model_ppio": "PPIO",
|
||||
"model_qwen": "Qwen",
|
||||
"model_siliconflow": "Siliconflow",
|
||||
"model_sparkdesk": "SprkDesk",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"Chinese_ip_tip": "It is detected that you are a mainland Chinese IP, click to jump to visit the mainland China version.",
|
||||
"Login": "Login",
|
||||
"agree": "agree",
|
||||
"cookies_tip": " This website uses cookies to provide a better service experience. By continuing to use the site, you agree to our Cookie Policy.",
|
||||
"forget_password": "Find Password",
|
||||
"login_failed": "Login failed",
|
||||
"login_success": "Login successful",
|
||||
@@ -9,12 +11,10 @@
|
||||
"password_tip": "Password must be at least 6 characters long and contain at least two combinations: numbers, letters, or special characters",
|
||||
"policy_tip": "By using this service, you agree to our",
|
||||
"privacy": "Privacy Policy",
|
||||
"privacy_policy": "Privacy Policy",
|
||||
"redirect": "Jump",
|
||||
"register": "Register",
|
||||
"root_password_placeholder": "The root user password is the value of the environment variable DEFAULT_ROOT_PSW",
|
||||
"terms": "Terms",
|
||||
"use_root_login": "Log in as root user",
|
||||
"agree": "agree",
|
||||
"cookies_tip": " This website uses cookies to provide a better service experience. By continuing to use the site, you agree to our Cookie Policy.",
|
||||
"privacy_policy": "Privacy Policy"
|
||||
"use_root_login": "Log in as root user"
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
"quote_role_system_tip": "Please note that the {{question}} variable is removed from the \"Quote Template Prompt Words\"",
|
||||
"quote_role_user_tip": "Please pay attention to adding the {{question}} variable in the \"Quote Template Prompt Word\"",
|
||||
"raw_response": "Raw Response",
|
||||
"reasoning_text": "Thinking text",
|
||||
"regex": "Regex",
|
||||
"reply_text": "Reply Text",
|
||||
"request_error": "Request Error",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user