UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

121 lines (120 loc) 6.59 kB
import { c as normalizeOptionalLowercaseString } from "./string-coerce-CIXf7egm.js"; import { n as normalizeAccountId } from "./account-id-CETVCrTz.js"; import { t as normalizeAnyChannelId } from "./registry-normalize-CY8V_nbx.js"; import "./registry-COqNvmCg.js"; import { n as resolveNormalizedAccountEntry } from "./account-lookup-CvFhSs3G.js"; import { t as normalizeChatType } from "./chat-type-CG0X_HJM.js"; import { d as isReplyPayloadStatusNotice, i as copyReplyPayloadMetadata } from "./reply-payload-DahKk-7n.js"; import { t as getChannelPlugin } from "./registry-Cz6cv4VC.js"; import "./plugins-Cozj1Enf.js"; import { n as getLoadedChannelThreadingAdapter } from "./thread-addressing-D0QS0tJI.js"; import { n as isSingleUseReplyToMode } from "./reply-reference-cLEWJ7Kr.js"; //#region src/auto-reply/reply/reply-threading.ts /** Reply threading policy helpers for channel replies and status notices. */ function normalizeReplyToModeChatType(chatType) { return chatType === "direct" || chatType === "group" || chatType === "channel" ? chatType : void 0; } /** Resolve configured reply-to mode from channel and chat-type config. */ function resolveConfiguredReplyToMode(cfg, channel, chatType, accountId) { const provider = normalizeAnyChannelId(channel) ?? normalizeOptionalLowercaseString(channel); if (!provider) return "all"; const channelConfig = cfg.channels?.[provider]; const normalizedAccountId = accountId?.trim(); const accountConfig = normalizedAccountId ? resolveNormalizedAccountEntry(channelConfig?.accounts, normalizeAccountId(normalizedAccountId), normalizeAccountId) : void 0; const normalizedChatType = normalizeReplyToModeChatType(chatType); if (normalizedChatType) { const accountMode = accountConfig?.replyToModeByChatType?.[normalizedChatType] ?? accountConfig?.replyToMode; if (accountMode !== void 0) return accountMode; const scopedMode = channelConfig?.replyToModeByChatType?.[normalizedChatType]; if (scopedMode !== void 0) return scopedMode; } return accountConfig?.replyToMode ?? channelConfig?.replyToMode ?? "all"; } /** Resolve reply-to mode using channel threading adapter override when present. */ function resolveReplyToModeWithThreading(cfg, threading, params = {}) { return threading?.resolveReplyToMode?.({ cfg, accountId: params.accountId, chatType: params.chatType }) ?? resolveConfiguredReplyToMode(cfg, params.channel, params.chatType, params.accountId); } /** Resolve effective reply-to mode for a channel/account/chat tuple. */ function resolveReplyToMode(cfg, channel, accountId, chatType) { const normalizedAccountId = normalizeOptionalLowercaseString(accountId); if (!normalizedAccountId) return resolveConfiguredReplyToMode(cfg, channel, chatType); const provider = normalizeAnyChannelId(channel) ?? normalizeOptionalLowercaseString(channel); return resolveReplyToModeWithThreading(cfg, provider ? getChannelPlugin(provider)?.threading : void 0, { channel, accountId: normalizedAccountId, chatType }); } /** Resolve the account that routed reply delivery will use when none is explicit. */ function resolveReplyDeliveryAccountId(cfg, channel, accountId) { const explicitAccountId = normalizeOptionalLowercaseString(accountId); if (explicitAccountId) return explicitAccountId; const provider = normalizeAnyChannelId(channel) ?? normalizeOptionalLowercaseString(channel); if (!provider) return; const plugin = getChannelPlugin(provider); if (!plugin) return; const configuredDefault = normalizeOptionalLowercaseString(plugin.config.defaultAccountId?.(cfg)); if (configuredDefault) return configuredDefault; const channelConfiguredDefault = normalizeOptionalLowercaseString(cfg.channels?.[provider]?.defaultAccount); if (channelConfiguredDefault) return channelConfiguredDefault; return plugin.config.listAccountIds(cfg).map((listedAccountId) => normalizeOptionalLowercaseString(listedAccountId)).find((listedAccountId) => Boolean(listedAccountId)) ?? "default"; } /** Build the canonical reply policy context consumed by delivery adapters. */ function createReplyDeliveryContext(replyToMode, chatType) { const normalizedChatType = normalizeChatType(chatType ?? void 0); return { ...normalizedChatType ? { chatType: normalizedChatType } : {}, replyToMode }; } /** Create a payload filter that strips reply targets according to reply-to mode. */ function createReplyToModeFilter(mode, opts = {}) { let hasThreaded = false; const apply = (payload, preview = false) => { const isStatusNotice = isReplyPayloadStatusNotice(payload); if (!payload.replyToId) return payload; if (mode === "off") { const isExplicit = Boolean(payload.replyToTag) || Boolean(payload.replyToCurrent); if (opts.allowExplicitReplyTagsWhenOff && isExplicit && !isStatusNotice) return payload; return copyReplyPayloadMetadata(payload, { ...payload, replyToId: void 0 }); } if (mode === "all") return payload; if (isSingleUseReplyToMode(mode) && hasThreaded) { if (isStatusNotice) return payload; return copyReplyPayloadMetadata(payload, { ...payload, replyToId: void 0 }); } if (isSingleUseReplyToMode(mode) && !isStatusNotice && !preview) hasThreaded = true; return payload; }; return Object.assign((payload) => apply(payload), { preview: (payload) => apply(payload, true) }); } /** Resolve whether implicit current-message replies are allowed under threading policy. */ function resolveImplicitCurrentMessageReplyAllowance(mode, policy) { const implicitCurrentMessage = policy?.implicitCurrentMessage ?? "default"; if (implicitCurrentMessage === "allow") return true; if (implicitCurrentMessage === "deny") return false; return mode !== "batched"; } /** Build threading policy for batched reply-to mode. */ function resolveBatchedReplyThreadingPolicy(mode, isBatched) { if (mode !== "batched") return; return { implicitCurrentMessage: isBatched ? "allow" : "deny" }; } /** Create a reply-to filter using channel-specific explicit-tag defaults. */ function createReplyToModeFilterForChannel(mode, channel) { const normalized = normalizeOptionalLowercaseString(channel); const adapter = getLoadedChannelThreadingAdapter(normalized); return createReplyToModeFilter(mode, { allowExplicitReplyTagsWhenOff: adapter?.allowExplicitReplyTagsWhenOff ?? adapter?.allowTagsWhenOff ?? Boolean(normalized) }); } //#endregion export { resolveReplyDeliveryAccountId as a, resolveImplicitCurrentMessageReplyAllowance as i, createReplyToModeFilterForChannel as n, resolveReplyToMode as o, resolveBatchedReplyThreadingPolicy as r, createReplyDeliveryContext as t };