Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions src/kimi_cli/ui/shell/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,7 @@ def __bool__(self) -> bool:
_GIT_BRANCH_TTL = 5.0
_GIT_STATUS_TTL = 15.0
_TIP_ROTATE_INTERVAL = 30.0
_CONTEXT_USAGE_WARNING_THRESHOLD = 0.80
_MAX_CWD_COLS = 30
_MAX_BRANCH_COLS = 22

Expand Down Expand Up @@ -2204,7 +2205,7 @@ def _render_bottom_toolbar(self) -> FormattedText:
if tip_text and _display_width(tip_text) <= remaining:
fragments.append((tc.tip, tip_text))

# ── line 2: toast (left) + context (right) — always rendered ──────
# ── line 2: toast (left) + optional warning/status text (right) ──────
fragments.append(("", "\n"))

right_text = self._render_right_span(status)
Expand All @@ -2224,8 +2225,9 @@ def _render_bottom_toolbar(self) -> FormattedText:
else:
left_width = 0

fragments.append(("", " " * max(0, columns - left_width - right_width)))
fragments.append(("", right_text))
if right_text:
fragments.append(("", " " * max(0, columns - left_width - right_width)))
fragments.append(("", right_text))

return FormattedText(fragments)

Expand All @@ -2250,10 +2252,12 @@ def _get_one_rotating_tip(self) -> str | None:
@staticmethod
def _render_right_span(status: StatusSnapshot) -> str:
current_toast = _current_toast("right")
if current_toast is None:
return format_context_status(
status.context_usage,
status.context_tokens,
status.max_context_tokens,
)
return current_toast.message
if current_toast is not None:
return current_toast.message
if status.context_usage < _CONTEXT_USAGE_WARNING_THRESHOLD:
return ""
return format_context_status(
status.context_usage,
status.context_tokens,
status.max_context_tokens,
)
26 changes: 22 additions & 4 deletions tests/ui_and_conv/test_prompt_tips.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,12 +434,30 @@ def test_mode_drops_model_name_and_dot_on_very_narrow_terminal(monkeypatch: Any)
# ── Line 2 structural correctness ─────────────────────────────────────────────


def test_toolbar_line2_context_appears_on_line2_not_line1(monkeypatch: Any) -> None:
def test_toolbar_line2_hides_context_below_warning_threshold(monkeypatch: Any) -> None:
prompt_session = _make_toolbar_session(tips=[])
prompt_session._status_provider = lambda: StatusSnapshot(
context_usage=0.42,
context_tokens=3_000,
max_context_tokens=10_000,
)
lines = _render_toolbar_lines(prompt_session, 80, monkeypatch)

assert "context:" not in lines[2]
assert "context:" not in lines[1]


def test_toolbar_line2_context_appears_at_warning_threshold(monkeypatch: Any) -> None:
prompt_session = _make_toolbar_session(tips=[])
prompt_session._status_provider = lambda: StatusSnapshot(
context_usage=0.80,
context_tokens=8_000,
max_context_tokens=10_000,
)
lines = _render_toolbar_lines(prompt_session, 80, monkeypatch)

assert "context: 0.0%" in lines[2]
assert "context: 0.0%" not in lines[1]
assert "context: 80.0% (8k/10k)" in lines[2]
assert "context: 80.0% (8k/10k)" not in lines[1]


def test_toolbar_line2_left_toast_appears_on_line2_not_line1(monkeypatch: Any) -> None:
Expand Down Expand Up @@ -619,7 +637,7 @@ def get_size() -> Any:
rendered_toolbar = prompt_session._render_bottom_toolbar()
plain_toolbar = "".join(fragment[1] for fragment in rendered_toolbar)
assert "tip" in plain_toolbar
assert "context: 0.0%" in plain_toolbar
assert "context:" not in plain_toolbar


def test_modal_prompt_hides_normal_separator_and_prompt_label(monkeypatch) -> None:
Expand Down
Loading