From 2c81852773fcd171c712cad67bf71065475f6a69 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Mon, 9 Mar 2026 17:28:44 +0000 Subject: [PATCH] chore(ui): use same chat interface for agent Signed-off-by: Ettore Di Giacinto --- core/http/react-ui/src/App.css | 17 ++ core/http/react-ui/src/pages/AgentChat.jsx | 250 +++++++++------------ 2 files changed, 127 insertions(+), 140 deletions(-) diff --git a/core/http/react-ui/src/App.css b/core/http/react-ui/src/App.css index de5d536f4..792837ea8 100644 --- a/core/http/react-ui/src/App.css +++ b/core/http/react-ui/src/App.css @@ -1255,6 +1255,23 @@ background: var(--color-primary-light); } +.chat-message-system { + align-self: center; + max-width: 90%; +} +.chat-message-system .chat-message-bubble { + font-style: italic; + color: var(--color-text-secondary); + background: var(--color-bg-secondary); + border: 1px solid var(--color-border); + font-size: 0.8rem; +} +.chat-message-timestamp { + font-size: 0.6875rem; + color: var(--color-text-muted); + margin-top: 2px; +} + .chat-input-area { padding: var(--spacing-sm) var(--spacing-lg); background: var(--color-bg-secondary); diff --git a/core/http/react-ui/src/pages/AgentChat.jsx b/core/http/react-ui/src/pages/AgentChat.jsx index 3ed3669be..2211fcfc2 100644 --- a/core/http/react-ui/src/pages/AgentChat.jsx +++ b/core/http/react-ui/src/pages/AgentChat.jsx @@ -1,6 +1,8 @@ import { useState, useEffect, useRef, useCallback } from 'react' import { useParams, useNavigate, useOutletContext } from 'react-router-dom' import { agentsApi } from '../utils/api' +import { renderMarkdown, highlightAll } from '../utils/markdown' +import DOMPurify from 'dompurify' export default function AgentChat() { const { name } = useParams() @@ -10,6 +12,7 @@ export default function AgentChat() { const [input, setInput] = useState('') const [processing, setProcessing] = useState(false) const messagesEndRef = useRef(null) + const messagesRef = useRef(null) const textareaRef = useRef(null) const eventSourceRef = useRef(null) const messageIdCounter = useRef(0) @@ -88,6 +91,11 @@ export default function AgentChat() { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }) }, [messages]) + // Highlight code blocks + useEffect(() => { + if (messagesRef.current) highlightAll(messagesRef.current) + }, [messages]) + const handleSend = useCallback(async () => { const msg = input.trim() if (!msg || processing) return @@ -109,106 +117,26 @@ export default function AgentChat() { } } - return ( -
- + const copyMessage = (content) => { + navigator.clipboard.writeText(content) + addToast('Copied to clipboard', 'success', 2000) + } -
-

+ const senderToRole = (sender) => { + if (sender === 'agent') return 'assistant' + if (sender === 'user') return 'user' + return 'system' + } + + return ( +
+ {/* Header */} +
+ {name} -

-
+ +
@@ -218,29 +146,69 @@ export default function AgentChat() {
-
+ {/* Messages */} +
{messages.length === 0 && !processing && ( -
- Send a message to start chatting with {name}. -
- )} - {messages.map(msg => ( -
-
- {msg.sender === 'system' - ?
- :
{msg.content}
- } -
- {new Date(msg.timestamp).toLocaleTimeString()} -
+
+
+ +
+

Chat with {name}

+

Send a message to start a conversation with this agent.

+
+ Enter to send + Shift+Enter for newline
- ))} + )} + {messages.map(msg => { + const role = senderToRole(msg.sender) + + if (role === 'system') { + return ( +
+
+
+
+ {new Date(msg.timestamp).toLocaleTimeString()} +
+
+
+ ) + } + + return ( +
+
+ +
+
+
+ {role === 'user' ? ( +
/g, '>').replace(/\n/g, '
') }} /> + ) : ( +
+ )} +
+
+ +
+
+ {new Date(msg.timestamp).toLocaleTimeString()} +
+
+
+ ) + })} {processing && ( -
-
-
+
+
+ +
+
+
Thinking...
@@ -249,30 +217,32 @@ export default function AgentChat() {
-
-