Skip to content

fix(ui): use totalTokens instead of inputTokens for context notice banner#46620

Closed
IgnacioPro wants to merge 6 commits intoopenclaw:mainfrom
IgnacioPro:fix-46582-banner-tokens
Closed

fix(ui): use totalTokens instead of inputTokens for context notice banner#46620
IgnacioPro wants to merge 6 commits intoopenclaw:mainfrom
IgnacioPro:fix-46582-banner-tokens

Conversation

@IgnacioPro
Copy link
Copy Markdown

Fixes #46582

Changes

  • Changed renderContextNotice() to use session?.totalTokens instead of session?.inputTokens
  • This ensures the context warning banner accurately reflects total token usage instead of just input tokens
  • Updated test fixture to include totalTokens field
  • Added test case verifying banner doesn't show when inputTokens is high but totalTokens is low
  • All UI tests passing (540 tests)

Testing

  • UI test suite: ✓ 540 passed
  • Browser-specific tests: ✓ 2 passed (chat context notice)
  • New test case validates the fix behavior

…nner

- Fix openclaw#46582: Changed renderContextNotice() to use session?.totalTokens instead of session?.inputTokens
- This ensures the context warning banner accurately reflects total token usage
- Updated test fixture to include totalTokens field
- Added test case to verify banner doesn't show when inputTokens is high but totalTokens is low
- Configured vitest to include chat.browser.test.ts in test suite
Copilot AI review requested due to automatic review settings March 14, 2026 22:27
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 14, 2026

Greptile Summary

This PR fixes the context warning banner to use totalTokens instead of inputTokens when calculating context window usage, which is semantically correct — totalTokens accounts for both input and output tokens and is the accurate measure of how much of the context window has been consumed.

  • chat.ts: Single-line fix swapping session?.inputTokens for session?.totalTokens in renderContextNotice. Both fields are optional on GatewaySessionRow, so the existing ?? 0 fallback is still valid.
  • chat.browser.test.ts: Fixture updated to include totalTokens, and a well-targeted regression test added to confirm the banner is suppressed when inputTokens is high but totalTokens is low.
  • vitest.config.ts: The chat.browser.test.ts file is added to the root config's include list, but it is already picked up by ui/vitest.config.ts's browser project (via src/**/*.browser.test.ts). This causes the test to run twice — once in Playwright/Chromium (the correct environment) and once in the root pool: "forks" Node.js environment that has no DOM or jsdom configured, which is mismatched with a test that relies on getComputedStyle and getBoundingClientRect.

Confidence Score: 3/5

  • The core fix is correct, but the vitest.config.ts change duplicates a browser test into the wrong (non-DOM) test environment.
  • The one-line change to chat.ts and the accompanying test are both correct and well-motivated. The regression test case is well-written. The score is reduced because adding chat.browser.test.ts to the root vitest.config.ts is incorrect — the file is already run by ui/vitest.config.ts in its proper Playwright/Chromium environment, and running it again under pool: "forks" (Node.js without DOM) is an environment mismatch that can mask real failures.
  • vitest.config.ts — the addition of chat.browser.test.ts to the root include list should be removed.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: vitest.config.ts
Line: 88

Comment:
**Duplicate test registration causes double test execution**

`ui/vitest.config.ts` already picks up `*.browser.test.ts` files via the `browser` project:

```ts
// ui/vitest.config.ts
defineProject({
  test: {
    name: "browser",
    include: ["src/**/*.browser.test.ts"],  // matches ui/src/ui/views/chat.browser.test.ts
    browser: { enabled: true, provider: playwright(), ... },
  },
}),
```

Adding the same file here means it runs **twice**: once in Playwright/Chromium (the intended environment), and once in this root config's `pool: "forks"` (Node.js) environment — which has no DOM and no `jsdom` environment configured. The root `test/setup.ts` does not establish any DOM globals either.

The `chat.browser.test.ts` test uses real browser APIs (`getComputedStyle`, `getBoundingClientRect`) that require an actual browser or at minimum `jsdom`. Running it under `pool: "forks"` without a DOM environment risks silently degraded assertions or `document is not defined` failures that hide true regressions.

