Compare commits
71 Commits
v4.8.10-al
...
v4.8.10-fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08190c2f0d | ||
|
|
6a85c8c2b6 | ||
|
|
bbdab1d40e | ||
|
|
78ad2791cd | ||
|
|
5f3c8e9046 | ||
|
|
30057f01a6 | ||
|
|
3ea185315d | ||
|
|
a1ae08f62b | ||
|
|
91ec895fd2 | ||
|
|
1a33642635 | ||
|
|
e9681c8ed5 | ||
|
|
69ff65973f | ||
|
|
52ac445557 | ||
|
|
d45cb2f84a | ||
|
|
1cb71c6bfb | ||
|
|
fb59b60761 | ||
|
|
9334a0dcf6 | ||
|
|
c614f8b9ca | ||
|
|
478386c612 | ||
|
|
dfcffc7fc1 | ||
|
|
b4238257b6 | ||
|
|
38f47956cd | ||
|
|
7fed4d697f | ||
|
|
5ed89130ef | ||
|
|
3671e55001 | ||
|
|
3bcc3430fb | ||
|
|
d6233cd7b1 | ||
|
|
64708ea424 | ||
|
|
85a11d08b2 | ||
|
|
a7569037fe | ||
|
|
4726034344 | ||
|
|
9a57e94b79 | ||
|
|
761e35c226 | ||
|
|
5ebe0017a0 | ||
|
|
036097243a | ||
|
|
84de95d294 | ||
|
|
fdab383b26 | ||
|
|
060492dbf7 | ||
|
|
9d5fd24085 | ||
|
|
903f39fe17 | ||
|
|
2ef98c24be | ||
|
|
6d00f73e91 | ||
|
|
813eaacfd0 | ||
|
|
322ca757af | ||
|
|
a177a302d4 | ||
|
|
034108c218 | ||
|
|
0632dfed80 | ||
|
|
6c16fa9166 | ||
|
|
ac4854a47b | ||
|
|
b9a6b71fe9 | ||
|
|
aba50e958e | ||
|
|
52cbfeace3 | ||
|
|
bebf565c06 | ||
|
|
c9bb39d802 | ||
|
|
454a479fd8 | ||
|
|
d057ad3a45 | ||
|
|
a206d77287 | ||
|
|
14bd1b5404 | ||
|
|
450167c951 | ||
|
|
67445b40bc | ||
|
|
d3731d221a | ||
|
|
f6e2d13e21 | ||
|
|
77e6cf4157 | ||
|
|
fd3f32d083 | ||
|
|
f7544ea47b | ||
|
|
a1a9a0b463 | ||
|
|
dbfe1fca31 | ||
|
|
94f3b7f2d6 | ||
|
|
22a0f6bcfa | ||
|
|
c1d08c0ccc | ||
|
|
a4c19fbd0a |
BIN
.github/imgs/intro1.png
vendored
|
Before Width: | Height: | Size: 259 KiB After Width: | Height: | Size: 173 KiB |
BIN
.github/imgs/intro2.png
vendored
|
Before Width: | Height: | Size: 371 KiB After Width: | Height: | Size: 273 KiB |
BIN
.github/imgs/intro3.png
vendored
|
Before Width: | Height: | Size: 259 KiB After Width: | Height: | Size: 168 KiB |
BIN
.github/imgs/intro4.png
vendored
|
Before Width: | Height: | Size: 228 KiB After Width: | Height: | Size: 159 KiB |
2
.vscode/settings.json
vendored
@@ -13,7 +13,7 @@
|
||||
"js",
|
||||
"ts"
|
||||
],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.keystyle": "flat",
|
||||
"i18n-ally.sortKeys": true,
|
||||
"i18n-ally.keepFulfilled": false,
|
||||
"i18n-ally.sourceLanguage": "zh", // 根据此语言文件翻译其他语言文件的变量和内容
|
||||
|
||||
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 215 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 299 KiB After Width: | Height: | Size: 298 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 158 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 209 KiB After Width: | Height: | Size: 119 KiB |
@@ -86,3 +86,12 @@ Verification Token 默认生成的这个 Token 用于校验来源。但我们使
|
||||
然后就可以在工作台里找到你的机器人啦。接下来就是把机器人拉进群组,或者单独与它对话。
|
||||
|
||||

