fix: reasoning response (#3684)

* perf: supplement assistant empty response

* check array

* fix: reasoning response

* fix: reasoning response
This commit is contained in:
Archer
2025-02-03 14:21:54 +08:00
committed by archer
parent 9e100957eb
commit 2a209d43af
9 changed files with 71 additions and 43 deletions

View File

@@ -80,6 +80,7 @@ export type AppSimpleEditFormType = {
maxToken?: number; maxToken?: number;
isResponseAnswerText: boolean; isResponseAnswerText: boolean;
maxHistories: number; maxHistories: number;
[NodeInputKeyEnum.aiChatReasoning]?: boolean;
}; };
dataset: { dataset: {
datasets: SelectedDatasetType; datasets: SelectedDatasetType;

View File

@@ -16,7 +16,8 @@ export const getDefaultAppForm = (): AppSimpleEditFormType => {
temperature: 0, temperature: 0,
isResponseAnswerText: true, isResponseAnswerText: true,
maxHistories: 6, maxHistories: 6,
maxToken: 4000 maxToken: 4000,
aiChatReasoning: true
}, },
dataset: { dataset: {
datasets: [], datasets: [],

View File

@@ -88,7 +88,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
quoteTemplate, quoteTemplate,
quotePrompt, quotePrompt,
aiChatVision, aiChatVision,
aiChatReasoning, aiChatReasoning = true,
fileUrlList: fileLinks, // node quote file links fileUrlList: fileLinks, // node quote file links
stringQuoteText //abandon stringQuoteText //abandon
} }

View File

@@ -241,25 +241,28 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
// Histories store // Histories store
if (assistantResponses) { if (assistantResponses) {
chatAssistantResponse = chatAssistantResponse.concat(assistantResponses); chatAssistantResponse = chatAssistantResponse.concat(assistantResponses);
} else if (answerText) { } else {
// save assistant text response if (reasoningText) {
const isResponseAnswerText =
inputs.find((item) => item.key === NodeInputKeyEnum.aiChatIsResponseText)?.value ?? true;
if (isResponseAnswerText) {
chatAssistantResponse.push({ chatAssistantResponse.push({
type: ChatItemValueTypeEnum.text, type: ChatItemValueTypeEnum.reasoning,
text: { reasoning: {
content: answerText content: reasoningText
} }
}); });
} }
} else if (reasoningText) { if (answerText) {
chatAssistantResponse.push({ // save assistant text response
type: ChatItemValueTypeEnum.reasoning, const isResponseAnswerText =
reasoning: { inputs.find((item) => item.key === NodeInputKeyEnum.aiChatIsResponseText)?.value ?? true;
content: reasoningText if (isResponseAnswerText) {
chatAssistantResponse.push({
type: ChatItemValueTypeEnum.text,
text: {
content: answerText
}
});
} }
}); }
} }
if (rewriteHistories) { if (rewriteHistories) {

View File

@@ -244,7 +244,6 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
if (!httpJsonBody) return {}; if (!httpJsonBody) return {};
if (httpContentType === ContentTypes.json) { if (httpContentType === ContentTypes.json) {
httpJsonBody = replaceJsonBodyString(httpJsonBody); httpJsonBody = replaceJsonBodyString(httpJsonBody);
console.log(httpJsonBody);
return json5.parse(httpJsonBody); return json5.parse(httpJsonBody);
} }

View File

@@ -226,6 +226,25 @@ const ChatBox = ({
status, status,
moduleName: name moduleName: name
}; };
} else if (event === SseResponseEventEnum.answer && reasoningText) {
if (lastValue.type === ChatItemValueTypeEnum.reasoning && lastValue.reasoning) {
lastValue.reasoning.content += reasoningText;
return {
...item,
value: item.value.slice(0, -1).concat(lastValue)
};
} else {
const val: AIChatItemValueItemType = {
type: ChatItemValueTypeEnum.reasoning,
reasoning: {
content: reasoningText
}
};
return {
...item,
value: item.value.concat(val)
};
}
} else if ( } else if (
(event === SseResponseEventEnum.answer || event === SseResponseEventEnum.fastAnswer) && (event === SseResponseEventEnum.answer || event === SseResponseEventEnum.fastAnswer) &&
text text
@@ -248,25 +267,6 @@ const ChatBox = ({
value: item.value.slice(0, -1).concat(lastValue) value: item.value.slice(0, -1).concat(lastValue)
}; };
} }
} else if (event === SseResponseEventEnum.answer && reasoningText) {
if (lastValue.type === ChatItemValueTypeEnum.reasoning && lastValue.reasoning) {
lastValue.reasoning.content += reasoningText;
return {
...item,
value: item.value.slice(0, -1).concat(lastValue)
};
} else {
const val: AIChatItemValueItemType = {
type: ChatItemValueTypeEnum.reasoning,
reasoning: {
content: reasoningText
}
};
return {
...item,
value: item.value.concat(val)
};
}
} else if (event === SseResponseEventEnum.toolCall && tool) { } else if (event === SseResponseEventEnum.toolCall && tool) {
const val: AIChatItemValueItemType = { const val: AIChatItemValueItemType = {
type: ChatItemValueTypeEnum.tool, type: ChatItemValueTypeEnum.tool,

View File

@@ -142,15 +142,18 @@ ${toolResponse}`}
); );
const RenderResoningContent = React.memo(function RenderResoningContent({ const RenderResoningContent = React.memo(function RenderResoningContent({
content, content,
showAnimation isChatting,
isLastResponseValue
}: { }: {
content: string; content: string;
showAnimation: boolean; isChatting: boolean;
isLastResponseValue: boolean;
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const showAnimation = isChatting && isLastResponseValue;
return ( return (
<Accordion allowToggle defaultIndex={0}> <Accordion allowToggle defaultIndex={isLastResponseValue ? 0 : undefined}>
<AccordionItem borderTop={'none'} borderBottom={'none'}> <AccordionItem borderTop={'none'} borderBottom={'none'}>
<AccordionButton <AccordionButton
w={'auto'} w={'auto'}
@@ -341,7 +344,13 @@ const AIResponseBox = ({ value, isLastResponseValue, isChatting }: props) => {
<RenderText showAnimation={isChatting && isLastResponseValue} text={value.text.content} /> <RenderText showAnimation={isChatting && isLastResponseValue} text={value.text.content} />
); );
if (value.type === ChatItemValueTypeEnum.reasoning && value.reasoning) if (value.type === ChatItemValueTypeEnum.reasoning && value.reasoning)
return <RenderResoningContent showAnimation={isChatting} content={value.reasoning.content} />; return (
<RenderResoningContent
isChatting={isChatting}
isLastResponseValue={isLastResponseValue}
content={value.reasoning.content}
/>
);
if (value.type === ChatItemValueTypeEnum.tool && value.tools) if (value.type === ChatItemValueTypeEnum.tool && value.tools)
return <RenderTool showAnimation={isChatting} tools={value.tools} />; return <RenderTool showAnimation={isChatting} tools={value.tools} />;
if (value.type === ChatItemValueTypeEnum.interactive && value.interactive) { if (value.type === ChatItemValueTypeEnum.interactive && value.interactive) {

View File

@@ -138,9 +138,16 @@ const EditForm = ({
model: appForm.aiSettings.model, model: appForm.aiSettings.model,
temperature: appForm.aiSettings.temperature, temperature: appForm.aiSettings.temperature,
maxToken: appForm.aiSettings.maxToken, maxToken: appForm.aiSettings.maxToken,
maxHistories: appForm.aiSettings.maxHistories maxHistories: appForm.aiSettings.maxHistories,
aiChatReasoning: appForm.aiSettings.aiChatReasoning ?? true
}} }}
onChange={({ model, temperature, maxToken, maxHistories }: SettingAIDataType) => { onChange={({
model,
temperature,
maxToken,
maxHistories,
aiChatReasoning = false
}) => {
setAppForm((state) => ({ setAppForm((state) => ({
...state, ...state,
aiSettings: { aiSettings: {
@@ -148,7 +155,8 @@ const EditForm = ({
model, model,
temperature, temperature,
maxToken, maxToken,
maxHistories: maxHistories ?? 6 maxHistories: maxHistories ?? 6,
aiChatReasoning
} }
})); }));
}} }}

View File

@@ -190,6 +190,13 @@ export function form2AppWorkflow(
label: '', label: '',
valueType: WorkflowIOValueTypeEnum.boolean, valueType: WorkflowIOValueTypeEnum.boolean,
value: true value: true
},
{
key: NodeInputKeyEnum.aiChatReasoning,
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: formData.aiSettings.aiChatReasoning
} }
], ],
outputs: AiChatModule.outputs outputs: AiChatModule.outputs