From 6fecd0c15b5171b662eae36b5af62bece387f2d9 Mon Sep 17 00:00:00 2001 From: "anthropic-code-agent[bot]" <242468646+Claude@users.noreply.github.com> Date: Thu, 9 Apr 2026 11:47:18 +0000 Subject: [PATCH 1/5] Fix cost calculations by removing duplicate multiplier application The CSV data already includes model multipliers in requestsUsed values. Fixed excessCost calculation in getModelUsageSummary and getExpectedExcessCost to not multiply by the multiplier again. Updated tests to reflect correct behavior. The multiplier is still displayed in the UI for informational purposes. Agent-Logs-Url: https://github.com/RHSplinter/github-copilot-premium-reqs-usage/sessions/7777403e-d7c3-4c8b-8f8e-ff51db24c81e Co-authored-by: RHSplinter <60773832+RHSplinter@users.noreply.github.com> --- src/lib/utils.ts | 10 +++++++--- src/test/model-info-limits.test.ts | 12 +++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 58a452f..410f858 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -251,7 +251,9 @@ export function getModelUsageSummary(data: CopilotUsageData[]): ModelUsageSummar } // Calculate excess cost - groupedSummary[key].excessCost = groupedSummary[key].exceedingRequests * groupedSummary[key].multiplier * EXCESS_REQUEST_COST; + // Note: requestsUsed in the CSV already includes the model multiplier, + // so we don't multiply by the multiplier again + groupedSummary[key].excessCost = groupedSummary[key].exceedingRequests * EXCESS_REQUEST_COST; }); // Convert to array and sort by total requests (descending) @@ -952,13 +954,15 @@ export function getExpectedExcessCost(data: CopilotUsageData[], plan: string = C const numDays = datesForAverage.length; - // Project extra requests per model over remaining days and apply cost multiplier + // Project extra requests per model over remaining days + // Note: requestsUsed in the CSV already includes the model multiplier, + // so we don't multiply by the multiplier again Object.entries(modelTotals).forEach(([model, total]) => { const multiplier = getModelMultiplier(model); if (multiplier === 0) return; // Free models have no cost const dailyAvg = total / numDays; const projectedExtra = dailyAvg * remainingDays; - totalExpectedCost += projectedExtra * multiplier * EXCESS_REQUEST_COST; + totalExpectedCost += projectedExtra * EXCESS_REQUEST_COST; }); }); diff --git a/src/test/model-info-limits.test.ts b/src/test/model-info-limits.test.ts index a5cf9f7..936ac65 100644 --- a/src/test/model-info-limits.test.ts +++ b/src/test/model-info-limits.test.ts @@ -98,14 +98,16 @@ describe('Model Info and Limits Feature', () => { expect(defaultGroup).toBeDefined(); if (defaultGroup) { - // 50 exceeding requests * 0x multiplier * $0.04 = $0.00 - expect(defaultGroup.excessCost).toBe(50 * 0 * EXCESS_REQUEST_COST); + // 50 exceeding requests * $0.04 = $2.00 + // Note: CSV requestsUsed already includes the multiplier + expect(defaultGroup.excessCost).toBe(50 * EXCESS_REQUEST_COST); } - + const o3Model = result.find(item => item.model === 'o3-mini-2025-01-31'); if (o3Model) { - // 10 exceeding requests * 0.33x multiplier * $0.04 = $0.132 - expect(o3Model.excessCost).toBe(10 * 0.33 * EXCESS_REQUEST_COST); + // 10 exceeding requests * $0.04 = $0.40 + // Note: CSV requestsUsed already includes the 0.33x multiplier + expect(o3Model.excessCost).toBe(10 * EXCESS_REQUEST_COST); } }); From 4b54487ce16a5f456d49c1f95b6ed8e23978032b Mon Sep 17 00:00:00 2001 From: Raymond Splinter Date: Thu, 9 Apr 2026 13:53:30 +0200 Subject: [PATCH 2/5] Remove notes --- src/lib/utils.ts | 4 ---- src/test/model-info-limits.test.ts | 2 -- 2 files changed, 6 deletions(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 410f858..fc93324 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -251,8 +251,6 @@ export function getModelUsageSummary(data: CopilotUsageData[]): ModelUsageSummar } // Calculate excess cost - // Note: requestsUsed in the CSV already includes the model multiplier, - // so we don't multiply by the multiplier again groupedSummary[key].excessCost = groupedSummary[key].exceedingRequests * EXCESS_REQUEST_COST; }); @@ -955,8 +953,6 @@ export function getExpectedExcessCost(data: CopilotUsageData[], plan: string = C const numDays = datesForAverage.length; // Project extra requests per model over remaining days - // Note: requestsUsed in the CSV already includes the model multiplier, - // so we don't multiply by the multiplier again Object.entries(modelTotals).forEach(([model, total]) => { const multiplier = getModelMultiplier(model); if (multiplier === 0) return; // Free models have no cost diff --git a/src/test/model-info-limits.test.ts b/src/test/model-info-limits.test.ts index 936ac65..4e0cd82 100644 --- a/src/test/model-info-limits.test.ts +++ b/src/test/model-info-limits.test.ts @@ -99,14 +99,12 @@ describe('Model Info and Limits Feature', () => { if (defaultGroup) { // 50 exceeding requests * $0.04 = $2.00 - // Note: CSV requestsUsed already includes the multiplier expect(defaultGroup.excessCost).toBe(50 * EXCESS_REQUEST_COST); } const o3Model = result.find(item => item.model === 'o3-mini-2025-01-31'); if (o3Model) { // 10 exceeding requests * $0.04 = $0.40 - // Note: CSV requestsUsed already includes the 0.33x multiplier expect(o3Model.excessCost).toBe(10 * EXCESS_REQUEST_COST); } }); From c252b7403c064e820aa538caa22b40e84512a4ff Mon Sep 17 00:00:00 2001 From: "anthropic-code-agent[bot]" <242468646+Claude@users.noreply.github.com> Date: Thu, 9 Apr 2026 12:03:12 +0000 Subject: [PATCH 3/5] Ensure excess costs for default models are always 0 Default models (with multiplier = 0) are free and should never incur excess costs, even when exceeding quota. Added check to ensure excessCost is 0 for models with multiplier = 0. Updated test to reflect this correct behavior. Agent-Logs-Url: https://github.com/RHSplinter/github-copilot-premium-reqs-usage/sessions/4b7fec75-998c-4d97-980b-8190a0d0b13c Co-authored-by: RHSplinter <60773832+RHSplinter@users.noreply.github.com> --- src/lib/utils.ts | 9 ++++++++- src/test/model-info-limits.test.ts | 6 ++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index fc93324..14ef5c0 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -251,7 +251,14 @@ export function getModelUsageSummary(data: CopilotUsageData[]): ModelUsageSummar } // Calculate excess cost - groupedSummary[key].excessCost = groupedSummary[key].exceedingRequests * EXCESS_REQUEST_COST; + // Note: requestsUsed in the CSV already includes the model multiplier, + // so we don't multiply by the multiplier again + // Free models (multiplier = 0) have no excess cost + if (groupedSummary[key].multiplier === 0) { + groupedSummary[key].excessCost = 0; + } else { + groupedSummary[key].excessCost = groupedSummary[key].exceedingRequests * EXCESS_REQUEST_COST; + } }); // Convert to array and sort by total requests (descending) diff --git a/src/test/model-info-limits.test.ts b/src/test/model-info-limits.test.ts index 4e0cd82..881e180 100644 --- a/src/test/model-info-limits.test.ts +++ b/src/test/model-info-limits.test.ts @@ -98,13 +98,15 @@ describe('Model Info and Limits Feature', () => { expect(defaultGroup).toBeDefined(); if (defaultGroup) { - // 50 exceeding requests * $0.04 = $2.00 - expect(defaultGroup.excessCost).toBe(50 * EXCESS_REQUEST_COST); + // Default models are free (multiplier = 0), so excess cost is always $0.00 + // even if there are exceeding requests + expect(defaultGroup.excessCost).toBe(0); } const o3Model = result.find(item => item.model === 'o3-mini-2025-01-31'); if (o3Model) { // 10 exceeding requests * $0.04 = $0.40 + // Note: CSV requestsUsed already includes the 0.33x multiplier expect(o3Model.excessCost).toBe(10 * EXCESS_REQUEST_COST); } }); From db8e5d7a1c53bc8f50536893402f40d7850abd7a Mon Sep 17 00:00:00 2001 From: Raymond Splinter Date: Thu, 9 Apr 2026 14:07:52 +0200 Subject: [PATCH 4/5] Remove notes --- src/lib/utils.ts | 2 -- src/test/model-info-limits.test.ts | 1 - 2 files changed, 3 deletions(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 14ef5c0..f874c47 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -251,8 +251,6 @@ export function getModelUsageSummary(data: CopilotUsageData[]): ModelUsageSummar } // Calculate excess cost - // Note: requestsUsed in the CSV already includes the model multiplier, - // so we don't multiply by the multiplier again // Free models (multiplier = 0) have no excess cost if (groupedSummary[key].multiplier === 0) { groupedSummary[key].excessCost = 0; diff --git a/src/test/model-info-limits.test.ts b/src/test/model-info-limits.test.ts index 881e180..3656811 100644 --- a/src/test/model-info-limits.test.ts +++ b/src/test/model-info-limits.test.ts @@ -106,7 +106,6 @@ describe('Model Info and Limits Feature', () => { const o3Model = result.find(item => item.model === 'o3-mini-2025-01-31'); if (o3Model) { // 10 exceeding requests * $0.04 = $0.40 - // Note: CSV requestsUsed already includes the 0.33x multiplier expect(o3Model.excessCost).toBe(10 * EXCESS_REQUEST_COST); } }); From f6800b6713572b03b05195b6b34191bb7ae37dbc Mon Sep 17 00:00:00 2001 From: Raymond Splinter Date: Thu, 9 Apr 2026 14:53:35 +0200 Subject: [PATCH 5/5] Added GPT-5 mini to default models --- src/lib/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index f874c47..c6e22d3 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -401,7 +401,7 @@ export const MODEL_MULTIPLIERS: Record = { }; // Default models that should be grouped -export const DEFAULT_MODELS = ['GPT-4o', 'GPT-4.1', 'gpt-4o-2024-11-20', 'gpt-4.1-2025-04-14']; +export const DEFAULT_MODELS = ['GPT-4o', 'GPT-4.1', 'GPT-5 mini', 'gpt-4o-2024-11-20', 'gpt-4.1-2025-04-14']; function normalizeModelName(model: string): string { return model.replace(/^Auto:\s*/, '').trim();