Skip to content
↑↓Navigate↵SelectescClose

Registry generator

Generate and sign provider catalogs, import pricing, and collect Azure Foundry model data

nexus-registry-generator is a standalone workspace binary that collects provider catalogs and writes one nexus-registry-artifact JSON document per provider. It has no database dependency. Provider credentials are read only for live generation from OPENAI_API_KEY and ANTHROPIC_API_KEY.

Every model the provider’s API lists becomes a catalog entry. Live collection refuses to create an artifact when an enabled model lacks published base pricing active at generation time, so missing evidence cannot be converted into an endpoint disablement. Fixture and operator inputs may carry deliberately disabled rows. --skip-unpriced removes those disabled entries from an artifact. There is no curated support list: which models a deployment serves is decided by reviewing the generated artifact before importing it, and afterwards with nexus registry models endpoints enable / disable.

Writes <output>/<provider>.json (pretty-printed canonical JSON) for each requested provider and prints <provider>\t<digest>\t<path> per file to stdout. Existing files are never overwritten unless --force is passed. Each artifact’s id is <artifact-id>-<provider>.

Generate deterministically from the copied provider fixtures:

Terminal window
cargo run -p nexus-registry-generator -- generate \
--fixture-dir tools/registry-generator/tests/fixtures \
--generated-at 2026-07-10T12:00:00Z \
--artifact-id provider-catalog-2026-07-10 \
--output dist/provider-catalog

Live generation omits --fixture-dir.

generate can fetch one or more explicitly configured HTTPS JSON documents and record each URL and SHA-256 in the artifact’s sources. These records are non-authoritative cross-check evidence: they do not create, select, or alter any price, and no cross-check URL is required for live generation. For example, configured LiteLLM, models.dev, or OpenRouter JSON endpoints can be retained with:

Terminal window
cargo run -p nexus-registry-generator -- generate \
--pricing-evidence-url https://models.dev/api.json \
--pricing-evidence-url https://example.com/openrouter-models.json \
--output dist/provider-catalog

The command rejects non-HTTPS URLs and invalid JSON responses.

Sign with a 32-byte Ed25519 secret key encoded as hexadecimal or base64:

Terminal window
cargo run -p nexus-registry-generator -- generate \
--generated-at 2026-07-10T12:00:00Z \
--artifact-id provider-catalog-2026-07-10 \
--signing-key signing-key.txt \
--key-id registry-production \
--output dist/provider-catalog

Builds an artifact for one provider from two operator-authored CSVs: a catalog CSV (one row per model) and a rates CSV (one row per priced meter). Rate prices are USD per million tokens for token meters and USD per single request/call otherwise, exactly as published by the provider. Starter files with the required column sets live in templates/catalog.template.csv and templates/rates.template.csv. Catalog CSVs may also include optional embedding_dimensions and embedding_max_inputs columns.

Terminal window
cargo run -p nexus-registry-generator -- from-csv \
--provider nexus_mock \
--catalog catalog.csv \
--rates rates.csv \
--output dist/nexus_mock.json

Azure publishes no machine-readable Foundry catalog, so this subcommand lists the deployments of a live resource and writes the from-csv pair with what the listing proves — deployment name, base model, publisher, and advertised capabilities — leaving everything else blank and naming it in the summary.

Configuration comes from the environment, and every value has a flag override:

Variable Use
AZURE_FOUNDRY_PROJECT_ENDPOINT Preferred surface; reports publisher and capabilities
AZURE_FOUNDRY_OPENAI_ENDPOINT Fallback surface; deployment and base model only
AZURE_FOUNDRY_API_KEY Resource api-key (override the variable with --api-key-env)

The deployment-listing api-version is a property of each surface (2025-05-01 for the projects surface, 2023-03-15-preview for the data plane, which is the last version that still serves the listing) and is pinned accordingly; --api-version overrides it. AZURE_FOUNDRY_API_VERSION configures inference rather than discovery and is deliberately not read here.

Terminal window
cargo run -p nexus-registry-generator -- foundry-csv \
--output dist/foundry \
--context-length 128000 \
--max-output-tokens 16384

--context-length and --max-output-tokens apply to the rows the published models page states no limit for; the token limits the artifact contract requires are otherwise left blank for editing (embedding rows always leave the output limit empty, as the contract requires). --catalog-only emits every row disabled and non-routable for staged review, and a deployment advertising no capability the Foundry adapter dispatches is emitted that way regardless.

No Foundry surface reports whether a model reasons, which modalities it takes, or its token limits. Those columns come from the published Azure OpenAI models page, matched to each deployment’s base model by name. Only published wording is recognized; a model described in unknown wording, or absent from the page, keeps the collector’s own values, and the capability summary counts those rows as making that claim without evidence. An embedding row keeps its embedding output and empty output limit regardless, because those define the row’s class.

Every run saves what it read to model-catalog.json beside the CSVs. --model-catalog <FILE> reads that file instead of the page, which is the only path for a network that cannot reach learn.microsoft.com:

Terminal window
cargo run -p nexus-registry-generator -- foundry-csv \
--output dist/foundry \
--model-catalog model-catalog.json

A JSON array of the same rows is accepted as well, for a model the page does not cover. An unreachable page is a warning rather than a failure: the pair is still written, and the capability summary reports which rows went without published facts.

--prices reads the Azure pricing pages for the publishers involved and fills the rates CSV:

Terminal window
cargo run -p nexus-registry-generator -- foundry-csv \
--output dist/foundry --prices \
--context-length 128000 --max-output-tokens 16384

Every price on those pages is server-rendered into a price-data span carrying a region-to-price map, so the pages parse without a browser. Only standard per-million-token meters are read; provisioned, batch, priority, and fine-tuning columns are ignored because a number lifted from one of them into a pay-as-you-go rate card would misbill every request. Cached Input becomes the cache_read_token meter, which is emitted whether or not the deployment’s capabilities implied one.

Filling is deliberately conservative:

  • A price is written only when the published model name matches the deployment’s base model name exactly (case and separators aside) and the published deployment scope matches the one the deployment’s SKU implies (GlobalStandard to Global, DataZoneStandard to DataZone, Standard to Regional). Rows published without a scope apply to every scope.
  • A near name is a miss. Mistral-Large-3 is left blank and reported rather than priced from Mistral Medium 3.5.
  • Prices differ by region, so the region is explicit: it defaults to the region the resource itself reports (via the x-ms-region response header) and --region overrides it, taking either form (East US 2, eastus2, or the page’s own us-east-2).
  • Each filled price is printed with the row label, table section, region, and page URL it came from, so every number can be checked against the page.
  • pricing-evidence.json is written beside the CSVs with every price observed for every region, the SHA-256 of each page as parsed, and the reason for each miss.

--pricing-fixture-dir reads recorded <page>.html files instead of fetching, for offline runs and tests.

Validating references, digests, and an optional signature end-to-end is a nexus-cli responsibility, not this tool’s: see the nexus-registry README, which enforces the full signature policy (unsigned-fixture vs. required-key) that operators actually rely on.

The accepted live providers for generate are OpenAI and Anthropic; Azure AI Foundry is collected by foundry-csv instead, because its catalog carries no pricing. The artifact contract independently rejects routable Bedrock endpoints.