UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

205 lines (204 loc) 7.54 kB
import { c as normalizeOptionalString } from "./string-coerce-mnp54Vah.js"; import "./string-coerce-runtime-CEGJWkQ_.js"; import { i as createUnionActionGate } from "./channel-actions-BOfvC-Gl.js"; import { t as extractToolSend } from "./tool-send-DzTXHBeR.js"; import { t as inspectDiscordAccount } from "./account-inspect-DVZXXjia.js"; import { r as listDiscordAccountIds, t as createDiscordActionGate } from "./accounts-BI_6uJlY.js"; import { s as readDiscordComponentSpec } from "./components-CDHzCfc9.js"; import { i as withDiscordInboundEventDeliveryMetadata } from "./inbound-event-delivery-BI9WnEey.js"; //#region extensions/discord/src/channel-actions.ts const trustedRequesterGuildAdminActions = new Set([ "emoji-upload", "sticker-upload", "role-add", "role-remove", "channel-create", "channel-edit", "channel-delete", "channel-move", "category-create", "category-edit", "category-delete", "event-create", "timeout", "kick", "ban" ]); const localExecutionActions = new Set([ "send", "upload-file", "thread-reply", "sticker", "emoji-upload", "sticker-upload", "event-create" ]); function resolveDiscordActionExecutionMode({ action }) { return localExecutionActions.has(action) ? "local" : "gateway"; } let discordChannelActionsRuntimePromise; async function loadDiscordChannelActionsRuntime() { discordChannelActionsRuntimePromise ??= import("./channel-actions.runtime.js"); return await discordChannelActionsRuntimePromise; } function listDiscoverableDiscordAccounts(cfg) { return listDiscordAccountIds(cfg).map((accountId) => inspectDiscordAccount({ cfg, accountId })).filter((account) => account.enabled && account.configured); } function resolveDiscordActionDiscovery(cfg) { const accounts = listDiscoverableDiscordAccounts(cfg); if (accounts.length === 0) return null; const unionGate = createUnionActionGate(accounts, (account) => createDiscordActionGate({ cfg, accountId: account.accountId })); return { isEnabled: (key, defaultValue = true) => unionGate(key, defaultValue) }; } function resolveScopedDiscordActionDiscovery(params) { if (!params.accountId) return resolveDiscordActionDiscovery(params.cfg); const account = inspectDiscordAccount({ cfg: params.cfg, accountId: params.accountId }); if (!account.enabled || !account.configured) return null; const gate = createDiscordActionGate({ cfg: params.cfg, accountId: account.accountId }); return { isEnabled: (key, defaultValue = true) => gate(key, defaultValue) }; } function describeDiscordMessageTool({ cfg, accountId }) { const discovery = resolveScopedDiscordActionDiscovery({ cfg, accountId }); if (!discovery) return { actions: [], capabilities: [], schema: null }; const actions = new Set(["send"]); if (discovery.isEnabled("polls")) actions.add("poll"); if (discovery.isEnabled("reactions")) { actions.add("react"); actions.add("reactions"); actions.add("emoji-list"); } if (discovery.isEnabled("messages")) { actions.add("upload-file"); actions.add("read"); actions.add("edit"); actions.add("delete"); } if (discovery.isEnabled("pins")) { actions.add("pin"); actions.add("unpin"); actions.add("list-pins"); } if (discovery.isEnabled("permissions")) actions.add("permissions"); if (discovery.isEnabled("threads")) { actions.add("thread-create"); actions.add("thread-list"); actions.add("thread-reply"); } if (discovery.isEnabled("search")) actions.add("search"); if (discovery.isEnabled("stickers")) actions.add("sticker"); if (discovery.isEnabled("memberInfo")) actions.add("member-info"); if (discovery.isEnabled("roleInfo")) actions.add("role-info"); if (discovery.isEnabled("emojiUploads")) actions.add("emoji-upload"); if (discovery.isEnabled("stickerUploads")) actions.add("sticker-upload"); if (discovery.isEnabled("roles", false)) { actions.add("role-add"); actions.add("role-remove"); } if (discovery.isEnabled("channelInfo")) { actions.add("channel-info"); actions.add("channel-list"); } if (discovery.isEnabled("channels")) { actions.add("channel-create"); actions.add("channel-edit"); actions.add("channel-delete"); actions.add("channel-move"); actions.add("category-create"); actions.add("category-edit"); actions.add("category-delete"); } if (discovery.isEnabled("voiceStatus")) actions.add("voice-status"); if (discovery.isEnabled("events")) { actions.add("event-list"); actions.add("event-create"); } if (discovery.isEnabled("moderation", false)) { actions.add("timeout"); actions.add("kick"); actions.add("ban"); } if (discovery.isEnabled("presence", false)) actions.add("set-presence"); return { actions: Array.from(actions), capabilities: ["presentation"] }; } const discordMessageActions = { resolveExecutionMode: resolveDiscordActionExecutionMode, describeMessageTool: describeDiscordMessageTool, requiresTrustedRequesterSender: ({ action, toolContext }) => normalizeOptionalString(toolContext?.currentChannelProvider)?.toLowerCase() === "discord" && trustedRequesterGuildAdminActions.has(action), extractToolSend: ({ args }) => { const action = normalizeOptionalString(args.action) ?? ""; if (action === "sendMessage") return extractToolSend(args, "sendMessage"); if (action === "threadReply") { const channelId = normalizeOptionalString(args.channelId) ?? ""; return channelId ? { to: `channel:${channelId}` } : null; } return null; }, prepareSendPayload: ({ ctx, payload }) => { if (ctx.action !== "send") return null; const payloadWithDeliveryMetadata = withDiscordInboundEventDeliveryMetadata(payload, { sessionKey: ctx.sessionKey, inboundEventKind: ctx.inboundEventKind }); const rawComponents = ctx.params.components; if (typeof rawComponents === "function") return null; const componentSpec = rawComponents && typeof rawComponents === "object" && !Array.isArray(rawComponents) ? readDiscordComponentSpec(rawComponents) : void 0; const nativeComponents = Array.isArray(rawComponents) ? rawComponents : void 0; const embeds = Array.isArray(ctx.params.embeds) ? ctx.params.embeds : void 0; if ((componentSpec || nativeComponents) && embeds?.length) return null; const filename = normalizeOptionalString(ctx.params.filename); if (!componentSpec && !nativeComponents && !embeds?.length && !filename) return payloadWithDeliveryMetadata; const discordData = payloadWithDeliveryMetadata.channelData?.discord && typeof payloadWithDeliveryMetadata.channelData.discord === "object" && !Array.isArray(payloadWithDeliveryMetadata.channelData.discord) ? payloadWithDeliveryMetadata.channelData.discord : {}; return { ...payloadWithDeliveryMetadata, channelData: { ...payloadWithDeliveryMetadata.channelData, discord: { ...discordData, ...componentSpec ? { components: componentSpec } : {}, ...nativeComponents ? { components: nativeComponents } : {}, ...embeds?.length ? { embeds } : {}, ...filename ? { filename } : {} } } }; }, handleAction: async ({ action, params, cfg, accountId, requesterSenderId, toolContext, mediaAccess, mediaLocalRoots, mediaReadFile, sessionKey, inboundEventKind }) => { return await (await loadDiscordChannelActionsRuntime()).handleDiscordMessageAction({ action, params, cfg, accountId, requesterSenderId, toolContext, mediaAccess, mediaLocalRoots, mediaReadFile, ...sessionKey ? { sessionKey } : {}, ...inboundEventKind ? { inboundEventKind } : {} }); } }; //#endregion export { discordMessageActions as t };