AiDotNet.Evolution 0.1.0

dotnet add package AiDotNet.Evolution --version 0.1.0
                    
NuGet\Install-Package AiDotNet.Evolution -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AiDotNet.Evolution" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AiDotNet.Evolution" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="AiDotNet.Evolution" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AiDotNet.Evolution --version 0.1.0
                    
#r "nuget: AiDotNet.Evolution, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AiDotNet.Evolution@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AiDotNet.Evolution&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=AiDotNet.Evolution&version=0.1.0
                    
Install as a Cake Tool

<h1 align="center">AiDotNet.Evolution</h1>

<p align="center"> <strong>Evolutionary search for .NET that keeps the receipts — deterministic, budgeted, and resumable.</strong> </p>

<p align="center"> <a href="https://www.nuget.org/packages/AiDotNet.Evolution"><img src="https://img.shields.io/nuget/vpre/AiDotNet.Evolution?logo=nuget" alt="NuGet"></a> <a href="https://github.com/ooples/AiDotNet.Evolution/actions/workflows/build.yml"><img src="https://github.com/ooples/AiDotNet.Evolution/actions/workflows/build.yml/badge.svg?branch=main" alt="Build and Test"></a> <a href="./LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" alt="Apache 2.0"></a> <img src="https://img.shields.io/badge/.NET-10%20%7C%208%20%7C%20Framework%204.7.1-512BD4?logo=dotnet&logoColor=white" alt=".NET 10, .NET 8, .NET Framework 4.7.1"> </p>

<p align="center"> <img src="https://img.shields.io/badge/deps-none%20on%20.NET%208%20%2F%2010-2ea043" alt="No third-party dependencies on .NET 8 and .NET 10"> <img src="https://img.shields.io/badge/LLM-optional-8b5cf6" alt="LLM optional"> <img src="https://img.shields.io/badge/replay-byte--identical-3b82f6" alt="Deterministic replay"> <img src="https://img.shields.io/badge/telemetry-none-2ea043" alt="No telemetry"> <img src="https://img.shields.io/badge/12-runnable%20examples-0d9488" alt="12 runnable examples"> </p>


You have something you can score — a model config, a GPU kernel, a compiler schedule, a prompt, a piece of generated code — and too many possible versions of it to try by hand. This searches that space for you, in .NET.

It is a quality-diversity engine, so it returns a map of the best candidate of each kind rather than a thousand variations of one local optimum. It is a library: no service, no account, no telemetry.

Quick start

dotnet add package AiDotNet.Evolution --prerelease
using AiDotNet.Evolution;

// 1. Describe the space you want to search.
EvolutionSearchSpace space = new EvolutionSearchSpaceBuilder()
    .Add(EvolutionParameter.Integer("depth", 1, 20))
    .Add(EvolutionParameter.Logarithmic("rate", 0.0001, 1.0))
    .Build();

// 2. Say how good a candidate is. Anything you can score works here.
var task = new EvolutionSearchTask(space, "quickstart", "v1", "score-v1", (genome, _, _) =>
    new ValueTask<EvolutionTaskResult>(EvolutionTaskResult.Completed(
        quality: -Math.Abs(genome.Number("depth") - 7) - Math.Abs(Math.Log10(genome.Number("rate") / 0.01)),
        descriptors: new Dictionary<string, double> { ["depth"] = genome.Number("depth") },
        costUnits: 1)));

// 3. Run the search.
var engine = new EvolutionEngine<EvolutionSearchGenome>(
    task,
    EvolutionSearchPresets.CreateAdaptiveMixed(space),
    _ => new MapElitesArchive<EvolutionSearchGenome>(new[] { new EvolutionDescriptorDefinition("depth", 1, 21, 10) }),
    new EvolutionEngineOptions { RunId = "quickstart", Seed = 42, MaxEvaluationAttempts = 200 });

EvolutionRunResult<EvolutionSearchGenome> result = await engine.RunAsync(
    new[] { space.Sample(StableRandom.CreateStream(42, 0)) });

Console.WriteLine($"best quality : {result.Best!.Evaluation.Quality:F4}");
Console.WriteLine($"depth        : {result.Best.Candidate.CanonicalGenome.Genome.Number("depth")}");
best quality : -0.0111
depth        : 7

Three objects: a space, a task that scores a candidate, and an engine. Everything below is optional.

The three ids on EvolutionSearchTask — task id, task version, evaluator version — are how the engine refuses a checkpoint or a cached score produced by a different scoring function. Change how you score, bump the evaluator version, and stale results stop being reused.

What it gives you

  • Deterministic runs. Same seed, same result, and every run emits a StateHash you can compare. One example runs a search across three processes, kills them mid-flight, and asserts the resumed report is byte-identical to the uninterrupted one.
  • Budgets you cannot overrun. Every evaluation is admitted against a resource ledger before it runs and charged after. A worker that dies holding a reservation leaves a retained liability, not a silent refund.
  • Real checkpoint/resume. Archives, operator learning, island topology, random streams and the ledger restore together; an incompatible checkpoint is refused rather than reinterpreted.
  • LLMs optional. The engine knows nothing about models or prompts. Supply model-driven mutation through a typed contract and it is metered like any other operator, or leave it out and pay nothing per evaluation.
  • Runs where you already are. .NET 10, .NET 8, and .NET Framework 4.7.1, with no third-party dependencies on .NET 8 and 10. Only 4.7.1 pulls one in, System.Text.Json, because it is not in-box there.
  • Evaluation can leave the process. Hand work to external workers over a durable coordinator that persists work, leases and receipts together, and survives a crash on either side. TypeScript, Python and C ABI bindings ship with it.

