UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

254 lines (253 loc) 9.74 kB
import { c as normalizeOptionalString } from "./string-coerce-mnp54Vah.js"; import { n as resolveChannelGroupRequireMention } from "./group-policy-CShy7eWv.js"; import { i as createLazyRuntimeNamedExport } from "./lazy-runtime-D-7_JraP.js"; import { i as readRemoteMediaBuffer } from "./fetch-2npQWHQh.js"; import { t as sanitizeForPlainText } from "./sanitize-text-BOGhD8MR.js"; import { t as createMessageReceiptFromOutboundResults } from "./receipt-B3SXxhHV.js"; import { t as adaptScopedAccountAccessor } from "./channel-config-helpers-lj5quus3.js"; import { n as missingTargetError } from "./target-errors-B0SYsRYn.js"; import { a as resolveChannelMediaMaxBytes } from "./media-runtime-fgpmX6eL.js"; import "./string-coerce-runtime-CEGJWkQ_.js"; import { t as chunkTextForOutbound } from "./text-chunking-D45TeeEs.js"; import { _ as createAllowlistProviderOpenWarningCollector, m as composeAccountWarningCollectors } from "./channel-policy-CIW58SA5.js"; import { t as createChannelDirectoryAdapter } from "./directory-runtime-om8jJAZt.js"; import { f as listResolvedDirectoryGroupEntriesFromMapKeys, p as listResolvedDirectoryUserEntriesFromAllowFrom } from "./directory-config-helpers-DEDTHx2P.js"; import { T as defineChannelMessageAdapter } from "./channel-outbound-B3_Zy-kG.js"; import { n as loadOutboundMediaFromUrl } from "./outbound-media-MHBXtJsJ.js"; import { t as PAIRING_APPROVED_MESSAGE } from "./pairing-message-DNhqI-OE.js"; import { i as resolveGoogleChatAccount } from "./accounts-BedKEwKe.js"; import { T as shouldSuppressGoogleChatManualExecApprovalFollowupPayload, i as resolveGoogleChatOutboundSpace, n as isGoogleChatUserTarget, r as normalizeGoogleChatTarget } from "./targets-BIe3h2UJ.js"; import "./runtime-api-Dp_Hh2eL.js"; import { r as formatGoogleChatAllowFromEntry } from "./channel-base-D9bH8n7T.js"; //#region extensions/googlechat/src/group-policy.ts function resolveGoogleChatGroupRequireMention(params) { return resolveChannelGroupRequireMention({ cfg: params.cfg, channel: "googlechat", groupId: params.groupId, accountId: params.accountId }); } //#endregion //#region extensions/googlechat/src/channel.adapters.ts const loadGoogleChatChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-DtxTFBoI.js"), "googleChatChannelRuntime"); function createGoogleChatSendReceipt(params) { const messageId = params.messageId?.trim(); return createMessageReceiptFromOutboundResults({ results: messageId ? [{ channel: "googlechat", messageId, chatId: params.chatId, conversationId: params.chatId }] : [], threadId: params.chatId, kind: params.kind }); } const formatAllowFromEntry = formatGoogleChatAllowFromEntry; const collectGoogleChatSecurityWarnings = composeAccountWarningCollectors(createAllowlistProviderOpenWarningCollector({ providerConfigPresent: (cfg) => cfg.channels?.googlechat !== void 0, resolveGroupPolicy: (account) => account.config.groupPolicy, buildOpenWarning: { surface: "Google Chat spaces", openBehavior: "allows any space to trigger (mention-gated)", remediation: "Set channels.googlechat.groupPolicy=\"allowlist\" and configure channels.googlechat.groups" } }), (account) => account.config.dm?.policy === "open" && "- Google Chat DMs are open to anyone. Set channels.googlechat.dm.policy=\"pairing\" or \"allowlist\"."); const googlechatGroupsAdapter = { resolveRequireMention: resolveGoogleChatGroupRequireMention }; const googlechatDirectoryAdapter = createChannelDirectoryAdapter({ listPeers: async (params) => listResolvedDirectoryUserEntriesFromAllowFrom({ ...params, resolveAccount: adaptScopedAccountAccessor(resolveGoogleChatAccount), resolveAllowFrom: (account) => account.config.dm?.allowFrom, normalizeId: (entry) => normalizeGoogleChatTarget(entry) ?? entry }), listGroups: async (params) => listResolvedDirectoryGroupEntriesFromMapKeys({ ...params, resolveAccount: adaptScopedAccountAccessor(resolveGoogleChatAccount), resolveGroups: (account) => account.config.groups }) }); const googlechatSecurityAdapter = { dm: { channelKey: "googlechat", resolvePolicy: (account) => account.config.dm?.policy, resolveAllowFrom: (account) => account.config.dm?.allowFrom, allowFromPathSuffix: "dm.", normalizeEntry: (raw) => formatAllowFromEntry(raw) }, collectWarnings: collectGoogleChatSecurityWarnings }; const googlechatThreadingAdapter = { scopedAccountReplyToMode: { resolveAccount: (cfg, accountId) => resolveGoogleChatAccount({ cfg, accountId }), resolveReplyToMode: (account, _chatType) => account.config.replyToMode, fallback: "off" }, buildToolContext: ({ cfg, accountId, context, hasRepliedRef }) => { const currentChannelId = normalizeGoogleChatTarget(context.To); const replyToId = normalizeOptionalString(context.ReplyToIdFull) ?? normalizeOptionalString(context.ReplyToId); return { currentChannelId, currentMessageId: replyToId, currentThreadTs: replyToId, replyToMode: resolveGoogleChatAccount({ cfg, accountId }).config.replyToMode, hasRepliedRef }; } }; const googlechatPairingTextAdapter = { idLabel: "googlechatUserId", message: PAIRING_APPROVED_MESSAGE, normalizeAllowEntry: (entry) => formatAllowFromEntry(entry), notify: async ({ cfg, id, message, accountId }) => { const account = resolveGoogleChatAccount({ cfg, accountId }); if (account.credentialSource === "none") return; const user = normalizeGoogleChatTarget(id) ?? id; const space = await resolveGoogleChatOutboundSpace({ account, target: isGoogleChatUserTarget(user) ? user : `users/${user}` }); const { sendGoogleChatMessage } = await loadGoogleChatChannelRuntime(); await sendGoogleChatMessage({ account, space, text: message }); } }; const googlechatOutboundAdapter = { base: { deliveryMode: "direct", chunker: chunkTextForOutbound, chunkerMode: "markdown", textChunkLimit: 4e3, sanitizeText: ({ text }) => sanitizeForPlainText(text), normalizePayload: ({ payload }) => shouldSuppressGoogleChatManualExecApprovalFollowupPayload(payload) ? null : payload, resolveTarget: ({ to }) => { const trimmed = normalizeOptionalString(to) ?? ""; if (trimmed) { const normalized = normalizeGoogleChatTarget(trimmed); if (!normalized) return { ok: false, error: missingTargetError("Google Chat", "<spaces/{space}|users/{user}>") }; return { ok: true, to: normalized }; } return { ok: false, error: missingTargetError("Google Chat", "<spaces/{space}|users/{user}>") }; } }, attachedResults: { channel: "googlechat", sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => { const account = resolveGoogleChatAccount({ cfg, accountId }); const space = await resolveGoogleChatOutboundSpace({ account, target: to }); const thread = typeof threadId === "number" ? String(threadId) : threadId ?? replyToId ?? void 0; const { sendGoogleChatMessage } = await loadGoogleChatChannelRuntime(); const messageId = (await sendGoogleChatMessage({ account, space, text, thread }))?.messageName ?? ""; return { messageId, chatId: space, receipt: createGoogleChatSendReceipt({ messageId, chatId: space, kind: "text" }) }; }, sendMedia: async ({ cfg, to, text, mediaUrl, mediaAccess, mediaLocalRoots, mediaReadFile, accountId, replyToId, threadId }) => { if (!mediaUrl) throw new Error("Google Chat mediaUrl is required."); const account = resolveGoogleChatAccount({ cfg, accountId }); const space = await resolveGoogleChatOutboundSpace({ account, target: to }); const thread = typeof threadId === "number" ? String(threadId) : threadId ?? replyToId ?? void 0; const effectiveMaxBytes = resolveChannelMediaMaxBytes({ cfg, resolveChannelLimitMb: ({ cfg: cfgLocal, accountId: accountIdLocal }) => (cfgLocal.channels?.googlechat)?.accounts?.[accountIdLocal]?.mediaMaxMb ?? (cfgLocal.channels?.googlechat)?.mediaMaxMb, accountId }) ?? (account.config.mediaMaxMb ?? 20) * 1024 * 1024; const loaded = /^https?:\/\//i.test(mediaUrl) ? await readRemoteMediaBuffer({ url: mediaUrl, maxBytes: effectiveMaxBytes }) : await loadOutboundMediaFromUrl(mediaUrl, { maxBytes: effectiveMaxBytes, mediaAccess, mediaLocalRoots, mediaReadFile }); const { sendGoogleChatMessage, uploadGoogleChatAttachment } = await loadGoogleChatChannelRuntime(); const upload = await uploadGoogleChatAttachment({ account, space, filename: loaded.fileName ?? "attachment", buffer: loaded.buffer, contentType: loaded.contentType }); const messageId = (await sendGoogleChatMessage({ account, space, text, thread, attachments: upload.attachmentUploadToken ? [{ attachmentUploadToken: upload.attachmentUploadToken, contentName: loaded.fileName }] : void 0 }))?.messageName ?? ""; return { messageId, chatId: space, receipt: createGoogleChatSendReceipt({ messageId, chatId: space, kind: "media" }) }; } } }; const googlechatMessageAdapter = defineChannelMessageAdapter({ id: "googlechat", durableFinal: { capabilities: { text: true, media: true, thread: true, messageSendingHooks: true } }, send: { text: googlechatOutboundAdapter.attachedResults.sendText, media: googlechatOutboundAdapter.attachedResults.sendMedia } }); //#endregion export { googlechatPairingTextAdapter as a, googlechatOutboundAdapter as i, googlechatGroupsAdapter as n, googlechatSecurityAdapter as o, googlechatMessageAdapter as r, googlechatThreadingAdapter as s, googlechatDirectoryAdapter as t };