Skip to content

ui: Context usage gauge and panel - #25340

Merged
allozaur merged 41 commits into
ggml-org:masterfrom
allozaur:feat/24346-context-usage-ui
Jul 8, 2026
Merged

allozaur merged 41 commits into
ggml-org:masterfrom
allozaur:feat/24346-context-usage-ui

Conversation

@allozaur

@allozaur allozaur commented Jul 6, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Close #24346

demo_h264_2.mp4
  • Moved Reasoning to Chat Form Add Panel (renamed from ChatFormActionReasoningEffortSubmenu → ChatFormActionAddReasoningSubmenu, nested as a submenu)
  • Updated defaults for Reasoning (OFF added to ReasoningEffort enum, labels restructured)
  • Context usage gauge and panel — new donut progress + hover card with model info, context bar, and collapsible token breakdown (tool defs, reading, output, avg speed)
  • Removed ChatScreenProcessingInfo component and its context provider (replaced by the gauge)
  • toolsStore now owns the OpenAI wire format exclusively — removed getToolDefinitionsForLLM and normalizeSchemaProperties from mcpStore
  • /tokenize endpoint + TokenizeService with FNV-1a hashing for tool token count caching
  • MCP store cleanup — removed inline OpenAI tool conversion, connection lifecycle/health checks/executeTool remain
  • Stream constants update, migration service updates

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES, Ornith-1.0-35B with Zed, Pi and llama-ui via llama serve

@allozaur
allozaur force-pushed the feat/24346-context-usage-ui branch from e7cb827 to 6734cb6 Compare July 6, 2026 07:04
Comment thread tools/ui/package.json Resolved
@ServeurpersoCom

Copy link
Copy Markdown
Contributor

This is a genuine optimization of states display and ergonomy. It’s no longer a draft, it's ready for review!
I'm keeping the live branch running on my server to see if I run into any bugs; so far, I have no issues to report for now

@allozaur
allozaur marked this pull request as ready for review July 7, 2026 20:06
@allozaur
allozaur requested a review from a team as a code owner July 7, 2026 20:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a context-usage gauge to the chat UI and refactors related reasoning/tooling plumbing in tools/ui, including reasoning defaults, MCP tool wire-format ownership, and removal of the old processing-info UI.

Changes:

  • Introduces a new context usage gauge (donut + hover-card details) and supporting hook/components.
  • Reworks reasoning defaults/controls (adds ReasoningEffort.OFF, updates how thinking is derived and sent to the API).
  • Refactors MCP tool definition handling so toolsStore owns OpenAI-compatible tool payload shaping; removes the old processing info component/context and some UI settings.

Reviewed changes