What people search with it

You want to tune Your genome is Your score is
Model hyperparameters depth, learning rate, family held-out metric
A GPU kernel or compiler schedule tile sizes, unroll factors, fusion measured runtime
Generated code or programs the program itself tests passed, then speed
A prompt or agent policy template and parameter choices task success rate
Feature subsets which columns are in cross-validated score
Deployment configs replicas, batch size, cache sizes cost under an SLA

The engine knows nothing about any of these. You implement IEvolutionTask<TGenome> and it stays out of your domain.

Twelve examples you can run

dotnet run --project examples/TypedParameterSearch -c Release
Example What it shows
TypedParameterSearch Mixed integer/real/categorical space with conditional parameters
ParetoSearch Competing objectives, keeping the tradeoff front instead of one winner
AdaptiveIslandSearch Parallel islands, migration, restarting stalled populations
SurrogateSearch A cheap learned model ranks candidates before you pay for real evaluation
MultiFidelitySearch Cheap-first screening with successive halving and promotion
ReplicatedEvaluation Noisy scores, repeated sampling, confirmation before believing a win
PersistentEvaluation Reusing earlier evaluations across runs, with freshness and force-fresh
OperatorCreditSearch Learning which mutation strategies earn their cost
ProposalPipeline Overlapping proposal generation with evaluation, bounded in flight
CompilerGuidedSearch Using compiler feedback to steer program improvement
DurableWork External workers, crash recovery, and exactly-once receipts
DurableSession A live engine session driven across a durable host process

Measured, not asserted

Results that were not measured are labeled as not measured. The repository ships retained evidence — including failed and discarded campaigns — each with an offline verifier you can run without trusting us.

Evidence Scale
Pareto search 180 matched-budget runs, reproduced from the recorded state hashes in CI
Proposal pipeline 576 live executions and 576 offline replays; 13,824 proposal calls, 18,432 evaluations
Surrogate ranking 240 runs, 27,248 pilot calls
Adaptive islands 62,720 local objective calls
Engine performance Isolated per-core measurement, with the failed campaigns retained

The external harness runs SciPy differential evolution and upstream pyribs CMA-ME against the same C# evaluator — no Python reimplementation of the objective to tilt the result. See the comparison contract and run it yourself.

main enforces a coverage ratchet (≥89.8% line, ≥74.51% branch), builds all three target frameworks, and runs 1,400+ tests with zero skips. A pull request that skips a test fails the build rather than reporting green.

Going further

Capability Doc
Mixed, conditional and log-scaled spaces Typed search spaces
Competing objectives Pareto search
Budgets and liabilities Resource accounting
Noisy scores and confirmation Replicated evaluation
Cheap screening first Screening · Multi-fidelity
Learned candidate ranking Surrogate selection
Which operators earn their keep Operator credit · Portfolios
Parallel islands and restarts Adaptive islands
Overlapping proposal and evaluation Proposal pipeline
Reusing past evaluations safely Persistent reuse · Warm starts
Where a measurement came from Measurement origin
High-dimensional archives Centroid archives
Work that runs outside the process Durable external work · Worker protocol · Work identity

Contracts you implement

IEvolutionTask<TGenome> (identity, validation, evaluation) · IVariationOperator<TGenome> (proposes immutable genomes) · IEvolutionArchive<TGenome> (what to keep; MapElitesArchive<TGenome> ships) · IEvolutionGenomeCodec<TGenome> (checkpointing without imposing a serializer) · ISelectionPolicy<TGenome>, ICandidateRefiner<TGenome>, IMigrationPolicy<TGenome>.

Reference-typed genomes implement IImmutableEvolutionGenome<TGenome> and return an independently owned copy from CreateOwnedSnapshot. The engine takes that snapshot once at canonicalization, so archives, migration and selection never clone on their hot paths.

AiDotNet.Evolution.Programs and AiDotNet.Evolution.CSharp add standalone program contracts, process execution, script metrics, model judging and novelty screening. The core package depends on neither AiDotNet nor AiDotNet.Tensors.

Contributing

See CONTRIBUTING.md for local validation, and repository setup for CI, security and release configuration.

License

Apache License 2.0. This is an independent .NET implementation with its own engine, orchestration, persistence and integration contracts; no OpenEvolve runtime code is copied or ported. OpenEvolve was reviewed as prior art during design, and THIRD-PARTY-NOTICES.md records that review under its Apache-2.0 terms.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Framework net471 is compatible.  net472 was computed.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.7.1

  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on AiDotNet.Evolution:

Package Downloads
AiDotNet.Evolution.Surrogates

Optional bounded numeric surrogate adapters with explicit reliability diagnostics for AiDotNet.Evolution.

AiDotNet.Evolution.Programs

Compiler-neutral bounded program improvement and artifact-bound promotion.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 72 9/19/2026
0.1.0-preview.2 63 9/11/2026
0.1.0-preview.1 1,216 9/9/2026