mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix: persist explicit usage models on replay
This commit is contained in:
@@ -128,6 +128,13 @@ export function recordUsageScan(
|
|||||||
last_cache_creation_tokens = excluded.last_cache_creation_tokens
|
last_cache_creation_tokens = excluded.last_cache_creation_tokens
|
||||||
WHERE usage_events.kind = 'delta'
|
WHERE usage_events.kind = 'delta'
|
||||||
`)
|
`)
|
||||||
|
const updateCumulativeModel = db.prepare(`
|
||||||
|
UPDATE usage_events
|
||||||
|
SET model = ?
|
||||||
|
WHERE session_id = ?
|
||||||
|
AND source_key = ?
|
||||||
|
AND kind = 'cumulative'
|
||||||
|
`)
|
||||||
|
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
statement.run({
|
statement.run({
|
||||||
@@ -147,6 +154,9 @@ export function recordUsageScan(
|
|||||||
last_cache_read_tokens: event.lastCacheReadTokens,
|
last_cache_read_tokens: event.lastCacheReadTokens,
|
||||||
last_cache_creation_tokens: event.lastCacheCreationTokens
|
last_cache_creation_tokens: event.lastCacheCreationTokens
|
||||||
})
|
})
|
||||||
|
if (event.kind === 'cumulative' && event.model !== null) {
|
||||||
|
updateCumulativeModel.run(event.model, event.sessionId, event.sourceKey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -256,6 +256,43 @@ describe('usage service', () => {
|
|||||||
store.close()
|
store.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('replaces a cumulative fallback model when a replay adds an explicit model', () => {
|
||||||
|
const store = new Store(':memory:')
|
||||||
|
const session = store.sessions.getOrCreateSession(
|
||||||
|
'codex-explicit-model-replay-test',
|
||||||
|
{ path: '/tmp', host: 'test', flavor: 'codex' },
|
||||||
|
null,
|
||||||
|
'default',
|
||||||
|
'deepseek-v4-flash'
|
||||||
|
)
|
||||||
|
const tokenCount = (model?: string) => ({
|
||||||
|
type: 'codex',
|
||||||
|
data: {
|
||||||
|
type: 'token_count',
|
||||||
|
model,
|
||||||
|
thread_id: 'thread-1',
|
||||||
|
turn_id: 'turn-1',
|
||||||
|
info: {
|
||||||
|
total_token_usage: { input_tokens: 100, output_tokens: 10 },
|
||||||
|
last_token_usage: { input_tokens: 100, output_tokens: 10 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
addAgentMessage(store, session.id, tokenCount())
|
||||||
|
expect(getUsageSummary(store, 'default', 'all').byModel).toEqual([
|
||||||
|
expect.objectContaining({ key: 'deepseek-v4-flash', totalTokens: 110, requests: 1 })
|
||||||
|
])
|
||||||
|
|
||||||
|
addAgentMessage(store, session.id, tokenCount('gpt-5.6-sol'))
|
||||||
|
const result = getUsageSummary(store, 'default', 'all')
|
||||||
|
expect(result.totals).toEqual(expect.objectContaining({ totalTokens: 110, requests: 1 }))
|
||||||
|
expect(result.byModel).toEqual([
|
||||||
|
expect.objectContaining({ key: 'gpt-5.6-sol', totalTokens: 110, requests: 1 })
|
||||||
|
])
|
||||||
|
store.close()
|
||||||
|
})
|
||||||
|
|
||||||
it('preserves event-level models across model switches and epoch rebuilds', () => {
|
it('preserves event-level models across model switches and epoch rebuilds', () => {
|
||||||
const store = new Store(':memory:')
|
const store = new Store(':memory:')
|
||||||
const session = store.sessions.getOrCreateSession(
|
const session = store.sessions.getOrCreateSession(
|
||||||
|
|||||||
Reference in New Issue
Block a user