mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 11:00:21 +00:00
fix: add per-channel markdown table conversion (#1495) (thanks @odysseus0)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { chunkMarkdownIR, markdownToIR, type MarkdownLinkSpan } from "../markdown/ir.js";
|
||||
import type { MarkdownTableMode } from "../config/types.base.js";
|
||||
import { renderMarkdownWithMarkers } from "../markdown/render.js";
|
||||
|
||||
// Escape special characters for Slack mrkdwn format.
|
||||
@@ -83,12 +84,20 @@ function buildSlackLink(link: MarkdownLinkSpan, text: string) {
|
||||
};
|
||||
}
|
||||
|
||||
export function markdownToSlackMrkdwn(markdown: string): string {
|
||||
type SlackMarkdownOptions = {
|
||||
tableMode?: MarkdownTableMode;
|
||||
};
|
||||
|
||||
export function markdownToSlackMrkdwn(
|
||||
markdown: string,
|
||||
options: SlackMarkdownOptions = {},
|
||||
): string {
|
||||
const ir = markdownToIR(markdown ?? "", {
|
||||
linkify: false,
|
||||
autolink: false,
|
||||
headingStyle: "bold",
|
||||
blockquotePrefix: "> ",
|
||||
tableMode: options.tableMode,
|
||||
});
|
||||
return renderMarkdownWithMarkers(ir, {
|
||||
styleMarkers: {
|
||||
@@ -103,12 +112,17 @@ export function markdownToSlackMrkdwn(markdown: string): string {
|
||||
});
|
||||
}
|
||||
|
||||
export function markdownToSlackMrkdwnChunks(markdown: string, limit: number): string[] {
|
||||
export function markdownToSlackMrkdwnChunks(
|
||||
markdown: string,
|
||||
limit: number,
|
||||
options: SlackMarkdownOptions = {},
|
||||
): string[] {
|
||||
const ir = markdownToIR(markdown ?? "", {
|
||||
linkify: false,
|
||||
autolink: false,
|
||||
headingStyle: "bold",
|
||||
blockquotePrefix: "> ",
|
||||
tableMode: options.tableMode,
|
||||
});
|
||||
const chunks = chunkMarkdownIR(ir, limit);
|
||||
return chunks.map((chunk) =>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createReplyReferencePlanner } from "../../auto-reply/reply/reply-reference.js";
|
||||
import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../../auto-reply/tokens.js";
|
||||
import type { ReplyPayload } from "../../auto-reply/types.js";
|
||||
import type { MarkdownTableMode } from "../../config/types.base.js";
|
||||
import type { RuntimeEnv } from "../../runtime.js";
|
||||
import { markdownToSlackMrkdwnChunks } from "../format.js";
|
||||
import { sendMessageSlack } from "../send.js";
|
||||
@@ -116,6 +117,7 @@ export async function deliverSlackSlashReplies(params: {
|
||||
respond: SlackRespondFn;
|
||||
ephemeral: boolean;
|
||||
textLimit: number;
|
||||
tableMode?: MarkdownTableMode;
|
||||
}) {
|
||||
const messages: string[] = [];
|
||||
const chunkLimit = Math.min(params.textLimit, 4000);
|
||||
@@ -127,7 +129,9 @@ export async function deliverSlackSlashReplies(params: {
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
if (!combined) continue;
|
||||
for (const chunk of markdownToSlackMrkdwnChunks(combined, chunkLimit)) {
|
||||
for (const chunk of markdownToSlackMrkdwnChunks(combined, chunkLimit, {
|
||||
tableMode: params.tableMode,
|
||||
})) {
|
||||
messages.push(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { listSkillCommandsForAgents } from "../../auto-reply/skill-commands.js";
|
||||
import { dispatchReplyWithDispatcher } from "../../auto-reply/reply/provider-dispatcher.js";
|
||||
import { finalizeInboundContext } from "../../auto-reply/reply/inbound-context.js";
|
||||
import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "../../config/commands.js";
|
||||
import { resolveMarkdownTableMode } from "../../config/markdown-tables.js";
|
||||
import { danger, logVerbose } from "../../globals.js";
|
||||
import { buildPairingReply } from "../../pairing/pairing-messages.js";
|
||||
import {
|
||||
@@ -424,6 +425,11 @@ export function registerSlackMonitorSlashCommands(params: {
|
||||
respond,
|
||||
ephemeral: slashCommand.ephemeral,
|
||||
textLimit: ctx.textLimit,
|
||||
tableMode: resolveMarkdownTableMode({
|
||||
cfg,
|
||||
channel: "slack",
|
||||
accountId: route.accountId,
|
||||
}),
|
||||
});
|
||||
},
|
||||
onError: (err, info) => {
|
||||
@@ -438,6 +444,11 @@ export function registerSlackMonitorSlashCommands(params: {
|
||||
respond,
|
||||
ephemeral: slashCommand.ephemeral,
|
||||
textLimit: ctx.textLimit,
|
||||
tableMode: resolveMarkdownTableMode({
|
||||
cfg,
|
||||
channel: "slack",
|
||||
accountId: route.accountId,
|
||||
}),
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { SlackTokenSource } from "./accounts.js";
|
||||
import { resolveSlackAccount } from "./accounts.js";
|
||||
import { createSlackWebClient } from "./client.js";
|
||||
import { markdownToSlackMrkdwnChunks } from "./format.js";
|
||||
import { resolveMarkdownTableMode } from "../config/markdown-tables.js";
|
||||
import { parseSlackTarget } from "./targets.js";
|
||||
import { resolveSlackBotToken } from "./token.js";
|
||||
|
||||
@@ -143,7 +144,12 @@ export async function sendMessageSlack(
|
||||
const { channelId } = await resolveChannelId(client, recipient);
|
||||
const textLimit = resolveTextChunkLimit(cfg, "slack", account.accountId);
|
||||
const chunkLimit = Math.min(textLimit, SLACK_TEXT_LIMIT);
|
||||
const chunks = markdownToSlackMrkdwnChunks(trimmedMessage, chunkLimit);
|
||||
const tableMode = resolveMarkdownTableMode({
|
||||
cfg,
|
||||
channel: "slack",
|
||||
accountId: account.accountId,
|
||||
});
|
||||
const chunks = markdownToSlackMrkdwnChunks(trimmedMessage, chunkLimit, { tableMode });
|
||||
const mediaMaxBytes =
|
||||
typeof account.config.mediaMaxMb === "number"
|
||||
? account.config.mediaMaxMb * 1024 * 1024
|
||||
|
||||
Reference in New Issue
Block a user