Skip to content

Commit a341907

Browse files
authored
Merge pull request #486 from microsoft/macae-v3-dev-marktayl
Macae v3 dev marktayl
2 parents 83ee3a4 + 96dadc8 commit a341907

File tree

14 files changed

+177
-93
lines changed

14 files changed

+177
-93
lines changed

data/agent_teams/marketing.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"input_key": "",
4444
"type": "",
4545
"name": "ProxyAgent",
46-
"deployment_name": "gpt-4.1-mini",
46+
"deployment_name": "",
4747
"icon": "",
4848
"system_message": "",
4949
"description": "",

data/agent_teams/retail.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
"name": "OrderDataAgent",
3030
"deployment_name": "gpt-4.1-mini",
3131
"icon": "",
32-
"system_message": "You have access to internal order, inventory, product, and fulfilment 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 fulfilment data. Ask this agent if you have questions about products, shipping delays, customerr orders, warehouse management, etc.",
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.",
3434
"use_rag": true,
3535
"use_mcp": false,
3636
"use_bing": false,
@@ -42,7 +42,7 @@
4242
{
4343
"input_key": "",
4444
"type": "",
45-
"name": "AnalysisRecomendationAgent",
45+
"name": "AnalysisRecommendationAgent",
4646
"deployment_name": "o4-mini",
4747
"icon": "",
4848
"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.",
@@ -54,6 +54,22 @@
5454
"index_name": "",
5555
"index_foundry_name": "",
5656
"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
5773
}
5874
],
5975
"protected": false,
@@ -64,7 +80,7 @@
6480
{
6581
"id": "task-1",
6682
"name": "Satisfaction Plan",
67-
"prompt": "Create a plan to improve Emily Thompson's satisfaction.",
83+
"prompt": "Analyze the satisfaction of Emily Thompson with Contoso. If needed, provide a plan to increase her satisfaction.",
6884
"created": "",
6985
"creator": "",
7086
"logo": ""

src/backend/.env.sample

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ APPLICATIONINSIGHTS_CONNECTION_STRING=
1717
AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME=gpt-4o
1818
AZURE_COGNITIVE_SERVICES="https://cognitiveservices.azure.com/.default"
1919
AZURE_AI_AGENT_ENDPOINT=
20-
AZURE_BING_CONNECTION_NAME=
20+
# AZURE_BING_CONNECTION_NAME=
2121
REASONING_MODEL_NAME=o3
2222
APP_ENV=dev
2323
MCP_SERVER_ENDPOINT=http://localhost:8080/mcp

src/backend/common/config/app_config.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
from typing import Optional
55

66
from azure.ai.projects.aio import AIProjectClient
7+
from azure.cosmos import CosmosClient
78
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
89
from dotenv import load_dotenv
10+
from semantic_kernel import Kernel
911

1012
# Load environment variables from .env file
1113
load_dotenv()
@@ -52,9 +54,9 @@ def __init__(self):
5254
)
5355
self.AZURE_OPENAI_ENDPOINT = self._get_required("AZURE_OPENAI_ENDPOINT")
5456
self.REASONING_MODEL_NAME = self._get_optional("REASONING_MODEL_NAME", "o3")
55-
self.AZURE_BING_CONNECTION_NAME = self._get_optional(
56-
"AZURE_BING_CONNECTION_NAME"
57-
)
57+
# self.AZURE_BING_CONNECTION_NAME = self._get_optional(
58+
# "AZURE_BING_CONNECTION_NAME"
59+
# )
5860
self.SUPPORTED_MODELS = self._get_optional("SUPPORTED_MODELS")
5961
# Frontend settings
6062
self.FRONTEND_SITE_NAME = self._get_optional(
@@ -82,7 +84,7 @@ def __init__(self):
8284
self.AZURE_AI_SEARCH_INDEX_NAME = self._get_optional("AZURE_AI_SEARCH_INDEX_NAME")
8385
self.AZURE_AI_SEARCH_ENDPOINT = self._get_optional("AZURE_AI_SEARCH_ENDPOINT")
8486
self.AZURE_AI_SEARCH_API_KEY = self._get_optional("AZURE_AI_SEARCH_API_KEY")
85-
self.BING_CONNECTION_NAME = self._get_optional("BING_CONNECTION_NAME")
87+
# self.BING_CONNECTION_NAME = self._get_optional("BING_CONNECTION_NAME")
8688

8789
test_team_json = self._get_optional("TEST_TEAM_JSON")
8890

@@ -125,7 +127,7 @@ def get_azure_credentials(self):
125127
async def get_access_token(self) -> str:
126128
"""Get Azure access token for API calls."""
127129
try:
128-
credential = self.get_azure_credentials(self.AZURE_CLIENT_ID)
130+
credential = self.get_azure_credentials()
129131
token = credential.get_token(self.AZURE_COGNITIVE_SERVICES)
130132
return token.token
131133
except Exception as e:
@@ -190,7 +192,7 @@ def get_cosmos_database_client(self):
190192
try:
191193
if self._cosmos_client is None:
192194
self._cosmos_client = CosmosClient(
193-
self.COSMOSDB_ENDPOINT, credential=get_azure_credential(self.AZURE_CLIENT_ID)
195+
self.COSMOSDB_ENDPOINT, credential=self.get_azure_credential(self.AZURE_CLIENT_ID)
194196
)
195197

196198
if self._cosmos_database is None:
@@ -227,7 +229,7 @@ def get_ai_project_client(self):
227229
return self._ai_project_client
228230

229231
try:
230-
credential = get_azure_credential(self.AZURE_CLIENT_ID)
232+
credential = self.get_azure_credential(self.AZURE_CLIENT_ID)
231233
if credential is None:
232234
raise RuntimeError(
233235
"Unable to acquire Azure credentials; ensure Managed Identity is configured"

src/backend/common/utils/utils_kernel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ async def create_RAI_agent() -> FoundryAgentTemplate:
4040
model_deployment_name=model_deployment_name,
4141
enable_code_interpreter=False,
4242
mcp_config=None,
43-
bing_config=None,
43+
#bing_config=None,
4444
search_config=None
4545
)
4646

src/backend/v3/config/settings.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414
from fastapi import WebSocket
1515
from semantic_kernel.agents.orchestration.magentic import MagenticOrchestration
1616
from semantic_kernel.connectors.ai.open_ai import (
17-
AzureChatCompletion,
18-
OpenAIChatPromptExecutionSettings,
19-
)
20-
17+
AzureChatCompletion, OpenAIChatPromptExecutionSettings)
2118
from v3.models.messages import WebsocketMessageType
2219

