Skip to content

fix(control-ui): use fresh totals for context usage notice#45335

Closed
KaneOrca wants to merge 3 commits intoopenclaw:mainfrom
KaneOrca:fix/control-ui-context-usage-pr
Closed

fix(control-ui): use fresh totals for context usage notice#45335
KaneOrca wants to merge 3 commits intoopenclaw:mainfrom
KaneOrca:fix/control-ui-context-usage-pr

Conversation

@KaneOrca
Copy link
Copy Markdown

Summary

  • Fix the Control UI chat context warning so it uses fresh totalTokens snapshots when available instead of accumulated inputTokens
  • Keep /usage aligned with the same context-usage calculation rule
  • Add missing .context-notice styles so the warning icon renders as a compact inline notice instead of a giant raw SVG
  • Add targeted regression tests and document the calculation rule in Control UI docs

Change Type

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • None

User-visible / Behavior Changes

  • High-context warnings in Control UI chat no longer render as a full-page warning triangle when they appear
  • Chat context usage and /usage now prefer fresh totalTokens snapshots, so long tool loops do not overstate current context-window usage
  • When no fresh total snapshot exists, the UI still falls back to accumulated inputTokens

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: None

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local dev checkout
  • Model/provider: gpt-5.4 session snapshot in Control UI
  • Integration/channel (if any): Control UI chat
  • Relevant config (redacted): local gateway token auth

Steps

  1. Open a Control UI chat session whose accumulated inputTokens greatly exceed the fresh totalTokens snapshot after long tool loops.
  2. Observe the chat context warning or run /usage.
  3. Compare the reported context percentage and the warning rendering.

Expected

  • Context usage should reflect the current context snapshot, not the accumulated input across prior tool loops
  • The warning icon should render as a compact inline notice

Actual

  • After this change, chat and /usage report context usage from fresh totalTokens when available
  • The warning notice renders as a styled inline pill with a constrained icon size

Evidence

  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Targeted verification run locally:

  • pnpm exec vitest ui/src/ui/views/chat.test.ts --run -> 15/15 passed
  • pnpm exec vitest --config vitest.config.ts --project unit-node src/ui/chat/slash-command-executor.node.test.ts --run -> 14/14 passed
  • Live Control UI check confirmed the selected session was agent:warden:main, .context-notice count was 0, and a style probe reported .context-notice__icon at 16px x 16px

Human Verification

  • Verified scenarios: live Control UI session selection and context notice state; targeted unit tests for chat notice and /usage
  • Edge cases checked: fallback to inputTokens when totalTokensFresh is false; legacy main alias handling for /usage
  • What you did not verify: full pnpm build && pnpm check && pnpm test; screenshot attachments were not added to this PR form

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: None

Failure Recovery

  • How to disable/revert this change quickly: revert this commit
  • Files/config to restore: restore the previous versions of the touched Control UI files
  • Known bad symptoms reviewers should watch for: context percentage regressing to accumulated-input behavior; warning icon rendering without CSS constraints

Risks and Mitigations

  • Risk: sessions without fresh totals still need a fallback path
  • Mitigation: keep explicit fallback to inputTokens when totalTokensFresh === false
  • Risk: session selector naming ambiguity (main vs agent:warden:main) is not addressed in this PR
  • Mitigation: kept scope limited to warning correctness/rendering; follow-up can address session-label disambiguation

AI disclosure

AI-assisted change. Final code and targeted verification were reviewed locally.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: web-ui App: web-ui size: S labels Mar 13, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 13, 2026

Greptile Summary

This PR fixes two related issues in the Control UI: (1) the chat context-usage warning and /usage slash command were using accumulated inputTokens instead of the current totalTokens snapshot, causing false-positive high-context warnings after long tool loops; and (2) the warning SVG lacked CSS constraints, rendering as an oversized raw icon.

Key changes:

  • Adds resolveSessionContextUsageTokens helper in presenter.ts that returns totalTokens when totalTokensFresh !== false, falling back to inputTokens only when the snapshot is explicitly stale.
  • Wires the helper into both renderContextNotice (chat view) and executeUsage (/usage command) so both use the same calculation rule.
  • Adds totalTokensFresh?: boolean to GatewaySessionRow in types.ts.
  • Adds .context-notice / .context-notice__icon / .context-notice__detail CSS classes to constrain the warning pill to an inline 16×16 icon.
  • Adds targeted regression tests covering the fresh-total and legacy-alias paths; updates the existing alias test fixture with totalTokensFresh: false to preserve its expected 30% assertion under the new helper.
  • Documents the calculation rule in both English and Chinese Control UI docs.

Minor concerns noted:

  • When totalTokensFresh is absent (undefined) on a legacy row, the helper implicitly treats totalTokens as fresh — this is intentional but represents a silent behavior change for any session row that carried totalTokens before this field was introduced.
  • The new chat-view test only covers the "no notice" path; complementary tests for the "notice shown via fresh total" and "fallback via inputTokens" paths are absent.

Confidence Score: 4/5

  • Safe to merge; changes are narrowly scoped to context-usage display logic with no backend or data-model impact.
  • The core fix is correct and well-reasoned: preferring a fresh totalTokens snapshot over accumulated inputTokens produces more accurate context-window usage figures. The fallback path (totalTokensFresh === false → use inputTokens) is preserved and tested. The CSS addition is purely additive. The only minor gap is that the totalTokensFresh === undefined case silently changes behavior for legacy rows, and the new chat-view test covers only one of three relevant notice scenarios.
  • ui/src/ui/presenter.ts — review the implicit-fresh assumption for totalTokensFresh === undefined; ui/src/ui/views/chat.test.ts — consider adding positive-path and fallback-path notice tests.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: ui/src/ui/presenter.ts
Line: 38-39

Comment:
**Implicit "fresh" assumption when `totalTokensFresh` is absent**

When `totalTokensFresh` is `undefined` (i.e., the gateway row pre-dates this field), the condition `row?.totalTokensFresh !== false` evaluates to `true`, so `totalTokens` is returned as if it were a fresh snapshot. For sessions that already had `totalTokens` set — but where the API was accumulating it across tool loops — this silently changes the displayed percentage compared to the previous behaviour of always using `inputTokens`.

This is intentional according to the PR description ("prefer fresh totals when available"), but worth noting that this is effectively a **behavior change for any session row that carries `totalTokens` without `totalTokensFresh`**, not purely a bug-fix for sessions that explicitly set `totalTokensFresh: true`.

Consider adding a brief comment to make the intent explicit:

```suggestion
  if (typeof total === "number" && Number.isFinite(total) && row?.totalTokensFresh !== false) {
    // When totalTokensFresh is undefined (legacy rows), we still prefer totalTokens
    // over accumulated inputTokens as the better proxy for current context usage.
    return total;
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: ui/src/ui/views/chat.test.ts
Line: 356-383

Comment:
**Missing complementary test cases for context notice**

The new test confirms that when `totalTokensFresh: true` and the fresh `totalTokens` is below the 85 % threshold, no notice is rendered — which is the core regression being fixed.

Two related scenarios aren't covered and would strengthen confidence:

1. **Positive path**: `totalTokensFresh: true` with `totalTokens / contextTokens ≥ 0.85` — the notice *should* appear using the fresh total, not `inputTokens`.
2. **Fallback path**: `totalTokensFresh: false` with high accumulated `inputTokens` — the notice should still appear via the `inputTokens` fallback.

Without these, a future refactor that accidentally drops the `≥ 0.85` branch for fresh totals would go undetected by the new test.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 8b8836b

Comment thread ui/src/ui/presenter.ts
Comment thread ui/src/ui/views/chat.test.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8b8836b624

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread docs/zh-CN/web/control-ui.md Outdated
@KaneOrca
Copy link
Copy Markdown
Author

Supplemental visual evidence for this UI fix.

This is a local minimal repro of the context-usage notice rendering, added to document the before/after visual difference for reviewers.

  • Left: missing notice styles let the warning SVG dominate the chat canvas
  • Right: the fixed .context-notice and .context-notice__icon render as a compact inline pill

Uploading openclaw-context-notice-before-after.png…

@BunsDev
Copy link
Copy Markdown
Member

BunsDev commented Apr 25, 2026

Closing as superseded by #71297. The canonical PR keeps the Control UI chat context notice fix narrower and current: fresh totalTokens are used for the warning, stale snapshots are suppressed instead of rendered, live session metadata is merged from gateway events, overlapping session refreshes are coalesced, and the compact CTA/test coverage are included there.

This PR overlaps that same Control UI chat warning/styling path, so keeping #71297 as the review path avoids maintaining two implementations of the same fix.

@BunsDev BunsDev closed this Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui docs Improvements or additions to documentation size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants