mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
Normalize OpenCode cache reads and writes consistently across usage views, persistence and telemetry. Continues #20187. Co-authored-by: griffinmartin <griffinmartin@users.noreply.github.com>
102 lines
3.5 KiB
TypeScript
102 lines
3.5 KiB
TypeScript
import { mkdtempSync, realpathSync, rmSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { expect, it } from 'vitest'
|
|
import { codexOpenCodeTokenSessions } from '../usage/agent-token-usage'
|
|
import { createUsageWorktreeResolver } from '../usage/usage-worktree-resolver'
|
|
import { getDefaultState, normalizePersistedState } from './persisted-state-normalization'
|
|
import { writeOpenCodeUsageDatabase } from './opencode-usage-sqlite-fixture'
|
|
import { parseOpenCodeUsageDatabase } from './scanner'
|
|
import { parseOpenCodeUsageRow } from './opencode-usage-row-parsing'
|
|
|
|
it.each([
|
|
{ input: 638, read: 642944, write: 1024, total: 644706 },
|
|
{ input: 0, read: 0, write: 1024, total: 1124 }
|
|
])(
|
|
'preserves cache writes and uncached input in $total tokens',
|
|
({ input, read, write, total }) => {
|
|
const parsed = parseOpenCodeUsageRow({
|
|
id: 'cache-write-message',
|
|
session_id: 'cache-write-session',
|
|
time_created: 1_777_777_700_000,
|
|
time_updated: null,
|
|
directory: null,
|
|
title: null,
|
|
worktree: null,
|
|
session_model: null,
|
|
data: JSON.stringify({
|
|
tokens: { input, output: 100, reasoning: 0, total, cache: { read, write } }
|
|
})
|
|
})
|
|
expect(parsed).toMatchObject({
|
|
inputTokens: input + read + write,
|
|
cachedInputTokens: read + write,
|
|
cacheWriteInputTokens: write,
|
|
outputTokens: 100,
|
|
totalTokens: total
|
|
})
|
|
expect((parsed?.inputTokens ?? 0) - (parsed?.cachedInputTokens ?? 0)).toBe(input)
|
|
}
|
|
)
|
|
|
|
it.each(['v1', 'v2-only'] as const)(
|
|
'preserves separate cache read and write telemetry after %s aggregation and reload',
|
|
async (generation) => {
|
|
const directory = realpathSync(mkdtempSync(join(tmpdir(), 'orca-cache-buckets-')))
|
|
try {
|
|
const path = join(directory, 'opencode.db')
|
|
const sessions = [
|
|
{
|
|
id: 'cache-session',
|
|
directory,
|
|
tokensInput: 638,
|
|
tokensOutput: 100,
|
|
tokensCacheRead: 642944,
|
|
tokensCacheWrite: 1024
|
|
}
|
|
]
|
|
writeOpenCodeUsageDatabase(path, {
|
|
generation,
|
|
legacySessions: sessions,
|
|
v2Sessions: sessions,
|
|
worktree: directory
|
|
})
|
|
const resolver = await createUsageWorktreeResolver([
|
|
{
|
|
repoId: 'repo',
|
|
worktreeId: 'folder',
|
|
path: directory,
|
|
displayName: 'Repo'
|
|
}
|
|
])
|
|
const database = await parseOpenCodeUsageDatabase(path, resolver)
|
|
const state = normalizePersistedState({
|
|
...getDefaultState(),
|
|
processedDatabases: [structuredClone(database)],
|
|
sessions: structuredClone(database.sessions),
|
|
dailyAggregates: structuredClone(database.dailyAggregates)
|
|
})
|
|
expect(state.dailyAggregates[0]).toMatchObject({
|
|
inputTokens: 644606,
|
|
cachedInputTokens: 643968,
|
|
cacheWriteInputTokens: 1024
|
|
})
|
|
expect(state.sessions[0]?.modelBreakdown[0]?.cacheWriteInputTokens).toBe(1024)
|
|
expect(state.sessions[0]?.locationModelBreakdown[0]?.cacheWriteInputTokens).toBe(1024)
|
|
for (const sessions of [state.sessions, state.processedDatabases[0]?.sessions ?? []]) {
|
|
expect(codexOpenCodeTokenSessions(sessions)).toEqual([
|
|
{
|
|
providerSessionId: 'cache-session',
|
|
input_tokens: 638,
|
|
output_tokens: 100,
|
|
cached_input_tokens: 642944,
|
|
cache_write_input_tokens: 1024
|
|
}
|
|
])
|
|
}
|
|
} finally {
|
|
rmSync(directory, { recursive: true, force: true })
|
|
}
|
|
}
|
|
)
|