From f2b54d18d8a55091083b0b0ce90dcd07bb4c7f2c Mon Sep 17 00:00:00 2001 From: Peter Lindsey Date: Sun, 14 Jun 2026 12:47:20 +0800 Subject: [PATCH] feat(usage): make built-in default footer Telegram-friendly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The built-in default footer (added in #92657) only defined a `discord` surface. Telegram and every other surface fall through to `output.default`, which was authored for a wide terminal: space-separated badges, a leading space-less join onto the message body, and ↕️ token + 🗄 cache% segments. On a narrow Telegram screen this wrapped at arbitrary spaces (often mid-meter or between 📚 and its bar) and welded onto the end of the message text. Make `default` read well on a phone: - Leading \n so the footer sits on its own line below the body. - Tight badges (no separators between model/flags/reasoning/fast). - NBSP before "|" and 💰; 📚 glued hard to the meter so it can't wrap there. - Single regular space after "|" as the only sanctioned wrap point. - Drop ↕️ tokens and 🗄 cache% from the default — noise for most users (still available to anyone via a custom messages.usageTemplate). Discord surface trimmed to match for consistency (keeps its -# dim header). --- src/auto-reply/usage-bar/default-template.ts | 43 +++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/auto-reply/usage-bar/default-template.ts b/src/auto-reply/usage-bar/default-template.ts index 9a042c8e87bc..910994276002 100644 --- a/src/auto-reply/usage-bar/default-template.ts +++ b/src/auto-reply/usage-bar/default-template.ts @@ -24,43 +24,38 @@ export const DEFAULT_USAGE_BAR_TEMPLATE: UsageBarTemplate = { }, output: { sep: "", + // Telegram (and any surface without its own list) falls through to `default`, + // so the default is built to read well on a narrow phone screen: + // - Tight badges: no separators between model/flags/reasoning/fast. + // - NBSP (\u00A0) before "|" and before 💰 keeps those joins non-breaking. + // - 📚 is glued hard to the meter so it can't wrap between books and bars. + // - The single regular space after "|" is the only sanctioned wrap point. + // - Leading \n drops the footer onto its own line, below the message body. default: [ - { text: "{model.provider}{identity.emoji|🤖} {model.display_name|alias:models}" }, - { map: "model.is_fallback", cases: { true: " 🔄" } }, - { map: "model.is_override", cases: { true: " 📌" } }, - { when: "model.reasoning", text: " {model.reasoning|alias:reasoning}" }, - { map: "state.fast_mode", cases: { true: " ⚡", false: " 🐌" } }, + { text: "\n{model.provider}{identity.emoji|🤖}{model.display_name|alias:models}" }, + { map: "model.is_fallback", cases: { true: "🔄" } }, + { map: "model.is_override", cases: { true: "📌" } }, + { when: "model.reasoning", text: "{model.reasoning|alias:reasoning}" }, + { map: "state.fast_mode", cases: { true: "⚡️", false: "🐌" } }, { when: "context.max_tokens", - text: " | 📚 [{context.pct_used|meter:5:braille}]{context.max_tokens|num}", + text: "\u00A0| 📚[{context.pct_used|meter:5:braille}]{context.max_tokens|num}", }, - { - when: "usage.has_split_tokens", - text: " ↕️ {usage.input_tokens|num|?}/{usage.output_tokens|num|?}", - }, - { when: "usage.has_total_only_tokens", text: " ↕️ {usage.total_tokens|num}" }, - { when: "usage.cache_hit_pct", text: " 🗄 {usage.cache_hit_pct|pct}" }, - { when: "cost.turn_usd", text: " 💰{cost.turn_usd|fixed:4}" }, + { when: "cost.turn_usd", text: "\u00A0💰{cost.turn_usd|fixed:4}" }, ], surfaces: { discord: [ { text: "-# -\n" }, - { text: "-# {model.provider}{identity.emoji|🤖} {model.display_name|alias:models}" }, + { text: "-# {model.provider}{identity.emoji|🤖}{model.display_name|alias:models}" }, { map: "model.is_fallback", cases: { true: "🔄" } }, { map: "model.is_override", cases: { true: "📌" } }, - { when: "model.reasoning", text: " {model.reasoning|alias:reasoning}" }, - { map: "state.fast_mode", cases: { true: " ⚡️", false: " 🐌" } }, + { when: "model.reasoning", text: "{model.reasoning|alias:reasoning}" }, + { map: "state.fast_mode", cases: { true: "⚡️", false: "🐌" } }, { when: "context.max_tokens", - text: " | 📚 [{context.pct_used|meter:5:braille}]{context.max_tokens|num}", + text: "\u00A0| 📚[{context.pct_used|meter:5:braille}]{context.max_tokens|num}", }, - { - when: "usage.has_split_tokens", - text: " ↕️ {usage.input_tokens|num|?}/{usage.output_tokens|num|?}", - }, - { when: "usage.has_total_only_tokens", text: " ↕️ {usage.total_tokens|num}" }, - { when: "usage.cache_hit_pct", text: " 🗄 {usage.cache_hit_pct|pct}" }, - { when: "cost.turn_usd", text: " 💰{cost.turn_usd|fixed:4}" }, + { when: "cost.turn_usd", text: "\u00A0💰{cost.turn_usd|fixed:4}" }, ], }, },