Skip to content

Commit 709cfe8

Browse files
committed
Initial commit: Azure AI Agent Web App
Full-stack web application showcasing Azure AI Foundry Agent Service integration with ASP.NET Core and React. Features: - Single-page chat interface with streaming responses - Entra ID authentication (MSAL.js + JWT Bearer) - Azure AI Foundry Agent Service integration (Projects API) - File upload support for vision-capable agents - Accessible UI with Fluent UI components - Automated deployment with Azure Developer CLI (azd) - Docker containerization for Azure Container Apps Tech Stack: - Backend: ASP.NET Core 9.0, Azure.AI.Projects SDK - Frontend: React 19, TypeScript, Vite, Fluent UI v9 - Infrastructure: Bicep, Azure Container Apps, Container Registry - Auth: Microsoft Entra ID with RBAC
0 parents  commit 709cfe8

121 files changed

Lines changed: 19372 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Dependencies (exclude ALL node_modules directories)
2+
**/node_modules
3+
node_modules
4+
npm-debug.log
5+
6+
# Build outputs (exclude ALL build directories)
7+
.next
8+
out
9+
build
10+
**/dist
11+
dist
12+
bin
13+
obj
14+
**/bin/
15+
**/obj/
16+
**/build/
17+
18+
# Testing
19+
coverage
20+
.vs
21+
22+
# Misc
23+
.DS_Store
24+
*.pem
25+
26+
# Environment files (will be set via build args or runtime env vars)
27+
.env*.local
28+
.env
29+
.env.development
30+
.env.production
31+
32+
# NPM Configuration (INCLUDE .npmrc for custom registries)
33+
# If you use a custom npm registry, add .npmrc to frontend/ directory
34+
# and it will be copied into Docker builds
35+
# Note: For private registries requiring authentication, use build secrets:
36+
# docker build --secret id=npmrc,src=frontend/.npmrc ...
37+
# DO NOT include .npmrc - it gets copied to support custom registries
38+
39+
# Git
40+
.git
41+
.gitignore
42+
.github
43+
44+
# Docker
45+
Dockerfile
46+
.dockerignore
47+
docker-compose.yml
48+
docker-compose.override.yml
49+
50+
# Dev containers
51+
.devcontainer
52+
53+
# Azure (not needed in container)
54+
.azure
55+
azure.yaml
56+
azure.yaml.json
57+
58+
# Infrastructure (not needed in container)
59+
infra
60+
61+
# Documentation (not needed in container)
62+
README.md
63+
*.md
64+
docs
65+
66+
# IDE and scripts (not needed in container)
67+
.vscode
68+
.idea
69+
scripts
70+
71+
# Hooks (not needed in container)
72+
hooks
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
---
2+
description: Azure AI Foundry Agent Service development mode - SDK research, MCP integration, and agent implementation patterns
3+
tools: ['edit', 'search', 'new', 'runCommands', 'runTasks', 'Microsoft Docs/*', 'github/github-mcp-server/get_file_contents', 'github/github-mcp-server/search_code', 'microsoft/playwright-mcp/*', 'runSubagent', 'usages', 'vscodeAPI', 'problems', 'changes', 'fetch', 'githubRepo', 'extensions', 'todos']
4+
model: Claude Sonnet 4.5 (copilot)
5+
---
6+
7+
# Azure AI Agent Development Mode
8+
9+
**Purpose**: Specialized mode for Azure AI Foundry Agent Service development with ASP.NET Core + React.
10+
11+
**When to use**: AI agent features, authentication, SDK integrations, state management, UI components.
12+
13+
## Documentation Layers
14+
15+
Avoid token waste by understanding what lives where:
16+
17+
1. **copilot-instructions.md** (always loaded) → Architecture, workflows, deployment commands, critical patterns
18+
2. **AGENTS.md files** (loaded on-demand) → Implementation details when touching backend/, frontend/, infra/, deployment/
19+
3. **This file** → SDK research patterns, MCP tool usage, testing workflows
20+
21+
**Your role**: Research SDKs, validate with tests, connect documentation sources. Don't duplicate what's in copilot-instructions.md.
22+
23+
## Azure AI Agent SDK Research Pattern
24+
25+
**CRITICAL**: Don't guess SDK usage. Follow this research workflow:
26+
27+
### 1. Search Official Documentation (Start here)
28+
29+
**Official SDK Repository**: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.Agents.Persistent
30+
31+
Use available MCP tools to search Microsoft Learn documentation for Azure AI Agents Persistent SDK features, patterns, and examples.
32+
33+
### 2. Check Semantic Kernel Samples (Complementary patterns)
34+
35+
**Repository**: https://github.com/microsoft/semantic-kernel
36+
37+
**Relevant paths**:
38+
- `dotnet/samples/GettingStartedWithAgents/AzureAIAgent/` - Getting started examples
39+
- `dotnet/samples/Concepts/Agents/` - Advanced patterns (Step##_*.cs files)
40+
41+
Semantic Kernel provides rich examples of Azure AI Agent patterns using its abstraction layer. Use available GitHub MCP tools to search and browse these samples for proven implementation patterns.
42+
43+
**Note**: Semantic Kernel abstracts agent operations through its framework. When adapting patterns, translate SK abstractions to direct Azure.AI.Agents.Persistent SDK types.
44+
45+
### 3. Azure AI Foundry Agent Samples
46+
47+
**Official Samples Repository**: https://github.com/azure-ai-foundry/foundry-samples
48+
49+
**Key paths**:
50+
- `samples/microsoft/csharp/getting-started-agents/` - C# quickstart samples
51+
- `samples/microsoft/python/getting-started-agents/` - Python quickstart samples
52+
- `samples/microsoft/typescript/getting-started-agents/` - TypeScript quickstart samples
53+
- `samples/microsoft/data/` - Sample data files (product info, etc.)
54+
55+
These are the official Azure AI Foundry Agent Service samples showing function calling, file search, code interpreter, and streaming patterns. Use available GitHub MCP tools to explore language-specific implementations.
56+
57+
**Additional UI Sample**: https://github.com/Azure-Samples/get-started-with-ai-agents
58+
- React-based chat UI components and UX patterns
59+
- **Note**: Backend uses Node.js - focus on frontend patterns only
60+
61+
### 4. Broad Code Search (Last resort)
62+
63+
Use available GitHub search tools to find usage examples of specific Azure.AI.Agents.Persistent types across public repositories when official documentation is insufficient.
64+
65+
### Current SDK Version
66+
67+
**Package**: `Azure.AI.Agents.Persistent` v1.2.0-beta.6 (pinned in WebApp.Api.csproj)
68+
69+
**Why pinned**: Beta SDK with evolving API surface. Upgrade deliberately to avoid breaking changes.
70+
71+
**Resources**:
72+
- **NuGet**: https://www.nuget.org/packages/Azure.AI.Agents.Persistent
73+
- **SDK Source**: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.Agents.Persistent
74+
- **API Reference**: https://learn.microsoft.com/en-us/dotnet/api/azure.ai.agents.persistent
75+
- **Official Samples**: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.Agents.Persistent/samples
76+
77+
**Key sample files**:
78+
- Function calling with streaming
79+
- MCP tool integration
80+
- File upload and vector search
81+
- Async patterns
82+
83+
### Microsoft Agent Framework (Higher-level abstraction)
84+
85+
**Package**: `Microsoft.Agents.AI.AzureAI` v1.0.0-preview (also in project)
86+
87+
The Microsoft Agent Framework provides a higher-level abstraction over the Azure AI Foundry Agent Service, offering simplified agent creation and orchestration patterns.
88+
89+
**Resources**:
90+
- **NuGet**: https://www.nuget.org/packages/Microsoft.Agents.AI.AzureAI
91+
- **Documentation**: https://learn.microsoft.com/en-us/agent-framework/user-guide/agents/agent-types/azure-ai-foundry-agent
92+
- **GitHub Samples**: https://github.com/microsoft/agent-framework/tree/main/dotnet/samples
93+
- **Quickstart**: https://learn.microsoft.com/en-us/agent-framework/tutorials/quick-start
94+
95+
**When to use**:
96+
- Need unified agent abstraction across multiple AI services
97+
- Want simplified agent lifecycle management
98+
- Building multi-agent orchestration scenarios
99+
- Prefer higher-level `AIAgent` abstractions over direct SDK calls
100+
101+
**Relationship**: Agent Framework wraps `PersistentAgentsClient` and provides `CreateAIAgentAsync()` extension methods for simplified agent creation. Both can coexist in the same project.
102+
103+
See backend/AGENTS.md for full implementation patterns (credentials, streaming, error handling, cancellation tokens).
104+
105+
## Testing with Playwright MCP
106+
107+
**CRITICAL**: Always test changes before completion.
108+
109+
### Testing Priority (Token efficiency)
110+
111+
1. **Console logs** - State transitions, errors (0 tokens)
112+
2. **Network tab** - API calls, status codes (minimal tokens)
113+
3. **Accessibility snapshot** - DOM structure (low tokens)
114+
4. **Screenshots** - Visual verification (high tokens - only when essential)
115+
116+
### Workflow
117+
118+
```powershell
119+
# Start servers
120+
.\deployment\scripts\start-local-dev.ps1
121+
122+
# Then use Playwright MCP:
123+
# 1. Navigate to http://localhost:5173
124+
# 2. Check console (before/after interactions)
125+
# 3. Verify network requests
126+
# 4. Take accessibility snapshot for DOM validation
127+
```
128+
129+
### When to Test (Not optional)
130+
131+
- After UI component or API endpoint changes
132+
- Before committing multi-step implementations
133+
- When user reports issues
134+
135+
### Validation Checklist
136+
137+
- [ ] Console shows expected actions (🔄 [timestamp] ACTION_TYPE)
138+
- [ ] No console errors/warnings
139+
- [ ] Network tab shows correct status codes (200/400/401/500)
140+
- [ ] DOM elements present in accessibility snapshot
141+
142+
## MCP Tool Usage Strategy
143+
144+
### Documentation Research
145+
146+
Use available Microsoft Learn documentation tools to:
147+
1. **Search** Microsoft Learn for Azure AI Agents SDK topics
148+
2. **Fetch** complete documentation pages when search results need more depth
149+
3. Find official samples, API references, and best practices
150+
151+
### GitHub Repository Access
152+
153+
Use available GitHub MCP tools to:
154+
1. **Search code** across repositories for implementation examples
155+
2. **Browse files** in specific paths for sample code
156+
3. Access repositories: Azure SDK, Semantic Kernel, Azure Samples
157+
158+
### Browser Testing
159+
160+
Use available browser automation tools to:
161+
1. Navigate to http://localhost:5173 after starting local dev
162+
2. Check console logs for state transitions and errors
163+
3. Inspect network requests for API validation
164+
4. Capture accessibility snapshots for DOM structure
165+
5. Take screenshots only when visual verification is essential
166+
167+
## Project-Specific Context
168+
169+
**Architecture**: Single-conversation UI (full-width chat, no sidebar/history)
170+
**State**: Redux-style via React Context + useReducer with dev logging
171+
172+
### AI Agent Service Configuration
173+
174+
**Auto-discovery** (`azd up`): Searches subscription for AI Foundry resources → prompts user to select if multiple exist → discovers agents via REST API → validates RBAC permissions → configures everything automatically.
175+
176+
**Change resource**: `azd provision` (re-runs discovery + updates RBAC + regenerates `.env` files) or `azd env set AI_FOUNDRY_RESOURCE_GROUP <rg>` then `azd provision`.
177+
178+
**Implementation**: `deployment/hooks/preprovision.ps1` (discovery), `infra/main.bicep` (RBAC via `core/security/role-assignment.bicep`).

.github/copilot-instructions.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# AI Agent Web App - Copilot Instructions
2+
3+
**Purpose**: AI-powered web application with Entra ID authentication and Azure AI Foundry Agent Service integration.
4+
5+
## Architecture Overview
6+
7+
### Single Container Pattern
8+
ASP.NET Core serves both REST API (`/api/*`) and React SPA (same origin).
9+
10+
### Authentication Flow
11+
1. Browser → `MSAL.js` (PKCE flow) → JWT with `Chat.ReadWrite` scope
12+
2. Frontend → Backend (JWT Bearer token)
13+
3. Backend → Azure AI Foundry Agent Service (`ManagedIdentityCredential`)
14+
15+
### Configuration Strategy
16+
- **Local**: `.env` files (gitignored, auto-generated)
17+
- **Production**: Environment variables + Docker build args
18+
19+
## Key Files
20+
21+
| File | Purpose |
22+
|------|---------||
23+
| `backend/WebApp.Api/Program.cs` | Middleware + JWT + API endpoints |
24+
| `frontend/src/config/authConfig.ts` | MSAL configuration |
25+
| `deployment/hooks/preprovision.ps1` | Entra app + `.env` generation + AI Foundry discovery |
26+
| `deployment/hooks/postprovision.ps1` | Docker build + deployment |
27+
| `infra/main-app.bicep` | Container App configuration |
28+
29+
## Development Commands
30+
31+
| Command | Purpose | Time |
32+
|---------|---------|------|
33+
| `azd up` | Full deployment (Entra app + infrastructure + container) | 10-12 min |
34+
| `.\deployment\scripts\deploy.ps1` | Code-only deployment (Docker rebuild + push) | 3-5 min |
35+
| VS Code task: "Start Local Dev Servers" | Start local dev (backend + frontend) | Instant |
36+
| `.\deployment\scripts\start-local-dev.ps1` | Start local dev (manual) | Instant |
37+
38+
**Note**: `azd deploy` is not used. This template uses an infra-only pattern where `postprovision` handles initial deployment. For code updates, run the deployment script directly to avoid redundant builds.
39+
40+
## Development Workflow
41+
42+
### Step 1: Initial Setup
43+
- **Goal**: Configure authentication and generate config files
44+
- **Action**: Run `azd up` (creates Entra app, deploys to Azure)
45+
- **Result**: `.env` files generated in `frontend/` and `backend/WebApp.Api/`
46+
47+
### Step 2: Daily Development
48+
- **Goal**: Run local servers with hot reload
49+
- **Action**: Run VS Code task "Start Local Dev Servers"
50+
- **Result**: Backend (port 8080) + Frontend (port 5173) in separate terminals
51+
52+
### Step 3: Deploy Changes
53+
- **Goal**: Update cloud deployment with code changes
54+
- **Action**: Run `.\deployment\scripts\deploy.ps1` (Docker rebuild + push)
55+
- **Transition**: Test at `https://<app>.azurecontainerapps.io`
56+
57+
## Custom npm Registries
58+
59+
**Pattern**: Add `.npmrc` to `frontend/` directory
60+
61+
```ini
62+
# frontend/.npmrc
63+
registry=https://registry.example.com/
64+
//registry.example.com/:_authToken=${NPM_TOKEN}
65+
```
66+
67+
Dockerfile copies `.npmrc` if present. Don't commit tokens.
68+
69+
## Critical Patterns
70+
71+
### Middleware Order (NEVER reorder)
72+
**Goal**: Serve static files, validate auth, route APIs, fallback to SPA
73+
74+
**See**: `backend/WebApp.Api/Program.cs` for correct ordering:
75+
1. `UseDefaultFiles()` / `UseStaticFiles()` - Serve SPA assets
76+
2. `UseAuthentication()` / `UseAuthorization()` - Validate JWT
77+
3. Map API endpoints
78+
4. `MapFallbackToFile("index.html")` - MUST BE LAST
79+
80+
### API Endpoint Pattern
81+
**Always use**: `.RequireAuthorization("RequireChatScope")` + `CancellationToken` + `IHostEnvironment` (for error handling)
82+
83+
**See**: `backend/WebApp.Api/Program.cs` for endpoint patterns with:
84+
- `ErrorResponseFactory.CreateFromException()` for RFC 7807-compliant errors
85+
- Development vs production error detail sanitization
86+
- Proper exception handling in streaming and non-streaming endpoints
87+
88+
### Credential Strategy
89+
**Local**: `ChainedTokenCredential` (uses `az login`)
90+
**Production**: `ManagedIdentityCredential` (system-assigned)
91+
92+
**See**: `backend/WebApp.Api/Services/AzureAIAgentService.cs` constructor for environment-aware credential selection
93+
94+
## Deployment Phases
95+
96+
1. **preprovision** → Entra app + AI Foundry auto-discovery + `.env` generation
97+
2. **provision** → Deploy Azure resources via Bicep
98+
3. **postprovision** → Updates redirect URIs + calls `build-and-deploy-container.ps1` to build/deploy container
99+
100+
**Deployment logic**: Shared `build-and-deploy-container` module (DRY) uses local Docker if available, ACR cloud build otherwise.
101+
102+
**Code-only deployment**: Use `.\deployment\scripts\deploy.ps1` (faster than `azd up`).
103+
104+
## Troubleshooting
105+
106+
| Issue | Fix |
107+
|-------|-----|
108+
| `VITE_ENTRA_SPA_CLIENT_ID not set` | Run `azd up` |
109+
| `AI_AGENT_ENDPOINT not configured` | Run `azd provision` to re-discover AI Foundry resources |
110+
| No AI Foundry resources found | Create an AI Foundry resource at https://ai.azure.com |
111+
| 401 on `/api/*` | Verify token has `Chat.ReadWrite` scope |
112+
| `ManagedIdentityCredential` error locally | Set `ASPNETCORE_ENVIRONMENT=Development` |
113+
| Multiple AI Foundry resources | Run `azd provision` to select a different resource |
114+
115+
## Folder Documentation
116+
117+
See `AGENTS.md` files for implementation details:
118+
- `backend/AGENTS.md` → ASP.NET Core + JWT + AI Agent SDK
119+
- `frontend/AGENTS.md` → React + MSAL + Vite
120+
- `infra/AGENTS.md` → Bicep + RBAC + Container Apps
121+
- `deployment/AGENTS.md` → Hooks + Docker + Deployment
122+
123+
## Essential Rules
124+
125+
### ✅ Always Do
126+
- Use `.RequireAuthorization("RequireChatScope")` on all API endpoints
127+
- Accept and propagate `CancellationToken` in async methods
128+
- Use `ErrorResponseFactory.CreateFromException()` for consistent error responses
129+
- Implement `IDisposable` for services with disposable resources (e.g., `SemaphoreSlim`)
130+
- Validate file uploads before processing (size, count, type)
131+
- Use explicit credentials: `ChainedTokenCredential` (local) or `ManagedIdentityCredential` (cloud)
132+
- Try `acquireTokenSilent()` first, fallback to `acquireTokenPopup()`
133+
- Access `import.meta.env.*` at module level only
134+
135+
### ❌ Never Do
136+
- Commit `.env*` files
137+
- Use `.Result` or `.Wait()` on async methods
138+
- Expose internal error details in production (use `IHostEnvironment.IsDevelopment()`)
139+
- Forget disposal guards in `IDisposable` methods
140+
- Reorder middleware pipeline
141+
- Access `import.meta.env.*` inside functions

0 commit comments

Comments
 (0)