Copilot reviewed 52 out of 53 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/ui/src/lib/utils/branching.ts Trims docstrings in branching helpers
tools/ui/src/lib/stores/tools.svelte.ts Moves MCP tool wire-shaping into tools store
tools/ui/src/lib/stores/mcp.svelte.ts Removes OpenAI tool generation from MCP store
tools/ui/src/lib/stores/conversations.svelte.ts Derives thinking from reasoning effort defaults
tools/ui/src/lib/stores/chat.svelte.ts Omits effort when set to OFF
tools/ui/src/lib/stores/agentic.svelte.ts Types now reference toolsStore tool payload
tools/ui/src/lib/services/migration.service.ts Comment tweak in config migration
tools/ui/src/lib/services/chat.service.ts Minor doc/comment wording change
tools/ui/src/lib/hooks/use-processing-state.svelte.ts Simplifies monitoring stop behavior
tools/ui/src/lib/hooks/use-mcp-recommendations.svelte.ts Simplifies opt-in dialog scheduling logic
tools/ui/src/lib/hooks/use-context-gauge.svelte.ts New hook for context gauge state
tools/ui/src/lib/enums/reasoning-effort.enums.ts Adds ReasoningEffort.OFF
tools/ui/src/lib/enums/index.ts Re-exports new chat statistics mode enum
tools/ui/src/lib/enums/chat.enums.ts Adds ChatMessageStatisticsMode
tools/ui/src/lib/contexts/processing-info.context.ts Removes processing-info context (deleted)
tools/ui/src/lib/contexts/index.ts Stops exporting processing-info context
tools/ui/src/lib/constants/storage.ts Removes thinking-default localStorage key
tools/ui/src/lib/constants/settings-registry.ts Removes some display settings entries
tools/ui/src/lib/constants/settings-keys.ts Removes keys for deleted settings
tools/ui/src/lib/constants/reasoning-effort.ts Adds OFF label and enum-backed values
tools/ui/src/lib/constants/css-classes.ts Adds submenu width constant
tools/ui/src/lib/constants/context-keys.ts Removes processing-info context key
tools/ui/src/lib/components/ui/hover-card/index.ts New hover-card component exports
tools/ui/src/lib/components/ui/hover-card/hover-card.svelte New hover-card root wrapper
tools/ui/src/lib/components/ui/hover-card/hover-card-trigger.svelte New hover-card trigger wrapper
tools/ui/src/lib/components/ui/hover-card/hover-card-portal.svelte New hover-card portal wrapper
tools/ui/src/lib/components/ui/hover-card/hover-card-content.svelte New hover-card content wrapper
tools/ui/src/lib/components/app/settings/SettingsChat/SettingsChatToolsTab.svelte Adjusts tools tab label rendering
tools/ui/src/lib/components/app/dialogs/DialogMcpServerRecommendations.svelte Updates recommendations dialog behavior
tools/ui/src/lib/components/app/content/SyntaxHighlightedCode.svelte Improves code block overflow sizing
tools/ui/src/lib/components/app/content/CollapsibleContentBlock.svelte Adjusts collapsible layout classes
tools/ui/src/lib/components/app/chat/index.ts Exports new reasoning submenu + gauge; removes old processing info export
tools/ui/src/lib/components/app/chat/ChatScreen/ChatScreenProcessingInfo.svelte Removes processing info component (deleted)
tools/ui/src/lib/components/app/chat/ChatScreen/ChatScreen.svelte Drops processing-info usage/context wiring
tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageStatistics/ChatMessageStatistics.svelte Adds fixed-mode stats rendering support
tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessages.svelte Passes last-user/next-assistant metadata
tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageAgenticContent.svelte Revises agentic turn layout + stats gating
tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageUser/ChatMessageUserPending.svelte Simplifies pending user message positioning
tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageUser/ChatMessageUser.svelte Shows reading stats on user message rows
tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageAssistant/ChatMessageAssistant.svelte Simplifies assistant stats view handling
tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessage.svelte Wires through new user-message metadata props
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeLoadModel.svelte New load-model prompt row
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDial.svelte New donut dial component
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetails.svelte New hover-card details panel
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetailRow.svelte New detail row component
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/context-gauge.ts New color/threshold helpers
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ChatFormContextGauge.svelte New gauge entrypoint component
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormReasoningEffortSubmenu.svelte Adjusts submenu styling and checkmark placement
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActions.svelte Replaces reasoning toggle with context gauge
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionAddReasoningSubmenu.svelte Moves reasoning controls into “Add” submenu
tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionAddDropdown.svelte Adds reasoning submenu to Add dropdown
tools/ui/package.json Bumps @internationalized/date version
tools/ui/package-lock.json Locks @internationalized/date bump
Files not reviewed (1)
  • tools/ui/package-lock.json: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@allozaur
allozaur force-pushed the feat/24346-context-usage-ui branch from fc33b19 to af49e54 Compare July 8, 2026 06:01
@ServeurpersoCom

Copy link
Copy Markdown
Contributor

Regression-free quick test PR on desktop and mobile: It remains to be seen whether this popup is readable on mobile (touch event).
Mobile

@ServeurpersoCom ServeurpersoCom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. follow-up for mobile popup

