Skip to content

Commit 1644523

Browse files
committed
Adding support for proxy agent messages
1 parent 065f152 commit 1644523

File tree

2 files changed

+64
-28
lines changed

2 files changed

+64
-28
lines changed

src/backend/v3/magentic_agents/magentic_agent_factory.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from typing import List, Union
1010

1111
from common.models.messages_kernel import TeamConfiguration
12+
from v3.config.settings import current_user_id
1213
from v3.magentic_agents.foundry_agent import FoundryAgentTemplate
1314
from v3.magentic_agents.models.agent_models import (BingConfig, MCPConfig,
1415
SearchConfig)
@@ -60,7 +61,8 @@ async def create_agent_from_config(self, agent_obj: SimpleNamespace) -> Union[Fo
6061

6162
if not deployment_name and agent_obj.name.lower() == "proxyagent":
6263
self.logger.info("Creating ProxyAgent")
63-
return ProxyAgent()
64+
user_id = current_user_id.get()
65+
return ProxyAgent(user_id=user_id)
6466

6567
# Validate supported models
6668
supported_models = json.loads(os.getenv("SUPPORTED_MODELS"))

src/backend/v3/magentic_agents/proxy_agent.py

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,23 @@
44
import logging
55
import uuid
66
from collections.abc import AsyncIterable
7-
from typing import AsyncIterator
7+
from typing import AsyncIterator, Optional
88

9+
from pydantic import Field
910
from semantic_kernel.agents import ( # pylint: disable=no-name-in-module
1011
AgentResponseItem, AgentThread)
1112
from semantic_kernel.agents.agent import Agent
12-
from semantic_kernel.contents import AuthorRole, ChatMessageContent
13+
from semantic_kernel.contents import (AuthorRole, ChatMessageContent,
14+
StreamingChatMessageContent)
1315
from semantic_kernel.contents.chat_history import ChatHistory
1416
from semantic_kernel.contents.history_reducer.chat_history_reducer import \
1517
ChatHistoryReducer
1618
from semantic_kernel.exceptions.agent_exceptions import \
1719
AgentThreadOperationException
1820
from typing_extensions import override
21+
from v3.callbacks.response_handlers import (agent_response_callback,
22+
streaming_agent_response_callback)
23+
from v3.config.settings import current_user_id
1924

2025

2126
class DummyAgentThread(AgentThread):
@@ -82,15 +87,48 @@ def __init__(self, message: ChatMessageContent, thread: AgentThread):
8287

8388
class ProxyAgent(Agent):
8489
"""Simple proxy agent that prompts for human clarification."""
90+
91+
# Declare as Pydantic field
92+
user_id: Optional[str] = Field(default=None, description="User ID for WebSocket messaging")
8593

86-
def __init__(self):
94+
def __init__(self, user_id: str = None, **kwargs):
95+
# Get user_id from parameter or context, fallback to empty string
96+
effective_user_id = user_id or current_user_id.get() or ""
8797
super().__init__(
88-
name="ProxyAgent",
98+
name="ProxyAgent",
8999
description="""Call this agent when you need to clarify requests by asking the human user
90100
for more information. Ask it for more details about any unclear requirements, missing information,
91-
or if you need the user to elaborate on any aspect of the task."""
101+
or if you need the user to elaborate on any aspect of the task.""",
102+
user_id=effective_user_id,
103+
**kwargs
92104
)
93105
self.instructions = ""
106+
107+
self.user_id = user_id or current_user_id.get()
108+
109+
def _create_message_content(self, content: str, thread_id: str = None) -> ChatMessageContent:
110+
"""Create a ChatMessageContent with proper metadata."""
111+
return ChatMessageContent(
112+
role=AuthorRole.ASSISTANT,
113+
content=content,
114+
name=self.name,
115+
metadata={"thread_id": thread_id} if thread_id else {}
116+
)
117+
118+
async def _trigger_response_callbacks(self, message_content: ChatMessageContent):
119+
"""Manually trigger the same response callbacks used by other agents."""
120+
# Trigger the standard agent response callback
121+
agent_response_callback(message_content, self.user_id)
122+
123+
async def _trigger_streaming_callbacks(self, content: str, is_final: bool = False):
124+
"""Manually trigger streaming callbacks for real-time updates."""
125+
streaming_message = StreamingChatMessageContent(
126+
role=AuthorRole.ASSISTANT,
127+
content=content,
128+
name=self.name,
129+
choice_index=0
130+
)
131+
await streaming_agent_response_callback(streaming_message, is_final, self.user_id)
94132

95133
async def invoke(self, message: str,*, thread: AgentThread | None = None,**kwargs) -> AsyncIterator[ChatMessageContent]:
96134
"""Ask human user for clarification about the message."""
@@ -101,10 +139,10 @@ async def invoke(self, message: str,*, thread: AgentThread | None = None,**kwarg
101139
construct_thread=lambda: DummyAgentThread(),
102140
expected_type=DummyAgentThread,
103141
)
104-
# Replace with websocket call when available
105-
print(f"\nProxyAgent: Another agent is asking for clarification about:")
106-
print(f" Request: {message}")
107-
print("-" * 60)
142+
# Send clarification request via response handlers
143+
clarification_request = f"I need clarification about: {message}"
144+
clarification_message = self._create_message_content(clarification_request, thread.id)
145+
# await self._trigger_response_callbacks(clarification_message)
108146

109147
# Get human input
110148
human_response = input("Please provide clarification: ").strip()
@@ -114,12 +152,11 @@ async def invoke(self, message: str,*, thread: AgentThread | None = None,**kwarg
114152

115153
response = f"Human clarification: {human_response}"
116154

117-
chat_message = ChatMessageContent(
118-
role=AuthorRole.ASSISTANT,
119-
content=response,
120-
name=self.name,
121-
metadata={"thread_id": thread.id}
122-
)
155+
# Send response via response handlers
156+
response_message = self._create_message_content(response, thread.id)
157+
#await self._trigger_response_callbacks(response_message)
158+
159+
chat_message = response_message
123160

124161
yield AgentResponseItem(
125162
message=chat_message,
@@ -144,10 +181,9 @@ async def invoke_stream(self, messages, thread=None, **kwargs) -> AsyncIterator[
144181
else:
145182
message = str(messages)
146183

147-
# Replace with websocket call when available
148-
print(f"\nProxyAgent: Another agent is asking for clarification about:")
149-
print(f" Request: {message}")
150-
print("-" * 60)
184+
# Send clarification request via streaming callbacks
185+
clarification_request = f"I need clarification about: {message}"
186+
#await self._trigger_streaming_callbacks(clarification_request)
151187

152188
# Get human input - replace with websocket call when available
153189
human_response = input("Please provide clarification: ").strip()
@@ -157,12 +193,10 @@ async def invoke_stream(self, messages, thread=None, **kwargs) -> AsyncIterator[
157193

158194
response = f"Human clarification: {human_response}"
159195

160-
chat_message = ChatMessageContent(
161-
role=AuthorRole.ASSISTANT,
162-
content=response,
163-
name=self.name,
164-
metadata={"thread_id": thread.id}
165-
)
196+
# Send response via streaming callbacks
197+
#await self._trigger_streaming_callbacks(response, is_final=True)
198+
199+
chat_message = self._create_message_content(response, thread.id)
166200

167201
yield AgentResponseItem(
168202
message=chat_message,
@@ -184,6 +218,6 @@ async def get_response(self, chat_history, **kwargs):
184218
content="No clarification provided."
185219
)
186220

187-
async def create_proxy_agent():
221+
async def create_proxy_agent(user_id: str = None):
188222
"""Factory function for human proxy agent."""
189-
return ProxyAgent()
223+
return ProxyAgent(user_id=user_id)

0 commit comments

Comments
 (0)