🐛 fix(Playground): Fix reasoning panel auto-collapse behavior to allow user control

- Add `hasAutoCollapsed` flag to track auto-collapse state
- Modify reasoning panel to auto-collapse only once after thinking completion
- Allow users to manually toggle reasoning panel after auto-collapse
- Update message creation, streaming updates, and completion handlers
- Ensure consistent behavior across stream/non-stream requests and error cases

Previously, the reasoning/thinking panel would auto-collapse every time
the AI completed its thinking process, preventing users from reopening
it to review the reasoning content. Now it auto-collapses only once
when thinking is complete, then allows full user control.

Files changed:
- web/src/hooks/useApiRequest.js: Updated all message handling functions
- web/src/utils/messageUtils.js: Added hasAutoCollapsed to initial state
This commit is contained in:
Apple\Apple
2025-05-31 01:29:19 +08:00
parent 02bc3cde53
commit caff73a746
2 changed files with 27 additions and 5 deletions

View File

@@ -65,12 +65,16 @@ export const useApiRequest = (
const isThinkingComplete = (lastMessage.reasoningContent && !lastMessage.isThinkingComplete) || const isThinkingComplete = (lastMessage.reasoningContent && !lastMessage.isThinkingComplete) ||
thinkingCompleteFromTags; thinkingCompleteFromTags;
// 只在第一次思考完成时自动关闭,之后由用户控制
const shouldAutoCollapse = isThinkingComplete && !lastMessage.hasAutoCollapsed;
newMessage = { newMessage = {
...newMessage, ...newMessage,
content: newContent, content: newContent,
status: MESSAGE_STATUS.INCOMPLETE, status: MESSAGE_STATUS.INCOMPLETE,
isThinkingComplete: isThinkingComplete, isThinkingComplete: isThinkingComplete,
isReasoningExpanded: (shouldCollapseReasoning || shouldCollapseFromThinkTag) hasAutoCollapsed: shouldAutoCollapse ? true : lastMessage.hasAutoCollapsed,
isReasoningExpanded: shouldAutoCollapse
? false : lastMessage.isReasoningExpanded, ? false : lastMessage.isReasoningExpanded,
}; };
} }
@@ -90,13 +94,18 @@ export const useApiRequest = (
lastMessage.status === MESSAGE_STATUS.ERROR) { lastMessage.status === MESSAGE_STATUS.ERROR) {
return prevMessage; return prevMessage;
} }
// 只在第一次思考完成时自动关闭,之后由用户控制
const shouldAutoCollapse = !lastMessage.hasAutoCollapsed;
return [ return [
...prevMessage.slice(0, -1), ...prevMessage.slice(0, -1),
{ {
...lastMessage, ...lastMessage,
status: status, status: status,
isThinkingComplete: true, isThinkingComplete: true,
isReasoningExpanded: false hasAutoCollapsed: shouldAutoCollapse ? true : lastMessage.hasAutoCollapsed,
isReasoningExpanded: shouldAutoCollapse ? false : lastMessage.isReasoningExpanded
} }
]; ];
}); });
@@ -163,13 +172,17 @@ export const useApiRequest = (
const newMessages = [...prevMessage]; const newMessages = [...prevMessage];
const lastMessage = newMessages[newMessages.length - 1]; const lastMessage = newMessages[newMessages.length - 1];
if (lastMessage?.status === MESSAGE_STATUS.LOADING) { if (lastMessage?.status === MESSAGE_STATUS.LOADING) {
// 只在第一次思考完成时自动关闭,之后由用户控制
const shouldAutoCollapse = !lastMessage.hasAutoCollapsed;
newMessages[newMessages.length - 1] = { newMessages[newMessages.length - 1] = {
...lastMessage, ...lastMessage,
content: processed.content, content: processed.content,
reasoningContent: processed.reasoningContent, reasoningContent: processed.reasoningContent,
status: MESSAGE_STATUS.COMPLETE, status: MESSAGE_STATUS.COMPLETE,
isThinkingComplete: true, isThinkingComplete: true,
isReasoningExpanded: false hasAutoCollapsed: shouldAutoCollapse ? true : lastMessage.hasAutoCollapsed,
isReasoningExpanded: shouldAutoCollapse ? false : lastMessage.isReasoningExpanded
}; };
} }
return newMessages; return newMessages;
@@ -189,12 +202,16 @@ export const useApiRequest = (
const newMessages = [...prevMessage]; const newMessages = [...prevMessage];
const lastMessage = newMessages[newMessages.length - 1]; const lastMessage = newMessages[newMessages.length - 1];
if (lastMessage?.status === MESSAGE_STATUS.LOADING) { if (lastMessage?.status === MESSAGE_STATUS.LOADING) {
// 只在第一次思考完成时自动关闭,之后由用户控制
const shouldAutoCollapse = !lastMessage.hasAutoCollapsed;
newMessages[newMessages.length - 1] = { newMessages[newMessages.length - 1] = {
...lastMessage, ...lastMessage,
content: t('请求发生错误: ') + error.message, content: t('请求发生错误: ') + error.message,
status: MESSAGE_STATUS.ERROR, status: MESSAGE_STATUS.ERROR,
isThinkingComplete: true, isThinkingComplete: true,
isReasoningExpanded: false hasAutoCollapsed: shouldAutoCollapse ? true : lastMessage.hasAutoCollapsed,
isReasoningExpanded: shouldAutoCollapse ? false : lastMessage.isReasoningExpanded
}; };
} }
return newMessages; return newMessages;
@@ -338,6 +355,9 @@ export const useApiRequest = (
lastMessage.reasoningContent || '' lastMessage.reasoningContent || ''
); );
// 只在第一次思考完成时自动关闭,之后由用户控制
const shouldAutoCollapse = !lastMessage.hasAutoCollapsed;
return [ return [
...prevMessage.slice(0, -1), ...prevMessage.slice(0, -1),
{ {
@@ -346,7 +366,8 @@ export const useApiRequest = (
reasoningContent: processed.reasoningContent || null, reasoningContent: processed.reasoningContent || null,
content: processed.content, content: processed.content,
isThinkingComplete: true, isThinkingComplete: true,
isReasoningExpanded: false hasAutoCollapsed: shouldAutoCollapse ? true : lastMessage.hasAutoCollapsed,
isReasoningExpanded: shouldAutoCollapse ? false : lastMessage.isReasoningExpanded
} }
]; ];
} }

View File

@@ -107,6 +107,7 @@ export const createLoadingAssistantMessage = () => createMessage(
reasoningContent: '', reasoningContent: '',
isReasoningExpanded: true, isReasoningExpanded: true,
isThinkingComplete: false, isThinkingComplete: false,
hasAutoCollapsed: false,
status: 'loading' status: 'loading'
} }
); );