Merge pull request #801 from EuanTop/fix/opencode-session-model

fix(opencode): read session fallback model from the real schema
This commit is contained in:
Resham Joshi 2026-08-03 13:57:16 -07:00 committed by GitHub
commit 8dd5a62801
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 8 deletions

View file

@ -36,7 +36,21 @@ type SessionTokenRow = {
tokens_reasoning?: number
tokens_cache_read?: number
tokens_cache_write?: number
model_id?: string
model?: Uint8Array | string
}
function parseSessionModel(value: Uint8Array | string | undefined): string | undefined {
try {
const parsed: unknown = JSON.parse(blobToText(value))
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return undefined
const model = parsed as Record<string, unknown>
const id = typeof model['id'] === 'string' ? model['id'].trim() : ''
const providerID = typeof model['providerID'] === 'string' ? model['providerID'].trim() : ''
return id && providerID ? `${providerID}/${id}` : undefined
} catch {
return undefined
}
}
function tryQuerySessionTokens(db: SqliteDatabase, sessionId: string): {
@ -45,7 +59,9 @@ function tryQuerySessionTokens(db: SqliteDatabase, sessionId: string): {
} | null {
try {
const rows = db.query<SessionTokenRow>(
`SELECT cost, tokens_input, tokens_output, tokens_reasoning, tokens_cache_read, tokens_cache_write, model_id FROM session WHERE id = ?`,
`SELECT cost, tokens_input, tokens_output, tokens_reasoning, tokens_cache_read, tokens_cache_write,
CAST(model AS BLOB) AS model
FROM session WHERE id = ?`,
[sessionId],
)
if (rows.length === 0) return null
@ -57,7 +73,7 @@ function tryQuerySessionTokens(db: SqliteDatabase, sessionId: string): {
reasoning: r.tokens_reasoning ?? 0,
cacheRead: r.tokens_cache_read ?? 0,
cacheWrite: r.tokens_cache_write ?? 0,
model: r.model_id ?? undefined,
model: parseSessionModel(r.model),
}
} catch {
return null
@ -324,4 +340,3 @@ export async function discoverSqliteSessions(
return sessions
}

View file

@ -225,9 +225,10 @@ export const PROVIDER_PARSE_VERSIONS: Record<string, string> = {
'lingtai-tui': 'token-ledger-registry-activity-v3',
'ibm-bob': 'worktree-project-grouping-v1',
kiro: 'ide-parsing-v1-est-cost',
opencode: 'session-model-v1',
quickdesk: 'emf-sqlite-v2-est-cost',
kimicode: 'wire-usage-v1-est-cost',
'kilo-code': 'worktree-project-grouping-v1',
'kilo-code': 'worktree-project-grouping-v1-session-model-v1',
'roo-code': 'worktree-project-grouping-v1',
warp: 'worktree-project-grouping-v1-est-cost',
antigravity: 'worktree-project-grouping-v5',

View file

@ -823,10 +823,15 @@ skipUnlessSqlite('opencode provider - session parsing', () => {
db.exec(`ALTER TABLE session ADD COLUMN tokens_reasoning INTEGER`)
db.exec(`ALTER TABLE session ADD COLUMN tokens_cache_read INTEGER`)
db.exec(`ALTER TABLE session ADD COLUMN tokens_cache_write INTEGER`)
db.exec(`ALTER TABLE session ADD COLUMN model_id TEXT`)
db.exec(`ALTER TABLE session ADD COLUMN model TEXT`)
insertSession(db, 'sess-1')
db.prepare(`UPDATE session SET cost = 0.15, tokens_input = 5000, tokens_output = 2000, tokens_reasoning = 0, tokens_cache_read = 3000, tokens_cache_write = 1000, model_id = 'claude-sonnet-4-20250514' WHERE id = 'sess-1'`).run()
db.prepare(`UPDATE session SET cost = ?, tokens_input = ?, tokens_output = ?, tokens_reasoning = ?, tokens_cache_read = ?, tokens_cache_write = ?, model = ? WHERE id = ?`)
.run(0.15, 5000, 2000, 0, 3000, 1000, JSON.stringify({
providerID: 'anthropic',
id: 'claude-sonnet-4-20250514',
variant: 'high',
}), 'sess-1')
insertMessage(db, 'msg-1', 'sess-1', 1700000001000, {
role: 'assistant', modelID: 'claude-sonnet-4-20250514',
@ -840,7 +845,7 @@ skipUnlessSqlite('opencode provider - session parsing', () => {
expect(calls[0]!.cacheReadInputTokens).toBe(3000)
expect(calls[0]!.cacheCreationInputTokens).toBe(1000)
expect(calls[0]!.costUSD).toBeGreaterThan(0)
expect(calls[0]!.model).toBe('claude-sonnet-4-20250514')
expect(calls[0]!.model).toBe('anthropic/claude-sonnet-4-20250514')
expect(calls[0]!.deduplicationKey).toBe('opencode:sess-1:session-level')
})