mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(telegram): preserve tables across legacy message delivery (#118257)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
This commit is contained in:
committed by
GitHub
parent
a1c2009b91
commit
474c4e671e
@@ -323,6 +323,25 @@ describe("deliverReplies", () => {
|
||||
expect(firstMockCallArg(sendMessage, 1)).toBe("hello");
|
||||
});
|
||||
|
||||
it("keeps native-command tables visible in non-rich block-mode replies", async () => {
|
||||
const { runtime, sendMessage, bot } = createSendMessageHarness();
|
||||
const table = "| A | B |\n| --- | --- |\n| 1 | 2 |";
|
||||
|
||||
await deliverWith({
|
||||
replies: [{ text: `Before\n\n${table}\n\nAfter` }],
|
||||
runtime,
|
||||
bot,
|
||||
tableMode: "block",
|
||||
});
|
||||
|
||||
expect(sendMessage).toHaveBeenCalledTimes(1);
|
||||
const sent = firstSendText(sendMessage);
|
||||
expect(sent).toContain("Before");
|
||||
expect(sent).toContain(`<pre><code>${table}\n</code></pre>`);
|
||||
expect(sent).toContain("After");
|
||||
expectRecordFields(firstMockCallArg(sendMessage, 2), { parse_mode: "HTML" });
|
||||
});
|
||||
|
||||
it("delivers prepared HTML without reparsing visible syntax as Markdown", async () => {
|
||||
const runtime = createRuntime();
|
||||
const sendMessage = vi.fn().mockResolvedValue({ message_id: 1, chat: { id: "123" } });
|
||||
|
||||
@@ -139,12 +139,24 @@ describe("markdownToTelegramHtml", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("renders block-mode tables as code in legacy Telegram HTML", () => {
|
||||
it.each([
|
||||
{ name: "a table-only reply", before: "", after: "" },
|
||||
{ name: "a table between surrounding prose", before: "Before\n\n", after: "\n\nAfter" },
|
||||
])("keeps $name visible in one-shot and chunked legacy Telegram HTML", ({ before, after }) => {
|
||||
const table = "| A | B |\n| --- | --- |\n| 1 | 2 |";
|
||||
const markdown = `${before}${table}${after}`;
|
||||
const html = markdownToTelegramHtml(markdown, { tableMode: "block" });
|
||||
const chunks = markdownToTelegramChunks(markdown, 4096, { tableMode: "block" });
|
||||
|
||||
expect(markdownToTelegramHtml(table, { tableMode: "block" })).toBe(
|
||||
"<pre><code>| A | B |\n| --- | --- |\n| 1 | 2 |\n</code></pre>",
|
||||
);
|
||||
expect(html).toContain(`<pre><code>${table}\n</code></pre>`);
|
||||
expect(chunks.map((chunk) => chunk.html)).toEqual([html]);
|
||||
expect(chunks[0]?.text).toContain("| 1 | 2 |");
|
||||
if (before) {
|
||||
expect(html).toContain("Before");
|
||||
}
|
||||
if (after) {
|
||||
expect(html).toContain("After");
|
||||
}
|
||||
});
|
||||
|
||||
it("normalizes raw code language HTML without leaking tags", () => {
|
||||
|
||||
@@ -147,19 +147,22 @@ function preserveTelegramListBoundarySpacing(markdown: string): string {
|
||||
return out.join("\n");
|
||||
}
|
||||
|
||||
export function markdownToTelegramHtml(
|
||||
markdown: string,
|
||||
options: { tableMode?: MarkdownTableMode; wrapFileRefs?: boolean } = {},
|
||||
): string {
|
||||
const tableMode = options.tableMode === "block" ? "code" : options.tableMode;
|
||||
const ir = markdownToIR(preserveTelegramListBoundarySpacing(markdown ?? ""), {
|
||||
function parseTelegramLegacyMarkdown(markdown: string, tableMode?: MarkdownTableMode): MarkdownIR {
|
||||
return markdownToIR(preserveTelegramListBoundarySpacing(markdown ?? ""), {
|
||||
assistantTranscriptRoleHeaders: true,
|
||||
linkify: true,
|
||||
enableSpoilers: true,
|
||||
headingStyle: "none",
|
||||
blockquotePrefix: "",
|
||||
tableMode,
|
||||
tableMode: tableMode === "block" ? "code" : tableMode,
|
||||
});
|
||||
}
|
||||
|
||||
export function markdownToTelegramHtml(
|
||||
markdown: string,
|
||||
options: { tableMode?: MarkdownTableMode; wrapFileRefs?: boolean } = {},
|
||||
): string {
|
||||
const ir = parseTelegramLegacyMarkdown(markdown, options.tableMode);
|
||||
const html = renderTelegramHtml(ir);
|
||||
const telegramHtml = renderSupportedTelegramHtml(html);
|
||||
// Apply file reference wrapping if requested (for chunked rendering)
|
||||
@@ -910,14 +913,7 @@ export function markdownToTelegramChunks(
|
||||
limit: number,
|
||||
options: { tableMode?: MarkdownTableMode } = {},
|
||||
): TelegramFormattedChunk[] {
|
||||
const ir = markdownToIR(preserveTelegramListBoundarySpacing(markdown ?? ""), {
|
||||
assistantTranscriptRoleHeaders: true,
|
||||
linkify: true,
|
||||
enableSpoilers: true,
|
||||
headingStyle: "none",
|
||||
blockquotePrefix: "",
|
||||
tableMode: options.tableMode,
|
||||
});
|
||||
const ir = parseTelegramLegacyMarkdown(markdown, options.tableMode);
|
||||
return renderTelegramChunksWithinHtmlLimit(ir, limit);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user