EncryptedTouhid.AgentFramework.Templates 0.4.1

dotnet new install EncryptedTouhid.AgentFramework.Templates::0.4.1
                    
This package contains a .NET Template Package you can call from the shell/command line.

Complete Agent — Microsoft Agent Framework Template

CI NuGet version NuGet pre-release NuGet downloads License: MIT .NET 10

A production-grade dotnet new template for building AI agents on Microsoft Agent Framework in .NET 10.

Generates a Clean-Architecture solution with everything a real deployment needs: dependency injection, validated configuration, versioned prompts, function tools, RAG, conversation memory, content moderation, cost budgeting, JWT + API-key auth, distributed rate limiting, OpenTelemetry, retries, health checks, structured JSON output, streaming, plus Docker and Kubernetes manifests.


Quick start

# 1. Install the template
dotnet new install EncryptedTouhid.AgentFramework.Templates

# 2. Generate a new solution
dotnet new et-complete-agent -n CompleteAgent
cd CompleteAgent

# 3. Set a provider + API key (Azure OpenAI shown below)
dotnet user-secrets set "Agent:AzureOpenAI:Endpoint" "https://<resource>.openai.azure.com" \
    --project src/EncryptedTouhid.CompleteAgent.Host
az login   # DefaultAzureCredential picks this up

# 4. Set an API key for your agent endpoint
dotnet user-secrets set "Authentication:ApiKey" "$(openssl rand -hex 16)" \
    --project src/EncryptedTouhid.CompleteAgent.Host

# 5. Run
dotnet run --project src/EncryptedTouhid.CompleteAgent.Host
# Call the agent
curl -X POST http://localhost:5000/agent/run \
  -H "X-API-Key: <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"input": "Summarise Clean Architecture in two sentences."}'

What you get

CompleteAgent/
├── CompleteAgent.sln
├── Dockerfile                                Multi-stage, distroless, non-root
├── docker-compose.yml                        Agent + Redis + Qdrant for local dev
├── deploy/k8s/                               Namespace, Deployment, HPA, NetworkPolicy, ...
├── src/
│   ├── EncryptedTouhid.CompleteAgent.Domain/                    Contracts, value records (zero deps)
│   ├── EncryptedTouhid.CompleteAgent.Application/               Runner, tools, workflows, sanitiser, retry
│   ├── EncryptedTouhid.CompleteAgent.Infrastructure/            LLM client, EF Core, Qdrant, moderation
│   └── EncryptedTouhid.CompleteAgent.Host/                      Program.cs, endpoints, auth, telemetry
└── tests/
    └── EncryptedTouhid.CompleteAgent.Application.Tests/         xUnit + NSubstitute + FakeTimeProvider

All assemblies use the EncryptedTouhid.<ProjectName>.* namespace convention. The EncryptedTouhid. prefix is the org marker and stays fixed; the middle segment is whatever you pass to dotnet new -n.


Feature inventory

Agent core

LLM providers Azure OpenAI (DefaultAzureCredential) and OpenAI (OPENAI_API_KEY), switchable at runtime
Function tools GetCurrentTimeTool, SearchKnowledgeBaseTool, RetrieveDocumentsTool (RAG) — extend via AIFunctionFactory.Create
Workflow ResearchAndSummariseWorkflow (multi-agent pipeline)
Streaming IAsyncEnumerable<string> runner + SSE HTTP endpoint
Structured output Sentiment classifier endpoint returning typed JSON
Conversation memory IConversationStore with eight backings: InMemory, Sqlite, SqlServer, AzureSql, Postgres, MySql, Cosmos, Mongo. TTL + message cap honoured per provider, matching IAuditLog impl ships per backend
RAG IDocumentRetriever with InMemory cosine-similarity + Qdrant gRPC implementations
Versioned prompts src/<Name>.Host/Prompts/v1/{system,guardrails,examples}.md — bump to v2/ for a roll

Safety & policy

Input sanitisation InputSanitiser delimits and escapes user input to mitigate prompt injection
Output guardrail OutputGuardrail scrubs emails, secrets, phone numbers from agent responses
Content moderation IContentModerator abstraction with no-op default + Azure AI Content Safety implementation
PII-safe logging PromptRedactor truncates and redacts before logs; source-gen LoggerMessage everywhere
Prompt evals Golden-set tests verifying prompt structure and absence of leaked secrets

Platform & ops

