Skip to content

Settings menu: minor UX and state-consistency bugs #164

Description

@QueryPlanner

What

Found during a code-reduction audit of the Telegram /model//thinking settings UI (now in telegram/settings_menu.py after #161). Four small, non-crashing bugs.

  1. Misleading "Updating settings…" toast on pure navigation (settings_menu.py:240): answer_callback_query(query.id, text="Updating settings…") fires unconditionally before dispatch, including for action == "thinking" (just opening a submenu) and action == "back" — both write nothing, so the toast is inaccurate.
  2. Redundant profile reload after a write. update_inference_profile(...) (lines 246, 273, 283) already returns the freshly merged, validated InferenceProfile, but the return value is discarded and _edit_model_menu immediately re-reads via _load_profile, causing an avoidable extra storage round-trip on every settings change.
  3. Current-selection checkmark matched by rendered label text, not the underlying value (settings_menu.py:184): text=f"{label}{' ✓' if label == current else ''}". If _REASONING_LABELS is ever edited so two different effort values render the same label, the wrong option (or none/multiple) gets marked as selected.
  4. Latent UI mismatch when a model's reasoning becomes mandatory (settings_menu.py:434): when reasoning.mandatory is true, "none"/"Off" is silently excluded from the option list, but if the currently stored effort for that chat is "none", the "Current: Off" line still renders even though there's no matching selectable button — a confusing but non-crashing state mismatch.

Priority

Low — cosmetic/UX papercuts, no data loss or crash risk.

Level of Effort

Small (S) — each is a localized, few-line fix independent of the others.

Sources

Passing criteria / definition of done

  • handle_callback sends a toast only for actions that actually mutate stored preferences (model/reasoning/reset), verified by a test asserting no "Updating settings…" text for action in {"thinking", "back"}.
  • _edit_model_menu/callback handling renders directly from the profile returned by update_inference_profile instead of re-fetching; a test asserts _load_profile (or the storage mock) is not called an extra time after a successful write.
  • The reasoning-menu checkmark match is keyed on the option's underlying value, not its label; a test constructs two options that would render the same label and asserts only the correct one is checked.
  • When the currently-stored effort is excluded by mandatory=True, the menu either falls back to a valid current value or surfaces an explicit note instead of silently showing a value with no matching button; a test covers this case.
  • pytest tests/test_telegram_settings_menu.py -q passes with the new assertions.
  • ruff check, ruff format --check, and mypy src/blacki/telegram/ all pass with no new warnings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions