refactor: deduplicate reply payload helpers

This commit is contained in:
Peter Steinberger
2026-03-18 17:29:54 +00:00
parent 656679e6e0
commit 8d73bc77fa
67 changed files with 2246 additions and 1366 deletions

View File

@@ -5,9 +5,11 @@ import {
} from "openclaw/plugin-sdk/channel-config-helpers";
import { createAllowlistProviderRestrictSendersWarningCollector } from "openclaw/plugin-sdk/channel-policy";
import {
createAttachedChannelResultAdapter,
createChannelDirectoryAdapter,
createLoggedPairingApprovalNotifier,
createMessageToolButtonsSchema,
createScopedAccountReplyToModeResolver,
type ChannelMessageToolDiscovery,
} from "openclaw/plugin-sdk/channel-runtime";
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
@@ -308,14 +310,17 @@ export const mattermostPlugin: ChannelPlugin<ResolvedMattermostAccount> = {
blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 },
},
threading: {
resolveReplyToMode: ({ cfg, accountId, chatType }) => {
const account = resolveMattermostAccount({ cfg, accountId: accountId ?? "default" });
const kind =
chatType === "direct" || chatType === "group" || chatType === "channel"
? chatType
: "channel";
return resolveMattermostReplyToMode(account, kind);
},
resolveReplyToMode: createScopedAccountReplyToModeResolver({
resolveAccount: (cfg, accountId) =>
resolveMattermostAccount({ cfg, accountId: accountId ?? "default" }),
resolveReplyToMode: (account, chatType) =>
resolveMattermostReplyToMode(
account,
chatType === "direct" || chatType === "group" || chatType === "channel"
? chatType
: "channel",
),
}),
},
reload: { configPrefixes: ["channels.mattermost"] },
configSchema: buildChannelConfigSchema(MattermostConfigSchema),
@@ -385,33 +390,32 @@ export const mattermostPlugin: ChannelPlugin<ResolvedMattermostAccount> = {
}
return { ok: true, to: trimmed };
},
sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {
const result = await sendMessageMattermost(to, text, {
...createAttachedChannelResultAdapter({
channel: "mattermost",
sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) =>
await sendMessageMattermost(to, text, {
cfg,
accountId: accountId ?? undefined,
replyToId: replyToId ?? (threadId != null ? String(threadId) : undefined),
}),
sendMedia: async ({
cfg,
accountId: accountId ?? undefined,
replyToId: replyToId ?? (threadId != null ? String(threadId) : undefined),
});
return { channel: "mattermost", ...result };
},
sendMedia: async ({
cfg,
to,
text,
mediaUrl,
mediaLocalRoots,
accountId,
replyToId,
threadId,
}) => {
const result = await sendMessageMattermost(to, text, {
cfg,
accountId: accountId ?? undefined,
to,
text,
mediaUrl,
mediaLocalRoots,
replyToId: replyToId ?? (threadId != null ? String(threadId) : undefined),
});
return { channel: "mattermost", ...result };
},
accountId,
replyToId,
threadId,
}) =>
await sendMessageMattermost(to, text, {
cfg,
accountId: accountId ?? undefined,
mediaUrl,
mediaLocalRoots,
replyToId: replyToId ?? (threadId != null ? String(threadId) : undefined),
}),
}),
},
status: {
defaultRuntime: {

View File

@@ -1,3 +1,4 @@
import { deliverTextOrMediaReply } from "openclaw/plugin-sdk/reply-payload";
import type { OpenClawConfig, PluginRuntime, ReplyPayload } from "../runtime-api.js";
import { getAgentScopedMediaLocalRoots } from "../runtime-api.js";
@@ -26,46 +27,34 @@ export async function deliverMattermostReplyPayload(params: {
tableMode: MarkdownTableMode;
sendMessage: SendMattermostMessage;
}): Promise<void> {
const mediaUrls =
params.payload.mediaUrls ?? (params.payload.mediaUrl ? [params.payload.mediaUrl] : []);
const text = params.core.channel.text.convertMarkdownTables(
params.payload.text ?? "",
params.tableMode,
);
if (mediaUrls.length === 0) {
const chunkMode = params.core.channel.text.resolveChunkMode(
params.cfg,
"mattermost",
params.accountId,
);
const chunks = params.core.channel.text.chunkMarkdownTextWithMode(
text,
params.textLimit,
chunkMode,
);
for (const chunk of chunks.length > 0 ? chunks : [text]) {
if (!chunk) {
continue;
}
const mediaLocalRoots = getAgentScopedMediaLocalRoots(params.cfg, params.agentId);
const chunkMode = params.core.channel.text.resolveChunkMode(
params.cfg,
"mattermost",
params.accountId,
);
await deliverTextOrMediaReply({
payload: params.payload,
text,
chunkText: (value) =>
params.core.channel.text.chunkMarkdownTextWithMode(value, params.textLimit, chunkMode),
sendText: async (chunk) => {
await params.sendMessage(params.to, chunk, {
accountId: params.accountId,
replyToId: params.replyToId,
});
}
return;
}
const mediaLocalRoots = getAgentScopedMediaLocalRoots(params.cfg, params.agentId);
let first = true;
for (const mediaUrl of mediaUrls) {
const caption = first ? text : "";
first = false;
await params.sendMessage(params.to, caption, {
accountId: params.accountId,
mediaUrl,
mediaLocalRoots,
replyToId: params.replyToId,
});
}
},
sendMedia: async ({ mediaUrl, caption }) => {
await params.sendMessage(params.to, caption ?? "", {
accountId: params.accountId,
mediaUrl,
mediaLocalRoots,
replyToId: params.replyToId,
});
},
});
}