fix: add per-channel markdown table conversion (#1495) (thanks @odysseus0)
This commit is contained in:
@@ -8,6 +8,7 @@ import { EmbeddedBlockChunker } from "../agents/pi-embedded-block-chunker.js";
|
||||
import { clearHistoryEntries } from "../auto-reply/reply/history.js";
|
||||
import { dispatchReplyWithBufferedBlockDispatcher } from "../auto-reply/reply/provider-dispatcher.js";
|
||||
import { danger, logVerbose } from "../globals.js";
|
||||
import { resolveMarkdownTableMode } from "../config/markdown-tables.js";
|
||||
import { deliverReplies } from "./bot/delivery.js";
|
||||
import { resolveTelegramDraftStreamingChunking } from "./draft-chunking.js";
|
||||
import { createTelegramDraftStream } from "./draft-stream.js";
|
||||
@@ -123,6 +124,11 @@ export const dispatchTelegramMessage = async ({
|
||||
let prefixContext: ResponsePrefixContext = {
|
||||
identityName: resolveIdentityName(cfg, route.agentId),
|
||||
};
|
||||
const tableMode = resolveMarkdownTableMode({
|
||||
cfg,
|
||||
channel: "telegram",
|
||||
accountId: route.accountId,
|
||||
});
|
||||
|
||||
const { queuedFinal } = await dispatchReplyWithBufferedBlockDispatcher({
|
||||
ctx: ctxPayload,
|
||||
@@ -144,6 +150,7 @@ export const dispatchTelegramMessage = async ({
|
||||
replyToMode,
|
||||
textLimit,
|
||||
messageThreadId: resolvedThreadId,
|
||||
tableMode,
|
||||
onVoiceRecording: sendRecordVoice,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -15,6 +15,7 @@ import { resolveTelegramCustomCommands } from "../config/telegram-custom-command
|
||||
import { dispatchReplyWithBufferedBlockDispatcher } from "../auto-reply/reply/provider-dispatcher.js";
|
||||
import { finalizeInboundContext } from "../auto-reply/reply/inbound-context.js";
|
||||
import { danger, logVerbose } from "../globals.js";
|
||||
import { resolveMarkdownTableMode } from "../config/markdown-tables.js";
|
||||
import { resolveAgentRoute } from "../routing/resolve-route.js";
|
||||
import { resolveCommandAuthorizedFromAuthorizers } from "../channels/command-gating.js";
|
||||
import type { ChannelGroupPolicy } from "../config/group-policy.js";
|
||||
@@ -269,6 +270,11 @@ export const registerTelegramNativeCommands = ({
|
||||
id: isGroup ? buildTelegramGroupPeerId(chatId, resolvedThreadId) : String(chatId),
|
||||
},
|
||||
});
|
||||
const tableMode = resolveMarkdownTableMode({
|
||||
cfg,
|
||||
channel: "telegram",
|
||||
accountId: route.accountId,
|
||||
});
|
||||
const skillFilter = firstDefined(topicConfig?.skills, groupConfig?.skills);
|
||||
const systemPromptParts = [
|
||||
groupConfig?.systemPrompt?.trim() || null,
|
||||
@@ -327,6 +333,7 @@ export const registerTelegramNativeCommands = ({
|
||||
replyToMode,
|
||||
textLimit,
|
||||
messageThreadId: resolvedThreadId,
|
||||
tableMode,
|
||||
});
|
||||
},
|
||||
onError: (err, info) => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { markdownToTelegramChunks, markdownToTelegramHtml } from "../format.js";
|
||||
import { splitTelegramCaption } from "../caption.js";
|
||||
import type { ReplyPayload } from "../../auto-reply/types.js";
|
||||
import type { ReplyToMode } from "../../config/config.js";
|
||||
import type { MarkdownTableMode } from "../../config/types.base.js";
|
||||
import { danger, logVerbose } from "../../globals.js";
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
import { mediaKindFromMime } from "../../media/constants.js";
|
||||
@@ -26,6 +27,7 @@ export async function deliverReplies(params: {
|
||||
replyToMode: ReplyToMode;
|
||||
textLimit: number;
|
||||
messageThreadId?: number;
|
||||
tableMode?: MarkdownTableMode;
|
||||
/** Callback invoked before sending a voice message to switch typing indicator. */
|
||||
onVoiceRecording?: () => Promise<void> | void;
|
||||
}) {
|
||||
@@ -49,7 +51,9 @@ export async function deliverReplies(params: {
|
||||
? [reply.mediaUrl]
|
||||
: [];
|
||||
if (mediaList.length === 0) {
|
||||
const chunks = markdownToTelegramChunks(reply.text || "", textLimit);
|
||||
const chunks = markdownToTelegramChunks(reply.text || "", textLimit, {
|
||||
tableMode: params.tableMode,
|
||||
});
|
||||
for (const chunk of chunks) {
|
||||
await sendTelegramText(bot, chatId, chunk.html, runtime, {
|
||||
replyToMessageId:
|
||||
@@ -139,7 +143,9 @@ export async function deliverReplies(params: {
|
||||
// Send deferred follow-up text right after the first media item.
|
||||
// Chunk it in case it's extremely long (same logic as text-only replies).
|
||||
if (pendingFollowUpText && isFirstMedia) {
|
||||
const chunks = markdownToTelegramChunks(pendingFollowUpText, textLimit);
|
||||
const chunks = markdownToTelegramChunks(pendingFollowUpText, textLimit, {
|
||||
tableMode: params.tableMode,
|
||||
});
|
||||
for (const chunk of chunks) {
|
||||
const replyToMessageIdFollowup =
|
||||
replyToId && (replyToMode === "all" || !hasReplied) ? replyToId : undefined;
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
type MarkdownIR,
|
||||
} from "../markdown/ir.js";
|
||||
import { renderMarkdownWithMarkers } from "../markdown/render.js";
|
||||
import type { MarkdownTableMode } from "../config/types.base.js";
|
||||
|
||||
export type TelegramFormattedChunk = {
|
||||
html: string;
|
||||
@@ -46,12 +47,15 @@ function renderTelegramHtml(ir: MarkdownIR): string {
|
||||
});
|
||||
}
|
||||
|
||||
export function markdownToTelegramHtml(markdown: string): string {
|
||||
export function markdownToTelegramHtml(
|
||||
markdown: string,
|
||||
options: { tableMode?: MarkdownTableMode } = {},
|
||||
): string {
|
||||
const ir = markdownToIR(markdown ?? "", {
|
||||
linkify: true,
|
||||
headingStyle: "none",
|
||||
blockquotePrefix: "",
|
||||
tableMode: "bullets",
|
||||
tableMode: options.tableMode,
|
||||
});
|
||||
return renderTelegramHtml(ir);
|
||||
}
|
||||
@@ -59,12 +63,13 @@ export function markdownToTelegramHtml(markdown: string): string {
|
||||
export function markdownToTelegramChunks(
|
||||
markdown: string,
|
||||
limit: number,
|
||||
options: { tableMode?: MarkdownTableMode } = {},
|
||||
): TelegramFormattedChunk[] {
|
||||
const ir = markdownToIR(markdown ?? "", {
|
||||
linkify: true,
|
||||
headingStyle: "none",
|
||||
blockquotePrefix: "",
|
||||
tableMode: "bullets",
|
||||
tableMode: options.tableMode,
|
||||
});
|
||||
const chunks = chunkMarkdownIR(ir, limit);
|
||||
return chunks.map((chunk) => ({
|
||||
|
||||
@@ -17,6 +17,7 @@ import { loadWebMedia } from "../web/media.js";
|
||||
import { resolveTelegramAccount } from "./accounts.js";
|
||||
import { resolveTelegramFetch } from "./fetch.js";
|
||||
import { markdownToTelegramHtml } from "./format.js";
|
||||
import { resolveMarkdownTableMode } from "../config/markdown-tables.js";
|
||||
import { splitTelegramCaption } from "./caption.js";
|
||||
import { recordSentMessage } from "./sent-message-cache.js";
|
||||
import { parseTelegramTarget, stripTelegramInternalPrefixes } from "./targets.js";
|
||||
@@ -310,7 +311,12 @@ export async function sendMessageTelegram(
|
||||
throw new Error("Message must be non-empty for Telegram sends");
|
||||
}
|
||||
const textMode = opts.textMode ?? "markdown";
|
||||
const htmlText = textMode === "html" ? text : markdownToTelegramHtml(text);
|
||||
const tableMode = resolveMarkdownTableMode({
|
||||
cfg,
|
||||
channel: "telegram",
|
||||
accountId: account.accountId,
|
||||
});
|
||||
const htmlText = textMode === "html" ? text : markdownToTelegramHtml(text, { tableMode });
|
||||
const textParams = hasThreadParams
|
||||
? {
|
||||
parse_mode: "HTML" as const,
|
||||
|
||||
Reference in New Issue
Block a user