fix(adapter-telegram): support MarkdownV2#405
Closed
fuxingloh wants to merge 2 commits intovercel:mainfrom
Closed
Conversation
Contributor
|
@fuxingloh is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
1 task
Contributor
|
done in #407 but thank you ❤️ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
chat-adapter-telegram@4.25.0.patch — drop-in patch for local testing
Problem
Telegram rejected most LLM replies with:
.,(,),-,|,!appear in ordinary prose, so this fired constantly. Downstream harnesses worked around it by wrappingthread.post(result.fullStream)in atry/catchthat fell back to plain text — doubling latency and dropping the stream.Root cause: the adapter sent
parse_mode: "Markdown"(legacy) and passed through text fromremark-stringify, which does not escape the 18 characters MarkdownV2 reserves.Fix
Switch to
parse_mode: "MarkdownV2"and replaceTelegramFormatConverter.fromAstwith an mdast walker that applies context-aware escaping per the Telegram spec._ * [ ] ( ) ~ \> # + - = | { } . !`code/pre`and\(…))and\Also:
*…*, italic →_…_, strike →~…~, headings → bold.\-, ordered numerals asN\..\-\-\-.renderPostable(string)now escapes plain strings — safe default for raw LLM output.renderPostable({ raw })still passes through unescaped (caller opt-in).Migration
No API changes. Output format differs:
**bold**→*bold**italic*→_italic_~~strike~~→~strike~Callers hand-crafting legacy-Markdown strings and passing them via
{ raw }will now render as literal text. Switch to{ markdown }for proper conversion.Sources
escapeSymbolssemantics cross-checked againsttelegram-markdown-v2.Testing
pnpm --filter @chat-adapter/telegram test— 103/103 pass (60 index, 9 cards, 34 markdown).pnpm --filter @chat-adapter/telegram typecheck— clean.pnpm --filter @chat-adapter/telegram build— clean.New
markdown.test.tscases cover:.,(,),/,!(the exact trigger from the bug report).`and\escaped inside inline code.)escaped inside link URLs.*,_,~).>.Updated
index.test.tsassertions fromparse_mode === "Markdown"to"MarkdownV2".Changeset:
.changeset/telegram-markdown-v2-escape.md(minor).Test plan
chat-adapter-telegram@4.25.0.patchlocally and verify in a real chat for a week.