@allozaur
allozaur force-pushed the feat/24346-context-usage-ui branch from af49e54 to e7b8277 Compare July 8, 2026 07:00

@ggerganov ggerganov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Neat!

allozaur added 12 commits July 8, 2026 09:15
…rmat

Previously mcpStore.getToolDefinitionsForLLM() owned the MCP->OpenAI
shape conversion (plus normalizeSchemaProperties). That created two
sources of truth for what gets sent to the LLM, with the
duplication-prone risk of the deduplicated enabled list (which feeds
the token-count cache) drifting from the bytes actually shipped on
chat.

Now:
- mcpStore: pure protocol state + routing. Drop getToolDefinitionsForLLM
  and the inline OpenAIToolDefinition conversion + normalizeSchemaProperties.
  Doc comment adjusted to declare wire-format ownership as belonging
  to toolsStore. Connection lifecycle, health checks, executeTool,
  and the connections/toolsIndex remain.
- toolsStore: owns the wire shape (added earlier this series). mcpEntries()
  inlines the MCP tool conversion; uses normalizeJsonSchema (the JSON
  Schema util extracted in the prior commit) so missing 'type' fields
  are inferred from defaults. mcpTools getter iterates mcpEntries() so
  the Settings UI and the deduplicated enabled list see the same
  definitions. getEnabledToolsForLLM iterates mcpEntries() instead of
  calling mcpStore, so the JSON sent to the LLM is identical to what
  toolsStore.refreshEnabledToolsTokenCount tokenizes.
- agentic: the chat-completion tools field's type was annotated as
  ReturnType<typeof mcpStore.getToolDefinitionsForLLM>, claiming the
  shape was owned by mcpStore. Switch to ReturnType<typeof
  toolsStore.getEnabledToolsForLLM>, the actual source.

Assisted-by: Claude
@allozaur
allozaur force-pushed the feat/24346-context-usage-ui branch from e7b8277 to 6a1d53c Compare July 8, 2026 07:15
@allozaur
allozaur merged commit f1161b1 into ggml-org:master Jul 8, 2026
6 checks passed
@dagbdagb

dagbdagb commented Jul 8, 2026

Copy link
Copy Markdown

Nice! But the visual element to trigger that panel is close to invisible...

@ServeurpersoCom

Copy link
Copy Markdown
Contributor

Nice! But the visual element to trigger that panel is close to invisible...

This will be improved in a follow-up PR, because, as it happens, triggering this panel isn't possible on mobile for the time being.

@trofen

trofen commented Jul 11, 2026

Copy link
Copy Markdown

Regarding the Reasoning control specifically: moving it from a visible button next to the input field into the “Add” menu feels less convenient and less intuitive.
Reasoning is a setting that users may toggle fairly often, so hiding it behind an extra menu makes it harder to discover and adds unnecessary friction. I think the previous placement was clearer, or at least the Reasoning toggle should remain directly accessible near the input field.

@allozaur

Copy link
Copy Markdown
Contributor Author

Regarding the Reasoning control specifically: moving it from a visible button next to the input field into the “Add” menu feels less convenient and less intuitive. Reasoning is a setting that users may toggle fairly often, so hiding it behind an extra menu makes it harder to discover and adds unnecessary friction. I think the previous placement was clearer, or at least the Reasoning toggle should remain directly accessible near the input field.

hey, I'll revisit this one soon as a part of models management milestone

danielzgtg added a commit to danielzgtg/llama.cpp that referenced this pull request Jul 21, 2026
This makes llama-server match llama-cli's behavior of enabling reasoning
by default again.

Upgrading from April's llama.cpp, I thought a regression broke reasoning
support.
https://www.reddit.com/r/LocalLLaMA/comments/1u2yufo/cant_seem_to_enable_reasoning_in_llamacpp/
shows other people struggling with this. I tried `--reasoning on` and
`--reasoning-budget -1` to no avail. Unlike Claude and Gemini which have
the thinking option on the model selection button, somehow we have our
reasoning limit buried in the multimedia button, where coders and
text-only users would never look.

