Header menu logo Nao

Nao — F# Agent Framework

Nao is an F# framework for building, orchestrating, and evaluating LLM-powered agents with production-grade governance, observability, and verification.

Projects

Project

Description

Nao.Core

Core domain types — messages, roles, content metadata, LLM provider interface

Nao.Agents

Agent framework — ETCLOVG harness, tools (verify/revert), execution journal, orchestration

Nao.Providers

LLM provider implementations (Ollama, OpenAI, Anthropic, vLLM, llama.cpp)

Nao.Loader

Workspace loader — JSON definitions, multi-mode execution (Process/HTTP/Custom), plugins

Nao.Eval

Agent evaluation framework — test cases, evaluators, LLM judge, regression

Nao.Runtime.Orleans

Distributed runtime — multi-workspace registry, group directory, session grains

Nao.Assistant

Avalonia.FuncUI desktop chat app — embedded ASP.NET Core + Orleans host, live execution-trace streaming, dark/light themes, localizable UI

Architecture

The framework implements the ETCLOVG seven-layer taxonomy for structured agent execution:

┌─────────────────────────────────────────────────────────────────────┐
│                     Nao.Runtime.Orleans                               │
│  WorkspaceRegistry · SessionGrain · GroupDirectoryGrain · Persistence  │
├─────────────────────────────────────────────────────────────────────┤
│                        Nao.Loader                                    │
│  JSON Definitions · Multi-mode Execution · Assembly Plugins            │
├─────────────────────────────────────────────────────────────────────┤
│                        Nao.Eval                                      │
│  EvalCase · IEvaluator · LlmJudge · EvalReport · Regression         │
├─────────────────────────────────────────────────────────────────────┤
│                        Nao.Agents (ETCLOVG)                          │
│ ┌───────┐ ┌──────┐ ┌─────────┐ ┌───────────┐ ┌─────────┐ ┌──────┐ │
│ │E:Exec │ │T:Tool│ │C:Context│ │L:Lifecycle│ │O:Observe│ │V:Veri│ │
│ │Sandbox│ │Proto │ │Memory   │ │Pipeline   │ │Trace    │ │Regres│ │
│ │Limits │ │Schema│ │Compact  │ │Hooks      │ │Metrics  │ │Judge │ │
│ └───────┘ └──────┘ └─────────┘ └───────────┘ └─────────┘ └──────┘ │
│ ┌────────────────────────────────────────────────────────────────┐  │
│ │G: Permission · ResourceAccess · Constitution · Audit · Policy  │  │
│ └────────────────────────────────────────────────────────────────┘  │
│ ┌────────────────────────────────────────────────────────────────┐  │
│ │               EtclovgHarness (integrates all layers)           │  │
│ └────────────────────────────────────────────────────────────────┘  │
├─────────────────────────────────────────────────────────────────────┤
│                        Nao.Core                                      │
│  Message · Role · ContentMeta · CompletionOptions · ILlmProvider      │
└─────────────────────────────────────────────────────────────────────┘

ETCLOVG Layers

E — Execution Environment

Resource-bounded sandboxed agent execution. Enforces time limits, LLM call budgets, token caps, and cost ceilings.

T — Tool Interface & Protocol

MCP-inspired structured tool discovery and invocation with middleware:

C — Context & Memory

Tiered memory management and context compaction:

L — Lifecycle & Orchestration

Agent lifecycle state machine and multi-stage pipelines:

Custom Orchestrators

The orchestrator's behavior can be customized by subclassing OrchestratorBase and overriding virtual members:

Virtual Member

Purpose

BuildSystemPrompt()

Generate the system prompt sent to the LLM

TryParseAction(content)

Parse LLM output into AgentAction (tool call, delegation, or final answer)

OnToolResult(name, input, result)

Post-processing hook after a tool executes

OnRoundComplete(round, content)

Hook called after each reasoning round

This pattern exists because function-valued behavior (like custom action parsers) cannot be expressed in JSON workspace definitions. Users subclass OrchestratorBase and register an IOrchestratorFactory via DI to have the runtime use their custom orchestrator.

O — Observability & Operations

Distributed tracing, cost metrics, and resilience:

V — Verification & Evaluation

Pre-flight readiness, execution traces, quality judgement, and regression detection:

G — Governance & Security

Permissions, constitutional rules, audit logging, and runtime policy enforcement:

Resource Permissions

The resource-permission system is the resource-level companion to the capability-level PermissionModel:

Key Concepts

Agents are Stateless

The runtime (Orleans grains) owns all state — conversation history, memory entries, and session metadata. Agents are created fresh per request:

  1. Grain loads persisted conversation from storage
  2. Grain creates a fresh agent instance via DefinitionBuilder
  3. Agent processes the input and returns a response
  4. Grain persists the updated conversation; agent is discarded

Workspace Definitions

Agents, tools, eval suites, and governance configs can be defined as JSON in the .nao/ directory:

.nao/
├── agents/        ← Agent definitions (prompt, model, tools, sub-agents)
├── tools/         ← Tool definitions (process, HTTP, or custom executors)
├── evals/         ← Evaluation suite definitions
└── governance/    ← Constitution rules, permissions

Or discovered from .NET assemblies in the plugins/ directory.

Tools support three execution strategies via ToolExecutionDef:

Mode

JSON field

Use case

Process

command + args

Run any executable (bash, python, node, .exe)

HTTP

url + method + headers

Call REST APIs, webhooks

Custom

executor + config

Use registered IToolExecutor (gRPC, MCP, etc.)

Tools can also declare verify_command/revert_command for correctness checks and rollback.

Multi-Workspace Runtime

Multiple isolated workspaces can coexist within a single Orleans silo:

Group Directory

Organizational multi-tenancy for teams and enterprises:

Orchestration

The Orchestrator processes multi-turn interactions by: - Parsing LLM responses into typed AgentAction values - Executing tool calls and feeding results back - Delegating to sub-agents when appropriate - Enforcing round limits to prevent infinite loops

The EtclovgHarness wraps orchestration with all seven layers for production use.

Getting Started

# Restore tools
dotnet tool restore

# Build
dotnet build

# Run tests
dotnet test

# Generate documentation
dotnet fsdocs build --output docs/output

API Reference

API documentation is auto-generated from XML doc comments in the source code using FSharp.Formatting.

Type something to start searching.