Feat: system tool support stream response (#5206)

* Match SSE for FastGPT (#5168)

* Match SSE for FastGPT

* Modify the judgment

* Optimize logic for SSE transmission

* Refactor imports

* directly use workflowStreamResponse from props

* improve error handling and streamline onStreamData logic

* Refactor API client configuration

* perf: system tool support sse

* update doc

---------

Co-authored-by: Zhuangzai fa <143257420+ctrlz526@users.noreply.github.com>
This commit is contained in:
Archer
2025-07-12 16:39:01 +08:00
committed by GitHub
parent b591a16399
commit dae1093139
11 changed files with 113 additions and 68 deletions

View File

@@ -1,5 +1,6 @@
import { getErrText } from '@fastgpt/global/common/error/utils';
import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import type { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import {
type DispatchNodeResultType,
@@ -9,11 +10,13 @@ import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { MCPClient } from '../../../app/mcp';
import { getSecretValue } from '../../../../common/secret/utils';
import type { McpToolDataType } from '@fastgpt/global/core/app/mcpTools/type';
import { runTool } from '../../../app/tool/api';
import { runSystemTool } from '../../../app/tool/api';
import { MongoSystemPlugin } from '../../../app/plugin/systemPluginSchema';
import { SystemToolInputTypeEnum } from '@fastgpt/global/core/app/systemTool/constants';
import type { StoreSecretValueType } from '@fastgpt/global/common/secret/type';
import { getSystemPluginById, splitCombinePluginId } from '../../../app/plugin/controller';
import { getSystemPluginById } from '../../../app/plugin/controller';
import { textAdaptGptResponse } from '@fastgpt/global/core/workflow/runtime/utils';
import { pushTrack } from '../../../../common/middle/tracks/utils';
type SystemInputConfigType = {
type: SystemToolInputTypeEnum;
@@ -39,13 +42,16 @@ export const dispatchRunTool = async (props: RunToolProps): Promise<RunToolRespo
runningUserInfo,
runningAppInfo,
variables,
workflowStreamResponse,
node: { name, avatar, toolConfig, version }
} = props;
const systemToolId = toolConfig?.systemTool?.toolId;
try {
// run system tool
if (toolConfig?.systemTool?.toolId) {
const tool = await getSystemPluginById(toolConfig.systemTool!.toolId);
if (systemToolId) {
const tool = await getSystemPluginById(systemToolId);
const inputConfigParams = await (async () => {
switch (params.system_input_config?.type) {
@@ -73,28 +79,47 @@ export const dispatchRunTool = async (props: RunToolProps): Promise<RunToolRespo
};
const formatToolId = tool.id.split('-')[1];
const result = await runTool({
toolId: formatToolId,
inputs,
systemVar: {
user: {
id: variables.userId,
teamId: runningUserInfo.teamId,
name: runningUserInfo.tmbId
},
app: {
id: runningAppInfo.id,
name: runningAppInfo.id
},
tool: {
id: formatToolId,
version
},
time: variables.cTime
}
});
const usagePoints = await (async () => {
const result = await (async () => {
const res = await runSystemTool({
toolId: formatToolId,
inputs,
systemVar: {
user: {
id: variables.userId,
teamId: runningUserInfo.teamId,
name: runningUserInfo.tmbId
},
app: {
id: runningAppInfo.id,
name: runningAppInfo.id
},
tool: {
id: formatToolId,
version
},
time: variables.cTime
},
onMessage: ({ type, content }) => {
if (workflowStreamResponse && content) {
workflowStreamResponse({
event: type as unknown as SseResponseEventEnum,
data: textAdaptGptResponse({
text: content
})
});
}
}
});
if (res.error) {
return Promise.reject(res.error);
}
if (!res.output) return {};
return res.output;
})();
const usagePoints = (() => {
if (
params.system_input_config?.type !== SystemToolInputTypeEnum.system ||
result[NodeOutputKeyEnum.systemError]
@@ -104,6 +129,16 @@ export const dispatchRunTool = async (props: RunToolProps): Promise<RunToolRespo
return tool.currentCost ?? 0;
})();
pushTrack.runSystemTool({
teamId: runningUserInfo.teamId,
tmbId: runningUserInfo.tmbId,
uid: runningUserInfo.tmbId,
toolId: tool.id,
result: 1,
usagePoint: usagePoints,
msg: result[NodeOutputKeyEnum.systemError]
});
return {
[DispatchNodeResponseKeyEnum.nodeResponse]: {
toolRes: result,
@@ -142,6 +177,17 @@ export const dispatchRunTool = async (props: RunToolProps): Promise<RunToolRespo
};
}
} catch (error) {
if (systemToolId) {
pushTrack.runSystemTool({
teamId: runningUserInfo.teamId,
tmbId: runningUserInfo.tmbId,
uid: runningUserInfo.tmbId,
toolId: systemToolId,
result: 0,
msg: getErrText(error)
});
}
return {
[DispatchNodeResponseKeyEnum.nodeResponse]: {
moduleLogo: avatar,