Imported from alastairlundy/ModelsDotDevSharp (
AGENTS.md). Install upstream withnpx skills add alastairlundy/ModelsDotDevSharp. Copyright stays with the author.
AGENTS.md
Project
- C# library that wraps the public models.dev API (
https://models.dev/api.json,/models.json,/catalog.json) for .NET consumers. - Single project:
src/ModelsDotDevSharp/ModelsDotDevSharp.csproj; solution issrc/ModelsDotDevSharp.slnx(XML solution format). TargetFramework=net10.0,LangVersion=14,ImplicitUsings=enable,Nullable=enable. No multi-targeting. Noglobal.json— SDK version is whatever is installed locally.
Build, package, restore
- Build:
dotnet build src/ModelsDotDevSharp.slnx(ordotnet build src/ModelsDotDevSharp/ModelsDotDevSharp.csproj). - Pack:
dotnet pack src/ModelsDotDevSharp/ModelsDotDevSharp.csproj—GeneratePackageOnBuild=trueis set, so a.nupkgis produced on build. - Test:
dotnet test src/ModelsDotDevSharp.slnxruns the TUnit test project attests/ModelsDotDevSharp.Tests/. Tests DO exist — do not treatdotnet testas a no-op. - No CI workflows exist in
.github/workflows/. Dependabot (.github/dependabot.yml) updates NuGet weekly and looks for GitHub Actions (none yet).
Dependency management — Central Package Management
src/Directory.Packages.propshasManagePackageVersionsCentrally=true.- All NuGet versions live in
Directory.Packages.props. The.csprojonly declares<PackageReference Include="..." />with noVersion=. - To add/update a package, edit
src/Directory.Packages.propsonly. Do not addVersion=attributes to the.csproj. - Current packages:
Microsoft.Extensions.DependencyInjection.Abstractions10.0.9,Microsoft.Extensions.Http10.0.9,Microsoft.Extensions.Options10.0.9 (all at the .NET 10.0.9 patch track) +TUnit1.65.51 (test project only).
AOT / trimming constraints
- The project sets
IsTrimmable=true,EnableAoTAnalyzer=true,PublishTrimmed=true. Treat the library as AOT- and trim-safe. - JSON deserialization goes through
System.Text.Jsonsource generators only — no reflection. The contexts live at:src/ModelsDotDevSharp/Contexts/ModelInfoJsonContext.cs(providers + models:AIProviderInfo,AIProviderInfo[],AIModelInfo,AIModelInfo[],AIModelCostInfo,AIModelModalities,AIModelLimit,AIModelCostTier,AIModelTierInfo,AIModelStatus,AIModelReasoningOption,AIModelInterleaved,AIModelExperimental,AIModelProviderOverride)src/ModelsDotDevSharp/Contexts/ModelMetadataJsonContext.cs(AIModelMetadata,AIModelMetadata[],AIModelWeightInfo,AIModelBenchmark,AIModelLimit,AIModelModalities)src/ModelsDotDevSharp/Contexts/CatalogJsonContext.cs(AICatalogand the provider/model types used by the catalog)
- Custom
JsonConverters live insrc/ModelsDotDevSharp/Converters/and are wired into the contexts via[JsonSourceGenerationOptions(Converters = [...])]:FlexibleDateOnlyConverter,InterleavedBooleanOrObjectConverter,AIProviderInfoArrayFlatteningConverter,AIModelInfoArrayFlatteningConverter,ModelsJsonFlatteningConverter,CostContextOverridePostProcessor. - When you add a new serializable model, you must also add a matching
[JsonSerializable(typeof(YourType))]to the relevant context (or extend an existing one). Otherwise AOT builds will fail and trimming warnings will appear. - Repositories take
IHttpClientFactory+IOptions<ModelsDevOptions>via constructor injection — that is the supported HTTP path. Don't addstatic HttpClientfields.
Compatibility with models.dev is the primary contract
- Every
Models/*.cstype uses[JsonPropertyName("...")]to bind to models.dev's JSON field names. Names likeinput_audio,output_audio,cache_read,cache_write,structured_output,tool_call,open_weights,last_updated,knowledgemust stay byte-for-byte identical to the upstream schema. - When models.dev's schema changes, update the matching property name and (if needed) add the field. Do not rename C# properties without also updating the
JsonPropertyName. - The base address is configurable via
ModelsDevOptions.BaseAddress(defaults tohttps://models.dev) and set throughAddModelsDotDevSharp(opts => opts.BaseAddress = ...). The endpoints are hardcoded per repository:/api.json(providers),/models.json(model metadata),/catalog.json(catalog). - Public API surface:
- Abstractions:
IModelInfoRepository,IModelMetadataRepository,ICatalogRepository(inAbstractions/) - Implementations:
ModelInfoRepository,ModelMetadataRepository,CatalogRepository - DI entry point:
ModelsDevServiceCollectionExtensions.AddModelsDotDevSharp(...)(uses a C# 14extensionblock) - Options:
ModelsDevOptions(currently justBaseAddress) - New methods belong on the interface and the implementation together.
- Abstractions:
Code layout conventions
- Namespaces: root types in
ModelsDotDevSharp, abstractions inModelsDotDevSharp.Abstractions, JSON contexts inModelsDotDevSharp.Contexts, converters inModelsDotDevSharp.Converters.GlobalUsings.csimports all of these plusSystem.ComponentModel,System.Text.Json.Serialization, andMicrosoft.Extensions.Options, so individual files usually skip those usings. - Models are C#
recordtypes with mutableget; set;properties (notinit). Keep that pattern for consistency with the existing files. - Every source file starts with the MIT license header (see any
Models/*.cs). - The
.csproj.DotSettingsfile is a JetBrains Rider/ReSharper setting (namespace-folder skip). Ignore it unless working in Rider.
Known behaviors worth knowing
GetModelInfoByIdAsyncandGetProviderInfoByIdAsynccatchNullReferenceExceptionfrom LINQFirst/FirstAsyncand rethrow asArgumentException. Don't "fix" the throw type without confirming it isn't part of the public contract.GetCatalogAsyncthrows a bareException("Could not connect to the ModelDotDev API")when the JSON deserializes tonull. Caller code may depend on that message.GetProviderInfosAsyncreturns an empty array (not an exception) when the response body is empty or deserializes tonull.src/.idea/is a JetBrains IDE folder; it is gitignored via/src/.ideain the root.gitignore. Do not commit changes to it.
What is intentionally not here
- README is packed into the NuGet package via
<PackageReadmeFile>README.md</PackageReadmeFile>(the file at repo root). Don't expand the README beyond what's needed unless asked. - No analyzer, formatter, or lint config files (
Directory.Build.props,Directory.Build.targets,.editorconfig) are committed. The repo relies on .NET SDK defaults plus the Rider.DotSettingsfile.
Agent skills
Issue tracker
Issues and PRDs for this repo live as GitHub issues at alastairlundy/ModelsDotDevSharp; use the gh CLI. See docs/agents/issue-tracker.md.
Triage labels
Triage labels use the canonical five strings (needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix) — no overrides. See docs/agents/triage-labels.md.
Domain docs
Single-context layout: one CONTEXT.md and docs/adr/ at the repo root (neither exists yet; skills will create them lazily). See docs/agents/domain.md.