fix(server): keep usage pricing aliases distinct - #5810

Open
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys
Open

fix(server): keep usage pricing aliases distinct#5810
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys

Conversation

@caezium

@caeziumcaezium commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Separate exact provider-qualified rates, bare aliases, and the public model count.
  • Resolve qualified model names only through their exact provider key.
  • Prefer a canonical bare rate, allow one unambiguous provider fallback, and leave ambiguous collisions unpriced.
  • Make case/whitespace-normalized collisions deterministic instead of document-order dependent.
  • Keep aliases from inflating pricing.knownModels.

Why

The rate parser currently strips provider prefixes before insertion, so LiteLLM entries ending in the same model name overwrite one another. JSON order can change base and cache pricing, including replacing a canonical cache-read rate with full input price.

Closes#5797

Verification

  • 16 focused pricing and aggregation tests passed after review fixes.
  • Targeted formatting and lint passed.
  • Server typecheck passed; only pre-existing unrelated Effect suggestions remain.
  • Branch rebased on current upstream/main.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No UI changes

Implemented with gpt-5.6-sol in T3 Code through the Codex harness.

Note

Fix lookupRate to keep provider-qualified and bare alias entries distinct in RateTable

  • Restructures RateTable in usagePricing.ts from a flat Map<string, ModelRate> into an object with exactRates, bareAliases, and modelCount, so provider-qualified and bare alias entries are stored separately.
  • parseRateTable now drops ambiguous normalized duplicates (no canonical provenance) and only creates bare aliases for canonical or unambiguous entries.
  • lookupRate no longer falls back from a missing provider-qualified key to a bare alias; bare lookups still resolve via exactRates then bareAliases.
  • UsageService switches from Map.size to rateTableModelCount() so alias-only entries are excluded from model counts and rate-status decisions.
  • Behavioral Change: provider-qualified model lookups that previously matched a bare alias will now return null if no exact entry exists.

Macroscope summarized c3b1d5c.


Note

Medium Risk
Changes how transcript model names map to LiteLLM rates, so some costs may shift from priced to unpriced (or vice versa) for ambiguous or provider-qualified names.

Overview
Fixes LiteLLM usage pricing so provider-qualified model keys no longer overwrite each other when normalized to the same bare name.

RateTable is no longer a single Map; it now holds exactRates, optional bareAliases, and modelCount. parseRateTable indexes entries by the full normalized key, resolves duplicate spellings only when one row matches the canonical key (otherwise drops the key), and adds a bare alias only for a canonical bare entry or a single unambiguous provider-qualified candidate. lookupRate uses exact keys for provider/model lookups (no bare fallback on miss); bare names still resolve via exact then alias. UsageService uses emptyRateTable, rateTableModelCount, and reports knownModels from exact entries only.

Adds usagePricing.test.ts for alias/collision behavior; aggregation tests build rates via parseRateTable.

Reviewed by Cursor Bugbot for commit c3b1d5c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73cbbf5f-9a6e-4139-a8e2-f7d88a635b69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 9, 2026
@caezium
caezium marked this pull request as ready for review August 9, 2026 10:26
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR modifies pricing lookup logic in the usage/billing infrastructure. Changes to billing and pricing code paths require human review regardless of apparent simplicity, as they can affect cost calculations for users.

You can customize Macroscope's approvability policy. Learn more.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Usage pricing is order-dependent across provider-qualified models

1 participant

@caezium
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(server): keep usage pricing aliases distinct - #5810

Open
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys
Open

fix(server): keep usage pricing aliases distinct#5810
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys

Conversation

@caezium

@caeziumcaezium commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Separate exact provider-qualified rates, bare aliases, and the public model count.
  • Resolve qualified model names only through their exact provider key.
  • Prefer a canonical bare rate, allow one unambiguous provider fallback, and leave ambiguous collisions unpriced.
  • Make case/whitespace-normalized collisions deterministic instead of document-order dependent.
  • Keep aliases from inflating pricing.knownModels.

