fix(opencode): include cache read and write usage totals

This commit is contained in:
Neil
2026-09-20 20:58:17 -07:00
parent 169bccc544
commit 2e41c6be0a
2 changed files with 35 additions and 11 deletions
@@ -27,6 +27,7 @@ type OpenCodeSessionUsageRow = {
tokens_output: number
tokens_reasoning: number
tokens_cache_read: number
tokens_cache_write: number
}
function getProjectJoin(db: Database.Database): string {
@@ -61,6 +62,17 @@ function canReadSessionUsageRows(db: Database.Database): boolean {
)
}
function getSessionCacheWriteSelect(db: Database.Database): string {
return columnExists(db, 'session', 'tokens_cache_write') ? 's.tokens_cache_write' : '0'
}
function getSessionTokenTotalExpression(db: Database.Database): string {
const cacheWrite = columnExists(db, 'session', 'tokens_cache_write')
? ' + tokens_cache_write'
: ''
return `tokens_input + tokens_output + tokens_reasoning + tokens_cache_read${cacheWrite}`
}
function getSessionUsageRowCount(db: Database.Database): number {
if (!canReadSessionUsageRows(db)) {
return 0
@@ -69,7 +81,7 @@ function getSessionUsageRowCount(db: Database.Database): number {
.prepare(
`SELECT COUNT(*) AS count
FROM session
WHERE tokens_input + tokens_output + tokens_reasoning + tokens_cache_read > 0`
WHERE ${getSessionTokenTotalExpression(db)} > 0`
)
.get() as { count?: number } | undefined
return row?.count ?? 0
@@ -78,14 +90,17 @@ function getSessionUsageRowCount(db: Database.Database): number {
function selectSessionUsageRows(db: Database.Database): OpenCodeUsageRow[] {
const projectJoin = getProjectJoin(db)
const sessionModelSelect = getSessionModelSelect(db)
const cacheWriteSelect = getSessionCacheWriteSelect(db)
const tokenTotalExpression = getSessionTokenTotalExpression(db)
const rows = db
.prepare(
`SELECT s.id, s.id AS session_id, s.time_created, s.time_updated,
s.directory, s.title, p.worktree, ${sessionModelSelect},
s.cost, s.tokens_input, s.tokens_output, s.tokens_reasoning, s.tokens_cache_read
s.cost, s.tokens_input, s.tokens_output, s.tokens_reasoning, s.tokens_cache_read,
${cacheWriteSelect} AS tokens_cache_write
FROM session s
${projectJoin}
WHERE s.tokens_input + s.tokens_output + s.tokens_reasoning + s.tokens_cache_read > 0
WHERE ${tokenTotalExpression.replaceAll('tokens_', 's.tokens_')} > 0
ORDER BY s.time_created, s.id`
)
.all() as OpenCodeSessionUsageRow[]
@@ -105,10 +120,15 @@ function selectSessionUsageRows(db: Database.Database): OpenCodeUsageRow[] {
input: row.tokens_input,
output: row.tokens_output,
reasoning: row.tokens_reasoning,
total: row.tokens_input + row.tokens_output + row.tokens_reasoning,
total:
row.tokens_input +
row.tokens_output +
row.tokens_reasoning +
row.tokens_cache_read +
row.tokens_cache_write,
cache: {
read: row.tokens_cache_read,
write: 0
write: row.tokens_cache_write
}
}
})
+10 -6
View File
@@ -43,6 +43,7 @@ function createSessionTotalsSchema(db: Database.Database): void {
tokens_output INTEGER,
tokens_reasoning INTEGER,
tokens_cache_read INTEGER,
tokens_cache_write INTEGER,
time_created INTEGER,
time_updated INTEGER
);
@@ -57,9 +58,9 @@ function insertSessionTotalsRow(
db.prepare(
`INSERT INTO session (
id, directory, title, model, cost,
tokens_input, tokens_output, tokens_reasoning, tokens_cache_read,
tokens_input, tokens_output, tokens_reasoning, tokens_cache_read, tokens_cache_write,
time_created, time_updated
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run(
sessionId,
`${WORKTREE}/packages/app`,
@@ -70,6 +71,7 @@ function insertSessionTotalsRow(
100,
0,
0,
0,
1_777_777_700_000,
1_777_777_800_000
)
@@ -235,6 +237,7 @@ describe('parseOpenCodeUsageDatabase', () => {
tokens_output INTEGER,
tokens_reasoning INTEGER,
tokens_cache_read INTEGER,
tokens_cache_write INTEGER,
time_created INTEGER,
time_updated INTEGER
);
@@ -243,9 +246,9 @@ describe('parseOpenCodeUsageDatabase', () => {
db.prepare(
`INSERT INTO session (
id, project_id, directory, title, model, cost,
tokens_input, tokens_output, tokens_reasoning, tokens_cache_read,
tokens_input, tokens_output, tokens_reasoning, tokens_cache_read, tokens_cache_write,
time_created, time_updated
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run(
'session-1',
'project-1',
@@ -257,6 +260,7 @@ describe('parseOpenCodeUsageDatabase', () => {
500,
100,
250,
75,
1_777_777_700_000,
1_777_777_800_000
)
@@ -274,7 +278,7 @@ describe('parseOpenCodeUsageDatabase', () => {
totalCachedInputTokens: 250,
totalOutputTokens: 500,
totalReasoningOutputTokens: 100,
totalTokens: 1850,
totalTokens: 1925,
estimatedCostUsd: 0.06
})
expect(parsed.dailyAggregates).toEqual([
@@ -284,7 +288,7 @@ describe('parseOpenCodeUsageDatabase', () => {
cachedInputTokens: 250,
outputTokens: 500,
reasoningOutputTokens: 100,
totalTokens: 1850,
totalTokens: 1925,
estimatedCostUsd: 0.06
})
])