Skip to content

feat(models): Phase 3 — pricing axis to D2' (authority, model) exact-lookup contract - #4629

Draft
wpfleger96 wants to merge 1 commit into
duncan/databricks-model-label-registryfrom
hayt/usage-v2-pricing-axis
Draft

feat(models): Phase 3 — pricing axis to D2' (authority, model) exact-lookup contract#4629
wpfleger96 wants to merge 1 commit into
duncan/databricks-model-label-registryfrom
hayt/usage-v2-pricing-axis

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Aug 3, 2026

Copy link
Copy Markdown
Member

Summary

Implements the D2' pricing contract from the Usage v2 plan: an optional generated pricing table/API keyed on exact (billing-authority domain, billable-model-string) pairs. No family inference, no prefix stripping, no case normalization. Billing authority is a distinct namespace from the runtime transport Provider enum; match is exact or nothing.

Manifest (scripts/model-capabilities.json)

Replaced pricing_rules (17 prefix-match rules) + pricing_exact_records (3 records) with a flat pricing_records list of 20 exact records, each containing:

  • authority — registered bare-host billing-authority token (api.anthropic.com, api.openai.com)
  • model — exact model string returned by the provider API in its response body
  • usd_per_mtok — input, output, cache_read, cache_write (null fields = price unpublished, never zero)
  • _source — models.dev entry + retrieval date (2026-08-03, SHA 6fd293ae)

Semantics: current list prices (ccusage-aligned). cache_write scoped to default ephemeral class; other classes/TTLs unknown.

Authorities included: api.anthropic.com (11 models) and api.openai.com (9 models). Databricks routes and custom/unknown endpoints are not represented. The publisher (P2 scope) must omit PricingIdentity for those routes; manifest lookup returns null/None.

Generator (scripts/generate-model-capabilities.mjs)

Replaced all old pricing machinery with strict validation + exact-emit:

Validation (hard errors on non-conforming records — no silent skips):

  • authority must be an exact registered token from the closed set (api.anthropic.com, api.openai.com, openrouter.ai); path-bearing, scheme-prefixed, or unknown values rejected
  • model must be nonempty; control/NUL/quote/backslash characters rejected
  • usd_per_mtok.input and .output: finite nonneg required; cache rates null or finite nonneg
  • _source provenance field required and nonempty
  • Duplicate detection on exact emitted (authority, model) pairs

Generation: no toLowerCase() anywhere — records are emitted verbatim. PRICING_TABLE keys on ${authority}\0${model} (exact strings, no transforms).

modelPricing.ts is standalone — no import from modelCapabilities.ts.

Generated API

generated_model_capabilities.rs:

pub fn lookup_pricing(authority: &str, model: &str) -> Option<ModelPricing>

Exact match — no to_ascii_lowercase(), no fallback. Returns None for unknown authority, unknown model, or noncanonical casing.

modelPricing.ts (new file):

export function lookupModelPricing(authority: string, model: string): ModelPricing | null

Same semantics: exact Map lookup, null means price unknown, never treat as zero.

Tests

Rust pricing tests (23):

  • Anthropic and OpenAI model rates
  • Null guards: unknown authority, custom base URL, unknown model, empty authority/model, both empty, wrong authority for known model
  • Exact-match guards: uppercase authority → None; mixed-case authority → None; mixed-case model → None (no case folding)
  • Databricks guards: workspace URL authority → None; "databricks" authority → None

Manifest validator mutation tests (18 new, 43 total in scripts/test-manifest-validator.mjs):

  • Missing authority, unregistered/path-bearing/scheme authority, uppercase authority (case collision)
  • Empty model, unsafe chars in model (double-quote, backslash, NUL, control character)
  • Missing usd_per_mtok.output, negative rates, string cache rate, negative cache_read
  • Missing/empty _source provenance
  • Duplicate (authority, model) pair

Gate

Check Result
cargo test -p buzz-agent pricing 23 passed, 0 failed
cargo test -p buzz-agent (full) 452 passed, 0 failed
node scripts/generate-model-capabilities.mjs --check OK: Rust + TS + TS Pricing
node --test scripts/test-manifest-validator.mjs 43 passed, 0 failed
just desktop-check Clean
modelCapabilities.ts lines 809 ≤ 1000 ✓
modelPricing.ts lines 171 (new file) ✓

