mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-04 05:41:29 +00:00
refactor(pricing): fan-out batch 1 — goose, mux, open-design, lingtai-tui, droid
This commit is contained in:
parent
34905db773
commit
0eb0c6f2da
7 changed files with 23 additions and 58 deletions
|
|
@ -3,7 +3,7 @@ import { join } from 'path'
|
|||
import { homedir } from 'os'
|
||||
|
||||
import { readSessionFile, readSessionLines } from '../fs-utils.js'
|
||||
import { calculateCost, getShortModelName } from '../models.js'
|
||||
import { getShortModelName } from '../models.js'
|
||||
import { extractBashCommands } from '../bash-utils.js'
|
||||
import { normalizeContentBlocks } from '../content-utils.js'
|
||||
import type {
|
||||
|
|
@ -255,15 +255,6 @@ function createParser(
|
|||
if (seenKeys.has(dedupKey)) continue
|
||||
seenKeys.add(dedupKey)
|
||||
|
||||
const costUSD = calculateCost(
|
||||
sessionModelDisplay.toLowerCase(),
|
||||
inputTokens,
|
||||
outputTokens + thinkingTokens,
|
||||
cacheCreationTokens,
|
||||
cacheReadTokens,
|
||||
0,
|
||||
)
|
||||
|
||||
// Use the call's timestamp, or session_start timestamp
|
||||
const timestamp = call.timestamp || ''
|
||||
|
||||
|
|
@ -277,7 +268,7 @@ function createParser(
|
|||
cachedInputTokens: cacheReadTokens,
|
||||
reasoningTokens: thinkingTokens,
|
||||
webSearchRequests: 0,
|
||||
costUSD,
|
||||
costBasis: 'estimated',
|
||||
tools: call.tools,
|
||||
bashCommands: call.bashCommands,
|
||||
timestamp,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { join } from 'path'
|
||||
import { homedir, platform } from 'os'
|
||||
|
||||
import { calculateCost, getShortModelName } from '../models.js'
|
||||
import { getShortModelName } from '../models.js'
|
||||
import { extractBashCommands } from '../bash-utils.js'
|
||||
import { isSqliteAvailable, getSqliteLoadError, openDatabase, blobToText, type SqliteDatabase } from '../sqlite.js'
|
||||
import type { ToolCall } from '../types.js'
|
||||
|
|
@ -190,7 +190,6 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
|
||||
const config = parseModelConfig(blobToText(session.model_config_json))
|
||||
const model = config.model_name ?? 'unknown'
|
||||
const costUSD = calculateCost(model, inputTokens, outputTokens, 0, 0, 0)
|
||||
|
||||
const { tools, bashCommands, toolSequence } = extractToolsFromMessages(db, sessionId)
|
||||
const userMessage = getFirstUserMessage(db, sessionId)
|
||||
|
|
@ -210,7 +209,7 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
cachedInputTokens: 0,
|
||||
reasoningTokens: 0,
|
||||
webSearchRequests: 0,
|
||||
costUSD,
|
||||
costBasis: 'estimated',
|
||||
tools,
|
||||
bashCommands,
|
||||
toolSequence: toolSequence.length > 1 ? toolSequence : undefined,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { basename, delimiter, dirname, join, resolve } from 'path'
|
|||
import { homedir } from 'os'
|
||||
|
||||
import { readSessionLines } from '../fs-utils.js'
|
||||
import { calculateCost, getShortModelName } from '../models.js'
|
||||
import { getShortModelName } from '../models.js'
|
||||
import type { ParsedProviderCall, Provider, SessionParser, SessionSource } from './types.js'
|
||||
|
||||
type JsonObject = Record<string, unknown>
|
||||
|
|
@ -366,15 +366,6 @@ function createParser(source: SessionSource): SessionParser {
|
|||
cachedInputTokens,
|
||||
].join(':')
|
||||
|
||||
const costUSD = calculateCost(
|
||||
model,
|
||||
inputTokens,
|
||||
outputTokens + reasoningTokens,
|
||||
0,
|
||||
cachedInputTokens,
|
||||
0,
|
||||
)
|
||||
|
||||
yield {
|
||||
provider: 'lingtai-tui',
|
||||
model,
|
||||
|
|
@ -385,7 +376,7 @@ function createParser(source: SessionSource): SessionParser {
|
|||
cachedInputTokens,
|
||||
reasoningTokens,
|
||||
webSearchRequests: 0,
|
||||
costUSD,
|
||||
costBasis: 'estimated',
|
||||
tools: activity.tools,
|
||||
bashCommands: [],
|
||||
subagentTypes: activity.subagentTypes,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { basename, dirname, join, resolve } from 'path'
|
|||
import { homedir } from 'os'
|
||||
|
||||
import { readSessionLines } from '../fs-utils.js'
|
||||
import { calculateCost, getShortModelName } from '../models.js'
|
||||
import { getShortModelName } from '../models.js'
|
||||
import { extractBashCommands } from '../bash-utils.js'
|
||||
import type { Provider, SessionSource, SessionParser, ParsedProviderCall } from './types.js'
|
||||
import { safeNumber } from '../parser.js'
|
||||
|
|
@ -217,15 +217,6 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
return typeof script === 'string' ? extractBashCommands(script) : []
|
||||
})
|
||||
|
||||
const costUSD = calculateCost(
|
||||
model,
|
||||
inputTokens,
|
||||
outputTokens + reasoning,
|
||||
cacheCreate,
|
||||
cacheRead,
|
||||
0,
|
||||
)
|
||||
|
||||
const timestamp = toIsoTimestamp(meta.timestamp, msg.createdAt)
|
||||
|
||||
yield {
|
||||
|
|
@ -238,7 +229,7 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
cachedInputTokens: cacheRead,
|
||||
reasoningTokens: reasoning,
|
||||
webSearchRequests: 0,
|
||||
costUSD,
|
||||
costBasis: 'estimated',
|
||||
tools,
|
||||
bashCommands,
|
||||
timestamp,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { basename, dirname, join } from 'path'
|
|||
import { homedir, platform } from 'os'
|
||||
|
||||
import { readSessionLines } from '../fs-utils.js'
|
||||
import { calculateCost } from '../models.js'
|
||||
import type { Provider, SessionSource, SessionParser, ParsedProviderCall } from './types.js'
|
||||
|
||||
const PROVIDER_NAME = 'open-design'
|
||||
|
|
@ -199,14 +198,6 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
seenKeys.add(dedupKey)
|
||||
|
||||
const uncachedInputTokens = Math.max(0, usage.inputTokens - usage.cacheReadTokens)
|
||||
const costUSD = calculateCost(
|
||||
currentModel,
|
||||
uncachedInputTokens,
|
||||
usage.outputTokens + usage.reasoningTokens,
|
||||
0,
|
||||
usage.cacheReadTokens,
|
||||
0,
|
||||
)
|
||||
|
||||
yield {
|
||||
provider: PROVIDER_NAME,
|
||||
|
|
@ -220,7 +211,7 @@ function createParser(source: SessionSource, seenKeys: Set<string>): SessionPars
|
|||
cachedInputTokens: usage.cacheReadTokens,
|
||||
reasoningTokens: usage.reasoningTokens,
|
||||
webSearchRequests: 0,
|
||||
costUSD,
|
||||
costBasis: 'estimated',
|
||||
tools: [],
|
||||
bashCommands: [],
|
||||
timestamp: timestampValue(entry.timestamp),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { tmpdir } from 'os'
|
|||
|
||||
import { createMuxProvider } from '../../src/providers/mux.js'
|
||||
import type { ParsedProviderCall } from '../../src/providers/types.js'
|
||||
import { priceProviderCall } from '../../src/pricing-pass.js'
|
||||
|
||||
let tmpDir: string
|
||||
|
||||
|
|
@ -187,7 +188,7 @@ describe('mux provider - session discovery', () => {
|
|||
const sessions = await provider.discoverSessions()
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for (const source of sessions) {
|
||||
for await (const call of provider.createSessionParser(source, seenKeys).parse()) calls.push(call)
|
||||
for await (const call of provider.createSessionParser(source, seenKeys).parse()) calls.push(priceProviderCall(call))
|
||||
}
|
||||
|
||||
expect(calls).toHaveLength(2)
|
||||
|
|
@ -217,7 +218,7 @@ describe('mux provider - chat.jsonl parsing', () => {
|
|||
const source = { path: filePath, project: 'myproject', provider: 'mux' }
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) {
|
||||
calls.push(call)
|
||||
calls.push(priceProviderCall(call))
|
||||
}
|
||||
|
||||
expect(calls).toHaveLength(1)
|
||||
|
|
@ -253,7 +254,7 @@ describe('mux provider - chat.jsonl parsing', () => {
|
|||
const source = { path: filePath, project: 'myproject', provider: 'mux' }
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) {
|
||||
calls.push(call)
|
||||
calls.push(priceProviderCall(call))
|
||||
}
|
||||
|
||||
expect(calls[0]!.tools).toEqual(['Read', 'Edit', 'Bash'])
|
||||
|
|
@ -274,7 +275,7 @@ describe('mux provider - chat.jsonl parsing', () => {
|
|||
const source = { path: filePath, project: 'myproject', provider: 'mux' }
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) {
|
||||
calls.push(call)
|
||||
calls.push(priceProviderCall(call))
|
||||
}
|
||||
expect(calls).toHaveLength(0)
|
||||
})
|
||||
|
|
@ -288,7 +289,7 @@ describe('mux provider - chat.jsonl parsing', () => {
|
|||
const source = { path: filePath, project: 'myproject', provider: 'mux' }
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) {
|
||||
calls.push(call)
|
||||
calls.push(priceProviderCall(call))
|
||||
}
|
||||
expect(calls).toHaveLength(0)
|
||||
})
|
||||
|
|
@ -301,9 +302,9 @@ describe('mux provider - chat.jsonl parsing', () => {
|
|||
const seenKeys = new Set<string>()
|
||||
|
||||
const first: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, seenKeys).parse()) first.push(call)
|
||||
for await (const call of provider.createSessionParser(source, seenKeys).parse()) first.push(priceProviderCall(call))
|
||||
const second: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, seenKeys).parse()) second.push(call)
|
||||
for await (const call of provider.createSessionParser(source, seenKeys).parse()) second.push(priceProviderCall(call))
|
||||
|
||||
expect(first).toHaveLength(1)
|
||||
expect(second).toHaveLength(0)
|
||||
|
|
@ -320,7 +321,7 @@ describe('mux provider - chat.jsonl parsing', () => {
|
|||
const provider = createMuxProvider(tmpDir)
|
||||
const source = { path: filePath, project: 'myproject', provider: 'mux' }
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) calls.push(call)
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) calls.push(priceProviderCall(call))
|
||||
|
||||
expect(calls).toHaveLength(2)
|
||||
expect(calls[0]!.userMessage).toBe('first question')
|
||||
|
|
@ -333,7 +334,7 @@ describe('mux provider - chat.jsonl parsing', () => {
|
|||
const provider = createMuxProvider(tmpDir)
|
||||
const source = { path: join(tmpDir, 'sessions', 'nope', 'chat.jsonl'), project: 'x', provider: 'mux' }
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) calls.push(call)
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) calls.push(priceProviderCall(call))
|
||||
expect(calls).toHaveLength(0)
|
||||
})
|
||||
|
||||
|
|
@ -350,7 +351,7 @@ describe('mux provider - chat.jsonl parsing', () => {
|
|||
const provider = createMuxProvider(tmpDir)
|
||||
const source = { path: filePath, project: 'p', provider: 'mux' }
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) calls.push(call)
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) calls.push(priceProviderCall(call))
|
||||
|
||||
expect(calls).toHaveLength(2)
|
||||
expect(new Set(calls.map(c => c.deduplicationKey)).size).toBe(2)
|
||||
|
|
@ -368,7 +369,7 @@ describe('mux provider - chat.jsonl parsing', () => {
|
|||
const provider = createMuxProvider(tmpDir)
|
||||
const source = { path: filePath, project: 'p', provider: 'mux' }
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) calls.push(call)
|
||||
for await (const call of provider.createSessionParser(source, new Set()).parse()) calls.push(priceProviderCall(call))
|
||||
|
||||
expect(calls).toHaveLength(3) // none of the malformed lines aborted the parse
|
||||
expect(calls.find(c => c.deduplicationKey === 'mux:ws-abc:good')?.inputTokens).toBe(100)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { clearSessionCache, filterProjectsByDateRange, parseAllSessions } from '
|
|||
import { allProviderNames } from '../../src/providers/index.js'
|
||||
import { createOpenDesignProvider } from '../../src/providers/open-design.js'
|
||||
import type { ParsedProviderCall, SessionSource } from '../../src/providers/types.js'
|
||||
import { priceProviderCall } from '../../src/pricing-pass.js'
|
||||
|
||||
const fixtureRoot = join(import.meta.dirname, '../fixtures/open-design')
|
||||
const dataDir = join(fixtureRoot, 'namespaces', 'release-stable', 'data')
|
||||
|
|
@ -19,7 +20,7 @@ let cacheDir: string | undefined
|
|||
async function collect(source: SessionSource, seenKeys = new Set<string>()): Promise<ParsedProviderCall[]> {
|
||||
const provider = createOpenDesignProvider()
|
||||
const calls: ParsedProviderCall[] = []
|
||||
for await (const call of provider.createSessionParser(source, seenKeys).parse()) calls.push(call)
|
||||
for await (const call of provider.createSessionParser(source, seenKeys).parse()) calls.push(priceProviderCall(call))
|
||||
return calls
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue