Skip to content

Commit 5893f74

Browse files
committed
Refactor AgentMessageResponse model and usage
Removed unused fields from AgentMessageResponse in both backend and frontend models for consistency. Updated related logic in PlanPage and PlanDataService to match the new structure and improve message persistence handling.
1 parent a04a1c4 commit 5893f74

File tree

8 files changed

+51
-43
lines changed

8 files changed

+51
-43
lines changed

src/backend/common/models/messages_kernel.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from datetime import datetime, timezone
33
from enum import Enum
44
from typing import Any, Dict, List, Literal, Optional
5+
from pydantic import BaseModel
56
from semantic_kernel.kernel_pydantic import Field, KernelBaseModel
67

78
class DataType(str, Enum):
@@ -53,6 +54,7 @@ class PlanStatus(str, Enum):
5354
failed = "failed"
5455
canceled = "canceled"
5556
approved = "approved"
57+
created = "created"
5658

5759

5860
class HumanFeedbackStatus(str, Enum):
@@ -109,7 +111,21 @@ class UserCurrentTeam(BaseDataModel):
109111
user_id: str
110112
team_id: str
111113

112-
114+
class MStep(BaseModel):
115+
"""model of a step in a plan"""
116+
agent: str = ""
117+
action: str = ""
118+
class MPlan(BaseModel):
119+
"""model of a plan"""
120+
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
121+
user_id: str = ""
122+
team_id: str = ""
123+
plan_id: str = ""
124+
overall_status: PlanStatus = PlanStatus.created
125+
user_request: str = ""
126+
team: List[str] = []
127+
facts: str = ""
128+
steps: List[MStep] = []
113129
class Plan(BaseDataModel):
114130
"""Represents a plan containing multiple steps."""
115131

@@ -120,6 +136,7 @@ class Plan(BaseDataModel):
120136
overall_status: PlanStatus = PlanStatus.in_progress
121137
approved: bool = False
122138
source: str = AgentType.PLANNER.value
139+
m_plan: Optional[MPlan] = None
123140
summary: Optional[str] = None
124141
team_id: Optional[str] = None
125142
human_clarification_request: Optional[str] = None

src/backend/v3/api/router.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,12 +1340,12 @@ async def get_plan_by_id(request: Request, plan_id: Optional[str] = Query(None)
13401340

13411341
team = await memory_store.get_team_by_id(team_id=plan.team_id)
13421342
agent_messages = await memory_store.get_agent_messages(plan_id=plan.plan_id)
1343-
m_plan = await memory_store.get_mplan(plan_id=plan.plan_id)
1343+
13441344
return {
13451345
"plan": plan,
13461346
"team": team if team else None,
13471347
"messages": agent_messages,
1348-
"m_plan": m_plan if m_plan else None,
1348+
"m_plan": plan.m_plan,
13491349
}
13501350
else:
13511351
track_event_if_configured(

src/backend/v3/common/services/plan_service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ async def handle_plan_approval(
158158
orchestration_config.plans[human_feedback.m_plan_id] = mplan
159159
if plan:
160160
plan.overall_status = PlanStatus.approved
161+
plan.m_plan = mplan
161162
await memory_store.update_plan(plan)
162-
await memory_store.add_mplan(mplan)
163163
track_event_if_configured(
164164
"PlanApproved",
165165
{

src/backend/v3/models/messages.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,18 +139,14 @@ class ApprovalRequest(KernelBaseModel):
139139

140140
@dataclass(slots=True)
141141
class AgentMessageResponse:
142-
"""Message sent to HumanAgent to request approval for a step."""
142+
"""Response message representing an agent's message."""
143143
plan_id: str
144144
agent: str
145145
content: str
146146
agent_type: AgentMessageType
147147
is_final: bool = False
148-
m_plan_id: Optional[str] = None
149-
user_id: Optional[str] = None
150-
timestamp: Optional[str] = field(default_factory=lambda: str(time.time()))
151-
raw_data: Optional[str] = None
152-
steps: List[Any] = Field(default_factory=list)
153-
next_steps: List[Any] = Field(default_factory=list)
148+
raw_data: str = None
149+
154150

155151
class WebsocketMessageType(str, Enum):
156152
"""Types of WebSocket messages."""

src/backend/v3/models/models.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ class MStep(BaseModel):
2424
class MPlan(BaseModel):
2525
"""model of a plan"""
2626
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
27-
data_type: Literal[DataType.m_plan] = Field(DataType.m_plan, Literal=True)
28-
session_id: str = Field(default_factory=lambda: str(uuid.uuid4())) # db partition key
2927
user_id: str = ""
3028
team_id: str = ""
3129
plan_id: str = ""

src/frontend/src/models/agentMessage.tsx

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export interface AgentMessageData {
3535
* Corresponds to the Python AgentMessageResponse class.
3636
*/
3737
export interface AgentMessageResponse {
38-
is_final?: boolean;
38+
3939
/** Plan identifier */
4040
plan_id: string;
4141
/** Agent name or identifier */
@@ -44,18 +44,10 @@ export interface AgentMessageResponse {
4444
content: string;
4545
/** Type of agent (Human or AI) */
4646
agent_type: AgentMessageType;
47-
/** Associated m_plan identifier */
48-
m_plan_id?: string;
49-
/** User identifier */
50-
user_id?: string;
51-
/** Timestamp when the message was created */
52-
timestamp?: string;
47+
is_final: boolean;
5348
/** Raw data associated with the message */
54-
raw_data?: string;
55-
/** Steps associated with the message */
56-
steps?: any[];
57-
/** Next steps associated with the message */
58-
next_steps?: any[];
49+
raw_data: string;
50+
5951
}
6052

6153
export interface FinalMessage {

src/frontend/src/pages/PlanPage.tsx

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ const PlanPage: React.FC = () => {
6969
console.log(is_final)
7070
console.log(agentMessageData)
7171
const agentMessageResponse = PlanDataService.createAgentMessageResponse(agentMessageData, planData, is_final);
72+
console.log('📤 Persisting agent message:', agentMessageResponse);
7273
void apiService.sendAgentMessage(agentMessageResponse)
7374
.then(saved => {
7475
console.log('[agent_message][persisted]', {
@@ -215,24 +216,28 @@ const PlanPage: React.FC = () => {
215216
timestamp: Date.now(),
216217
steps: [], // intentionally always empty
217218
next_steps: [], // intentionally always empty
218-
content: "🎉🎉 " + (finalMessage.content || ''),
219+
content: "🎉🎉 " + (finalMessage.data?.content || ''),
219220
raw_data: finalMessage || '',
220221
} as AgentMessageData;
221222

222223

223224
console.log('✅ Parsed final result message:', agentMessageData);
224-
setStreamingMessageBuffer("");
225-
setShowProcessingPlanSpinner(false);
226-
setAgentMessages(prev => [...prev, agentMessageData]);
227-
scrollToBottom();
228-
// Persist the agent message
229-
const is_final = finalMessage?.status === 'completed' || false;
230-
if (finalMessage?.status === 'completed' && planData?.plan) {
231-
planData.plan.overall_status = PlanStatus.COMPLETED;
232-
setPlanData({ ...planData });
225+
// we ignore the terminated message
226+
if (finalMessage?.data?.status === PlanStatus.COMPLETED) {
227+
setStreamingMessageBuffer("");
228+
setShowProcessingPlanSpinner(false);
229+
setAgentMessages(prev => [...prev, agentMessageData]);
230+
scrollToBottom();
231+
// Persist the agent message
232+
const is_final = true;
233+
if (planData?.plan) {
234+
planData.plan.overall_status = PlanStatus.COMPLETED;
235+
setPlanData({ ...planData });
236+
}
237+
238+
processAgentMessage(agentMessageData, planData, is_final);
233239
}
234240

235-
processAgentMessage(agentMessageData, planData, is_final);
236241

237242
});
238243

@@ -344,6 +349,9 @@ const PlanPage: React.FC = () => {
344349
console.log("Plan data fetched:", planResult);
345350
if (planResult?.plan?.overall_status === PlanStatus.IN_PROGRESS) {
346351
setShowApprovalButtons(true);
352+
353+
} else {
354+
setWaitingForPlan(false);
347355
}
348356
if (planResult?.plan?.overall_status !== PlanStatus.COMPLETED) {
349357
setContinueWithWebsocketFlow(true);

src/frontend/src/services/PlanDataService.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,17 +197,14 @@ export class PlanDataService {
197197
console.log("Invalid plan data provided to createAgentMessageResponse");
198198
}
199199
return {
200-
is_final: is_final,
200+
201201
plan_id: planData.plan.plan_id,
202202
agent: agentMessage.agent,
203203
content: agentMessage.content,
204204
agent_type: agentMessage.agent_type,
205-
m_plan_id: planData.mplan?.id || undefined,
206-
user_id: planData.plan.user_id,
207-
timestamp: agentMessage.timestamp ? agentMessage.timestamp.toString() : new Date().getTime().toString(),
208-
raw_data: agentMessage.raw_data,
209-
steps: agentMessage.steps,
210-
next_steps: agentMessage.next_steps
205+
is_final: is_final,
206+
raw_data: JSON.stringify(agentMessage.raw_data),
207+
211208
};
212209
}
213210

0 commit comments

Comments
 (0)