This line should be removed from the root `vitest.config.ts` — the file is already covered by `ui/vitest.config.ts`.

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

Last reviewed commit: 4b259be

Comment thread vitest.config.ts Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an inaccurate “context usage” warning banner in the chat UI by basing the banner threshold on the session’s context-size snapshot (totalTokens) instead of cumulative input tokens (inputTokens), addressing the regression reported in #46582.

Changes:

  • Update renderContextNotice() to compute usage from session?.totalTokens.
  • Update the chat context-notice browser test fixture to include totalTokens.
  • Add a browser test case ensuring the banner does not appear when inputTokens is high but totalTokens is low.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
vitest.config.ts Adds the new chat browser test file to the root Vitest include list.
ui/src/ui/views/chat.ts Switches banner usage calculation from inputTokens to totalTokens.
ui/src/ui/views/chat.browser.test.ts Updates fixtures and adds a regression test for the banner logic change.

Comment thread vitest.config.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: 4b259becdb

ℹ️ 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 vitest.config.ts Outdated
@IgnacioPro
Copy link
Copy Markdown
Author

✅ Fixed CI: added environment: "jsdom" to browser test project config in ui/vitest.config.ts. Browser tests now have DOM access and should pass. See commit 12ce092f8.

@openclaw-barnacle openclaw-barnacle Bot added the gateway Gateway runtime label Mar 17, 2026
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation cli CLI command changes size: S and removed gateway Gateway runtime size: XS labels Mar 17, 2026
@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord channel: imessage Channel integration: imessage channel: matrix Channel integration: matrix channel: signal Channel integration: signal channel: slack Channel integration: slack channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web channel: feishu Channel integration: feishu labels Mar 17, 2026
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: 5cba7b23c3

ℹ️ 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".

} from "./src/mention.js";
export { feishuPlugin } from "./src/channel.js";

export default defineChannelPluginEntry({
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore feishuPlugin named export

Removing the feishuPlugin re-export from this module breaks existing named imports (src/channels/plugins/bundled.ts imports { feishuPlugin } from extensions/feishu/index.js), so loading bundled channel plugins will fail once this commit lands. This turns an unrelated UI fix into a channel-registry/runtime break for any startup path that evaluates bundled plugins.

Useful? React with 👍 / 👎.

# Conflicts:
#	src/plugin-sdk/index.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: 4de4c7cf8d

ℹ️ 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 src/plugin-sdk/index.ts
export type { OpenClawConfig } from "../config/config.js";
/** @deprecated Use OpenClawConfig instead */
export type { OpenClawConfig as ClawdbotConfig } from "../config/config.js";
export { isDangerousNameMatchingEnabled } from "../config/dangerous-name-matching.js";
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep root plugin-sdk export surface minimal

Re-exporting isDangerousNameMatchingEnabled from the root SDK entrypoint breaks the existing root-surface contract: src/plugin-sdk/index.test.ts ("keeps the root runtime surface intentionally small") explicitly asserts that this symbol is not present on openclaw/plugin-sdk. With this line added, that expectation flips and the root entry now leaks internal runtime helpers that were intentionally kept off the top-level API.

Useful? React with 👍 / 👎.

@steipete
Copy link
Copy Markdown
Contributor

Closing this as implemented after Codex review.

Current main already implements the requested behavior: the context notice banner uses session.totalTokens instead of session.inputTokens, and there is a regression test for the high-input/low-total case this PR describes.

What I checked:

So I’m closing this as already implemented rather than keeping a duplicate issue open.

Review notes: reviewed against 56fe2aab9c87; fix evidence: commit f85806b6d786.

@steipete steipete 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 channel: discord Channel integration: discord channel: feishu Channel integration: feishu channel: imessage Channel integration: imessage channel: matrix Channel integration: matrix channel: signal Channel integration: signal channel: slack Channel integration: slack channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web cli CLI command changes docs Improvements or additions to documentation size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: banner uses cumulative Tokens in instead of Context"

3 participants