Skip to content

Commit 2271392

Browse files
committed
Refactor agent message handling and validation logic
Improves agent message processing by restructuring the backend to use a new handler for agent messages, adds error handling and event tracking, and updates plan service logic for message persistence. Also cleans up unused imports in PlanPage.tsx and refines orchestration config typing for plans.
1 parent a61d821 commit 2271392

File tree

5 files changed

+84
-22
lines changed

5 files changed

+84
-22
lines changed

src/backend/common/models/messages_kernel.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,9 @@ class AgentMessageData (BaseDataModel):
261261
data_type: Literal[DataType.m_plan_message] = Field(DataType.m_plan_message, Literal=True)
262262
plan_id: str
263263
user_id: str
264-
m_plan_id: Optional[str] = None
265264
agent: str
265+
m_plan_id: Optional[str] = None
266266
agent_type: AgentMessageType = AgentMessageType.AI_AGENT
267-
timestamp: int
268267
content: str
269268
raw_data: str
270269
steps: List[Any] = Field(default_factory=list)

src/backend/v3/api/router.py

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,25 @@ async def agent_message_user(
501501
status_code=401, detail="Missing or invalid user information"
502502
)
503503
# Set the approval in the orchestration config
504-
505504

505+
try:
506+
507+
result = await PlanService.handle_agent_messages(agent_message, user_id)
508+
print("Agent message processed:", result)
509+
except ValueError as ve:
510+
print(f"ValueError processing agent message: {ve}")
511+
except Exception as e:
512+
print(f"Error processing agent message: {e}")
513+
514+
track_event_if_configured(
515+
"AgentMessageReceived",
516+
{
517+
"agent": agent_message.agent,
518+
"content": agent_message.content,
519+
"user_id": user_id,
520+
},
521+
)
522+
return {"status": "message recorded",}
506523

507524

508525
@app_v3.post("/upload_team_config")
@@ -564,24 +581,25 @@ async def upload_team_config(
564581
)
565582

566583
# Validate content with RAI before processing
567-
rai_valid, rai_error = await rai_validate_team_config(json_data)
568-
if not rai_valid:
569-
track_event_if_configured(
570-
"Team configuration RAI validation failed",
571-
{
584+
if not team_id:
585+
rai_valid, rai_error = await rai_validate_team_config(json_data)
586+
if not rai_valid:
587+
track_event_if_configured(
588+
"Team configuration RAI validation failed",
589+
{
572590
"status": "failed",
573591
"user_id": user_id,
574592
"filename": file.filename,
575593
"reason": rai_error,
576594
},
577595
)
596+
578597
raise HTTPException(status_code=400, detail=rai_error)
579598

580599
track_event_if_configured(
581-
"Team configuration RAI validation passed",
582-
{"status": "passed", "user_id": user_id, "filename": file.filename},
583-
)
584-
600+
"Team configuration RAI validation passed",
601+
{"status": "passed", "user_id": user_id, "filename": file.filename},
602+
)
585603
# Initialize memory store and service
586604
memory_store = await DatabaseFactory.get_database(user_id=user_id)
587605
team_service = TeamService(memory_store)

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

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
1+
from dataclasses import Field, asdict
2+
import json
13
import logging
4+
import time
25
from typing import Dict, Any, Optional
36
from common.database.database_factory import DatabaseFactory
4-
from common.database.database_base import DatabaseBase
7+
8+
from v3.models.models import MPlan
59
import v3.models.messages as messages
6-
from common.models.messages_kernel import PlanStatus
10+
from common.models.messages_kernel import AgentMessageData, AgentMessageType, AgentType, PlanStatus
711
from v3.config.settings import orchestration_config
812
from common.utils.event_utils import track_event_if_configured
13+
import uuid
14+
from semantic_kernel.kernel_pydantic import Field
915

16+
class MPlanExpanded(MPlan):
17+
session_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
18+
1019
logger = logging.getLogger(__name__)
20+
def build_agent_message_from_user_clarification(
21+
human_feedback: messages.UserClarificationResponse,
22+
user_id: str
23+
) -> AgentMessageData:
24+
"""
25+
Convert a UserClarificationResponse (human feedback) into an AgentMessageData.
26+
"""
27+
# NOTE: AgentMessageType enum currently defines values with trailing commas in messages_kernel.py.
28+
# e.g. HUMAN_AGENT = "Human_Agent", -> value becomes ('Human_Agent',)
29+
# Consider fixing that enum (remove trailing commas) so .value is a string.
30+
return AgentMessageData(
31+
plan_id = human_feedback.plan_id or "",
32+
user_id = user_id,
33+
m_plan_id = human_feedback.m_plan_id or None,
34+
agent = AgentType.HUMAN.value, # or simply "Human_Agent"
35+
agent_type = AgentMessageType.HUMAN_AGENT, # will serialize per current enum definition
36+
content = human_feedback.answer or "",
37+
raw_data = json.dumps(asdict(human_feedback)),
38+
steps = [], # intentionally empty
39+
next_steps = [] # intentionally empty
40+
)
1141

12-
class PlanService:
1342

43+
class PlanService:
1444

1545
@staticmethod
1646
async def handle_plan_approval(human_feedback: messages.PlanApprovalResponse, user_id: str) -> bool:
@@ -74,7 +104,7 @@ async def handle_plan_approval(human_feedback: messages.PlanApprovalResponse, us
74104
return True
75105

76106
@staticmethod
77-
async def handle_agent_messages(standard_message: messages.AgentMessage, user_id: str) -> bool:
107+
async def handle_agent_messages(agent_message: messages.AgentMessageResponse, user_id: str) -> bool:
78108
"""
79109
Process an AgentMessage coming from the client.
80110
@@ -105,4 +135,22 @@ async def handle_human_clarification(human_feedback: messages.UserClarificationR
105135
Raises:
106136
ValueError on invalid state
107137
"""
108-
return True
138+
try:
139+
agent_msg = build_agent_message_from_user_clarification(human_feedback, user_id)
140+
141+
# Persist if your database layer supports it.
142+
# Look for or implement something like: memory_store.add_agent_message(agent_msg)
143+
memory_store = await DatabaseFactory.get_database(user_id=user_id)
144+
if hasattr(memory_store, "add_agent_message"):
145+
await memory_store.add_agent_message(agent_msg)
146+
else:
147+
# Fallback: log or ignore if persistence not yet implemented
148+
logging.debug("add_agent_message not implemented; skipping persistence")
149+
150+
# Optionally emit over websocket if you have a broadcaster:
151+
# await websocket_manager.broadcast(WebsocketMessageType.AGENT_MESSAGE, agent_msg.model_dump())
152+
153+
return True
154+
except Exception as e:
155+
logger.exception("Failed to handle human clarification -> agent message: %s", e)
156+
return False

src/backend/v3/config/settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from semantic_kernel.agents.orchestration.magentic import MagenticOrchestration
1616
from semantic_kernel.connectors.ai.open_ai import (
1717
AzureChatCompletion, OpenAIChatPromptExecutionSettings)
18-
from v3.models.messages import WebsocketMessageType
18+
from v3.models.messages import WebsocketMessageType, MPlan
1919

2020
logger = logging.getLogger(__name__)
2121

@@ -82,7 +82,7 @@ def __init__(self):
8282
self.orchestrations: Dict[str, MagenticOrchestration] = (
8383
{}
8484
) # user_id -> orchestration instance
85-
self.plans: Dict[str, any] = {} # plan_id -> plan details
85+
self.plans: Dict[str, MPlan] = {} # plan_id -> plan details
8686
self.approvals: Dict[str, bool] = {} # m_plan_id -> approval status
8787
self.sockets: Dict[str, WebSocket] = {} # user_id -> WebSocket
8888
self.clarifications: Dict[str, str] = {} # m_plan_id -> clarification response

src/frontend/src/pages/PlanPage.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ import Octo from "../coral/imports/Octopus.png";
1717
import PanelRightToggles from "../coral/components/Header/PanelRightToggles";
1818
import { TaskListSquareLtr } from "../coral/imports/bundleicons";
1919
import LoadingMessage, { loadingMessages } from "../coral/components/LoadingMessage";
20-
import { RAIErrorCard, RAIErrorData } from "../components/errors";
21-
import { TeamConfig } from "../models/Team";
22-
import { TeamService } from "../services/TeamService";
2320
import webSocketService from "../services/WebSocketService";
2421
import { APIService } from "../api/apiService";
2522
import { StreamMessage, StreamingPlanUpdate } from "../models";

0 commit comments

Comments
 (0)