Skip to content

Commit 357b7f1

Browse files
fix some bugs (#6210)
* fix v4.14.5 bugs * type * fix * fix * custom feedback * fix * code * fix * remove invalid function --------- Co-authored-by: archer <[email protected]>
1 parent 29baf39 commit 357b7f1

File tree

23 files changed

+232
-571
lines changed

23 files changed

+232
-571
lines changed

document/content/docs/upgrading/4-14/4145.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,11 @@ description: 'FastGPT V4.14.5 更新说明'
3636
5. 加载默认模型时,maxTokens 字段未赋值,导致模型最大响应值配置为空。
3737
6. S3 文件清理队列因网络稳定问题出现阻塞,导致删除任务不再执行。
3838
7. 对话日志接口适配 mongo4.x 语法。
39+
8. 变量更新节点将文件 URL 字符串数组错误转换为对象数组。
40+
9. 多个表单输入节点共享 sessionStorage 导致默认值不显示。
41+
10. 代码运行节点切换语言后,AI 仍使用旧语言生成代码。
42+
11. 多个自定义反馈节点并发写入触发数据库写入冲突。
43+
12. 交互节点后续的自定义反馈节点写入失败。
44+
3945

4046
## 插件

document/data/doc-last-modified.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
"document/content/docs/protocol/terms.en.mdx": "2025-12-15T23:36:54+08:00",
105105
"document/content/docs/protocol/terms.mdx": "2025-12-15T23:36:54+08:00",
106106
"document/content/docs/toc.en.mdx": "2025-08-04T13:42:36+08:00",
107-
"document/content/docs/toc.mdx": "2026-01-06T18:19:42+08:00",
107+
"document/content/docs/toc.mdx": "2026-01-06T13:25:46+08:00",
108108
"document/content/docs/upgrading/4-10/4100.mdx": "2025-08-02T19:38:37+08:00",
109109
"document/content/docs/upgrading/4-10/4101.mdx": "2025-09-08T20:07:20+08:00",
110110
"document/content/docs/upgrading/4-11/4110.mdx": "2025-08-05T23:20:39+08:00",
@@ -204,4 +204,4 @@
204204
"document/content/docs/use-cases/external-integration/openapi.mdx": "2025-09-29T11:34:11+08:00",
205205
"document/content/docs/use-cases/external-integration/wecom.mdx": "2025-12-10T20:07:05+08:00",
206206
"document/content/docs/use-cases/index.mdx": "2025-07-24T14:23:04+08:00"
207-
}
207+
}

packages/global/core/workflow/runtime/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export enum DispatchNodeResponseKeyEnum {
3131
interactive = 'INTERACTIVE', // is interactive
3232
runTimes = 'runTimes', // run times
3333
newVariables = 'newVariables', // new variables
34-
memories = 'system_memories' // memories
34+
memories = 'system_memories', // memories
35+
customFeedbacks = 'customFeedbacks' // custom feedbacks
3536
}
3637