Why

The rate parser currently strips provider prefixes before insertion, so LiteLLM entries ending in the same model name overwrite one another. JSON order can change base and cache pricing, including replacing a canonical cache-read rate with full input price.

Closes#5797

Verification

  • 16 focused pricing and aggregation tests passed after review fixes.
  • Targeted formatting and lint passed.
  • Server typecheck passed; only pre-existing unrelated Effect suggestions remain.
  • Branch rebased on current upstream/main.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No UI changes

Implemented with gpt-5.6-sol in T3 Code through the Codex harness.

Note

Fix lookupRate to keep provider-qualified and bare alias entries distinct in RateTable

  • Restructures RateTable in usagePricing.ts from a flat Map<string, ModelRate> into an object with exactRates, bareAliases, and modelCount, so provider-qualified and bare alias entries are stored separately.
  • parseRateTable now drops ambiguous normalized duplicates (no canonical provenance) and only creates bare aliases for canonical or unambiguous entries.
  • lookupRate no longer falls back from a missing provider-qualified key to a bare alias; bare lookups still resolve via exactRates then bareAliases.
  • UsageService switches from Map.size to rateTableModelCount() so alias-only entries are excluded from model counts and rate-status decisions.
  • Behavioral Change: provider-qualified model lookups that previously matched a bare alias will now return null if no exact entry exists.

Macroscope summarized c3b1d5c.


Note

Medium Risk
Changes how transcript model names map to LiteLLM rates, so some costs may shift from priced to unpriced (or vice versa) for ambiguous or provider-qualified names.

Overview
Fixes LiteLLM usage pricing so provider-qualified model keys no longer overwrite each other when normalized to the same bare name.

RateTable is no longer a single Map; it now holds exactRates, optional bareAliases, and modelCount. parseRateTable indexes entries by the full normalized key, resolves duplicate spellings only when one row matches the canonical key (otherwise drops the key), and adds a bare alias only for a canonical bare entry or a single unambiguous provider-qualified candidate. lookupRate uses exact keys for provider/model lookups (no bare fallback on miss); bare names still resolve via exact then alias. UsageService uses emptyRateTable, rateTableModelCount, and reports knownModels from exact entries only.

Adds usagePricing.test.ts for alias/collision behavior; aggregation tests build rates via parseRateTable.

Reviewed by Cursor Bugbot for commit c3b1d5c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73cbbf5f-9a6e-4139-a8e2-f7d88a635b69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 9, 2026
@caezium
caezium marked this pull request as ready for review August 9, 2026 10:26
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR modifies pricing lookup logic in the usage/billing infrastructure. Changes to billing and pricing code paths require human review regardless of apparent simplicity, as they can affect cost calculations for users.

You can customize Macroscope's approvability policy. Learn more.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Usage pricing is order-dependent across provider-qualified models

1 participant

@caezium
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): keep usage pricing aliases distinct - #5810

Open
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys
Open

fix(server): keep usage pricing aliases distinct#5810
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys

Conversation

@caezium

@caeziumcaezium commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Separate exact provider-qualified rates, bare aliases, and the public model count.
  • Resolve qualified model names only through their exact provider key.
  • Prefer a canonical bare rate, allow one unambiguous provider fallback, and leave ambiguous collisions unpriced.
  • Make case/whitespace-normalized collisions deterministic instead of document-order dependent.
  • Keep aliases from inflating pricing.knownModels.

Why

The rate parser currently strips provider prefixes before insertion, so LiteLLM entries ending in the same model name overwrite one another. JSON order can change base and cache pricing, including replacing a canonical cache-read rate with full input price.

Closes#5797

Verification

  • 16 focused pricing and aggregation tests passed after review fixes.
  • Targeted formatting and lint passed.
  • Server typecheck passed; only pre-existing unrelated Effect suggestions remain.
  • Branch rebased on current upstream/main.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No UI changes

