From 0a3c7a20f335637241c4dfd8dfc2dae623b8319e Mon Sep 17 00:00:00 2001 From: "DASOL.HWANG" Date: Wed, 14 Jan 2026 13:57:33 +0900 Subject: [PATCH] feat: add reasoning content toggle for assistant messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add toggleable reasoning_content field for assistant role messages in the Agent block's messages input component. Features: - Added reasoning_content optional field to Message interface - Added '+ Reasoning' / '− Reasoning' toggle button for assistant messages - Reasoning content field appears/hides based on toggle state - Auto-shows reasoning content when existing data contains reasoning_content - Full support for variable references, env vars, and all existing features - Maintains clean UI by showing field only when needed This enables users to add reasoning/thinking content separately from the main response content, useful for: - o1/o3 models with reasoning capabilities - Few-shot learning examples with chain-of-thought - Debugging and transparency in agent responses --- .../messages-input/messages-input.tsx | 233 ++++++++++++++++-- 1 file changed, 211 insertions(+), 22 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/messages-input/messages-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/messages-input/messages-input.tsx index f81dd6ac5b..65cda2df16 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/messages-input/messages-input.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/messages-input/messages-input.tsx @@ -20,6 +20,7 @@ const MAX_TEXTAREA_HEIGHT_PX = 320 interface Message { role: 'system' | 'user' | 'assistant' content: string + reasoning_content?: string } /** @@ -60,6 +61,7 @@ export function MessagesInput({ const [localMessages, setLocalMessages] = useState([{ role: 'user', content: '' }]) const accessiblePrefixes = useAccessibleReferencePrefixes(blockId) const [openPopoverIndex, setOpenPopoverIndex] = useState(null) + const [showReasoningContent, setShowReasoningContent] = useState>({}) const subBlockInput = useSubBlockInput({ blockId, subBlockId, @@ -74,8 +76,24 @@ export function MessagesInput({ useEffect(() => { if (isPreview && previewValue && Array.isArray(previewValue)) { setLocalMessages(previewValue) + // Auto-show reasoning content if it exists + const reasoningMap: Record = {} + previewValue.forEach((msg, idx) => { + if (msg.role === 'assistant' && msg.reasoning_content) { + reasoningMap[idx] = true + } + }) + setShowReasoningContent(reasoningMap) } else if (messages && Array.isArray(messages) && messages.length > 0) { setLocalMessages(messages) + // Auto-show reasoning content if it exists + const reasoningMap: Record = {} + messages.forEach((msg, idx) => { + if (msg.role === 'assistant' && msg.reasoning_content) { + reasoningMap[idx] = true + } + }) + setShowReasoningContent(reasoningMap) } }, [isPreview, previewValue, messages]) @@ -117,6 +135,24 @@ export function MessagesInput({ [localMessages, setMessages, isPreview, disabled] ) + /** + * Updates a specific message's reasoning_content + */ + const updateMessageReasoningContent = useCallback( + (index: number, reasoning_content: string) => { + if (isPreview || disabled) return + + const updatedMessages = [...localMessages] + updatedMessages[index] = { + ...updatedMessages[index], + reasoning_content, + } + setLocalMessages(updatedMessages) + setMessages(updatedMessages) + }, + [localMessages, setMessages, isPreview, disabled] + ) + /** * Updates a specific message's role */ @@ -199,6 +235,21 @@ export function MessagesInput({ [localMessages, setMessages, isPreview, disabled] ) + /** + * Toggles reasoning content visibility for a message + */ + const toggleReasoningContent = useCallback( + (index: number) => { + if (isPreview || disabled) return + + setShowReasoningContent((prev) => ({ + ...prev, + [index]: !prev[index], + })) + }, + [isPreview, disabled] + ) + /** * Capitalizes the first letter of the role */ @@ -355,25 +406,26 @@ export function MessagesInput({ className='flex cursor-pointer items-center justify-between px-[8px] pt-[6px]' onClick={(e) => handleHeaderClick(index, e)} > - setOpenPopoverIndex(open ? index : null)} - > - - - +
+ setOpenPopoverIndex(open ? index : null)} + > + + +
{(['system', 'user', 'assistant'] as const).map((role) => ( @@ -390,10 +442,25 @@ export function MessagesInput({ ))}
-
+ +
{!isPreview && !disabled && ( -
+
+ {message.role === 'assistant' && ( + + )} {currentMessages.length > 1 && ( <>