3738
export const needReplaceReferenceInputTypeList = [

packages/global/core/workflow/runtime/type.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ export type ChatDispatchProps = {
6868
responseChatItemId?: string;
6969
histories: ChatItemType[];
7070
variables: Record<string, any>; // global variable
71-
cloneVariables: Record<string, any>;
7271
query: UserChatItemValueItemType[]; // trigger query
7372
chatConfig: AppSchema['chatConfig'];
7473
lastInteractive?: WorkflowInteractiveResponseType; // last interactive response
@@ -274,6 +273,7 @@ export type DispatchNodeResultType<T = {}, ERR = { [NodeOutputKeyEnum.errorText]
274273
[DispatchNodeResponseKeyEnum.newVariables]?: Record<string, any>;
275274
[DispatchNodeResponseKeyEnum.memories]?: Record<string, any>;
276275
[DispatchNodeResponseKeyEnum.interactive]?: InteractiveNodeResponseType;
276+
[DispatchNodeResponseKeyEnum.customFeedbacks]?: string[];
277277

278278
data?: T;
279279
error?: ERR;

packages/service/core/chat/controller.ts

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -195,47 +195,6 @@ export async function getChatItems({
195195
return { histories, total, hasMorePrev, hasMoreNext };
196196
}
197197

198-
export const addCustomFeedbacks = async ({
199-
appId,
200-
chatId,
201-
dataId,
202-
feedbacks
203-
}: {
204-
appId: string;
205-
chatId?: string;
206-
dataId?: string;
207-
feedbacks: string[];
208-
}) => {
209-
if (!chatId || !dataId) return;
210-
211-
try {
212-
await mongoSessionRun(async (session) => {
213-
// Add custom feedbacks to ChatItem
214-
await MongoChatItem.updateOne(
215-
{
216-
appId,
217-
chatId,
218-
dataId
219-
},
220-
{
221-
$push: { customFeedbacks: { $each: feedbacks } }
222-
},
223-
{ session }
224-
);
225-
226-
// Update ChatLog feedback statistics
227-
await updateChatFeedbackCount({
228-
appId,
229-
chatId,
230-
session
231-
});
232-
});
233-
} catch (error) {
234-
addLog.error('addCustomFeedbacks error', error);
235-
throw error;
236-
}
237-
};
238-
239198
/**
240199
* Update feedback count statistics for a chat in Chat table
241200
* This method aggregates feedback data from chatItems and updates the Chat table

packages/service/core/workflow/dispatch/child/runApp.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
131131
assistantResponses,
132132
runTimes,
133133
workflowInteractiveResponse,
134-
system_memories
134+
system_memories,
135+
customFeedbacks
135136
} = await runWorkflow({
136137
...props,
137138
usageId: undefined,
@@ -205,7 +206,8 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
205206
totalPoints: usagePoints
206207
}
207208
],
208-
[DispatchNodeResponseKeyEnum.toolResponses]: text
209+
[DispatchNodeResponseKeyEnum.toolResponses]: text,
210+
[DispatchNodeResponseKeyEnum.customFeedbacks]: customFeedbacks
209211
};
210212
} catch (error) {
211213
return getNodeErrResponse({ error });

packages/service/core/workflow/dispatch/index.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type {
2424
} from '@fastgpt/global/core/workflow/runtime/type';
2525
import type { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type.d';
2626
import { getErrText, UserError } from '@fastgpt/global/common/error/utils';
27-
import { ChatItemValueTypeEnum } from '@fastgpt/global/core/chat/constants';
27+
import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
2828
import { filterPublicNodeResponseData } from '@fastgpt/global/core/chat/utils';
2929
import {
3030
checkNodeRunStatus,
@@ -57,13 +57,12 @@ import { addPreviewUrlToChatItems, presignVariablesFileUrls } from '../../chat/u
5757
import type { MCPClient } from '../../app/mcp';
5858
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
5959
import { i18nT } from '../../../../web/i18n/utils';
60-
import { clone } from 'lodash';
6160
import { validateFileUrlDomain } from '../../../common/security/fileUrlValidator';
6261
import { delAgentRuntimeStopSign, shouldWorkflowStop } from './workflowStatus';
6362

6463
type Props = Omit<
6564
ChatDispatchProps,
66-
'checkIsStopping' | 'workflowDispatchDeep' | 'timezone' | 'externalProvider' | 'cloneVariables'
65+
'checkIsStopping' | 'workflowDispatchDeep' | 'timezone' | 'externalProvider'
6766
> & {
6867
runtimeNodes: RuntimeNodeItemType[];
6968
runtimeEdges: RuntimeEdgeItemType[];
@@ -182,7 +181,6 @@ export async function dispatchWorkFlow({
182181
}
183182

184183
// Get default variables
185-
const cloneVariables = clone(data.variables);
186184
const defaultVariables = {
187185
...externalProvider.externalWorkflowVariables,
188186
...(await getSystemVariables({
@@ -228,8 +226,7 @@ export async function dispatchWorkFlow({
228226
workflowDispatchDeep: 0,
229227
usageId: newUsageId,
230228
concatUsage,
231-
mcpClientMemory,
232-
cloneVariables
229+
mcpClientMemory
233230
}).finally(async () => {
234231
if (streamCheckTimer) {
235232
clearInterval(streamCheckTimer);
@@ -273,8 +270,7 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise<DispatchFlowR
273270
usageId,
274271
concatUsage,
275272
runningUserInfo: { teamId },
276-
mcpClientMemory,
277-
cloneVariables
273+
mcpClientMemory
278274
} = data;
279275

280276
// Over max depth
@@ -296,7 +292,6 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise<DispatchFlowR
296292
[DispatchNodeResponseKeyEnum.toolResponses]: null,
297293
[DispatchNodeResponseKeyEnum.newVariables]: runtimeSystemVar2StoreType({
298294
variables,
299-
cloneVariables,
300295
removeObj: externalProvider.externalWorkflowVariables,
301296
userVariablesConfigs: data.chatConfig?.variables
302297
}),
@@ -343,6 +338,7 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise<DispatchFlowR
343338
}
344339
| undefined;
345340
system_memories: Record<string, any> = {}; // Workflow node memories
341+
customFeedbackList: string[] = []; // Custom feedbacks collected from nodes
346342

347343
// Debug
348344
debugNextStepRunNodes: RuntimeNodeItemType[] = []; // 记录 Debug 模式下,下一个阶段需要执行的节点。
@@ -720,7 +716,8 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise<DispatchFlowR
720716
assistantResponses,
721717
rewriteHistories,
722718
runTimes = 1,
723-
system_memories: newMemories
719+
system_memories: newMemories,
720+
customFeedbacks
724721
}: NodeResponseCompleteType) => {
725722
// Add run times
726723
this.workflowRunTimes += runTimes;
@@ -737,6 +734,11 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise<DispatchFlowR
737734
this.chatResponses.push(responseData);
738735
}
739736

737+
// Collect custom feedbacks
738+
if (customFeedbacks && Array.isArray(customFeedbacks)) {
739+
this.customFeedbackList = this.customFeedbackList.concat(customFeedbacks);
740+
}
741+
740742
// Push usage in real time. Avoid a workflow usage a large number of points
741743
if (nodeDispatchUsages) {
742744
if (usageId) {
@@ -1120,14 +1122,15 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise<DispatchFlowR
11201122
[DispatchNodeResponseKeyEnum.toolResponses]: workflowQueue.toolRunResponse,
11211123
[DispatchNodeResponseKeyEnum.newVariables]: runtimeSystemVar2StoreType({
11221124
variables,
1123-
cloneVariables,
11241125
removeObj: externalProvider.externalWorkflowVariables,
11251126
userVariablesConfigs: data.chatConfig?.variables
11261127
}),
11271128
[DispatchNodeResponseKeyEnum.memories]:
11281129
Object.keys(workflowQueue.system_memories).length > 0
11291130
? workflowQueue.system_memories
11301131
: undefined,
1132+
[DispatchNodeResponseKeyEnum.customFeedbacks]:
1133+
workflowQueue.customFeedbackList.length > 0 ? workflowQueue.customFeedbackList : undefined,
11311134
durationSeconds
11321135
};
11331136
};

packages/service/core/workflow/dispatch/loop/runLoop.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
5151
const outputValueArr = interactiveData ? interactiveData.loopResult : [];
5252
const loopResponseDetail: ChatHistoryItemResType[] = [];
5353
let assistantResponses: AIChatItemValueItemType[] = [];
54+
const customFeedbacks: string[] = [];
5455
let totalPoints = 0;
5556
let newVariables: Record<string, any> = props.variables;
5657
let interactiveResponse: WorkflowInteractiveResponseType | undefined = undefined;
@@ -116,6 +117,11 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
116117
assistantResponses.push(...response.assistantResponses);
117118
totalPoints += response.flowUsages.reduce((acc, usage) => acc + usage.totalPoints, 0);
118119

120+
// Collect custom feedbacks
121+
if (response[DispatchNodeResponseKeyEnum.customFeedbacks]) {
122+
customFeedbacks.push(...response[DispatchNodeResponseKeyEnum.customFeedbacks]);
123+
}
124+
119125
// Concat new variables
120126
newVariables = {
121127
...newVariables,
@@ -163,6 +169,8 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
163169
}
164170
]
165171
: [],
166-
[DispatchNodeResponseKeyEnum.newVariables]: newVariables
172+
[DispatchNodeResponseKeyEnum.newVariables]: newVariables,
173+
[DispatchNodeResponseKeyEnum.customFeedbacks]:
174+
customFeedbacks.length > 0 ? customFeedbacks : undefined
167175
};
168176
};

packages/service/core/workflow/dispatch/plugin/run.ts

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -132,35 +132,41 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
132132
appId: String(plugin.id),
133133
...(externalProvider ? externalProvider.externalWorkflowVariables : {})
134134
};
135-
const { flowResponses, flowUsages, assistantResponses, runTimes, system_memories } =
136-
await runWorkflow({
137-
...props,
138-
usageId: undefined,
139-
// Rewrite stream mode
140-
...(system_forbid_stream
141-
? {
142-
stream: false,
143-
workflowStreamResponse: undefined
144-
}
145-
: {}),
146-
runningAppInfo: {
147-
id: String(plugin.id),
148-
name: plugin.name,
149-
// 如果系统插件有 teamId 和 tmbId,则使用系统插件的 teamId 和 tmbId(管理员指定了插件作为系统插件)
150-
teamId: plugin.teamId || runningAppInfo.teamId,
151-
tmbId: plugin.tmbId || runningAppInfo.tmbId,
152-
isChildApp: true
153-
},
135+
const {
136+
flowResponses,
137+
flowUsages,
138+
assistantResponses,
139+
runTimes,
140+
system_memories,
141+
[DispatchNodeResponseKeyEnum.customFeedbacks]: customFeedbacks
142+
} = await runWorkflow({
143+
...props,
144+
usageId: undefined,
145+
// Rewrite stream mode
146+
...(system_forbid_stream
147+
? {
148+
stream: false,
149+
workflowStreamResponse: undefined
150+
}
151+
: {}),
152+
runningAppInfo: {
153+
id: String(plugin.id),
154+
name: plugin.name,
155+
// 如果系统插件有 teamId 和 tmbId,则使用系统插件的 teamId 和 tmbId(管理员指定了插件作为系统插件)
156+
teamId: plugin.teamId || runningAppInfo.teamId,
157+
tmbId: plugin.tmbId || runningAppInfo.tmbId,
158+
isChildApp: true
159+
},
160+
variables: runtimeVariables,
161+
query: serverGetWorkflowToolRunUserQuery({
162+
pluginInputs: getWorkflowToolInputsFromStoreNodes(plugin.nodes),
154163
variables: runtimeVariables,
155-
query: serverGetWorkflowToolRunUserQuery({
156-
pluginInputs: getWorkflowToolInputsFromStoreNodes(plugin.nodes),
157-
variables: runtimeVariables,
158-
files
159-
}).value,
160-
chatConfig: {},
161-
runtimeNodes,
162-
runtimeEdges: storeEdges2RuntimeEdges(plugin.edges)
163-
});
164+
files
165+
}).value,
166+
chatConfig: {},
167+
runtimeNodes,
168+
runtimeEdges: storeEdges2RuntimeEdges(plugin.edges)
169+
});
164170
const output = flowResponses.find((item) => item.moduleType === FlowNodeTypeEnum.pluginOutput);
165171

166172
const usagePoints = await computedAppToolUsage({
@@ -200,7 +206,8 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
200206
acc[key] = output.pluginOutput![key];
201207
return acc;
202208
}, {})
203-
: null
209+
: null,
210+
[DispatchNodeResponseKeyEnum.customFeedbacks]: customFeedbacks
204211
};
205212
} catch (error) {
206213
return getNodeErrResponse({
Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
import {
2-
DispatchNodeResponseKeyEnum,
3-
SseResponseEventEnum
4-
} from '@fastgpt/global/core/workflow/runtime/constants';
1+
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
52
import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
63
import type { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
74
import { type DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
8-
import { addCustomFeedbacks } from '../../../chat/controller';
9-
import { textAdaptGptResponse } from '@fastgpt/global/core/workflow/runtime/utils';
105

116
type Props = ModuleDispatchProps<{
127
[NodeInputKeyEnum.textareaInput]: string;
@@ -15,37 +10,13 @@ type Response = DispatchNodeResultType<{}>;
1510

1611
export const dispatchCustomFeedback = (props: Record<string, any>): Response => {
1712
const {
18-
runningAppInfo: { id: appId },
19-
chatId,
20-
responseChatItemId: dataId,
21-
stream,
22-
workflowStreamResponse,
2313
params: { system_textareaInput: feedbackText = '' }
2414
} = props as Props;
2515

26-
setTimeout(() => {
27-
addCustomFeedbacks({
28-
appId,
29-
chatId,
30-
dataId,
31-
feedbacks: [feedbackText]
32-
});
33-
}, 60000);
34-
35-
if (stream) {
36-
if (!chatId || !dataId) {
37-
workflowStreamResponse?.({
38-
event: SseResponseEventEnum.fastAnswer,
39-
data: textAdaptGptResponse({
40-
text: `\n\n**自定义反馈成功: (仅调试模式下展示该内容)**: "${feedbackText}"\n\n`
41-
})
42-
});
43-
}
44-
}
45-
4616
return {
4717
[DispatchNodeResponseKeyEnum.nodeResponse]: {
4818
textOutput: feedbackText
49-
}
19+
},
20+
[DispatchNodeResponseKeyEnum.customFeedbacks]: [feedbackText]
5021
};
5122
};

0 commit comments

Comments
 (0)