Skip to content

Commit c915021

Browse files
committed
Refactor WebSocket message types and models
Moved WebSocket-related types (StreamMessage, StreamingPlanUpdate, etc.) from the service to the models directory for better separation of concerns. Introduced a WebsocketMessageType enum for consistent message type handling. Updated imports and usages across components, hooks, and services to use the new model definitions. Improved message handling logic in WebSocketService for clarity and maintainability.
1 parent 59867a4 commit c915021

File tree

9 files changed

+214
-317
lines changed

9 files changed

+214
-317
lines changed

src/frontend/src/components/content/PlanPanelRight.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ import {
1212
ClockRegular,
1313
PersonRegular,
1414
} from "@fluentui/react-icons";
15-
import { MPlanData } from "../../models";
15+
import { MPlanData, StreamingPlanUpdate } from "../../models";
1616
import { TaskService } from "../../services/TaskService";
17-
import { Step } from "../../models/plan";
1817
import { PlanDataService } from "../../services/PlanDataService";
19-
import webSocketService, { StreamingPlanUpdate } from "../../services/WebSocketService";
18+
import webSocketService from "../../services/WebSocketService";
2019
import ContentNotFound from "../NotFound/ContentNotFound";
2120

2221
// Clean interface - only display-related props

src/frontend/src/hooks/useWebSocket.tsx

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useCallback, useEffect, useRef, useState } from 'react';
2-
import { webSocketService, StreamMessage } from '../services/WebSocketService';
2+
import { webSocketService } from '@/services';
3+
import { StreamMessage } from '../models';
34

