diff --git a/docSite/assets/imgs/trigger1.png b/docSite/assets/imgs/trigger1.png deleted file mode 100644 index f2df2c25a..000000000 Binary files a/docSite/assets/imgs/trigger1.png and /dev/null differ diff --git a/docSite/assets/imgs/trigger2.png b/docSite/assets/imgs/trigger2.png deleted file mode 100644 index d66f66fca..000000000 Binary files a/docSite/assets/imgs/trigger2.png and /dev/null differ diff --git a/docSite/content/docs/development/faq.md b/docSite/content/docs/development/faq.md index c82692f9b..9223d6e9b 100644 --- a/docSite/content/docs/development/faq.md +++ b/docSite/content/docs/development/faq.md @@ -23,10 +23,6 @@ images: [] 可以。需要准备好向量模型和LLM模型。 -### 页面中可以正常回复,API 报错 - -页面中是用 stream=true 模式,所以API也需要设置 stream=true 来进行测试。部分模型接口(国产居多)非 Stream 的兼容有点垃圾。 - ### 其他模型没法进行问题分类/内容提取 1. 看日志。如果提示 JSON invalid,not support tool 之类的,说明该模型不支持工具调用或函数调用,需要设置`toolChoice=false`和`functionCall=false`,就会默认走提示词模式。目前内置提示词仅针对了商业模型API进行测试。问题分类基本可用,内容提取不太行。 @@ -43,12 +39,36 @@ images: [] 1. 问题补全需要经过一轮AI生成。 2. 会进行3~5轮的查询,如果数据库性能不足,会有明显影响。 -### 模型响应为空(core.chat.Chat API is error or undefined) +### 对话接口报错或返回为空(core.chat.Chat API is error or undefined) -1. 检查 key 问题。curl 请求看是否正常。务必用 stream=true 模式。并且 maxToken 等相关参数尽量一致。 +1. 检查 AI 的 key 问题:通过 curl 请求看是否正常。务必用 stream=true 模式。并且 maxToken 等相关参数尽量一致。 2. 如果是国内模型,可能是命中风控了。 3. 查看模型请求日志,检查出入参数是否异常。 +```sh +# curl 例子。 +curl --location --request POST 'https://xxx.cn/v1/chat/completions' \ +--header 'Authorization: Bearer sk-xxxx' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "model": "gpt-3.5-turbo", + "stream": true, + "temperature": 1, + "max_tokens": 3000, + "messages": [ + { + "role": "user", + "content": "你是谁" + } + ] +}' +``` + +### 页面中可以正常回复,API 报错 + +页面中是用 stream=true 模式,所以API也需要设置 stream=true 来进行测试。部分模型接口(国产居多)非 Stream 的兼容有点垃圾。 +和上一个问题一样,curl 测试。 + ### 知识库索引没有进度/索引很慢 先看日志报错信息。有以下几种情况: @@ -77,6 +97,8 @@ images: [] OneAPI 账号的余额不足,默认 root 用户只有 200 刀,可以手动修改。 +路径:打开OneAPI -> 用户 -> root用户右边的编辑 -> 剩余余额调大 + ### xxx渠道找不到 FastGPT 模型配置文件中的 model 必须与 OneAPI 渠道中的模型对应上,否则就会提示这个错误。可检查下面内容: diff --git a/docSite/content/docs/development/upgrading/48.md b/docSite/content/docs/development/upgrading/48.md index ad52ce4d2..80aea7b35 100644 --- a/docSite/content/docs/development/upgrading/48.md +++ b/docSite/content/docs/development/upgrading/48.md @@ -11,21 +11,45 @@ weight: 824 FastGPT workflow V2上线,支持更加简洁的工作流模式。 -**由于工作流差异较大,需要手动重新构建。** + +{{% alert icon="🤖 " context="success" %}} +**由于工作流差异较大,不少地方需要手动重新构建。请依次重建插件和应用** + +简易尽快更新工作流,避免未来持续迭代后导致无法兼容。 +{{% /alert %}} + 给应用和插件增加了 version 的字段,用于标识是旧工作流还是新工作流。当你更新 4.8 后,保存和新建的工作流均为新版,旧版工作流会有一个重置的弹窗提示。并且,如果是通过 API 和 分享链接 调用的工作流,仍可以正常使用,直到你下次保存它们。 +## 商业版配置更新 + +商业版用户如果配置了邮件验证码,需要在管理端 -> 项目配置 -> 登录配置 -> 邮箱登录配置 -> 修改 **邮箱服务SMTP地址**,之前只能配置别名,现在可以配置自定义的地址。下面是一组别名和实际地址关系: + +qq: smtp.qq.com +gmail: smtp.gmail.com + ## V4.8 更新说明 1. 重构 - 工作流 -2. 新增 - 判断器。支持 if elseIf else 判断。 -3. 新增 - 变量更新节点。支持更新运行中工作流输出变量,或更新全局变量。 -4. 新增 - 工作流 Debug 模式,可以调试单个节点或者逐步调试工作流。 -5. 新增 - 定时执行应用。可轻松实现定时任务。 -6. 新增 - 插件自定义输入优化,可以渲染输入组件。 -7. 优化 - 工作流连线,可以四向连接,方便构建循环工作流。 -8. 优化 - 工作流上下文传递,性能🚀。 -9. 优化 - 简易模式,更新配置后自动更新调试框内容,无需保存。 -10. 优化 - worker进程管理,并将计算 Token 任务分配给 worker 进程。 -11. 修复 - 工具调用时候,name不能是数字开头(随机数有概率数字开头) -12. 修复 - 分享链接, query 全局变量会被缓存。 \ No newline at end of file +2. 新增 - 判断器。支持 if elseIf else 判断。 @newfish-cmyk (preview版本的if else节点需要删除重建) +3. 新增 - 变量更新节点。支持更新运行中工作流输出变量,或更新全局变量。@newfish-cmyk +4. 新增 - 工作流自动保存和版本管理。 +5. 新增 - 工作流 Debug 模式,可以调试单个节点或者逐步调试工作流。 +6. 新增 - 定时执行应用。可轻松实现定时任务。 +7. 新增 - 插件自定义输入优化,可以渲染输入组件。 +8. 新增 - 分享链接发送对话前 hook https://github.com/labring/FastGPT/pull/1252 @gaord +9. 优化 - 工作流连线,可以四向连接,方便构建循环工作流。 +10. 优化 - 工作流上下文传递,性能🚀。 +11. 优化 - ctrl和alt+enter换行,换行符位置不正确。 +12. 优化 - chat中存储变量配置。避免修改变量后,影响旧的对话。 +13. 优化 - 简易模式,更新配置后自动更新调试框内容,无需保存。 +14. 优化 - worker进程管理,并将计算 Token 任务分配给 worker 进程。 +15. 优化 - 工具调用支持指定字段数据类型(string, boolean, number) https://github.com/labring/FastGPT/issues/1236 +16. 优化 - completions接口size限制 https://github.com/labring/FastGPT/issues/1241 +17. 优化 - Node api 中间件。优化 api 端代码。@c121914yu +18. 优化 - 对话记录保持为偶数进行截取,避免部分模型不支持奇数的历史记录,最大长度增加到50轮。 https://github.com/labring/FastGPT/issues/1384 +19. 优化 - HTTP节点错误后终止进程 https://github.com/labring/FastGPT/issues/1290 +20. 修复 - 工具调用时候,name不能是数字开头(随机数有概率数字开头)@c121914yu +21. 修复 - 分享链接, query 全局变量会被缓存。 @c121914yu +22. 修复 - 工具调用字段兼容。 https://github.com/labring/FastGPT/issues/1253 +23. 修复 - HTTP 模块url光标问题 https://github.com/labring/FastGPT/issues/1334 @maquannene \ No newline at end of file diff --git a/docSite/content/docs/workflow/modules/trigger.md b/docSite/content/docs/workflow/modules/trigger.md deleted file mode 100644 index 2dc7f7c68..000000000 --- a/docSite/content/docs/workflow/modules/trigger.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: "触发器" -description: "FastGPT 触发器模块介绍" -icon: "work_history" -draft: false -toc: true -weight: 360 ---- - -细心的同学可以发现,在每个功能模块里都会有一个叫【触发器】的外部输入,并且是 any 类型。 - -它的**核心作用**就是控制模块的执行时机,以下图两个知识库搜索中的【AI 对话】模块为例子: - -| 图 1 | 图 2 | -| ---------------------------- | ---------------------------- | -| ![](/imgs/trigger1.png) | ![](/imgs/trigger2.png) | - -【知识库搜索】模块中,由于**引用内容**始终会有输出,会导致【AI 对话】模块的**引用内容**输入无论有没有搜到内容都会被赋值。如果此时不连接触发器(图 2),在搜索结束后必定会执行【AI 对话】模块。 - -有时候,你可能希望空搜索时候进行额外处理,例如:回复固定内容、调用其他提示词的 GPT、发送一个 HTTP 请求…… 此时就需要用到触发器,需要将 **搜索结果不为空** 和 **触发器** 连接起来。 - -当搜索结果为空时,【知识库搜索】模块不会输出 **搜索结果不为空** 的结果,因此 【AI 对话】 模块的触发器始终为空,便不会执行。 - -总之,记住模块执行的逻辑就可以灵活的使用触发器:**外部输入字段(有连接的才有效)全部被赋值时才会被执行**。 diff --git a/packages/service/common/string/tiktoken/index.ts b/packages/service/common/string/tiktoken/index.ts index 686a380c9..1870cfe24 100644 --- a/packages/service/common/string/tiktoken/index.ts +++ b/packages/service/common/string/tiktoken/index.ts @@ -56,8 +56,8 @@ export const countGptMessagesTokens = ( clearTimeout(timer); // 检测是否有内存泄漏 - addLog.info(`Count token time: ${Date.now() - start}, token: ${data}`); - console.log(Object.keys(global.tiktokenWorker.callbackMap)); + // addLog.info(`Count token time: ${Date.now() - start}, token: ${data}`); + // console.log(Object.keys(global.tiktokenWorker.callbackMap)); }; worker.postMessage({ diff --git a/packages/web/package.json b/packages/web/package.json index 934f1c665..719536f40 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -24,7 +24,6 @@ "i18next": "23.10.0", "lexical": "0.12.6", "lodash": "^4.17.21", - "mammoth": "^1.6.0", "next-i18next": "15.2.0", "papaparse": "^5.4.1", "pdfjs-dist": "4.0.269", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b1740577..29364d5cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -277,9 +277,6 @@ importers: lodash: specifier: ^4.17.21 version: 4.17.21 - mammoth: - specifier: ^1.6.0 - version: 1.6.0 next-i18next: specifier: 15.2.0 version: 15.2.0(i18next@23.10.0)(next@13.5.2)(react-i18next@13.5.0)(react@18.2.0) diff --git a/projects/app/next.config.js b/projects/app/next.config.js index b8a87085a..1dc30f51b 100644 --- a/projects/app/next.config.js +++ b/projects/app/next.config.js @@ -86,12 +86,7 @@ const nextConfig = { serverComponentsExternalPackages: ['mongoose', 'pg'], // 指定导出包优化,按需引入包模块 optimizePackageImports: ['mongoose', 'pg'], - outputFileTracingRoot: path.join(__dirname, '../../'), - outputFileTracingIncludes: { - '/api/common/file/previewContent.ts': [ - path.resolve(process.cwd(), '../../packages/service/worker/**/*') - ] - } + outputFileTracingRoot: path.join(__dirname, '../../') } }; diff --git a/projects/app/src/components/core/workflow/Flow/nodes/render/NodeCard.tsx b/projects/app/src/components/core/workflow/Flow/nodes/render/NodeCard.tsx index 929db47a9..8691f0899 100644 --- a/projects/app/src/components/core/workflow/Flow/nodes/render/NodeCard.tsx +++ b/projects/app/src/components/core/workflow/Flow/nodes/render/NodeCard.tsx @@ -231,17 +231,20 @@ const MenuRender = React.memo(function MenuRender({ flowNodeType: node.data.flowNodeType, inputs: node.data.inputs, outputs: node.data.outputs, - showStatus: node.data.showStatus + showStatus: node.data.showStatus, + pluginId: node.data.pluginId }; return state.concat( storeNode2FlowNode({ item: { + flowNodeType: template.flowNodeType, + avatar: template.avatar, name: template.name, intro: template.intro, nodeId: getNanoid(), position: { x: node.position.x + 200, y: node.position.y + 50 }, - flowNodeType: template.flowNodeType, showStatus: template.showStatus, + pluginId: template.pluginId, inputs: template.inputs, outputs: template.outputs } diff --git a/projects/app/src/pages/api/core/app/update.ts b/projects/app/src/pages/api/core/app/update.ts index 83f9150d6..002f3b038 100644 --- a/projects/app/src/pages/api/core/app/update.ts +++ b/projects/app/src/pages/api/core/app/update.ts @@ -1,10 +1,7 @@ import type { NextApiRequest, NextApiResponse } from 'next'; -import { jsonRes } from '@fastgpt/service/common/response'; -import { connectToDatabase } from '@/service/mongo'; import { MongoApp } from '@fastgpt/service/core/app/schema'; import type { AppUpdateParams } from '@/global/core/app/api'; import { authApp } from '@fastgpt/service/support/permission/auth/app'; -import { getScheduleTriggerApp } from '@/service/core/app/utils'; import { beforeUpdateAppFormat } from '@fastgpt/service/core/app/controller'; import { NextAPI } from '@/service/middle/entry'; @@ -36,7 +33,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { avatar, intro, permission, - version: 'v2', ...(teamTags && teamTags), ...(formatNodes && { modules: formatNodes diff --git a/projects/app/src/pages/app/detail/components/FlowEdit/Header.tsx b/projects/app/src/pages/app/detail/components/FlowEdit/Header.tsx index 078c90459..bcfb3979f 100644 --- a/projects/app/src/pages/app/detail/components/FlowEdit/Header.tsx +++ b/projects/app/src/pages/app/detail/components/FlowEdit/Header.tsx @@ -51,6 +51,8 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({ > >; }) { + const isV2Workflow = app?.version === 'v2'; + const theme = useTheme(); const { toast } = useToast(); const { t } = useTranslation(); @@ -97,7 +99,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({ const onclickSave = useCallback( async (forbid?: boolean) => { // version preview / debug mode, not save - if (isShowVersionHistories || forbid) return; + if (!isV2Workflow || isShowVersionHistories || forbid) return; const { nodes } = await getWorkflowStore(); @@ -219,7 +221,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({ {app.name} - {!isShowVersionHistories && ( + {!isShowVersionHistories && isV2Workflow && ( ); }, [ - ConfirmModal, - app.name, - flowData2StoreDataAndCheck, + theme.borders.base, isSaving, - onExportWorkflow, - onOpenImport, - onclickPublish, - onclickSave, - openConfigPublish, - isShowVersionHistories, saveAndBack, - saveLabel, - setIsShowVersionHistories, - setWorkflowTestData, + app.name, + isShowVersionHistories, + isV2Workflow, t, - theme.borders.base + saveLabel, + onOpenImport, + onExportWorkflow, + openConfigPublish, + onclickPublish, + ConfirmModal, + onclickSave, + setIsShowVersionHistories, + flowData2StoreDataAndCheck, + setWorkflowTestData ]); return ( diff --git a/projects/app/src/pages/app/detail/components/FlowEdit/index.tsx b/projects/app/src/pages/app/detail/components/FlowEdit/index.tsx index 71bd08654..a5aa8bc72 100644 --- a/projects/app/src/pages/app/detail/components/FlowEdit/index.tsx +++ b/projects/app/src/pages/app/detail/components/FlowEdit/index.tsx @@ -15,7 +15,7 @@ const Render = ({ app, onClose }: Props) => { const { openConfirm, ConfirmModal } = useConfirm({ showCancel: false, content: - '检测到您的高级编排为旧版,系统将为您自动格式化成新版工作流。\n\n由于版本差异较大,会导致许多工作流无法正常排布,请重新手动连接工作流。如仍异常,可尝试删除对应节点后重新添加。\n\n你可以直接点击测试进行调试,无需点击保存,点击保存为新版工作流。' + '检测到您的高级编排为旧版,系统将为您自动格式化成新版工作流。\n\n由于版本差异较大,会导致一些工作流无法正常排布,请重新手动连接工作流。如仍异常,可尝试删除对应节点后重新添加。\n\n你可以直接点击调试进行工作流测试,调试完毕后点击发布。直到你点击发布,新工作流才会真正保存生效。\n\n在你发布新工作流前,自动保存不会生效。' }); const initData = useContextSelector(WorkflowContext, (v) => v.initData);