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
26 changes: 24 additions & 2 deletions .config/samples-config-v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@
"configuration": "Manual configurations required",
"thumbnailPath": "assets/sampleResponse.png",
"gifPath": "assets/sampleResponse.png",
"suggested": false
"suggested": true
},
{
"id": "coffee-agent",
Expand All @@ -914,7 +914,29 @@
"configuration": "Manual configurations required",
"thumbnailPath": "assets/coffee-agent-sample-response.png",
"gifPath": "assets/coffee-agent-sample-response.png",
"suggested": false
"suggested": true
},
{
"id": "ProxyAgent-CSharp",
"shortId": "ProxyAgent-CSharp",
"onboardDate": "2025-11-14",
"title": "AI Foundry Agent to M365 Copilot With SSO",
"shortDescription": "Sample to connect an AI Foundry Agent to M365 Copilot using M365 Agent SDK. Leverage SSO to pass user token to AI Foundry.",
"fullDescription": "This sample shows how to integrate AI Foundry agents—grounded in SharePoint—into Microsoft 365 Copilot and Teams using Agent Framework v2 and the M365 Agents SDK. It turns a complex, multi-day setup into a secure, two-click experience.",
"types": [
"Custom Engine Agent"
],
"tags": [
"C#",
"Azure",
"Agent",
"AI Foundry"
],
"time": "5 mins to run",
"configuration": "Manual configurations required",
"thumbnailPath": "images/screen009.jpg",
"gifPath": "images/screen009.jpg",
"suggested": true
}
]
}
60 changes: 60 additions & 0 deletions ProxyAgent-CSharp/.github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# GitHub Copilot Instructions for Microsoft Foundry Agent for M365

## Project Overview
This is a proxy solution that connects Microsoft Foundry agents to Microsoft 365 Copilot and Teams using the Microsoft 365 Agents Toolkit.

## Technology Stack
- **.NET 9** - Bot application runtime
- **Microsoft 365 Agents SDK** - Microsoft 365 Agents SDK
- **Microsoft 365 Agents Toolkit** - Formerly Teams Toolkit
- **Microsoft Foundry Agent SDK** - For agent integration
- **Bicep** - Infrastructure as Code
- **Managed Identity** - For production authentication (no secrets)

## Architecture Patterns
- Use the proxy pattern to route messages between M365 Copilot and Microsoft Foundry
- Bot Service acts as the messaging endpoint
- Managed Identity for authentication in production
- Client Secret + Single Tenant for local development
- SSO with federated credentials (no client secrets in SSO flow)

## Coding Standards
- Use C# 12 features and nullable reference types
- Follow async/await patterns consistently
- Use dependency injection for services
- Implement proper error handling and logging
- Use configuration-based settings (appsettings.json)

## Key Components
- `AzureAgent.cs` - Main agent integration logic
- `Program.cs` - Bot setup and middleware configuration
- Bicep modules - Reusable infrastructure components
- `m365agents.yml` - Orchestration for provisioning and deployment

## Common Patterns
- SSO authentication uses federated credentials
- Bot responds via `turnContext.SendActivityAsync()`
- Environment-specific configuration via `appsettings.{Environment}.json`
- Infrastructure deployments use conditional logic (first-time vs. update)

## Security Best Practices
- Never commit secrets or `.env` files
- Use Managed Identity in production (no secrets)
- Use federated credentials for SSO (no client secrets)
- Keep `appsettings.Development.json` in `.gitignore`

## Naming Conventions
- Bicep modules: lowercase with hyphens (e.g., `app-registration.bicep`)
- C# classes: PascalCase
- Environment variables: UPPER_SNAKE_CASE
- Resource names: Use consistent naming pattern with suffix

## Deployment
- Local: Press F5 in VS Code (automatic provisioning)
- Azure: Use `atk provision` and `atk deploy` commands
- Two deployment modes: Local (dev tunnel) and Production (Azure App Service)

## Testing
- Local debugging via F5 in VS Code
- Automatic sideloading in Teams/M365 Copilot
- Test SSO flow with federated credentials
16 changes: 16 additions & 0 deletions ProxyAgent-CSharp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

.vs/
.vs
*.pubxml








12 changes: 12 additions & 0 deletions ProxyAgent-CSharp/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"recommendations": [
"ms-dotnettools.csharp",
"ms-dotnettools.csdevkit",
"ms-azuretools.vscode-bicep",
"ms-azuretools.azure-dev",
"ms-azuretools.vscode-azureresourcegroups",
"microsoft.vscode-azure-agent-toolkit",
"ms-vscode.vscode-node-azure-pack",
"TeamsDevApp.ms-teams-vscode-extension"
]
}
128 changes: 128 additions & 0 deletions ProxyAgent-CSharp/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch in Teams (Edge)",
"type": "msedge",
"request": "launch",
"url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{local:TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}",
"presentation": {
"group": "Teams",
"hidden": true,
"order": 1
},
"internalConsoleOptions": "neverOpen"
},
{
"name": "Launch in Teams (Chrome)",
"type": "chrome",
"request": "launch",
"url": "https://teams.microsoft.com/l/app/${{{local:TEAMS_APP_ID}}}?installAppPackage=true&webjoin=true&appTenantId=${{local:TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}",
"presentation": {
"group": "Teams",
"hidden": true,
"order": 2
},
"internalConsoleOptions": "neverOpen"
},
{
"name": "Launch in Copilot (Edge)",
"type": "msedge",
"request": "launch",
"url": "https://m365.cloud.microsoft/chat/entity1-d870f6cd-4aa5-4d42-9626-ab690c041429/${local:agent-hint}?auth=2&$login_hint=${TEAMSFX_M365_USER_NAME}&developerMode=Basic",
"presentation": {
"group": "Copilot",
"hidden": true,
"order": 3
},
"internalConsoleOptions": "neverOpen"
},
{
"name": "Launch in Copilot (Chrome)",
"type": "chrome",
"request": "launch",
"url": "https://m365.cloud.microsoft/chat/entity1-d870f6cd-4aa5-4d42-9626-ab690c041429/${{local:agent-hint}}?auth=2&${{TEAMSFX_M365_USER_NAME}}&developerMode=Basic",
"presentation": {
"group": "Copilot",
"hidden": true,
"order": 4
},
"internalConsoleOptions": "neverOpen"
},
{
"type": "coreclr",
"request": "launch",
"name": "Launch AzureAgentToM365ATK",
"preLaunchTask": "test build",
"program": "${workspaceFolder}/AzureAgentToM365ATK/bin/Debug/net9.0/AzureAgentToM365ATK.dll",
"args": [],
"cwd": "${workspaceFolder}/AzureAgentToM365ATK",
"stopAtEntry": false,
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"presentation": {
"hidden": true,
"group": "all"
}
}
],
"compounds": [
{
"name": "Debug in Teams (Edge)",
"configurations": [
"Launch in Teams (Edge)",
"Launch AzureAgentToM365ATK"
],
"preLaunchTask": "PreReq & Start Tunnel",
"postDebugTask": "Stop All Services",
"presentation": {
"group": "all",
"order": 1
},
"stopAll": true
},
{
"name": "Debug in Teams (Chrome)",
"configurations": [
"Launch in Teams (Chrome)",
"Launch AzureAgentToM365ATK"
],
"preLaunchTask": "PreReq & Start Tunnel",
"postDebugTask": "Stop All Services",
"presentation": {
"group": "all",
"order": 2
},
"stopAll": true
},
{
"name": "Debug in Copilot (Edge)",
"configurations": [
"Launch AzureAgentToM365ATK",
"Launch in Copilot (Edge)",
],
"preLaunchTask": "PreReq & Start Tunnel",
"postDebugTask": "Stop All Services",
"presentation": {
"group": "all",
"order": 3
},
"stopAll": true
},
{
"name": "Debug in Copilot (Chrome)",
"configurations": [
"Launch AzureAgentToM365ATK",
"Launch in Copilot (Chrome)"
],
"preLaunchTask": "PreReq & Start Tunnel",
"postDebugTask": "Stop All Services",
"presentation": {
"group": "all",
"order": 4
},
"stopAll": true
}
]
}
44 changes: 44 additions & 0 deletions ProxyAgent-CSharp/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
// C# Development
"dotnet.defaultSolution": "AzureAgentToM365ATK.sln",
"omnisharp.enableRoslynAnalyzers": true,
// Microsoft 365 Agents Toolkit
"m365agents.telemetry": false,
// File Associations
"files.associations": {
"*.bicep": "bicep",
"m365agents*.yml": "yaml",
"*.atkproj": "xml"
},
// Files to exclude from Explorer
"files.exclude": {
"**/bin": true,
"**/obj": true,
"**/.env.*.user": true
},
// Search exclusions
"search.exclude": {
"**/bin": true,
"**/obj": true,
"**/node_modules": true
},
// Editor settings
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
},
// Terminal settings
"terminal.integrated.cwd": "${workspaceFolder}",
// Recommended Extensions
"recommendations": [
"ms-dotnettools.csharp",
"ms-dotnettools.csdevkit",
"ms-azuretools.vscode-bicep",
"ms-azuretools.azure-dev",
"ms-vscode.azure-account",
"msazurermtools.azurerm-vscode-tools",
"microsoft.vscode-azure-agent-toolkit"
],
"dotnet.completion.showCompletionItemsFromUnimportedNamespaces": true
}
Loading
Loading