Skip to content

Commit 3097461

Browse files
committed
Enhance agent and buffer message UI components
Updated StreamingAgentMessage to improve message rendering, add bot tags, copy button, and sample data tag for assistant messages. Refined TeamSelected spacing using non-breaking spaces. Changed StreamingBufferMessage to show the last 500 characters of the buffer with a leading ellipsis for long messages.
1 parent 4b97c0f commit 3097461

File tree

4 files changed

+98
-23
lines changed

4 files changed

+98
-23
lines changed

src/frontend/src/components/common/TeamSelected.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ const TeamSelected: React.FC<TeamSelectedProps> = ({ selectedTeam }) => {
99
return (
1010
<div className={styles.teamSelectorContent}>
1111
<Caption1 className={styles.currentTeamLabel}>
12-
Current Team
12+
&nbsp;&nbsp;Current Team
1313
</Caption1>
1414
<Body1 className={styles.currentTeamName}>
15-
{" "} {selectedTeam ? selectedTeam.name : 'No team selected'}
15+
&nbsp;&nbsp;{selectedTeam ? selectedTeam.name : 'No team selected'}
1616
</Body1>
1717
</div>
1818
);

src/frontend/src/components/content/streaming/StreamingAgentMessage.tsx

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,109 @@
1-
import { AgentMessageData } from "@/models";
1+
import { AgentMessageData, AgentMessageType, role } from "@/models";
22
import ReactMarkdown from "react-markdown";
33
import remarkGfm from "remark-gfm";
44
import rehypePrism from "rehype-prism";
5+
import { Body1, Button, Tag } from "@fluentui/react-components";
6+
import { TaskService } from "@/services";
7+
import { Copy } from "@/coral/imports/bundleicons";
8+
import { DiamondRegular, HeartRegular } from "@fluentui/react-icons";
59

610

711
const StreamingAgentMessage = (agentMessages: AgentMessageData[]) => {
812
if (!agentMessages?.length) return null;
913

1014
// Filter out messages with empty content
1115
const validMessages = agentMessages.filter(msg => msg.raw_content?.trim());
12-
16+
const messages = validMessages;
1317
if (!validMessages.length) return null;
1418

1519
return (
16-
<div className="streaming-agent-messages">
17-
{validMessages.map((message, index) => (
18-
<div key={`${message.agent}-${message.timestamp}-${index}`} className="agent-message">
19-
<div className="agent-name">
20-
<strong>{message.agent}</strong>:
21-
</div>
22-
<div className="agent-content">
23-
<ReactMarkdown
24-
remarkPlugins={[remarkGfm]}
25-
rehypePlugins={[rehypePrism]}
26-
>
27-
{message.raw_content.trim()}
28-
</ReactMarkdown>
20+
// <div className="streaming-agent-messages">
21+
// {validMessages.map((message, index) => (
22+
// <div key={`${message.agent}-${message.timestamp}-${index}`} className="agent-message">
23+
// <div className="agent-name">
24+
// <strong>{message.agent}</strong>:
25+
// </div>
26+
// <div className="agent-content">
27+
// <ReactMarkdown
28+
// remarkPlugins={[remarkGfm]}
29+
// rehypePlugins={[rehypePrism]}
30+
// >
31+
// {message.raw_content.trim()}
32+
// </ReactMarkdown>
33+
// </div>
34+
// </div>
35+
// ))}
36+
// </div>
37+
38+
<div className="message-wrapper">
39+
{messages.map((msg, index) => {
40+
const isHuman = msg.agent_type === AgentMessageType.HUMAN_AGENT;
41+
42+
return (
43+
<div
44+
key={index}
45+
className={`message ${isHuman ? role.user : role.assistant}`}
46+
>
47+
{!isHuman && (
48+
<div className="plan-chat-header">
49+
<div className="plan-chat-speaker">
50+
<Body1 className="speaker-name">
51+
{TaskService.cleanTextToSpaces(msg.agent)}
52+
</Body1>
53+
<Tag
54+
size="extra-small"
55+
shape="rounded"
56+
appearance="brand"
57+
className="bot-tag"
58+
>
59+
BOT
60+
</Tag>
61+
</div>
62+
</div>
63+
)}
64+
65+
<Body1>
66+
<div className="plan-chat-message-content">
67+
<ReactMarkdown
68+
remarkPlugins={[remarkGfm]}
69+
rehypePlugins={[rehypePrism]}
70+
>
71+
{TaskService.cleanHRAgent(msg.raw_content) || ""}
72+
</ReactMarkdown>
73+
74+
{!isHuman && (
75+
<div className="assistant-footer">
76+
<div className="assistant-actions">
77+
<div>
78+
<Button
79+
onClick={() =>
80+
msg.raw_content &&
81+
navigator.clipboard.writeText(msg.raw_content)
82+
}
83+
title="Copy Response"
84+
appearance="subtle"
85+
style={{ height: 28, width: 28 }}
86+
icon={<Copy />}
87+
/>
88+
</div>
89+
90+
<Tag
91+
icon={<DiamondRegular />}
92+
appearance="filled"
93+
size="extra-small"
94+
>
95+
Sample data for demonstration purposes only.
96+
</Tag>
97+
</div>
98+
</div>
99+
)}
100+
</div>
101+
</Body1>
29102
</div>
30-
</div>
31-
))}
103+
);
104+
})}
32105
</div>
106+
33107
);
34108
};
35109

src/frontend/src/components/content/streaming/StreamingBufferMessage.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ const renderBufferMessage = (streamingMessageBuffer: string) => {
1212

1313
if (!streamingMessageBuffer || streamingMessageBuffer.trim() === "") return null;
1414

15-
const previewText = streamingMessageBuffer.length > 500
16-
? streamingMessageBuffer.substring(0, 500) + "..."
17-
: streamingMessageBuffer;
15+
const start = Math.max(0, streamingMessageBuffer.length - 500);
16+
const previewText = start === 0
17+
? streamingMessageBuffer
18+
: "..." + streamingMessageBuffer.substring(start);
1819

1920
return (
2021
<div style={{

src/frontend/src/pages/PlanPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ const PlanPage: React.FC = () => {
518518
streamingMessages={streamingMessages}
519519
wsConnected={wsConnected}
520520
onPlanApproval={(approved) => setPlanApproved(approved)}
521-
onPlanProcessing={(showProcessingPlanSpinner) => setShowProcessingPlanSpinner(showProcessingPlanSpinner)}
521+
setShowProcessingPlanSpinner={(showProcessingPlanSpinner) => setShowProcessingPlanSpinner(showProcessingPlanSpinner)}
522522
planApprovalRequest={planApprovalRequest}
523523
waitingForPlan={waitingForPlan}
524524
messagesContainerRef={messagesContainerRef}

0 commit comments

Comments
 (0)