diff options
author | A.J. Shulman <Shulman.aj@gmail.com> | 2024-08-20 15:17:25 -0400 |
---|---|---|
committer | A.J. Shulman <Shulman.aj@gmail.com> | 2024-08-20 15:17:25 -0400 |
commit | 4c0c7794c85cfdbcd61a7ee5cb9a29494fd0444b (patch) | |
tree | abf99fc24966e65a0e0db3f8e17ccb6edcff2d4c /src/client/views/nodes/ChatBox/MessageComponent.tsx | |
parent | 4b6ce2ffcb82c1a7467ef7ed8b67b97094a8f6b6 (diff) |
better styling, now thoughts and actions are hidden, scroll works better
next steps:
- [ ] Ensure it doesn’t create more web documents when one already exists
- [ ] Citations should not be rendered on the next line but on the same line as the text
- [ ] If invalid XML, run get 3.5 to verify and fix XML based one examples
- [ ] Making sure if you ask for other information, it doesn’t go to the same website. Providing website history in use rules for the search tool and website scraper tool or in the prompt directly
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> |