Skip to content

Commit 09003db

Browse files
asizikovCopilot
andcommitted
refactor: standardize AI credit naming
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d475794 commit 09003db

19 files changed

Lines changed: 166 additions & 171 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ The application expects CSV files with the following primary columns:
8484
- `aic_quantity` - AI Credits for the same usage row
8585
- `aic_gross_amount` - AI Credit gross cost for the same usage row
8686

87-
The viewer now supports both billing units. On `requests` rows, `quantity` and `applied_cost_per_quantity` drive PRU-based calculations, while `aic_quantity` and `aic_gross_amount` remain comparison values and stay `0` when those AI Credit fields are absent. On `ai-units` rows, Premium Requests and generic PRU gross/discount/net totals are counted as `0`; AI Credits are counted from the AI-specific credit fields (`aic_quantity`, falling back to `quantity` only when the AI field is absent) and AI Credit gross cost comes from `aic_gross_amount` (falling back to `gross_amount` only when the AI field is absent). Legacy `aiu_*` column names from older exports are still accepted during parsing, but they are no longer the documented format.
87+
The viewer now supports both billing units. On `requests` rows, `quantity` and `applied_cost_per_quantity` drive PRU-based calculations, while `aic_quantity` and `aic_gross_amount` remain comparison values and stay `0` when those AI Credit fields are absent. On `ai-units` rows, Premium Requests and generic PRU gross/discount/net totals are counted as `0`; AI Credits are counted from the AI-specific credit fields (`aic_quantity`, falling back to `quantity` only when the AI field is absent) and AI Credit gross cost comes from `aic_gross_amount` (falling back to `gross_amount` only when the AI field is absent).
8888

8989
See [docs/report-format.md](docs/report-format.md) for detailed format specifications.
9090

docs/report-format.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,3 @@ Source examples: files in `examples/`. Some existing sample exports still use th
3939
- The app streams the file, treats the first row as the header, and counts subsequent data rows without loading the entire file into memory.
4040
- Current calculations support both row types: on `requests` rows, `quantity` and `applied_cost_per_quantity` describe PRU usage while `aic_quantity` and `aic_gross_amount` remain reference/comparison values and stay `0` when those AI Credit fields are absent; on `ai-units` rows, Premium Requests and generic PRU gross/discount/net totals are counted as `0`, while AI Credits and AI Credit gross cost are taken from the AI-specific fields (`aic_quantity` / `aic_gross_amount`, with fallback to `quantity` / `gross_amount` only when those AI-specific fields are absent).
4141
- Reports without `aic_quantity` still load, but AI Credit summaries will display `0`.
42-
- Older exports that still use legacy `aiu_quantity` / `aiu_gross_amount` headers are accepted as parser fallbacks.

src/App.css

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@
435435
color: #6366f1;
436436
}
437437

