Skip to content

feat: Add status bar with model and usage information - #3591

Merged
BinaryMuse merged 6 commits into
mainfrom
mkt/client-usage
Jul 8, 2026
Merged

feat: Add status bar with model and usage information#3591
BinaryMuse merged 6 commits into
mainfrom
mkt/client-usage

Conversation

@BinaryMuse

Copy link
Copy Markdown
Member

This PR adds a status bar that includes the currently selected model on the left and the user's overall AI usage on the right, if it's over a certain threshold, as well as a short string (either in whole number days, hours, or minutes) describing when the limit will reset.

image

The threshold is currently set to 50%, and it changes color as usage gets higher.

image image

The percentage is based on either input or output usage, whichever is higher; e.g., if a user has 40% input usage and 80% output usage, the widget will show 80%.

Usage is cached for 60 seconds in the AI database, and if stale, is updated in the background when the TUI launches. Each turn ends in an event that sends updated usage information, so the widget will remain correct over the course of a session.

@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a status bar to the AI TUI showing the currently selected model and credit usage when it exceeds 50%, with color-coded bar and reset countdown. Usage snapshots are fetched on TUI open (with 60s cache), refreshed in the background if stale, and updated at the end of each turn via the done event.

  • New usage.rs module handles snapshot deserialization, cache-key generation, background HTTP fetch, and the percentage/reset-delta helpers.
  • A new usage SQLite table caches the snapshot per hashed auth token; AiSessionStore and SessionService gain get_usage/set_usage methods.
  • StreamControl::Done is extended to carry an optional UsageSnapshot from the server, and DriverEvent::Usage propagates it to the view state without touching the FSM.

Confidence Score: 5/5

Safe to merge — changes are additive and well-isolated from existing functionality.

The usage snapshot path is entirely additive: a missing or stale cache is a no-op for rendering, fetch failures are swallowed with a debug log, and the done-event credits field is parsed leniently. No existing code paths are altered in a breaking way.

No files require special attention.

Important Files Changed

Filename Overview
crates/atuin-ai/src/usage.rs New module: UsageSnapshot type, percentage/reset helpers, background fetch, cache key. Tests pass and logic matches PR description (max of input/output, not average).
crates/atuin-ai/src/driver.rs Adds DriverEvent::Usage variant and update_usage helper; uses same block_on pattern as existing persist() function. ViewState gains optional usage field.
crates/atuin-ai/src/tui/view/mod.rs Adds status_bar_view with model label and color-coded usage bar; width calculation correctly accounts for all spans including Unicode bar characters.
crates/atuin-ai/src/store.rs Adds get_usage/set_usage (upsert) to AiSessionStore with correct parameterized SQL and a roundtrip test.
crates/atuin-ai/src/commands/inline.rs Reads cached usage at startup, sets it on initial ViewState, and spawns a background refresh task when the cache is stale.
crates/atuin-ai/src/stream.rs StreamControl::Done extended with optional credits field; parsed leniently with .ok() so missing/malformed credits don't break the stream.
crates/atuin-ai/src/session.rs SessionService trait gains get/set_cached_usage methods; LocalSessionService delegates to AiSessionStore. CachedUsageSnapshot wrapper added.
crates/atuin-ai/migrations/20260707000000_create_ai_usage.sql Creates usage table with user_key PK; uses IF NOT EXISTS for safety.
crates/atuin-ai/src/lib.rs Registers new usage module.

Reviews (2): Last reviewed commit: "Return CachedUsageSnapshot from get_cach..." | Re-trigger Greptile

Comment thread crates/atuin-ai/src/usage.rs Outdated
@BinaryMuse
BinaryMuse requested review from ellie and taylordotfish July 8, 2026 18:58
Comment thread crates/atuin-ai/src/session.rs Outdated
taylordotfish
taylordotfish previously approved these changes Jul 8, 2026

@taylordotfish taylordotfish 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.

