mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-05-16 19:44:14 +00:00
feat(compare): add ModelStats type and aggregateModelStats
This commit is contained in:
parent
7cb1cf58bf
commit
9d119bfe40
2 changed files with 200 additions and 0 deletions
63
src/compare-stats.ts
Normal file
63
src/compare-stats.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import type { ProjectSummary } from './types.js'
|
||||
|
||||
export type ModelStats = {
|
||||
model: string
|
||||
calls: number
|
||||
cost: number
|
||||
outputTokens: number
|
||||
inputTokens: number
|
||||
cacheReadTokens: number
|
||||
cacheWriteTokens: number
|
||||
totalTurns: number
|
||||
editTurns: number
|
||||
oneShotTurns: number
|
||||
retries: number
|
||||
selfCorrections: number
|
||||
firstSeen: string
|
||||
lastSeen: string
|
||||
}
|
||||
|
||||
export function aggregateModelStats(projects: ProjectSummary[]): ModelStats[] {
|
||||
const byModel = new Map<string, ModelStats>()
|
||||
|
||||
const ensure = (model: string): ModelStats => {
|
||||
let s = byModel.get(model)
|
||||
if (!s) {
|
||||
s = { model, calls: 0, cost: 0, outputTokens: 0, inputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, totalTurns: 0, editTurns: 0, oneShotTurns: 0, retries: 0, selfCorrections: 0, firstSeen: '', lastSeen: '' }
|
||||
byModel.set(model, s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
for (const project of projects) {
|
||||
for (const session of project.sessions) {
|
||||
for (const turn of session.turns) {
|
||||
if (turn.assistantCalls.length === 0) continue
|
||||
const primaryModel = turn.assistantCalls[0]!.model
|
||||
if (primaryModel === '<synthetic>') continue
|
||||
|
||||
const ms = ensure(primaryModel)
|
||||
ms.totalTurns++
|
||||
if (turn.hasEdits) ms.editTurns++
|
||||
if (turn.hasEdits && turn.retries === 0) ms.oneShotTurns++
|
||||
ms.retries += turn.retries
|
||||
|
||||
for (const call of turn.assistantCalls) {
|
||||
if (call.model === '<synthetic>') continue
|
||||
const cs = call.model === primaryModel ? ms : ensure(call.model)
|
||||
cs.calls++
|
||||
cs.cost += call.costUSD
|
||||
cs.outputTokens += call.usage.outputTokens
|
||||
cs.inputTokens += call.usage.inputTokens
|
||||
cs.cacheReadTokens += call.usage.cacheReadInputTokens
|
||||
cs.cacheWriteTokens += call.usage.cacheCreationInputTokens
|
||||
|
||||
if (!cs.firstSeen || call.timestamp < cs.firstSeen) cs.firstSeen = call.timestamp
|
||||
if (!cs.lastSeen || call.timestamp > cs.lastSeen) cs.lastSeen = call.timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [...byModel.values()].sort((a, b) => b.cost - a.cost)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue