An intelligent task management assistant built with Microsoft Agent Framework, Azure OpenAI, and .NET Aspire. Features a ChatGPT-like streaming interface using AG-UI protocol with Server-Sent Events (SSE), Clean Architecture with dual-database persistence (SQL Server + PostgreSQL), production-grade observability with OpenTelemetry, and comprehensive testing infrastructure (225+ tests).
Watch the full demonstration of the Task Agent in action, showcasing:
- Natural language task management
- AI-powered suggestions and insights
- Content Safety protection
- Real-time chat management
- Modern Next.js frontend with ChatGPT-inspired UI
This project is documented in a comprehensive article series on C# Corner:
- Building a Task Management AI Agent - Microsoft Agent Framework, Azure OpenAI integration, and Clean Architecture
- Securing AI Agents - Azure AI Content Safety with Prompt Shield and parallel validation
- Production-Grade Observability - .NET Aspire, OpenTelemetry, and Application Insights
- Modern Frontend Architecture - Next.js 16 separation, dual-database strategy, and Azure Static Web Apps
- Real-Time Streaming with AG-UI - SSE streaming, ChatGPT-like progressive rendering, and state persistence
Topics Covered:
- π€ Autonomous AI agents with function calling
- π Multi-layer security (Prompt Shield + Content Moderation)
- π Production observability (Aspire Dashboard + Application Insights)
- βοΈ Modern React with Next.js 16 and TypeScript
- ποΈ Dual-database architecture (SQL Server + PostgreSQL)
- βοΈ Azure deployment with Static Web Apps
# 1. Configure your Azure credentials in src/backend/services/TaskAgent/src/TaskAgent.WebApi/appsettings.Development.json
# 2. Setup PostgreSQL database (see docs/POSTGRESQL_MIGRATION.md for details)
# 3. Run with .NET Aspire (includes Aspire Dashboard)
dotnet run --project src/TaskAgent.AppHost
# Or run backend standalone
cd src/backend/services/TaskAgent/src
dotnet run --project TaskAgent.WebApi
# 4. Run frontend (separate terminal)
cd src/frontend/task-agent-web
pnpm install
pnpm devAccess:
- Frontend: http://localhost:3000
- Backend API: https://localhost:5001
- Aspire Dashboard: https://localhost:17198 (when using Aspire)
Backend Features:
- π¬ Natural Language Interface: Talk to your task manager like a person
- π‘οΈ Multi-Layer Security: Azure Content Safety protection (Prompt Shield + Content Moderation)
- π Production-Grade Observability: Full OpenTelemetry stack with .NET Aspire
- π Centralized Logging: Serilog with console, file, and OpenTelemetry sinks
- π― AG-UI Protocol: Custom streaming endpoint
/api/agent/chatwith SSE and state persistence - β Complete CRUD: Create, read, update, and delete tasks
- π Smart Analytics: Task summaries with filtering by status and priority
- π¨ Beautiful Tables: Markdown-formatted responses with emojis
- π‘ Contextual Suggestions: Agent provides helpful next actions
- ποΈ PostgreSQL Persistence: Entity Framework Core with JSON storage (preserves property order)
- π¬ Chat Management: Persistent threads with automatic message persistence
- π Distributed Tracing: End-to-end request tracking with custom activity sources
- π Custom Metrics: Real-time monitoring of AI agent operations
Frontend Features:
- βοΈ Modern React: Next.js 16 + React 19 with TypeScript
- π― Server Components: Optimized bundle size and performance
- π¨ ChatGPT-Inspired UI: Full-height adaptive layout with Tailwind CSS 4
- π Dark Theme Support: System detection + manual toggle with next-themes
- π Smart Layout: Centered welcome state, fixed input when chatting
- π Independent Scrolling: Fixed header and input, scrollable messages
- π‘ Clickable Suggestions: Interactive suggestion buttons from AI
- β³ Contextual Loading: Rotating status messages during processing
- β‘ Optimistic Updates: Instant message feedback
- π Markdown Rendering: Rich text formatting in chat
- π Type Safety: Full TypeScript with backend contract alignment
- π§© Clean Architecture: Separation of concerns (UI β Hooks β API)
- π Chat Management: List, load, and delete chats with auto-generated titles
- ποΈ Sidebar Navigation: Collapsible sidebar with chat history
This project implements production-grade observability using .NET Aspire and OpenTelemetry with a hybrid architecture:
Stack: OpenTelemetry β OTLP Exporter β Aspire Dashboard (https://localhost:17198)
Features:
- π Real-time metrics visualization
- π Distributed tracing with automatic trace correlation
- π Structured logging with log levels and scopes (via Serilog + OpenTelemetry)
- π Dependency mapping (Azure OpenAI, Content Safety, PostgreSQL)
- π― Custom instrumentation for AI agent operations
Stack: OpenTelemetry β Azure Monitor Exporter β Application Insights
Features:
- π Performance monitoring and alerting
- πΊοΈ Application Map with dependencies
- π₯ Live metrics and real-time telemetry
- π Custom dashboards and workbooks
- π Smart detection and anomaly alerts
Centralized Configuration via ServiceDefaults:
- Logging (Serilog) - Console + File sinks + OpenTelemetry integration
- Tracing (OpenTelemetry Activity) - Custom activity sources for AI agent
- Metrics (OpenTelemetry Meter) - Custom meters for AI operations
Custom AI Agent Metrics:
Meter: "TaskAgent.Agent"
Counters:
- agent.requests β Total requests to the agent
- agent.function_calls β Function tool invocations
- agent.errors β Error count by type
Histograms:
- agent.response.duration β Response time in millisecondsBuilt-in Metrics (automatic):
- ASP.NET Core instrumentation (HTTP requests, response times)
- HTTP Client instrumentation (Azure OpenAI, Content Safety calls)
- Runtime instrumentation (GC, thread pool, exceptions)
Custom Activity Sources:
ActivitySource: "TaskAgent.Agent"
Spans:
- Agent.ProcessMessage β End-to-end message processing
- Function.{FunctionName} β Individual function tool calls
Tags:
- thread.id β Chat thread identifier
- function.name β Called function name
- message.length β User message size
- response.length β Agent response sizeBuilt-in Traces (automatic):
- ASP.NET Core HTTP requests
- Entity Framework Core SQL queries (development only)
- HTTP client calls to Azure services
Configuration:
- Formatted messages included
- Log scopes enabled
- Integration with OpenTelemetry
- Automatic correlation with traces
Log Levels:
- Information: Agent operations, function calls
- Warning: Content safety blocks, validation failures
- Error: Exceptions, service failures
Smart Environment Detection:
// Automatically selects exporter based on configuration
if (OTEL_EXPORTER_OTLP_ENDPOINT exists)
β Use OTLP β Aspire Dashboard
if (APPLICATIONINSIGHTS_CONNECTION_STRING exists)
β Use Azure Monitor β Application InsightsSecurity: SQL statement capture is disabled in production to prevent sensitive data leakage.
Service Discovery: HTTPS-only in production, HTTP + HTTPS in development.
This application leverages Azure OpenAI's built-in content filtering system for content safety.
Azure OpenAI automatically filters content in the following categories:
- Hate speech β Medium threshold (blocks moderate+ severity)
- Violence β Medium threshold (blocks moderate+ severity)
- Sexual content β Medium threshold (blocks moderate+ severity)
- Self-harm β Medium threshold (blocks moderate+ severity)
- Prompt injection attacks (Jailbreak detection)
When content filter triggers:
- Azure OpenAI returns HTTP 400 with
code: "content_filter" - Backend catches
ClientResultExceptioninAgentStreamingService - Sends
CONTENT_FILTERSSE event to frontend - Frontend displays ChatGPT-like friendly message in chat (not toast)
Blocked Message Handling:
- β Blocked messages appear as assistant responses in chat (not error toasts)
- β Thread placeholders created for chat continuity (ChatGPT-like UX)
- β Blocked content is NEVER persisted in database (security measure)
- β Automatic sidebar updates when threads are created
- β Smart title regeneration when first valid message is sent after a block
- β Optimized sidebar refresh: only reloads when title changes from null (efficient!)
Best Practices:
- Generic conversational refusals (like ChatGPT) - no technical details exposed
- Security violations render as normal bot messages
- No error styling for content safety blocks
For detailed testing guide: See docs/CONTENT_SAFETY.md
Built with Clean Architecture for maintainability and testability:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend (Next.js) β
β β’ React 19 + TypeScript β
β β’ Server Components + Client Components β
β β’ Chat Management UI β
ββββββββββββββββββββββ¬βββββββββββββββββββββββββββββ
β REST API
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Backend (.NET 10) β
β β
β Presentation β Infrastructure β Application β
β β Domain β
β β
β β’ AI Agent with 6 function tools β
β β’ Content Safety middleware β
β β’ Dual-database persistence β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Databases & Services β
β β’ SQL Server: Task entities β
β β’ PostgreSQL: Chat threads (JSON) β
β β’ Azure OpenAI: GPT-4o-mini β
β β’ Azure AI Content Safety β
β β’ Application Insights β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
For detailed architecture documentation:
- π Backend README - Clean Architecture layers, API endpoints, observability
- π Frontend README - Component structure, state management, API integration
- π Architecture Decisions - Dual-database rationale and patterns
- π Architecture Diagrams - Visual diagrams (system overview, SSE flow, observability)
| Technology | Purpose |
|---|---|
| .NET 10 | Modern web framework |
| ASP.NET Core Web API | RESTful API |
| .NET Aspire 13.0.0 | Cloud-native orchestration |
| OpenTelemetry | Observability framework |
| Entity Framework Core 10 | Database ORM |
| SQL Server | Task data persistence |
| PostgreSQL 15+ | Chat persistence |
| Microsoft Agent Framework | Autonomous AI agents (preview) |
| Azure OpenAI (GPT-4o-mini) | Language model |
| Azure AI Content Safety | Security & moderation |
| Technology | Purpose |
|---|---|
| Next.js 16 | React framework |
| React 19 | UI library |
| TypeScript 5 | Type-safe JavaScript |
| Tailwind CSS 4 | Utility-first CSS |
| pnpm | Fast package manager |
| react-markdown | Markdown rendering |
| SWR (planned) | Data fetching & caching |
| Technology | Purpose |
|---|---|
| xUnit 2.9.3 | .NET testing framework |
| FluentAssertions 8.8.0 | Readable assertions |
| NSubstitute 5.3.0 | Mocking framework |
| Testcontainers 4.4.0 | Real database containers |
| Vitest | Frontend unit testing |
| Playwright | E2E testing |
Comprehensive test suites for both backend and frontend with 225+ tests total.
| Project | Tests | Type | Description |
|---|---|---|---|
TaskAgent.Domain.UnitTests |
28 | Unit | Entity validation, constants |
TaskAgent.Application.UnitTests |
76 | Unit | AI function tools with mocks |
TaskAgent.Infrastructure.IntegrationTests |
27 | Integration | Real SQL Server/PostgreSQL via Testcontainers |
# Run all backend tests
cd src/backend/services/TaskAgent/tests
dotnet test
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
# Unit tests only (fast, no Docker)
dotnet test --filter "FullyQualifiedName~UnitTests"
# Integration tests (requires Docker)
dotnet test --filter "FullyQualifiedName~IntegrationTests"For detailed backend testing strategy: See Backend TESTING_STRATEGY.md
| Type | Tests | Description |
|---|---|---|
| Unit Tests | 57 | Components, hooks, utilities |
| E2E Tests | 37 | User flows with Playwright |
cd src/frontend/task-agent-web
# Unit tests with coverage
pnpm test:coverage
# E2E tests
pnpm test:e2eFor detailed frontend testing strategy: See Frontend TESTING_STRATEGY.md
Both workflows execute tests before deployment:
- Backend: Unit + Integration tests with Testcontainers
- Frontend: Unit tests with coverage + Playwright E2E
See Workflows README for detailed CI/CD documentation.
- .NET 10 SDK
- Node.js 20+ (for Next.js frontend)
- pnpm package manager (
npm install -g pnpm) - PostgreSQL 15+ (see PostgreSQL Setup Guide)
- Azure OpenAI resource with deployed model (GPT-4o-mini recommended)
- Azure AI Content Safety resource
- Azure Application Insights resource (for production)
1. Update appsettings.Development.json:
{
"AzureOpenAI": {
"Endpoint": "https://your-openai-resource.openai.azure.com/",
"ApiKey": "your-openai-api-key",
"ModelDeployment": "gpt-4o-mini"
}
}Note: Content safety is handled by Azure OpenAI's built-in content filtering. No separate configuration required.
2. Database Setup:
# Install PostgreSQL 15+ (see docs/POSTGRESQL_MIGRATION.md for detailed instructions)
# Create database
psql -U postgres
CREATE DATABASE "TaskAgentDb";
\q
# Update connection strings in appsettings.Development.json
{
"ConnectionStrings": {
"TasksConnection": "Server=localhost;Database=TaskAgentDb;Trusted_Connection=true;",
"ConversationsConnection": "Host=localhost;Port=5432;Database=taskagent_conversations;Username=postgres;Password=your_password"
}
}
# Migrations apply automatically on startup
# Or run manually from src/backend/services/TaskAgent/src:
dotnet ef database update --context TaskDbContext --project TaskAgent.Infrastructure --startup-project TaskAgent.WebApi
dotnet ef database update --context ConversationDbContext --project TaskAgent.Infrastructure --startup-project TaskAgent.WebApi3. Configure Frontend - Create .env.local:
# src/frontend/task-agent-web/.env.local
NEXT_PUBLIC_API_URL=https://localhost:50014. Install Frontend Dependencies:
cd src/frontend/task-agent-web
pnpm install5. Run with Aspire (recommended - runs both backend and prepares for frontend):
# From repository root
dotnet run --project src/TaskAgent.AppHost- Backend API: https://localhost:5001
- Aspire Dashboard: https://localhost:17198
6. Run Frontend (in a separate terminal):
cd src/frontend/task-agent-web
pnpm dev- Frontend: http://localhost:3000
1. Update appsettings.Production.json:
{
"AzureOpenAI": {
"Endpoint": "https://your-openai-resource.openai.azure.com/",
"ApiKey": "your-openai-api-key",
"ModelDeployment": "gpt-4o-mini"
},
"APPLICATIONINSIGHTS_CONNECTION_STRING": "InstrumentationKey=your-key;IngestionEndpoint=https://...",
"ConnectionStrings": {
"TasksConnection": "Server=tcp:your-server.database.windows.net,1433;Initial Catalog=TaskAgentDb;User ID=your_user;Password=your_password;Encrypt=True;",
"ConversationsConnection": "Host=your-postgres-server.postgres.database.azure.com;Port=5432;Database=TaskAgentDb;Username=your_user;Password=your_password;SslMode=Require;"
}
}Note: Content safety is handled by Azure OpenAI's built-in content filtering. No separate Content Safety resource required.
2. Deploy to Azure App Service using standard deployment methods.
The Task Agent provides 6 function tools:
| Function | Description |
|---|---|
CreateTask |
Create new tasks with title, description, priority |
ListTasks |
Show all tasks with optional filters |
GetTaskDetails |
Get detailed info about a specific task |
UpdateTask |
Modify task status or priority |
DeleteTask |
Remove tasks |
GetTaskSummary |
View statistics and analytics |
Example Interactions:
You: Create a high priority task to review the quarterly report
Agent: β
Task created! ID: 1, Priority: High
You: Show me all my tasks
Agent: [Displays beautiful Markdown table with all tasks]
π‘ Suggestions: β’ Filter by priority β’ Update oldest task
You: Mark task 1 as Completed
Agent: β
Task updated! Status changed to Completed
Lists 2+ tasks in beautiful formatted tables with emojis:
- Status: β³ Pending, π InProgress, β Completed
- Priority: π’ Low, π‘ Medium, π΄ High
Agent provides 1-2 smart suggestions after each operation:
- After creating: "View all tasks" or "Create follow-up"
- After listing: "Filter by priority" or "Update oldest task"
- After completing: "View remaining tasks" or "Get summary"
- Detects many pending tasks β suggests prioritizing
- Celebrates milestones β "π Great! You've completed 5 tasks!"
- Encourages progress
TaskAgentWeb/
βββ src/ # Source code root
β β
β βββ .editorconfig # C# code style rules (shared)
β βββ Directory.Build.props # β MSBuild properties (MUST be at src/ level)
β βββ Directory.Packages.props # β Central Package Management (MUST be at src/ level)
β βββ global.json # β .NET SDK + Aspire SDK versions (MUST be at src/ level)
β β
β βββ TaskAgent.AppHost/ # .NET Aspire orchestration (root level)
β β βββ AppHost.cs # Orchestrates backend (+ future frontend)
β β βββ appsettings.json # Aspire settings
β β βββ Properties/launchSettings.json # Aspire Dashboard launch config
β β
β βββ backend/ # Backend services (.NET 10 Web API)
β β βββ ... # See src/backend/services/TaskAgent/README.md
β β
β βββ frontend/ # Frontend applications (Next.js 16)
β βββ ... # See src/frontend/task-agent-web/README.md
β
βββ docs/ # Documentation
β βββ screenshots/ # Application screenshots
β βββ CONTENT_SAFETY.md # Content Safety testing guide (75+ cases)
β βββ DUAL_DATABASE_ARCHITECTURE.md # PostgreSQL + SQL Server patterns
β βββ POSTGRESQL_MIGRATION.md # PostgreSQL setup guide
β βββ FRONTEND_E2E_TESTING.md # Frontend testing guide
β
βββ scripts/ # PowerShell scripts
β βββ Analyze-Commits.ps1 # Commit analysis tool
β βββ config.json # Script configuration
β βββ README.md # Scripts documentation
β
βββ .github/ # GitHub workflows & Copilot instructions
β βββ copilot-instructions.md # Project-specific AI guidelines
β
βββ LICENSE # MIT License
βββ README.md # This file
For detailed structure:
- π Backend: See src/backend/services/TaskAgent/README.md for Clean Architecture layers (Domain, Application, Infrastructure, WebApp)
- π Frontend: See src/frontend/task-agent-web/README.md for Next.js components, hooks, and API integration
MSBuild Configuration at Root: Directory.Build.props, Directory.Packages.props, and global.json live at src/ level (not in backend/). MSBuild searches upward from each project directory - this ensures both TaskAgent.AppHost (at src/) and backend projects (at src/backend/services/) can access them. No duplicates needed.
Clean Architecture: Domain β Application β Infrastructure β WebApp (strict dependency flow, Domain has NO external dependencies)
Aspire Orchestration at Root: TaskAgent.AppHost lives outside backend/ because it orchestrates both backend and future frontend services
Backend-Only Telemetry: TaskAgent.ServiceDefaults is .NET-specific OpenTelemetry, lives in backend/, NOT used by frontend
Observability-First: OpenTelemetry instrumentation at every layer via ServiceDefaults
Hybrid Telemetry:
- Development: OTLP β Aspire Dashboard
- Production: Azure Monitor β Application Insights
Security: Content Safety middleware + HTTPS-only service discovery in production
- 2-Layer Defense: Automatic Prompt Shield + Content Moderation
- Fail-Secure: Blocks requests on Prompt Shield errors; Fail-Open on Content Moderation for availability
- Optimized Detection: Prompt Shield uses pre-trained model (no system context) to reduce false positives
- Performance: HttpClientFactory with Named HttpClient for connection pooling and DNS refresh
- Immutable DTOs: Record types for thread-safety and proper equality semantics
- Best Practices: ChatGPT-style generic refusals without exposing attack details
- See: docs/CONTENT_SAFETY.md for 75+ test cases and troubleshooting
- Input Validation: EF Core parameterized queries prevent SQL injection
- XSS Protection: DOMPurify sanitization on client-side
- Configuration Validation: Startup checks for missing credentials
- HTTPS Enforcement: Service discovery restricted to HTTPS in production
- Secret Management: Never commit API keys - use Azure Key Vault in production
- SQL Security: Database statement capture disabled in production
Real-time observability with traces, metrics, and logs
End-to-end request tracing with custom activity sources
AI agent performance metrics (requests, function calls, response time)
Response time and dependency tracking
Production distributed tracing
- Changelog - All notable changes to this project
- CI/CD Workflows - GitHub Actions pipelines (Backend & Frontend)
- Content Safety Guide - Security testing with 75+ test cases
- Documentation Index - Full documentation structure
This project is licensed under the MIT License - see the LICENSE file for details.
- β Free to use for personal and commercial projects
- β Free to modify and distribute
- β Free to use in your own educational content
- βΉοΈ Just keep the copyright notice
Built with β€οΈ using .NET 10, Next.js 16, React 19, Microsoft Agent Framework, .NET Aspire, and Clean Architecture

