Skip to content

Commit 1af63fb

Browse files
Merge pull request #446 from microsoft/macae-v3-fr-dev-92
feat: Macae v3 fr dev 92
2 parents 8115cdc + fd1f1e4 commit 1af63fb

File tree

26 files changed

+2412
-1393
lines changed

26 files changed

+2412
-1393
lines changed

src/backend/app_kernel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
allow_origins=[
7474
"http://localhost:3000", # Add this for local development
7575
"https://localhost:3000", # Add this if using HTTPS locally
76-
"http://127.0.0.1:3000",
76+
"https://127.0.0.1:3000",
7777
"http://127.0.0.1:3001",
7878
], # Allow all origins for development; restrict in production
7979
allow_credentials=True,

src/backend/common/models/messages_kernel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class Plan(BaseDataModel):
119119
team_id: Optional[str] = None
120120
human_clarification_request: Optional[str] = None
121121
human_clarification_response: Optional[str] = None
122-
122+
123123

124124
class Step(BaseDataModel):
125125
"""Represents an individual step (task) within a plan."""

src/backend/v3/api/router.py

Lines changed: 207 additions & 108 deletions
Large diffs are not rendered by default.

src/backend/v3/config/settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ class OrchestrationConfig:
7777
def __init__(self):
7878
self.orchestrations: Dict[str, MagenticOrchestration] = {} # user_id -> orchestration instance
7979
self.plans: Dict[str, any] = {} # plan_id -> plan details
80-
self.approvals: Dict[str, bool] = {} # plan_dot_id -> approval status
80+
self.approvals: Dict[str, bool] = {} # m_plan_id -> approval status
8181
self.sockets: Dict[str, WebSocket] = {} # user_id -> WebSocket
82-
self.clarifications: Dict[str, str] = {} # plan_dot_id -> clarification response
82+
self.clarifications: Dict[str, str] = {} # m_plan_id -> clarification response
8383

8484
def get_current_orchestration(self, user_id: str) -> MagenticOrchestration:
8585
"""get existing orchestration instance."""

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import os
44
from dataclasses import dataclass
5+
56
from common.config.app_config import config
67

8+
79
@dataclass(slots=True)
810
class MCPConfig:
911
"""Configuration for connecting to an MCP server."""
@@ -18,8 +20,8 @@ def from_env(cls) -> "MCPConfig":
1820
url = config.MCP_SERVER_ENDPOINT
1921
name = config.MCP_SERVER_NAME
2022
description = config.MCP_SERVER_DESCRIPTION
21-
tenant_id = config.TENANT_ID
22-
client_id = config.CLIENT_ID
23+
tenant_id = config.AZURE_TENANT_ID
24+
client_id = config.AZURE_CLIENT_ID
2325

2426
# Raise exception if any required environment variable is missing
2527
if not all([url, name, description, tenant_id, client_id]):

src/backend/v3/models/messages.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class PlanApprovalRequest:
4949
@dataclass(slots=True)
5050
class PlanApprovalResponse:
5151
"""Response for plan approval from the frontend."""
52-
plan_dot_id: str
52+
m_plan_id: str
5353
approved: bool
5454
feedback: str | None = None
5555
plan_id: str | None = None

src/backend/v3/orchestration/human_approval_manager.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from semantic_kernel.agents.orchestration.magentic import (
1313
MagenticContext, StandardMagenticManager)
1414
from semantic_kernel.agents.orchestration.prompts._magentic_prompts import \
15-
ORCHESTRATOR_TASK_LEDGER_FACTS_PROMPT
15+
ORCHESTRATOR_TASK_LEDGER_PLAN_PROMPT
1616
from semantic_kernel.contents import ChatMessageContent
1717
from v3.config.settings import (connection_config, current_user_id,
1818
orchestration_config)
@@ -37,13 +37,14 @@ def __init__(self, *args, **kwargs):
3737
# object.__setattr__(self, 'current_user_id', None)
3838

3939
custom_addition = """
40-
To address this request we have assembled the following team:
40+
Before creating the final plan, please ask each agent - team member to list all relevant tools (including MCP tools, plug-ins, etc.) they have access to. For each tool, list its required parameters.
41+
Obtain every required parameter that is not specified in the users request. These questions should be sent to the proxy agent. Do not ask for information that is outside of this list of required parameters.
4142
42-
{{$team}}
43-
44-
Please check with the team members to list all relevant tools they have access to, and their required parameters."""
43+
Once this information is obtained, replan to create a final bullet-point plan to address the original request using the data and clarifications obtained.
44+
Each step in the plan should start with a specific agent which is responsible for executing it.
45+
"""
4546

46-
kwargs['task_ledger_facts_prompt'] = ORCHESTRATOR_TASK_LEDGER_FACTS_PROMPT + custom_addition
47+
kwargs['task_ledger_plan_prompt'] = ORCHESTRATOR_TASK_LEDGER_PLAN_PROMPT + custom_addition
4748

4849
super().__init__(*args, **kwargs)
4950

@@ -78,7 +79,12 @@ async def plan(self, magentic_context: MagenticContext) -> Any:
7879
"participant_descriptions": magentic_context.participant_descriptions
7980
} if hasattr(magentic_context, 'participant_descriptions') else {}
8081
)
81-
82+
try:
83+
orchestration_config.plans[self.magentic_plan.id] = self.magentic_plan
84+
except Exception as e:
85+
print(f"Error processing plan approval: {e}")
86+
87+
8288
# Send the approval request to the user's WebSocket
8389
# The user_id will be automatically retrieved from context
8490
await connection_config.send_status_update_async({
@@ -105,15 +111,15 @@ async def plan(self, magentic_context: MagenticContext) -> Any:
105111
# )
106112

107113

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

111117
# To do: implement timeout and error handling
112-
if plan_dot_id not in orchestration_config.approvals:
113-
orchestration_config.approvals[plan_dot_id] = None
114-
while orchestration_config.approvals[plan_dot_id] is None:
118+
if m_plan_id not in orchestration_config.approvals:
119+
orchestration_config.approvals[m_plan_id] = None
120+
while orchestration_config.approvals[m_plan_id] is None:
115121
await asyncio.sleep(0.2)
116-
return messages.PlanApprovalResponse(approved=orchestration_config.approvals[plan_dot_id], plan_dot_id=plan_dot_id)
122+
return messages.PlanApprovalResponse(approved=orchestration_config.approvals[m_plan_id], m_plan_id=m_plan_id)
117123

118124

119125
async def prepare_final_answer(self, magentic_context: MagenticContext) -> ChatMessageContent:

src/backend/v3/orchestration/orchestration_manager.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,17 @@ async def callback(streaming_message: StreamingChatMessageContent, is_final: boo
8181
return callback
8282

8383
@classmethod
84-
async def get_current_or_new_orchestration(self, user_id: str, team_config: TeamConfiguration) -> MagenticOrchestration:
84+
async def get_current_or_new_orchestration(self, user_id: str, team_config: TeamConfiguration, team_switched: bool) -> MagenticOrchestration: # add team_switched: bool parameter
8585
"""get existing orchestration instance."""
8686
current_orchestration = orchestration_config.get_current_orchestration(user_id)
87-
if current_orchestration is None:
87+
if current_orchestration is None or team_switched: # add check for team_switched flag
88+
if current_orchestration is not None and team_switched:
89+
for agent in current_orchestration._members:
90+
if agent.name != "ProxyAgent":
91+
try:
92+
await agent.close()
93+
except Exception as e:
94+
print(f"Error closing agent: {e}")
8895
factory = MagenticAgentFactory()
8996
agents = await factory.get_agents(team_config_input=team_config)
9097
orchestration_config.orchestrations[user_id] = await self.init_orchestration(agents, user_id)

0 commit comments

Comments
 (0)