mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-18 13:23:33 +08:00
fix: align transcript context fallback with cli totals
The live desktop context path already routes through the CLI get_context_usage control request and the shared analyzeContextUsage implementation. The offline transcript fallback was still using its own prompt-token-only estimate, so disconnected sessions could report a lower context total than the live /context path. The fallback now reuses the same current-context total helper and includes output tokens as next-turn context. Constraint: Desktop must still show context estimates when the CLI process is not running Rejected: Keep transcript fallback prompt-only | it diverges from the live CLI /context total and can drop after responses Confidence: high Scope-risk: narrow Directive: Transcript context fallback must stay aligned with calculateCurrentContextTokenTotal Tested: bun test src/server/__tests__/conversations.test.ts --test-name-pattern "context-only|structured session inspection|reconstruct Sonnet 4.6 transcript usage" Tested: bun test src/utils/__tests__/context.test.ts Tested: bun run check:server
This commit is contained in:
parent
f02fe83e28
commit
1029c9e7bc
@ -372,8 +372,9 @@ describe('ConversationService', () => {
|
||||
expect(usage?.models[0]?.model).toBe('claude-sonnet-4-6')
|
||||
expect(usage?.models[0]?.contextWindow).toBe(200_000)
|
||||
expect(contextEstimate?.model).toBe('claude-sonnet-4-6')
|
||||
expect(contextEstimate?.totalTokens).toBe(100)
|
||||
expect(contextEstimate?.totalTokens).toBe(120)
|
||||
expect(contextEstimate?.rawMaxTokens).toBe(200_000)
|
||||
expect(contextEstimate?.categories.some((category) => category.name === 'Output tokens' && category.tokens === 20)).toBe(true)
|
||||
} finally {
|
||||
if (previousConfigDir === undefined) {
|
||||
delete process.env.CLAUDE_CONFIG_DIR
|
||||
|
||||
@ -13,6 +13,7 @@ import { sanitizePath as sanitizePortablePath } from '../../utils/sessionStorage
|
||||
import type { FileHistorySnapshot } from '../../utils/fileHistory.js'
|
||||
import { calculateUSDCost, MODEL_COSTS } from '../../utils/modelCost.js'
|
||||
import {
|
||||
calculateCurrentContextTokenTotal,
|
||||
MODEL_CONTEXT_WINDOW_DEFAULT,
|
||||
getContextWindowForModel,
|
||||
getModelMaxOutputTokens,
|
||||
@ -891,12 +892,19 @@ export class SessionService {
|
||||
if (!latest) return null
|
||||
|
||||
const rawMaxTokens = this.getTranscriptContextWindow(latest.model)
|
||||
const totalTokens = latest.inputTokens + latest.cacheReadInputTokens + latest.cacheCreationInputTokens
|
||||
const promptTokens = latest.inputTokens + latest.cacheReadInputTokens + latest.cacheCreationInputTokens
|
||||
const totalTokens = calculateCurrentContextTokenTotal(promptTokens, {
|
||||
input_tokens: latest.inputTokens,
|
||||
output_tokens: latest.outputTokens,
|
||||
cache_read_input_tokens: latest.cacheReadInputTokens,
|
||||
cache_creation_input_tokens: latest.cacheCreationInputTokens,
|
||||
})
|
||||
const percentage = rawMaxTokens > 0 ? Math.round((totalTokens / rawMaxTokens) * 100) : 0
|
||||
const categories: TranscriptContextEstimate['categories'] = [
|
||||
{ name: 'Input tokens', tokens: latest.inputTokens, color: '#8f3217' },
|
||||
{ name: 'Cache read', tokens: latest.cacheReadInputTokens, color: '#0f5c8f' },
|
||||
{ name: 'Cache write', tokens: latest.cacheCreationInputTokens, color: '#7c3aed' },
|
||||
{ name: 'Output tokens', tokens: latest.outputTokens, color: '#2f7d32' },
|
||||
{ name: 'Free space', tokens: Math.max(0, rawMaxTokens - totalTokens), color: '#a1a1aa', isDeferred: true },
|
||||
].filter((category) => category.tokens > 0)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user