From a9a8bbe3dd2436c7726f5b1eb988e0247b4587be Mon Sep 17 00:00:00 2001 From: Paul Kloppers Date: Thu, 14 May 2026 00:04:36 +0200 Subject: [PATCH] ui(redstone): dismiss /model keyboard on selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit selectModel was re-rendering the full picker with the โœ… moved to the new pick. Per design feedback, drop the keyboard once a choice is made โ€” the callback toast plus a confirmation body is enough. Keeps the chat tidy after the switch. editMessageText without reply_markup clears the inline keyboard. Co-Authored-By: Claude Opus 4.7 --- bot/bot.ts | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/bot/bot.ts b/bot/bot.ts index e0ddb96..fdaabc2 100644 --- a/bot/bot.ts +++ b/bot/bot.ts @@ -684,31 +684,16 @@ async function selectModel(ctx: Context, modelId: string) { return; } kvSet("llm_model", modelId); - await ctx.answerCallbackQuery({ text: `model: ${modelId}` }); - // Re-render the picker so the โœ… moves to the new pick. + await ctx.answerCallbackQuery({ text: `model set: ${modelId}` }); + // Dismiss the keyboard and replace the picker body with a confirmation. + // editMessageText with no reply_markup clears the inline keyboard. try { - const models = await fetchOpenRouterModels(); - const usable = models.filter((m) => m.supported_parameters?.includes("tools")); - const ROUTER_RE = /^openrouter\/(free|auto)\b/; - const routers = usable.filter((m) => ROUTER_RE.test(m.id)); - const rest = usable.filter((m) => !ROUTER_RE.test(m.id)) - .sort((a, b) => { - const af = isFreeModel(a), bf = isFreeModel(b); - if (af !== bf) return af ? -1 : 1; - return (a.name || a.id).localeCompare(b.name || b.id); - }); - const list = [...routers, ...rest].slice(0, 20); - const kb = new InlineKeyboard(); - for (const m of list) { - kb.text(modelButtonLabel(m, m.id === modelId), `model:${m.id}`).row(); - } - const header = - `๐Ÿง  LLM model picker\n\n` + - `Active: ${escape(modelId)}\n\n` + - `๐ŸŸข free ยท ๐Ÿ’ฐ paid ยท ๐Ÿ›  tools ยท ๐Ÿง  thinking`; - await ctx.editMessageText(header, { parse_mode: "HTML", reply_markup: kb }); + await ctx.editMessageText( + `๐Ÿง  LLM model\n\nActive: ${escape(modelId)}\n\nSwitched. The new model takes effect on the next message.`, + { parse_mode: "HTML" }, + ); } catch { - /* leave keyboard as-is if refresh fails */ + /* edit can fail if the original message is too old; the toast already confirmed */ } }