fix(telegram): sanitize outbound markdown for legacy parse mode
The @chat-adapter/telegram adapter hardcodes parse_mode=Markdown (legacy) but its converter emits CommonMark. Messages containing **bold** or list bullets that round-trip to `*` produce "can't parse entities" errors and get dropped after retries. Add an opt-in transformOutboundText hook on the chat-sdk bridge and wire a Telegram-specific sanitizer that downgrades **bold** to *bold*, rewrites dash/plus list bullets to a Unicode bullet so the adapter's re-stringify doesn't inject stray `*`, and strips unbalanced delimiters or brackets. Only Telegram opts in; other channels are unaffected. Workaround until upstream (vercel/chat) ships mode-aware conversion — PR #367 adds a parseMode knob but not the converter fix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -57,10 +57,18 @@ export interface ChatSdkBridgeConfig {
|
||||
* way and the default depends on installation style.
|
||||
*/
|
||||
supportsThreads: boolean;
|
||||
/**
|
||||
* Optional transform applied to outbound text/markdown before it reaches the
|
||||
* adapter. Used by channels that need to sanitize for a platform-specific
|
||||
* quirk (e.g. Telegram's legacy Markdown parse mode).
|
||||
*/
|
||||
transformOutboundText?: (text: string) => string;
|
||||
}
|
||||
|
||||
export function createChatSdkBridge(config: ChatSdkBridgeConfig): ChannelAdapter {
|
||||
const { adapter } = config;
|
||||
const transformText = (t: string): string =>
|
||||
config.transformOutboundText ? config.transformOutboundText(t) : t;
|
||||
let chat: Chat;
|
||||
let state: SqliteStateAdapter;
|
||||
let setupConfig: ChannelSetup;
|
||||
@@ -321,7 +329,7 @@ export function createChatSdkBridge(config: ChatSdkBridgeConfig): ChannelAdapter
|
||||
|
||||
if (content.operation === 'edit' && content.messageId) {
|
||||
await adapter.editMessage(tid, content.messageId as string, {
|
||||
markdown: (content.text as string) || (content.markdown as string) || '',
|
||||
markdown: transformText((content.text as string) || (content.markdown as string) || ''),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -370,7 +378,8 @@ export function createChatSdkBridge(config: ChatSdkBridgeConfig): ChannelAdapter
|
||||
}
|
||||
|
||||
// Normal message
|
||||
const text = (content.markdown as string) || (content.text as string);
|
||||
const rawText = (content.markdown as string) || (content.text as string);
|
||||
const text = rawText ? transformText(rawText) : rawText;
|
||||
if (text) {
|
||||
// Attach files if present (FileUpload format: { data, filename })
|
||||
const fileUploads = message.files?.map((f: { data: Buffer; filename: string }) => ({
|
||||
|
||||
Reference in New Issue
Block a user