438-
.aiu-callout {
438+
.aic-callout {
439439
font-size: 15px;
440440
font-weight: 700;
441441
background: #ffffff;
@@ -659,7 +659,7 @@
659659
color: #1f2328;
660660
}
661661

662-
.comparison-card__big-number--aiu {
662+
.comparison-card__big-number--aic {
663663
color: #2da44e;
664664
}
665665

@@ -1085,7 +1085,7 @@ td.cost-centers-view__num {
10851085
opacity: 0.7;
10861086
}
10871087

1088-
.products-view__legendSwatch--aiu {
1088+
.products-view__legendSwatch--aic {
10891089
background: #54aeff;
10901090
}
10911091

@@ -1156,7 +1156,7 @@ td.cost-centers-view__num {
11561156
background: rgba(207, 34, 46, 0.7);
11571157
}
11581158

1159-
.products-view__barFill--aiu {
1159+
.products-view__barFill--aic {
11601160
background: #54aeff;
11611161
}
11621162

@@ -1172,7 +1172,7 @@ td.cost-centers-view__num {
11721172
color: #cf222e;
11731173
}
11741174

1175-
.products-view__barValue--aiu {
1175+
.products-view__barValue--aic {
11761176
color: #0969da;
11771177
}
11781178

src/App.tsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ import { OrganizationAggregator, type OrganizationResult } from './pipeline/aggr
2020
import { UserUsageAggregator, type UserUsageResult } from './pipeline/aggregators/userUsageAggregator'
2121
import { runPipeline } from './pipeline/runPipeline'
2222
import { fillDataForRange } from './utils/fillDataForRange'
23-
import { formatAiu, formatUsd } from './utils/format'
23+
import { formatAic, formatUsd } from './utils/format'
2424

2525
type Status = 'idle' | 'processing' | 'done'
2626

2727
function createEmptyDailyUsage(date: string): DailyUsageData {
2828
return {
2929
date,
3030
requests: 0,
31-
aiuQuantity: 0,
31+
aicQuantity: 0,
3232
grossAmount: 0,
33-
aiuGrossAmount: 0,
33+
aicGrossAmount: 0,
3434
aicNetAmount: 0,
3535
discountAmount: 0,
3636
netAmount: 0,
@@ -190,24 +190,24 @@ function App() {
190190
const overviewTotals = dailyUsageData.reduce(
191191
(totals, day) => {
192192
totals.requests += day.requests
193-
totals.aiuQuantity += day.aiuQuantity
193+
totals.aicQuantity += day.aicQuantity
194194
totals.grossAmount += day.grossAmount
195-
totals.aiuGrossAmount += day.aiuGrossAmount
195+
totals.aicGrossAmount += day.aicGrossAmount
196196
totals.discountAmount += day.discountAmount
197197
totals.netAmount += day.netAmount
198198
return totals
199199
},
200-
{ requests: 0, aiuQuantity: 0, grossAmount: 0, aiuGrossAmount: 0, aicNetAmount: 0, discountAmount: 0, netAmount: 0 },
200+
{ requests: 0, aicQuantity: 0, grossAmount: 0, aicGrossAmount: 0, aicNetAmount: 0, discountAmount: 0, netAmount: 0 },
201201
)
202202

203203
const pooledAicCredits = (userUsage?.users ?? []).reduce((sum, user) => sum + getIncludedAicCredits(user.totalMonthlyQuota), 0)
204204

205205
const aicDiscountRate =
206-
overviewTotals.aiuQuantity > 0
207-
? Math.min(pooledAicCredits / overviewTotals.aiuQuantity, 1)
206+
overviewTotals.aicQuantity > 0
207+
? Math.min(pooledAicCredits / overviewTotals.aicQuantity, 1)
208208
: 0
209-
const aicDiscount = aicDiscountRate * overviewTotals.aiuGrossAmount
210-
const aicNetAmount = Math.max(overviewTotals.aiuGrossAmount - aicDiscount, 0)
209+
const aicDiscount = aicDiscountRate * overviewTotals.aicGrossAmount
210+
const aicNetAmount = Math.max(overviewTotals.aicGrossAmount - aicDiscount, 0)
211211

212212
return (
213213
<div className={`app ${hasReport ? 'app--review' : ''}`}>
@@ -392,7 +392,7 @@ function App() {
392392
<div className="context-banner">
393393
<h2 className="context-banner__title">GitHub Copilot is moving to token-based billing</h2>
394394
<p className="context-banner__body">
395-
Starting May 1, 2026, Copilot usage will be measured in AI Credits (AICs) instead of Premium Requests (PRUs). <strong className="aiu-callout">1 AIC = $0.01.</strong> This preview shows what your usage would look like under the new pricing.
395+
Starting May 1, 2026, Copilot usage will be measured in AI Credits (AICs) instead of Premium Requests (PRUs). <strong className="aic-callout">1 AIC = $0.01.</strong> This preview shows what your usage would look like under the new pricing.
396396
</p>
397397
{fileName && (
398398
<p className="context-banner__note">
@@ -445,13 +445,13 @@ function App() {
445445
</div>
446446
<div className="card comparison-card">
447447
<div className="comparison-card__label">Token-based billing (AICs)</div>
448-
<div className="comparison-card__big-number comparison-card__big-number--aiu">{formatUsd(aicNetAmount)}</div>
449-
<div className="comparison-card__period">{formatAiu(overviewTotals.aiuQuantity)} AICs</div>
448+
<div className="comparison-card__big-number comparison-card__big-number--aic">{formatUsd(aicNetAmount)}</div>
449+
<div className="comparison-card__period">{formatAic(overviewTotals.aicQuantity)} AICs</div>
450450
<div className="comparison-card__rate">1 AIC = $0.01</div>
451451
<div className="comparison-card__breakdown">
452452
<div className="comparison-card__breakdown-row">
453453
<span>Gross cost</span>
454-
<span>{formatUsd(overviewTotals.aiuGrossAmount)}</span>
454+
<span>{formatUsd(overviewTotals.aicGrossAmount)}</span>
455455
</div>
456456
<div className="comparison-card__breakdown-row comparison-card__breakdown-row--muted">
457457
<span>Included credits discount</span>
@@ -479,7 +479,7 @@ function App() {
479479
{
480480
label: 'AI Credits',
481481
color: '#22c55e',
482-
data: filledDailyUsageData.map((day) => day.aiuQuantity),
482+
data: filledDailyUsageData.map((day) => day.aicQuantity),
483483
yAxisID: 'y1',
484484
},
485485
]}
@@ -498,7 +498,7 @@ function App() {
498498
{
499499
label: 'AIC Gross Cost',
500500
color: '#54aeff',
501-
data: filledDailyUsageData.map((day) => day.aiuGrossAmount),
501+
data: filledDailyUsageData.map((day) => day.aicGrossAmount),
502502
yAxisID: 'y',
503503
},
504504
]}

src/pipeline/aggregators/costCenterAggregator.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ export type CostTotals = {
66
grossAmount: number
77
discountAmount: number
88
netAmount: number
9-
aiuQuantity: number
10-
aiuGrossAmount: number
9+
aicQuantity: number
10+
aicGrossAmount: number
1111
aicNetAmount: number
1212
}
1313

1414
export type CostCenterUserTotals = {
1515
requests: number
1616
grossAmount: number
1717
netAmount: number
18-
aiuQuantity: number
19-
aiuGrossAmount: number
18+
aicQuantity: number
19+
aicGrossAmount: number
2020
aicNetAmount: number
2121
}
2222

@@ -47,8 +47,8 @@ function createCostTotals(): CostTotals {
4747
grossAmount: 0,
4848
discountAmount: 0,
4949
netAmount: 0,
50-
aiuQuantity: 0,
51-
aiuGrossAmount: 0,
50+
aicQuantity: 0,
51+
aicGrossAmount: 0,
5252
aicNetAmount: 0,
5353
}
5454
}
@@ -64,7 +64,7 @@ function ensureTotals(map: Map<string, CostTotals>, key: string): CostTotals {
6464
function ensureUserTotals(map: Map<string, CostCenterUserTotals>, key: string): CostCenterUserTotals {
6565
const existing = map.get(key)
6666
if (existing) return existing
67-
const created: CostCenterUserTotals = { requests: 0, grossAmount: 0, netAmount: 0, aiuQuantity: 0, aiuGrossAmount: 0, aicNetAmount: 0 }
67+
const created: CostCenterUserTotals = { requests: 0, grossAmount: 0, netAmount: 0, aicQuantity: 0, aicGrossAmount: 0, aicNetAmount: 0 }
6868
map.set(key, created)
6969
return created
7070
}
@@ -97,32 +97,32 @@ export class CostCenterAggregator implements Aggregator<TokenUsageRecord, CostCe
9797

9898
if (username) costCenter.users.add(username)
9999

100-
const { requests, grossAmount, discountAmount, netAmount, aiuQuantity, aiuGrossAmount, aicNetAmount } = getUsageMetrics(record)
100+
const { requests, grossAmount, discountAmount, netAmount, aicQuantity, aicGrossAmount, aicNetAmount } = getUsageMetrics(record)
101101

102102
costCenter.totals.requests += requests
103103
costCenter.totals.grossAmount += grossAmount
104104
costCenter.totals.discountAmount += discountAmount
105105
costCenter.totals.netAmount += netAmount
106-
costCenter.totals.aiuQuantity += aiuQuantity
107-
costCenter.totals.aiuGrossAmount += aiuGrossAmount
106+
costCenter.totals.aicQuantity += aicQuantity
107+
costCenter.totals.aicGrossAmount += aicGrossAmount
108108
costCenter.totals.aicNetAmount += aicNetAmount
109109

110110
const byModel = ensureTotals(costCenter.totalsByModel, model)
111111
byModel.requests += requests
112112
byModel.grossAmount += grossAmount
113113
byModel.discountAmount += discountAmount
114114
byModel.netAmount += netAmount
115-
byModel.aiuQuantity += aiuQuantity
116-
byModel.aiuGrossAmount += aiuGrossAmount
115+
byModel.aicQuantity += aicQuantity
116+
byModel.aicGrossAmount += aicGrossAmount
117117
byModel.aicNetAmount += aicNetAmount
118118

119119
if (username) {
120120
const byUser = ensureUserTotals(costCenter.totalsByUser, username)
121121
byUser.requests += requests
122122
byUser.grossAmount += grossAmount
123123
byUser.netAmount += netAmount
124-
byUser.aiuQuantity += aiuQuantity
125-
byUser.aiuGrossAmount += aiuGrossAmount
124+
byUser.aicQuantity += aicQuantity
125+
byUser.aicGrossAmount += aicGrossAmount
126126
byUser.aicNetAmount += aicNetAmount
127127
}
128128
}

src/pipeline/aggregators/dailyUsageAggregator.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { getUsageMetrics, type TokenUsageRecord } from '../parser'
44
export interface DailyUsageData {
55
date: string
66
requests: number
7-
aiuQuantity: number
7+
aicQuantity: number
88
grossAmount: number
9-
aiuGrossAmount: number
9+
aicGrossAmount: number
1010
aicNetAmount: number
1111
discountAmount: number
1212
netAmount: number
@@ -25,13 +25,13 @@ export class DailyUsageAggregator implements Aggregator<TokenUsageRecord, DailyU
2525

2626
const existing = this.dataByDate.get(date)
2727

28-
const { requests, aiuQuantity, grossAmount, aiuGrossAmount, aicNetAmount, discountAmount, netAmount } = getUsageMetrics(record)
28+
const { requests, aicQuantity, grossAmount, aicGrossAmount, aicNetAmount, discountAmount, netAmount } = getUsageMetrics(record)
2929

3030
if (existing) {
3131
existing.requests += requests
32-
existing.aiuQuantity += aiuQuantity
32+
existing.aicQuantity += aicQuantity
3333
existing.grossAmount += grossAmount
34-
existing.aiuGrossAmount += aiuGrossAmount
34+
existing.aicGrossAmount += aicGrossAmount
3535
existing.aicNetAmount += aicNetAmount
3636
existing.discountAmount += discountAmount
3737
existing.netAmount += netAmount
@@ -41,9 +41,9 @@ export class DailyUsageAggregator implements Aggregator<TokenUsageRecord, DailyU
4141
this.dataByDate.set(date, {
4242
date,
4343
requests,
44-
aiuQuantity,
44+
aicQuantity,
4545
grossAmount,
46-
aiuGrossAmount,
46+
aicGrossAmount,
4747
aicNetAmount,
4848
discountAmount,
4949
netAmount,

src/pipeline/aggregators/modelUsageAggregator.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ import { getUsageMetrics, type TokenUsageHeader, type TokenUsageRecord } from '.
44
export type ModelDailyUsageData = {
55
date: string
66
requests: number
7-
aiuQuantity: number
7+
aicQuantity: number
88
grossAmount: number
9-
aiuGrossAmount: number
9+
aicGrossAmount: number
1010
aicNetAmount: number
1111
discountAmount: number
1212
netAmount: number
1313
}
1414

1515
export type ModelUsageTotals = {
1616
requests: number
17-
aiuQuantity: number
17+
aicQuantity: number
1818
grossAmount: number
19-
aiuGrossAmount: number
19+
aicGrossAmount: number
2020
aicNetAmount: number
2121
discountAmount: number
2222
netAmount: number
@@ -40,9 +40,9 @@ function ensureDay(model: ModelInternal, date: string): ModelDailyUsageData {
4040
const created: ModelDailyUsageData = {
4141
date,
4242
requests: 0,
43-
aiuQuantity: 0,
43+
aicQuantity: 0,
4444
grossAmount: 0,
45-
aiuGrossAmount: 0,
45+
aicGrossAmount: 0,
4646
aicNetAmount: 0,
4747
discountAmount: 0,
4848
netAmount: 0,
@@ -70,9 +70,9 @@ export class ModelUsageAggregator implements Aggregator<TokenUsageRecord, ModelU
7070
byDate: new Map(),
7171
totals: {
7272
requests: 0,
73-
aiuQuantity: 0,
73+
aicQuantity: 0,
7474
grossAmount: 0,
75-
aiuGrossAmount: 0,
75+
aicGrossAmount: 0,
7676
aicNetAmount: 0,
7777
discountAmount: 0,
7878
netAmount: 0,
@@ -81,21 +81,21 @@ export class ModelUsageAggregator implements Aggregator<TokenUsageRecord, ModelU
8181
this.byModel.set(modelName, model)
8282
}
8383

84-
const { requests, aiuQuantity, grossAmount, aiuGrossAmount, aicNetAmount, discountAmount, netAmount } = getUsageMetrics(record)
84+
const { requests, aicQuantity, grossAmount, aicGrossAmount, aicNetAmount, discountAmount, netAmount } = getUsageMetrics(record)
8585

8686
const day = ensureDay(model, date)
8787
day.requests += requests
88-
day.aiuQuantity += aiuQuantity
88+
day.aicQuantity += aicQuantity
8989
day.grossAmount += grossAmount
90-
day.aiuGrossAmount += aiuGrossAmount
90+
day.aicGrossAmount += aicGrossAmount
9191
day.aicNetAmount += aicNetAmount
9292
day.discountAmount += discountAmount
9393
day.netAmount += netAmount
9494

9595
model.totals.requests += requests
96-
model.totals.aiuQuantity += aiuQuantity
96+
model.totals.aicQuantity += aicQuantity
9797
model.totals.grossAmount += grossAmount
98-
model.totals.aiuGrossAmount += aiuGrossAmount
98+
model.totals.aicGrossAmount += aicGrossAmount
9999
model.totals.aicNetAmount += aicNetAmount
100100
model.totals.discountAmount += discountAmount
101101
model.totals.netAmount += netAmount

0 commit comments

Comments
 (0)