Skip to content

Commit ca2e9d8

Browse files
committed
Add agent message streaming to plan chat
Introduces support for streaming agent messages in the plan chat by adding the AgentMessageData model, a new StreamingAgentMessage renderer, and updating PlanChat and PlanPage to handle and display agent messages. This enhances visibility into agent activity during plan generation.
1 parent 11f0c66 commit ca2e9d8

File tree

5 files changed

+49
-6
lines changed

5 files changed

+49
-6
lines changed

src/frontend/src/components/content/PlanChat.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,23 @@ import ChatInput from "../../coral/modules/ChatInput";
2424
import InlineToaster, {
2525
useInlineToaster,
2626
} from "../toast/InlineToaster";
27-
import { WebsocketMessageType } from "@/models";
27+
import { AgentMessageData, WebsocketMessageType } from "@/models";
2828
import getUserPlan from "./streaming/StreamingUserPlan";
2929
import renderUserPlanMessage from "./streaming/StreamingUserPlanMessage";
3030
import renderPlanResponse from "./streaming/StreamingPlanResponse";
3131
import renderThinkingState from "./streaming/StreamingPlanState";
3232
import ContentNotFound from "../NotFound/ContentNotFound";
3333
import PlanChatBody from "./PlanChatBody";
3434
import renderBufferMessage from "./streaming/StreamingBufferMessage";
35+
import renderAgentMessages from "./streaming/StreamingAgentMessage";
3536
interface SimplifiedPlanChatProps extends PlanChatProps {
3637
onPlanReceived?: (planData: MPlanData) => void;
3738
initialTask?: string;
3839
planApprovalRequest: MPlanData | null;
3940
waitingForPlan: boolean;
4041
messagesContainerRef: React.RefObject<HTMLDivElement>;
4142
streamingMessageBuffer: string;
42-
agentMessages: any[];
43+
agentMessages: AgentMessageData[];
4344
}
4445

4546
const PlanChat: React.FC<SimplifiedPlanChatProps> = ({
@@ -159,6 +160,8 @@ const PlanChat: React.FC<SimplifiedPlanChatProps> = ({
159160

160161
{/* Plan response with all information */}
161162
{renderPlanResponse(planApprovalRequest, handleApprovePlan, handleRejectPlan, processingApproval, showApprovalButtons)}
163+
{renderAgentMessages(agentMessages)}
164+
162165

163166
{/* Streaming plan updates */}
164167
{renderBufferMessage(streamingMessageBuffer)}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { AgentMessageData } from "@/models";
2+
3+
import ReactMarkdown from "react-markdown";
4+
import remarkGfm from "remark-gfm";
5+
import rehypePrism from "rehype-prism";
6+
// Render AI thinking/planning state
7+
const renderAgentMessages = (agentMessages: AgentMessageData[]) => {
8+
if (!agentMessages || agentMessages.length === 0) return null;
9+
10+
return (
11+
<div >
12+
{agentMessages.map((msg, index) => {
13+
const trimmed = msg.raw_content?.trim();
14+
if (!trimmed) return null; // skip if empty, null, or whitespace
15+
return (
16+
<div key={index} style={{ marginBottom: '16px' }}>
17+
<strong>{msg.agent}</strong>:
18+
<ReactMarkdown
19+
remarkPlugins={[remarkGfm]}
20+
rehypePlugins={[rehypePrism]}
21+
>
22+
{trimmed}
23+
</ReactMarkdown>
24+
</div>
25+
);
26+
})}
27+
</div>
28+
);
29+
};
30+
export default renderAgentMessages;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
import ReactMarkdown from "react-markdown";
88
import remarkGfm from "remark-gfm";
99
import rehypePrism from "rehype-prism";
10-
import { useState } from "react";
10+
1111
// Render AI thinking/planning state
1212
const renderBufferMessage = (streamingMessageBuffer: string) => {
1313
if (!streamingMessageBuffer || streamingMessageBuffer.trim() === "") return null;

src/frontend/src/models/agentMessage.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,12 @@ export interface AgentMessage extends BaseModel {
1717
/** Optional step identifier associated with the message */
1818
step_id?: string;
1919
}
20+
21+
export interface AgentMessageData {
22+
agent: string;
23+
timestamp: number;
24+
steps: any[]; // intentionally always empty
25+
next_steps: []; // intentionally always empty
26+
raw_content: string;
27+
raw_data: string;
28+
}

src/frontend/src/pages/PlanPage.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useRef, useState, useMemo } from "react"
22
import { useParams, useNavigate } from "react-router-dom";
33
import { Spinner, Text } from "@fluentui/react-components";
44
import { PlanDataService } from "../services/PlanDataService";
5-
import { ProcessedPlanData, PlanWithSteps, WebsocketMessageType, MPlanData } from "../models";
5+
import { ProcessedPlanData, PlanWithSteps, WebsocketMessageType, MPlanData, AgentMessageData } from "../models";
66
import PlanChat from "../components/content/PlanChat";
77
import PlanPanelRight from "../components/content/PlanPanelRight";
88
import PlanPanelLeft from "../components/content/PlanPanelLeft";
@@ -57,7 +57,7 @@ const PlanPage: React.FC = () => {
5757
// RAI Error state
5858
const [raiError, setRAIError] = useState<RAIErrorData | null>(null);
5959

60-
const [agentMessages, setAgentMessages] = useState<any[]>([]);
60+
const [agentMessages, setAgentMessages] = useState<AgentMessageData[]>([]);
6161
// Team config state
6262
const [teamConfig, setTeamConfig] = useState<TeamConfig | null>(null);
6363
const [loadingTeamConfig, setLoadingTeamConfig] = useState(true);
@@ -137,7 +137,8 @@ const PlanPage: React.FC = () => {
137137
useEffect(() => {
138138
const unsubscribe = webSocketService.on(WebsocketMessageType.AGENT_MESSAGE, (agentMessage: any) => {
139139
console.log('📋 Agent Message', agentMessage);
140-
setAgentMessages(prev => [...prev, agentMessage]);
140+
const agentMessageData = agentMessage.data as AgentMessageData;
141+
setAgentMessages(prev => [...prev, agentMessageData]);
141142
scrollToBottom();
142143
});
143144

0 commit comments

Comments
 (0)