fix(usage): honor provider-aware pricing precedence

This commit is contained in:
Tam Nhu Tran committed 2026-04-28 16:11:07 -04:00
1 parent f736190196
commit c7141b3d3a
4 files changed
+91 -8

No files matched your search

+17
View File
@@ -327,6 +327,11 @@ describe('model-pricing', () => {
name: 'GPT-5.5',
cost: { input: 5, output: 30, cache_read: 0.5 },
},
'gpt-4o': {
id: 'gpt-4o',
name: 'GPT-4o',
cost: { input: 2.5, output: 10, cache_read: 1.25 },
},
'openai-exclusive-model': {
id: 'openai-exclusive-model',
name: 'OpenAI Exclusive Model',
@@ -343,6 +348,11 @@ describe('model-pricing', () => {
name: 'GPT-5.5',
cost: { input: 0, output: 0 },
},
'gpt-4o': {
id: 'gpt-4o',
name: 'GPT-4o',
cost: { input: 0, output: 0 },
},
},
},
});
@@ -371,6 +381,13 @@ describe('model-pricing', () => {
expect(pricing.outputPerMillion).toBe(0);
});
it('prefers provider-aware models.dev pricing over exact static table matches', () => {
const pricing = getModelPricing('gpt-4o', { provider: 'github-copilot' });
expect(pricing.inputPerMillion).toBe(0);
expect(pricing.outputPerMillion).toBe(0);
expect(getModelPricing('gpt-4o').inputPerMillion).toBe(2.5);
});
it('does not use ambiguous model-only models.dev matches', () => {
const pricing = getModelPricing('gpt-5.5');
expect(pricing).toEqual(getModelPricing('unknown-model-xyz'));
@@ -108,7 +108,7 @@ describe('cliproxy usage transformer', () => {
it('retains failed requests when they carry usage and skips zero-usage failures', () => {
const flat = extractCliproxyUsageHistoryDetails(sampleResponse);
expect(flat).toHaveLength(4);
expect(flat[0].provider).toBe('gemini');
expect(flat[0].provider).toBe('google');
expect(
flat.some(
(entry) =>
@@ -296,5 +296,71 @@ describe('cliproxy usage transformer', () => {
expect(paid?.cost).toBe(35.5);
expect(subscription?.cost).toBe(0);
});
it('canonicalizes CLIProxy provider aliases before grouping history details', () => {
const response: CliproxyUsageApiResponse = {
usage: {
apis: {
ghcp: {
models: {
'gpt-5.5': {
details: [
{
timestamp: '2026-03-03T10:00:00.000Z',
source: 'copilot-alias',
auth_index: 0,
tokens: {
input_tokens: 1_000_000,
output_tokens: 0,
reasoning_tokens: 0,
cached_tokens: 0,
total_tokens: 1_000_000,
},
failed: false,
},
],
},
},
},
'github-copilot': {
models: {
'gpt-5.5': {
details: [
{
timestamp: '2026-03-03T11:00:00.000Z',
source: 'copilot-canonical',
auth_index: 1,
tokens: {
input_tokens: 2_000_000,
output_tokens: 0,
reasoning_tokens: 0,
cached_tokens: 0,
total_tokens: 2_000_000,
},
failed: false,
},
],
},
},
},
},
},
};
const details = extractCliproxyUsageHistoryDetails(response);
expect(details.map((detail) => detail.provider)).toEqual([
'github-copilot',
'github-copilot',
]);
const [daily] = transformCliproxyToDailyUsage(response);
expect(daily.modelBreakdowns).toHaveLength(1);
expect(daily.modelBreakdowns[0]).toMatchObject({
modelName: 'gpt-5.5',
provider: 'github-copilot',
inputTokens: 3_000_000,
});
expect(daily.modelsUsed).toEqual(['gpt-5.5']);
});
});
});