|
| 1 | +# M365 Copilot Integration — Architecture Overview |
| 2 | + |
| 3 | +> **Last Updated**: 2026-03-26 |
| 4 | +> **Project**: ai-m365-copilot-integration (R1) |
| 5 | +
|
| 6 | +## System Architecture |
| 7 | + |
| 8 | +``` |
| 9 | +┌─────────────────────────────────────────────────────────────────────┐ |
| 10 | +│ M365 COPILOT (Microsoft's Orchestrator) │ |
| 11 | +│ │ |
| 12 | +│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ |
| 13 | +│ │ Copilot in MDA │ │ Copilot in Teams │ │ |
| 14 | +│ │ (side pane on Dataverse │ │ (future — R2) │ │ |
| 15 | +│ │ forms) │ │ │ │ |
| 16 | +│ └──────────┬──────────────────┘ └──────────┬──────────────────┘ │ |
| 17 | +│ │ │ │ |
| 18 | +│ └──────────┬──────────────────────┘ │ |
| 19 | +│ │ │ |
| 20 | +│ ┌─────────────────────▼──────────────────────────────────────────┐│ |
| 21 | +│ │ Declarative Agent (declarativeAgent.json) ││ |
| 22 | +│ │ • Instructions (system prompt): Spaarke legal ops vocabulary ││ |
| 23 | +│ │ • Conversation starters: "Find documents...", "Run a scan..." ││ |
| 24 | +│ │ • Capabilities: API Plugin ││ |
| 25 | +│ └─────────────────────┬──────────────────────────────────────────┘│ |
| 26 | +│ │ │ |
| 27 | +│ ┌─────────────────────▼──────────────────────────────────────────┐│ |
| 28 | +│ │ API Plugin (spaarke-api-plugin.json) ││ |
| 29 | +│ │ 27 functions with AI-readable descriptions ││ |
| 30 | +│ │ Copilot AI decides WHEN to call each function ││ |
| 31 | +│ └─────────────────────┬──────────────────────────────────────────┘│ |
| 32 | +│ │ │ |
| 33 | +│ ┌─────────────────────▼──────────────────────────────────────────┐│ |
| 34 | +│ │ OpenAPI Spec (spaarke-bff-openapi.yaml) ││ |
| 35 | +│ │ 35+ operations: chat, search, playbooks, analysis, events... ││ |
| 36 | +│ └─────────────────────┬──────────────────────────────────────────┘│ |
| 37 | +└────────────────────────┼────────────────────────────────────────────┘ |
| 38 | + │ HTTPS (direct call, no intermediary) |
| 39 | + ▼ |
| 40 | +┌─────────────────────────────────────────────────────────────────────┐ |
| 41 | +│ SPAARKE BFF API (spe-api-dev-67e2xz.azurewebsites.net) │ |
| 42 | +│ │ |
| 43 | +│ ┌──────────────────────────────────────────────────────────────┐ │ |
| 44 | +│ │ Agent Gateway Layer (NEW — src/server/api/.../Api/Agent/) │ │ |
| 45 | +│ │ │ │ |
| 46 | +│ │ AgentEndpoints.cs — POST /api/agent/message │ │ |
| 47 | +│ │ GET /api/agent/playbooks │ │ |
| 48 | +│ │ POST /api/agent/run-playbook │ │ |
| 49 | +│ │ GET /api/agent/playbooks/status │ │ |
| 50 | +│ │ │ │ |
| 51 | +│ │ SpaarkeAgentHandler.cs — M365 Agents SDK ActivityHandler │ │ |
| 52 | +│ │ AgentTokenService.cs — SSO/OBO token exchange │ │ |
| 53 | +│ │ AgentConversationService — Multi-turn session mapping │ │ |
| 54 | +│ │ AdaptiveCardFormatter — Response → Adaptive Card JSON │ │ |
| 55 | +│ │ PlaybookInvocationService — Search → Select → Execute flow │ │ |
| 56 | +│ │ EmailDraftService — Matter context → AI email draft │ │ |
| 57 | +│ │ HandoffUrlBuilder — Deep-links to Analysis Workspace │ │ |
| 58 | +│ │ AgentPlaybookStatusSvc — Async job tracking │ │ |
| 59 | +│ │ AgentConfigurationSvc — Admin controls, feature toggles │ │ |
| 60 | +│ │ AgentErrorHandler — User-friendly error cards │ │ |
| 61 | +│ │ AgentTelemetry — Interaction metrics │ │ |
| 62 | +│ └────────────────────────────────┬─────────────────────────────┘ │ |
| 63 | +│ │ delegates to │ |
| 64 | +│ ┌────────────────────────────────▼─────────────────────────────┐ │ |
| 65 | +│ │ EXISTING BFF SERVICES (no new AI logic) │ │ |
| 66 | +│ │ │ │ |
| 67 | +│ │ /api/ai/chat/* — Conversational AI with RAG │ │ |
| 68 | +│ │ /api/ai/search — Semantic/hybrid document search │ │ |
| 69 | +│ │ /api/ai/playbooks/* — Playbook management + execution │ │ |
| 70 | +│ │ /api/ai/analysis/* — Document analysis + workspace │ │ |
| 71 | +│ │ /api/v1/documents/* — Document CRUD + metadata │ │ |
| 72 | +│ │ /api/v1/events/* — Tasks, deadlines, assignments │ │ |
| 73 | +│ │ /api/workspace/* — Portfolio, briefing, summaries │ │ |
| 74 | +│ │ /api/communications/* — Email sending │ │ |
| 75 | +│ └────────────────────────────────┬─────────────────────────────┘ │ |
| 76 | +│ │ │ |
| 77 | +│ ┌────────────────────────────────▼─────────────────────────────┐ │ |
| 78 | +│ │ AZURE SERVICES │ │ |
| 79 | +│ │ Azure OpenAI — LLM (our model, not Microsoft's) │ │ |
| 80 | +│ │ AI Search — Semantic search (tenant-isolated) │ │ |
| 81 | +│ │ Redis — Token + session caching │ │ |
| 82 | +│ │ SPE via Graph — Document storage (discoverabilityDisabled) │ │ |
| 83 | +│ │ Dataverse — Entity data (matters, events, contacts) │ │ |
| 84 | +│ └──────────────────────────────────────────────────────────────┘ │ |
| 85 | +└─────────────────────────────────────────────────────────────────────┘ |
| 86 | +``` |
| 87 | + |
| 88 | +## Key Design Principles |
| 89 | + |
| 90 | +### 1. Agent Endpoints Are Thin Adapters |
| 91 | +The agent gateway (`/api/agent/*`) contains zero AI orchestration logic. Every operation delegates to existing BFF services. This minimizes new code surface and reuses proven infrastructure. |
| 92 | + |
| 93 | +### 2. SPE Documents Are Never Directly Grounded |
| 94 | +SPE containers remain `discoverabilityDisabled = true`. M365 Copilot cannot directly access document content. All document access flows through the BFF API with per-matter/per-project authorization enforcement. |
| 95 | + |
| 96 | +### 3. Adaptive Cards for Structured Results |
| 97 | +All responses to Copilot use Adaptive Card JSON (schema 1.5). Cards include `Action.Submit` buttons for follow-up actions and deep-links to Analysis Workspace for complex work. |
| 98 | + |
| 99 | +### 4. Async Pattern for Long-Running Operations |
| 100 | +Playbooks that exceed the 30-second API response timeout return a progress indicator card with a deep-link to the Analysis Workspace code page. Status can be polled via `GET /api/agent/playbooks/status/{jobId}`. |
| 101 | + |
| 102 | +### 5. M365 Copilot = General Chat; SprkChat = Deep Analysis |
| 103 | +Copilot handles: document search, playbook invocation, matter queries, email drafting, navigation. SprkChat handles: streaming editor integration, inline AI toolbar, compound write-back actions (Analysis Workspace only). |
| 104 | + |
| 105 | +## Deployment Components |
| 106 | + |
| 107 | +| Component | Location | Deployed To | |
| 108 | +|-----------|----------|-------------| |
| 109 | +| Declarative Agent manifest | `src/solutions/CopilotAgent/` | M365 Org App Catalog | |
| 110 | +| API Plugin + OpenAPI spec | `src/solutions/CopilotAgent/` | M365 Org App Catalog | |
| 111 | +| Adaptive Card templates | `src/solutions/CopilotAgent/cards/` | Reference only (cards built in code) | |
| 112 | +| Agent gateway services | `src/server/api/.../Api/Agent/` | Azure App Service (BFF API) | |
| 113 | +| Bot Service | `infrastructure/bot-service/` | Azure Bot Service | |
| 114 | +| BYOK templates | `infrastructure/byok/` | Customer Azure subscription | |
| 115 | + |
| 116 | +## Authentication Flow |
| 117 | + |
| 118 | +``` |
| 119 | +User on MDA Form → M365 Copilot side pane |
| 120 | + │ |
| 121 | + ├── User has Entra ID session (same as MDA) |
| 122 | + │ |
| 123 | + ▼ |
| 124 | +Declarative Agent → API Plugin |
| 125 | + │ |
| 126 | + ├── API Plugin authenticates to BFF via OAuth 2.0 |
| 127 | + │ (delegated permissions, user's identity) |
| 128 | + │ |
| 129 | + ▼ |
| 130 | +BFF API (AgentTokenService) |
| 131 | + │ |
| 132 | + ├── Validates incoming token |
| 133 | + ├── OBO exchange → Graph API token (Files.Read.All, FileStorageContainer.Selected) |
| 134 | + ├── OBO exchange → Dataverse token |
| 135 | + ├── Caches tokens in Redis (tenant-scoped keys per ADR-014) |
| 136 | + │ |
| 137 | + ▼ |
| 138 | +Results returned with user's authorization enforced |
| 139 | +``` |
| 140 | + |
| 141 | +## File Inventory |
| 142 | + |
| 143 | +### Agent Gateway (11 files) |
| 144 | +``` |
| 145 | +src/server/api/Sprk.Bff.Api/Api/Agent/ |
| 146 | +├── AgentEndpoints.cs — 4 REST endpoints (message, playbooks, run, status) |
| 147 | +├── AgentAuthorizationFilter.cs — Endpoint filter for agent auth (ADR-008) |
| 148 | +├── AgentModels.cs — Request/response DTOs |
| 149 | +├── AgentTokenService.cs — SSO/OBO token exchange |
| 150 | +├── AgentConversationService.cs — Multi-turn conversation session mapping |
| 151 | +├── AdaptiveCardFormatterService.cs — BFF response → Adaptive Card JSON |
| 152 | +├── PlaybookInvocationService.cs — Full playbook invocation orchestration |
| 153 | +├── PlaybookStatusEndpoints.cs — Async job tracking service |
| 154 | +├── EmailDraftService.cs — Email draft generation |
| 155 | +├── HandoffUrlBuilder.cs — Deep-link URL generation |
| 156 | +├── SpaarkeAgentHandler.cs — M365 Agents SDK ActivityHandler |
| 157 | +├── AgentConfigurationService.cs — Admin controls and feature toggles |
| 158 | +├── AgentErrorHandler.cs — User-friendly error card generation |
| 159 | +└── AgentTelemetry.cs — Interaction metrics and logging |
| 160 | +``` |
| 161 | + |
| 162 | +### Copilot Agent Package (6 files) |
| 163 | +``` |
| 164 | +src/solutions/CopilotAgent/ |
| 165 | +├── declarativeAgent.json — Agent manifest with instructions |
| 166 | +├── spaarke-api-plugin.json — 27 API Plugin function definitions |
| 167 | +├── spaarke-bff-openapi.yaml — OpenAPI spec (35+ operations) |
| 168 | +├── appPackage/ |
| 169 | +│ ├── manifest.json — Teams app manifest |
| 170 | +│ └── env.dev.json — Dev environment config |
| 171 | +└── cards/ — 10 Adaptive Card templates |
| 172 | + ├── document-list.json |
| 173 | + ├── matter-summary.json |
| 174 | + ├── task-list.json |
| 175 | + ├── playbook-menu.json |
| 176 | + ├── risk-findings.json |
| 177 | + ├── playbook-library.json |
| 178 | + ├── email-preview.json |
| 179 | + ├── handoff-card.json |
| 180 | + ├── progress-indicator.json |
| 181 | + └── error-card.json |
| 182 | +``` |
| 183 | + |
| 184 | +### Infrastructure (5 files) |
| 185 | +``` |
| 186 | +infrastructure/ |
| 187 | +├── bot-service/ |
| 188 | +│ ├── main.bicep — Azure Bot Service template |
| 189 | +│ └── parameters.dev.json — Dev parameters |
| 190 | +└── byok/ |
| 191 | + ├── main.bicep — Full BYOK stack template |
| 192 | + ├── parameters.template.json — Customer parameter template |
| 193 | + └── README.md — BYOK deployment guide |
| 194 | +``` |
| 195 | + |
| 196 | +## ADR Compliance |
| 197 | + |
| 198 | +| ADR | How Complied | |
| 199 | +|-----|-------------| |
| 200 | +| ADR-001 | All agent endpoints use Minimal API pattern | |
| 201 | +| ADR-008 | AgentAuthorizationFilter on all endpoints | |
| 202 | +| ADR-010 | Concrete types, no unnecessary interfaces, AddAgentModule() | |
| 203 | +| ADR-013 | Extends BFF (no separate service), reuses existing AI services | |
| 204 | +| ADR-014 | Redis caching with tenant-scoped keys | |
| 205 | +| ADR-015 | Never logs document content/prompts — identifiers only | |
| 206 | +| ADR-016 | Rate limiting on all agent endpoints | |
| 207 | +| ADR-019 | ProblemDetails for errors, stable errorCodes, correlation IDs | |
| 208 | + |
| 209 | +--- |
| 210 | + |
| 211 | +*Architecture document for M365 Copilot Integration R1* |
0 commit comments