feat: toolcall stream response (#6009)
Some checks failed
Document deploy / sync-images (push) Has been cancelled
Build FastGPT images in Personal warehouse / get-vars (push) Has been cancelled
Document deploy / generate-timestamp (push) Has been cancelled
Document deploy / build-images (map[domain:https://fastgpt.cn suffix:cn]) (push) Has been cancelled
Document deploy / build-images (map[domain:https://fastgpt.io suffix:io]) (push) Has been cancelled
Document deploy / update-images (map[deployment:fastgpt-docs domain:https://fastgpt.cn kube_config:KUBE_CONFIG_CN suffix:cn]) (push) Has been cancelled
Document deploy / update-images (map[deployment:fastgpt-docs domain:https://fastgpt.io kube_config:KUBE_CONFIG_IO suffix:io]) (push) Has been cancelled
Build FastGPT images in Personal warehouse / build-fastgpt-images (map[arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
Build FastGPT images in Personal warehouse / build-fastgpt-images (map[arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
Build FastGPT images in Personal warehouse / release-fastgpt-images (push) Has been cancelled

This commit is contained in:
Archer 2025-11-29 09:24:47 +08:00 committed by GitHub
parent a7929bd565
commit b0a58b98f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 72 additions and 30 deletions

View File

@ -114,6 +114,7 @@ description: FastGPT 文档目录
- [/docs/upgrading/4-14/4141](/docs/upgrading/4-14/4141)
- [/docs/upgrading/4-14/4142](/docs/upgrading/4-14/4142)
- [/docs/upgrading/4-14/4143](/docs/upgrading/4-14/4143)
- [/docs/upgrading/4-14/4144](/docs/upgrading/4-14/4144)
- [/docs/upgrading/4-8/40](/docs/upgrading/4-8/40)
- [/docs/upgrading/4-8/41](/docs/upgrading/4-8/41)
- [/docs/upgrading/4-8/42](/docs/upgrading/4-8/42)

View File

@ -0,0 +1,18 @@
---
title: 'V4.14.4(进行中)'
description: 'FastGPT V4.14.4 更新说明'
---
## 🚀 新增内容
1. 工具调用支持配置流输出
## ⚙️ 优化
## 🐛 修复
## 插件

View File

@ -1,5 +1,5 @@
{
"title": "4.14.x",
"description": "",
"pages": ["4143", "4142", "4141", "4140"]
"pages": ["4144", "4143", "4142", "4141", "4140"]
}

View File

@ -117,7 +117,7 @@
"document/content/docs/upgrading/4-14/4140.mdx": "2025-11-06T15:43:00+08:00",
"document/content/docs/upgrading/4-14/4141.mdx": "2025-11-19T10:15:27+08:00",
"document/content/docs/upgrading/4-14/4142.mdx": "2025-11-18T19:27:14+08:00",
"document/content/docs/upgrading/4-14/4143.mdx": "2025-11-25T17:08:33+08:00",
"document/content/docs/upgrading/4-14/4143.mdx": "2025-11-26T20:52:05+08:00",
"document/content/docs/upgrading/4-8/40.mdx": "2025-08-02T19:38:37+08:00",
"document/content/docs/upgrading/4-8/41.mdx": "2025-08-02T19:38:37+08:00",
"document/content/docs/upgrading/4-8/42.mdx": "2025-08-02T19:38:37+08:00",

View File

@ -70,7 +70,8 @@ export const getHistoryPreview = (
item.text?.content || item?.tools?.map((item) => item.toolName).join(',') || ''
);
})
.join('') || ''
.join('')
.trim() || ''
);
}
return '';

View File

@ -52,6 +52,13 @@ export const AgentNode: FlowNodeTemplateType = {
label: '',
valueType: WorkflowIOValueTypeEnum.number
},
{
key: NodeInputKeyEnum.aiChatIsResponseText,
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: true,
valueType: WorkflowIOValueTypeEnum.boolean
},
{
key: NodeInputKeyEnum.aiChatVision,
renderTypeList: [FlowNodeInputTypeEnum.hidden],

View File

@ -265,7 +265,7 @@ export const loadRequestMessages = async ({
| undefined
) => {
if (typeof content === 'string') {
return content || '';
return content?.trim() || '';
}
// 交互节点
if (!content) return '';
@ -273,7 +273,10 @@ export const loadRequestMessages = async ({
const result = content.filter((item) => item?.type === 'text');
if (result.length === 0) return '';
return result.map((item) => item.text).join('\n');
return result
.map((item) => item.text)
.join('\n')
.trim();
};
if (messages.length === 0) {

View File

@ -57,7 +57,8 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
history = 6,
fileUrlList: fileLinks,
aiChatVision,
aiChatReasoning
aiChatReasoning,
isResponseAnswerText = true
}
} = props;
@ -235,7 +236,9 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
(sum, item) => sum + item.runTimes,
0
),
[DispatchNodeResponseKeyEnum.assistantResponses]: previewAssistantResponses,
[DispatchNodeResponseKeyEnum.assistantResponses]: isResponseAnswerText
? previewAssistantResponses
: undefined,
[DispatchNodeResponseKeyEnum.nodeResponse]: {
// 展示的积分消耗
totalPoints: totalPointsUsage,

View File

@ -33,7 +33,8 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo
aiChatStopSign,
aiChatResponseFormat,
aiChatJsonSchema,
aiChatReasoning
aiChatReasoning,
isResponseAnswerText = true
}
} = workflowProps;
@ -141,6 +142,7 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo
});
},
onStreaming({ text }) {
if (!isResponseAnswerText) return;
workflowStreamResponse?.({
write,
event: SseResponseEventEnum.answer,
@ -150,6 +152,7 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo
});
},
onToolCall({ call }) {
if (!isResponseAnswerText) return;
const toolNode = toolNodesMap.get(call.function.name);
if (toolNode) {
workflowStreamResponse?.({
@ -168,6 +171,7 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo
}
},
onToolParam({ tool, params }) {
if (!isResponseAnswerText) return;
workflowStreamResponse?.({
write,
event: SseResponseEventEnum.toolParams,
@ -209,18 +213,20 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo
// Format tool response
const stringToolResponse = formatToolResponse(toolRunResponse.toolResponses);
workflowStreamResponse?.({
event: SseResponseEventEnum.toolResponse,
data: {
tool: {
id: call.id,
toolName: '',
toolAvatar: '',
params: '',
response: sliceStrStartEnd(stringToolResponse, 5000, 5000)
if (isResponseAnswerText) {
workflowStreamResponse?.({
event: SseResponseEventEnum.toolResponse,
data: {
tool: {
id: call.id,
toolName: '',
toolAvatar: '',
params: '',
response: sliceStrStartEnd(stringToolResponse, 5000, 5000)
}
}
}
});
});
}
toolRunResponses.push(toolRunResponse);
@ -258,18 +264,20 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo
// console.dir(runtimeEdges, { depth: null });
const stringToolResponse = formatToolResponse(toolRunResponse.toolResponses);
workflowStreamResponse?.({
event: SseResponseEventEnum.toolResponse,
data: {
tool: {
id: toolParams.toolCallId,
toolName: '',
toolAvatar: '',
params: '',
response: sliceStrStartEnd(stringToolResponse, 5000, 5000)
if (isResponseAnswerText) {
workflowStreamResponse?.({
event: SseResponseEventEnum.toolResponse,
data: {
tool: {
id: toolParams.toolCallId,
toolName: '',
toolAvatar: '',
params: '',
response: sliceStrStartEnd(stringToolResponse, 5000, 5000)
}
}
}
});
});
}
toolRunResponses.push(toolRunResponse);
const assistantMessages = chats2GPTMessages({

View File

@ -31,6 +31,7 @@ export type DispatchToolModuleProps = ModuleDispatchProps<{
[NodeInputKeyEnum.aiSystemPrompt]: string;
[NodeInputKeyEnum.aiChatTemperature]: number;
[NodeInputKeyEnum.aiChatMaxToken]: number;
[NodeInputKeyEnum.aiChatIsResponseText]: boolean;
[NodeInputKeyEnum.aiChatVision]?: boolean;
[NodeInputKeyEnum.aiChatReasoning]?: boolean;
[NodeInputKeyEnum.aiChatTopP]?: number;