45
export interface WebSocketState {
56
isConnected: boolean;
@@ -15,7 +16,7 @@ export const useWebSocket = () => {
1516
isReconnecting: false,
1617
error: null
1718
});
18-
19+
1920
const isConnectedRef = useRef(false);
2021
const isConnectingRef = useRef(false);
2122
const lastSessionIdRef = useRef<string | null>(null);
@@ -32,54 +33,54 @@ export const useWebSocket = () => {
3233

3334
const connectWebSocket = useCallback(async (sessionId: string, processId?: string) => {
3435
if (isConnectedRef.current || isConnectingRef.current) return;
35-
36+
3637
setIsConnecting(true);
3738
lastSessionIdRef.current = sessionId;
3839
lastProcessIdRef.current = processId;
39-
40+
4041
try {
4142
await webSocketService.connect(sessionId, processId);
4243
isConnectedRef.current = true;
43-
setState(prev => ({
44-
...prev,
45-
isConnected: true,
46-
isConnecting: false,
47-
error: null
44+
setState(prev => ({
45+
...prev,
46+
isConnected: true,
47+
isConnecting: false,
48+
error: null
4849
}));
4950
} catch (error) {
5051
console.error('Failed to connect to WebSocket:', error);
5152
isConnectedRef.current = false;
5253
isConnectingRef.current = false;
53-
setState(prev => ({
54-
...prev,
55-
isConnected: false,
56-
isConnecting: false,
57-
error: 'Failed to connect to server'
54+
setState(prev => ({
55+
...prev,
56+
isConnected: false,
57+
isConnecting: false,
58+
error: 'Failed to connect to server'
5859
}));
5960
}
6061
}, [setIsConnecting]);
6162

6263
const reconnect = useCallback(async () => {
6364
if (!lastSessionIdRef.current) return;
64-
65+
6566
setIsReconnecting(true);
6667
try {
6768
await webSocketService.connect(lastSessionIdRef.current, lastProcessIdRef.current);
6869
isConnectedRef.current = true;
69-
setState(prev => ({
70-
...prev,
71-
isConnected: true,
72-
isReconnecting: false,
73-
error: null
70+
setState(prev => ({
71+
...prev,
72+
isConnected: true,
73+
isReconnecting: false,
74+
error: null
7475
}));
7576
} catch (error) {
7677
console.error('Failed to reconnect to WebSocket:', error);
7778
isConnectedRef.current = false;
78-
setState(prev => ({
79-
...prev,
80-
isConnected: false,
81-
isReconnecting: false,
82-
error: 'Failed to reconnect to server'
79+
setState(prev => ({
80+
...prev,
81+
isConnected: false,
82+
isReconnecting: false,
83+
error: 'Failed to reconnect to server'
8384
}));
8485
}
8586
}, [setIsReconnecting]);
@@ -88,11 +89,11 @@ export const useWebSocket = () => {
8889
webSocketService.disconnect();
8990
isConnectedRef.current = false;
9091
isConnectingRef.current = false;
91-
setState(prev => ({
92-
...prev,
93-
isConnected: false,
94-
isConnecting: false,
95-
isReconnecting: false
92+
setState(prev => ({
93+
...prev,
94+
isConnected: false,
95+
isConnecting: false,
96+
isReconnecting: false
9697
}));
9798
}, []);
9899

@@ -102,8 +103,8 @@ export const useWebSocket = () => {
102103
if (message.data?.connected !== undefined) {
103104
const connected = message.data.connected;
104105
isConnectedRef.current = connected;
105-
setState(prev => ({
106-
...prev,
106+
setState(prev => ({
107+
...prev,
107108
isConnected: connected,
108109
isConnecting: false,
109110
isReconnecting: false,
@@ -115,10 +116,10 @@ export const useWebSocket = () => {
115116
// Set up error listener
116117
const unsubscribeError = webSocketService.on('error', (message: StreamMessage) => {
117118
isConnectedRef.current = false;
118-
setState(prev => ({
119-
...prev,
119+
setState(prev => ({
120+
...prev,
120121
isConnected: false,
121-
error: message.data?.error || 'WebSocket error occurred'
122+
error: message.data?.error || 'WebSocket error occurred'
122123
}));
123124
});
124125

src/frontend/src/models/enums.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,19 @@ export enum HumanFeedbackStatus {
235235
ACCEPTED = "accepted",
236236
REJECTED = "rejected"
237237
}
238+
239+
export enum WebsocketMessageType {
240+
SYSTEM_MESSAGE = "system_message",
241+
AGENT_MESSAGE = "agent_message",
242+
AGENT_STREAM_START = "agent_stream_start",
243+
AGENT_STREAM_END = "agent_stream_end",
244+
AGENT_MESSAGE_STREAMING = "agent_message_streaming",
245+
AGENT_TOOL_MESSAGE = "agent_tool_message",
246+
PLAN_APPROVAL_REQUEST = "plan_approval_request",
247+
PLAN_APPROVAL_RESPONSE = "plan_approval_response",
248+
REPLAN_APPROVAL_REQUEST = "replan_approval_request",
249+
REPLAN_APPROVAL_RESPONSE = "replan_approval_response",
250+
USER_CLARIFICATION_REQUEST = "user_clarification_request",
251+
USER_CLARIFICATION_RESPONSE = "user_clarification_response",
252+
FINAL_RESULT_MESSAGE = "final_result_message"
253+
}

src/frontend/src/models/index.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,5 @@ export type { Agent as TaskAgent } from './taskDetails';
2222
// Export Team models (Agent interface takes precedence)
2323
export * from './Team';
2424

25-
// Export WebSocket service types that are needed by components
26-
export type {
27-
StreamingPlanUpdate,
28-
StreamMessage,
29-
ParsedPlanApprovalRequest
30-
} from '../services/WebSocketService';
3125

3226
// Add other model exports as needed

src/frontend/src/models/messages.tsx

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { AgentType, StepStatus, PlanStatus } from './enums';
1+
import { AgentType, StepStatus, PlanStatus, WebsocketMessageType } from './enums';
2+
import { MPlanData } from './plan';
23

34
/**
45
* Message roles compatible with Semantic Kernel
@@ -114,4 +115,57 @@ export interface PlanStateUpdate {
114115
session_id: string;
115116
/** Overall status of the plan */
116117
overall_status: PlanStatus;
118+
}
119+
120+
121+
122+
export interface StreamMessage {
123+
type: WebsocketMessageType
124+
plan_id?: string;
125+
session_id?: string;
126+
data?: any;
127+
timestamp?: string | number;
128+
}
129+
130+
export interface StreamingPlanUpdate {
131+
plan_id: string;
132+
session_id?: string;
133+
step_id?: string;
134+
agent_name?: string;
135+
content?: string;
136+
status?: 'in_progress' | 'completed' | 'error' | 'creating_plan' | 'pending_approval';
137+
message_type?: 'thinking' | 'action' | 'result' | 'clarification_needed' | 'plan_approval_request';
138+
timestamp?: number;
139+
is_final?: boolean;
140+
}
141+
142+
export interface PlanApprovalRequestData {
143+
plan_id: string;
144+
session_id: string;
145+
plan: {
146+
steps: Array<{
147+
id: string;
148+
description: string;
149+
agent: string;
150+
estimated_duration?: string;
151+
}>;
152+
total_steps: number;
153+
estimated_completion?: string;
154+
};
155+
status: 'PENDING_APPROVAL';
156+
}
157+
158+
export interface PlanApprovalResponseData {
159+
plan_id: string;
160+
session_id: string;
161+
approved: boolean;
162+
feedback?: string;
163+
}
164+
165+
// Structured plan approval request
166+
export interface ParsedPlanApprovalRequest {
167+
type: 'parsed_plan_approval_request';
168+
plan_id: string;
169+
parsedData: MPlanData;
170+
rawData: string;
117171
}

src/frontend/src/models/plan.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { AgentType, PlanStatus, StepStatus, HumanFeedbackStatus } from './enums';
2-
import { StreamingPlanUpdate } from '../services/WebSocketService';
2+
import { StreamingPlanUpdate } from './messages';
33

44
/**
55
* Base interface with common fields

src/frontend/src/pages/PlanPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import LoadingMessage, { loadingMessages } from "../coral/components/LoadingMess
2020
import { RAIErrorCard, RAIErrorData } from "../components/errors";
2121
import { TeamConfig } from "../models/Team";
2222
import { TeamService } from "../services/TeamService";
23-
import webSocketService, { StreamMessage, StreamingPlanUpdate } from "../services/WebSocketService";
23+
import webSocketService from "../services/WebSocketService";
2424
import { APIService } from "../api/apiService";
25-
import { Step } from "../models/plan";
25+
import { StreamMessage, StreamingPlanUpdate } from "../models";
2626

2727
import "../styles/PlanPage.css"
2828

0 commit comments

Comments
 (0)