Skip to content

Commit 8c0c564

Browse files
committed
Merge branch 'macae-v3-dev-v2-vip' into macae-v3-fr-dev-92
2 parents 45dceba + 18589b5 commit 8c0c564

File tree

3 files changed

+55
-31
lines changed

3 files changed

+55
-31
lines changed

src/backend/v3/callbacks/response_handlers.py

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33
Provides detailed monitoring and response handling for different agent types.
44
"""
55
import asyncio
6+
import json
7+
import logging
68
import sys
9+
import time
710

811
from semantic_kernel.contents import (ChatMessageContent,
912
StreamingChatMessageContent)
1013
from v3.config.settings import connection_config, current_user_id
14+
from v3.models.messages import (AgentMessage, AgentMessageStreaming,
15+
AgentToolCall, AgentToolMessage)
1116

1217

1318
def agent_response_callback(message: ChatMessageContent, user_id: str = None) -> None:
@@ -16,39 +21,39 @@ def agent_response_callback(message: ChatMessageContent, user_id: str = None) ->
1621

1722
# Get agent name to determine handling
1823
agent_name = message.name or "Unknown Agent"
19-
24+
# Get message type
25+
content_type = getattr(message, 'content_type', 'text')
26+
2027
role = getattr(message, 'role', 'unknown')
2128

2229
# Send to WebSocket
2330
if user_id:
2431
try:
25-
asyncio.create_task(connection_config.send_status_update_async({
26-
"type": "agent_message",
27-
"data": {"agent_name": agent_name, "content": message.content, "role": role}
28-
}, user_id))
32+
if message.items and message.items[0].content_type == 'function_call':
33+
final_message = AgentToolMessage(agent_name=agent_name)
34+
for item in message.items:
35+
if item.content_type == 'function_call':
36+
tool_call = AgentToolCall(tool_name=item.name or "unknown_tool", arguments=item.arguments or {})
37+
final_message.tool_calls.append(tool_call)
38+
asyncio.create_task(connection_config.send_status_update_async(final_message, user_id))
39+
logging.info(f"Function call: {final_message}")
40+
elif message.items and message.items[0].content_type == 'function_result':
41+
# skip returning these results for now - agent will return in a later message
42+
pass
43+
else:
44+
final_message = AgentMessage(agent_name=agent_name, timestamp=time.time() or "", content=message.content or "")
45+
asyncio.create_task(connection_config.send_status_update_async(final_message, user_id))
46+
logging.info(f"{role.capitalize()} message: {final_message}")
2947
except Exception as e:
30-
print(f"Error sending WebSocket message: {e}")
31-
32-
print(f"\n **{agent_name}** (role: {role})")
33-
34-
if message.items[-1].content_type == 'function_call':
35-
print(f"🔧 Function call: {message.items[-1].function_name}, Arguments: {message.items[-1].arguments}")
36-
48+
logging.error(f"Response_callback: Error sending WebSocket message: {e}")
3749

38-
# Add this function after your agent_response_callback function
3950
async def streaming_agent_response_callback(streaming_message: StreamingChatMessageContent, is_final: bool, user_id: str = None) -> None:
4051
"""Simple streaming callback to show real-time agent responses."""
41-
if streaming_message.name != "CoderAgent":
42-
# Print streaming content as it arrives
43-
if hasattr(streaming_message, 'content') and streaming_message.content:
44-
print(streaming_message.content, end='', flush=False)
45-
46-
# Send to WebSocket
47-
if user_id:
48-
try:
49-
await connection_config.send_status_update_async({
50-
"type": "streaming_message",
51-
"data": {"agent_name": streaming_message.name or "Unknown Agent", "content": streaming_message.content, "is_final": is_final}
52-
}, user_id)
53-
except Exception as e:
54-
print(f"Error sending streaming WebSocket message: {e}")
52+
# process only content messages
53+
if hasattr(streaming_message, 'content') and streaming_message.content:
54+
if user_id:
55+
try:
56+
message = AgentMessageStreaming(agent_name=streaming_message.name or "Unknown Agent", content=streaming_message.content, is_final=is_final)
57+
await connection_config.send_status_update_async(message, user_id)
58+
except Exception as e:
59+
logging.error(f"Response_callback: Error sending streaming WebSocket message: {e}")

src/backend/v3/magentic_agents/proxy_agent.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,6 @@ async def invoke_stream(self, messages, thread=None, **kwargs) -> AsyncIterator[
194194

195195
# Send clarification request via streaming callbacks
196196
clarification_request = f"I need clarification about: {message}"
197-
#self._create_message_content(clarification_request, thread.id)
198-
# await self._trigger_streaming_callbacks(clarification_request)
199197

200198
clarification_message = UserClarificationRequest(
201199
question=clarification_request,

src/backend/v3/models/messages.py

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

33
import uuid
4-
from dataclasses import dataclass
4+
from dataclasses import asdict, dataclass, field
55
from typing import Any, Dict, List, Literal, Optional
66

77
from semantic_kernel.kernel_pydantic import Field, KernelBaseModel
@@ -15,6 +15,10 @@ class AgentMessage:
1515
timestamp: str
1616
content: str
1717

18+
def to_dict(self) -> Dict[str, Any]:
19+
"""Convert the AgentMessage to a dictionary for JSON serialization."""
20+
return asdict(self)
21+
1822
@dataclass(slots=True)
1923
class AgentStreamStart:
2024
"""Start of a streaming message from the backend to the frontend via WebSocket."""
@@ -32,12 +36,29 @@ class AgentMessageStreaming:
3236
content: str
3337
is_final: bool = False
3438

39+
def to_dict(self) -> Dict[str, Any]:
40+
"""Convert the AgentMessageStreaming to a dictionary for JSON serialization."""
41+
return asdict(self)
42+
3543
@dataclass(slots=True)
3644
class AgentToolMessage:
3745
"""Message from an agent using a tool."""
3846
agent_name: str
47+
tool_calls: List['AgentToolCall'] = field(default_factory=list)
48+
49+
def to_dict(self) -> Dict[str, Any]:
50+
"""Convert the AgentToolMessage to a dictionary for JSON serialization."""
51+
return asdict(self)
52+
53+
@dataclass(slots=True)
54+
class AgentToolCall:
55+
"""Message representing a tool call from an agent."""
3956
tool_name: str
40-
input: str
57+
arguments: Dict[str, Any]
58+
59+
def to_dict(self) -> Dict[str, Any]:
60+
"""Convert the AgentToolCall to a dictionary for JSON serialization."""
61+
return asdict(self)
4162

4263
@dataclass(slots=True)
4364
class PlanApprovalRequest:

0 commit comments

Comments
 (0)