From 0e521390af5918da223d19596a5b4d067cbf7daa Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Tue, 16 Jun 2026 16:02:17 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=A9=B9=20fix:=20surface=20projections=20a?= =?UTF-8?q?s=20estimates,=20not=20authoritative=20snapshots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A first-cut projection carries the SDK's windowing but omits instruction/tool overhead, so rendering it as `isEstimate: false` showed a confident under-count for snapshot-less branches. Mark projection-sourced views `isEstimate: true` + `snapshotActive: false` (and drop the snapshot field) so they present as a better estimate than sumBranch — improved used/window number, estimate framing, no misleading granular breakdown with ~0 tools. Real snapshots stay authoritative. (Codex round 3, projection.ts:139.) --- client/src/hooks/Chat/useTokenUsage.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/client/src/hooks/Chat/useTokenUsage.ts b/client/src/hooks/Chat/useTokenUsage.ts index 7d0db3f9f7..68030f1eb0 100644 --- a/client/src/hooks/Chat/useTokenUsage.ts +++ b/client/src/hooks/Chat/useTokenUsage.ts @@ -249,12 +249,18 @@ export default function useTokenUsage({ * slots in ahead of the estimate when no snapshot exists. Snapshot and * projection share the render-relevant fields, so they render uniformly. */ let effective: ContextSnapshot | TContextUsageEvent | null = null; + /** A server projection is the SDK's windowing but, in this first cut, omits + * instruction/tool overhead — so it's surfaced as an ESTIMATE (a better one + * than sumBranch), never a false-authoritative number. Real snapshots stay + * authoritative. */ + let projected = false; if (currentActive) { effective = snapshot; } else if (branchSnapshot != null) { effective = branchSnapshot; } else if (projection != null) { effective = projection; + projected = true; } if (effective != null) { @@ -274,9 +280,9 @@ export default function useTokenUsage({ usedTokens, maxTokens, percent: maxTokens > 0 ? Math.min((usedTokens / maxTokens) * 100, 100) : 0, - isEstimate: false, - snapshot: effective as ContextSnapshot, - snapshotActive: true, + isEstimate: projected, + snapshot: projected ? null : (effective as ContextSnapshot), + snapshotActive: !projected, branchTotals, branchUsage, totalUsage,