C# · .NET 10 · In-process library
Token Economy API
Calculate a run’s cost, compare model and reasoning choices, and decide whether a task can start.
The core APIs are deterministic. Your application supplies usage, task evidence, and provider capacity; it also runs the selected CLI. No API key, HTTP service, or model call is required to use the library.
This guide describes the current library source. Package releases · Complete C# example
Start with a cost calculation
Add the package to a .NET 10 project.
dotnet add package TokenEconomy
This complete example uses a fixed execution time so its result can be reproduced.
using TokenEconomy;
var atUtc = new DateTime(2026, 9, 12, 0, 0, 0, DateTimeKind.Utc);
CostBreakdown cost = ModelPriceCatalog.Default.ComputeCost(
KnownModels.ClaudeSonnet5,
new TokenUsage(Input: 100_000, Output: 10_000,
CacheRead: 20_000, CacheWrite: 5_000),
atUtc);
if (!cost.HasPrice)
{
Console.WriteLine($"Cost unavailable: {cost.Status}");
return;
}
Console.WriteLine($"Input: {cost.InputCost:F5}");
Console.WriteLine($"Output: {cost.OutputCost:F5}");
Console.WriteLine($"Cache read: {cost.CacheReadCost:F5}");
Console.WriteLine($"Cache write: {cost.CacheWriteCost:F5}");
Console.WriteLine($"Total: {cost.Total:F5} {cost.Currency}");
Input: 0.20000
Output: 0.10000
Cache read: 0.00400
Cache write: 0.01250
Total: 0.31650 USDThis is a dated list-price estimate. Retain cost.Caveat when showing the amount. For included subscription usage, label it API-equivalent consumption; it does not represent an additional charge or a quota percentage. Billing contexts and comparison method
Choose the API for your task
| You need to… | Call | You receive |
|---|---|---|
| Price measured tokens | ComputeCost | CostBreakdown |
| Find the rate at a past time | ResolvePrice | PriceResolution |
| Inspect one named model | EvaluateModel | ModelSuggestion? |
| Compare compatible core models | SuggestModel | Ranked ModelSuggestion list |
| Build a capability table | Describe | ModelEfficiencyRow list |
| Estimate task scope and consumption | TaskComplexityEstimator.Estimate | TaskComplexityEstimate |
| Decide whether an attempt can run | ModelRouter.Route | ModelRoutingResult |
| Suggest routes when creating a task | Recommend / Select | Task-class advice / quota selection |
| Measure spend per accepted result | ComputeObserved | Outcome metrics and coverage |
Calculate token costs
CostBreakdown ModelPriceCatalog.ComputeCost(
ModelId model, TokenUsage usage, DateTime atUtc)
Pass a model ID, measured token counts, and the run’s UTC timestamp. A string? overload accepts model IDs or catalog aliases. Use KnownModels for typed built-in IDs and ModelId.Of(value) for your own.
Token components must not overlap
| TokenUsage field | What to pass |
|---|---|
Input | Fresh input tokens, excluding cache reads and cache writes. |
Output | Billed output tokens, including reasoning tokens when the provider counts them as output. |
CacheRead | Input tokens read from cache; defaults to 0. |
CacheWrite | Input tokens written to cache; defaults to 0. |
Each component costs tokens × rate / 1,000,000. A missing cache rate uses the input rate. Non-positive counts currently contribute zero; validate usage at your application boundary if negative values indicate invalid telemetry.
Read CostBreakdown
| Field | Meaning |
|---|---|
Status, HasPrice | Whether a rate was found. Check this before using the component costs. |
InputCost, OutputCost, CacheReadCost, CacheWriteCost | Decimal amounts for the four token components. |
Total, Currency | The summed amount and currency. Total is nullable. |
ModelId, Price | Canonical ID and the exact dated price entry used. |
Unconfirmed | The catalog rate is provisional. |
Caveat, IsEstimatedListPrice | Identifies the result as a published-list-price estimate. |
Missing prices are explicit
Resolved: a price applies;HasPriceis true.UnknownModel: no catalog listing matches the ID.NoPriceForDate: the model is known, but no price period covers the timestamp.
For the last two states, Total is null. The zero-valued component fields do not mean that the run was free. UsageUnavailable also exists in the shared status enum for consumers with no measurement; ComputeCost itself takes a usage value.
For input/output-only telemetry, catalog.Cost(model, tokensIn, tokensOut, executedAt) is a convenience wrapper.
Look up prices and history
ModelListing? Find(ModelId model)
PriceResolution ResolvePrice(ModelId model, DateTime atUtc)
IReadOnlyList<ModelPrice> PriceDevelopment(ModelId model)
Call these methods on ModelPriceCatalog.Default or a custom catalog. String overloads also exist. Lookup trims whitespace, ignores case, and treats dots and dashes alike.
using TokenEconomy;
var catalog = ModelPriceCatalog.Default;
var atUtc = new DateTime(2026, 9, 12, 0, 0, 0, DateTimeKind.Utc);
PriceResolution result = catalog.ResolvePrice(KnownModels.ClaudeSonnet5, atUtc);
if (result.Price is { } price)
Console.WriteLine($"{price.InputPerMTok:F2} / {price.OutputPerMTok:F2} {price.Currency} per MTok");
else
Console.WriteLine(result.Status);
// 2.00 / 10.00 USD per MTok
PriceResolution contains Status, ModelId, nullable Price, and Found. Find returns null for an unknown model; PriceDevelopment returns an empty list.
ModelPrice also exposes SourceUrls, VerifiedOn, and ValidFromBasis. These distinguish a verified rate from the evidence for its historical start date. Browse all model prices and histories.
A price applies from ValidFrom through its optional ValidTo, including both endpoints. Pass UTC values. The catalog retains historical periods and rejects overlaps when constructed.
Evaluate one model and its reasoning level
ModelSuggestion? ModelEfficiencyMatrix.EvaluateModel(
ModelId model, TaskClass taskClass, BudgetPressure budgetPressure,
DateTime atUtc, EffortLevel? desiredEffort = null)
This call returns an object describing a named model’s compatibility with a task. The reasoning level is in SuggestedEffort.
using TokenEconomy;
ModelSuggestion? sonnet = ModelEfficiencyMatrix.Default.EvaluateModel(
KnownModels.ClaudeSonnet5,
TaskClass.Feature,
BudgetPressure.Tight,
new DateTime(2026, 9, 12, 0, 0, 0, DateTimeKind.Utc));
if (sonnet is null)
{
Console.WriteLine("No evaluation is available for this model and task.");
return;
}
Console.WriteLine($"Model: {sonnet.ModelId}");
Console.WriteLine($"Reasoning: {sonnet.SuggestedEffort}");
Console.WriteLine($"Compatibility score: {sonnet.Score}");
Console.WriteLine($"Evidence: {sonnet.EvidenceStatus}");
Console.WriteLine(sonnet.Rationale);
Model: claude-sonnet-5
Reasoning: Medium
Compatibility score: 60
Evidence: ProvisionalWhy Medium? Why 60?
Feature defaults to Medium. Tight increases the weight of cost in ranking; it keeps this reasoning level. Critical lowers the desired effort by one step before it is fitted to the model’s supported levels.
Here, Capable contributes 60 points and Standard cost contributes 0: 60 + 0 = 60. The score combines task suitability and the dated cost class under the selected budget pressure. It is an ordinal ranking value: larger ranks ahead. It is neither a benchmark result nor a probability of success. The Rationale explains the factors; the policy source defines their weights.
You can request desiredEffort: EffortLevel.High. The result uses a supported level at or below the request, with the model’s minimum as a floor. Read the returned value instead of assuming the request was accepted unchanged.
All ModelSuggestion fields
| Field | Meaning |
|---|---|
ModelId, Cli | Canonical model ID and its associated CLI. |
SuggestedEffort | Reasoning effort after fitting the request to supported levels. |
Tier, Suitability | Maintained capability band and fit for the task class. |
CostClass, CostUnconfirmed | Dated price band and whether the applied price is provisional. |
Score, Rationale | Compatibility rank and its explanation. |
EvidenceStatus, Provisional | Evidence supporting the policy entry and whether it still needs validation. |
ReviewQuality | Review-specific evidence when available; otherwise null. |
null means that the model/task combination cannot be evaluated: for example, the model is unknown, unsupported, restricted, deprecated, has no mapped CLI, or has no task suitability. Missing price alone produces CostClass.Unknown. This method does not check provider quota or CLI availability.
Rank compatible core models
IReadOnlyList<ModelSuggestion> ModelEfficiencyMatrix.SuggestModel(
TaskClass taskClass, BudgetPressure budgetPressure,
IEnumerable<Cli>? availableClis, DateTime atUtc)
Supply the CLIs your host can use. The result contains candidates in descending compatibility order, with the same fields as EvaluateModel.
using TokenEconomy;
var ranked = ModelEfficiencyMatrix.Default.SuggestModel(
TaskClass.Feature, BudgetPressure.Tight,
availableClis: [Cli.Codex],
atUtc: new DateTime(2026, 9, 12, 0, 0, 0, DateTimeKind.Utc));
if (ranked.Count == 0)
{
Console.WriteLine("Wait: no eligible model is available.");
return;
}
ModelSuggestion best = ranked[0];
Console.WriteLine($"{best.ModelId} / {best.SuggestedEffort}");
Console.WriteLine(best.Rationale);
With the current catalog, this example ranks gpt-5.6-terra / Medium first. Results change with the task, budget pressure, available CLIs, and catalog version.
Unknown CLI mappings, restricted, deprecated, unsupported, fallback-only, and non-core-workflow profiles are excluded. An empty or null CLI set returns an empty list. No provider is probed.
The score is a coarse compatibility comparison. Task-class advice also retains study evidence; attempt routing enforces the concrete task’s correctness floors.
Inspect capability, effort, and status
IReadOnlyList<ModelEfficiencyRow> ModelEfficiencyMatrix.Describe(DateTime atUtc)
Each row contains ModelId, Vendor, nullable Cli, Tier, CostClass, EffortLevels, per-task Suitability, and policy/evidence flags. Restricted and deprecated entries remain visible for inspection.
EffortLevels lists supported values. SuggestedEffort belongs to a task-specific evaluation; a model does not have one universal recommended effort. Use ResolvePrice alongside Describe to add concrete token rates.
Selection status in one line
- ✓ Selectable
- Allowed for its declared workflow roles.
- ↪ Fallback only
- Allowed through an explicitly qualified fallback.
- ⊘ Unsupported
- No permitted route in the current policy.
- ⏸ Restricted
- Blocked by policy.
- − Deprecated
- Retained for history; excluded from new selections.
Why selectable and provisional?
Selectable is permission. Provisional is evidence maturity. A model can be allowed while its task or reasoning-level claims still need validation. Price confirmation is a separate flag.
To substantiate a route, retain versioned runs for the exact model, reasoning level, and task class; meet the relevant benchmark’s acceptance gate; and review uncertainty and trust evidence. Updating one model’s benchmark does not validate every task or effort level.
The matrix links each model to its available scores and evidence gaps. Public benchmark scores and local task studies keep their original scales and test conditions.
Read the evidence behind a model score
BenchmarkEvidenceCatalog.Default exposes the embedded benchmark definitions and sourced measurements. ResultsFor(typeId) returns a list of BenchmarkResult; filter by model, effort and availability date. This example reads Opus 5 / Max from the official Terminal-Bench 4.0 leaderboard. It makes no provider call.
using System.Text.Json;
using TokenEconomy;
var catalog = BenchmarkEvidenceCatalog.Default;
var asOf = new DateOnly(2026, 9, 12);
var result = catalog.ResultsFor("terminal-bench-v4.0-official-native-agents")
.Where(r => r.ModelId == KnownModels.ClaudeOpus5
&& r.ReasoningEffort == EffortLevel.Max && r.PublishedAt <= asOf)
.OrderByDescending(r => r.PublishedAt)
.FirstOrDefault();
if (result is null)
{
Console.WriteLine("No matching benchmark evidence at this date.");
return;
}
var type = catalog.FindType(result.BenchmarkTypeId)!;
Console.WriteLine(JsonSerializer.Serialize(new
{
Model = result.ModelId.Value,
Effort = result.ReasoningEffort.ToString(),
Benchmark = type.Name,
type.Version,
result.Score,
type.Unit,
Scale = new { type.MinimumScore, type.MaximumScore,
Direction = type.Direction.ToString() },
EvidenceKind = result.Confidence.ToString(),
result.PublishedAt,
result.RetrievedAt,
result.SourceUrl,
type.MethodologyUrl,
result.EvidenceExcerpt,
result.Context // Harness, sample, uncertainty, date basis and extra sources.
}, new JsonSerializerOptions { WriteIndented = true }));
The result is 51.82% resolved on the original 0–100 scale, using Claude Code: 66 tasks, 330 trials, with a reported 95% confidence interval of ±3.39 percentage points. These are benchmark measurements, separate from the router’s policy score. Compare the published evidence →
| Read | Interpretation |
|---|---|
Score + BenchmarkType.Unit, range and direction | The original metric. Do not average incompatible benchmark scales or treat it as a universal quality percentage. |
Context.Harness, TaskCount, TrialCount, AttemptsPerTask | Which agent ran and what was sampled. Here, balanced attempts per task were not independently checked; the field stays null. |
ConfidenceIntervalHalfWidth, ConfidenceIntervalLevel, ReportedErrorHalfWidth | Retain the publisher’s uncertainty and scale. An error bar without a stated confidence level is not automatically a 95% interval. BenchmarkResult.Confidence identifies evidence provenance, such as ThirdParty; it is not a statistical confidence level. |
PublishedAt, RetrievedAt, Context.DateBasis, ObservedAt | Here, PublishedAt is the first observed public snapshot on September 12. Source creation/update timestamps are separate and do not establish the run date. |
SourceUrl, MethodologyUrl, AdditionalSourceUrls, SampleNotes | Keep the original source and its qualifications beside the number. Null context fields mean unknown; a legacy result may have no Context at all. |
ResultsFor returns an empty list for an unknown benchmark type; FindType returns null for an unknown type ID. The null-forgiving lookup above is safe after selecting a result from the validated catalog.
Read published code-review measurements
Filter BenchmarkEvidenceCatalog.Types by BenchmarkCapabilityClass.CodeReview, then read each type’s original results. This complete example selects Fable 5.1 and retains separate precision, known-issue coverage and configuration records. It makes no model call.
using System.Text.Json;
using TokenEconomy;
var catalog = BenchmarkEvidenceCatalog.Default;
var model = KnownModels.ClaudeFable51;
var asOf = new DateOnly(2026, 9, 12);
var found = false;
foreach (var type in catalog.Types
.Where(type => type.CapabilityClass == BenchmarkCapabilityClass.CodeReview)
.OrderBy(type => type.Id, StringComparer.Ordinal))
{
foreach (var result in catalog.ResultsFor(type.Id)
.Where(result => result.ModelId == model && result.PublishedAt <= asOf)
.OrderBy(result => result.PublishedAt))
{
found = true;
Console.WriteLine(JsonSerializer.Serialize(new
{
Model = result.ModelId.Value,
Effort = result.ReasoningEffort.ToString(),
Metric = type.Name,
BenchmarkTypeId = type.Id,
type.Version,
result.Score,
type.Unit,
OriginalScale = new { type.MinimumScore, type.MaximumScore,
Direction = type.Direction.ToString() },
type.CitationNote,
result.PublishedAt,
result.RetrievedAt,
result.SourceUrl,
type.MethodologyUrl,
result.EvidenceExcerpt,
result.Context
}, new JsonSerializerOptions { WriteIndented = true }));
}
}
if (!found) Console.WriteLine("No published review evidence for this model at this date.");
// Each object is one original metric and protocol. No blended quality score.
// Unspecified means the publisher did not identify the API reasoning effort.
Download the complete C# example →
Compare the same metric, protocol and output stream. Known-issue coverage uses the benchmark’s known defects as its denominator; it cannot establish recall over every possible defect. Comment precision describes the benchmark’s emitted-comment assessment. Raw, processed and actionable comments are different populations. Keep the source’s definitions and matching rules beside each number.
A publisher’s “Low” or “High” review profile is not automatically a provider reasoning level. Such records use EffortLevel.Unspecified unless the source identifies the API setting. Context retains the harness, sample notes, dates, uncertainty and sources. Missing sample size or uncertainty stays unknown. These measurements do not establish local maintainer acceptance, and a finding absent from a partial known-issue list is not automatically a false positive.
Read Quality Studio review-run evidence
The existing QualityStudioReviewRunImporter accepts Token Economy’s schema-v1 review-run drop: actual model/effort/CLI, review scope and optional confirmed/dismissed counts. The example reads JSON files from a directory, checks conflicting run identities, aggregates them and reads each model’s ReviewQuality. It writes no files.
using System.Text.Json;
using System.Text.Json.Serialization;
using TokenEconomy;
if (args.Length != 1)
throw new ArgumentException("Expected a directory of Token Economy schema-v1 review-run JSON files.");
var importer = new QualityStudioReviewRunImporter();
var runs = Directory.EnumerateFiles(args[0], "*.json", SearchOption.TopDirectoryOnly)
.Order(StringComparer.Ordinal)
.Select(path => importer.Import(path, $"quality-studio-drop/{Path.GetFileName(path)}"))
.ToArray();
foreach (var group in runs.GroupBy(run => run.SourceRunId, StringComparer.Ordinal))
if (group.Select(run => run.SourceArtifactSha256).Distinct().Skip(1).Any())
throw new InvalidDataException($"Conflicting content for review run {group.Key}.");
var report = new ReviewEvidenceAggregator().Aggregate(runs);
var knowledge = ModelRoutingKnowledgeBase.PolicyOnly.WithReviewEvidence(report);
var models = runs.Select(run => run.CanonicalModel).OfType<string>().Distinct();
var quality = models.Select(model => knowledge.ReviewQualityFor(model)).ToArray();
Console.WriteLine(JsonSerializer.Serialize(new
{
report.ImportedRunCount,
report.FixtureRunCount,
report.EligibleOperationalRunCount,
report.ConfidenceGates,
IneligibleRuns = runs.Where(run => !run.EligibleForAggregation)
.Select(run => new { run.SourceRunId, run.EligibilityIssues }),
ReviewQuality = quality
}, new JsonSerializerOptions
{
WriteIndented = true,
Converters = { new JsonStringEnumConverter() }
}));
// Read-only: no review launch, evidence write, task mutation or provider call.
// Native QS /review/runs/{id}/report JSON is a different contract; do not rename it.
// Unknown assessments stay null. Fixtures cannot supply operational evidence.
Download the complete C# example → Run it with dotnet run -- ./review-run-drop in a console project referencing TokenEconomy.
With the checked-in fixture, the result is 1 imported run, 1 fixture, 0 eligible operational runs. FindingOutcomeCoverage, FindingConfirmationRate and Suitability remain null; GateFailures explains the missing evidence. The default gates require 20 operational runs, 20 assessed findings and 70% assessment coverage. Passing them provides observational support, not controlled validation or review recall.
Download a complete C# reader for the native Quality Studio JSON report. It takes the host URL, repository ID and run ID, preserves the original report and counts exported finding entries. These counts do not assert unique, newly emitted or confirmed defects. Native fields and integration limits.
The native Quality Studio report endpoint is a different contract. Its report revision, operational finding state and requested route cannot be relabelled as this drop’s actual execution route and confirmed/dismissed outcomes. A producer must supply the documented facts. Later assessment changes must retain the original review-run identity; changing the ID to import a revised count would inflate the sample.
For retained history, ReviewEvidencePipeline.Run(repositoryRoot, dropDirectory, outputRoot) writes immutable normalized runs and a derived report. Identical reimports are no-ops; changed content for an existing run ID is rejected. Hosts can compose a valid report with ModelRoutingKnowledgeBase.PolicyOnly.WithReviewEvidence(report) and ModelEfficiencyMatrix.FromKnowledge(knowledge). The committed fixture-only evidence currently produces no review-model recommendation.
Decide whether an attempt can run
ModelRoutingResult ModelRouter.Route(ModelRoutingSelectionRequest request)
Use this as the admission decision before each attempt. It combines the upfront task estimate, routing policy, previous-attempt evidence, workflow role, optional operator pin, and supplied capacity.
| Input | Your host supplies |
|---|---|
Task | A ComplexityCard with the task’s prompt, acceptance criteria, scope, and risk signals. |
UpfrontEstimate | A matching TaskComplexityEstimate, normally from TaskComplexityEstimator.Estimate(task). |
AvailableClis | The set of CLIs available to the attempt. |
Capacity | Budget pressure, a run-scoped provider snapshot, and whether deterministic verification is available. |
This example uses snapshot supplied by the host. The complete example constructs a clearly labeled demo snapshot and prints the result.
ComplexityCard task = new()
{
TaskKey = "DEMO-1",
Prompt = "Add an optional display name to stored user preferences and migrate existing records.",
TaskType = "feature",
AcceptanceCriteria = ["Existing records retain their saved preferences.", "Migration tests pass."],
ReferencedSubsystems = ["preferences"],
HardFloorTriggers = [ComplexityHardFloorTrigger.PersistentStateMigration],
};
var estimate = new TaskComplexityEstimator().Estimate(task);
ModelRoutingResult result = ModelRouter.Default.Route(new ModelRoutingSelectionRequest
{
Task = task,
UpfrontEstimate = estimate,
AvailableClis = [Cli.Codex, Cli.Claude],
Capacity = new ModelRoutingCapacity
{
ProviderAvailability = snapshot,
BudgetPressure = BudgetPressure.Tight,
DeterministicVerificationAvailable = true,
},
});
if (result.Disposition == ModelRoutingDisposition.Selected
&& result.SelectedRoute is { } route)
Console.WriteLine($"{route.ModelId} / {route.ThinkingLevel} via {route.Cli}");
else
Console.WriteLine($"{result.Disposition}: {result.FallbackOrWaitReason}");
gpt-5.6-sol / medium via CodexThis task scores 45; its broadContract correctness floor raises the required route. A cheaper compatibility candidate cannot lower that floor. SelectedRoute.ThinkingLevel is the reasoning level to use for the admitted attempt.
Handle all three outcomes
| Disposition | SelectedRoute | Host action |
|---|---|---|
Selected | Present | Use the returned model, CLI, and thinking level. |
Wait | Null | Show the reason and obtain suitable capacity before retrying. |
OverrideRequired | Null | Ask the operator to resolve the policy or pin conflict. |
Every result retains RecommendedRoute, ScoreWorksheet with its scorecard and effective policy score, correctness floor, policy/evidence versions, selection source, reasons, and uncertainty. Keep these together so an operator can inspect why the route was selected or blocked.
The router performs no probes, launches, logging, or writes. Missing, stale, or suspicious quota does not count as healthy capacity. Provider fallbacks must be declared and task-qualified.
Full routing contract and evaluation order · Score windows and correctness floors · Provider snapshot contract
Recommend routes when creating a task
TaskClassRecommendation Recommend(TaskClass taskClass)
TaskClassSelectionResult Select(
TaskClassRecommendation recommendation,
ProviderAvailabilitySnapshot quotaState, DateTime atUtc)
Call these methods on TaskClassRecommendationCatalog.Default. Recommend gives a stable ranked candidate set for a task class, including reasoning levels, evidence versions, rationale, uncertainty, and downgrade conditions.
using TokenEconomy;
TaskClassRecommendation advice =
TaskClassRecommendationCatalog.Default.Recommend(TaskClass.Feature);
foreach (var candidate in advice.Candidates)
Console.WriteLine($"{candidate.Model} / {candidate.ThinkingLevel}");
// gpt-5.6-sol / Medium
// claude-sonnet-5 / High
Select(advice, snapshot, atUtc) chooses only from that candidate set, using fresh quota headroom and retained outcome evidence. Inspect Disposition, nullable Selected, and Reason.
Selected: a candidate has usable capacity.RecommendationOnly: quota evidence is missing, stale, suspicious, or incomplete.Wait: capacity is known to be unavailable, exhausted, or critical.
Selection does not add a downgrade outside the set. Run the concrete task through ModelRouter.Route before launch. Task-class advice and coarse compatibility ranking may differ because they use different evidence.
Published task-class studies and outcome costs · Recommendation contract
Measure cost per accepted result
OutcomeEfficiencyReport OutcomeEfficiency.ComputeObserved(
IEnumerable<DeliveryAttemptEfficiencyInput> attempts,
ModelPriceCatalog catalog, EfficiencyScope scope)
OutcomeEfficiency.ComputeObserved(…) calculates tokens and dated list-price cost per accepted delivery, initial and retry-adjusted cost, retry uplift, and measurement coverage.
Supply the cohort’s attempts and their acceptance outcomes. Failed semantic attempts and failed execution attempts both contribute measured spend. Missing usage or prices leave complete-cohort metrics null and retain an unknown reason.
| Input / result | Fields to retain |
|---|---|
| Each attempt | DeliveryId, AttemptId, contiguous AttemptOrdinal, Model, UTC ExecutedAtUtc, nullable Usage, Outcome, FailureClass. |
| Scope | TaskClass, AcceptanceDefinition, and IncludedWorkflowRoles. |
| Volume | DeliveriesStarted, DeliveriesAccepted, Attempts, RetryAttempts. |
| Per accepted result | TokensPerAcceptedOutcome, TokenComponentsPerAcceptedOutcome, CostPerAcceptedDelivery, AttemptsPerAcceptedDelivery. |
| Retry costs | InitialCostPerStartedDelivery, RetryAdjustedCostPerStartedDelivery, RetryCostUplift, SemanticRetryRate. |
| Coverage and unknowns | TokenCoverage, CostCoverage, KnownPartialCost, Currency, Unconfirmed, Caveat, UnknownReasons. |
Identical repeated attempt records are deduplicated. Conflicting records, invalid attempt order, non-UTC execution times, or workflow roles outside the declared scope raise ArgumentException. No accepted delivery leaves per-accepted-result metrics null. Mixed currencies prevent a complete cost metric.
Use these measurements to compare a model and reasoning level on a stated task set. Keep the sample size, acceptance rule, coverage, and recorded attempts with the score.
Use your own catalog
Construct new ModelPriceCatalog(listings) from your ModelListing values. Each listing supplies a canonical ID, aliases, and dated ModelPrice history. Pass that catalog and matching profiles to ModelEfficiencyMatrix when you need custom compatibility data.
The price catalog rejects blank model IDs, normalized ID/alias collisions, inverted validity periods, and overlapping periods with ArgumentException. Each matrix profile must resolve to a catalog listing.
Connect the decision to your host
Your host records usage and timestamps, probes CLI availability and quota, persists evidence, and launches approved attempts. Keep operator pins separate from the route selected for one attempt.
AgentStudioTaskAdmission.PrepareAttempt connects the router to an estimate store and run ledger. It records the decision and produces an attempt-local LaunchRoute only for a Selected result.
The library also exposes contracts for media capabilities and model migrations. Capacity forecasting is a separate design proposal.
Host order, persistence, and adapter contracts · All public types