Related

Stacks on #3603 (duncan/databricks-model-label-registry) — when that merges, this PR retargets to main and gets rebased.

Related: #4632 (P1 — NIP-AM normative amendment, defines authority token registry), #4000 (P2+P4a — cache-category repair, aggregation, Usage v2 backend), #4001 (P5 — Usage v2 UI). P4b (cost computation in #4000) consumes lookup_pricing(authority, model) from this PR after it lands on main.

@wpfleger96
wpfleger96 requested a review from a team as a code owner August 3, 2026 22:26
@wpfleger96
wpfleger96 marked this pull request as draft August 3, 2026 22:32
@wpfleger96
wpfleger96 force-pushed the hayt/usage-v2-pricing-axis branch from 4f6c083 to 9ef6623 Compare August 3, 2026 23:15
@wpfleger96 wpfleger96 changed the title feat(models): Phase 3 — add pricing axis to model-capabilities manifest feat(models): Phase 3 — pricing axis to D2' (authority, model) exact-lookup contract Aug 3, 2026
…lookup contract

Replaces lookup_pricing(raw_model_id) + normalize_for_pricing + 17 prefix rules
with an exact (billing-authority domain, billable-model-string) lookup. Billing
authority is a distinct namespace from the runtime transport Provider enum.
Match is exact: no case normalization, no prefix matching, no inference.

Manifest (scripts/model-capabilities.json):
- Removed _comment_pricing, pricing_rules (17 rules), pricing_exact_records (3 records)
- Added flat pricing_records list of 20 exact records, each with authority + model +
  usd_per_mtok (input/output/cache_read/cache_write) + _source provenance
- Authorities: api.anthropic.com, api.openai.com — registered bare-host tokens per
  D2'/NIP-AM; not transport Provider enum values
- Semantics: current list prices (ccusage-aligned); cache_write scoped to ephemeral;
  other classes unknown

Generator (scripts/generate-model-capabilities.mjs):
- Removed all old pricing machinery (pricingNormalize, normalizeVersionSeparators,
  pricingRules, pricingExactRecords, resolvePricing, all TS rule-resolver emission)
- Strict pricing-record validation: registered authority (closed set: api.anthropic.com,
  api.openai.com, openrouter.ai); nonempty verbatim model; no control/NUL/quote/backslash
  in key fields; finite nonnegative input/output; cache rates null or finite nonneg;
  _source provenance required; duplicate detection on exact emitted identities
- byAuthority grouping uses exact record values — no toLowerCase() anywhere in
  pricing generation path
- REGISTERED_AUTHORITIES set; hasUnsafeKeyChars() guard
- TS PRICING_TABLE: key is ${authority}\0${model} (exact strings, no transforms)
- lookupModelPricing(authority, model) performs exact Map lookup (no normalization)
- modelPricing.ts is standalone (no import from modelCapabilities)

Generated artifacts:
- generated_model_capabilities.rs: lookup_pricing(authority: &str, model: &str)
  performs exact match — no to_ascii_lowercase() calls, no fallback
- modelPricing.ts: exact PRICING_TABLE + lookupModelPricing(authority, model)

Tests (generated_model_capabilities_tests.rs, 23 pricing tests):
- Anthropic models with correct rates (claude-fable-5, claude-opus-5, claude-sonnet-5,
  claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5)
- OpenAI models incl. gpt-5.6-luna different tier, gpt-5.5 null cache_write, gpt-5-pro
  null cache fields
- Null guards: unknown authority, custom base URL, unknown model, empty authority,
  empty model, both empty, wrong authority for known model
- Exact-match guards: uppercase authority -> None, mixed-case authority -> None,
  mixed-case model -> None (no case folding)
- Databricks guards: workspace URL authority -> None, 'databricks' authority -> None

Manifest validator tests (scripts/test-manifest-validator.mjs, 43 tests total):
- 18 new pricing-record mutation tests covering: missing authority, unregistered/path-
  bearing/scheme authority, empty model, unsafe chars (double-quote, backslash, NUL,
  control), missing output, negative rates, invalid cache rate, missing/empty provenance,
  duplicate records, uppercase authority (case collision)

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
@wpfleger96
wpfleger96 force-pushed the hayt/usage-v2-pricing-axis branch from 9ef6623 to bd68126 Compare August 4, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant