mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 11:55:47 -06:00
perf(telegram): reuse prepared rich message plan (#127719)
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
committed by
GitHub
parent
f6b42ea223
commit
0382ca218a
@@ -219,18 +219,28 @@ export function buildTelegramRichBlocksPlan(
|
||||
};
|
||||
}
|
||||
|
||||
export function splitTelegramRichMessageTextChunks(params: {
|
||||
text: string;
|
||||
textLimit: number;
|
||||
tableMode?: MarkdownTableMode;
|
||||
skipEntityDetection?: boolean;
|
||||
}): TelegramRichTextChunk[] {
|
||||
export function splitTelegramRichMessageTextChunks(
|
||||
params:
|
||||
| {
|
||||
text: string;
|
||||
textLimit: number;
|
||||
tableMode?: MarkdownTableMode;
|
||||
skipEntityDetection?: boolean;
|
||||
}
|
||||
| {
|
||||
plan: TelegramRichMessagePlan;
|
||||
textLimit: number;
|
||||
},
|
||||
): TelegramRichTextChunk[] {
|
||||
// Convert the full markdown document first so fences/tables stay intact, then
|
||||
// enforce block/char limits on the typed block list (including oversized pre).
|
||||
const plan = buildTelegramRichMarkdownPlan(params.text, {
|
||||
tableMode: params.tableMode,
|
||||
skipEntityDetection: params.skipEntityDetection,
|
||||
});
|
||||
const plan =
|
||||
"plan" in params
|
||||
? params.plan
|
||||
: buildTelegramRichMarkdownPlan(params.text, {
|
||||
tableMode: params.tableMode,
|
||||
skipEntityDetection: params.skipEntityDetection,
|
||||
});
|
||||
// The render already committed to the document-level linkify decision (a
|
||||
// skip anywhere disables our file-ref code-wrapping everywhere), so every
|
||||
// chunk must carry the same wire flag; re-deriving per chunk would let
|
||||
@@ -248,7 +258,7 @@ export function splitTelegramRichMessageTextChunks(params: {
|
||||
degradationReasons: index === 0 ? plan.degradationReasons : [],
|
||||
};
|
||||
});
|
||||
if (chunked.length === 0 && params.text.trim()) {
|
||||
if (chunked.length === 0 && "text" in params && params.text.trim()) {
|
||||
// Markdown that projects to zero blocks (e.g. link definitions only) must
|
||||
// still send readable source text instead of silently dropping the reply.
|
||||
const blocks: InputRichBlock[] = [{ type: "paragraph", text: params.text }];
|
||||
|
||||
@@ -106,18 +106,15 @@ export function planTelegramTextDeliveryPages(
|
||||
if (richPlan.richMessage.blocks.length === 0 && params.text.trim()) {
|
||||
return [plainPage(params.text)];
|
||||
}
|
||||
return splitTelegramRichMessageTextChunks({
|
||||
text: params.text,
|
||||
textLimit: maxChars,
|
||||
tableMode: params.tableMode,
|
||||
skipEntityDetection: params.skipEntityDetection,
|
||||
}).map((chunk) => ({
|
||||
plainText: chunk.plainText,
|
||||
sourceText: chunk.plainText,
|
||||
sourceTextMode: "markdown" as const,
|
||||
richMessage: chunk.richMessage,
|
||||
degradationReasons: chunk.degradationReasons,
|
||||
}));
|
||||
return splitTelegramRichMessageTextChunks({ plan: richPlan, textLimit: maxChars }).map(
|
||||
(chunk) => ({
|
||||
plainText: chunk.plainText,
|
||||
sourceText: chunk.plainText,
|
||||
sourceTextMode: "markdown" as const,
|
||||
richMessage: chunk.richMessage,
|
||||
degradationReasons: chunk.degradationReasons,
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (params.textMode === "plain") {
|
||||
return splitTelegramPlainTextChunks(params.text, maxChars)
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
createPluginStateSyncKeyedStoreForTests,
|
||||
resetPluginStateStoreForTests,
|
||||
} from "openclaw/plugin-sdk/plugin-state-test-runtime";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { createTelegramCallbackMessageActions } from "./bot-handlers.callback-actions.js";
|
||||
import { buildTelegramMessageContextForTest } from "./bot-message-context.test-harness.js";
|
||||
import { telegramPlugin } from "./channel.js";
|
||||
@@ -23,6 +23,21 @@ import { sendTypingTelegram } from "./send-actions.js";
|
||||
import { sendMessageTelegram } from "./send-message.js";
|
||||
import { sendPollTelegram } from "./send-special.js";
|
||||
|
||||
const richMarkdownProjection = vi.hoisted(() => ({ count: 0 }));
|
||||
|
||||
vi.mock("./rich-blocks.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("./rich-blocks.js")>();
|
||||
return {
|
||||
...actual,
|
||||
markdownToTelegramRichBlocks: (
|
||||
...args: Parameters<typeof actual.markdownToTelegramRichBlocks>
|
||||
) => {
|
||||
richMarkdownProjection.count += 1;
|
||||
return actual.markdownToTelegramRichBlocks(...args);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
type CapturedRequest = {
|
||||
body: Buffer;
|
||||
contentType: string;
|
||||
@@ -151,6 +166,7 @@ describe("Telegram topic transport payloads", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
requests.length = 0;
|
||||
richMarkdownProjection.count = 0;
|
||||
resetPluginStateStoreForTests();
|
||||
resetTelegramMessageCacheForTest();
|
||||
installTelegramStateRuntimeForTest();
|
||||
@@ -259,6 +275,7 @@ describe("Telegram topic transport payloads", () => {
|
||||
direct_messages_topic_id: DIRECT_TOPIC_ID,
|
||||
});
|
||||
expect(request && parseJsonBody(request)).not.toHaveProperty("message_thread_id");
|
||||
expect(richMarkdownProjection.count).toBe(1);
|
||||
});
|
||||
|
||||
it("rejects poll and typing for channel Direct Messages without transport", async () => {
|
||||
|
||||
Reference in New Issue
Block a user