|
||||
|
||||
## FAQ
|
||||
|
||||
### 发送了消息,没响应
|
||||
|
||||
1. 检查飞书机器人回调地址、权限等是否正确。
|
||||
2. 查看 FastGPT 对话日志,是否有对应的提问记录
|
||||
3. 如果有记录,飞书没回应,则是没给机器人开权限。
|
||||
4. 如果没记录,则可能是应用运行报错了,可以先试试最简单的机器人。(飞书机器人无法输入全局变量、文件、图片内容)
|
||||
@@ -62,6 +62,23 @@ weight: 113
|
||||
34.142.157.52
|
||||
```
|
||||
|
||||
国内版用户(fastgpt.cn)可以填写下面的 IP 白名单:
|
||||
|
||||
```
|
||||
47.97.59.172
|
||||
121.43.108.48
|
||||
121.41.75.88
|
||||
121.41.178.7
|
||||
121.40.65.187
|
||||
121.196.235.183
|
||||
120.55.195.90
|
||||
120.55.193.112
|
||||
120.26.229.115
|
||||
112.124.41.79
|
||||
101.37.205.32
|
||||
47.98.190.173
|
||||
```
|
||||
|
||||
## 4. 获取AES Key,选择加密方式
|
||||
|
||||

|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: 'V4.8.10(进行中)'
|
||||
title: 'V4.8.10'
|
||||
description: 'FastGPT V4.8.10 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
@@ -11,37 +11,94 @@ weight: 814
|
||||
|
||||
### 1. 做好数据备份
|
||||
|
||||
### 2. 更新商业版环境变量
|
||||
|
||||
### 2. 商业版 —— 修改环境变量
|
||||
|
||||
1. 需要给`fastgpt-pro`镜像,增加沙盒的环境变量:`SANDBOX_URL=http://xxxxx:3000`
|
||||
2. 给两个镜像增加环境变量,以便更好的存储系统日志:
|
||||
2. 给`fastgpt-pro`镜像和`fastgpt`镜像增加环境变量,以便更好的存储系统日志:
|
||||
|
||||
```
|
||||
LOG_LEVEL=debug
|
||||
STORE_LOG_LEVEL=warn
|
||||
```
|
||||
|
||||
### 3. 修改镜像tag
|
||||
|
||||
- 更新 FastGPT 镜像 tag: v4.8.10
|
||||
- 更新 FastGPT 商业版镜像 tag: v4.8.10
|
||||
- Sandbox 镜像,可以不更新
|
||||
|
||||
## 4. 执行初始化
|
||||
|
||||
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`;{{host}} 替换成**FastGPT 域名**。
|
||||
|
||||
```bash
|
||||
curl --location --request POST 'https://{{host}}/api/admin/initv4810' \
|
||||
--header 'rootkey: {{rootkey}}' \
|
||||
--header 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
1. 初始化发布记录版本标记
|
||||
2. 初始化开票记录
|
||||
|
||||
-------
|
||||
|
||||
## V4.8.10 更新说明
|
||||
|
||||
1. 新增 - 模板市场
|
||||
2. 新增 - 工作流节点拖动自动对齐吸附
|
||||
3. 新增 - 用户选择节点(Debug 模式暂未支持)
|
||||
4. 新增 - 工作流撤销和重做
|
||||
5. 新增 - 工作流本次编辑记录,取代自动保存
|
||||
6. 新增 - 工作流版本支持重命名
|
||||
7. 商业版新增 - 飞书机器人接入
|
||||
8. 商业版新增 - 公众号接入接入
|
||||
9. 商业版新增 - 自助开票申请
|
||||
10. 商业版新增 - SSO 定制
|
||||
11. 优化 - 知识库集合禁用,目录禁用会递归修改其下所有 children 的禁用状态。
|
||||
12. 优化 - 节点选择,避免切换 tab 时候,path 加载报错。
|
||||
13. 优化 - 最新 React Markdown 组件,支持 Base64 图片。
|
||||
14. 优化 - 知识库列表 UI。
|
||||
15. 优化 - 支持无网络配置情况下运行。
|
||||
16. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
|
||||
17. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
|
||||
18. 修复 - 选择 Milvus 部署时,无法导出知识库。
|
||||
19. 修复 - 创建 APP 副本,无法复制系统配置。
|
||||
20. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
|
||||
完整内容请见:[4.8.10 release](https://github.com/labring/FastGPT/releases/tag/v4.8.10)
|
||||
|
||||
1. 新增 - 模板市场。
|
||||
2. 新增 - 工作流节点拖动自动对齐吸附。
|
||||
3. 新增 - 用户选择节点(Debug 模式暂未支持)。
|
||||
4. 新增 - 工作流增加 uid 全局变量。
|
||||
5. 新增 - 工作流撤销和重做。
|
||||
6. 新增 - 工作流本次编辑记录,取代自动保存。
|
||||
7. 新增 - 工作流版本支持重命名。
|
||||
8. 新增 - 工作流的“应用调用”节点弃用,迁移成单独节点,与插件使用方式相同,同时可以传递全局变量和用户上传的文件。
|
||||
9. 新增 - 插件增加使用说明配置。
|
||||
10. 新增 - 插件自定义输入支持单选框。
|
||||
11. 新增 - HTTP 节点支持 text/plain 模式。
|
||||
12. 新增 - HTTP模块支持超时配置、支持更多的 Body 类型,params 和 headers 支持新的变量选择模式。
|
||||
13. 新增 - 工作流导出导入,支持直接导出和导入 JSON 文件,便于交流。
|
||||
14. 新增 - 发送验证码安全校验。
|
||||
15. 商业版新增 - 飞书机器人接入。
|
||||
16. 商业版新增 - 公众号接入接入。
|
||||
17. 商业版新增 - 自助开票申请。
|
||||
18. 商业版新增 - SSO 定制。
|
||||
19. 优化 - 工作流循环校验,避免 skip 循环空转。同时支持分支完全并发执行。
|
||||
20. 优化 - 工作流嵌套执行,参数可能存在的污染问题。
|
||||
21. 优化 - 部分全局变量,增加数据类型约束。
|
||||
22. 优化 - 节点选择,避免切换 tab 时候,path 加载报错。
|
||||
23. 优化 - 最新 React Markdown 组件,支持 Base64 图片。
|
||||
24. 优化 - 对话框性能问题。
|
||||
25. 优化 - 单选框打开后自动滚动到选中的位置。
|
||||
26. 优化 - 知识库集合禁用,目录禁用会递归修改其下所有 children 的禁用状态。
|
||||
27. 优化 - SSE 响应代码优化。
|
||||
28. 优化 - 无 SSL 证书情况下,优化复制。
|
||||
29. 优化 - 知识库列表 UI。
|
||||
30. 优化 - 知识库详情页 UI。
|
||||
31. 优化 - 支持无网络配置情况下运行。
|
||||
32. 优化 - 调整.env.template关于mongodb的说明,使得更易于理解。
|
||||
33. 优化 - 新的支付模式。
|
||||
34. 优化 - 用户默认头像。
|
||||
35. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
|
||||
36. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
|
||||
37. 修复 - 选择 Milvus 部署时,无法导出知识库。
|
||||
38. 修复 - 创建 APP 副本,无法复制系统配置。
|
||||
39. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
|
||||
40. 修复 - 内容提取的数据类型与输出数据类型未一致。
|
||||
41. 修复 - 工作流运行时间统计错误。
|
||||
42. 修复 - stream 模式下,工具调用有可能出现 undefined。
|
||||
43. 修复 - reranker typo。
|
||||
44. 修复 - home host typo。
|
||||
45. 修复 - i18n display。
|
||||
46. 修复 - 全局变量可重复定义 key。
|
||||
47. 修复 - 全局变量在 Debug 模式下不可持久化。
|
||||
48. 修复 - 全局变量在 API 中无法持久化。
|
||||
49. 修复 - OpenAPI,detail=false模式下,不应该返回 tool 调用结果,仅返回文字。(可解决 cow 不适配问题)。
|
||||
50. 修复 - 知识库标签重复加载。
|
||||
51. 修复 - 网络链接重新获取时,自定义分割符不生效。
|
||||
52. 修复 - 插件运行时,会传递额外的全局变量,可能造成插件内变量污染。
|
||||
53. 文档 - qa docs。
|
||||
54. 文档 - Update feishu.md。
|
||||
55. 文档 - update baseURL。
|
||||
|
||||
24
docSite/content/zh-cn/docs/development/upgrading/4811.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: 'V4.8.11(进行中)'
|
||||
description: 'FastGPT V4.8.11 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 813
|
||||
---
|
||||
|
||||
## 更新指南
|
||||
|
||||
### 1. 做好数据备份
|
||||
|
||||
-------
|
||||
|
||||
## V4.8.11 更新预告
|
||||
|
||||
1.
|
||||
2. 新增 - 工作流循环执行节点。
|
||||
3. 新增 - 工作流用户表单输入节点。
|
||||
4. 新增 - 插件输出,支持指定某些字段为工具调用结果。
|
||||
5. 新增 - 插件支持配置使用引导、全局变量和文件输入。
|
||||
6. 新增 - 简易模式支持新的版本管理方式。
|
||||
7. 新增 - 聊天记录滚动加载,不再只加载 30 条。
|
||||
@@ -1,4 +1,4 @@
|
||||
baseURL = "https://doc.fastgpt.in"
|
||||
baseURL = "https://doc.tryfastgpt.ai"
|
||||
languageCode = "en-GB"
|
||||
contentDir = "content"
|
||||
enableEmoji = true
|
||||
|
||||
0
fastgpt@4.0
Normal file
@@ -10,7 +10,7 @@
|
||||
"postinstall": "sh ./scripts/postinstall.sh",
|
||||
"initIcon": "node ./scripts/icon/init.js",
|
||||
"previewIcon": "node ./scripts/icon/index.js",
|
||||
"checkI18n": "node ./scripts/i18n/delete-unused-keys.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"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@chakra-ui/cli": "^2.4.1",
|
||||
@@ -30,4 +30,4 @@
|
||||
"node": ">=18.16.0",
|
||||
"pnpm": ">=9.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { PromptTemplateItem } from '../type.d';
|
||||
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
export const Prompt_QuoteTemplateList: PromptTemplateItem[] = [
|
||||
{
|
||||
title: '标准模板',
|
||||
desc: '标准提示词,用于结构不固定的知识库。',
|
||||
title: i18nT('app:template.standard_template'),
|
||||
desc: i18nT('app:template.standard_template_des'),
|
||||
value: `{{q}}
|
||||
{{a}}`
|
||||
},
|
||||
{
|
||||
title: '问答模板',
|
||||
desc: '适合 QA 问答结构的知识库,可以让AI较为严格的按预设内容回答',
|
||||
title: i18nT('app:template.qa_template'),
|
||||
desc: i18nT('app:template.qa_template_des'),
|
||||
value: `<Question>
|
||||
{{q}}
|
||||
</Question>
|
||||
@@ -18,14 +18,14 @@ export const Prompt_QuoteTemplateList: PromptTemplateItem[] = [
|
||||
</Answer>`
|
||||
},
|
||||
{
|
||||
title: '标准严格模板',
|
||||
desc: '在标准模板基础上,对模型的回答做更严格的要求。',
|
||||
title: i18nT('app:template.standard_strict'),
|
||||
desc: i18nT('app:template.standard_strict_des'),
|
||||
value: `{{q}}
|
||||
{{a}}`
|
||||
},
|
||||
{
|
||||
title: '严格问答模板',
|
||||
desc: '在问答模板基础上,对模型的回答做更严格的要求。',
|
||||
title: i18nT('app:template.hard_strict'),
|
||||
desc: i18nT('app:template.hard_strict_des'),
|
||||
value: `<Question>
|
||||
{{q}}
|
||||
</Question>
|
||||
@@ -37,7 +37,7 @@ export const Prompt_QuoteTemplateList: PromptTemplateItem[] = [
|
||||
|
||||
export const Prompt_QuotePromptList: PromptTemplateItem[] = [
|
||||
{
|
||||
title: '标准模板',
|
||||
title: i18nT('app:template.standard_template'),
|
||||
desc: '',
|
||||
value: `使用 <Data></Data> 标记中的内容作为你的知识:
|
||||
|
||||
@@ -55,7 +55,7 @@ export const Prompt_QuotePromptList: PromptTemplateItem[] = [
|
||||
问题:"""{{question}}"""`
|
||||
},
|
||||
{
|
||||
title: '问答模板',
|
||||
title: i18nT('app:template.qa_template'),
|
||||
desc: '',
|
||||
value: `使用 <QA></QA> 标记中的问答对进行回答。
|
||||
|
||||
@@ -72,7 +72,7 @@ export const Prompt_QuotePromptList: PromptTemplateItem[] = [
|
||||
问题:"""{{question}}"""`
|
||||
},
|
||||
{
|
||||
title: '标准严格模板',
|
||||
title: i18nT('app:template.standard_strict'),
|
||||
desc: '',
|
||||
value: `忘记你已有的知识,仅使用 <Data></Data> 标记中的内容作为你的知识:
|
||||
|
||||
@@ -94,7 +94,7 @@ export const Prompt_QuotePromptList: PromptTemplateItem[] = [
|
||||
问题:"""{{question}}"""`
|
||||
},
|
||||
{
|
||||
title: '严格问答模板',
|
||||
title: i18nT('app:template.hard_strict'),
|
||||
desc: '',
|
||||
value: `忘记你已有的知识,仅使用 <QA></QA> 标记中的问答对进行回答。
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ export const Prompt_AgentQA = {
|
||||
- 答案需详细完整,尽可能保留原文描述,可以适当扩展答案描述。
|
||||
- 答案可以包含普通文字、链接、代码、表格、公示、媒体链接等 Markdown 元素。
|
||||
- 最多提出 50 个问题。
|
||||
- 生成的问题和答案和源文本语言相同。
|
||||
`,
|
||||
fixedText: `请按以下格式整理学习成果:
|
||||
<Context>
|
||||
|
||||
10
packages/global/core/app/type.d.ts
vendored
@@ -1,7 +1,11 @@
|
||||
import type { FlowNodeTemplateType, StoreNodeItemType } from '../workflow/type/node';
|
||||
import { AppTypeEnum } from './constants';
|
||||
import { PermissionTypeEnum } from '../../support/permission/constant';
|
||||
import { NodeInputKeyEnum, VariableInputEnum } from '../workflow/constants';
|
||||
import {
|
||||
NodeInputKeyEnum,
|
||||
VariableInputEnum,
|
||||
WorkflowIOValueTypeEnum
|
||||
} from '../workflow/constants';
|
||||
import { SelectedDatasetType } from '../workflow/api';
|
||||
import { DatasetSearchModeEnum } from '../dataset/constants';
|
||||
import { TeamTagSchema as TeamTagsSchemaType } from '@fastgpt/global/support/user/team/type.d';
|
||||
@@ -92,6 +96,9 @@ export type AppChatConfigType = {
|
||||
scheduledTriggerConfig?: AppScheduledTriggerConfigType;
|
||||
chatInputGuide?: ChatInputGuideConfigType;
|
||||
fileSelectConfig?: AppFileSelectConfigType;
|
||||
|
||||
// plugin
|
||||
instruction?: string;
|
||||
};
|
||||
export type SettingAIDataType = {
|
||||
model: string;
|
||||
@@ -111,6 +118,7 @@ export type VariableItemType = {
|
||||
required: boolean;
|
||||
maxLen: number;
|
||||
enums: { value: string }[];
|
||||
valueType: WorkflowIOValueTypeEnum;
|
||||
};
|
||||
// tts
|
||||
export type AppTTSConfigType = {
|
||||
|
||||
@@ -118,7 +118,7 @@ export const chats2GPTMessages = ({
|
||||
tool_calls
|
||||
})
|
||||
.concat(toolResponse);
|
||||
} else if (value.text) {
|
||||
} else if (value.text?.content) {
|
||||
results.push({
|
||||
dataId,
|
||||
role: ChatCompletionRequestMessageRoleEnum.Assistant,
|
||||
@@ -142,7 +142,7 @@ export const GPTMessages2Chats = (
|
||||
messages: ChatCompletionMessageParam[],
|
||||
reserveTool = true
|
||||
): ChatItemType[] => {
|
||||
return messages
|
||||
const chatMessages = messages
|
||||
.map((item) => {
|
||||
const value: ChatItemType['value'] = [];
|
||||
const obj = GPT2Chat[item.role];
|
||||
@@ -151,12 +151,23 @@ export const GPTMessages2Chats = (
|
||||
obj === ChatRoleEnum.System &&
|
||||
item.role === ChatCompletionRequestMessageRoleEnum.System
|
||||
) {
|
||||
value.push({
|
||||
type: ChatItemValueTypeEnum.text,
|
||||
text: {
|
||||
content: item.content
|
||||
}
|
||||
});
|
||||
if (Array.isArray(item.content)) {
|
||||
item.content.forEach((item) => [
|
||||
value.push({
|
||||
type: ChatItemValueTypeEnum.text,
|
||||
text: {
|
||||
content: item.text
|
||||
}
|
||||
})
|
||||
]);
|
||||
} else {
|
||||
value.push({
|
||||
type: ChatItemValueTypeEnum.text,
|
||||
text: {
|
||||
content: item.content
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (
|
||||
obj === ChatRoleEnum.Human &&
|
||||
item.role === ChatCompletionRequestMessageRoleEnum.User
|
||||
@@ -277,6 +288,22 @@ export const GPTMessages2Chats = (
|
||||
} as ChatItemType;
|
||||
})
|
||||
.filter((item) => item.value.length > 0);
|
||||
|
||||
// Merge data with the same dataId
|
||||
const result = chatMessages.reduce((result: ChatItemType[], currentItem) => {
|
||||
const lastItem = result[result.length - 1];
|
||||
|
||||
if (lastItem && lastItem.dataId === currentItem.dataId && lastItem.obj === currentItem.obj) {
|
||||
// @ts-ignore
|
||||
lastItem.value = lastItem.value.concat(currentItem.value);
|
||||
} else {
|
||||
result.push(currentItem);
|
||||
}
|
||||
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const chatValue2RuntimePrompt = (value: ChatItemValueItemType[]): RuntimeUserPromptType => {
|
||||
|
||||
1
packages/global/core/chat/type.d.ts
vendored
@@ -151,6 +151,7 @@ export type ChatHistoryItemType = HistoryItemType & {
|
||||
/* ------- response data ------------ */
|
||||
export type ChatHistoryItemResType = DispatchNodeResponseType & {
|
||||
nodeId: string;
|
||||
id: string;
|
||||
moduleType: FlowNodeTypeEnum;
|
||||
moduleName: string;
|
||||
};
|
||||
|
||||
@@ -12,17 +12,17 @@ export const DatasetTypeMap = {
|
||||
collectionLabel: 'common.Folder'
|
||||
},
|
||||
[DatasetTypeEnum.dataset]: {
|
||||
icon: 'core/dataset/commonDataset',
|
||||
icon: 'core/dataset/commonDatasetOutline',
|
||||
label: 'common_dataset',
|
||||
collectionLabel: 'common.File'
|
||||
},
|
||||
[DatasetTypeEnum.websiteDataset]: {
|
||||
icon: 'core/dataset/websiteDataset',
|
||||
icon: 'core/dataset/websiteDatasetOutline',
|
||||
label: 'website_dataset',
|
||||
collectionLabel: 'common.Website'
|
||||
},
|
||||
[DatasetTypeEnum.externalFile]: {
|
||||
icon: 'core/dataset/externalDataset',
|
||||
icon: 'core/dataset/externalDatasetOutline',
|
||||
label: 'external_file',
|
||||
collectionLabel: 'common.File'
|
||||
}
|
||||
|
||||
1
packages/global/core/dataset/type.d.ts
vendored
@@ -51,6 +51,7 @@ export type DatasetCollectionSchemaType = {
|
||||
chunkSize: number;
|
||||
chunkSplitter?: string;
|
||||
qaPrompt?: string;
|
||||
ocrParse?: boolean;
|
||||
|
||||
tags?: string[];
|
||||
|
||||
|
||||
@@ -52,6 +52,9 @@ export enum NodeInputKeyEnum {
|
||||
scheduleTrigger = 'scheduleTrigger',
|
||||
chatInputGuide = 'chatInputGuide',
|
||||
|
||||
// plugin config
|
||||
instruction = 'instruction',
|
||||
|
||||
// entry
|
||||
userChatInput = 'userChatInput',
|
||||
inputFiles = 'inputFiles',
|
||||
@@ -105,6 +108,8 @@ export enum NodeInputKeyEnum {
|
||||
httpMethod = 'system_httpMethod',
|
||||
httpParams = 'system_httpParams',
|
||||
httpJsonBody = 'system_httpJsonBody',
|
||||
httpFormBody = 'system_httpFormBody',
|
||||
httpContentType = 'system_httpContentType',
|
||||
httpTimeout = 'system_httpTimeout',
|
||||
abandon_httpUrl = 'url',
|
||||
|
||||
@@ -128,6 +133,7 @@ export enum NodeInputKeyEnum {
|
||||
|
||||
// read files
|
||||
fileUrlList = 'fileUrlList',
|
||||
|
||||
// user select
|
||||
userSelectOptions = 'userSelectOptions'
|
||||
}
|
||||
@@ -213,3 +219,13 @@ export enum RuntimeEdgeStatusEnum {
|
||||
|
||||
export const VARIABLE_NODE_ID = 'VARIABLE_NODE_ID';
|
||||
export const DYNAMIC_INPUT_REFERENCE_KEY = 'DYNAMIC_INPUT_REFERENCE_KEY';
|
||||
|
||||
// http node body content type
|
||||
export enum ContentTypes {
|
||||
none = 'none',
|
||||
formData = 'form-data',
|
||||
xWwwFormUrlencoded = 'x-www-form-urlencoded',
|
||||
json = 'json',
|
||||
xml = 'xml',
|
||||
raw = 'raw-text'
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WorkflowIOValueTypeEnum } from '../constants';
|
||||
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
export enum FlowNodeInputTypeEnum { // render ui
|
||||
reference = 'reference', // reference to other node output
|
||||
input = 'input', // one line input
|
||||
@@ -15,6 +15,7 @@ export enum FlowNodeInputTypeEnum { // render ui
|
||||
|
||||
// special input
|
||||
selectApp = 'selectApp',
|
||||
customVariable = 'customVariable',
|
||||
|
||||
// ai model select
|
||||
selectLLMModel = 'selectLLMModel',
|
||||
@@ -44,7 +45,7 @@ export const FlowNodeInputMap: Record<
|
||||
icon: 'core/workflow/inputType/numberInput'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.select]: {
|
||||
icon: 'core/workflow/inputType/input'
|
||||
icon: 'core/workflow/inputType/option'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.switch]: {
|
||||
icon: 'core/workflow/inputType/switch'
|
||||
@@ -79,8 +80,11 @@ export const FlowNodeInputMap: Record<
|
||||
[FlowNodeInputTypeEnum.hidden]: {
|
||||
icon: 'core/workflow/inputType/select'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.customVariable]: {
|
||||
icon: 'core/workflow/inputType/customVariable'
|
||||
},
|
||||
[FlowNodeInputTypeEnum.custom]: {
|
||||
icon: 'core/workflow/inputType/select'
|
||||
icon: 'core/workflow/inputType/custom'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -94,6 +98,7 @@ export enum FlowNodeOutputTypeEnum {
|
||||
export enum FlowNodeTypeEnum {
|
||||
emptyNode = 'emptyNode',
|
||||
systemConfig = 'userGuide',
|
||||
pluginConfig = 'pluginConfig',
|
||||
globalVariable = 'globalVariable',
|
||||
workflowStart = 'workflowStart',
|
||||
chatNode = 'chatNode',
|
||||
@@ -106,6 +111,7 @@ export enum FlowNodeTypeEnum {
|
||||
contentExtract = 'contentExtract',
|
||||
httpRequest468 = 'httpRequest468',
|
||||
runApp = 'app',
|
||||
appModule = 'appModule',
|
||||
pluginModule = 'pluginModule',
|
||||
pluginInput = 'pluginInput',
|
||||
pluginOutput = 'pluginOutput',
|
||||
@@ -161,23 +167,23 @@ export const FlowValueTypeMap = {
|
||||
value: WorkflowIOValueTypeEnum.any
|
||||
},
|
||||
[WorkflowIOValueTypeEnum.chatHistory]: {
|
||||
label: '历史记录',
|
||||
label: i18nT('common:core.chat.History'),
|
||||
value: WorkflowIOValueTypeEnum.chatHistory
|
||||
},
|
||||
[WorkflowIOValueTypeEnum.datasetQuote]: {
|
||||
label: '知识库引用',
|
||||
label: i18nT('common:core.workflow.Dataset quote'),
|
||||
value: WorkflowIOValueTypeEnum.datasetQuote
|
||||
},
|
||||
[WorkflowIOValueTypeEnum.selectApp]: {
|
||||
label: '选择应用',
|
||||
label: i18nT('common:plugin.App'),
|
||||
value: WorkflowIOValueTypeEnum.selectApp
|
||||
},
|
||||
[WorkflowIOValueTypeEnum.selectDataset]: {
|
||||
label: '选择知识库',
|
||||
label: i18nT('common:core.chat.Select dataset'),
|
||||
value: WorkflowIOValueTypeEnum.selectDataset
|
||||
},
|
||||
[WorkflowIOValueTypeEnum.dynamic]: {
|
||||
label: '动态输入',
|
||||
label: i18nT('common:core.workflow.dynamic_input'),
|
||||
value: WorkflowIOValueTypeEnum.dynamic
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@ export enum DispatchNodeResponseKeyEnum {
|
||||
childrenResponses = 'childrenResponses', // Some nodes make recursive calls that need to be returned
|
||||
toolResponses = 'toolResponses', // The result is passed back to the tool node for use
|
||||
assistantResponses = 'assistantResponses', // assistant response
|
||||
rewriteHistories = 'rewriteHistories', // If have the response, workflow histories will be rewrite
|
||||
|
||||
interactive = 'INTERACTIVE' // is interactive
|
||||
}
|
||||
|
||||
38
packages/global/core/workflow/runtime/type.d.ts
vendored
@@ -2,9 +2,9 @@ import { ChatNodeUsageType } from '../../../support/wallet/bill/type';
|
||||
import {
|
||||
ChatItemType,
|
||||
UserChatItemValueItemType,
|
||||
ChatItemValueItemType,
|
||||
ToolRunResponseItemType,
|
||||
NodeOutputItemType
|
||||
NodeOutputItemType,
|
||||
AIChatItemValueItemType
|
||||
} from '../../chat/type';
|
||||
import { FlowNodeInputItemType, FlowNodeOutputItemType } from '../type/io.d';
|
||||
import { StoreNodeItemType } from '../type/node';
|
||||
@@ -19,16 +19,22 @@ import { RuntimeNodeItemType } from '../runtime/type';
|
||||
import { RuntimeEdgeItemType } from './edge';
|
||||
import { ReadFileNodeResponse } from '../template/system/readFiles/type';
|
||||
import { UserSelectOptionType } from '../template/system/userSelect/type';
|
||||
import { WorkflowResponseType } from '../../../../service/core/workflow/dispatch/type';
|
||||
|
||||
/* workflow props */
|
||||
export type ChatDispatchProps = {
|
||||
res?: NextApiResponse;
|
||||
requestOrigin?: string;
|
||||
mode: 'test' | 'chat' | 'debug';
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
user: UserModelSchema;
|
||||
app: AppDetailType | AppSchema;
|
||||
|
||||
runningAppInfo: {
|
||||
id: string; // May be the id of the system plug-in (cannot be used directly to look up the table)
|
||||
teamId: string;
|
||||
tmbId: string; // App tmbId
|
||||
};
|
||||
uid: string; // Who run this workflow
|
||||
|
||||
chatId?: string;
|
||||
responseChatItemId?: string;
|
||||
histories: ChatItemType[];
|
||||
@@ -36,9 +42,9 @@ export type ChatDispatchProps = {
|
||||
query: UserChatItemValueItemType[]; // trigger query
|
||||
chatConfig: AppSchema['chatConfig'];
|
||||
stream: boolean;
|
||||
detail: boolean; // response detail
|
||||
maxRunTimes: number;
|
||||
isToolCall?: boolean;
|
||||
workflowStreamResponse?: WorkflowResponseType;
|
||||
};
|
||||
|
||||
export type ModuleDispatchProps<T> = ChatDispatchProps & {
|
||||
@@ -49,10 +55,12 @@ export type ModuleDispatchProps<T> = ChatDispatchProps & {
|
||||
};
|
||||
|
||||
export type SystemVariablesType = {
|
||||
userId: string;
|
||||
appId: string;
|
||||
chatId?: string;
|
||||
responseChatItemId?: string;
|
||||
histories: ChatItemType[];
|
||||
cTime: string;
|
||||
};
|
||||
|
||||
/* node props */
|
||||
@@ -68,7 +76,7 @@ export type RuntimeNodeItemType = {
|
||||
inputs: FlowNodeInputItemType[];
|
||||
outputs: FlowNodeOutputItemType[];
|
||||
|
||||
pluginId?: string;
|
||||
pluginId?: string; // workflow id / plugin id
|
||||
};
|
||||
|
||||
export type PluginRuntimeType = {
|
||||
@@ -95,6 +103,8 @@ export type DispatchNodeResponseType = {
|
||||
error?: Record<string, any>;
|
||||
customInputs?: Record<string, any>;
|
||||
customOutputs?: Record<string, any>;
|
||||
nodeInputs?: Record<string, any>;
|
||||
nodeOutputs?: Record<string, any>;
|
||||
|
||||
// bill
|
||||
tokens?: number;
|
||||
@@ -158,15 +168,19 @@ export type DispatchNodeResponseType = {
|
||||
|
||||
// user select
|
||||
userSelectResult?: string;
|
||||
|
||||
// update var
|
||||
updateVarResult?: any[];
|
||||
};
|
||||
|
||||
export type DispatchNodeResultType<T> = {
|
||||
export type DispatchNodeResultType<T = {}> = {
|
||||
[DispatchNodeResponseKeyEnum.skipHandleId]?: string[]; // skip some edge handle id
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]?: DispatchNodeResponseType; // The node response detail
|
||||
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]?: ChatNodeUsageType[]; //
|
||||
[DispatchNodeResponseKeyEnum.childrenResponses]?: DispatchNodeResultType[];
|
||||
[DispatchNodeResponseKeyEnum.toolResponses]?: ToolRunResponseItemType;
|
||||
[DispatchNodeResponseKeyEnum.assistantResponses]?: ChatItemValueItemType[];
|
||||
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]?: ChatNodeUsageType[]; // Node total usage
|
||||
[DispatchNodeResponseKeyEnum.childrenResponses]?: DispatchNodeResultType[]; // Children node response
|
||||
[DispatchNodeResponseKeyEnum.toolResponses]?: ToolRunResponseItemType; // Tool response
|
||||
[DispatchNodeResponseKeyEnum.assistantResponses]?: AIChatItemValueItemType[]; // Assistant response(Store to db)
|
||||
[DispatchNodeResponseKeyEnum.rewriteHistories]?: ChatItemType[];
|
||||
} & T;
|
||||
|
||||
/* Single node props */
|
||||
|
||||
@@ -27,16 +27,32 @@ export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number
|
||||
return limit * 2;
|
||||
};
|
||||
|
||||
/*
|
||||
Get interaction information (if any) from the last AI message.
|
||||
What can be done:
|
||||
1. Get the interactive data
|
||||
2. Check that the workflow starts at the interaction node
|
||||
*/
|
||||
export const getLastInteractiveValue = (histories: ChatItemType[]) => {
|
||||
const lastAIMessage = histories.findLast((item) => item.obj === ChatRoleEnum.AI);
|
||||
|
||||
if (lastAIMessage) {
|
||||
const interactiveValue = lastAIMessage.value.find(
|
||||
(v) => v.type === ChatItemValueTypeEnum.interactive
|
||||
);
|
||||
const lastValue = lastAIMessage.value[lastAIMessage.value.length - 1];
|
||||
|
||||
if (interactiveValue && 'interactive' in interactiveValue) {
|
||||
return interactiveValue.interactive;
|
||||
if (
|
||||
!lastValue ||
|
||||
lastValue.type !== ChatItemValueTypeEnum.interactive ||
|
||||
!lastValue.interactive
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check is user select
|
||||
if (
|
||||
lastValue.interactive.type === 'userSelect' &&
|
||||
!lastValue.interactive.params.userSelectedVal
|
||||
) {
|
||||
return lastValue.interactive;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,39 +133,6 @@ export const filterWorkflowEdges = (edges: RuntimeEdgeItemType[]) => {
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
区分普通连线和递归连线
|
||||
递归连线:可以通过往上查询 nodes,最终追溯到自身
|
||||
*/
|
||||
export const splitEdges2WorkflowEdges = ({
|
||||
edges,
|
||||
allEdges,
|
||||
currentNode
|
||||
}: {
|
||||
edges: RuntimeEdgeItemType[];
|
||||
allEdges: RuntimeEdgeItemType[];
|
||||
currentNode: RuntimeNodeItemType;
|
||||
}) => {
|
||||
const commonEdges: RuntimeEdgeItemType[] = [];
|
||||
const recursiveEdges: RuntimeEdgeItemType[] = [];
|
||||
|
||||
edges.forEach((edge) => {
|
||||
const checkIsCurrentNode = (edge: RuntimeEdgeItemType): boolean => {
|
||||
const sourceEdge = allEdges.find((item) => item.target === edge.source);
|
||||
if (!sourceEdge) return false;
|
||||
if (sourceEdge.source === currentNode.nodeId) return true;
|
||||
return checkIsCurrentNode(sourceEdge);
|
||||
};
|
||||
if (checkIsCurrentNode(edge)) {
|
||||
recursiveEdges.push(edge);
|
||||
} else {
|
||||
commonEdges.push(edge);
|
||||
}
|
||||
});
|
||||
|
||||
return { commonEdges, recursiveEdges };
|
||||
};
|
||||
|
||||
/*
|
||||
1. 输入线分类:普通线和递归线(可以追溯到自身)
|
||||
2. 起始线全部非 waiting 执行,或递归线全部非 waiting 执行
|
||||
@@ -161,31 +144,72 @@ export const checkNodeRunStatus = ({
|
||||
node: RuntimeNodeItemType;
|
||||
runtimeEdges: RuntimeEdgeItemType[];
|
||||
}) => {
|
||||
const workflowEdges = filterWorkflowEdges(runtimeEdges).filter(
|
||||
/*
|
||||
区分普通连线和递归连线
|
||||
递归连线:可以通过往上查询 nodes,最终追溯到自身
|
||||
*/
|
||||
const splitEdges2WorkflowEdges = ({
|
||||
sourceEdges,
|
||||
allEdges,
|
||||
currentNode
|
||||
}: {
|
||||
sourceEdges: RuntimeEdgeItemType[];
|
||||
allEdges: RuntimeEdgeItemType[];
|
||||
currentNode: RuntimeNodeItemType;
|
||||
}) => {
|
||||
const commonEdges: RuntimeEdgeItemType[] = [];
|
||||
const recursiveEdges: RuntimeEdgeItemType[] = [];
|
||||
|
||||
const checkIsCircular = (edge: RuntimeEdgeItemType, visited: Set<string>): boolean => {
|
||||
if (edge.source === currentNode.nodeId) {
|
||||
return true; // 检测到环,并且环中包含当前节点
|
||||
}
|
||||
if (visited.has(edge.source)) {
|
||||
return false; // 检测到环,但不包含当前节点(子节点成环)
|
||||
}
|
||||
visited.add(edge.source);
|
||||
|
||||
const nextEdges = allEdges.filter((item) => item.target === edge.source);
|
||||
return nextEdges.some((nextEdge) => checkIsCircular(nextEdge, new Set(visited)));
|
||||
};
|
||||
|
||||
sourceEdges.forEach((edge) => {
|
||||
if (checkIsCircular(edge, new Set([currentNode.nodeId]))) {
|
||||
recursiveEdges.push(edge);
|
||||
} else {
|
||||
commonEdges.push(edge);
|
||||
}
|
||||
});
|
||||
|
||||
return { commonEdges, recursiveEdges };
|
||||
};
|
||||
|
||||
const runtimeNodeSourceEdge = filterWorkflowEdges(runtimeEdges).filter(
|
||||
(item) => item.target === node.nodeId
|
||||
);
|
||||
|
||||
// Entry
|
||||
if (workflowEdges.length === 0) {
|
||||
if (runtimeNodeSourceEdge.length === 0) {
|
||||
return 'run';
|
||||
}
|
||||
|
||||
// Classify edges
|
||||
const { commonEdges, recursiveEdges } = splitEdges2WorkflowEdges({
|
||||
edges: workflowEdges,
|
||||
sourceEdges: runtimeNodeSourceEdge,
|
||||
allEdges: runtimeEdges,
|
||||
currentNode: node
|
||||
});
|
||||
|
||||
// check skip
|
||||
if (commonEdges.every((item) => item.status === 'skipped')) {
|
||||
// check skip(其中一组边,全 skip)
|
||||
if (commonEdges.length > 0 && commonEdges.every((item) => item.status === 'skipped')) {
|
||||
return 'skip';
|
||||
}
|
||||
if (recursiveEdges.length > 0 && recursiveEdges.every((item) => item.status === 'skipped')) {
|
||||
return 'skip';
|
||||
}
|
||||
|
||||
// check active
|
||||
if (commonEdges.every((item) => item.status !== 'waiting')) {
|
||||
// check active(有一类边,不全是 wait 即可运行)
|
||||
if (commonEdges.length > 0 && commonEdges.every((item) => item.status !== 'waiting')) {
|
||||
return 'run';
|
||||
}
|
||||
if (recursiveEdges.length > 0 && recursiveEdges.every((item) => item.status !== 'waiting')) {
|
||||
@@ -236,7 +260,7 @@ export const textAdaptGptResponse = ({
|
||||
finish_reason?: null | 'stop';
|
||||
extraData?: Object;
|
||||
}) => {
|
||||
return JSON.stringify({
|
||||
return {
|
||||
...extraData,
|
||||
id: '',
|
||||
object: '',
|
||||
@@ -252,7 +276,7 @@ export const textAdaptGptResponse = ({
|
||||
finish_reason
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/* Update runtimeNode's outputs with interactive data from history */
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SystemConfigNode } from './system/systemConfig';
|
||||
import { PluginConfigNode } from './system/pluginConfig';
|
||||
import { EmptyNode } from './system/emptyNode';
|
||||
import { WorkflowStart } from './system/workflowStart';
|
||||
import { AiChatModule } from './system/aiChat';
|
||||
@@ -12,10 +13,11 @@ import { HttpNode468 } from './system/http468';
|
||||
import { ToolModule } from './system/tools';
|
||||
import { StopToolNode } from './system/stopTool';
|
||||
|
||||
import { RunAppModule } from './system/runApp/index';
|
||||
import { RunAppModule } from './system/abandoned/runApp/index';
|
||||
import { PluginInputModule } from './system/pluginInput';
|
||||
import { PluginOutputModule } from './system/pluginOutput';
|
||||
import { RunPluginModule } from './system/runPlugin';
|
||||
import { RunAppNode } from './system/runApp';
|
||||
import { AiQueryExtension } from './system/queryExtension';
|
||||
|
||||
import type { FlowNodeTemplateType } from '../type/node';
|
||||
@@ -44,8 +46,7 @@ const systemNodes: FlowNodeTemplateType[] = [
|
||||
LafModule,
|
||||
IfElseNode,
|
||||
VariableUpdateNode,
|
||||
CodeNode,
|
||||
RunAppModule
|
||||
CodeNode
|
||||
];
|
||||
/* app flow module templates */
|
||||
export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
@@ -57,6 +58,7 @@ export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
];
|
||||
/* plugin flow module templates */
|
||||
export const pluginSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
PluginConfigNode,
|
||||
PluginInputModule,
|
||||
PluginOutputModule,
|
||||
...systemNodes
|
||||
@@ -70,5 +72,7 @@ export const moduleTemplatesFlat: FlowNodeTemplateType[] = [
|
||||
)
|
||||
),
|
||||
EmptyNode,
|
||||
RunPluginModule
|
||||
RunPluginModule,
|
||||
RunAppNode,
|
||||
RunAppModule
|
||||
];
|
||||
|
||||
@@ -9,8 +9,9 @@ export const Input_Template_History: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.history,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.chatHistory,
|
||||
label: 'core.module.input.label.chat history',
|
||||
description: '最多携带多少轮对话记录',
|
||||
label: i18nT('common:core.module.input.label.chat history'),
|
||||
description: i18nT('workflow:max_dialog_rounds'),
|
||||
|
||||
required: true,
|
||||
min: 0,
|
||||
max: 50,
|
||||
@@ -21,7 +22,7 @@ export const Input_Template_UserChatInput: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.userChatInput,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: '用户问题',
|
||||
label: i18nT('workflow:user_question'),
|
||||
required: true
|
||||
};
|
||||
|
||||
@@ -36,14 +37,14 @@ export const Input_Template_DynamicInput: FlowNodeInputItemType = {
|
||||
export const Input_Template_SelectAIModel: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.aiModel,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.selectLLMModel, FlowNodeInputTypeEnum.reference],
|
||||
label: 'core.module.input.label.aiModel',
|
||||
label: i18nT('common:core.module.input.label.aiModel'),
|
||||
required: true,
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
};
|
||||
export const Input_Template_SettingAiModel: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.aiModel,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.settingLLMModel, FlowNodeInputTypeEnum.reference],
|
||||
label: 'core.module.input.label.aiModel',
|
||||
label: i18nT('common:core.module.input.label.aiModel'),
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
};
|
||||
|
||||
@@ -52,7 +53,7 @@ export const Input_Template_System_Prompt: FlowNodeInputItemType = {
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
max: 3000,
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: 'core.ai.Prompt',
|
||||
label: i18nT('common:core.ai.Prompt'),
|
||||
description: chatNodeSystemPromptTip,
|
||||
placeholder: chatNodeSystemPromptTip
|
||||
};
|
||||
@@ -61,7 +62,7 @@ export const Input_Template_Dataset_Quote: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.aiChatDatasetQuote,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.settingDatasetQuotePrompt],
|
||||
label: '',
|
||||
debugLabel: '知识库引用',
|
||||
debugLabel: i18nT('workflow:knowledge_base_reference'),
|
||||
description: '',
|
||||
valueType: WorkflowIOValueTypeEnum.datasetQuote
|
||||
};
|
||||
@@ -73,3 +74,12 @@ export const Input_Template_Text_Quote: FlowNodeInputItemType = {
|
||||
description: i18nT('app:document_quote_tip'),
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
};
|
||||
export const Input_Template_File_Link: FlowNodeInputItemType = {
|
||||
key: NodeInputKeyEnum.fileUrlList,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.reference],
|
||||
required: true,
|
||||
label: i18nT('app:workflow.user_file_input'),
|
||||
debugLabel: i18nT('app:workflow.user_file_input'),
|
||||
description: i18nT('app:workflow.user_file_input_desc'),
|
||||
valueType: WorkflowIOValueTypeEnum.arrayString
|
||||
};
|
||||
|
||||
@@ -3,16 +3,17 @@ import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../../type/node.d';
|
||||
} from '../../../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../../../type/node';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../../constants';
|
||||
import { Input_Template_History, Input_Template_UserChatInput } from '../../input';
|
||||
import { getHandleConfig } from '../../utils';
|
||||
} from '../../../../constants';
|
||||
import { Input_Template_History, Input_Template_UserChatInput } from '../../../input';
|
||||
import { getHandleConfig } from '../../../utils';
|
||||
import { i18nT } from '../../../../../../../web/i18n/utils';
|
||||
|
||||
export const RunAppModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.runApp,
|
||||
@@ -21,8 +22,8 @@ export const RunAppModule: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/runApp',
|
||||
name: '应用调用',
|
||||
intro: '可以选择一个其他应用进行调用',
|
||||
name: i18nT('workflow:application_call'),
|
||||
intro: i18nT('workflow:select_another_application_to_call'),
|
||||
showStatus: true,
|
||||
version: '481',
|
||||
isTool: true,
|
||||
@@ -31,22 +32,22 @@ export const RunAppModule: FlowNodeTemplateType = {
|
||||
key: NodeInputKeyEnum.runAppSelectApp,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.selectApp, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.selectApp,
|
||||
label: '选择一个应用',
|
||||
description: '选择一个其他应用进行调用',
|
||||
label: i18nT('workflow:select_an_application'),
|
||||
description: i18nT('workflow:choose_another_application_to_call'),
|
||||
required: true
|
||||
},
|
||||
Input_Template_History,
|
||||
{
|
||||
...Input_Template_UserChatInput,
|
||||
toolDescription: '用户问题'
|
||||
toolDescription: i18nT('workflow:user_question')
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.history,
|
||||
key: NodeOutputKeyEnum.history,
|
||||
label: '新的上下文',
|
||||
description: '将该应用回复内容拼接到历史记录中,作为新的上下文返回',
|
||||
label: i18nT('workflow:new_context'),
|
||||
description: i18nT('workflow:append_application_reply_to_history_as_new_context'),
|
||||
valueType: WorkflowIOValueTypeEnum.chatHistory,
|
||||
valueDesc: chatHistoryValueDesc,
|
||||
required: true,
|
||||
@@ -55,8 +56,8 @@ export const RunAppModule: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.answerText,
|
||||
key: NodeOutputKeyEnum.answerText,
|
||||
label: '回复的文本',
|
||||
description: '将在应用完全结束后触发',
|
||||
label: i18nT('workflow:reply_text'),
|
||||
description: i18nT('workflow:trigger_after_application_completion'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
@@ -81,22 +81,23 @@ export const AiChatModule: FlowNodeTemplateType = {
|
||||
// settings modal ---
|
||||
{
|
||||
...Input_Template_System_Prompt,
|
||||
label: 'core.ai.Prompt',
|
||||
label: i18nT('common:core.ai.Prompt'),
|
||||
description: chatNodeSystemPromptTip,
|
||||
placeholder: chatNodeSystemPromptTip
|
||||
},
|
||||
Input_Template_History,
|
||||
Input_Template_Dataset_Quote,
|
||||
Input_Template_Text_Quote,
|
||||
{ ...Input_Template_UserChatInput, toolDescription: '用户问题' }
|
||||
|
||||
{ ...Input_Template_UserChatInput, toolDescription: i18nT('workflow:user_question') }
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.history,
|
||||
key: NodeOutputKeyEnum.history,
|
||||
required: true,
|
||||
label: 'core.module.output.label.New context',
|
||||
description: 'core.module.output.description.New context',
|
||||
label: i18nT('common:core.module.output.label.New context'),
|
||||
description: i18nT('common:core.module.output.description.New context'),
|
||||
valueType: WorkflowIOValueTypeEnum.chatHistory,
|
||||
valueDesc: chatHistoryValueDesc,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
@@ -105,8 +106,8 @@ export const AiChatModule: FlowNodeTemplateType = {
|
||||
id: NodeOutputKeyEnum.answerText,
|
||||
key: NodeOutputKeyEnum.answerText,
|
||||
required: true,
|
||||
label: 'core.module.output.label.Ai response content',
|
||||
description: 'core.module.output.description.Ai response content',
|
||||
label: i18nT('common:core.module.output.label.Ai response content'),
|
||||
description: i18nT('common:core.module.output.description.Ai response content'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
FlowNodeTemplateTypeEnum
|
||||
} from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
|
||||
export const AssignedAnswerModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.answerNode,
|
||||
@@ -14,9 +15,9 @@ export const AssignedAnswerModule: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/reply',
|
||||
name: '指定回复',
|
||||
intro:
|
||||
'该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。',
|
||||
name: i18nT('workflow:assigned_reply'),
|
||||
intro: i18nT('workflow:intro_assigned_reply'),
|
||||
|
||||
version: '481',
|
||||
isTool: true,
|
||||
inputs: [
|
||||
@@ -25,9 +26,9 @@ export const AssignedAnswerModule: FlowNodeTemplateType = {
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
required: true,
|
||||
label: 'core.module.input.label.Response content',
|
||||
description: 'core.module.input.description.Response content',
|
||||
placeholder: 'core.module.input.description.Response content'
|
||||
label: i18nT('common:core.module.input.label.Response content'),
|
||||
description: i18nT('common:core.module.input.description.Response content'),
|
||||
placeholder: i18nT('common:core.module.input.description.Response content')
|
||||
}
|
||||
],
|
||||
outputs: []
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
import { Input_Template_System_Prompt } from '../../input';
|
||||
import { LLMModelTypeEnum } from '../../../../ai/constants';
|
||||
import { getHandleConfig } from '../../utils';
|
||||
import { i18nT } from '../../../../../../web/i18n/utils';
|
||||
|
||||
export const ClassifyQuestionModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.classifyQuestion,
|
||||
@@ -26,8 +27,8 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(true, false, true, true),
|
||||
avatar: 'core/workflow/template/questionClassify',
|
||||
name: '问题分类',
|
||||
intro: `根据用户的历史记录和当前问题判断该次提问的类型。可以添加多组问题类型,下面是一个模板例子:\n类型1: 打招呼\n类型2: 关于商品“使用”问题\n类型3: 关于商品“购买”问题\n类型4: 其他问题`,
|
||||
name: i18nT('workflow:question_classification'),
|
||||
intro: i18nT('workflow:intro_question_classification'),
|
||||
showStatus: true,
|
||||
version: '481',
|
||||
inputs: [
|
||||
@@ -50,15 +51,15 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = {
|
||||
label: '',
|
||||
value: [
|
||||
{
|
||||
value: '打招呼',
|
||||
value: 'Greeting',
|
||||
key: 'wqre'
|
||||
},
|
||||
{
|
||||
value: '关于 xxx 的问题',
|
||||
value: 'Question regarding xxx',
|
||||
key: 'sdfa'
|
||||
},
|
||||
{
|
||||
value: '其他问题',
|
||||
value: 'Other Questions',
|
||||
key: 'agex'
|
||||
}
|
||||
]
|
||||
@@ -69,7 +70,7 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = {
|
||||
id: NodeOutputKeyEnum.cqResult,
|
||||
key: NodeOutputKeyEnum.cqResult,
|
||||
required: true,
|
||||
label: '分类结果',
|
||||
label: i18nT('workflow:classification_result'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import { Input_Template_SelectAIModel, Input_Template_History } from '../../input';
|
||||
import { LLMModelTypeEnum } from '../../../../ai/constants';
|
||||
import { getHandleConfig } from '../../utils';
|
||||
import { i18nT } from '../../../../../../web/i18n/utils';
|
||||
|
||||
export const ContextExtractModule: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.contentExtract,
|
||||
@@ -21,8 +22,8 @@ export const ContextExtractModule: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/extractJson',
|
||||
name: '文本内容提取',
|
||||
intro: '可从文本中提取指定的数据,例如:sql语句、搜索关键词、代码等',
|
||||
name: i18nT('workflow:text_content_extraction'),
|
||||
intro: i18nT('workflow:intro_text_content_extraction'),
|
||||
showStatus: true,
|
||||
isTool: true,
|
||||
version: '481',
|
||||
@@ -35,27 +36,25 @@ export const ContextExtractModule: FlowNodeTemplateType = {
|
||||
key: NodeInputKeyEnum.description,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: '提取要求描述',
|
||||
description:
|
||||
'给AI一些对应的背景知识或要求描述,引导AI更好的完成任务。\n该输入框可使用全局变量。',
|
||||
placeholder:
|
||||
'例如: \n1. 当前时间为: {{cTime}}。你是一个实验室预约助手,你的任务是帮助用户预约实验室,从文本中获取对应的预约信息。\n2. 你是谷歌搜索助手,需要从文本中提取出合适的搜索词。'
|
||||
label: i18nT('workflow:extraction_requirements_description'),
|
||||
description: i18nT('workflow:extraction_requirements_description_detail'),
|
||||
placeholder: i18nT('workflow:extraction_requirements_placeholder')
|
||||
},
|
||||
Input_Template_History,
|
||||
{
|
||||
key: NodeInputKeyEnum.contextExtractInput,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea],
|
||||
label: '需要提取的文本',
|
||||
label: i18nT('workflow:text_to_extract'),
|
||||
required: true,
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
toolDescription: '需要检索的内容'
|
||||
toolDescription: i18nT('workflow:content_to_retrieve')
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.extractKeys,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
description: "由 '描述' 和 'key' 组成一个目标字段,可提取多个目标字段",
|
||||
description: i18nT('workflow:target_fields_description'),
|
||||
value: [] // {valueType: string; desc: string; key: string; required: boolean; enum: string[]}[]
|
||||
}
|
||||
],
|
||||
@@ -63,18 +62,18 @@ export const ContextExtractModule: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.success,
|
||||
key: NodeOutputKeyEnum.success,
|
||||
label: '字段完全提取',
|
||||
label: i18nT('workflow:full_field_extraction'),
|
||||
required: true,
|
||||
description: '提取字段全部填充时返回 true (模型提取或使用默认值均属于成功)',
|
||||
description: i18nT('workflow:full_field_extraction_description'),
|
||||
valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.contextExtractFields,
|
||||
key: NodeOutputKeyEnum.contextExtractFields,
|
||||
label: '完整提取结果',
|
||||
label: i18nT('workflow:complete_extraction_result'),
|
||||
required: true,
|
||||
description: '一个 JSON 字符串,例如:{"name:":"YY","Time":"2023/7/2 18:00"}',
|
||||
description: i18nT('workflow:complete_extraction_result_description'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { WorkflowIOValueTypeEnum } from '../../../constants';
|
||||
|
||||
export type ContextExtractAgentItemType = {
|
||||
valueType: 'string' | 'number' | 'boolean';
|
||||
valueType:
|
||||
| WorkflowIOValueTypeEnum.string
|
||||
| WorkflowIOValueTypeEnum.number
|
||||
| WorkflowIOValueTypeEnum.boolean;
|
||||
desc: string;
|
||||
key: string;
|
||||
required: boolean;
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
NodeInputKeyEnum
|
||||
} from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
|
||||
export const CustomFeedbackNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.customFeedback,
|
||||
@@ -14,8 +15,8 @@ export const CustomFeedbackNode: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/customFeedback',
|
||||
name: '自定义反馈',
|
||||
intro: '该模块被触发时,会给当前的对话记录增加一条反馈。可用于自动记录对话效果等。',
|
||||
name: i18nT('workflow:custom_feedback'),
|
||||
intro: i18nT('workflow:intro_custom_feedback'),
|
||||
version: '486',
|
||||
inputs: [
|
||||
{
|
||||
@@ -23,7 +24,7 @@ export const CustomFeedbackNode: FlowNodeTemplateType = {
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
required: true,
|
||||
label: '反馈的文本'
|
||||
label: i18nT('workflow:feedback_text')
|
||||
}
|
||||
],
|
||||
outputs: []
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { getNanoid } from '../../../../common/string/tools';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { FlowNodeInputItemType } from '../../type/io.d';
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
|
||||
export const getOneQuoteInputTemplate = ({
|
||||
key = getNanoid(),
|
||||
@@ -24,8 +25,8 @@ export const getOneQuoteInputTemplate = ({
|
||||
}): FlowNodeInputItemType => ({
|
||||
key,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.reference],
|
||||
label: `引用${index}`,
|
||||
debugLabel: '知识库引用',
|
||||
label: `${i18nT('workflow:quote_num')},{ num: ${index} }`,
|
||||
debugLabel: i18nT('workflow:knowledge_base_reference'),
|
||||
canEdit: true,
|
||||
valueType: WorkflowIOValueTypeEnum.datasetQuote
|
||||
});
|
||||
@@ -37,15 +38,17 @@ export const DatasetConcatModule: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/datasetConcat',
|
||||
name: '知识库搜索引用合并',
|
||||
intro: '可以将多个知识库搜索结果进行合并输出。使用 RRF 的合并方式进行最终排序输出。',
|
||||
name: i18nT('workflow:knowledge_base_search_merge'),
|
||||
intro: i18nT('workflow:intro_knowledge_base_search_merge'),
|
||||
|
||||
showStatus: false,
|
||||
version: '486',
|
||||
inputs: [
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetMaxTokens,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
label: '最大 Tokens',
|
||||
label: i18nT('workflow:max_tokens'),
|
||||
|
||||
value: 3000,
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
},
|
||||
@@ -60,7 +63,7 @@ export const DatasetConcatModule: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.datasetQuoteQA,
|
||||
key: NodeOutputKeyEnum.datasetQuoteQA,
|
||||
label: 'core.module.Dataset quote.label',
|
||||
label: i18nT('common:core.module.Dataset quote.label'),
|
||||
type: FlowNodeOutputTypeEnum.static,
|
||||
valueType: WorkflowIOValueTypeEnum.datasetQuote,
|
||||
valueDesc: datasetQuoteValueDesc
|
||||
|
||||
@@ -34,7 +34,7 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSelectList,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.selectDataset, FlowNodeInputTypeEnum.reference],
|
||||
label: 'core.module.input.label.Select dataset',
|
||||
label: i18nT('common:core.module.input.label.Select dataset'),
|
||||
value: [],
|
||||
valueType: WorkflowIOValueTypeEnum.selectDataset,
|
||||
required: true
|
||||
@@ -90,34 +90,24 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
|
||||
},
|
||||
{
|
||||
...Input_Template_UserChatInput,
|
||||
toolDescription: '需要检索的内容'
|
||||
toolDescription: i18nT('workflow:content_to_search')
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.collectionFilterMatch,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.JSONEditor, FlowNodeInputTypeEnum.reference],
|
||||
label: '集合元数据过滤',
|
||||
label: i18nT('workflow:collection_metadata_filter'),
|
||||
|
||||
valueType: WorkflowIOValueTypeEnum.object,
|
||||
isPro: true,
|
||||
description: `目前支持标签和创建时间过滤,需按照以下格式填写:
|
||||
{
|
||||
"tags": {
|
||||
"$and": ["标签 1","标签 2"],
|
||||
"$or": ["有 $and 标签时,and 生效,or 不生效"]
|
||||
},
|
||||
"createTime": {
|
||||
"$gte": "YYYY-MM-DD HH:mm 格式即可,集合的创建时间大于该时间",
|
||||
"$lte": "YYYY-MM-DD HH:mm 格式即可,集合的创建时间小于该时间,可和 $gte 共同使用"
|
||||
}
|
||||
}
|
||||
`
|
||||
description: i18nT('workflow:filter_description')
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.datasetQuoteQA,
|
||||
key: NodeOutputKeyEnum.datasetQuoteQA,
|
||||
label: 'core.module.Dataset quote.label',
|
||||
description: '特殊数组格式,搜索结果为空时,返回空数组。',
|
||||
label: i18nT('common:core.module.Dataset quote.label'),
|
||||
description: i18nT('workflow:special_array_format'),
|
||||
type: FlowNodeOutputTypeEnum.static,
|
||||
valueType: WorkflowIOValueTypeEnum.datasetQuote,
|
||||
valueDesc: datasetQuoteValueDesc
|
||||
|
||||
@@ -8,11 +8,13 @@ import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
FlowNodeTemplateTypeEnum
|
||||
FlowNodeTemplateTypeEnum,
|
||||
ContentTypes
|
||||
} from '../../constants';
|
||||
import { Input_Template_DynamicInput } from '../input';
|
||||
import { Output_Template_AddOutput } from '../output';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
|
||||
export const HttpNode468: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.httpRequest468,
|
||||
@@ -21,15 +23,15 @@ export const HttpNode468: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/httpRequest',
|
||||
name: 'HTTP 请求',
|
||||
intro: '可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)',
|
||||
name: i18nT('workflow:http_request'),
|
||||
intro: i18nT('workflow:intro_http_request'),
|
||||
showStatus: true,
|
||||
isTool: true,
|
||||
version: '481',
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_DynamicInput,
|
||||
description: 'core.module.input.description.HTTP Dynamic Input',
|
||||
description: i18nT('common:core.module.input.description.HTTP Dynamic Input'),
|
||||
customInputConfig: {
|
||||
selectValueTypeList: Object.values(WorkflowIOValueTypeEnum),
|
||||
showDescription: false,
|
||||
@@ -59,7 +61,7 @@ export const HttpNode468: FlowNodeTemplateType = {
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: '',
|
||||
description: 'core.module.input.description.Http Request Url',
|
||||
description: i18nT('common:core.module.input.description.Http Request Url'),
|
||||
placeholder: 'https://api.ai.com/getInventory',
|
||||
required: false
|
||||
},
|
||||
@@ -69,8 +71,8 @@ export const HttpNode468: FlowNodeTemplateType = {
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
value: [],
|
||||
label: '',
|
||||
description: 'core.module.input.description.Http Request Header',
|
||||
placeholder: 'core.module.input.description.Http Request Header',
|
||||
description: i18nT('common:core.module.input.description.Http Request Header'),
|
||||
placeholder: i18nT('common:core.module.input.description.Http Request Header'),
|
||||
required: false
|
||||
},
|
||||
{
|
||||
@@ -81,6 +83,7 @@ export const HttpNode468: FlowNodeTemplateType = {
|
||||
label: '',
|
||||
required: false
|
||||
},
|
||||
// json body data
|
||||
{
|
||||
key: NodeInputKeyEnum.httpJsonBody,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
@@ -88,6 +91,24 @@ export const HttpNode468: FlowNodeTemplateType = {
|
||||
value: '',
|
||||
label: '',
|
||||
required: false
|
||||
},
|
||||
// form body data
|
||||
{
|
||||
key: NodeInputKeyEnum.httpFormBody,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
value: [],
|
||||
label: '',
|
||||
required: false
|
||||
},
|
||||
// body data type
|
||||
{
|
||||
key: NodeInputKeyEnum.httpContentType,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
value: ContentTypes.json,
|
||||
label: '',
|
||||
required: false
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
@@ -97,17 +118,17 @@ export const HttpNode468: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.error,
|
||||
key: NodeOutputKeyEnum.error,
|
||||
label: '请求错误',
|
||||
description: 'HTTP请求错误信息,成功时返回空',
|
||||
label: i18nT('workflow:request_error'),
|
||||
description: i18nT('workflow:http_request_error_info'),
|
||||
valueType: WorkflowIOValueTypeEnum.object,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.httpRawResponse,
|
||||
key: NodeOutputKeyEnum.httpRawResponse,
|
||||
label: '原始响应',
|
||||
required: true,
|
||||
description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。',
|
||||
label: i18nT('workflow:raw_response'),
|
||||
description: i18nT('workflow:http_raw_response_description'),
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { i18nT } from '../../../../../../web/i18n/utils';
|
||||
|
||||
export enum VariableConditionEnum {
|
||||
equalTo = 'equalTo',
|
||||
notEqual = 'notEqual',
|
||||
@@ -29,64 +31,85 @@ export enum IfElseResultEnum {
|
||||
}
|
||||
|
||||
export const stringConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '等于', value: VariableConditionEnum.equalTo },
|
||||
{ label: '不等于', value: VariableConditionEnum.notEqual },
|
||||
{ label: '正则', value: VariableConditionEnum.reg },
|
||||
{ label: '包含', value: VariableConditionEnum.include },
|
||||
{ label: '不包含', value: VariableConditionEnum.notInclude },
|
||||
{ label: '开始为', value: VariableConditionEnum.startWith },
|
||||
{ label: '结束为', value: VariableConditionEnum.endWith }
|
||||
{ label: i18nT('workflow:is_empty'), value: VariableConditionEnum.isEmpty },
|
||||
{ label: i18nT('workflow:is_not_empty'), value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: i18nT('workflow:is_equal_to'), value: VariableConditionEnum.equalTo },
|
||||
{ label: i18nT('workflow:is_not_equal'), value: VariableConditionEnum.notEqual },
|
||||
{ label: i18nT('workflow:regex'), value: VariableConditionEnum.reg },
|
||||
{ label: i18nT('workflow:contains'), value: VariableConditionEnum.include },
|
||||
{ label: i18nT('workflow:not_contains'), value: VariableConditionEnum.notInclude },
|
||||
{ label: i18nT('workflow:start_with'), value: VariableConditionEnum.startWith },
|
||||
{ label: i18nT('workflow:end_with'), value: VariableConditionEnum.endWith }
|
||||
];
|
||||
export const numberConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '等于', value: VariableConditionEnum.equalTo },
|
||||
{ label: '不等于', value: VariableConditionEnum.notEqual },
|
||||
{ label: '大于', value: VariableConditionEnum.greaterThan },
|
||||
{ label: '大于等于', value: VariableConditionEnum.greaterThanOrEqualTo },
|
||||
{ label: '小于', value: VariableConditionEnum.lessThan },
|
||||
{ label: '小于等于', value: VariableConditionEnum.lessThanOrEqualTo }
|
||||
{ label: i18nT('workflow:is_empty'), value: VariableConditionEnum.isEmpty },
|
||||
{ label: i18nT('workflow:is_not_empty'), value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: i18nT('workflow:is_equal_to'), value: VariableConditionEnum.equalTo },
|
||||
{ label: i18nT('workflow:is_not_equal'), value: VariableConditionEnum.notEqual },
|
||||
{ label: i18nT('workflow:greater_than'), value: VariableConditionEnum.greaterThan },
|
||||
{
|
||||
label: i18nT('workflow:greater_than_or_equal_to'),
|
||||
value: VariableConditionEnum.greaterThanOrEqualTo
|
||||
},
|
||||
{ label: i18nT('workflow:less_than'), value: VariableConditionEnum.lessThan },
|
||||
{ label: i18nT('workflow:less_than_or_equal_to'), value: VariableConditionEnum.lessThanOrEqualTo }
|
||||
];
|
||||
export const booleanConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '等于', value: VariableConditionEnum.equalTo }
|
||||
{ label: i18nT('workflow:is_empty'), value: VariableConditionEnum.isEmpty },
|
||||
{ label: i18nT('workflow:is_not_empty'), value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: i18nT('workflow:is_equal_to'), value: VariableConditionEnum.equalTo }
|
||||
];
|
||||
export const arrayConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '包含', value: VariableConditionEnum.include },
|
||||
{ label: '不包含', value: VariableConditionEnum.notInclude },
|
||||
{ label: '长度等于', value: VariableConditionEnum.lengthEqualTo },
|
||||
{ label: '长度不等于', value: VariableConditionEnum.lengthNotEqualTo },
|
||||
{ label: '长度大于', value: VariableConditionEnum.lengthGreaterThan },
|
||||
{ label: '长度大于等于', value: VariableConditionEnum.lengthGreaterThanOrEqualTo },
|
||||
{ label: '长度小于', value: VariableConditionEnum.lengthLessThan },
|
||||
{ label: '长度小于等于', value: VariableConditionEnum.lengthLessThanOrEqualTo }
|
||||
{ label: i18nT('workflow:is_empty'), value: VariableConditionEnum.isEmpty },
|
||||
{ label: i18nT('workflow:is_not_empty'), value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: i18nT('workflow:contains'), value: VariableConditionEnum.include },
|
||||
{ label: i18nT('workflow:not_contains'), value: VariableConditionEnum.notInclude },
|
||||
{ label: i18nT('workflow:length_equal_to'), value: VariableConditionEnum.lengthEqualTo },
|
||||
{ label: i18nT('workflow:length_not_equal_to'), value: VariableConditionEnum.lengthNotEqualTo },
|
||||
{ label: i18nT('workflow:length_greater_than'), value: VariableConditionEnum.lengthGreaterThan },
|
||||
{
|
||||
label: i18nT('workflow:length_greater_than_or_equal_to'),
|
||||
value: VariableConditionEnum.lengthGreaterThanOrEqualTo
|
||||
},
|
||||
{ label: i18nT('workflow:length_less_than'), value: VariableConditionEnum.lengthLessThan },
|
||||
{
|
||||
label: i18nT('workflow:length_less_than_or_equal_to'),
|
||||
value: VariableConditionEnum.lengthLessThanOrEqualTo
|
||||
}
|
||||
];
|
||||
export const objectConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty }
|
||||
{ label: i18nT('workflow:is_empty'), value: VariableConditionEnum.isEmpty },
|
||||
{ label: i18nT('workflow:is_not_empty'), value: VariableConditionEnum.isNotEmpty }
|
||||
];
|
||||
export const allConditionList = [
|
||||
{ label: '为空', value: VariableConditionEnum.isEmpty },
|
||||
{ label: '不为空', value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: '等于', value: VariableConditionEnum.equalTo },
|
||||
{ label: '不等于', value: VariableConditionEnum.notEqual },
|
||||
{ label: '包含', value: VariableConditionEnum.include },
|
||||
{ label: '不包含', value: VariableConditionEnum.notInclude },
|
||||
{ label: '开始为', value: VariableConditionEnum.startWith },
|
||||
{ label: '结束为', value: VariableConditionEnum.endWith },
|
||||
{ label: '大于', value: VariableConditionEnum.greaterThan },
|
||||
{ label: '大于等于', value: VariableConditionEnum.greaterThanOrEqualTo },
|
||||
{ label: '小于', value: VariableConditionEnum.lessThan },
|
||||
{ label: '小于等于', value: VariableConditionEnum.lessThanOrEqualTo },
|
||||
{ label: '长度等于', value: VariableConditionEnum.lengthEqualTo },
|
||||
{ label: '长度不等于', value: VariableConditionEnum.lengthNotEqualTo },
|
||||
{ label: '长度大于', value: VariableConditionEnum.lengthGreaterThan },
|
||||
{ label: '长度大于等于', value: VariableConditionEnum.lengthGreaterThanOrEqualTo },
|
||||
{ label: '长度小于', value: VariableConditionEnum.lengthLessThan },
|
||||
{ label: '长度小于等于', value: VariableConditionEnum.lengthLessThanOrEqualTo }
|
||||
{ label: i18nT('workflow:is_empty'), value: VariableConditionEnum.isEmpty },
|
||||
{ label: i18nT('workflow:is_not_empty'), value: VariableConditionEnum.isNotEmpty },
|
||||
{ label: i18nT('workflow:is_equal_to'), value: VariableConditionEnum.equalTo },
|
||||
{ label: i18nT('workflow:is_not_equal'), value: VariableConditionEnum.notEqual },
|
||||
{ label: i18nT('workflow:contains'), value: VariableConditionEnum.include },
|
||||
{ label: i18nT('workflow:not_contains'), value: VariableConditionEnum.notInclude },
|
||||
{ label: i18nT('workflow:start_with'), value: VariableConditionEnum.startWith },
|
||||
{ label: i18nT('workflow:end_with'), value: VariableConditionEnum.endWith },
|
||||
{ label: i18nT('workflow:greater_than'), value: VariableConditionEnum.greaterThan },
|
||||
{
|
||||
label: i18nT('workflow:greater_than_or_equal_to'),
|
||||
value: VariableConditionEnum.greaterThanOrEqualTo
|
||||
},
|
||||
{ label: i18nT('workflow:less_than'), value: VariableConditionEnum.lessThan },
|
||||
{
|
||||
label: i18nT('workflow:less_than_or_equal_to'),
|
||||
value: VariableConditionEnum.lessThanOrEqualTo
|
||||
},
|
||||
{ label: i18nT('workflow:length_equal_to'), value: VariableConditionEnum.lengthEqualTo },
|
||||
{ label: i18nT('workflow:length_not_equal_to'), value: VariableConditionEnum.lengthNotEqualTo },
|
||||
{ label: i18nT('workflow:length_greater_than'), value: VariableConditionEnum.lengthGreaterThan },
|
||||
{
|
||||
label: i18nT('workflow:length_greater_than_or_equal_to'),
|
||||
value: VariableConditionEnum.lengthGreaterThanOrEqualTo
|
||||
},
|
||||
{ label: i18nT('workflow:length_less_than'), value: VariableConditionEnum.lengthLessThan },
|
||||
{
|
||||
label: i18nT('workflow:length_less_than_or_equal_to'),
|
||||
value: VariableConditionEnum.lengthLessThanOrEqualTo
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { i18nT } from '../../../../../../web/i18n/utils';
|
||||
import {
|
||||
FlowNodeTemplateTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
@@ -19,8 +20,8 @@ export const IfElseNode: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(true, false, true, true),
|
||||
avatar: 'core/workflow/template/ifelse',
|
||||
name: '判断器',
|
||||
intro: '根据一定的条件,执行不同的分支。',
|
||||
name: i18nT('workflow:condition_checker'),
|
||||
intro: i18nT('workflow:execute_different_branches_based_on_conditions'),
|
||||
showStatus: true,
|
||||
version: '481',
|
||||
inputs: [
|
||||
@@ -47,7 +48,7 @@ export const IfElseNode: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.ifElseResult,
|
||||
key: NodeOutputKeyEnum.ifElseResult,
|
||||
label: '判断结果',
|
||||
label: i18nT('workflow:judgment_result'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import { Input_Template_DynamicInput } from '../input';
|
||||
import { Output_Template_AddOutput } from '../output';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
|
||||
export const nodeLafCustomInputConfig = {
|
||||
selectValueTypeList: Object.values(WorkflowIOValueTypeEnum),
|
||||
@@ -27,15 +28,15 @@ export const LafModule: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/lafDispatch',
|
||||
name: 'Laf 函数调用(测试)',
|
||||
intro: '可以调用Laf账号下的云函数。',
|
||||
name: i18nT('workflow:laf_function_call_test'),
|
||||
intro: i18nT('workflow:intro_laf_function_call'),
|
||||
showStatus: true,
|
||||
isTool: true,
|
||||
version: '481',
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_DynamicInput,
|
||||
description: '接收前方节点的输出值作为变量,这些变量可以被 Laf 请求参数使用。',
|
||||
description: i18nT('workflow:dynamic_input_description'),
|
||||
customInputConfig: nodeLafCustomInputConfig
|
||||
},
|
||||
{
|
||||
@@ -52,8 +53,8 @@ export const LafModule: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.httpRawResponse,
|
||||
key: NodeOutputKeyEnum.httpRawResponse,
|
||||
label: '原始响应',
|
||||
description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。',
|
||||
label: i18nT('workflow:raw_response'),
|
||||
description: i18nT('workflow:http_raw_response_description'),
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/node.d';
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
|
||||
export const PluginConfigNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.pluginConfig,
|
||||
templateType: FlowNodeTemplateTypeEnum.systemInput,
|
||||
flowNodeType: FlowNodeTypeEnum.pluginConfig,
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(false, false, false, false),
|
||||
avatar: 'core/workflow/template/systemConfig',
|
||||
name: i18nT('workflow:template.system_config'),
|
||||
intro: '',
|
||||
unique: true,
|
||||
forbidDelete: true,
|
||||
version: '4811',
|
||||
inputs: [],
|
||||
outputs: []
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/node';
|
||||
@@ -12,8 +13,8 @@ export const PluginInputModule: FlowNodeTemplateType = {
|
||||
unique: true,
|
||||
forbidDelete: true,
|
||||
avatar: 'core/workflow/template/workflowStart',
|
||||
name: '插件输入',
|
||||
intro: '可以配置插件需要哪些输入,利用这些输入来运行插件',
|
||||
name: i18nT('workflow:plugin_input'),
|
||||
intro: i18nT('workflow:intro_plugin_input'),
|
||||
showStatus: false,
|
||||
version: '481',
|
||||
inputs: [],
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/node';
|
||||
@@ -12,8 +13,8 @@ export const PluginOutputModule: FlowNodeTemplateType = {
|
||||
unique: true,
|
||||
forbidDelete: true,
|
||||
avatar: 'core/workflow/template/pluginOutput',
|
||||
name: '自定义插件输出',
|
||||
intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出',
|
||||
name: i18nT('workflow:custom_plugin_output'),
|
||||
intro: i18nT('workflow:intro_custom_plugin_output'),
|
||||
showStatus: false,
|
||||
version: '481',
|
||||
inputs: [],
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from '../input';
|
||||
import { LLMModelTypeEnum } from '../../../ai/constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
|
||||
export const AiQueryExtension: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.queryExtension,
|
||||
@@ -25,9 +26,8 @@ export const AiQueryExtension: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/queryExtension',
|
||||
name: '问题优化',
|
||||
intro:
|
||||
'使用问题优化功能,可以提高知识库连续对话时搜索的精度。使用该功能后,会先利用 AI 根据上下文构建一个或多个新的检索词,这些检索词更利于进行知识库搜索。该模块已内置在知识库搜索模块中,如果您仅进行一次知识库搜索,可直接使用知识库内置的补全功能。',
|
||||
name: i18nT('workflow:question_optimization'),
|
||||
intro: i18nT('workflow:intro_question_optimization'),
|
||||
showStatus: true,
|
||||
version: '481',
|
||||
inputs: [
|
||||
@@ -38,11 +38,11 @@ export const AiQueryExtension: FlowNodeTemplateType = {
|
||||
{
|
||||
key: NodeInputKeyEnum.aiSystemPrompt,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
label: 'core.app.edit.Query extension background prompt',
|
||||
label: i18nT('common:core.app.edit.Query extension background prompt'),
|
||||
max: 300,
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
description: 'core.app.edit.Query extension background tip',
|
||||
placeholder: 'core.module.QueryExtension.placeholder'
|
||||
description: i18nT('common:core.app.edit.Query extension background tip'),
|
||||
placeholder: i18nT('common:core.module.QueryExtension.placeholder')
|
||||
},
|
||||
Input_Template_History,
|
||||
Input_Template_UserChatInput
|
||||
@@ -51,8 +51,8 @@ export const AiQueryExtension: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.text,
|
||||
key: NodeOutputKeyEnum.text,
|
||||
label: 'core.module.output.label.query extension result',
|
||||
description: 'core.module.output.description.query extension result',
|
||||
label: i18nT('common:core.module.output.label.query extension result'),
|
||||
description: i18nT('common:core.module.output.description.query extension result'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
|
||||
19
packages/global/core/workflow/template/system/runApp.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/node';
|
||||
import { getHandleConfig } from '../utils';
|
||||
|
||||
export const RunAppNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.appModule,
|
||||
templateType: FlowNodeTemplateTypeEnum.other,
|
||||
flowNodeType: FlowNodeTypeEnum.appModule,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
intro: '',
|
||||
name: '',
|
||||
showStatus: false,
|
||||
isTool: false,
|
||||
version: '481',
|
||||
inputs: [], // [{key:'pluginId'},...]
|
||||
outputs: []
|
||||
};
|
||||
@@ -14,6 +14,7 @@ import { getHandleConfig } from '../../utils';
|
||||
import { Input_Template_DynamicInput } from '../../input';
|
||||
import { Output_Template_AddOutput } from '../../output';
|
||||
import { JS_TEMPLATE } from './constants';
|
||||
import { i18nT } from '../../../../../../web/i18n/utils';
|
||||
|
||||
export const CodeNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.code,
|
||||
@@ -22,14 +23,14 @@ export const CodeNode: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/codeRun',
|
||||
name: '代码运行',
|
||||
intro: '执行一段简单的脚本代码,通常用于进行复杂的数据处理。',
|
||||
name: i18nT('workflow:code_execution'),
|
||||
intro: i18nT('workflow:execute_a_simple_script_code_usually_for_complex_data_processing'),
|
||||
showStatus: true,
|
||||
version: '482',
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_DynamicInput,
|
||||
description: '这些变量会作为代码的运行的输入参数',
|
||||
description: i18nT('workflow:these_variables_will_be_input_parameters_for_code_execution'),
|
||||
customInputConfig: {
|
||||
selectValueTypeList: Object.values(WorkflowIOValueTypeEnum),
|
||||
showDescription: false,
|
||||
@@ -78,20 +79,20 @@ export const CodeNode: FlowNodeTemplateType = {
|
||||
outputs: [
|
||||
{
|
||||
...Output_Template_AddOutput,
|
||||
description: '将代码中 return 的对象作为输出,传递给后续的节点。变量名需要对应 return 的 key'
|
||||
description: i18nT('workflow:pass_returned_object_as_output_to_next_nodes')
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.rawResponse,
|
||||
key: NodeOutputKeyEnum.rawResponse,
|
||||
label: '完整响应数据',
|
||||
label: i18nT('workflow:full_response_data'),
|
||||
valueType: WorkflowIOValueTypeEnum.object,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.error,
|
||||
key: NodeOutputKeyEnum.error,
|
||||
label: '运行错误',
|
||||
description: '代码运行错误信息,成功时返回空',
|
||||
label: i18nT('workflow:execution_error'),
|
||||
description: i18nT('workflow:error_info_returns_empty_on_success'),
|
||||
valueType: WorkflowIOValueTypeEnum.object,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ import { FlowNodeTypeEnum } from '../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../type/node';
|
||||
import { FlowNodeTemplateTypeEnum } from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
|
||||
export const StopToolNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.stopTool,
|
||||
@@ -10,9 +11,8 @@ export const StopToolNode: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(false, false, false, false),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/stopTool',
|
||||
name: '工具调用终止',
|
||||
intro:
|
||||
'该模块需配置工具调用使用。当该模块被执行时,本次工具调用将会强制结束,并且不再调用AI针对工具调用结果回答问题。',
|
||||
name: i18nT('workflow:tool_call_termination'),
|
||||
intro: i18nT('workflow:intro_tool_call_termination'),
|
||||
version: '481',
|
||||
inputs: [],
|
||||
outputs: []
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from '../../constants';
|
||||
import { getHandleConfig } from '../utils';
|
||||
import { Input_Template_DynamicInput } from '../input';
|
||||
import { i18nT } from '../../../../../web/i18n/utils';
|
||||
|
||||
export const TextEditorNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.textEditor,
|
||||
@@ -20,13 +21,13 @@ export const TextEditorNode: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/textConcat',
|
||||
name: '文本拼接',
|
||||
intro: '可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。',
|
||||
name: i18nT('workflow:text_concatenation'),
|
||||
intro: i18nT('workflow:intro_text_concatenation'),
|
||||
version: '486',
|
||||
inputs: [
|
||||
{
|
||||
...Input_Template_DynamicInput,
|
||||
description: '可以引用其他节点的输出,作为文本拼接的变量,输入 / 唤起变量列表',
|
||||
description: i18nT('workflow:dynamic_input_description_concat'),
|
||||
customInputConfig: {
|
||||
selectValueTypeList: Object.values(WorkflowIOValueTypeEnum),
|
||||
showDescription: false,
|
||||
@@ -38,15 +39,15 @@ export const TextEditorNode: FlowNodeTemplateType = {
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
required: true,
|
||||
label: '拼接文本',
|
||||
placeholder: '可输入 / 唤起变量列表'
|
||||
label: i18nT('workflow:concatenation_text'),
|
||||
placeholder: i18nT('workflow:input_variable_list')
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.text,
|
||||
key: NodeOutputKeyEnum.text,
|
||||
label: '拼接结果',
|
||||
label: i18nT('workflow:concatenation_result'),
|
||||
type: FlowNodeOutputTypeEnum.static,
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ export const ToolModule: FlowNodeTemplateType = {
|
||||
|
||||
{
|
||||
...Input_Template_System_Prompt,
|
||||
label: 'core.ai.Prompt',
|
||||
label: i18nT('common:core.ai.Prompt'),
|
||||
description: chatNodeSystemPromptTip,
|
||||
placeholder: chatNodeSystemPromptTip
|
||||
},
|
||||
@@ -72,8 +72,8 @@ export const ToolModule: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.answerText,
|
||||
key: NodeOutputKeyEnum.answerText,
|
||||
label: 'core.module.output.label.Ai response content',
|
||||
description: 'core.module.output.description.Ai response content',
|
||||
label: i18nT('common:core.module.output.label.Ai response content'),
|
||||
description: i18nT('common:core.module.output.description.Ai response content'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
|
||||
@@ -15,12 +15,10 @@ type InteractiveBasicType = {
|
||||
type UserSelectInteractive = {
|
||||
type: 'userSelect';
|
||||
params: {
|
||||
// description: string;
|
||||
description: string;
|
||||
userSelectOptions: UserSelectOptionItemType[];
|
||||
userSelectedVal?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type InteractiveNodeResponseItemType = InteractiveBasicType & UserSelectInteractive;
|
||||
|
||||
export type UserInteractiveType = UserSelectInteractive;
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
WorkflowIOValueTypeEnum
|
||||
} from '../../../constants';
|
||||
import { getHandleConfig } from '../../utils';
|
||||
import { i18nT } from '../../../../../../web/i18n/utils';
|
||||
|
||||
export const VariableUpdateNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.variableUpdate,
|
||||
@@ -14,8 +15,8 @@ export const VariableUpdateNode: FlowNodeTemplateType = {
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/variableUpdate',
|
||||
name: '变量更新',
|
||||
intro: '可以更新指定节点的输出值或更新全局变量',
|
||||
name: i18nT('workflow:variable_update'),
|
||||
intro: i18nT('workflow:update_specified_node_output_or_global_variable'),
|
||||
showStatus: false,
|
||||
isTool: false,
|
||||
version: '481',
|
||||
|
||||
@@ -31,7 +31,7 @@ export const WorkflowStart: FlowNodeTemplateType = {
|
||||
forbidDelete: true,
|
||||
unique: true,
|
||||
version: '481',
|
||||
inputs: [{ ...Input_Template_UserChatInput, toolDescription: '用户问题' }],
|
||||
inputs: [{ ...Input_Template_UserChatInput, toolDescription: i18nT('workflow:user_question') }],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.userChatInput,
|
||||
|
||||
@@ -28,7 +28,7 @@ export type WorkflowTemplateBasicType = {
|
||||
};
|
||||
export type WorkflowTemplateType = {
|
||||
id: string;
|
||||
parentId?: string;
|
||||
parentId?: ParentIdType;
|
||||
isFolder?: boolean;
|
||||
|
||||
name: string;
|
||||
@@ -62,6 +62,8 @@ export type TemplateMarketListItemType = {
|
||||
|
||||
// system plugin
|
||||
export type SystemPluginTemplateItemType = WorkflowTemplateType & {
|
||||
customWorkflow?: string;
|
||||
|
||||
templateType: FlowNodeTemplateTypeEnum;
|
||||
isTool?: boolean;
|
||||
|
||||
@@ -77,8 +79,6 @@ export type SystemPluginTemplateItemType = WorkflowTemplateType & {
|
||||
description: string;
|
||||
value?: any;
|
||||
}[];
|
||||
|
||||
workflow: WorkflowTemplateBasicType;
|
||||
};
|
||||
|
||||
export type THelperLine = {
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { FlowNodeInputTypeEnum, FlowNodeOutputTypeEnum, FlowNodeTypeEnum } from './node/constant';
|
||||
import {
|
||||
chatHistoryValueDesc,
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from './node/constant';
|
||||
import {
|
||||
WorkflowIOValueTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
VariableInputEnum,
|
||||
variableMap,
|
||||
VARIABLE_NODE_ID
|
||||
VARIABLE_NODE_ID,
|
||||
NodeOutputKeyEnum
|
||||
} from './constants';
|
||||
import { FlowNodeInputItemType, FlowNodeOutputItemType, ReferenceValueProps } from './type/io.d';
|
||||
import { StoreNodeItemType } from './type/node';
|
||||
@@ -25,6 +31,8 @@ import {
|
||||
import { IfElseResultEnum } from './template/system/ifElse/constant';
|
||||
import { RuntimeNodeItemType } from './runtime/type';
|
||||
import { getReferenceVariableValue } from './runtime/utils';
|
||||
import { Input_Template_History, Input_Template_UserChatInput } from './template/input';
|
||||
import { i18nT } from '../../../web/i18n/utils';
|
||||
|
||||
export const getHandleId = (nodeId: string, type: 'source' | 'target', key: string) => {
|
||||
return `${nodeId}-${type}-${key}`;
|
||||
@@ -72,6 +80,10 @@ export const splitGuideModule = (guideModules?: StoreNodeItemType) => {
|
||||
guideModules?.inputs?.find((item) => item.key === NodeInputKeyEnum.chatInputGuide)?.value ||
|
||||
defaultChatInputGuideConfig;
|
||||
|
||||
// plugin
|
||||
const instruction: string =
|
||||
guideModules?.inputs?.find((item) => item.key === NodeInputKeyEnum.instruction)?.value || '';
|
||||
|
||||
return {
|
||||
welcomeText,
|
||||
variables,
|
||||
@@ -79,7 +91,8 @@ export const splitGuideModule = (guideModules?: StoreNodeItemType) => {
|
||||
ttsConfig,
|
||||
whisperConfig,
|
||||
scheduledTriggerConfig,
|
||||
chatInputGuide
|
||||
chatInputGuide,
|
||||
instruction
|
||||
};
|
||||
};
|
||||
|
||||
@@ -104,7 +117,8 @@ export const getAppChatConfig = ({
|
||||
ttsConfig,
|
||||
whisperConfig,
|
||||
scheduledTriggerConfig,
|
||||
chatInputGuide
|
||||
chatInputGuide,
|
||||
instruction
|
||||
} = splitGuideModule(systemConfigNode);
|
||||
|
||||
const config: AppChatConfigType = {
|
||||
@@ -113,6 +127,7 @@ export const getAppChatConfig = ({
|
||||
whisperConfig,
|
||||
scheduledTriggerConfig,
|
||||
chatInputGuide,
|
||||
instruction,
|
||||
...chatConfig,
|
||||
variables: storeVariables ?? chatConfig?.variables ?? variables,
|
||||
welcomeText: storeWelcomeText ?? chatConfig?.welcomeText ?? welcomeText
|
||||
@@ -147,9 +162,11 @@ export const getModuleInputUiField = (input: FlowNodeInputItemType) => {
|
||||
return {};
|
||||
};
|
||||
|
||||
export const pluginData2FlowNodeIO = (
|
||||
nodes: StoreNodeItemType[]
|
||||
): {
|
||||
export const pluginData2FlowNodeIO = ({
|
||||
nodes
|
||||
}: {
|
||||
nodes: StoreNodeItemType[];
|
||||
}): {
|
||||
inputs: FlowNodeInputItemType[];
|
||||
outputs: FlowNodeOutputItemType[];
|
||||
} => {
|
||||
@@ -157,14 +174,17 @@ export const pluginData2FlowNodeIO = (
|
||||
const pluginOutput = nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginOutput);
|
||||
|
||||
return {
|
||||
inputs: pluginInput
|
||||
? pluginInput.inputs.map((item) => ({
|
||||
...item,
|
||||
...getModuleInputUiField(item),
|
||||
value: getOrInitModuleInputValue(item),
|
||||
canEdit: false
|
||||
}))
|
||||
: [],
|
||||
inputs:
|
||||
pluginInput?.inputs.map((item) => ({
|
||||
...item,
|
||||
...getModuleInputUiField(item),
|
||||
value: getOrInitModuleInputValue(item),
|
||||
canEdit: false,
|
||||
renderTypeList:
|
||||
item.renderTypeList[0] === FlowNodeInputTypeEnum.customVariable
|
||||
? [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.input]
|
||||
: item.renderTypeList
|
||||
})) || [],
|
||||
outputs: pluginOutput
|
||||
? [
|
||||
...pluginOutput.inputs.map((item) => ({
|
||||
@@ -180,6 +200,80 @@ export const pluginData2FlowNodeIO = (
|
||||
};
|
||||
};
|
||||
|
||||
export const appData2FlowNodeIO = ({
|
||||
chatConfig
|
||||
}: {
|
||||
chatConfig?: AppChatConfigType;
|
||||
}): {
|
||||
inputs: FlowNodeInputItemType[];
|
||||
outputs: FlowNodeOutputItemType[];
|
||||
} => {
|
||||
const variableInput = !chatConfig?.variables
|
||||
? []
|
||||
: chatConfig.variables.map((item) => {
|
||||
const renderTypeMap = {
|
||||
[VariableInputEnum.input]: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
|
||||
[VariableInputEnum.textarea]: [
|
||||
FlowNodeInputTypeEnum.textarea,
|
||||
FlowNodeInputTypeEnum.reference
|
||||
],
|
||||
[VariableInputEnum.select]: [FlowNodeInputTypeEnum.select],
|
||||
[VariableInputEnum.custom]: [
|
||||
FlowNodeInputTypeEnum.input,
|
||||
FlowNodeInputTypeEnum.reference
|
||||
],
|
||||
default: [FlowNodeInputTypeEnum.reference]
|
||||
};
|
||||
|
||||
return {
|
||||
key: item.key,
|
||||
renderTypeList: renderTypeMap[item.type] || renderTypeMap.default,
|
||||
label: item.label,
|
||||
debugLabel: item.label,
|
||||
description: '',
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
required: item.required,
|
||||
list: item.enums.map((enumItem) => ({
|
||||
label: enumItem.value,
|
||||
value: enumItem.value
|
||||
}))
|
||||
};
|
||||
});
|
||||
|
||||
// const showFileLink =
|
||||
// chatConfig?.fileSelectConfig?.canSelectFile || chatConfig?.fileSelectConfig?.canSelectImg;
|
||||
|
||||
return {
|
||||
inputs: [
|
||||
Input_Template_History,
|
||||
Input_Template_UserChatInput,
|
||||
// ...(showFileLink ? [Input_Template_File_Link] : []),
|
||||
...variableInput
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.history,
|
||||
key: NodeOutputKeyEnum.history,
|
||||
required: true,
|
||||
label: i18nT('common:core.module.output.label.New context'),
|
||||
description: i18nT('common:core.module.output.description.New context'),
|
||||
valueType: WorkflowIOValueTypeEnum.chatHistory,
|
||||
valueDesc: chatHistoryValueDesc,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.answerText,
|
||||
key: NodeOutputKeyEnum.answerText,
|
||||
required: false,
|
||||
label: i18nT('common:core.module.output.label.Ai response content'),
|
||||
description: i18nT('common:core.module.output.description.Ai response content'),
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
export const formatEditorVariablePickerIcon = (
|
||||
variables: { key: string; label: string; type?: `${VariableInputEnum}`; required?: boolean }[]
|
||||
): EditorVariablePickerType[] => {
|
||||
@@ -232,25 +326,8 @@ export const updatePluginInputByVariables = (
|
||||
);
|
||||
};
|
||||
|
||||
export const removePluginInputVariables = (
|
||||
variables: Record<string, any>,
|
||||
nodes: RuntimeNodeItemType[]
|
||||
) => {
|
||||
const pluginInputNode = nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput);
|
||||
|
||||
if (!pluginInputNode) return variables;
|
||||
return Object.keys(variables).reduce(
|
||||
(acc, key) => {
|
||||
if (!pluginInputNode.inputs.find((input) => input.key === key)) {
|
||||
acc[key] = variables[key];
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, any>
|
||||
);
|
||||
};
|
||||
|
||||
export function replaceVariableLabel({
|
||||
// replace {{$xx.xx$}} variables for text
|
||||
export function replaceEditorVariable({
|
||||
text,
|
||||
nodes,
|
||||
variables,
|
||||
@@ -258,7 +335,7 @@ export function replaceVariableLabel({
|
||||
}: {
|
||||
text: any;
|
||||
nodes: RuntimeNodeItemType[];
|
||||
variables: Record<string, string | number>;
|
||||
variables: Record<string, any>; // global variables
|
||||
runningNode: RuntimeNodeItemType;
|
||||
}) {
|
||||
if (typeof text !== 'string') return text;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"jschardet": "3.1.1",
|
||||
"nanoid": "^4.0.1",
|
||||
"next": "14.2.5",
|
||||
"openai": "4.53.0",
|
||||
"openai": "4.57.0",
|
||||
"openapi-types": "^12.1.3",
|
||||
"timezones-list": "^3.0.2"
|
||||
},
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { NullPermission, PermissionKeyEnum, PermissionList } from '../constant';
|
||||
import { PermissionListType } from '../type';
|
||||
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
export enum AppPermissionKeyEnum {}
|
||||
export const AppPermissionList: PermissionListType = {
|
||||
[PermissionKeyEnum.read]: {
|
||||
...PermissionList[PermissionKeyEnum.read],
|
||||
description: '可使用该应用进行对话'
|
||||
description: i18nT('app:permission.des.read')
|
||||
},
|
||||
[PermissionKeyEnum.write]: {
|
||||
...PermissionList[PermissionKeyEnum.write],
|
||||
description: '可查看和编辑应用'
|
||||
description: i18nT('app:permission.des.write')
|
||||
},
|
||||
[PermissionKeyEnum.manage]: {
|
||||
...PermissionList[PermissionKeyEnum.manage],
|
||||
description: '写权限基础上,可配置发布渠道、查看对话日志、分配该应用权限'
|
||||
description: i18nT('app:permission.des.manage')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Permission } from './controller';
|
||||
import { PermissionListType } from './type';
|
||||
|
||||
import { i18nT } from '../../../web/i18n/utils';
|
||||
export enum AuthUserTypeEnum {
|
||||
token = 'token',
|
||||
root = 'root',
|
||||
@@ -27,15 +27,15 @@ export const PermissionTypeMap = {
|
||||
},
|
||||
[PermissionTypeEnum.publicRead]: {
|
||||
iconLight: 'support/permission/publicLight',
|
||||
label: '团队可访问'
|
||||
label: i18nT('user:permission.team_read')
|
||||
},
|
||||
[PermissionTypeEnum.publicWrite]: {
|
||||
iconLight: 'support/permission/publicLight',
|
||||
label: '团队可编辑'
|
||||
label: i18nT('user:permission.team_write')
|
||||
},
|
||||
[PermissionTypeEnum.clbPrivate]: {
|
||||
iconLight: 'support/permission/privateLight',
|
||||
label: '仅协作者'
|
||||
label: i18nT('user:permission.only_collaborators')
|
||||
}
|
||||
};
|
||||
|
||||
@@ -53,19 +53,19 @@ export enum PermissionKeyEnum {
|
||||
}
|
||||
export const PermissionList: PermissionListType = {
|
||||
[PermissionKeyEnum.read]: {
|
||||
name: '读权限',
|
||||
name: i18nT('common:permission.read'),
|
||||
description: '',
|
||||
value: 0b100,
|
||||
checkBoxType: 'single'
|
||||
},
|
||||
[PermissionKeyEnum.write]: {
|
||||
name: '写权限',
|
||||
name: i18nT('common:permission.write'),
|
||||
description: '',
|
||||
value: 0b110, // 如果某个资源有特殊要求,再重写这个值
|
||||
checkBoxType: 'single'
|
||||
},
|
||||
[PermissionKeyEnum.manage]: {
|
||||
name: '管理员',
|
||||
name: i18nT('common:permission.manager'),
|
||||
description: '',
|
||||
value: 0b111,
|
||||
checkBoxType: 'single'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
import { NullPermission, PermissionKeyEnum, PermissionList } from '../constant';
|
||||
|
||||
export enum DatasetPermissionKeyEnum {}
|
||||
@@ -5,15 +6,15 @@ export enum DatasetPermissionKeyEnum {}
|
||||
export const DatasetPermissionList = {
|
||||
[PermissionKeyEnum.read]: {
|
||||
...PermissionList[PermissionKeyEnum.read],
|
||||
description: '可查看知识库内容'
|
||||
description: i18nT('dataset:permission.des.read')
|
||||
},
|
||||
[PermissionKeyEnum.write]: {
|
||||
...PermissionList[PermissionKeyEnum.write],
|
||||
description: '可增加和变更知识库内容'
|
||||
description: i18nT('dataset:permission.des.write')
|
||||
},
|
||||
[PermissionKeyEnum.manage]: {
|
||||
...PermissionList[PermissionKeyEnum.manage],
|
||||
description: '可管理整个知识库数据和信息'
|
||||
description: i18nT('dataset:permission.des.manage')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { PermissionKeyEnum, PermissionList, ReadPermissionVal } from '../constant';
|
||||
import { PermissionListType } from '../type';
|
||||
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
export const TeamPermissionList: PermissionListType = {
|
||||
[PermissionKeyEnum.read]: {
|
||||
...PermissionList[PermissionKeyEnum.read],
|
||||
description: '成员仅可阅读相关资源,无法新建资源'
|
||||
description: i18nT('user:permission_des.read')
|
||||
},
|
||||
[PermissionKeyEnum.write]: {
|
||||
...PermissionList[PermissionKeyEnum.write],
|
||||
description: '除了可读资源外,还可以新建新的资源'
|
||||
description: i18nT('user:permission_des.write')
|
||||
},
|
||||
[PermissionKeyEnum.manage]: {
|
||||
...PermissionList[PermissionKeyEnum.manage],
|
||||
description: '可创建资源、邀请、删除成员'
|
||||
description: i18nT('user:permission_des.manage')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@ export enum UserAuthTypeEnum {
|
||||
register = 'register',
|
||||
findPassword = 'findPassword',
|
||||
wxLogin = 'wxLogin',
|
||||
bindNotification = 'bindNotification'
|
||||
bindNotification = 'bindNotification',
|
||||
captcha = 'captcha'
|
||||
}
|
||||
|
||||
export const userAuthTypeMap = {
|
||||
[UserAuthTypeEnum.register]: 'register',
|
||||
[UserAuthTypeEnum.findPassword]: 'findPassword',
|
||||
[UserAuthTypeEnum.wxLogin]: 'wxLogin',
|
||||
[UserAuthTypeEnum.bindNotification]: 'bindNotification'
|
||||
[UserAuthTypeEnum.bindNotification]: 'bindNotification',
|
||||
[UserAuthTypeEnum.captcha]: 'captcha'
|
||||
};
|
||||
|
||||
29
packages/global/support/wallet/bill/api.d.ts
vendored
@@ -1,16 +1,25 @@
|
||||
import { StandardSubLevelEnum, SubModeEnum } from '../sub/constants';
|
||||
import { BillTypeEnum } from './constants';
|
||||
|
||||
export type CreateBillProps = {
|
||||
type: BillTypeEnum;
|
||||
|
||||
// balance
|
||||
balance?: number; // read
|
||||
|
||||
month?: number;
|
||||
// extra dataset size
|
||||
extraDatasetSize?: number; // 1k
|
||||
extraPoints?: number; // 100w
|
||||
export type CreateStandPlanBill = {
|
||||
type: BillTypeEnum.standSubPlan;
|
||||
level: `${StandardSubLevelEnum}`;
|
||||
subMode: `${SubModeEnum}`;
|
||||
};
|
||||
type CreateExtractPointsBill = {
|
||||
type: BillTypeEnum.extraPoints;
|
||||
extraPoints: number;
|
||||
};
|
||||
type CreateExtractDatasetBill = {
|
||||
type: BillTypeEnum.extraDatasetSub;
|
||||
extraDatasetSize: number;
|
||||
month: number;
|
||||
};
|
||||
export type CreateBillProps =
|
||||
| CreateStandPlanBill
|
||||
| CreateExtractPointsBill
|
||||
| CreateExtractDatasetBill;
|
||||
|
||||
export type CreateBillResponse = {
|
||||
billId: string;
|
||||
codeUrl: string;
|
||||
|
||||
@@ -19,7 +19,6 @@ export type BillSchemaType = {
|
||||
month?: number;
|
||||
datasetSize?: number;
|
||||
extraPoints?: number;
|
||||
invoice: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
|
||||
export enum SubTypeEnum {
|
||||
standard = 'standard',
|
||||
extraDatasetSize = 'extraDatasetSize',
|
||||
@@ -19,19 +21,6 @@ export const subTypeMap = {
|
||||
}
|
||||
};
|
||||
|
||||
export enum SubStatusEnum {
|
||||
active = 'active',
|
||||
expired = 'expired'
|
||||
}
|
||||
export const subStatusMap = {
|
||||
[SubStatusEnum.active]: {
|
||||
label: 'support.wallet.subscription.status.active'
|
||||
},
|
||||
[SubStatusEnum.expired]: {
|
||||
label: 'support.wallet.subscription.status.canceled'
|
||||
}
|
||||
};
|
||||
|
||||
export enum SubModeEnum {
|
||||
month = 'month',
|
||||
year = 'year'
|
||||
@@ -39,11 +28,13 @@ export enum SubModeEnum {
|
||||
export const subModeMap = {
|
||||
[SubModeEnum.month]: {
|
||||
label: 'support.wallet.subscription.mode.Month',
|
||||
durationMonth: 1
|
||||
durationMonth: 1,
|
||||
payMonth: 1
|
||||
},
|
||||
[SubModeEnum.year]: {
|
||||
label: 'support.wallet.subscription.mode.Year',
|
||||
durationMonth: 12
|
||||
durationMonth: 12,
|
||||
payMonth: 10
|
||||
}
|
||||
};
|
||||
|
||||
@@ -56,23 +47,28 @@ export enum StandardSubLevelEnum {
|
||||
}
|
||||
export const standardSubLevelMap = {
|
||||
[StandardSubLevelEnum.free]: {
|
||||
label: 'support.wallet.subscription.standardSubLevel.free',
|
||||
desc: 'support.wallet.subscription.standardSubLevel.free desc'
|
||||
label: i18nT('common:support.wallet.subscription.standardSubLevel.free'),
|
||||
desc: i18nT('common:support.wallet.subscription.standardSubLevel.free desc'),
|
||||
weight: 1
|
||||
},
|
||||
[StandardSubLevelEnum.experience]: {
|
||||
label: 'support.wallet.subscription.standardSubLevel.experience',
|
||||
desc: ''
|
||||
label: i18nT('common:support.wallet.subscription.standardSubLevel.experience'),
|
||||
desc: i18nT('common:support.wallet.subscription.standardSubLevel.experience_desc'),
|
||||
weight: 2
|
||||
},
|
||||
[StandardSubLevelEnum.team]: {
|
||||
label: 'support.wallet.subscription.standardSubLevel.team',
|
||||
desc: ''
|
||||
label: i18nT('common:support.wallet.subscription.standardSubLevel.team'),
|
||||
desc: i18nT('common:support.wallet.subscription.standardSubLevel.team_desc'),
|
||||
weight: 3
|
||||
},
|
||||
[StandardSubLevelEnum.enterprise]: {
|
||||
label: 'support.wallet.subscription.standardSubLevel.enterprise',
|
||||
desc: ''
|
||||
label: i18nT('common:support.wallet.subscription.standardSubLevel.enterprise'),
|
||||
desc: i18nT('common:support.wallet.subscription.standardSubLevel.enterprise_desc'),
|
||||
weight: 4
|
||||
},
|
||||
[StandardSubLevelEnum.custom]: {
|
||||
label: 'support.wallet.subscription.standardSubLevel.custom',
|
||||
desc: ''
|
||||
label: i18nT('common:support.wallet.subscription.standardSubLevel.custom'),
|
||||
desc: '',
|
||||
weight: 5
|
||||
}
|
||||
};
|
||||
|
||||
9
packages/global/support/wallet/sub/type.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { StandardSubLevelEnum, SubModeEnum, SubStatusEnum, SubTypeEnum } from './constants';
|
||||
import { StandardSubLevelEnum, SubModeEnum, SubTypeEnum } from './constants';
|
||||
|
||||
// Content of plan
|
||||
export type TeamStandardSubPlanItemType = {
|
||||
@@ -36,17 +36,14 @@ export type TeamSubSchema = {
|
||||
_id: string;
|
||||
teamId: string;
|
||||
type: `${SubTypeEnum}`;
|
||||
status: `${SubStatusEnum}`;
|
||||
startTime: Date;
|
||||
expiredTime: Date;
|
||||
price: number;
|
||||
|
||||
currentMode: `${SubModeEnum}`;
|
||||
nextMode: `${SubModeEnum}`;
|
||||
currentSubLevel: `${StandardSubLevelEnum}`;
|
||||
nextSubLevel: `${StandardSubLevelEnum}`;
|
||||
currentSubLevel: StandardSubLevelEnum;
|
||||
nextSubLevel: StandardSubLevelEnum;
|
||||
|
||||
pointPrice: number;
|
||||
totalPoints: number;
|
||||
surplusPoints: number;
|
||||
|
||||
|
||||
@@ -14,13 +14,13 @@ export enum UsageSourceEnum {
|
||||
|
||||
export const UsageSourceMap = {
|
||||
[UsageSourceEnum.fastgpt]: {
|
||||
label: '在线使用'
|
||||
label: i18nT('common:core.chat.logs.online')
|
||||
},
|
||||
[UsageSourceEnum.api]: {
|
||||
label: 'Api'
|
||||
},
|
||||
[UsageSourceEnum.shareLink]: {
|
||||
label: '免登录链接'
|
||||
label: i18nT('common:core.chat.logs.free_login')
|
||||
},
|
||||
[UsageSourceEnum.training]: {
|
||||
label: 'dataset.Training Name'
|
||||
|
||||
@@ -2,11 +2,14 @@ import { markdownProcess } from '@fastgpt/global/common/string/markdown';
|
||||
import { uploadMongoImg } from '../image/controller';
|
||||
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
|
||||
import { addHours } from 'date-fns';
|
||||
import FormData from 'form-data';
|
||||
|
||||
import { WorkerNameEnum, runWorker } from '../../../worker/utils';
|
||||
import fs from 'fs';
|
||||
import { detectFileEncoding } from '@fastgpt/global/common/file/tools';
|
||||
import type { ReadFileResponse } from '../../../worker/readFile/type';
|
||||
import axios from 'axios';
|
||||
import { addLog } from '../../system/log';
|
||||
|
||||
export type readRawTextByLocalFileParams = {
|
||||
teamId: string;
|
||||
@@ -51,15 +54,7 @@ export const readRawContentByFileBuffer = async ({
|
||||
metadata?: Record<string, any>;
|
||||
}) => {
|
||||
// Upload image in markdown
|
||||
const matchMdImgTextAndUpload = ({
|
||||
teamId,
|
||||
md,
|
||||
metadata
|
||||
}: {
|
||||
md: string;
|
||||
teamId: string;
|
||||
metadata?: Record<string, any>;
|
||||
}) =>
|
||||
const matchMdImgTextAndUpload = ({ teamId, md }: { md: string; teamId: string }) =>
|
||||
markdownProcess({
|
||||
rawText: md,
|
||||
uploadImgController: (base64Img) =>
|
||||
@@ -72,18 +67,63 @@ export const readRawContentByFileBuffer = async ({
|
||||
})
|
||||
});
|
||||
|
||||
let { rawText, formatText } = await runWorker<ReadFileResponse>(WorkerNameEnum.readFile, {
|
||||
extension,
|
||||
encoding,
|
||||
buffer
|
||||
});
|
||||
/* If */
|
||||
const customReadfileUrl = process.env.CUSTOM_READ_FILE_URL;
|
||||
const customReadFileExtension = process.env.CUSTOM_READ_FILE_EXTENSION || '';
|
||||
const ocrParse = process.env.CUSTOM_READ_FILE_OCR || 'false';
|
||||
const readFileFromCustomService = async (): Promise<ReadFileResponse | undefined> => {
|
||||
if (
|
||||
!customReadfileUrl ||
|
||||
!customReadFileExtension ||
|
||||
!customReadFileExtension.includes(extension)
|
||||
)
|
||||
return;
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
const data = new FormData();
|
||||
data.append('file', buffer, {
|
||||
filename: `file.${extension}`
|
||||
});
|
||||
data.append('extension', extension);
|
||||
data.append('ocr', ocrParse);
|
||||
const { data: response } = await axios.post<{
|
||||
success: boolean;
|
||||
message: string;
|
||||
data: {
|
||||
page: number;
|
||||
markdown: string;
|
||||
};
|
||||
}>(customReadfileUrl, data, {
|
||||
timeout: 600000,
|
||||
headers: {
|
||||
...data.getHeaders()
|
||||
}
|
||||
});
|
||||
|
||||
addLog.info(`Use custom read file service, time: ${Date.now() - start}ms`);
|
||||
|
||||
const rawText = response.data.markdown;
|
||||
|
||||
return {
|
||||
rawText,
|
||||
formatText: rawText
|
||||
};
|
||||
};
|
||||
|
||||
let { rawText, formatText } =
|
||||
(await readFileFromCustomService()) ||
|
||||
(await runWorker<ReadFileResponse>(WorkerNameEnum.readFile, {
|
||||
extension,
|
||||
encoding,
|
||||
buffer
|
||||
}));
|
||||
|
||||
// markdown data format
|
||||
if (['md', 'html', 'docx'].includes(extension)) {
|
||||
if (['md', 'html', 'docx', ...customReadFileExtension.split(',')].includes(extension)) {
|
||||
rawText = await matchMdImgTextAndUpload({
|
||||
teamId: teamId,
|
||||
md: rawText,
|
||||
metadata: metadata
|
||||
md: rawText
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -101,3 +101,5 @@ export const urlsFetch = async ({
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
export const loadContentByCheerio = async (content: string) => cheerio.load(content);
|
||||
|
||||
@@ -48,7 +48,7 @@ export class PgVectorCtrl {
|
||||
const { teamId, datasetId, collectionId, vector, retry = 3 } = props;
|
||||
|
||||
try {
|
||||
const { rows } = await PgClient.insert(DatasetVectorTableName, {
|
||||
const { rowCount, rows } = await PgClient.insert(DatasetVectorTableName, {
|
||||
values: [
|
||||
[
|
||||
{ key: 'vector', value: `[${vector}]` },
|
||||
@@ -58,6 +58,11 @@ export class PgVectorCtrl {
|
||||
]
|
||||
]
|
||||
});
|
||||
|
||||
if (rowCount === 0) {
|
||||
return Promise.reject('insertDatasetData: no insert');
|
||||
}
|
||||
|
||||
return {
|
||||
insertId: rows[0].id
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import { getAIApi } from '../config';
|
||||
import { countGptMessagesTokens } from '../../../common/string/tiktoken/index';
|
||||
import { loadRequestMessages } from '../../chat/utils';
|
||||
|
||||
export const Prompt_QuestionGuide = `你是一个AI智能助手,可以回答和解决我的问题。请结合前面的对话记录,帮我生成 3 个问题,引导我继续提问。问题的长度应小于20个字符,按 JSON 格式返回: ["问题1", "问题2", "问题3"]`;
|
||||
export const Prompt_QuestionGuide = `你是一个AI智能助手,可以回答和解决我的问题。请结合前面的对话记录,帮我生成 3 个问题,引导我继续提问,生成问题的语言要与原问题相同。问题的长度应小于20个字符,按 JSON 格式返回: ["问题1", "问题2", "问题3"]`;
|
||||
|
||||
export async function createQuestionGuide({
|
||||
messages,
|
||||
@@ -19,6 +19,7 @@ export async function createQuestionGuide({
|
||||
content: Prompt_QuestionGuide
|
||||
}
|
||||
];
|
||||
|
||||
const ai = getAIApi({
|
||||
timeout: 480000
|
||||
});
|
||||
|
||||
@@ -50,9 +50,11 @@ export const getAppLatestVersion = async (appId: string, app?: AppSchema) => {
|
||||
const version = await MongoAppVersion.findOne({
|
||||
appId,
|
||||
isPublish: true
|
||||
}).sort({
|
||||
time: -1
|
||||
});
|
||||
})
|
||||
.sort({
|
||||
time: -1
|
||||
})
|
||||
.lean();
|
||||
|
||||
if (version) {
|
||||
return {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/node.d';
|
||||
import { FlowNodeTypeEnum, defaultNodeVersion } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { pluginData2FlowNodeIO } from '@fastgpt/global/core/workflow/utils';
|
||||
import { appData2FlowNodeIO, pluginData2FlowNodeIO } from '@fastgpt/global/core/workflow/utils';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
import type { PluginRuntimeType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
@@ -52,10 +52,10 @@ const getPluginTemplateById = async (
|
||||
showStatus: true,
|
||||
workflow: {
|
||||
nodes: item.modules,
|
||||
edges: item.edges
|
||||
edges: item.edges,
|
||||
chatConfig: item.chatConfig
|
||||
},
|
||||
templateType: FlowNodeTemplateTypeEnum.teamApp,
|
||||
isTool: true,
|
||||
version: item?.pluginData?.nodeVersion || defaultNodeVersion,
|
||||
originCost: 0,
|
||||
currentCost: 0
|
||||
@@ -71,22 +71,27 @@ const getPluginTemplateById = async (
|
||||
/* format plugin modules to plugin preview module */
|
||||
export async function getPluginPreviewNode({ id }: { id: string }): Promise<FlowNodeTemplateType> {
|
||||
const plugin = await getPluginTemplateById(id);
|
||||
const isPlugin = !!plugin.workflow.nodes.find(
|
||||
(node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput
|
||||
);
|
||||
|
||||
return {
|
||||
id: getNanoid(),
|
||||
pluginId: plugin.id,
|
||||
templateType: plugin.templateType,
|
||||
flowNodeType: FlowNodeTypeEnum.pluginModule,
|
||||
flowNodeType: isPlugin ? FlowNodeTypeEnum.pluginModule : FlowNodeTypeEnum.appModule,
|
||||
avatar: plugin.avatar,
|
||||
name: plugin.name,
|
||||
intro: plugin.intro,
|
||||
inputExplanationUrl: plugin.inputExplanationUrl,
|
||||
showStatus: plugin.showStatus,
|
||||
isTool: plugin.isTool,
|
||||
isTool: isPlugin,
|
||||
version: plugin.version,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
...pluginData2FlowNodeIO(plugin.workflow.nodes)
|
||||
...(isPlugin
|
||||
? pluginData2FlowNodeIO({ nodes: plugin.workflow.nodes })
|
||||
: appData2FlowNodeIO({ chatConfig: plugin.workflow.chatConfig }))
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ const SystemPluginSchema = new Schema({
|
||||
currentCost: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
customConfig: Object
|
||||
});
|
||||
|
||||
SystemPluginSchema.index({ pluginId: 1 });
|
||||
|
||||
16
packages/service/core/app/plugin/type.d.ts
vendored
@@ -1,4 +1,8 @@
|
||||
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
|
||||
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import {
|
||||
SystemPluginTemplateItemType,
|
||||
WorkflowTemplateBasicType
|
||||
} from '@fastgpt/global/core/workflow/type';
|
||||
|
||||
export type SystemPluginConfigSchemaType = {
|
||||
pluginId: string;
|
||||
@@ -7,4 +11,14 @@ export type SystemPluginConfigSchemaType = {
|
||||
currentCost: number;
|
||||
isActive: boolean;
|
||||
inputConfig: SystemPluginTemplateItemType['inputConfig'];
|
||||
|
||||
customConfig?: {
|
||||
name: string;
|
||||
avatar: string;
|
||||
intro?: string;
|
||||
version: string;
|
||||
weight?: number;
|
||||
workflow: WorkflowTemplateBasicType;
|
||||
templateType: FlowNodeTemplateTypeEnum;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -18,7 +18,8 @@ export const chatConfigType = {
|
||||
whisperConfig: Object,
|
||||
scheduledTriggerConfig: Object,
|
||||
chatInputGuide: Object,
|
||||
fileSelectConfig: Object
|
||||
fileSelectConfig: Object,
|
||||
instruction: String
|
||||
};
|
||||
|
||||
// schema
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ChatItemType, ChatItemValueItemType } from '@fastgpt/global/core/chat/type';
|
||||
import { MongoChatItem } from './chatItemSchema';
|
||||
import { addLog } from '../../common/system/log';
|
||||
import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { ChatItemValueTypeEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { delFileByFileIdList, getGFSCollection } from '../../common/file/gridfs/controller';
|
||||
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import { MongoChat } from './chatSchema';
|
||||
@@ -35,7 +35,8 @@ export async function getChatItems({
|
||||
|
||||
return { histories };
|
||||
}
|
||||
/* 临时适配旧的对话记录 */
|
||||
|
||||
/* Temporary adaptation for old conversation records */
|
||||
export const adaptStringValue = (value: any): ChatItemValueItemType[] => {
|
||||
if (typeof value === 'string') {
|
||||
return [
|
||||
@@ -79,52 +80,6 @@ export const addCustomFeedbacks = async ({
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Update the user selected index of the interactive module
|
||||
*/
|
||||
export const updateUserSelectedResult = async ({
|
||||
appId,
|
||||
chatId,
|
||||
userSelectedVal
|
||||
}: {
|
||||
appId: string;
|
||||
chatId?: string;
|
||||
userSelectedVal: string;
|
||||
}) => {
|
||||
if (!chatId) return;
|
||||
try {
|
||||
const chatItem = await MongoChatItem.findOne(
|
||||
{ appId, chatId, obj: ChatRoleEnum.AI },
|
||||
'value'
|
||||
).sort({ _id: -1 });
|
||||
|
||||
if (!chatItem) return;
|
||||
|
||||
const interactiveValue = chatItem.value.find(
|
||||
(v) => v.type === ChatItemValueTypeEnum.interactive
|
||||
);
|
||||
|
||||
if (
|
||||
!interactiveValue ||
|
||||
interactiveValue.type !== ChatItemValueTypeEnum.interactive ||
|
||||
!interactiveValue.interactive?.params
|
||||
)
|
||||
return;
|
||||
|
||||
interactiveValue.interactive = {
|
||||
...interactiveValue.interactive,
|
||||
params: {
|
||||
...interactiveValue.interactive.params,
|
||||
userSelectedVal
|
||||
}
|
||||
};
|
||||
|
||||
await chatItem.save();
|
||||
} catch (error) {
|
||||
addLog.error('updateUserSelectedResult error', error);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Delete chat files
|
||||
1. ChatId: Delete one chat files
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import type { AIChatItemType, UserChatItemType } from '@fastgpt/global/core/chat/type.d';
|
||||
import { MongoApp } from '../app/schema';
|
||||
import { ChatSourceEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import {
|
||||
ChatItemValueTypeEnum,
|
||||
ChatRoleEnum,
|
||||
ChatSourceEnum
|
||||
} from '@fastgpt/global/core/chat/constants';
|
||||
import { MongoChatItem } from './chatItemSchema';
|
||||
import { MongoChat } from './chatSchema';
|
||||
import { addLog } from '../../common/system/log';
|
||||
@@ -111,3 +115,85 @@ export async function saveChat({
|
||||
addLog.error(`update chat history error`, error);
|
||||
}
|
||||
}
|
||||
|
||||
export const updateInteractiveChat = async ({
|
||||
chatId,
|
||||
appId,
|
||||
teamId,
|
||||
tmbId,
|
||||
userSelectedVal,
|
||||
aiResponse,
|
||||
newVariables,
|
||||
newTitle
|
||||
}: {
|
||||
chatId: string;
|
||||
appId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
userSelectedVal: string;
|
||||
aiResponse: AIChatItemType & { dataId?: string };
|
||||
newVariables?: Record<string, any>;
|
||||
newTitle: string;
|
||||
}) => {
|
||||
if (!chatId) return;
|
||||
|
||||
const chatItem = await MongoChatItem.findOne({ appId, chatId, obj: ChatRoleEnum.AI }).sort({
|
||||
_id: -1
|
||||
});
|
||||
|
||||
if (!chatItem || chatItem.obj !== ChatRoleEnum.AI) return;
|
||||
|
||||
const interactiveValue = chatItem.value[chatItem.value.length - 1];
|
||||
|
||||
if (
|
||||
!interactiveValue ||
|
||||
interactiveValue.type !== ChatItemValueTypeEnum.interactive ||
|
||||
!interactiveValue.interactive?.params
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
interactiveValue.interactive = {
|
||||
...interactiveValue.interactive,
|
||||
params: {
|
||||
...interactiveValue.interactive.params,
|
||||
userSelectedVal
|
||||
}
|
||||
};
|
||||
|
||||
if (aiResponse.customFeedbacks) {
|
||||
chatItem.customFeedbacks = chatItem.customFeedbacks
|
||||
? [...chatItem.customFeedbacks, ...aiResponse.customFeedbacks]
|
||||
: aiResponse.customFeedbacks;
|
||||
}
|
||||
|
||||
if (aiResponse.responseData) {
|
||||
chatItem.responseData = chatItem.responseData
|
||||
? [...chatItem.responseData, ...aiResponse.responseData]
|
||||
: aiResponse.responseData;
|
||||
}
|
||||
|
||||
if (aiResponse.value) {
|
||||
chatItem.value = chatItem.value ? [...chatItem.value, ...aiResponse.value] : aiResponse.value;
|
||||
}
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
await chatItem.save({ session });
|
||||
await MongoChat.updateOne(
|
||||
{
|
||||
appId,
|
||||
chatId
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
variables: newVariables,
|
||||
title: newTitle,
|
||||
updateTime: new Date()
|
||||
}
|
||||
},
|
||||
{
|
||||
session
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||