2320
logger = logging.getLogger(__name__)
@@ -35,7 +32,7 @@ def __init__(self):
3532
self.endpoint = config.AZURE_OPENAI_ENDPOINT
3633
self.reasoning_model = config.REASONING_MODEL_NAME
3734
self.standard_model = config.AZURE_OPENAI_DEPLOYMENT_NAME
38-
self.bing_connection_name = config.AZURE_BING_CONNECTION_NAME
35+
#self.bing_connection_name = config.AZURE_BING_CONNECTION_NAME
3936

4037
# Create credential
4138
self.credential = config.get_azure_credentials()
@@ -89,6 +86,7 @@ def __init__(self):
8986
self.approvals: Dict[str, bool] = {} # m_plan_id -> approval status
9087
self.sockets: Dict[str, WebSocket] = {} # user_id -> WebSocket
9188
self.clarifications: Dict[str, str] = {} # m_plan_id -> clarification response
89+
self.max_rounds: int = 20 # Maximum number of replanning rounds 20 needed to accommodate complex tasks
9290

9391
def get_current_orchestration(self, user_id: str) -> MagenticOrchestration:
9492
"""get existing orchestration instance."""
@@ -199,16 +197,36 @@ async def send_status_update_async(
199197
)
200198
return
201199

202-
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
203204
try:
204-
if hasattr(message, "data") and hasattr(message, "type"):
205-
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}")
206221
except Exception as e:
207-
print(f"Error loading message data: {e}")
208-
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+
209227
standard_message = {
210228
"type": message_type,
211-
"data": message
229+
"data": message_data
212230
}
213231
connection = self.get_connection(process_id)
214232
if connection:

src/backend/v3/magentic_agents/foundry_agent.py

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
CodeInterpreterToolDefinition)
88
from semantic_kernel.agents import AzureAIAgent # pylint: disable=E0611
99
from v3.magentic_agents.common.lifecycle import AzureAgentBase
10-
from v3.magentic_agents.models.agent_models import (BingConfig, MCPConfig,
11-
SearchConfig)
10+
from v3.magentic_agents.models.agent_models import MCPConfig, SearchConfig
11+
12+
# from v3.magentic_agents.models.agent_models import (BingConfig, MCPConfig,
13+
# SearchConfig)
1214

1315
# exception too broad warning
1416
# pylint: disable=w0718
@@ -22,15 +24,15 @@ def __init__(self, agent_name: str,
2224
model_deployment_name: str,
2325
enable_code_interpreter: bool = False,
2426
mcp_config: MCPConfig | None = None,
25-
bing_config: BingConfig | None = None,
27+
#bing_config: BingConfig | None = None,
2628
search_config: SearchConfig | None = None) -> None:
2729
super().__init__(mcp=mcp_config)
2830
self.agent_name = agent_name
2931
self.agent_description = agent_description
3032
self.agent_instructions = agent_instructions
3133
self.model_deployment_name = model_deployment_name
3234
self.enable_code_interpreter = enable_code_interpreter
33-
self.bing = bing_config
35+
#self.bing = bing_config
3436
self.mcp = mcp_config
3537
self.search = search_config
3638
self._search_connection = None
@@ -40,19 +42,19 @@ def __init__(self, agent_name: str,
4042
if self.model_deployment_name is any(["o3", "o4-mini"]):
4143
raise ValueError("The current version of Foundry agents do not support reasoning models.")
4244

43-
async def _make_bing_tool(self) -> Optional[BingGroundingTool]:
44-
"""Create Bing search tool for web search."""
45-
if not all([self.client, self.bing.connection_name]):
46-
self.logger.info("Bing tool not enabled")
47-
return None
48-
try:
49-
self._bing_connection = await self.client.connections.get(name=self.bing.connection_name)
50-
bing_tool = BingGroundingTool(connection_id=self._bing_connection.id)
51-
self.logger.info("Bing tool created with connection %s", self._bing_connection.id)
52-
return bing_tool
53-
except Exception as ex:
54-
self.logger.error("Bing tool creation failed: %s", ex)
55-
return None
45+
# async def _make_bing_tool(self) -> Optional[BingGroundingTool]:
46+
# """Create Bing search tool for web search."""
47+
# if not all([self.client, self.bing.connection_name]):
48+
# self.logger.info("Bing tool not enabled")
49+
# return None
50+
# try:
51+
# self._bing_connection = await self.client.connections.get(name=self.bing.connection_name)
52+
# bing_tool = BingGroundingTool(connection_id=self._bing_connection.id)
53+
# self.logger.info("Bing tool created with connection %s", self._bing_connection.id)
54+
# return bing_tool
55+
# except Exception as ex:
56+
# self.logger.error("Bing tool creation failed: %s", ex)
57+
# return None
5658

5759
async def _make_azure_search_tool(self) -> Optional[AzureAISearchTool]:
5860
"""Create Azure AI Search tool for RAG capabilities."""
@@ -95,13 +97,13 @@ async def _collect_tools_and_resources(self) -> tuple[List, dict]:
9597
self.logger.error("Something went wrong, Azure AI Search tool not configured")
9698

9799
# Add Bing search tool
98-
if self.bing and self.bing.connection_name:
99-
bing_tool = await self._make_bing_tool()
100-
if bing_tool:
101-
tools.extend(bing_tool.definitions)
102-
self.logger.info("Added Bing search tools: %d tools", len(bing_tool.definitions))
103-
else:
104-
self.logger.error("Something went wrong, Bing tool not configured")
100+
# if self.bing and self.bing.connection_name:
101+
# bing_tool = await self._make_bing_tool()
102+
# if bing_tool:
103+
# tools.extend(bing_tool.definitions)
104+
# self.logger.info("Added Bing search tools: %d tools", len(bing_tool.definitions))
105+
# else:
106+
# self.logger.error("Something went wrong, Bing tool not configured")
105107

106108
if self.enable_code_interpreter:
107109
try:
@@ -145,7 +147,7 @@ async def create_foundry_agent(agent_name:str,
145147
agent_instructions:str,
146148
model_deployment_name:str,
147149
mcp_config:MCPConfig,
148-
bing_config:BingConfig,
150+
#bing_config:BingConfig,
149151
search_config:SearchConfig) -> FoundryAgentTemplate:
150152

151153
"""Factory function to create and open a ResearcherAgent."""
@@ -155,7 +157,7 @@ async def create_foundry_agent(agent_name:str,
155157
model_deployment_name=model_deployment_name,
156158
enable_code_interpreter=True,
157159
mcp_config=mcp_config,
158-
bing_config=bing_config,
160+
#bing_config=bing_config,
159161
search_config=search_config)
160162
await agent.open()
161163
return agent

src/backend/v3/magentic_agents/magentic_agent_factory.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
from types import SimpleNamespace
99
from typing import List, Union
1010

11+
from common.config.app_config import config
1112
from common.models.messages_kernel import TeamConfiguration
1213
from v3.config.settings import current_user_id
1314
from v3.magentic_agents.foundry_agent import FoundryAgentTemplate
14-
from v3.magentic_agents.models.agent_models import (BingConfig, MCPConfig,
15-
SearchConfig)
15+
from v3.magentic_agents.models.agent_models import MCPConfig, SearchConfig
16+
# from v3.magentic_agents.models.agent_models import (BingConfig, MCPConfig,
17+
# SearchConfig)
1618
from v3.magentic_agents.proxy_agent import ProxyAgent
1719
from v3.magentic_agents.reasoning_agent import ReasoningAgentTemplate
18-
from common.config.app_config import config
20+
1921

2022
class UnsupportedModelError(Exception):
2123
"""Raised when an unsupported model is specified."""
@@ -87,7 +89,7 @@ async def create_agent_from_config(self, agent_obj: SimpleNamespace) -> Union[Fo
8789
# Only create configs for explicitly requested capabilities
8890
search_config = SearchConfig.from_env() if getattr(agent_obj, 'use_rag', False) else None
8991
mcp_config = MCPConfig.from_env() if getattr(agent_obj, 'use_mcp', False) else None
90-
bing_config = BingConfig.from_env() if getattr(agent_obj, 'use_bing', False) else None
92+
# bing_config = BingConfig.from_env() if getattr(agent_obj, 'use_bing', False) else None
9193

9294
self.logger.info(f"Creating agent '{agent_obj.name}' with model '{deployment_name}' "
9395
f"(Template: {'Reasoning' if use_reasoning else 'Foundry'})")
@@ -114,7 +116,7 @@ async def create_agent_from_config(self, agent_obj: SimpleNamespace) -> Union[Fo
114116
model_deployment_name=deployment_name,
115117
enable_code_interpreter=getattr(agent_obj, 'coding_tools', False),
116118
mcp_config=mcp_config,
117-
bing_config=bing_config,
119+
#bing_config=bing_config,
118120
search_config=search_config
119121
)
120122

src/backend/v3/magentic_agents/models/agent_models.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,22 @@ def from_env(cls) -> "MCPConfig":
3535
client_id=client_id,
3636
)
3737

38-
@dataclass(slots=True)
39-
class BingConfig:
40-
"""Configuration for connecting to Bing Search."""
41-
connection_name: str = "Bing"
38+
# @dataclass(slots=True)
39+
# class BingConfig:
40+
# """Configuration for connecting to Bing Search."""
41+
# connection_name: str = "Bing"
4242

43-
@classmethod
44-
def from_env(cls) -> "BingConfig":
45-
connection_name = config.BING_CONNECTION_NAME
43+
# @classmethod
44+
# def from_env(cls) -> "BingConfig":
45+
# connection_name = config.BING_CONNECTION_NAME
4646

47-
# Raise exception if required environment variable is missing
48-
if not connection_name:
49-
raise ValueError(f"{cls.__name__} Missing required environment variables")
47+
# # Raise exception if required environment variable is missing
48+
# if not connection_name:
49+
# raise ValueError(f"{cls.__name__} Missing required environment variables")
5050

51-
return cls(
52-
connection_name=connection_name,
53-
)
51+
# return cls(
52+
# connection_name=connection_name,
53+
# )
5454

5555
@dataclass(slots=True)
5656
class SearchConfig:

0 commit comments

Comments
 (0)