I reenabled reasoning by default. Most people would want to default to
using the full capabilities of the model, instead of silently
restricting it.

PR ggml-org#25340 changed the default from MEDIUM to OFF. This changes it back.
@allozaur
allozaur deleted the feat/24346-context-usage-ui branch July 29, 2026 16:46
satindergrewal pushed a commit to satindergrewal/llama.cpp that referenced this pull request Aug 12, 2026
* feat: WIP

* feat: Retire ChatScreenProcessingInfo component, context, and keepStatsVisible settings

* feat: Always-on gauge with active-model /props, conversation stats and live-reactive reading/output/avg

* feat: Add /tokenize endpoint, TokenizeService, FNV-1a and JSON Schema utilities

* feat: Surface enabled-tools token count in context hover card

* refactor(tools): make toolsStore the sole owner of the OpenAI wire format

Previously mcpStore.getToolDefinitionsForLLM() owned the MCP->OpenAI
shape conversion (plus normalizeSchemaProperties). That created two
sources of truth for what gets sent to the LLM, with the
duplication-prone risk of the deduplicated enabled list (which feeds
the token-count cache) drifting from the bytes actually shipped on
chat.

Now:
- mcpStore: pure protocol state + routing. Drop getToolDefinitionsForLLM
  and the inline OpenAIToolDefinition conversion + normalizeSchemaProperties.
  Doc comment adjusted to declare wire-format ownership as belonging
  to toolsStore. Connection lifecycle, health checks, executeTool,
  and the connections/toolsIndex remain.
- toolsStore: owns the wire shape (added earlier this series). mcpEntries()
  inlines the MCP tool conversion; uses normalizeJsonSchema (the JSON
  Schema util extracted in the prior commit) so missing 'type' fields
  are inferred from defaults. mcpTools getter iterates mcpEntries() so
  the Settings UI and the deduplicated enabled list see the same
  definitions. getEnabledToolsForLLM iterates mcpEntries() instead of
  calling mcpStore, so the JSON sent to the LLM is identical to what
  toolsStore.refreshEnabledToolsTokenCount tokenizes.
- agentic: the chat-completion tools field's type was annotated as
  ReturnType<typeof mcpStore.getToolDefinitionsForLLM>, claiming the
  shape was owned by mcpStore. Switch to ReturnType<typeof
  toolsStore.getEnabledToolsForLLM>, the actual source.

Assisted-by: Claude

* feat: UI WIP

* feat: UI WIP

* feat: UI WIP

* feat: Adjust reasoning submenu layout and spacing

* feat: Adjust context usage gauge thresholds and styling

* feat: Split context usage gauge stats into current and cumulative breakdowns

* chore: Format

* refactor: Cleanup

* refactor: Cleanup

* feat: improve token gauge accuracy and display

* refactor: remove MCP recommendation gating and simplify server visibility

* feat: add token audit logging to ChatStore for debugging

* refactor: Simplify context token reading to use server promptTokens directly

* feat: Replace last-known token tracking with live server-derived stats for accurate streaming gauges

* feat: UI Improvements

* feat: Move prompt processing stats to the preceding user message

* feat: Fix context token double-counting and refine gauge layout

* refactor: remove always-show-agentic-turns setting and simplify agentic turn display

* feat: track and display cache tokens in context gauge

* feat: add diagnostic logging for chat completion requests

* refactor: improve token audit console output with fresh/cached breakdown

* fix: invalidate enabled tools token count cache on tool changes

* test: add unit tests for tools store token count invalidation

* refactor: Remove tools token counting infrastructure

* refactor: Update ChatFormContextGauge to use simplified token tracking

* refactor: Update ChatStore to remove tools token counting

* chore: Formatting

* feat: Improve UI text

* feat: simplify context usage derivation and refine gauge labels

* refactor: cleanup logs

* cleaning

* fix: UI

* refactor: Enums

