Skip to content

Commit bb466d4

Browse files
committed
fix messaging for the termination message
1 parent 5f1d5e3 commit bb466d4

File tree

5 files changed

+278
-16
lines changed

5 files changed

+278
-16
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
{
2+
"id": "10",
3+
"team_id": "team-business-operations",
4+
"name": "Business Operations Team2",
5+
"status": "visible",
6+
"created": "2025-08-05T00:00:00.000Z",
7+
"created_by": "Admin",
8+
"agents": [
9+
{
10+
"input_key": "hr-agent-001",
11+
"type": "HR",
12+
"name": "HR Specialist",
13+
"deployment_name": "gpt-4o",
14+
"system_message": "You are an AI Agent. You have knowledge about HR (e.g., human resources), policies, procedures, and onboarding guidelines.",
15+
"description": "Handles employee onboarding, HR policies, and human resources management tasks.",
16+
"icon": "Person",
17+
"index_name": "",
18+
"use_rag": false,
19+
"use_mcp": false,
20+
"coding_tools": false,
21+
"use_bing": false
22+
},
23+
{
24+
"input_key": "tech-support-001",
25+
"type": "TechSupport",
26+
"name": "Tech Support Specialist",
27+
"deployment_name": "gpt-4o",
28+
"system_message": "You are a Product agent. You have knowledge about product management, development, and compliance guidelines. When asked to call a function, you should summarize back what was done.",
29+
"description": "Provides technical support for mobile plans, telecommunications, and IT services.",
30+
"icon": "Phone",
31+
"index_name": "",
32+
"use_rag": false,
33+
"use_mcp": false,
34+
"coding_tools": false,
35+
"use_bing": false
36+
},
37+
{
38+
"input_key": "procurement-001",
39+
"type": "Procurement",
40+
"name": "Procurement Specialist",
41+
"deployment_name": "gpt-4o",
42+
"system_message": "You are a Procurement agent. You specialize in purchasing, vendor management, supply chain operations, and inventory control. You help with creating purchase orders, managing vendors, tracking orders, and ensuring efficient procurement processes.",
43+
"description": "Manages purchasing decisions, add-ons, and procurement processes.",
44+
"icon": "ShoppingBag",
45+
"index_name": "",
46+
"use_rag": false,
47+
"use_mcp": false,
48+
"coding_tools": false,
49+
"use_bing": false
50+
},
51+
{
52+
"input_key": "marketing-001",
53+
"type": "Marketing",
54+
"name": "Marketing Specialist",
55+
"deployment_name": "gpt-4o",
56+
"system_message": "You are a Marketing agent. You specialize in marketing strategy, campaign development, content creation, and market analysis. You help create effective marketing campaigns, analyze market data, and develop promotional content for products and services.",
57+
"description": "Creates marketing content, press releases, and promotional materials.",
58+
"icon": "DocumentEdit",
59+
"index_name": "",
60+
"use_rag": false,
61+
"use_mcp": false,
62+
"coding_tools": false,
63+
"use_bing": false
64+
},
65+
{
66+
"input_key": "generic-001",
67+
"type": "Generic",
68+
"name": "General Assistant",
69+
"deployment_name": "gpt-4o",
70+
"system_message": "You are a Generic agent that can help with general questions and provide basic information. You can search for information and perform simple calculations.",
71+
"description": "Provides general assistance and handles miscellaneous tasks that don't require specialized expertise.",
72+
"icon": "Bot",
73+
"index_name": "",
74+
"use_rag": false,
75+
"use_mcp": false,
76+
"coding_tools": false,
77+
"use_bing": false
78+
}
79+
],
80+
"description": "Business Operations team handles employee onboarding, telecommunications support, procurement, and marketing tasks for comprehensive business operations management.",
81+
"logo": "Building",
82+
"plan": "Multi-agent business operations plan covering HR, tech support, procurement, and marketing activities",
83+
"starting_tasks": [
84+
{
85+
"id": "onboard",
86+
"name": "Onboard employee",
87+
"prompt": "Onboard a new employee, Jessica Smith.",
88+
"created": "2025-08-05T00:00:00.000Z",
89+
"creator": "system",
90+
"logo": "Person"
91+
},
92+
{
93+
"id": "mobile",
94+
"name": "Mobile plan query",
95+
"prompt": "Ask about roaming plans prior to heading overseas.",
96+
"created": "2025-08-05T00:00:00.000Z",
97+
"creator": "system",
98+
"logo": "Phone"
99+
},
100+
{
101+
"id": "addon",
102+
"name": "Buy add-on",
103+
"prompt": "Enable roaming on mobile plan, starting next week.",
104+
"created": "2025-08-05T00:00:00.000Z",
105+
"creator": "system",
106+
"logo": "ShoppingBag"
107+
},
108+
{
109+
"id": "press",
110+
"name": "Draft a press release",
111+
"prompt": "Write a press release about our current products.",
112+
"created": "2025-08-05T00:00:00.000Z",
113+
"creator": "system",
114+
"logo": "DocumentEdit"
115+
}
116+
]
117+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
{
2+
"id": "3",
3+
"team_id": "team-3",
4+
"name": "Retail Customer Success Team2",
5+
"status": "visible",
6+
"created": "",
7+
"created_by": "",
8+
"agents": [
9+
{
10+
"input_key": "",
11+
"type": "",
12+
"name": "CustomerDataAgent",
13+
"deployment_name": "gpt-4.1-mini",
14+
"icon": "",
15+
"system_message": "You have access to internal customer data through a secure index. Use this data to answer questions about customers, their interactions with customer service, satisfaction, etc. Be mindful of privacy and compliance regulations when handling customer data.",
16+
"description": "An agent that has access to internal customer data, ask this agent if you have questions about customers or their interactions with customer service, satisfaction, etc.",
17+
"use_rag": true,
18+
"use_mcp": false,
19+
"use_bing": false,
20+
"use_reasoning": false,
21+
"index_name": "macae-index",
22+
"index_foundry_name": "",
23+
"index_endpoint": "",
24+
"coding_tools": false
25+
},
26+
{
27+
"input_key": "",
28+
"type": "",
29+
"name": "OrderDataAgent",
30+
"deployment_name": "gpt-4.1-mini",
31+
"icon": "",
32+
"system_message": "You have access to internal order, inventory, product, and fulfillment data through a secure index. Use this data to answer questions about products, shipping delays, customer orders, warehouse management, etc. Be mindful of privacy and compliance regulations when handling customer data.",
33+
"description": "An agent that has access to internal order, inventory, product, and fulfillment data. Ask this agent if you have questions about products, shipping delays, customer orders, warehouse management, etc.",
34+
"use_rag": true,
35+
"use_mcp": false,
36+
"use_bing": false,
37+
"use_reasoning": false,
38+
"index_name": "macae-index",
39+
"index_foundry_name": "",
40+
"coding_tools": true
41+
},
42+
{
43+
"input_key": "",
44+
"type": "",
45+
"name": "AnalysisRecommendationAgent",
46+
"deployment_name": "o4-mini",
47+
"icon": "",
48+
"system_message": "You are a reasoning agent that can analyze customer data and provide recommendations for improving customer satisfaction and retention. You do not have access to any data sources, but you can reason based on the information provided to you by other agents. Use your reasoning skills to identify patterns, trends, and insights that can help improve customer satisfaction and retention. Provide actionable recommendations based on your analysis. You have access to other agents that can answer questions and provide data about customers, products, orders, inventory, and fulfilment. Use these agents to gather information as needed.",
49+
"description": "A reasoning agent that can analyze customer data and provide recommendations for improving customer satisfaction and retention.",
50+
"use_rag": false,
51+
"use_mcp": false,
52+
"use_bing": false,
53+
"use_reasoning": true,
54+
"index_name": "",
55+
"index_foundry_name": "",
56+
"coding_tools": false
57+
},
58+
{
59+
"input_key": "",
60+
"type": "",
61+
"name": "ProxyAgent",
62+
"deployment_name": "",
63+
"icon": "",
64+
"system_message": "",
65+
"description": "",
66+
"use_rag": false,
67+
"use_mcp": false,
68+
"use_bing": false,
69+
"use_reasoning": false,
70+
"index_name": "",
71+
"index_foundry_name": "",
72+
"coding_tools": false
73+
}
74+
],
75+
"protected": false,
76+
"description": "Team focused on individualized customer relationship management and overall customer satisfaction.",
77+
"logo": "",
78+
"plan": "",
79+
"starting_tasks": [
80+
{
81+
"id": "task-1",
82+
"name": "Satisfaction Plan",
83+
"prompt": "Analyze the satisfaction of Emily Thompson with Contoso. If needed, provide a plan to increase her satisfaction.",
84+
"created": "",
85+
"creator": "",
86+
"logo": ""
87+
}
88+
]
89+
}

src/backend/v3/config/settings.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,16 +197,36 @@ async def send_status_update_async(
197197
)
198198
return
199199

200-
print(f" websocket {message}")
200+
print(f" websocket original message: {message}")
201+
print(f" websocket message type: {type(message)}")
202+
203+
# Convert message to proper format for frontend
201204
try:
202-
if hasattr(message, "data") and hasattr(message, "type"):
203-
message = message.data
205+
if hasattr(message, "to_dict"):
206+
# Use the custom to_dict method if available
207+
message_data = message.to_dict()
208+
print(f" websocket used to_dict(): {message_data}")
209+
elif hasattr(message, "data") and hasattr(message, "type"):
210+
# Handle structured messages with data property
211+
message_data = message.data
212+
print(f" websocket used message.data: {message_data}")
213+
elif isinstance(message, dict):
214+
# Already a dictionary
215+
message_data = message
216+
print(f" websocket already dict: {message_data}")
217+
else:
218+
# Convert to string if it's a simple type
219+
message_data = str(message)
220+
print(f" websocket converted to string: {message_data}")
204221
except Exception as e:
205-
print(f"Error loading message data: {e}")
206-
print(f" websocket after {message}")
222+
print(f"Error processing message data: {e}")
223+
message_data = str(message)
224+
225+
print(f" websocket final message_data: {message_data}")
226+
207227
standard_message = {
208228
"type": message_type,
209-
"data": message
229+
"data": message_data
210230
}
211231
connection = self.get_connection(process_id)
212232
if connection:

src/backend/v3/models/messages.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""Messages from the backend to the frontend via WebSocket."""
22

3-
from enum import Enum
43
import uuid
54
from dataclasses import asdict, dataclass, field
5+
from enum import Enum
66
from typing import Any, Dict, List, Literal, Optional
77

88
from semantic_kernel.kernel_pydantic import Field, KernelBaseModel
@@ -107,8 +107,22 @@ class UserClarificationResponse:
107107
@dataclass(slots=True)
108108
class FinalResultMessage:
109109
"""Final result message from the backend to the frontend."""
110-
result: str
111-
summary: str | None = None
110+
content: str # Changed from 'result' to 'content' to match frontend expectations
111+
status: str = "completed" # Added status field (defaults to 'completed')
112+
timestamp: Optional[float] = None # Added timestamp field
113+
summary: str | None = None # Keep summary for backward compatibility
114+
115+
def to_dict(self) -> Dict[str, Any]:
116+
"""Convert the FinalResultMessage to a dictionary for JSON serialization."""
117+
import time
118+
data = {
119+
"content": self.content,
120+
"status": self.status,
121+
"timestamp": self.timestamp or time.time()
122+
}
123+
if self.summary:
124+
data["summary"] = self.summary
125+
return data
112126

113127

114128
@dataclass(slots=True)

src/backend/v3/orchestration/human_approval_manager.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ async def plan(self, magentic_context: MagenticContext) -> Any:
104104

105105
# Send the approval request to the user's WebSocket
106106
# The user_id will be automatically retrieved from context
107-
await connection_config.send_status_update_async({
108-
"type": messages.WebsocketMessageType.PLAN_APPROVAL_REQUEST,
109-
"data": approval_message
110-
}, user_id=current_user_id.get(), message_type=messages.WebsocketMessageType.PLAN_APPROVAL_REQUEST)
107+
await connection_config.send_status_update_async(
108+
message=approval_message,
109+
user_id=current_user_id.get(),
110+
message_type=messages.WebsocketMessageType.PLAN_APPROVAL_REQUEST)
111111

112112
# Wait for user approval
113113
approval_response = await self._wait_for_user_approval(approval_message.plan.id)
@@ -134,10 +134,32 @@ async def replan(self,magentic_context: MagenticContext) -> Any:
134134
return replan
135135

136136
async def create_progress_ledger(self, magentic_context: MagenticContext) -> ProgressLedger:
137+
""" Check for max rounds exceeded and send final message if so. """
137138
if magentic_context.round_count >= orchestration_config.max_rounds:
138-
# Returning None will stop further background processing
139-
return None
140-
return await super().create_progress_ledger(magentic_context=magentic_context)
139+
# Send final message to user
140+
final_message = messages.FinalResultMessage(
141+
content="Process terminated: Maximum rounds exceeded",
142+
status="terminated",
143+
summary=f"Stopped after {magentic_context.round_count} rounds (max: {orchestration_config.max_rounds})"
144+
)
145+
146+
await connection_config.send_status_update_async(
147+
message= final_message,
148+
user_id=current_user_id.get(),
149+
message_type=messages.WebsocketMessageType.FINAL_RESULT_MESSAGE)
150+
151+
# Create a progress ledger that indicates the request is satisfied (task complete)
152+
from semantic_kernel.agents.orchestration.magentic import (
153+
ProgressLedger, ProgressLedgerItem)
154+
return ProgressLedger(
155+
is_request_satisfied=ProgressLedgerItem(reason="Maximum rounds exceeded", answer=True),
156+
is_in_loop=ProgressLedgerItem(reason="Terminating", answer=False),
157+
is_progress_being_made=ProgressLedgerItem(reason="Terminating", answer=False),
158+
next_speaker=ProgressLedgerItem(reason="Task complete", answer=""),
159+
instruction_or_question=ProgressLedgerItem(reason="Task complete", answer="Process terminated due to maximum rounds exceeded")
160+
)
161+
162+
return await super().create_progress_ledger(magentic_context)
141163

142164
async def _wait_for_user_approval(self, m_plan_id: Optional[str] = None) -> Optional[messages.PlanApprovalResponse]: # plan_id will not be optional in future
143165
"""Wait for user approval response."""

0 commit comments

Comments
 (0)