Context
Our pricing engine currently relies on normalized usage meters such as input_text_tokens, output_text_tokens, cached_read_text_tokens, cached_write_text_tokens, output_image, and output_video_seconds. This keeps billing deterministic across providers, but pricing variants are increasingly being encoded into meter names or provider-specific paths.
Examples that are becoming harder to model cleanly:
- cache write pricing with different retention windows
- batch pricing variants
- image pricing that varies by quality, size, or resolution
- video pricing that varies by duration, resolution, speed, or quality
- provider-specific request/tool products that still need normalized billing
Investigation
Explore adding a SKU/product layer above the existing normalized meter system. SKUs should describe named billable products while preserving canonical meters as the accounting primitive.
A possible shape:
{
"sku_id": "cache-write-text-1h",
"sku_name": "Cache Write Text Tokens (1 hour)",
"meter": "cached_write_text_tokens",
"unit": "token",
"attributes": {
"operation": "write",
"modality": "text",
"ttl": "1h"
}
}Pricing rules could continue to match on meter, while optional attributes select the right SKU and price. Usage normalization would still emit canonical quantities, with context used for SKU/rule selection.
Questions to answer
- What should be the boundary between canonical meters, SKUs, and pricing-rule match attributes?
- How should legacy split meters such as TTL-specific cache write meters migrate without breaking billing?
- Should pricing breakdown lines expose both
dimension/meterandsku_id/sku_name? - How should catalog validation prevent double-billing when both legacy split meters and SKU-attribute rules exist?
- How should this model apply to batch, image, video, tool, and request-based pricing?
Desired outcome
Produce a design proposal and migration plan that keeps current pricing functional while allowing richer named pricing products. The plan should include catalog schema changes, pricing-engine changes, validation checks, compatibility behavior, and a staged rollout path.
Activity
7Issue understanding
This issue tracks a design investigation for adding a SKU/product layer above the current normalized meter system in the AI Stats pricing engine. The goal is to model richer pricing products (e.g., cache write with different TTLs, batch variants, image/video quality tiers) while keeping canonical usage meters (`input_text_tokens`, `output_text_tokens`, `cached_write_text_tokens`, etc.) as the accounting primitive. The author wants a design proposal and migration plan covering schema changes, pricing-engine changes, validation, compatibility, and staged rollout.AI Agent Prompt (Copy/Paste)
Design a SKU-backed pricing layer for AI Stats.
Investigate the existing pricing engine and produce a design proposal + migration plan.
What exists today:
- Pricing lives in `packages/data/catalog/src/data/pricing/{provider}/{model}/{capability}/pricing.json` — each file has a `rules[]` array with `meter`, `unit`, `price_per_unit`, `match` conditions, etc.
- 42 canonical meters defined in `apps/web/src/lib/pricing/meters.ts` (e.g., `input_text_tokens`, `cached_write_text_tokens`, `cached_write_text_tokens_1h`, `output_video_seconds`)
- Pricing types/interfaces: `PricingRule` in `apps/web/src/lib/fetchers/models/getModelPricing.ts`, `ProviderPricing` in same file, display helpers in `apps/web/src/components/(data)/model/pricing/pricingHelpers.ts`
- Validation in `packages/data/catalog/src/data/validate.ts` (`checkPricingEntrySafety`) — checks meter names against `KNOWN_METERS`, enforces key format, timestamps, unit/price constraints, no mixed aggregate/detailed meters
- No SKU types, interfaces, or data structures exist yet
Your job:
1. Inspect the files above to understand the current shape.
2. Propose a SKU schema (as JSON) that sits above the meter layer — see issue for example shape.
3. Design how pricing rules would match on `meter` with optional attributes selecting the right SKU.
4. Address migration of legacy split meters (e.g., `cached_write_text_tokens_1h` → SKU-attribute model).
5. Propose how pricing breakdown lines in the gateway/web UI should expose both `dimension`/`meter` and `sku_id`/`sku_name`.
6. Design a validation rule to prevent double-billing when both legacy split meters and SKU-attribute rules exist for the same product.
7. Cover how this applies to batch, image, video, tool, and request pricing.
8. Propose a staged rollout path with no breaking changes to current billing.
9. Write the proposal as a markdown document in the repo (e.g., `packages/data/catalog/docs/pricing-sku-design.md` — create the `docs/` dir if needed).
Do NOT implement any code changes — produce the design document only. Validate your proposal makes sense by cross-referencing 3–5 real pricing.json files from different providers and explaining how they would map to the SKU model.
AI-206