Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .cursor/design/core/app/workflow/error_catch.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
description:
globs:
alwaysApply: false
---
这是一个工作流节点报错捕获的设计文档。

# 背景

现在工作流运行节点若其中有一个报错,则整个工作流中断,无法继续运行,只有红色英文toast,不太友好。对于对工作流可控性要求高的用户,愿意通过编排为报错兜底。现有编排较麻烦。

这类似于代码里的 try catch 机制,用户可以获得 catch 的错误,而不是直接抛错并结束工作流。

# 实现效果

1. 部分节点可以拥有报错捕获选项,也就是 node 里 catchError 不为 undefined 的节点,catchError=true 代表启用报错捕获,catchError=false 代表不启用报错捕获。
2. 支持报错捕获节点,在输出栏右侧会有一个“错误捕获”的开关。
3. node 的 output 属性种,有一个`errorField`的字段,标识该输出是开启报错捕获时候,才会拥有的输出。
4. 开启报错捕获的节点,在运行错误时,不会阻塞后续节点运行,而是输出报错信息,并继续向下执行。
5. 开启报错捕获的节点,会多出一个“错误输出”的分支连线,错误时候会走错误的分支提示。

# 实现方案

1. FlowNodeCommonType 属性上增加一个`catchError`的可选 boolean 值。如果需要报错捕获的节点,则设置 true/false,标识启用报错捕获,并且设置默认是否启用报错捕获。
2. FlowNodeOutputTypeEnume增加一个 error 枚举值,表示该字段是错误时候才展示的输出。
3. IOTitle 组件里接收 catchError 字段,如果为 true,则在右侧展示“错误捕获”的开关。
4. 所有现有的 RenderOutput 的组件,都需要改造。传入的 flowOutputList 都不包含 hidden 和 error类型的。
5. 单独在`FastGPT/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderOutput`下新建一个`CatchError`的组件,用于专门渲染错误类型输出,同时有一个 SourceHandler。
37 changes: 19 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,40 +47,41 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b
## 💡 RoadMap

`1` 应用编排能力
- [x] 对话工作流、插件工作流
- [x] 工具调用
- [x] Code sandbox
- [x] 循环调用
- [x] 用户选择
- [x] 表单输入

`2` 知识库能力
- [x] 对话工作流、插件工作流,包含基础的 RPA 节点。
- [x] Agent 调用
- [x] 用户交互节点
- [x] 双向 MCP
- [ ] 上下文管理
- [ ] AI 生成工作流

`2` 应用调试能力
- [x] 知识库单点搜索测试
- [x] 对话时反馈引用并可修改与删除
- [x] 完整调用链路日志
- [ ] 应用评测
- [ ] 高级编排 DeBug 调试模式
- [ ] 应用节点日志

`3` 知识库能力
- [x] 多库复用,混用
- [x] chunk 记录修改和删除
- [x] 支持手动输入,直接分段,QA 拆分导入
- [x] 支持 txt,md,html,pdf,docx,pptx,csv,xlsx (有需要更多可 PR file loader),支持 url 读取、CSV 批量导入
- [x] 混合检索 & 重排
- [x] API 知识库
- [ ] 自定义文件读取服务
- [ ] 自定义分块服务

`3` 应用调试能力
- [x] 知识库单点搜索测试
- [x] 对话时反馈引用并可修改与删除
- [x] 完整上下文呈现
- [x] 完整模块中间值呈现
- [ ] 高级编排 DeBug 模式
- [ ] RAG 模块热插拔

`4` OpenAPI 接口
- [x] completions 接口 (chat 模式对齐 GPT 接口)
- [x] 知识库 CRUD
- [x] 对话 CRUD
- [ ] 完整 API Documents

`5` 运营能力
- [x] 免登录分享窗口
- [x] Iframe 一键嵌入
- [x] 聊天窗口嵌入支持自定义 Icon,默认打开,拖拽等功能
- [x] 统一查阅对话记录,并对数据进行标注
- [ ] 应用运营日志

`6` 其他
- [x] 可视化模型配置。
Expand Down
56 changes: 56 additions & 0 deletions docSite/content/zh-cn/docs/development/upgrading/4110.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: 'V4.11.0(进行中)'
description: 'FastGPT V4.11.0 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 783
---

<!-- ## 升级说明

### 1. 修改环境变量

FastGPT 商业版用户,可以增加评估相关环境变量,并在更新后,在管理端点击一次保存。

```
EVAL_CONCURRENCY=3 # 评估单节点并发数
EVAL_LINE_LIMIT=1000 # 评估文件最大行数
```

### 2. 更新镜像:

- 更新 FastGPT 镜像tag: v4.11.0
- 更新 FastGPT 商业版镜像tag: v4.11.0
- 更新 fastgpt-plugin 镜像 tag: v0.1.4
- mcp_server 无需更新
- Sandbox 无需更新
- AIProxy 无需更新 -->

## 项目调整

1. 移除所有**开源功能**的限制,包括:应用数量和知识库数量上限。
2. 调整 RoadMap,增加`上下文管理`,`AI 生成工作流`,`高级编排 DeBug 调试模式`等计划。

## 🚀 新增内容

1. 商业版增加**应用评测(Beta 版)**,可对应用进行有监督评分。
2. 工作流部分节点支持报错捕获分支。
3. 对话页独立 tab 页面UX。
4. 支持 Signoz traces 和 logs 系统追踪。
5. 新增 Gemini2.5, grok4, kimi 模型配置。
6. 模型调用日志增加首字响应时长和请求 IP。

## ⚙️ 优化

1. 优化代码,避免递归造成的内存堆积。
2. 知识库训练:支持全部重试当前集合异常数据。
3. 工作流 valueTypeFormat,避免数据类型不一致。

## 🐛 修复

1. 问题分类和内容提取节点,默认模型无法通过前端校验,导致工作流无法运行和保存发布。

## 🔨 工具更新

1. Markdown 文本转 Docx 和 Xlsx 文件。
7 changes: 3 additions & 4 deletions docSite/content/zh-cn/docs/shopping_cart/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,18 @@ FastGPT 商业版是基于 FastGPT 开源版的增强版本,增加了一些独
| 文档知识库 | ✅ | ✅ | ✅ |
| 外部使用 | ✅ | ✅ | ✅ |
| API 知识库 | ✅ | ✅ | ✅ |
| 最大应用数量 | 500 | 无限制 | 由付费套餐决定 |
| 最大知识库数量(单个知识库内容无限制) | 30 | 无限制 | 由付费套餐决定 |
| 自定义版权信息 | ❌ | ✅ | 设计中 |
| 多租户与支付 | ❌ | ✅ | ✅ |
| 团队空间 & 权限 | ❌ | ✅ | ✅ |
| 应用发布安全配置 | ❌ | ✅ | ✅ |
| 内容审核 | ❌ | ✅ | ✅ |
| 应用评测 | ❌ | ✅ | ✅ |
| web站点同步 | ❌ | ✅ | ✅ |
| 增强训练模式 | ❌ | ✅ | ✅ |
| 图片知识库 | ❌ | ✅ | ✅ |
| 知识库索引增强 | ❌ | ✅ | ✅ |
| 第三方应用快速接入(飞书、公众号) | ❌ | ✅ | ✅ |
| 管理后台 | ❌ | ✅ | 不需要 |
| SSO 登录(可自定义,也可使用内置:Github、公众号、钉钉、谷歌等) | ❌ | ✅ | 不需要 |
| 图片知识库 | ❌ | 设计中 | 设计中 |
| 对话日志运营分析 | ❌ | 设计中 | 设计中 |
| 完整商业授权 | ❌ | ✅ | ✅ |
{{< /table >}}
Expand Down
35 changes: 0 additions & 35 deletions env.d.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,8 @@
declare global {
namespace NodeJS {
interface ProcessEnv {
LOG_DEPTH: string;
DEFAULT_ROOT_PSW: string;
DB_MAX_LINK: string;
FILE_TOKEN_KEY: string;
AES256_SECRET_KEY: string;
ROOT_KEY: string;
OPENAI_BASE_URL: string;
CHAT_API_KEY: string;
AIPROXY_API_ENDPOINT: string;
AIPROXY_API_TOKEN: string;
MULTIPLE_DATA_TO_BASE64: string;
MONGODB_URI: string;
MONGODB_LOG_URI?: string;
PG_URL: string;
OCEANBASE_URL: string;
MILVUS_ADDRESS: string;
MILVUS_TOKEN: string;
SANDBOX_URL: string;
PRO_URL: string;
FE_DOMAIN: string;
FILE_DOMAIN: string;
NEXT_PUBLIC_BASE_URL: string;
LOG_LEVEL?: string;
STORE_LOG_LEVEL?: string;
USE_IP_LIMIT?: string;
WORKFLOW_MAX_RUN_TIMES?: string;
WORKFLOW_MAX_LOOP_TIMES?: string;
CHECK_INTERNAL_IP?: string;
CHAT_LOG_URL?: string;
CHAT_LOG_INTERVAL?: string;
CHAT_LOG_SOURCE_ID_PREFIX?: string;
ALLOWED_ORIGINS?: string;
SHOW_COUPON?: string;
CONFIG_JSON_PATH?: string;
PASSWORD_LOGIN_LOCK_SECONDS?: string;
PASSWORD_EXPIRED_MONTH?: string;
MAX_LOGIN_SESSION?: string;
}
}
}
Expand Down
5 changes: 0 additions & 5 deletions packages/global/common/error/code/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export enum UserErrEnum {
userExist = 'userExist',
unAuthRole = 'unAuthRole',
account_psw_error = 'account_psw_error',
balanceNotEnough = 'balanceNotEnough',
unAuthSso = 'unAuthSso'
}
const errList = [
Expand All @@ -22,10 +21,6 @@ const errList = [
statusText: UserErrEnum.account_psw_error,
message: i18nT('common:code_error.account_error')
},
{
statusText: UserErrEnum.balanceNotEnough,
message: i18nT('common:code_error.user_error.balance_not_enough')
},
{
statusText: UserErrEnum.unAuthSso,
message: i18nT('user:sso_auth_failed')
Expand Down
6 changes: 6 additions & 0 deletions packages/global/common/error/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { replaceSensitiveText } from '../string/tools';
import { ERROR_RESPONSE } from './errorCode';

export const getErrText = (err: any, def = ''): any => {
const msg: string =
Expand All @@ -12,6 +13,11 @@ export const getErrText = (err: any, def = ''): any => {
err?.msg ||
err?.error ||
def;

if (ERROR_RESPONSE[msg]) {
return ERROR_RESPONSE[msg].message;
}

// msg && console.log('error =>', msg);
return replaceSensitiveText(msg);
};
Expand Down
3 changes: 2 additions & 1 deletion packages/global/common/system/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export type FastGPTFeConfigsType = {
bind_notification_method?: ['email' | 'phone'];
googleClientVerKey?: string;
mcpServerProxyEndpoint?: string;
chineseRedirectUrl?: string;

show_emptyChat?: boolean;
show_appStore?: boolean;
Expand Down Expand Up @@ -82,7 +83,6 @@ export type FastGPTFeConfigsType = {
customSharePageDomain?: string;

systemTitle?: string;
systemDescription?: string;
scripts?: { [key: string]: string }[];
favicon?: string;

Expand All @@ -109,6 +109,7 @@ export type FastGPTFeConfigsType = {

uploadFileMaxAmount?: number;
uploadFileMaxSize?: number;
evalFileMaxLines?: number;

// Compute by systemEnv.customPdfParse
showCustomPdfParse?: boolean;
Expand Down
16 changes: 9 additions & 7 deletions packages/global/common/system/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ export const delay = (ms: number) =>
}, ms);
});

export const retryFn = async <T>(fn: () => Promise<T>, retryTimes = 3): Promise<T> => {
try {
return fn();
} catch (error) {
if (retryTimes > 0) {
export const retryFn = async <T>(fn: () => Promise<T>, attempts = 3): Promise<T> => {
while (true) {
try {
return fn();
} catch (error) {
if (attempts <= 0) {
return Promise.reject(error);
}
await delay(500);
return retryFn(fn, retryTimes - 1);
attempts--;
}
return Promise.reject(error);
}
};

Expand Down
1 change: 1 addition & 0 deletions packages/global/core/ai/model.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export type LLMModelItemType = PriceType &
usedInClassify?: boolean; // classify
usedInExtractFields?: boolean; // extract fields
usedInToolCall?: boolean; // tool call
useInEvaluation?: boolean; // evaluation

functionCall: boolean;
toolChoice: boolean;
Expand Down
20 changes: 20 additions & 0 deletions packages/global/core/app/evaluation/api.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { PaginationProps } from '@fastgpt/web/common/fetch/type';

export type listEvaluationsBody = PaginationProps<{
searchKey?: string;
}>;

export type listEvalItemsBody = PaginationProps<{
evalId: string;
}>;

export type retryEvalItemBody = {
evalItemId: string;
};

export type updateEvalItemBody = {
evalItemId: string;
question: string;
expectedResponse: string;
variables: Record<string, string>;
};
22 changes: 22 additions & 0 deletions packages/global/core/app/evaluation/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { i18nT } from '../../../../web/i18n/utils';

export const evaluationFileErrors = i18nT('dashboard_evaluation:eval_file_check_error');

export enum EvaluationStatusEnum {
queuing = 0,
evaluating = 1,
completed = 2
}

export const EvaluationStatusMap = {
[EvaluationStatusEnum.queuing]: {
name: i18nT('dashboard_evaluation:queuing')
},
[EvaluationStatusEnum.evaluating]: {
name: i18nT('dashboard_evaluation:evaluating')
},
[EvaluationStatusEnum.completed]: {
name: i18nT('dashboard_evaluation:completed')
}
};
export const EvaluationStatusValues = Object.keys(EvaluationStatusMap).map(Number);
Loading