




























@@ -30,6 +30,7 @@ import {
3030type ChannelProgressDraftLine,
3131type ChannelProgressDraftCompositorLine,
3232createChannelProgressDraftCompositor,
33+resolveChannelProgressDraftLabel,
3334resolveChannelStreamingBlockEnabled,
3435resolveTranscriptBackedChannelFinalText,
3536} from "openclaw/plugin-sdk/channel-outbound";
@@ -152,7 +153,6 @@ const silentReplyDispatchLogger = createSubsystemLogger("telegram/silent-reply-d
152153153154/** Minimum chars before sending first streaming message (improves push notification UX) */
154155const DRAFT_MIN_INITIAL_CHARS = 30;
155-const DRAFT_MIN_INITIAL_DELAY_MS = 5_000;
156156157157type DraftPartialTextUpdate = {
158158text: string;
@@ -434,18 +434,6 @@ function sanitizeProgressMarkdownText(text: string): string {
434434return text.replaceAll("`", "'");
435435}
436436437-function formatProgressAsMarkdownCode(text: string): string {
438-const clipped = clipProgressMarkdownText(text);
439-return `\`${sanitizeProgressMarkdownText(clipped)}\``;
440-}
441-442-function formatTelegramProgressLine(text: string): string {
443-const trimmed = text.trim();
444-return trimmed.startsWith("_") && trimmed.endsWith("_")
445- ? trimmed
446- : formatProgressAsMarkdownCode(text);
447-}
448-449437function escapeTelegramProgressHtml(text: string): string {
450438return text
451439.replaceAll("&", "&")
@@ -454,21 +442,39 @@ function escapeTelegramProgressHtml(text: string): string {
454442.replaceAll('"', """);
455443}
456444457-function renderTelegramProgressStringLine(text: string): string {
458-const clipped = clipProgressMarkdownText(text.trim());
445+function normalizeTelegramProgressText(text: string, options?: { trim?: boolean }): string {
446+const source = options?.trim === false ? text : text.trim();
447+const clipped = clipProgressMarkdownText(source);
459448const italic = clipped.match(/^_(.*)_$/u);
460449if (italic) {
461-return `<i>${escapeTelegramProgressHtml(italic[1] ?? "")}</i>`;
450+return italic[1] ?? "";
451+}
452+return clipped;
453+}
454+455+function formatTelegramProgressLine(text: string): string {
456+return sanitizeProgressMarkdownText(normalizeTelegramProgressText(text, { trim: false }));
457+}
458+459+function renderTelegramProgressHtmlStringLine(text: string): string {
460+const normalized = normalizeTelegramProgressText(text);
461+const italic = text.trim().match(/^_(.*)_$/u);
462+if (italic) {
463+return `<i>${escapeTelegramProgressHtml(normalized)}</i>`;
462464}
463-return `<code>${escapeTelegramProgressHtml(clipped)}</code>`;
465+return `<code>${escapeTelegramProgressHtml(normalized)}</code>`;
464466}
465467466-function renderTelegramProgressLine(line: ChannelProgressDraftCompositorLine): string {
468+function renderTelegramProgressHtmlLine(line: ChannelProgressDraftCompositorLine): string {
467469if (typeof line === "string") {
468-return line.split(/\r?\n/u).map(renderTelegramProgressStringLine).filter(Boolean).join("<br>");
470+return line
471+.split(/\r?\n/u)
472+.map(renderTelegramProgressHtmlStringLine)
473+.filter(Boolean)
474+.join("\n");
469475}
470476if (!line.icon && line.label === "Commentary") {
471-return renderTelegramProgressStringLine(line.text);
477+return renderTelegramProgressHtmlStringLine(line.text);
472478}
473479const label = [line.icon, line.label].filter(Boolean).join(" ");
474480const parts = [`<b>${escapeTelegramProgressHtml(label)}</b>`];
@@ -478,7 +484,7 @@ function renderTelegramProgressLine(line: ChannelProgressDraftCompositorLine): s
478484} else {
479485const text = line.text.trim();
480486if (text && text !== label) {
481-parts.push(renderTelegramProgressStringLine(text));
487+parts.push(renderTelegramProgressHtmlStringLine(text));
482488}
483489}
484490if (line.status && line.status !== "completed" && line.status !== line.detail) {
@@ -490,18 +496,19 @@ function renderTelegramProgressLine(line: ChannelProgressDraftCompositorLine): s
490496function renderTelegramProgressDraftPreview(
491497text: string,
492498lines: readonly ChannelProgressDraftCompositorLine[],
493-richMessages: boolean,
499+label: string | undefined,
494500): TelegramDraftPreview {
495501const trimmed = text.trimEnd();
496-const [heading] = trimmed.split(/\r?\n/u, 1);
497-const renderedLines = lines.map(renderTelegramProgressLine).filter(Boolean);
498-const htmlParts = heading?.trim()
499- ? [`<b>${escapeTelegramProgressHtml(heading.trim())}</b>`, ...renderedLines]
500- : renderedLines;
501-const html = htmlParts.join("<br>");
502-if (!richMessages) {
503-return { text: html, parseMode: "HTML" };
504-}
502+const textLines = trimmed.split(/\r?\n/u);
503+const labelVisible =
504+label !== undefined && (trimmed === label || (textLines[0] === label && textLines[1] === ""));
505+const bodyLines = labelVisible ? textLines.slice(textLines[1] === "" ? 2 : 1) : textLines;
506+const renderedLines = lines.map(renderTelegramProgressHtmlLine).filter(Boolean);
507+const visibleLines = renderedLines.slice(-bodyLines.filter(Boolean).length);
508+const htmlParts = labelVisible
509+ ? [`<b>${escapeTelegramProgressHtml(label)}</b>`, ...visibleLines]
510+ : visibleLines;
511+const html = htmlParts.join("\n");
505512return {
506513text: trimmed,
507514richMessage: buildTelegramRichHtml(html, { skipEntityDetection: true }),
@@ -1029,7 +1036,6 @@ export const dispatchTelegramMessage = async ({
10291036replyToMessageId: draftReplyToMessageId,
10301037richMessages: telegramCfg.richMessages,
10311038minInitialChars: draftMinInitialChars,
1032-minInitialDelayMs: draftMinInitialChars > 0 ? DRAFT_MIN_INITIAL_DELAY_MS : undefined,
10331039renderText: renderStreamText,
10341040onSupersededPreview: (superseded) => {
10351041if (superseded.retain) {
@@ -1107,7 +1113,7 @@ export const dispatchTelegramMessage = async ({
11071113renderTelegramProgressDraftPreview(
11081114streamText,
11091115options?.lines ?? [],
1110-telegramCfg.richMessages === true,
1116+resolveChannelProgressDraftLabel({ entry: telegramCfg, seed: progressSeed }),
11111117),
11121118);
11131119if (options?.flush) {
@@ -1389,7 +1395,7 @@ export const dispatchTelegramMessage = async ({
13891395recomputeQueuedAnswerBlockRotations();
13901396}
13911397};
1392-const updateDraftFromPartial = async (lane: DraftLaneState, update: DraftPartialTextUpdate) => {
1398+const updateDraftFromPartial = (lane: DraftLaneState, update: DraftPartialTextUpdate) => {
13931399const laneStream = lane.stream;
13941400if (!laneStream || !update.text) {
13951401return;
@@ -1401,7 +1407,6 @@ export const dispatchTelegramMessage = async ({
14011407}
14021408if (lane === answerLane) {
14031409if (streamMode === "progress") {
1404-await progressDraft.noteActivity();
14051410return;
14061411}
14071412resetAnswerToolProgressDraft();
@@ -1428,7 +1433,7 @@ export const dispatchTelegramMessage = async ({
14281433reasoningStepState.noteReasoningHint();
14291434reasoningStepState.noteReasoningDelivered();
14301435}
1431-await updateDraftFromPartial(lanes[segment.lane], segment.update);
1436+updateDraftFromPartial(lanes[segment.lane], segment.update);
14321437}
14331438};
14341439const flushDraftLane = async (lane: DraftLaneState) => {
@@ -2145,9 +2150,6 @@ export const dispatchTelegramMessage = async ({
21452150}
21462151if (segment.lane === "answer" && info.kind === "tool") {
21472152if (verboseProgressActive()) {
2148-if (streamMode === "progress") {
2149-await rotateAnswerLaneAfterToolProgress();
2150-}
21512153if (
21522154await sendPayload(
21532155applyTextToPayload(effectivePayload, segment.update.text),
@@ -2299,9 +2301,6 @@ export const dispatchTelegramMessage = async ({
22992301}
23002302return;
23012303}
2302-if (streamMode === "progress" && info.kind === "tool") {
2303-await rotateAnswerLaneAfterToolProgress();
2304-}
23052304const delivered = await sendPayload(effectivePayload, {
23062305durable: info.kind === "final",
23072306});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。