Authentication X-API-Key middleware (constant-time compare) + optional JWT bearer (Entra ID / Auth0 / Okta)
Authorization AgentAccess policy — requires JWT when enabled, open when not
Rate limiting Per-key fixed window — in-memory default, Redis Lua-script for multi-instance
Cost budget Per-key daily token cap, returns 402 Payment Required when exceeded
Retries Exponential backoff on HttpRequestException, TimeoutException
Telemetry OpenTelemetry traces + metrics, OTLP + console exporters, instruments Microsoft.Agents.AI, ASP.NET Core, HttpClient
Health checks /healthz (liveness), /readyz (validates LLM config is present)
OpenAPI MapOpenApi() exposes the schema; wire your Swagger UI of choice

Engineering quality

Architecture Strict Clean Architecture: Domain ← Application ← Infrastructure ← Host
DI Microsoft.Extensions.DependencyInjection throughout; layer-scoped Add* extensions
Config Options pattern with DataAnnotations + IValidatableObject + ValidateOnStart
Analyzers NetAnalyzers, SonarAnalyzer.CSharp, SecurityCodeScan.VS2019
Build hygiene TreatWarningsAsErrors=true, nullable enabled, implicit usings, central package versioning
Tests xUnit + NSubstitute + FakeTimeProvider — all MIT/Apache, zero commercial libraries
AOT-friendly JSON JsonSerializerContext source-gen for endpoint DTOs

HTTP API surface

Method Path Description
POST /agent/run Single-turn request. Auto-persists turn when conversationId is supplied.
POST /agent/stream Server-Sent Events stream of agent output.
POST /agent/classify Structured-output example returning typed sentiment JSON.
DELETE /agent/conversations/{conversationId} Wipes a stored conversation.
GET /healthz Liveness — bypasses auth and rate limiting.
GET /readyz Readiness — validates LLM provider configuration.
GET /openapi/v1.json OpenAPI schema (raw JSON).
GET /scalar Interactive API explorer (Scalar UI, GitHub-themed, dark/light auto).

Request body for /agent/run and /agent/stream:

{ "input": "...", "conversationId": "optional-uuid" }

Configuration

Every knob lives in appsettings.json (or env vars prefixed COMPLETEAGENT_, or dotnet user-secrets). Defaults are dev-friendly so the template runs out of the box; production hardens by flipping switches.

Section What it controls
Agent LLM provider (AzureOpenAI/OpenAI), model, endpoint, API key
Authentication API key for the X-API-Key header
Jwt OIDC bearer auth (authority, audience, issuers) — disabled by default
RateLimit InMemory or Redis, permits, window, Redis connection string
CostBudget Daily token cap per key — disabled by default
Resilience Retry attempts, backoff seconds
Telemetry Service name, OTLP endpoint, console exporter toggle
Conversation TTL minutes, max messages per conversation
Persistence InMemory · Sqlite · SqlServer · AzureSql · Postgres · MySql · Cosmos · Mongo. Same connection string for relational + Mongo; nested Cosmos.* / Mongo.* blocks for document stores
Retrieval Embedding model, vector store (InMemory or Qdrant), Qdrant host/port
Moderation None or AzureContentSafety, endpoint, max severity threshold

Conversation memory backends

IConversationStore ships with 8 backings, selected via Persistence:ConversationStore. Every backend honours Conversation:TtlMinutes and Conversation:MaxMessagesPerConversation, has a matching IAuditLog implementation, exposes a provider-aware /readyz health check, and idempotently creates its schema / containers / indexes on startup.

Backend ConversationStore value Required config Best for
In-memory InMemory (default) none Dev, single-instance, no durability
SQLite Sqlite Persistence:ConnectionString="Data Source=completeagent.db" Single-node prod, embedded, zero ops
SQL Server SqlServer Persistence:ConnectionString="Server=...;Database=...;..." Existing MSSQL fleet, on-prem or VM
Azure SQL AzureSql Persistence:ConnectionString="Server=tcp:<x>.database.windows.net,1433;Database=...;..." Azure-managed SQL with retry-on-failure baked in
PostgreSQL Postgres Persistence:ConnectionString="Host=...;Username=...;Password=...;Database=..." Open-source RDBMS, Aurora / RDS / Supabase / Neon
MySQL MySql Persistence:ConnectionString="Server=...;Database=...;Uid=...;Pwd=..." Existing MySQL / MariaDB fleet, Aurora MySQL
Cosmos DB Cosmos Persistence:Cosmos:ConnectionString or Persistence:Cosmos:AccountEndpoint + Persistence:Cosmos:AccountKey (+ Database, ConversationsContainer, AuditContainer) Global distribution, autoscale, per-doc TTL
MongoDB Mongo Persistence:ConnectionString="mongodb://..." (+ Persistence:Mongo:Database, ConversationsCollection, AuditCollection) Document-oriented, replica sets, Atlas

Implementation details:

  • Relational (Sqlite · SqlServer · AzureSql · Postgres · MySql) share EfCoreConversationStore + EfCoreAuditLog. RelationalSchemaBootstrapper calls EnsureCreatedAsync on startup. SQL Server, Azure SQL, PostgreSQL, and MySQL use their native datetimeoffset types; SQLite uses a value converter to ticks so range queries translate.
  • Cosmos DB uses the native Microsoft.Azure.Cosmos SDK. Container is partitioned by /conversationId. CosmosSchemaBootstrapper creates database + containers (TTL set to Conversation:TtlMinutes × 60s).
  • MongoDB uses the native MongoDB.Driver. MongoSchemaBootstrapper ensures a compound (conversationId, createdAt) index for fast load plus a TTL index on createdAt for auto-expiry.

Health checks are auto-registered per selected backend (RelationalDbHealthCheck / CosmosHealthCheck / MongoHealthCheck) and tagged ready, so /readyz fails fast when the configured store is unreachable.

To plug a custom backing (DynamoDB, Cassandra, FoundationDB, …) implement IConversationStore and register it instead of calling AddInfrastructure's default. The contract is three methods: LoadAsync, AppendAsync, ClearAsync.


Deploy

Local — docker-compose

export OPENAI_API_KEY=sk-...
export API_KEY=$(openssl rand -hex 16)
docker compose up --build

Wires agent → redis → qdrant → aspire-dashboard with persistent volumes for SQLite and Qdrant.

Service URL
Agent API http://localhost:8080
Scalar API Explorer (GitHub-themed, dark/light auto) http://localhost:8080/scalar
Aspire Dashboard (traces, metrics, logs) http://localhost:18888
Qdrant UI http://localhost:6333/dashboard

The bundled Aspire Dashboard is OTLP-native and shows resources, console output, structured logs, distributed traces (agent.run, LLM calls, tool calls), and per-token metrics — zero config. Swap to Grafana / Application Insights / Honeycomb for production by pointing COMPLETEAGENT_Telemetry__OtlpEndpoint at their gateway.

Kubernetes

docker build -t ghcr.io/<your-org>/completeagent:1.0.0 .
docker push ghcr.io/<your-org>/completeagent:1.0.0

# Edit deploy/k8s/secret.example.yaml with real values (or use External Secrets / Key Vault CSI).
kubectl apply -k deploy/k8s

Bundled manifests: namespace, configmap, secret.example, deployment (non-root, read-only FS, dropped capabilities, 3 probes), service, hpa (2–10 replicas on CPU+memory), networkpolicy (DNS, HTTPS, internal services only), kustomization.


Develop the template

# Pack
dotnet pack -c Release -o ./artifacts

# Install from local nupkg
dotnet new install ./artifacts/EncryptedTouhid.AgentFramework.Templates.0.1.0.nupkg

# Generate a sample and smoke-test
dotnet new et-complete-agent -n Demo -o /tmp/Demo
(cd /tmp/Demo && dotnet build && dotnet test)

# Uninstall when iterating
dotnet new uninstall EncryptedTouhid.AgentFramework.Templates

CI runs the same pack → install → generate → build → test flow on every push (.github/workflows/ci.yml).


Versions

Version
.NET SDK 10.0.x (via global.json, rollForward: latestMajor)
Microsoft.Agents.AI 1.6.2
Microsoft.Extensions.AI 10.6.0
Azure.AI.OpenAI 2.1.0
OpenTelemetry 1.15.x
EntityFrameworkCore.Sqlite 10.0.8
Qdrant.Client 1.18.1

Roadmap / not yet included

  • WebApplicationFactory-based integration tests
  • Conversation summarisation when history exceeds context budget
  • Embedding cache
  • Idempotency keys, circuit breaker
  • Document chunker / ingestion pipeline
  • Citations from RAG, hallucination scoring
  • MCP server tools, multi-step planner
  • Multimodal (image / audio)

See Roadmap discussion in repo issues to vote or contribute.


License

MIT — see LICENSE.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.1 103 5/22/2026
0.4.0 106 5/22/2026
0.3.0 103 5/22/2026
0.2.0 102 5/22/2026