refactor(channels): dedupe message routing and telegram helpers

This commit is contained in:
Peter Steinberger
2026-02-22 07:37:54 +00:00
parent b109fa53ea
commit 75c1bfbae8
21 changed files with 566 additions and 410 deletions

View File

@@ -1,4 +1,3 @@
import type { OpenClawConfig } from "../config/config.js";
import {
resolveChannelGroupRequireMention,
resolveChannelGroupToolsPolicy,
@@ -32,6 +31,7 @@ import { normalizeSignalMessagingTarget } from "./plugins/normalize/signal.js";
import type {
ChannelCapabilities,
ChannelCommandAdapter,
ChannelConfigAdapter,
ChannelElevatedAdapter,
ChannelGroupAdapter,
ChannelId,
@@ -53,21 +53,10 @@ export type ChannelDock = {
};
streaming?: ChannelDockStreaming;
elevated?: ChannelElevatedAdapter;
config?: {
resolveAllowFrom?: (params: {
cfg: OpenClawConfig;
accountId?: string | null;
}) => Array<string | number> | undefined;
formatAllowFrom?: (params: {
cfg: OpenClawConfig;
accountId?: string | null;
allowFrom: Array<string | number>;
}) => string[];
resolveDefaultTo?: (params: {
cfg: OpenClawConfig;
accountId?: string | null;
}) => string | undefined;
};
config?: Pick<
ChannelConfigAdapter<unknown>,
"resolveAllowFrom" | "formatAllowFrom" | "resolveDefaultTo"
>;
groups?: ChannelGroupAdapter;
mentions?: ChannelMentionAdapter;
threading?: ChannelThreadingAdapter;
@@ -87,6 +76,12 @@ const formatLower = (allowFrom: Array<string | number>) =>
.filter(Boolean)
.map((entry) => entry.toLowerCase());
const stringifyAllowFrom = (allowFrom: Array<string | number>) =>
allowFrom.map((entry) => String(entry));
const trimAllowFromEntries = (allowFrom: Array<string | number>) =>
allowFrom.map((entry) => String(entry).trim()).filter(Boolean);
const formatDiscordAllowFrom = (allowFrom: Array<string | number>) =>
allowFrom
.map((entry) =>
@@ -133,6 +128,18 @@ function buildIMessageThreadToolContext(params: {
};
}
function buildThreadToolContextFromMessageThreadOrReply(params: {
context: ChannelThreadingContext;
hasRepliedRef: ChannelThreadingToolContext["hasRepliedRef"];
}): ChannelThreadingToolContext {
const threadId = params.context.MessageThreadId ?? params.context.ReplyToId;
return {
currentChannelId: params.context.To?.trim() || undefined,
currentThreadTs: threadId != null ? String(threadId) : undefined,
hasRepliedRef: params.hasRepliedRef,
};
}
function resolveCaseInsensitiveAccount<T>(
accounts: Record<string, T> | undefined,
accountId?: string | null,
@@ -182,13 +189,9 @@ const DOCKS: Record<ChatChannelId, ChannelDock> = {
outbound: { textChunkLimit: 4000 },
config: {
resolveAllowFrom: ({ cfg, accountId }) =>
(resolveTelegramAccount({ cfg, accountId }).config.allowFrom ?? []).map((entry) =>
String(entry),
),
stringifyAllowFrom(resolveTelegramAccount({ cfg, accountId }).config.allowFrom ?? []),
formatAllowFrom: ({ allowFrom }) =>
allowFrom
.map((entry) => String(entry).trim())
.filter(Boolean)
trimAllowFromEntries(allowFrom)
.map((entry) => entry.replace(/^(telegram|tg):/i, ""))
.map((entry) => entry.toLowerCase()),
resolveDefaultTo: ({ cfg, accountId }) => {
@@ -202,14 +205,8 @@ const DOCKS: Record<ChatChannelId, ChannelDock> = {
},
threading: {
resolveReplyToMode: ({ cfg }) => cfg.channels?.telegram?.replyToMode ?? "off",
buildToolContext: ({ context, hasRepliedRef }) => {
const threadId = context.MessageThreadId ?? context.ReplyToId;
return {
currentChannelId: context.To?.trim() || undefined,
currentThreadTs: threadId != null ? String(threadId) : undefined,
hasRepliedRef,
};
},
buildToolContext: ({ context, hasRepliedRef }) =>
buildThreadToolContextFromMessageThreadOrReply({ context, hasRepliedRef }),
},
},
whatsapp: {
@@ -426,14 +423,8 @@ const DOCKS: Record<ChatChannelId, ChannelDock> = {
},
threading: {
resolveReplyToMode: ({ cfg }) => cfg.channels?.googlechat?.replyToMode ?? "off",
buildToolContext: ({ context, hasRepliedRef }) => {
const threadId = context.MessageThreadId ?? context.ReplyToId;
return {
currentChannelId: context.To?.trim() || undefined,
currentThreadTs: threadId != null ? String(threadId) : undefined,
hasRepliedRef,
};
},
buildToolContext: ({ context, hasRepliedRef }) =>
buildThreadToolContextFromMessageThreadOrReply({ context, hasRepliedRef }),
},
},
slack: {
@@ -487,13 +478,9 @@ const DOCKS: Record<ChatChannelId, ChannelDock> = {
},
config: {
resolveAllowFrom: ({ cfg, accountId }) =>
(resolveSignalAccount({ cfg, accountId }).config.allowFrom ?? []).map((entry) =>
String(entry),
),
stringifyAllowFrom(resolveSignalAccount({ cfg, accountId }).config.allowFrom ?? []),
formatAllowFrom: ({ allowFrom }) =>
allowFrom
.map((entry) => String(entry).trim())
.filter(Boolean)
trimAllowFromEntries(allowFrom)
.map((entry) => (entry === "*" ? "*" : normalizeE164(entry.replace(/^signal:/i, ""))))
.filter(Boolean),
resolveDefaultTo: ({ cfg, accountId }) =>