* refactor: Extract context gauge logic into hook and split UI into sub-components

* refactor: Cleanup comments

---------

Co-authored-by: Pascal <admin@serveurperso.com>
zbrad pushed a commit to zbrad/llama.cpp that referenced this pull request Sep 10, 2026
* feat: WIP

* feat: Retire ChatScreenProcessingInfo component, context, and keepStatsVisible settings

* feat: Always-on gauge with active-model /props, conversation stats and live-reactive reading/output/avg

* feat: Add /tokenize endpoint, TokenizeService, FNV-1a and JSON Schema utilities

* feat: Surface enabled-tools token count in context hover card

* refactor(tools): make toolsStore the sole owner of the OpenAI wire format

Previously mcpStore.getToolDefinitionsForLLM() owned the MCP->OpenAI
shape conversion (plus normalizeSchemaProperties). That created two
sources of truth for what gets sent to the LLM, with the
duplication-prone risk of the deduplicated enabled list (which feeds
the token-count cache) drifting from the bytes actually shipped on
chat.

Now:
- mcpStore: pure protocol state + routing. Drop getToolDefinitionsForLLM
  and the inline OpenAIToolDefinition conversion + normalizeSchemaProperties.
  Doc comment adjusted to declare wire-format ownership as belonging
  to toolsStore. Connection lifecycle, health checks, executeTool,
  and the connections/toolsIndex remain.
- toolsStore: owns the wire shape (added earlier this series). mcpEntries()
  inlines the MCP tool conversion; uses normalizeJsonSchema (the JSON
  Schema util extracted in the prior commit) so missing 'type' fields
  are inferred from defaults. mcpTools getter iterates mcpEntries() so
  the Settings UI and the deduplicated enabled list see the same
  definitions. getEnabledToolsForLLM iterates mcpEntries() instead of
  calling mcpStore, so the JSON sent to the LLM is identical to what
  toolsStore.refreshEnabledToolsTokenCount tokenizes.
- agentic: the chat-completion tools field's type was annotated as
  ReturnType<typeof mcpStore.getToolDefinitionsForLLM>, claiming the
  shape was owned by mcpStore. Switch to ReturnType<typeof
  toolsStore.getEnabledToolsForLLM>, the actual source.

Assisted-by: Claude

* feat: UI WIP

* feat: UI WIP

* feat: UI WIP

* feat: Adjust reasoning submenu layout and spacing

* feat: Adjust context usage gauge thresholds and styling

* feat: Split context usage gauge stats into current and cumulative breakdowns

* chore: Format

* refactor: Cleanup

* refactor: Cleanup

* feat: improve token gauge accuracy and display

* refactor: remove MCP recommendation gating and simplify server visibility

* feat: add token audit logging to ChatStore for debugging

* refactor: Simplify context token reading to use server promptTokens directly

* feat: Replace last-known token tracking with live server-derived stats for accurate streaming gauges

* feat: UI Improvements

* feat: Move prompt processing stats to the preceding user message

* feat: Fix context token double-counting and refine gauge layout

* refactor: remove always-show-agentic-turns setting and simplify agentic turn display

* feat: track and display cache tokens in context gauge

* feat: add diagnostic logging for chat completion requests

* refactor: improve token audit console output with fresh/cached breakdown

* fix: invalidate enabled tools token count cache on tool changes

* test: add unit tests for tools store token count invalidation

* refactor: Remove tools token counting infrastructure

* refactor: Update ChatFormContextGauge to use simplified token tracking

* refactor: Update ChatStore to remove tools token counting

* chore: Formatting

* feat: Improve UI text

* feat: simplify context usage derivation and refine gauge labels

* refactor: cleanup logs

* cleaning

* fix: UI

* refactor: Enums

* refactor: Extract context gauge logic into hook and split UI into sub-components

* refactor: Cleanup comments

---------

Co-authored-by: Pascal <admin@serveurperso.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Context Usage Gauge UI in Chat Form

6 participants