diff options
Diffstat (limited to 'src/client/views/nodes/ChatBox/MessageComponent.tsx')
-rw-r--r-- | src/client/views/nodes/ChatBox/MessageComponent.tsx | 97 |
1 files changed, 48 insertions, 49 deletions
diff --git a/src/client/views/nodes/ChatBox/MessageComponent.tsx b/src/client/views/nodes/ChatBox/MessageComponent.tsx index 0b8fa6b96..00e9795e3 100644 --- a/src/client/views/nodes/ChatBox/MessageComponent.tsx +++ b/src/client/views/nodes/ChatBox/MessageComponent.tsx @@ -1,7 +1,7 @@ -import React from 'react'; +import React, { useState } from 'react'; import { observer } from 'mobx-react'; import { AssistantMessage, Citation, MessageContent, PROCESSING_TYPE, ProcessingInfo, TEXT_TYPE } from './types'; -import Markdown from 'react-markdown'; +import ReactMarkdown from 'react-markdown'; interface MessageComponentProps { message: AssistantMessage; @@ -12,37 +12,20 @@ interface MessageComponentProps { } const MessageComponentBox: React.FC<MessageComponentProps> = function ({ message, index, onFollowUpClick, onCitationClick, updateMessageCitations }) { + const [dropdownOpen, setDropdownOpen] = useState(false); + const renderContent = (item: MessageContent) => { const i = item.index; if (item.type === TEXT_TYPE.GROUNDED) { const citation_ids = item.citation_ids || []; return ( <span key={i} className="grounded-text"> - {item.text} + <ReactMarkdown>{item.text}</ReactMarkdown> {citation_ids.map((id, idx) => { const citation = message.citations?.find(c => c.citation_id === id); if (!citation) return null; return ( - <button - key={i + idx} - className="citation-button" - onClick={() => onCitationClick(citation)} - style={{ - display: 'inline-flex', - alignItems: 'center', - justifyContent: 'center', - width: '20px', - height: '20px', - borderRadius: '50%', - border: 'none', - background: '#ff6347', - color: 'white', - fontSize: '12px', - fontWeight: 'bold', - cursor: 'pointer', - margin: '0 2px', - padding: 0, - }}> + <button key={i + idx} className="citation-button" onClick={() => onCitationClick(citation)}> {idx + 1} </button> ); @@ -52,49 +35,65 @@ const MessageComponentBox: React.FC<MessageComponentProps> = function ({ message } else if (item.type === TEXT_TYPE.NORMAL) { return ( <span key={i} className="normal-text"> - {item.text} + <ReactMarkdown>{item.text}</ReactMarkdown> </span> ); } else if ('query' in item) { - // Handle the case where the item has a query property return ( <span key={i} className="query-text"> - {JSON.stringify(item.query)} + <ReactMarkdown>{JSON.stringify(item.query)}</ReactMarkdown> </span> ); } else { - // Fallback for any other unexpected cases - return <span key={i}>{JSON.stringify(item)}</span>; + return ( + <span key={i}> + <ReactMarkdown>{JSON.stringify(item)}</ReactMarkdown> + </span> + ); } }; - console.log(message.processing_info); + const hasProcessingInfo = message.processing_info && message.processing_info.length > 0; + + const renderProcessingInfo = (info: ProcessingInfo) => { + if (info.type === PROCESSING_TYPE.THOUGHT) { + return ( + <div key={info.index} className="dropdown-item"> + <strong>Thought:</strong> {info.content} + </div> + ); + } else if (info.type === PROCESSING_TYPE.ACTION) { + return ( + <div key={info.index} className="dropdown-item"> + <strong>Action:</strong> {info.content} + </div> + ); + } else { + return null; + } + }; return ( <div className={`message ${message.role}`}> - {message.processing_info && - (message.processing_info as ProcessingInfo[]).map(item => - item.type === PROCESSING_TYPE.THOUGHT ? ( - <div key={item.index} className="thought"> - <strong>Thought:</strong> {item.content} - </div> - ) : item.type === PROCESSING_TYPE.ACTION ? ( - <div key={item.index} className="action"> - <strong>Action:</strong> {item.content} - </div> - ) : ( - <div key={item.index} className="error"></div> - ) - )} - <div>{message.content && message.content.map(messageFragment => <React.Fragment key={messageFragment.index}>{renderContent(messageFragment)}</React.Fragment>)}</div> + <div className="message-content">{message.content && message.content.map(messageFragment => <React.Fragment key={messageFragment.index}>{renderContent(messageFragment)}</React.Fragment>)}</div> + {hasProcessingInfo && ( + <div className="processing-info"> + <button className="toggle-info" onClick={() => setDropdownOpen(!dropdownOpen)}> + {dropdownOpen ? 'Hide Agent Thoughts/Actions' : 'Show Agent Thoughts/Actions'} + </button> + {dropdownOpen && <div className="info-content">{message.processing_info.map(renderProcessingInfo)}</div>} + </div> + )} {message.follow_up_questions && message.follow_up_questions.length > 0 && ( <div className="follow-up-questions"> <h4>Follow-up Questions:</h4> - {message.follow_up_questions.map((question, idx) => ( - <button key={idx} className="follow-up-button" onClick={() => onFollowUpClick(question)}> - {question} - </button> - ))} + <div className="questions-list"> + {message.follow_up_questions.map((question, idx) => ( + <button key={idx} className="follow-up-button" onClick={() => onFollowUpClick(question)}> + {question} + </button> + ))} + </div> </div> )} </div> |