From 70ecc46384d216661e3bc396384184c8250f187a Mon Sep 17 00:00:00 2001 From: Johan Broberg Date: Mon, 17 Nov 2025 22:34:29 -0800 Subject: [PATCH 1/2] Update Python Agent Framework sample --- .../sample-agent/.env.template | 5 ---- .../sample-agent/AGENT-CODE-WALKTHROUGH.md | 20 ++++++++-------- python/agent-framework/sample-agent/agent.py | 23 ++++++------------- .../sample-agent/agent_interface.py | 2 +- .../sample-agent/host_agent_server.py | 15 ++++++------ .../sample-agent/pyproject.toml | 17 +++++++------- 6 files changed, 33 insertions(+), 49 deletions(-) diff --git a/python/agent-framework/sample-agent/.env.template b/python/agent-framework/sample-agent/.env.template index 383a9882..07f3d5c2 100644 --- a/python/agent-framework/sample-agent/.env.template +++ b/python/agent-framework/sample-agent/.env.template @@ -16,11 +16,6 @@ OPENAI_MODEL= USE_AGENTIC_AUTH=true -# Agentic Authentication Scope -AGENTIC_AUTH_SCOPE= - -AGENT_ID= - # Agent 365 Agentic Authentication Configuration CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID= CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET= diff --git a/python/agent-framework/sample-agent/AGENT-CODE-WALKTHROUGH.md b/python/agent-framework/sample-agent/AGENT-CODE-WALKTHROUGH.md index 5c69292b..ec9cf48b 100644 --- a/python/agent-framework/sample-agent/AGENT-CODE-WALKTHROUGH.md +++ b/python/agent-framework/sample-agent/AGENT-CODE-WALKTHROUGH.md @@ -238,14 +238,13 @@ def _initialize_services(self): logger.warning(f"⚠️ Could not initialize MCP tool service: {e}") self.tool_service = None -async def setup_mcp_servers(self, auth: Authorization, context: TurnContext): +async def setup_mcp_servers(self, auth: Authorization, auth_handler_name: str, context: TurnContext): """Set up MCP server connections""" try: if not self.tool_service: logger.warning("⚠️ MCP tool service not available - skipping MCP server setup") return - agent_user_id = os.getenv("AGENT_ID", "user123") use_agentic_auth = os.getenv("USE_AGENTIC_AUTH", "false").lower() == "true" if use_agentic_auth: @@ -253,8 +252,8 @@ async def setup_mcp_servers(self, auth: Authorization, context: TurnContext): chat_client=self.chat_client, agent_instructions="You are a helpful assistant with access to tools.", initial_tools=[], - agent_user_id=agent_user_id, auth=auth, + auth_handler_name=auth_handler_name, turn_context=context, ) else: @@ -262,8 +261,8 @@ async def setup_mcp_servers(self, auth: Authorization, context: TurnContext): chat_client=self.chat_client, agent_instructions="You are a helpful assistant with access to tools.", initial_tools=[], - agent_user_id=agent_user_id, auth=auth, + auth_handler_name=auth_handler_name, auth_token=self.auth_options.bearer_token, turn_context=context, ) @@ -282,7 +281,6 @@ async def setup_mcp_servers(self, auth: Authorization, context: TurnContext): The agent supports multiple authentication modes and extensive configuration options: **Environment Variables**: -- `AGENT_ID`: Unique identifier for this agent instance - `USE_AGENTIC_AUTH`: Choose between enterprise security (true) or simple tokens (false) - `ENV_ID`: Agent365 environment identifier - `BEARER_TOKEN`: Authentication token for MCP servers @@ -303,11 +301,11 @@ The agent supports multiple authentication modes and extensive configuration opt ```python async def process_user_message( - self, message: str, auth: Authorization, context: TurnContext + self, message: str, auth: Authorization, auth_handler_name: str, context: TurnContext ) -> str: """Process user message using the AgentFramework SDK""" try: - await self.setup_mcp_servers(auth, context) + await self.setup_mcp_servers(auth, auth_handler_name, context) result = await self.agent.run(message) return self._extract_result(result) or "I couldn't process your request at this time." except Exception as e: @@ -329,14 +327,14 @@ async def process_user_message( ```python async def handle_agent_notification_activity( - self, notification_activity, auth: Authorization, context: TurnContext + self, notification_activity, auth: Authorization, auth_handler_name: str, context: TurnContext ) -> str: """Handle agent notification activities (email, Word mentions, etc.)""" try: notification_type = notification_activity.notification_type logger.info(f"📬 Processing notification: {notification_type}") - await self.setup_mcp_servers(auth, context) + await self.setup_mcp_servers(auth, auth_handler_name, context) # Handle Email Notifications if notification_type == NotificationTypes.EMAIL_NOTIFICATION: @@ -413,12 +411,12 @@ async def initialize(self): raise async def process_user_message( - self, message: str, auth: Authorization, context: TurnContext + self, message: str, auth: Authorization, auth_handler_name: str, context: TurnContext ) -> str: """Process user message using the AgentFramework SDK""" try: # Setup MCP servers - await self.setup_mcp_servers(auth, context) + await self.setup_mcp_servers(auth, auth_handler_name, context) # Run the agent with the user message result = await self.agent.run(message) diff --git a/python/agent-framework/sample-agent/agent.py b/python/agent-framework/sample-agent/agent.py index e83928e6..6df3e761 100644 --- a/python/agent-framework/sample-agent/agent.py +++ b/python/agent-framework/sample-agent/agent.py @@ -182,7 +182,7 @@ def _initialize_services(self): logger.warning(f"⚠️ MCP tool service failed: {e}") self.tool_service = None - async def setup_mcp_servers(self, auth: Authorization, context: TurnContext): + async def setup_mcp_servers(self, auth: Authorization, auth_handler_name: str, context: TurnContext): """Set up MCP server connections""" if self.mcp_servers_initialized: return @@ -192,33 +192,24 @@ async def setup_mcp_servers(self, auth: Authorization, context: TurnContext): logger.warning("⚠️ MCP tool service unavailable") return - agent_user_id = os.getenv("AGENT_ID", "user123") use_agentic_auth = os.getenv("USE_AGENTIC_AUTH", "false").lower() == "true" if use_agentic_auth: - scope = os.getenv("AGENTIC_AUTH_SCOPE") - if not scope: - logger.error("❌ AGENTIC_AUTH_SCOPE is required when USE_AGENTIC_AUTH is enabled") - return - scopes = [scope] - authToken = await auth.exchange_token(context, scopes, "AGENTIC") - auth_token = authToken.token self.agent = await self.tool_service.add_tool_servers_to_agent( chat_client=self.chat_client, agent_instructions=self.AGENT_PROMPT, initial_tools=[], - agentic_app_id=agent_user_id, auth=auth, + auth_handler_name=auth_handler_name, turn_context=context, - auth_token=auth_token, ) else: self.agent = await self.tool_service.add_tool_servers_to_agent( chat_client=self.chat_client, agent_instructions=self.AGENT_PROMPT, initial_tools=[], - agentic_app_id=agent_user_id, auth=auth, + auth_handler_name=auth_handler_name, auth_token=self.auth_options.bearer_token, turn_context=context, ) @@ -244,11 +235,11 @@ async def initialize(self): logger.info("Agent initialized") async def process_user_message( - self, message: str, auth: Authorization, context: TurnContext + self, message: str, auth: Authorization, auth_handler_name: str, context: TurnContext ) -> str: """Process user message using the AgentFramework SDK""" try: - await self.setup_mcp_servers(auth, context) + await self.setup_mcp_servers(auth, auth_handler_name, context) result = await self.agent.run(message) return self._extract_result(result) or "I couldn't process your request at this time." except Exception as e: @@ -263,7 +254,7 @@ async def process_user_message( # async def handle_agent_notification_activity( - self, notification_activity, auth: Authorization, context: TurnContext + self, notification_activity, auth: Authorization, auth_handler_name: str, context: TurnContext ) -> str: """Handle agent notification activities (email, Word mentions, etc.)""" try: @@ -271,7 +262,7 @@ async def handle_agent_notification_activity( logger.info(f"📬 Processing notification: {notification_type}") # Setup MCP servers on first call - await self.setup_mcp_servers(auth, context) + await self.setup_mcp_servers(auth, auth_handler_name, context) # Handle Email Notifications if notification_type == NotificationTypes.EMAIL_NOTIFICATION: diff --git a/python/agent-framework/sample-agent/agent_interface.py b/python/agent-framework/sample-agent/agent_interface.py index f1578702..36b889c0 100644 --- a/python/agent-framework/sample-agent/agent_interface.py +++ b/python/agent-framework/sample-agent/agent_interface.py @@ -24,7 +24,7 @@ async def initialize(self) -> None: @abstractmethod async def process_user_message( - self, message: str, auth: Authorization, context: TurnContext + self, message: str, auth: Authorization, auth_handler_name: str, context: TurnContext ) -> str: """Process a user message and return a response.""" pass diff --git a/python/agent-framework/sample-agent/host_agent_server.py b/python/agent-framework/sample-agent/host_agent_server.py index c1d08ba0..93ea1aef 100644 --- a/python/agent-framework/sample-agent/host_agent_server.py +++ b/python/agent-framework/sample-agent/host_agent_server.py @@ -88,6 +88,8 @@ def __init__(self, agent_class: type[AgentInterface], *agent_args, **agent_kwarg f"Agent class {agent_class.__name__} must inherit from AgentInterface" ) + self.auth_handler_name = "AGENTIC" + self.agent_class = agent_class self.agent_args = agent_args self.agent_kwargs = agent_kwargs @@ -117,7 +119,7 @@ async def _setup_observability_token( exaau_token = await self.agent_app.auth.exchange_token( context, scopes=get_observability_authentication_scope(), - auth_handler_id="AGENTIC", + auth_handler_id=self.auth_handler_name, ) cache_agentic_token(tenant_id, agent_id, exaau_token.token) except Exception as e: @@ -138,8 +140,7 @@ async def _validate_agent_and_setup_context(self, context: TurnContext): # --- Handlers (Messages & Notifications) --- def _setup_handlers(self): """Setup message and notification handlers""" - use_agentic_auth = os.getenv("USE_AGENTIC_AUTH", "false").lower() == "true" - handler = ["AGENTIC"] if use_agentic_auth else None + handler = [self.auth_handler_name] async def help_handler(context: TurnContext, _: TurnState): await context.send_activity( @@ -147,8 +148,8 @@ async def help_handler(context: TurnContext, _: TurnState): "How can I help you today?" ) - self.agent_app.conversation_update("membersAdded")(help_handler) - self.agent_app.message("/help")(help_handler) + self.agent_app.conversation_update("membersAdded", auth_handlers=handler)(help_handler) + self.agent_app.message("/help", auth_handlers=handler)(help_handler) @self.agent_app.activity("message", auth_handlers=handler) async def on_message(context: TurnContext, _: TurnState): @@ -165,7 +166,7 @@ async def on_message(context: TurnContext, _: TurnState): logger.info(f"📨 {user_message}") response = await self.agent_instance.process_user_message( - user_message, self.agent_app.auth, context + user_message, self.agent_app.auth, self.auth_handler_name, context ) await context.send_activity(response) @@ -202,7 +203,7 @@ async def on_notification( response = ( await self.agent_instance.handle_agent_notification_activity( - notification_activity, self.agent_app.auth, context + notification_activity, self.agent_app.auth, self.auth_handler_name, context ) ) await context.send_activity(response) diff --git a/python/agent-framework/sample-agent/pyproject.toml b/python/agent-framework/sample-agent/pyproject.toml index 5a4453c1..29a3e2d0 100644 --- a/python/agent-framework/sample-agent/pyproject.toml +++ b/python/agent-framework/sample-agent/pyproject.toml @@ -3,7 +3,7 @@ name = "sample-agentframework-agent" version = "0.1.0" description = "Sample Agent Framework Agent using Microsoft Agent 365 SDK" authors = [ - { name = "Microsoft", email = "example@microsoft.com" } + { name = "Microsoft", email = "support@microsoft.com" } ] dependencies = [ # AgentFramework SDK - The official package @@ -35,14 +35,13 @@ dependencies = [ # Additional utilities "typing-extensions>=4.0.0", - # Local packages from local index - # - Update package versions to match your built wheels - "microsoft_agents_a365_tooling >= 0.1.0.dev12", - "microsoft_agents_a365_tooling_extensions_agentframework >= 0.1.0.dev12", - "microsoft_agents_a365_observability_core >= 0.1.0.dev12", - "microsoft_agents_a365_observability_extensions_agent_framework >= 0.1.0.dev12", - "microsoft_agents_a365_runtime >= 0.1.0.dev12", - "microsoft_agents_a365_notifications 0.1.0.dev12", + # Microsoft Agent 365 SDK packages + "microsoft_agents_a365_tooling >= 0.1.0", + "microsoft_agents_a365_tooling_extensions_agentframework >= 0.1.0", + "microsoft_agents_a365_observability_core >= 0.1.0", + "microsoft_agents_a365_observability_extensions_agent_framework >= 0.1.0", + "microsoft_agents_a365_runtime >= 0.1.0", + "microsoft_agents_a365_notifications >= 0.1.0" ] requires-python = ">=3.11" From 48d77dbff471b935420f43d9cecc69658214d67b Mon Sep 17 00:00:00 2001 From: Johan Broberg Date: Mon, 17 Nov 2025 22:37:11 -0800 Subject: [PATCH 2/2] Correct Tooling manifest --- python/agent-framework/sample-agent/ToolingManifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/agent-framework/sample-agent/ToolingManifest.json b/python/agent-framework/sample-agent/ToolingManifest.json index c7bc00b7..e842561c 100644 --- a/python/agent-framework/sample-agent/ToolingManifest.json +++ b/python/agent-framework/sample-agent/ToolingManifest.json @@ -3,9 +3,9 @@ { "mcpServerName": "mcp_MailTools", "mcpServerUniqueName": "mcp_MailTools", - "url": "https://preprod.agent365.svc.cloud.dev.microsoft/agents/servers/mcp_MailTools", + "url": "https://agent365.svc.cloud.microsoft/agents/servers/mcp_MailTools", "scope": "McpServers.Mail.All", - "audience": "05879165-0320-489e-b644-f72b33f3edf0" + "audience": "ea9ffc3e-8a23-4a7d-836d-234d7c7565c1" } ] } \ No newline at end of file