b05a47b9d2
The composer showed "<model> · Med" in one truncating pill and the only way to change the effort was to open the model menu, find the active model's row, and hover it for the per-row options submenu. Users read the pill as "this model is medium only" and never found the submenu. - New `ReasoningPill` next to the model pill: shows the active model's live effort (session value, else the profile default) and opens the same Thinking / Fast / Effort rows the catalog submenu offers, for the active model only. Hidden when the catalog reports `reasoning: false`; stays while capabilities are unknown so it never flickers during the fetch. Folds away with the model pill in the compact composer stages. - `useModelMenuController` (shell sibling) now owns the session write / preset / optimistic-store / rollback logic that lived inside `ModelMenuPanel`; the model menu and the new `ReasoningMenuPanel` share it so an edit from either surface is one code path. Tiles get their own pill bound to their SessionView, primary or tile — never the globals. - `ModelOptionsContent` (the submenu body) is exported container-free so the pill's top-level menu renders it without a Radix Sub wrapper. - The model pill drops the effort suffix (`formatModelPillLabel`: name + Fast); `formatModelStatusLabel` had no other caller and is removed. - `currentModelCapabilities()` in lib/model-options resolves the active pick's caps through `catalogProviderMatches` (aliases, custom slugs). Live (headless Electron + worktree `hermes serve`, CDP): before — one pill "Deepseek V4 Flash · Low", no effort control; after — "Deepseek V4 Flash" + "Low" pill; pick High → `config.get reasoning` on the live session returns high; a `reasoning:false` cap unmounts the pill; the catalog row submenu still writes through and the pill mirrors it. Credit: the dedicated-pill direction was proposed independently in composer selector on current main with the shared-controller shape.