Implemented with gpt-5.6-sol in T3 Code through the Codex harness.

Note

Fix lookupRate to keep provider-qualified and bare alias entries distinct in RateTable

  • Restructures RateTable in usagePricing.ts from a flat Map<string, ModelRate> into an object with exactRates, bareAliases, and modelCount, so provider-qualified and bare alias entries are stored separately.
  • parseRateTable now drops ambiguous normalized duplicates (no canonical provenance) and only creates bare aliases for canonical or unambiguous entries.
  • lookupRate no longer falls back from a missing provider-qualified key to a bare alias; bare lookups still resolve via exactRates then bareAliases.
  • UsageService switches from Map.size to rateTableModelCount() so alias-only entries are excluded from model counts and rate-status decisions.
  • Behavioral Change: provider-qualified model lookups that previously matched a bare alias will now return null if no exact entry exists.

Macroscope summarized c3b1d5c.


Note

Medium Risk
Changes how transcript model names map to LiteLLM rates, so some costs may shift from priced to unpriced (or vice versa) for ambiguous or provider-qualified names.

Overview
Fixes LiteLLM usage pricing so provider-qualified model keys no longer overwrite each other when normalized to the same bare name.

RateTable is no longer a single Map; it now holds exactRates, optional bareAliases, and modelCount. parseRateTable indexes entries by the full normalized key, resolves duplicate spellings only when one row matches the canonical key (otherwise drops the key), and adds a bare alias only for a canonical bare entry or a single unambiguous provider-qualified candidate. lookupRate uses exact keys for provider/model lookups (no bare fallback on miss); bare names still resolve via exact then alias. UsageService uses emptyRateTable, rateTableModelCount, and reports knownModels from exact entries only.

Adds usagePricing.test.ts for alias/collision behavior; aggregation tests build rates via parseRateTable.

Reviewed by Cursor Bugbot for commit c3b1d5c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73cbbf5f-9a6e-4139-a8e2-f7d88a635b69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 9, 2026
@caezium
caezium marked this pull request as ready for review August 9, 2026 10:26
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR modifies pricing lookup logic in the usage/billing infrastructure. Changes to billing and pricing code paths require human review regardless of apparent simplicity, as they can affect cost calculations for users.

You can customize Macroscope's approvability policy. Learn more.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Usage pricing is order-dependent across provider-qualified models

1 participant

@caezium
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): keep usage pricing aliases distinct - #5810

Open
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys
Open

fix(server): keep usage pricing aliases distinct#5810
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys

Conversation

@caezium

@caeziumcaezium commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Separate exact provider-qualified rates, bare aliases, and the public model count.
  • Resolve qualified model names only through their exact provider key.
  • Prefer a canonical bare rate, allow one unambiguous provider fallback, and leave ambiguous collisions unpriced.
  • Make case/whitespace-normalized collisions deterministic instead of document-order dependent.
  • Keep aliases from inflating pricing.knownModels.

Why

The rate parser currently strips provider prefixes before insertion, so LiteLLM entries ending in the same model name overwrite one another. JSON order can change base and cache pricing, including replacing a canonical cache-read rate with full input price.

Closes#5797

Verification

  • 16 focused pricing and aggregation tests passed after review fixes.
  • Targeted formatting and lint passed.
  • Server typecheck passed; only pre-existing unrelated Effect suggestions remain.
  • Branch rebased on current upstream/main.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No UI changes

Implemented with gpt-5.6-sol in T3 Code through the Codex harness.

Note

Fix lookupRate to keep provider-qualified and bare alias entries distinct in RateTable

  • Restructures RateTable in usagePricing.ts from a flat Map<string, ModelRate> into an object with exactRates, bareAliases, and modelCount, so provider-qualified and bare alias entries are stored separately.
  • parseRateTable now drops ambiguous normalized duplicates (no canonical provenance) and only creates bare aliases for canonical or unambiguous entries.
  • lookupRate no longer falls back from a missing provider-qualified key to a bare alias; bare lookups still resolve via exactRates then bareAliases.
  • UsageService switches from Map.size to rateTableModelCount() so alias-only entries are excluded from model counts and rate-status decisions.
  • Behavioral Change: provider-qualified model lookups that previously matched a bare alias will now return null if no exact entry exists.

Macroscope summarized c3b1d5c.


Note

Medium Risk
Changes how transcript model names map to LiteLLM rates, so some costs may shift from priced to unpriced (or vice versa) for ambiguous or provider-qualified names.

Overview
Fixes LiteLLM usage pricing so provider-qualified model keys no longer overwrite each other when normalized to the same bare name.

RateTable is no longer a single Map; it now holds exactRates, optional bareAliases, and modelCount. parseRateTable indexes entries by the full normalized key, resolves duplicate spellings only when one row matches the canonical key (otherwise drops the key), and adds a bare alias only for a canonical bare entry or a single unambiguous provider-qualified candidate. lookupRate uses exact keys for provider/model lookups (no bare fallback on miss); bare names still resolve via exact then alias. UsageService uses emptyRateTable, rateTableModelCount, and reports knownModels from exact entries only.

Adds usagePricing.test.ts for alias/collision behavior; aggregation tests build rates via parseRateTable.

Reviewed by Cursor Bugbot for commit c3b1d5c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73cbbf5f-9a6e-4139-a8e2-f7d88a635b69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 9, 2026
@caezium
caezium marked this pull request as ready for review August 9, 2026 10:26
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR modifies pricing lookup logic in the usage/billing infrastructure. Changes to billing and pricing code paths require human review regardless of apparent simplicity, as they can affect cost calculations for users.

You can customize Macroscope's approvability policy. Learn more.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Usage pricing is order-dependent across provider-qualified models

1 participant

@caezium
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(server): keep usage pricing aliases distinct - #5810

Open
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys
Open

fix(server): keep usage pricing aliases distinct#5810
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys

Conversation

@caezium

@caeziumcaezium commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Separate exact provider-qualified rates, bare aliases, and the public model count.
  • Resolve qualified model names only through their exact provider key.
  • Prefer a canonical bare rate, allow one unambiguous provider fallback, and leave ambiguous collisions unpriced.
  • Make case/whitespace-normalized collisions deterministic instead of document-order dependent.
  • Keep aliases from inflating pricing.knownModels.

Why

The rate parser currently strips provider prefixes before insertion, so LiteLLM entries ending in the same model name overwrite one another. JSON order can change base and cache pricing, including replacing a canonical cache-read rate with full input price.

Closes#5797

Verification

  • 16 focused pricing and aggregation tests passed after review fixes.
  • Targeted formatting and lint passed.
  • Server typecheck passed; only pre-existing unrelated Effect suggestions remain.
  • Branch rebased on current upstream/main.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No UI changes

Implemented with gpt-5.6-sol in T3 Code through the Codex harness.

Note

Fix lookupRate to keep provider-qualified and bare alias entries distinct in RateTable

  • Restructures RateTable in usagePricing.ts from a flat Map<string, ModelRate> into an object with exactRates, bareAliases, and modelCount, so provider-qualified and bare alias entries are stored separately.
  • parseRateTable now drops ambiguous normalized duplicates (no canonical provenance) and only creates bare aliases for canonical or unambiguous entries.
  • lookupRate no longer falls back from a missing provider-qualified key to a bare alias; bare lookups still resolve via exactRates then bareAliases.
  • UsageService switches from Map.size to rateTableModelCount() so alias-only entries are excluded from model counts and rate-status decisions.
  • Behavioral Change: provider-qualified model lookups that previously matched a bare alias will now return null if no exact entry exists.

Macroscope summarized c3b1d5c.


Note

Medium Risk
Changes how transcript model names map to LiteLLM rates, so some costs may shift from priced to unpriced (or vice versa) for ambiguous or provider-qualified names.

Overview
Fixes LiteLLM usage pricing so provider-qualified model keys no longer overwrite each other when normalized to the same bare name.

RateTable is no longer a single Map; it now holds exactRates, optional bareAliases, and modelCount. parseRateTable indexes entries by the full normalized key, resolves duplicate spellings only when one row matches the canonical key (otherwise drops the key), and adds a bare alias only for a canonical bare entry or a single unambiguous provider-qualified candidate. lookupRate uses exact keys for provider/model lookups (no bare fallback on miss); bare names still resolve via exact then alias. UsageService uses emptyRateTable, rateTableModelCount, and reports knownModels from exact entries only.

Adds usagePricing.test.ts for alias/collision behavior; aggregation tests build rates via parseRateTable.

Reviewed by Cursor Bugbot for commit c3b1d5c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73cbbf5f-9a6e-4139-a8e2-f7d88a635b69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 9, 2026
@caezium
caezium marked this pull request as ready for review August 9, 2026 10:26
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR modifies pricing lookup logic in the usage/billing infrastructure. Changes to billing and pricing code paths require human review regardless of apparent simplicity, as they can affect cost calculations for users.

You can customize Macroscope's approvability policy. Learn more.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Usage pricing is order-dependent across provider-qualified models

1 participant

@caezium
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): keep usage pricing aliases distinct - #5810

Open
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys
Open

fix(server): keep usage pricing aliases distinct#5810
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys

Conversation

@caezium

@caeziumcaezium commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Separate exact provider-qualified rates, bare aliases, and the public model count.
  • Resolve qualified model names only through their exact provider key.
  • Prefer a canonical bare rate, allow one unambiguous provider fallback, and leave ambiguous collisions unpriced.
  • Make case/whitespace-normalized collisions deterministic instead of document-order dependent.
  • Keep aliases from inflating pricing.knownModels.

Why

The rate parser currently strips provider prefixes before insertion, so LiteLLM entries ending in the same model name overwrite one another. JSON order can change base and cache pricing, including replacing a canonical cache-read rate with full input price.

Closes#5797

Verification

  • 16 focused pricing and aggregation tests passed after review fixes.
  • Targeted formatting and lint passed.
  • Server typecheck passed; only pre-existing unrelated Effect suggestions remain.
  • Branch rebased on current upstream/main.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No UI changes

Implemented with gpt-5.6-sol in T3 Code through the Codex harness.

Note

Fix lookupRate to keep provider-qualified and bare alias entries distinct in RateTable

  • Restructures RateTable in usagePricing.ts from a flat Map<string, ModelRate> into an object with exactRates, bareAliases, and modelCount, so provider-qualified and bare alias entries are stored separately.
  • parseRateTable now drops ambiguous normalized duplicates (no canonical provenance) and only creates bare aliases for canonical or unambiguous entries.
  • lookupRate no longer falls back from a missing provider-qualified key to a bare alias; bare lookups still resolve via exactRates then bareAliases.
  • UsageService switches from Map.size to rateTableModelCount() so alias-only entries are excluded from model counts and rate-status decisions.
  • Behavioral Change: provider-qualified model lookups that previously matched a bare alias will now return null if no exact entry exists.

Macroscope summarized c3b1d5c.


Note

Medium Risk
Changes how transcript model names map to LiteLLM rates, so some costs may shift from priced to unpriced (or vice versa) for ambiguous or provider-qualified names.

Overview
Fixes LiteLLM usage pricing so provider-qualified model keys no longer overwrite each other when normalized to the same bare name.

RateTable is no longer a single Map; it now holds exactRates, optional bareAliases, and modelCount. parseRateTable indexes entries by the full normalized key, resolves duplicate spellings only when one row matches the canonical key (otherwise drops the key), and adds a bare alias only for a canonical bare entry or a single unambiguous provider-qualified candidate. lookupRate uses exact keys for provider/model lookups (no bare fallback on miss); bare names still resolve via exact then alias. UsageService uses emptyRateTable, rateTableModelCount, and reports knownModels from exact entries only.

Adds usagePricing.test.ts for alias/collision behavior; aggregation tests build rates via parseRateTable.

Reviewed by Cursor Bugbot for commit c3b1d5c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73cbbf5f-9a6e-4139-a8e2-f7d88a635b69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 9, 2026
@caezium
caezium marked this pull request as ready for review August 9, 2026 10:26
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR modifies pricing lookup logic in the usage/billing infrastructure. Changes to billing and pricing code paths require human review regardless of apparent simplicity, as they can affect cost calculations for users.

You can customize Macroscope's approvability policy. Learn more.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Usage pricing is order-dependent across provider-qualified models

1 participant

@caezium
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): keep usage pricing aliases distinct - #5810

Open
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys
Open

fix(server): keep usage pricing aliases distinct#5810
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys

Conversation

@caezium

@caeziumcaezium commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Separate exact provider-qualified rates, bare aliases, and the public model count.
  • Resolve qualified model names only through their exact provider key.
  • Prefer a canonical bare rate, allow one unambiguous provider fallback, and leave ambiguous collisions unpriced.
  • Make case/whitespace-normalized collisions deterministic instead of document-order dependent.
  • Keep aliases from inflating pricing.knownModels.

Why

The rate parser currently strips provider prefixes before insertion, so LiteLLM entries ending in the same model name overwrite one another. JSON order can change base and cache pricing, including replacing a canonical cache-read rate with full input price.

Closes#5797

Verification

  • 16 focused pricing and aggregation tests passed after review fixes.
  • Targeted formatting and lint passed.
  • Server typecheck passed; only pre-existing unrelated Effect suggestions remain.
  • Branch rebased on current upstream/main.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No UI changes

Implemented with gpt-5.6-sol in T3 Code through the Codex harness.

Note

Fix lookupRate to keep provider-qualified and bare alias entries distinct in RateTable

  • Restructures RateTable in usagePricing.ts from a flat Map<string, ModelRate> into an object with exactRates, bareAliases, and modelCount, so provider-qualified and bare alias entries are stored separately.
  • parseRateTable now drops ambiguous normalized duplicates (no canonical provenance) and only creates bare aliases for canonical or unambiguous entries.
  • lookupRate no longer falls back from a missing provider-qualified key to a bare alias; bare lookups still resolve via exactRates then bareAliases.
  • UsageService switches from Map.size to rateTableModelCount() so alias-only entries are excluded from model counts and rate-status decisions.
  • Behavioral Change: provider-qualified model lookups that previously matched a bare alias will now return null if no exact entry exists.

Macroscope summarized c3b1d5c.


Note

Medium Risk
Changes how transcript model names map to LiteLLM rates, so some costs may shift from priced to unpriced (or vice versa) for ambiguous or provider-qualified names.

Overview
Fixes LiteLLM usage pricing so provider-qualified model keys no longer overwrite each other when normalized to the same bare name.

RateTable is no longer a single Map; it now holds exactRates, optional bareAliases, and modelCount. parseRateTable indexes entries by the full normalized key, resolves duplicate spellings only when one row matches the canonical key (otherwise drops the key), and adds a bare alias only for a canonical bare entry or a single unambiguous provider-qualified candidate. lookupRate uses exact keys for provider/model lookups (no bare fallback on miss); bare names still resolve via exact then alias. UsageService uses emptyRateTable, rateTableModelCount, and reports knownModels from exact entries only.

Adds usagePricing.test.ts for alias/collision behavior; aggregation tests build rates via parseRateTable.

Reviewed by Cursor Bugbot for commit c3b1d5c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73cbbf5f-9a6e-4139-a8e2-f7d88a635b69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 9, 2026
@caezium
caezium marked this pull request as ready for review August 9, 2026 10:26
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR modifies pricing lookup logic in the usage/billing infrastructure. Changes to billing and pricing code paths require human review regardless of apparent simplicity, as they can affect cost calculations for users.

You can customize Macroscope's approvability policy. Learn more.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Usage pricing is order-dependent across provider-qualified models

1 participant

@caezium
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(server): keep usage pricing aliases distinct - #5810

Open
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys
Open

fix(server): keep usage pricing aliases distinct#5810
caezium wants to merge 1 commit into
pingdotgg:mainfrom
caezium:agent/usage-pricing-keys

Conversation

@caezium

@caeziumcaezium commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Separate exact provider-qualified rates, bare aliases, and the public model count.
  • Resolve qualified model names only through their exact provider key.
  • Prefer a canonical bare rate, allow one unambiguous provider fallback, and leave ambiguous collisions unpriced.
  • Make case/whitespace-normalized collisions deterministic instead of document-order dependent.
  • Keep aliases from inflating pricing.knownModels.

Why

The rate parser currently strips provider prefixes before insertion, so LiteLLM entries ending in the same model name overwrite one another. JSON order can change base and cache pricing, including replacing a canonical cache-read rate with full input price.

Closes#5797

Verification

  • 16 focused pricing and aggregation tests passed after review fixes.
  • Targeted formatting and lint passed.
  • Server typecheck passed; only pre-existing unrelated Effect suggestions remain.
  • Branch rebased on current upstream/main.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No UI changes

Implemented with gpt-5.6-sol in T3 Code through the Codex harness.

Note

Fix lookupRate to keep provider-qualified and bare alias entries distinct in RateTable

  • Restructures RateTable in usagePricing.ts from a flat Map<string, ModelRate> into an object with exactRates, bareAliases, and modelCount, so provider-qualified and bare alias entries are stored separately.
  • parseRateTable now drops ambiguous normalized duplicates (no canonical provenance) and only creates bare aliases for canonical or unambiguous entries.
  • lookupRate no longer falls back from a missing provider-qualified key to a bare alias; bare lookups still resolve via exactRates then bareAliases.
  • UsageService switches from Map.size to rateTableModelCount() so alias-only entries are excluded from model counts and rate-status decisions.
  • Behavioral Change: provider-qualified model lookups that previously matched a bare alias will now return null if no exact entry exists.

Macroscope summarized c3b1d5c.


Note

Medium Risk
Changes how transcript model names map to LiteLLM rates, so some costs may shift from priced to unpriced (or vice versa) for ambiguous or provider-qualified names.

Overview
Fixes LiteLLM usage pricing so provider-qualified model keys no longer overwrite each other when normalized to the same bare name.

RateTable is no longer a single Map; it now holds exactRates, optional bareAliases, and modelCount. parseRateTable indexes entries by the full normalized key, resolves duplicate spellings only when one row matches the canonical key (otherwise drops the key), and adds a bare alias only for a canonical bare entry or a single unambiguous provider-qualified candidate. lookupRate uses exact keys for provider/model lookups (no bare fallback on miss); bare names still resolve via exact then alias. UsageService uses emptyRateTable, rateTableModelCount, and reports knownModels from exact entries only.

Adds usagePricing.test.ts for alias/collision behavior; aggregation tests build rates via parseRateTable.

Reviewed by Cursor Bugbot for commit c3b1d5c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73cbbf5f-9a6e-4139-a8e2-f7d88a635b69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 9, 2026
@caezium
caezium marked this pull request as ready for review August 9, 2026 10:26
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR modifies pricing lookup logic in the usage/billing infrastructure. Changes to billing and pricing code paths require human review regardless of apparent simplicity, as they can affect cost calculations for users.

You can customize Macroscope's approvability policy. Learn more.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Usage pricing is order-dependent across provider-qualified models

1 participant

@caezium