mirror of
https://github.com/stablyai/orca.git
synced 2026-09-23 00:02:29 +00:00
fix: track Claude Opus 4.8 usage pricing (#4681)
This commit is contained in:
@@ -210,6 +210,53 @@ describe('ClaudeUsageStore', () => {
|
||||
).toBeCloseTo(36.75)
|
||||
})
|
||||
|
||||
it('prices Claude Opus 4.8 with current Anthropic rates', async () => {
|
||||
const store = createStoreWithState({
|
||||
dailyAggregates: [
|
||||
{
|
||||
day: '2026-04-09',
|
||||
model: 'anthropic/claude-opus-4-8-20260528',
|
||||
projectKey: 'worktree:repo-1::/workspace/repo-a',
|
||||
projectLabel: 'Repo A',
|
||||
repoId: 'repo-1',
|
||||
worktreeId: 'repo-1::/workspace/repo-a',
|
||||
turnCount: 1,
|
||||
zeroCacheReadTurnCount: 0,
|
||||
inputTokens: 1_000_000,
|
||||
outputTokens: 1_000_000,
|
||||
cacheReadTokens: 1_000_000,
|
||||
cacheWriteTokens: 1_000_000
|
||||
},
|
||||
{
|
||||
day: '2026-04-09',
|
||||
model: 'claude-opus-4.8-20260528',
|
||||
projectKey: 'worktree:repo-1::/workspace/repo-a',
|
||||
projectLabel: 'Repo A',
|
||||
repoId: 'repo-1',
|
||||
worktreeId: 'repo-1::/workspace/repo-a',
|
||||
turnCount: 1,
|
||||
zeroCacheReadTurnCount: 0,
|
||||
inputTokens: 1_000_000,
|
||||
outputTokens: 1_000_000,
|
||||
cacheReadTokens: 1_000_000,
|
||||
cacheWriteTokens: 1_000_000
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const summary = await store.getSummary('orca', '30d')
|
||||
const breakdown = await store.getBreakdown('orca', '30d', 'model')
|
||||
|
||||
expect(summary.estimatedCostUsd).toBeCloseTo(73.5)
|
||||
expect(
|
||||
breakdown.find((row) => row.key === 'anthropic/claude-opus-4-8-20260528')
|
||||
?.estimatedCostUsd
|
||||
).toBeCloseTo(36.75)
|
||||
expect(
|
||||
breakdown.find((row) => row.key === 'claude-opus-4.8-20260528')?.estimatedCostUsd
|
||||
).toBeCloseTo(36.75)
|
||||
})
|
||||
|
||||
it('does not collapse older Opus 4.1 usage into current Opus 4.7 pricing', async () => {
|
||||
const store = createStoreWithState({
|
||||
dailyAggregates: [
|
||||
|
||||
@@ -56,6 +56,7 @@ const SONNET_LONG_CONTEXT_PRICING = {
|
||||
} satisfies Partial<ClaudeModelPricing>
|
||||
|
||||
const MODEL_PRICING: Record<string, ClaudeModelPricing> = {
|
||||
'claude-opus-4-8': { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
|
||||
'claude-opus-4-7': { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
|
||||
'claude-opus-4-6': { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
|
||||
'claude-opus-4-5': { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
|
||||
@@ -92,10 +93,13 @@ const MODEL_PRICING: Record<string, ClaudeModelPricing> = {
|
||||
const MODEL_ALIASES: Record<string, string> = {
|
||||
model_placeholder_m26: 'claude-opus-4-6',
|
||||
model_placeholder_m35: 'claude-sonnet-4-6',
|
||||
'claude-opus-4.8': 'claude-opus-4-8',
|
||||
'claude-opus-4.6': 'claude-opus-4-6',
|
||||
'claude-sonnet-4.6': 'claude-sonnet-4-6',
|
||||
'claude-opus-4.8-thinking': 'claude-opus-4-8',
|
||||
'claude-opus-4.6-thinking': 'claude-opus-4-6',
|
||||
'claude-sonnet-4.6-thinking': 'claude-sonnet-4-6',
|
||||
'claude-opus-4-8-thinking': 'claude-opus-4-8',
|
||||
'claude-opus-4-6-thinking': 'claude-opus-4-6',
|
||||
'claude-sonnet-4-6-thinking': 'claude-sonnet-4-6'
|
||||
}
|
||||
@@ -139,6 +143,9 @@ function normalizeModelForPricing(model: string | null): string | null {
|
||||
if (alias) {
|
||||
return alias
|
||||
}
|
||||
if (lower.includes('opus-4-8') || lower.includes('opus-4.8')) {
|
||||
return 'claude-opus-4-8'
|
||||
}
|
||||
if (lower.includes('opus-4-7')) {
|
||||
return 'claude-opus-4-7'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user