A comprehensive runtime for building intelligent agent applications with session persistence, observability, and provider abstraction built on .NET 10.
dotnet tool install -g hermesnetThen use:
hermesnet chat "solve 2+2"
hermesnet profile list
hermesnet session create my-sessiondotnet tool update -g hermesnet-
src/Hermes.Core/— Core runtime library- Session management and persistence
- Chat service abstractions
- Provider interface definitions
- Telemetry and observability
- Skill parsing and validation
-
src/Hermes.Host/— Application host and dependency injection- Service registration and configuration
- Provider factory implementation (IChatClient)
- Application startup and lifecycle management
- Settings management (appsettings.json)
-
src/Hermes.Cli/— Command-line interface- System.CommandLine-based CLI
- Chat command entry point
- Session management commands
- .NET 10.0 or later
- Visual Studio 2025 or VS Code with C# DevKit (recommended)
- Ollama (optional, for local provider testing)
dotnet restoredotnet builddotnet build --configuration Releasedotnet testdotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover-
Directory.Build.props— Shared build settings- C# 13 language version
- Nullable reference types enabled
- Implicit usings enabled
- Warnings treated as errors for code quality
-
Directory.Packages.props— Centralized NuGet versioning- Single source of truth for all package versions
- Prevents version conflicts across projects
-
global.json— .NET SDK version constraint- Enforces .NET 10.0 or later
- Microsoft.Extensions.AI — IChatClient abstraction for provider integration
- Microsoft.Extensions.DependencyInjection — Service container
- Microsoft.Extensions.Configuration — Settings management
- Microsoft.EntityFrameworkCore — Data persistence (EF Core)
- System.CommandLine — CLI framework
- OpenTelemetry — Observability baseline
- xUnit — Testing framework
- Coverlet.Collector — Code coverage
- Microsoft.NET.Test.Sdk — Test runner
# Start Ollama locally (if using local provider)
ollama serve
# In another terminal, run the Hermes CLI
dotnet run --project src/Hermes.Cli -- chat "What is 2+2?"Configuration: The CLI uses appsettings.json in the Hermes.Cli project:
{
"Provider": "Ollama", // Switch to "OpenAI" for cloud provider
"Ollama": {
"BaseUrl": "http://localhost:11434",
"Model": "llama2"
}
}- Open
HermesNET.slnxin Visual Studio 2025 - Build Solution (Ctrl+Shift+B)
- All three projects compile without warnings
- Release Notes v2.0.0 — Production release, features, quality metrics
- Migration Guide (M1→M2) — Upgrade path for M1 users (or start here if new)
- Quick Start Guide — 5-minute setup
- User Guide — Core concepts (profiles, sessions, memory)
- CLI Reference — Complete command reference
- Skill Authoring — Write custom skills
- API Reference — REST API endpoints
- Troubleshooting — Common issues and solutions
- Architecture Decisions — See
.squad/decisions.md - Testing & Quality Gates — See
docs/testing/ - Benchmarks — See
docs/benchmarks/ - M1 Baseline — See
M1-BASELINE.txt(OTel baseline measurements)
Hermes uses OpenTelemetry for distributed tracing and observability from Day 1. This enables early detection of performance regressions and overhead measurements.
The instrumentation strategy centers around three span types:
-
Turn Span (
hermes.chat.turn) — Root span wrapping the entire user request- Tags:
turn.id,message.length,response.length - Measures: End-to-end latency (user input → response returned)
- Tags:
-
Provider Call Span (
hermes.provider.call) — Child span for ChatClient calls- Tags:
provider.name,provider.latency_ms - Measures: Provider-specific latency (isolated from CLI overhead)
- Tags:
-
Session Persist Span (
hermes.session.persist) — Async background span- Tags:
session.id - Note: Not included in turn latency measurement (async, background operation)
- Tags:
Instrumentation is accessed via Hermes.Core.Telemetry.TelemetryProvider:
using Hermes.Core.Telemetry;
// Start a turn span
using (var turn = TelemetryProvider.StartTurnSpan(turnId))
{
TelemetryProvider.SetMessageLength(turn, message.Length);
// Start a provider call span
using (var provider = TelemetryProvider.StartProviderCallSpan("Ollama"))
{
var response = await chatClient.CompleteAsync(messages);
TelemetryProvider.SetProviderLatency(provider, elapsedMs);
}
TelemetryProvider.SetResponseLength(turn, response.Length);
}OpenTelemetry is initialized in Hermes.Cli/Program.cs:
var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("Hermes.Core")
.AddConsoleExporter() // M1: console logging for development
.Build();For production, replace AddConsoleExporter() with appropriate exporters (OTLP, Jaeger, etc.).
The M1 baseline establishes a performance reference point with OTel fully enabled:
- P95 Turn Latency: 55ms (local Ollama, console exporter active)
- Target: < 100ms with OTel ON
- Results: Committed to
M1-BASELINE.txt
This baseline is the reference point for M2's "no >20% OTel overhead" regression gate.
HermesNET is available as a global .NET tool:
dotnet tool install -g hermesnet
hermes profile create myprofile
hermes chat --profile myprofile --message "Hello!"Get started: See Quick Start Guide or the Full CLI User Guide
- All code must build with zero warnings (
TreatWarningsAsErrors=true) - Use C# 13 features freely (latest language version)
- Maintain nullable reference type safety
- Cover critical paths with xUnit tests
See LICENSE file in repository root.