Module: Rubino::UI::StatusBar
- Defined in:
- lib/rubino/ui/status_bar.rb
Overview
Formats the dim one-line status bar the BottomComposer renders BELOW the pinned input row:
default · minimax-m3 · ctx ~8.4k/64k (13%)
Content: the session MODE leads (the prompt chip moved here in the Rail-rubino redesign — the prompt is a constant “▍❯ ”), then the optional branch / active-skill tokens, the resolved model id and the context saturation — the SAME estimate the compaction logic runs on (Context::TokenBudget: chars/4 over the session messages, window from ‘model.context_length` / `context.max_tokens` with the TokenBudget default). The caller passes the values; this module only formats. ONE encoding of the saturation (P9): the used/window pair, with the percentage in parentheses — omitted entirely below 1% so a fresh session doesn’t carry a “(0%)”. With no usable window the bar degrades to ‘~8.4k tok`.
Color: everything dim, except the mode token when it carries risk (plan yellow, yolo red — subtle, no bold) and the percentage when high — yellow ≥ 70%, red ≥ 90% — matching the existing pastel usage. Each segment is styled SEPARATELY (never a colored span nested inside one dim span) so a colored reset can’t strip the dim from the rest of the line. The single leading space tucks the bar one column in, under the input rail.
Constant Summary collapse
- WARN_PCT =
70- CRIT_PCT =
90
Class Method Summary collapse
-
.abbreviate(count) ⇒ Object
Human token count: 842 → “842”, 8421 → “8.4k”, 128_000 → “128k”.
-
.chip_segments(chips, pastel) ⇒ Object
The leading session-context segments, in fixed order: mode, branch, skill (each omitted when absent).
- .mode_segment(mode, pastel) ⇒ Object
-
.percent_segment(pct, pastel) ⇒ Object
The “<pct>%” segment: dim normally, yellow from WARN_PCT, red from CRIT_PCT — the at-a-glance compaction warning.
-
.render(model:, tokens:, window: nil, chips: {}, pastel: Pastel.new) ⇒ Object
The styled status line.
Class Method Details
.abbreviate(count) ⇒ Object
Human token count: 842 → “842”, 8421 → “8.4k”, 128_000 → “128k”.
91 92 93 94 95 96 97 |
# File 'lib/rubino/ui/status_bar.rb', line 91 def abbreviate(count) n = count.to_i return n.to_s if n < 1000 k = n / 1000.0 k >= 100 ? "#{k.round}k" : format("%.1fk", k).sub(".0k", "k") end |
.chip_segments(chips, pastel) ⇒ Object
The leading session-context segments, in fixed order: mode, branch, skill (each omitted when absent). The mode token is dim for default and carries a subtle color accent when the mode carries risk — plan yellow, yolo red (the same red as the input rail’s brand accent).
64 65 66 67 68 69 70 |
# File 'lib/rubino/ui/status_bar.rb', line 64 def chip_segments(chips, pastel) segments = [] segments << mode_segment(chips[:mode], pastel) if chips[:mode] segments << pastel.dim("branch:#{chips[:branch]}") if chips[:branch] segments << pastel.dim("skill #{chips[:skill]}") if chips[:skill] segments end |
.mode_segment(mode, pastel) ⇒ Object
72 73 74 75 76 77 78 |
# File 'lib/rubino/ui/status_bar.rb', line 72 def mode_segment(mode, pastel) case mode.to_s when "plan" then pastel.yellow("plan") when "yolo" then pastel.red("yolo") else pastel.dim(mode.to_s) end end |
.percent_segment(pct, pastel) ⇒ Object
The “<pct>%” segment: dim normally, yellow from WARN_PCT, red from CRIT_PCT — the at-a-glance compaction warning.
82 83 84 85 86 87 88 |
# File 'lib/rubino/ui/status_bar.rb', line 82 def percent_segment(pct, pastel) text = "#{pct}%" return pastel.red(text) if pct >= CRIT_PCT return pastel.yellow(text) if pct >= WARN_PCT pastel.dim(text) end |
.render(model:, tokens:, window: nil, chips: {}, pastel: Pastel.new) ⇒ Object
The styled status line. chips carries the leading session-context tokens — :mode (the mode token shown FIRST; plan/yolo carry their accent), :branch (the short id after a ‘/branch` fork) and :skill (the active skill, rendered “skill <name>”) — each omitted when nil/absent, so callers without that context get the bare model-and-ctx bar. tokens is the estimated tokens in the conversation; window the model’s context window (nil/0 ⇒ unknown, percentage omitted). Returns a string ready to draw (leading indent included) — the composer clamps/omits it per terminal width.
46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/rubino/ui/status_bar.rb', line 46 def render(model:, tokens:, window: nil, chips: {}, pastel: Pastel.new) segments = chip_segments(chips, pastel) segments << pastel.dim(model.to_s) if window.to_i.positive? pct = (tokens.to_i * 100.0 / window.to_i).round ctx = pastel.dim("ctx ~#{abbreviate(tokens)}/#{abbreviate(window)}") ctx += " #{pastel.dim("(")}#{percent_segment(pct, pastel)}#{pastel.dim(")")}" if pct >= 1 segments << ctx else segments << pastel.dim("~#{abbreviate(tokens)} tok") end " #{segments.join(pastel.dim(" · "))}" end |