Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions python/agent-framework/sample-agent/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
20 changes: 9 additions & 11 deletions python/agent-framework/sample-agent/AGENT-CODE-WALKTHROUGH.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,32 +238,31 @@ 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:
self.agent = await self.tool_service.add_tool_servers_to_agent(
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:
self.agent = await self.tool_service.add_tool_servers_to_agent(
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,
)
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions python/agent-framework/sample-agent/ToolingManifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
]
}
23 changes: 7 additions & 16 deletions python/agent-framework/sample-agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
)
Expand All @@ -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:
Expand All @@ -263,15 +254,15 @@ async def process_user_message(
# <NotificationHandling>

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}")

# 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:
Expand Down
2 changes: 1 addition & 1 deletion python/agent-framework/sample-agent/agent_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 8 additions & 7 deletions python/agent-framework/sample-agent/host_agent_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -138,17 +140,16 @@ 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(
f"👋 **Hi there!** I'm **{self.agent_class.__name__}**, your AI assistant.\n\n"
"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):
Expand All @@ -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)

Expand Down Expand Up @@ -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)
Expand Down
17 changes: 8 additions & 9 deletions python/agent-framework/sample-agent/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"

Expand Down
Loading