Looks good overall, minor comment about another tuple return but I'll leave it to you to decide if it's worth changing.

Comment thread crates/atuin-ai/src/store.rs Outdated
Comment thread crates/atuin-ai/src/store.rs Outdated
@BinaryMuse
BinaryMuse merged commit 988e65d into main Jul 8, 2026
25 checks passed
@BinaryMuse
BinaryMuse deleted the mkt/client-usage branch July 8, 2026 21:49
taylordotfish pushed a commit that referenced this pull request Jul 9, 2026
### Bug Fixes

- *(ai)* Dispatch skills registered in the slash command registry
([#3593](#3593))
- *(ci)* Fossier install in scan workflow
([#3485](#3485))
- *(i18n)* Fix typos in Russian localization
([#3575](#3575))
- *(nu)* Use `char -u 1b` for ESC in OSC 133 sequences
([#3530](#3530))
- *(nu)* Suppress error when `ATUIN_HISTORY_ID` is missing in
`pre_prompt` hook
([#3587](#3587))
- *(pi)* Observe tool events instead of registering a bash tool
([#3557](#3557))
- *(pty-proxy)* Set `$SHELL` to the spawned shell
([#3548](#3548))
- *(search)* Fix terminal clearing with latest Ratatui
([#3578](#3578))
- *(sync)* Skip records that fail to decrypt or decode instead of
failing the whole store
([#3569](#3569))
- Atuin hangs when attempting to spawn daemon from Ctrl+R invocation
([#3502](#3502))
- Capture session ID from stream headers rather than final event
([#3531](#3531))
- Doctor resiliency fo runknown platforms + openbsd warning
([#3551](#3551))
- Double input on arrow keys in AI setup prompt on Windows
([#3552](#3552))
- Exclude AI agent commands from zsh-autosuggestions
([#3567](#3567))
- Silence shellcheck SC2016 on literal `$all-user` author filter
- Respect `store_failed` when using daemon
([#3571](#3571))


### Documentation

- Highlight `Ctrl-r` keybinding on docs page
([#3489](#3489))
- Document store purge workflow
([#3544](#3544))
- Fix command example typo in documentation
([#3536](#3536))
- Make commented-out lines in `config.toml` match real defaults
([#3583](#3583))
- Add fish shell cleanup step to uninstall instructions
([#3582](#3582))


### Features

- *(doctor)* Add whether daemon is enabled to `doctor` output
([#3572](#3572))
- *(pty-proxy)* Add `--shell` flag to override the spawned shell
([#3327](#3327))
- Setup fossier to stop bot slop prs
([#3482](#3482))
- Capture command output + expose to new `atuin_output` tool
([#3510](#3510))
- Cache user contexts on load until `/reload`
([#3525](#3525))
- Create database integration tests for atuin-server
([#3514](#3514))
- Add `/model` slash command for changing models
([#3576](#3576))
- Add mcp server for history tools and expand search filters
([#3581](#3581))
- Add status bar with model and usage information
([#3591](#3591))


### Miscellaneous Tasks

- *(rustdoc)* Fix Rustdoc warnings
([#3585](#3585))
- *(warnings)* Fix compile warnings with latest dependencies
([#3586](#3586))
- Vouch for all existing contributors
([#3486](#3486))
- Update GitHub app token format
- Update to Rust 1.96.1
([#3568](#3568))
- Adopt `derive_more` to reduce boilerplate across the codebase
([#3573](#3573))


### Performance

- *(search)* Scan history by recency until N unique
([#3553](#3553))
- Add `synchronous(Normal)` + `optimize_on_close` to record store SQLite
([#3577](#3577))
- Remove unnecessary clones in a hot path
([#3580](#3580))


### Refactor

- Implement `From<sqlx::Error>` and clean up `fix_error`
([#3484](#3484))
- Pull `fn into_utc` into `atuin-server-database` crate
([#3487](#3487))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants