aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/ChatBox/MessageComponent.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/ChatBox/MessageComponent.tsx')
-rw-r--r--src/client/views/nodes/ChatBox/MessageComponent.tsx97
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>