mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-04 05:41:29 +00:00
Merge pull request #817 from getagentseal/phase0/kimi-batch3
refactor(pricing): fan-out — openclaw, crush
This commit is contained in:
commit
6552b10bd8
4 changed files with 18 additions and 20 deletions
|
|
@ -2,7 +2,6 @@ import { readFile } from 'fs/promises'
|
|||
import { join, resolve } from 'path'
|
||||
import { homedir, platform } from 'os'
|
||||
|
||||
import { calculateCost } from '../models.js'
|
||||
import { isSqliteAvailable, getSqliteLoadError, openDatabase, type SqliteDatabase } from '../sqlite.js'
|
||||
import type { Provider, SessionSource, SessionParser, ParsedProviderCall } from './types.js'
|
||||
|
||||
|
|
@ -165,10 +164,7 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
|
||||
const model = dominantModel(db, sessionId)
|
||||
// Crush already records cost in dollars; trust it. Fall back to
|
||||
// pricing-table calculation only when the row is missing a cost.
|
||||
const costUSD = cost > 0
|
||||
? cost
|
||||
: calculateCost(model, inputTokens, outputTokens, 0, 0, 0)
|
||||
// host-side pricing-table calculation only when the row is missing a cost.
|
||||
|
||||
yield {
|
||||
provider: 'crush',
|
||||
|
|
@ -180,7 +176,9 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
cachedInputTokens: 0,
|
||||
reasoningTokens: 0,
|
||||
webSearchRequests: 0,
|
||||
costUSD,
|
||||
...(cost > 0
|
||||
? { costUSD: cost, costBasis: 'measured' as const }
|
||||
: { costBasis: 'estimated' as const }),
|
||||
tools: [],
|
||||
bashCommands: [],
|
||||
timestamp: epochSecondsToIso(session.updated_at ?? session.created_at),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { basename, join } from 'path'
|
|||
import { homedir } from 'os'
|
||||
|
||||
import { readSessionFile } from '../fs-utils.js'
|
||||
import { calculateCost } from '../models.js'
|
||||
import { extractBashCommands } from '../bash-utils.js'
|
||||
import type { Provider, SessionSource, SessionParser, ParsedProviderCall } from './types.js'
|
||||
|
||||
|
|
@ -172,9 +171,6 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
|
||||
const u = call.usage
|
||||
const costFromProvider = u.cost?.total ?? 0
|
||||
const costUSD = costFromProvider > 0
|
||||
? costFromProvider
|
||||
: calculateCost(call.model, u.input, u.output, u.cacheWrite, u.cacheRead, 0)
|
||||
|
||||
const ts = new Date(call.timestamp)
|
||||
if (isNaN(ts.getTime()) || ts.getTime() < 1_000_000_000_000) continue
|
||||
|
|
@ -189,7 +185,9 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
cachedInputTokens: u.cacheRead,
|
||||
reasoningTokens: 0,
|
||||
webSearchRequests: 0,
|
||||
costUSD,
|
||||
...(costFromProvider > 0
|
||||
? { costUSD: costFromProvider, costBasis: 'measured' as const }
|
||||
: { costBasis: 'estimated' as const }),
|
||||
tools: [...new Set(call.tools)],
|
||||
bashCommands: [...new Set(call.bashCommands)],
|
||||
timestamp: ts.toISOString(),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { tmpdir } from 'os'
|
|||
import { createRequire } from 'node:module'
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
||||
import { priceProviderCall } from '../../src/pricing-pass.js'
|
||||
import { isSqliteAvailable } from '../../src/sqlite.js'
|
||||
import { createCrushProvider } from '../../src/providers/crush.js'
|
||||
import type { ParsedProviderCall } from '../../src/providers/types.js'
|
||||
|
|
@ -123,7 +124,7 @@ async function writeRegistry(globalDataDir: string, entries: Record<string, { pa
|
|||
|
||||
async function collect(parser: { parse(): AsyncGenerator<ParsedProviderCall> }): Promise<ParsedProviderCall[]> {
|
||||
const out: ParsedProviderCall[] = []
|
||||
for await (const call of parser.parse()) out.push(call)
|
||||
for await (const call of parser.parse()) out.push(priceProviderCall(call))
|
||||
return out
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { describe, it, expect, afterAll } from 'vitest'
|
||||
import { priceProviderCall } from '../../src/pricing-pass.js'
|
||||
import { createOpenClawProvider } from '../../src/providers/openclaw.js'
|
||||
import { writeFile, mkdir, rm } from 'fs/promises'
|
||||
import { join } from 'path'
|
||||
|
|
@ -63,7 +64,7 @@ describe('openclaw provider', () => {
|
|||
const parser = provider.createSessionParser(sources[0], new Set())
|
||||
const calls: any[] = []
|
||||
for await (const call of parser.parse()) {
|
||||
calls.push(call)
|
||||
calls.push(priceProviderCall(call))
|
||||
}
|
||||
expect(calls.length).toBe(2)
|
||||
expect(calls[0].provider).toBe('openclaw')
|
||||
|
|
@ -82,7 +83,7 @@ describe('openclaw provider', () => {
|
|||
const sources = await provider.discoverSessions()
|
||||
const parser = provider.createSessionParser(sources[0], new Set())
|
||||
const calls: any[] = []
|
||||
for await (const call of parser.parse()) calls.push(call)
|
||||
for await (const call of parser.parse()) calls.push(priceProviderCall(call))
|
||||
expect(calls[1].costUSD).toBe(0.05)
|
||||
})
|
||||
|
||||
|
|
@ -93,7 +94,7 @@ describe('openclaw provider', () => {
|
|||
const sources = await provider.discoverSessions()
|
||||
const parser = provider.createSessionParser(sources[0], new Set())
|
||||
const calls: any[] = []
|
||||
for await (const call of parser.parse()) calls.push(call)
|
||||
for await (const call of parser.parse()) calls.push(priceProviderCall(call))
|
||||
expect(calls[1].tools).toContain('Bash')
|
||||
expect(calls[1].tools).toContain('Read')
|
||||
expect(calls[1].tools).toContain('Write')
|
||||
|
|
@ -108,11 +109,11 @@ describe('openclaw provider', () => {
|
|||
const seen = new Set<string>()
|
||||
const parser1 = provider.createSessionParser(sources[0], seen)
|
||||
const calls1: any[] = []
|
||||
for await (const c of parser1.parse()) calls1.push(c)
|
||||
for await (const c of parser1.parse()) calls1.push(priceProviderCall(c))
|
||||
expect(calls1.length).toBe(2)
|
||||
const parser2 = provider.createSessionParser(sources[0], seen)
|
||||
const calls2: any[] = []
|
||||
for await (const c of parser2.parse()) calls2.push(c)
|
||||
for await (const c of parser2.parse()) calls2.push(priceProviderCall(c))
|
||||
expect(calls2.length).toBe(0)
|
||||
})
|
||||
|
||||
|
|
@ -131,7 +132,7 @@ describe('openclaw provider', () => {
|
|||
const sources = await provider.discoverSessions()
|
||||
const parser = provider.createSessionParser(sources[0], new Set())
|
||||
const calls: any[] = []
|
||||
for await (const c of parser.parse()) calls.push(c)
|
||||
for await (const c of parser.parse()) calls.push(priceProviderCall(c))
|
||||
expect(calls[0].model).toBe('gpt-5.5')
|
||||
})
|
||||
|
||||
|
|
@ -150,7 +151,7 @@ describe('openclaw provider', () => {
|
|||
const sources = await provider.discoverSessions()
|
||||
const parser = provider.createSessionParser(sources[0], new Set())
|
||||
const calls: any[] = []
|
||||
for await (const c of parser.parse()) calls.push(c)
|
||||
for await (const c of parser.parse()) calls.push(priceProviderCall(c))
|
||||
expect(calls[0].model).toBe('glm-5.1:cloud')
|
||||
})
|
||||
|
||||
|
|
@ -168,7 +169,7 @@ describe('openclaw provider', () => {
|
|||
const sources = await provider.discoverSessions()
|
||||
const parser = provider.createSessionParser(sources[0], new Set())
|
||||
const calls: any[] = []
|
||||
for await (const c of parser.parse()) calls.push(c)
|
||||
for await (const c of parser.parse()) calls.push(priceProviderCall(c))
|
||||
expect(calls.length).toBe(0)
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue