Skip to content

fix(ui): make every cost/cache readout match its labeled scope#6096

Merged
SivanCola merged 2 commits into
esengine:main-v2from
SivanCola:fix/cost-display-scope-cleanups
Jul 6, 2026
Merged

fix(ui): make every cost/cache readout match its labeled scope#6096
SivanCola merged 2 commits into
esengine:main-v2from
SivanCola:fix/cost-display-scope-cleanups

Conversation

@SivanCola

Copy link
Copy Markdown
Collaborator

Summary

费用显示清理线的收尾(#6075 修掉了主污染源;这个 PR 打包剩余的四个口径错位),全部是"标签声称的口径 ≠ 实际显示的数"的问题:

  1. Desktop 状态栏「平均命中」口径静默切换:实时值来自 wire 会话计数器(仅 executor 主模型),fallback 却来自 tab 遥测(全部请求来源)——同一个标签在两种口径间跳变。现在优先全来源遥测(与「会话费用」tooltip 声称的"包含主模型、子代理和辅助调用"一致),executor-only 实时值仅在新会话首轮刷新前兜底。
  2. CLI 状态行对无缓存字段的 provider 显示 "本次命中 0.00%":旧逻辑在 hit+miss 为 0 时用 PromptTokens 充当分母。现在缓存字段缺席时隐藏该指标;真实的全 miss(字段存在、hit 为 0)仍照常显示 0.00%。
  3. serve Web UI「总费用」跨会话累计且有单请求兜底:计数器自页面加载起累计、/new//resume 后继续滚,且空值时退到单请求的 lastUsage.cost。现在会话轮换时重置计数器、删除单请求兜底、卡片改标为「会话费用/Session Cost」。
  4. Desktop ContextPanel 会话费用兜底链可能把单请求的 usage.cost 渲染在「会话费用」标签下;移除单请求分支(usage 仅贡献货币符号)。

Verification

  • New: TestCacheTagHiddenWhenProviderReportsNoCacheFields / TestCacheTagShowsRealZeroHit / TestCacheTagRendersHitRateAndSessionAverage(CLI);context-panel 测试新增"单请求费用不得渲染在会话标签下"与"本地累计仍渲染"两个用例。
  • go test ./internal/cli ./internal/serve green;frontend tsc --noEmit clean;context-panel-breakdown(40 pass)与 statusbar-workspace(13 pass)测试通过;serve 内联 JS 语法解析验证通过。

Cache impact

Cache-impact: none - display-layer only; no provider request, prompt, or tool schema changes.
Cache-guard: not applicable (no cache-sensitive files); UI test suites above cover the change.
System-prompt-review: N/A

Refs #5850 (关闭这条线的最后一批), #2945.

Four labeled-scope mismatches in cost/cache displays, bundled as the
tail of the cost-display cleanup line (esengine#6075 fixed the big one):

- Desktop status bar 平均命中 silently switched scope: the live value
  used the wire session counters (executor agent only) while the
  fallback used tab telemetry (all request sources). Prefer the
  all-sources telemetry — matching the 会话费用 tooltip's "includes
  main model, subagents and auxiliary calls" — with the executor-only
  live counters only bridging a fresh session's first turn.
- CLI status line painted "turn hit 0.00%" for providers that report
  no prompt-cache fields, by falling back to PromptTokens as the
  denominator. The tag now hides when cache fields are absent; a
  genuine full miss (fields present, hit zero) still renders.
- serve web UI "总费用" accumulated since page load across session
  rotations and fell back to a single request's cost. The counters now
  reset on /new and /resume, the single-request fallback is gone, and
  the card is relabeled 会话费用/Session Cost.
- Desktop ContextPanel's session-cost fallback chain could render one
  request's usage.cost under the 会话费用 label; single-request
  branches removed (usage now contributes currency only).
@SivanCola SivanCola requested a review from esengine as a code owner July 6, 2026 11:20
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) tui Terminal UI / CLI (internal/cli, internal/control) labels Jul 6, 2026
…es scope

Review catch on this PR: the panel's session cache average still
preferred usage.sessionCacheHitTokens — the wire session counters the
Go agent scopes to the executor only — over the all-sources telemetry,
while the same panel's session cost and per-source rows (and StatusBar
after this PR) already report all sources. Because the reducer keeps
s.usage across context refreshes, the executor-only number would stick
indefinitely.

Extract contextSessionCache: panel info first, ContextInfo second, wire
counters only as the pre-refresh bridge for a fresh session — and pick
hit/miss as a pair from a single source so the computed rate can never
mix scopes (the old per-field ?? chains could).
@SivanCola

Copy link
Copy Markdown
Collaborator Author

Valid catch — fixed in 72f0210.

The reviewer is right on both counts: (1) ContextPanel's session cache average still preferred usage.sessionCacheHitTokens (executor-only wire counters) over the all-sources telemetry this PR standardizes on, and (2) because the reducer preserves s.usage across context refreshes, the executor-only number would stick around indefinitely rather than being a transient fallback. The old comment even claimed the wire counters "include background tasks" — they don't; the Go agent scopes them to the executor, which is exactly the mismatch this PR exists to fix.

Fix mirrors the StatusBar preference and goes one step further: extracted contextSessionCache(info, context, usage) — panel telemetry first, ContextInfo second, wire counters only as a fresh session's pre-refresh bridge — and it picks hit/miss as a pair from a single source, so the computed rate can never mix scopes (the old per-field ?? chains could pair an executor hit count with a telemetry miss count).

Four new test cases pin the preference order and the no-data case; context-panel suite now 44 pass, tsc --noEmit clean.

@SivanCola SivanCola merged commit 0645b0e into esengine:main-v2 Jul 6, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

desktop Wails desktop app (desktop/**) tui Terminal UI / CLI (internal/cli, internal/control) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant