UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

201 lines (200 loc) • 9.46 kB
import { l as normalizeOptionalString } from "./string-coerce-1VuiLaaR.mjs"; import { y as uniqueStrings } from "./string-normalization-D6DKCpwE.mjs"; import { r as defaultRuntime } from "./runtime-BRg2NubB.mjs"; import { t as formatErrorMessage } from "./errors-BvOkmQM5.mjs"; import { t as normalizeAnyChannelId } from "./registry-normalize-DKVgg-js.mjs"; import { D as getPreparedMessageToolCatalog } from "./runtime-U4i1bMh7.mjs"; import "./registry-DvTPWA3B.mjs"; import { n as getLoadedChannelPlugin, r as listChannelPlugins, t as getChannelPlugin } from "./registry-Bcrk1FVy.mjs"; import "./plugins-BXkKReMp.mjs"; import { t as loadOptionalBundledChannelPublicArtifact } from "./optional-public-artifact-C1gsSm0z.mjs"; import { Type } from "typebox"; //#region src/channels/plugins/message-tool-api.ts /** * Resolves a bundled channel's message-tool discovery adapter without loading the full plugin. */ function resolveBundledChannelMessageToolDiscoveryAdapter(channelId) { const describeMessageTool = loadOptionalBundledChannelPublicArtifact({ channelId, artifactBasename: "message-tool-api.js" })?.describeMessageTool; if (typeof describeMessageTool !== "function") return; return { describeMessageTool }; } //#endregion //#region src/channels/plugins/message-action-discovery.ts /** Lists message-action adapters from the caller's exact prepared registry. */ const listMessageActionDiscoveryChannels = (preparedMessageToolCatalog) => (preparedMessageToolCatalog ?? getPreparedMessageToolCatalog())?.channels ?? listChannelPlugins(); const loggedMessageActionErrors = /* @__PURE__ */ new Set(); function resolveMessageActionDiscoveryChannelId(raw) { return normalizeAnyChannelId(raw) ?? normalizeOptionalString(raw); } function createMessageActionDiscoveryContext(params) { const currentChannelProvider = resolveMessageActionDiscoveryChannelId(params.channel ?? params.currentChannelProvider); return { cfg: params.cfg ?? {}, ...params.chatType ? { chatType: params.chatType } : {}, currentChannelId: params.currentChannelId, currentChannelProvider, currentThreadTs: params.currentThreadTs, currentMessageId: params.currentMessageId, accountId: params.accountId, sessionKey: params.sessionKey, sessionId: params.sessionId, agentId: params.agentId, requesterSenderId: params.requesterSenderId, senderIsOwner: params.senderIsOwner }; } function describeMessageToolSafely(params) { try { return params.describeMessageTool(params.context) ?? null; } catch (error) { const message = formatErrorMessage(error); const key = `${params.pluginId}:describeMessageTool:${message}`; if (!loggedMessageActionErrors.has(key)) { loggedMessageActionErrors.add(key); const stack = error instanceof Error && error.stack ? error.stack : null; defaultRuntime.error?.(`[message-action-discovery] ${params.pluginId}.actions.describeMessageTool failed: ${stack ?? message}`); } return null; } } function normalizeMessageToolMediaSourceParams(mediaSourceParams, action) { if (Array.isArray(mediaSourceParams)) return mediaSourceParams; if (!mediaSourceParams || typeof mediaSourceParams !== "object") return []; const scopedMediaSourceParams = mediaSourceParams; if (action) { const scoped = scopedMediaSourceParams[action]; return Array.isArray(scoped) ? scoped : []; } return Object.values(scopedMediaSourceParams).flatMap((scoped) => Array.isArray(scoped) ? scoped : []); } function resolveCurrentChannelMessageToolDiscoveryAdapter(channel, preparedMessageToolCatalog) { const channelId = resolveMessageActionDiscoveryChannelId(channel); if (!channelId) return null; const catalog = preparedMessageToolCatalog ?? getPreparedMessageToolCatalog(); const prepared = catalog?.getChannel(channelId); if (prepared?.actions) return { pluginId: prepared.id, actions: prepared.actions }; if (!catalog) { const loadedPlugin = getLoadedChannelPlugin(channelId); if (loadedPlugin?.actions) return { pluginId: loadedPlugin.id, actions: loadedPlugin.actions }; } const bundledActions = resolveBundledChannelMessageToolDiscoveryAdapter(channelId); if (bundledActions) return { pluginId: channelId, actions: bundledActions }; const plugin = catalog ? void 0 : getChannelPlugin(channelId); return plugin?.actions ? { pluginId: plugin.id, actions: plugin.actions } : null; } function resolveMessageActionDiscoveryForPlugin(params) { const adapter = params.actions; const described = adapter ? describeMessageToolSafely({ pluginId: params.pluginId, context: params.context, describeMessageTool: adapter.describeMessageTool }) : null; const schema = params.includeSchema ? described?.schema : void 0; return { actions: params.includeActions && Array.isArray(described?.actions) ? [...described.actions] : [], capabilities: params.includeCapabilities && Array.isArray(described?.capabilities) ? described.capabilities : [], schemaContributions: schema ? Array.isArray(schema) ? schema : [schema] : [], mediaSourceParams: normalizeMessageToolMediaSourceParams(described?.mediaSourceParams, params.action) }; } function listCrossChannelSchemaSupportedMessageActions(params) { const resolved = resolveCurrentMessageActionDiscovery(params, { includeActions: true, includeSchema: true }); if (!resolved) return []; const schemaBlockedActions = /* @__PURE__ */ new Set(); for (const contribution of resolved.schemaContributions) { if ((contribution.visibility ?? "current-channel") !== "current-channel") continue; if (!Object.hasOwn(contribution, "actions")) return []; const actions = contribution.actions; if (!Array.isArray(actions)) return []; for (const action of actions) schemaBlockedActions.add(action); } return resolved.actions.filter((action) => !schemaBlockedActions.has(action)); } /** * Merges schema properties while preserving the first plugin to define a key. */ function mergeToolSchemaProperties(target, source) { if (!source) return; for (const [name, schema] of Object.entries(source)) { if (name in target) continue; target[name] = Type.IsOptional(schema) ? schema : Type.Optional(schema); } } function resolveChannelMessageToolSchemaProperties(params) { const properties = {}; const currentChannel = resolveMessageActionDiscoveryChannelId(params.channel); const discoveryBase = createMessageActionDiscoveryContext(params); const contextForPlugin = (pluginId) => { const contextualAccountId = !currentChannel || resolveMessageActionDiscoveryChannelId(pluginId) === currentChannel ? params.accountId : void 0; return { ...discoveryBase, accountId: params.resolveAccountIdForChannel ? params.resolveAccountIdForChannel(pluginId, contextualAccountId) : contextualAccountId }; }; const seenPluginIds = /* @__PURE__ */ new Set(); const mergePluginSchema = (pluginId, actions) => { for (const contribution of resolveMessageActionDiscoveryForPlugin({ pluginId, actions, context: contextForPlugin(pluginId), includeSchema: true }).schemaContributions) { const visibility = contribution.visibility ?? "current-channel"; if (!currentChannel || visibility === "all-configured" || pluginId === currentChannel) mergeToolSchemaProperties(properties, contribution.properties); } }; const channels = listMessageActionDiscoveryChannels(params.preparedMessageToolCatalog); for (const plugin of channels) { if (!plugin.actions) continue; seenPluginIds.add(plugin.id); mergePluginSchema(plugin.id, plugin.actions); } if (currentChannel && !seenPluginIds.has(currentChannel)) { const currentActions = resolveCurrentChannelMessageToolDiscoveryAdapter(currentChannel, params.preparedMessageToolCatalog); if (currentActions?.actions) mergePluginSchema(currentActions.pluginId, currentActions.actions); } return properties; } function resolveCurrentMessageActionDiscovery(params, selection = {}) { const pluginActions = resolveCurrentChannelMessageToolDiscoveryAdapter(params.channel, params.preparedMessageToolCatalog); return pluginActions ? resolveMessageActionDiscoveryForPlugin({ ...pluginActions, context: createMessageActionDiscoveryContext(params), action: params.action, ...selection }) : null; } function resolveChannelMessageToolMediaSourceParamKeys(params) { return uniqueStrings(resolveCurrentMessageActionDiscovery(params)?.mediaSourceParams ?? []); } function channelSupportsMessageCapability(cfg, capability, preparedMessageToolCatalog) { return listMessageActionDiscoveryChannels(preparedMessageToolCatalog).map((plugin) => resolveMessageActionDiscoveryForPlugin({ pluginId: plugin.id, actions: plugin.actions, context: { cfg }, includeCapabilities: true }).capabilities).some((pluginCapabilities) => pluginCapabilities.includes(capability)); } function channelSupportsMessageCapabilityForChannel(params, capability) { return resolveCurrentMessageActionDiscovery(params, { includeCapabilities: true })?.capabilities.includes(capability) ?? false; } //#endregion export { listMessageActionDiscoveryChannels as a, resolveCurrentChannelMessageToolDiscoveryAdapter as c, listCrossChannelSchemaSupportedMessageActions as i, resolveMessageActionDiscoveryChannelId as l, channelSupportsMessageCapabilityForChannel as n, resolveChannelMessageToolMediaSourceParamKeys as o, createMessageActionDiscoveryContext as r, resolveChannelMessageToolSchemaProperties as s, channelSupportsMessageCapability as t, resolveMessageActionDiscoveryForPlugin as u };