UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

270 lines (269 loc) 11.1 kB
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js"; import { t as createSubsystemLogger } from "./subsystem-Dy2tqXOS.js"; import { o as resolveSessionStorePathCore } from "./paths-CXdaYWF_.js"; import { f as saveMediaBuffer } from "./store-Ph57PZ9P.js"; import { a as saveResponseMedia, i as saveRemoteMedia, r as readRemoteMediaBuffer } from "./fetch-BiZ7bEBv.js"; import "./logging-DB4bVraC.js"; import "./session-accessor-YsytfDtG.js"; import { m as recordInboundSessionMeta, p as readSessionUpdatedAtCore, y as updateSessionLastRoute } from "./session-accessor.sqlite-entry-CWk3jL7s.js"; import { a as shouldComputeCommandAuthorized, r as isControlCommandMessage, t as hasControlCommand } from "./command-detection-DoshyUmB.js"; import "./sessions-9nxpeTwt.js"; import { t as finalizeInboundContext } from "./inbound-context-BJXKd4x8.js"; import { a as createReplyDispatcherWithTyping } from "./reply-dispatcher-BjdCLv_G.js"; import { i as resolveHumanDelayConfig, r as resolveEffectiveMessagesConfig } from "./identity-L3YWE18q.js"; import { n as resolveChannelGroupRequireMention, t as resolveChannelGroupPolicy } from "./group-policy-BXx44oG5.js"; import { m as withReplyDispatcher, p as settleReplyDispatcher } from "./dispatch-from-config.finalize-DcagE2ge.js"; import { t as dispatchLowLevelChannelReplyFromConfig } from "./dispatch-from-config-Djp-96vr.js"; import { n as resolveSessionEntryResetFreshness } from "./entry-freshness-C81RWf2e.js"; import { s as resolveAgentRoute, t as buildAgentSessionKey } from "./resolve-route-BRXfbiKP.js"; import { a as chunkText, c as resolveTextChunkLimit, i as chunkMarkdownTextWithMode, o as chunkTextWithMode, r as chunkMarkdownText, s as resolveChunkMode, t as chunkByNewline } from "./chunk-DqjJztIp.js"; import { n as shouldHandleTextCommands } from "./commands-text-routing-sBs1BOcS.js"; import "./commands-registry-zRoXYk7P.js"; import { n as matchesMentionPatterns, r as matchesMentionWithExplicit, t as buildMentionRegexes } from "./mentions-BXIDEOtX.js"; import "./dispatch-rmguZY5M.js"; import { t as dispatchReplyWithBufferedBlockDispatcherCore } from "./provider-dispatcher-DyFXY5kS.js"; import { t as convertMarkdownTables } from "./tables-DmJoahaN.js"; import { a as resolveEnvelopeFormatOptions, t as formatAgentEnvelope } from "./envelope-CGxzYKMZ.js"; import { n as resolveInboundDebounceMs, t as createInboundDebouncer } from "./inbound-debounce-DZwl-vWn.js"; import { i as shouldAckReaction, n as removeAckReactionAfterReply, r as removeAckReactionHandleAfterReply, t as createAckReactionHandle } from "./ack-reactions-B_Yz1J57.js"; import { t as resolveCommandAuthorizedFromAuthorizers } from "./command-gating-65fgTdwb.js"; import { n as runChannelTurn, r as buildChannelInboundEventContext } from "./run-channel-turn-g-1d9x-q.js"; import { n as implicitMentionKindWhen, r as resolveInboundMentionDecision } from "./mention-gating-Cqy7URJJ.js"; import { n as setChannelConversationBindingMaxAgeBySessionKey, t as setChannelConversationBindingIdleTimeoutBySessionKey } from "./conversation-bindings-CAZVeWpm.js"; import { t as loadChannelOutboundAdapter } from "./load-D5vgLr5j.js"; import { t as recordInboundSession } from "./session-CGo-oQbb.js"; import { i as runPreparedChannelTurn, n as dispatchAssembledChannelTurn, r as dispatchRoutedChannelTurn } from "./lifecycle-DQ-vfJ_s.js"; import { t as resolveMarkdownTableMode } from "./markdown-tables-BI-3mmWv.js"; import { n as recordChannelActivity, t as getChannelActivity } from "./channel-activity-KGHrbxIK.js"; import { t as buildPairingReply } from "./pairing-messages-D9xr66Yq.js"; import { d as upsertChannelPairingRequest, l as removeChannelAllowFromStoreEntry, s as readChannelAllowFromStore } from "./pairing-store-CxXcVQPq.js"; //#region src/plugins/runtime/channel-runtime-contexts.ts const log = createSubsystemLogger("plugins/runtime-channel"); function normalizeRuntimeContextString(value) { return normalizeOptionalString(value) ?? ""; } function normalizeRuntimeContextKey(params) { const channelId = normalizeRuntimeContextString(params.channelId); const capability = normalizeRuntimeContextString(params.capability); const accountId = normalizeRuntimeContextString(params.accountId); if (!channelId || !capability) return null; return { mapKey: `${channelId}\u0000${accountId}\u0000${capability}`, normalizedKey: { channelId, capability, ...accountId ? { accountId } : {} } }; } function doesRuntimeContextWatcherMatch(params) { if (params.watcher.channelId && params.watcher.channelId !== params.event.key.channelId) return false; if (params.watcher.accountId !== void 0 && params.watcher.accountId !== (params.event.key.accountId ?? "")) return false; if (params.watcher.capability && params.watcher.capability !== params.event.key.capability) return false; return true; } /** Creates the in-memory channel runtime context registry used by plugin runtime surfaces. */ function createChannelRuntimeContextRegistry() { const runtimeContexts = /* @__PURE__ */ new Map(); const runtimeContextWatchers = /* @__PURE__ */ new Set(); const emitRuntimeContextEvent = (event) => { for (const watcher of runtimeContextWatchers) { if (!doesRuntimeContextWatcherMatch({ watcher: watcher.filter, event })) continue; try { watcher.onEvent(event); } catch (error) { const message = error instanceof Error ? error.message : String(error); log.error(`runtime context watcher failed during ${event.type} channel=${event.key.channelId} capability=${event.key.capability}` + (event.key.accountId ? ` account=${event.key.accountId}` : "") + `: ${message}`); } } }; return { register: (params) => { const normalized = normalizeRuntimeContextKey(params); if (!normalized) return { dispose: () => {} }; if (params.abortSignal?.aborted) return { dispose: () => {} }; const token = Symbol(normalized.mapKey); let disposed = false; const dispose = () => { if (disposed) return; disposed = true; params.abortSignal?.removeEventListener("abort", dispose); const current = runtimeContexts.get(normalized.mapKey); if (!current || current.token !== token) return; runtimeContexts.delete(normalized.mapKey); emitRuntimeContextEvent({ type: "unregistered", key: normalized.normalizedKey }); }; params.abortSignal?.addEventListener("abort", dispose, { once: true }); if (params.abortSignal?.aborted) { dispose(); return { dispose }; } runtimeContexts.set(normalized.mapKey, { token, context: params.context, normalizedKey: normalized.normalizedKey }); if (disposed) return { dispose }; emitRuntimeContextEvent({ type: "registered", key: normalized.normalizedKey, context: params.context }); return { dispose }; }, get: (params) => { const normalized = normalizeRuntimeContextKey(params); if (!normalized) return; return runtimeContexts.get(normalized.mapKey)?.context; }, watch: (params) => { const watcher = { filter: { ...params.channelId?.trim() ? { channelId: params.channelId.trim() } : {}, ...params.accountId != null ? { accountId: params.accountId.trim() } : {}, ...params.capability?.trim() ? { capability: params.capability.trim() } : {} }, onEvent: params.onEvent }; runtimeContextWatchers.add(watcher); return () => { runtimeContextWatchers.delete(watcher); }; } }; } //#endregion //#region src/plugins/runtime/runtime-channel.ts function createRuntimeChannel(options) { const dispatchInbound = (params) => dispatchRoutedChannelTurn({ ...params, ...options?.dispatchReplyFromConfig ? { dispatchReplyFromConfig: options.dispatchReplyFromConfig } : {} }); const sessionRuntime = { resolveStorePath: resolveSessionStorePathCore, readSessionUpdatedAt: readSessionUpdatedAtCore, recordSessionMetaFromInbound: recordInboundSessionMeta, recordInboundSession, updateLastRoute: updateSessionLastRoute, resolveEntryResetFreshness: resolveSessionEntryResetFreshness }; return { text: { chunkByNewline, chunkMarkdownText, chunkMarkdownTextWithMode, chunkText, chunkTextWithMode, resolveChunkMode, resolveTextChunkLimit, hasControlCommand, resolveMarkdownTableMode, convertMarkdownTables }, reply: { dispatchReplyWithBufferedBlockDispatcher: dispatchReplyWithBufferedBlockDispatcherCore, createReplyDispatcherWithTyping, resolveEffectiveMessagesConfig, resolveHumanDelayConfig, dispatchReplyFromConfig: options?.dispatchReplyFromConfig ?? dispatchLowLevelChannelReplyFromConfig, withReplyDispatcher, settleReplyDispatcher, finalizeInboundContext, formatAgentEnvelope, resolveEnvelopeFormatOptions }, routing: { buildAgentSessionKey, resolveAgentRoute }, pairing: { buildPairingReply, readAllowFromStore: ({ channel, accountId, env }) => readChannelAllowFromStore(channel, env, accountId), removeAllowFromStoreEntry: ({ channel, entry, accountId, env, pairingAdapter }) => removeChannelAllowFromStoreEntry({ channel, entry, accountId, env, pairingAdapter }), upsertPairingRequest: ({ channel, id, accountId, meta, env, pairingAdapter }) => upsertChannelPairingRequest({ channel, id, accountId, meta, env, pairingAdapter }) }, media: { readRemoteMediaBuffer, fetchRemoteMedia: readRemoteMediaBuffer, saveRemoteMedia, saveResponseMedia, saveMediaBuffer }, activity: { record: recordChannelActivity, get: getChannelActivity }, session: sessionRuntime, mentions: { buildMentionRegexes, matchesMentionPatterns, matchesMentionWithExplicit, implicitMentionKindWhen, resolveInboundMentionDecision }, reactions: { createAckReactionHandle, shouldAckReaction, removeAckReactionAfterReply, removeAckReactionHandleAfterReply }, groups: { resolveGroupPolicy: resolveChannelGroupPolicy, resolveRequireMention: resolveChannelGroupRequireMention }, debounce: { createInboundDebouncer, resolveInboundDebounceMs }, commands: { resolveCommandAuthorizedFromAuthorizers, isControlCommandMessage, shouldComputeCommandAuthorized, shouldHandleTextCommands }, outbound: { loadAdapter: loadChannelOutboundAdapter }, inbound: { buildContext: buildChannelInboundEventContext, run: runChannelTurn, runPreparedReply: runPreparedChannelTurn, dispatch: dispatchInbound, dispatchReply: dispatchAssembledChannelTurn }, threadBindings: { setIdleTimeoutBySessionKey: ({ channelId, targetSessionKey, accountId, idleTimeoutMs }) => setChannelConversationBindingIdleTimeoutBySessionKey({ channelId, targetSessionKey, accountId, idleTimeoutMs }), setMaxAgeBySessionKey: ({ channelId, targetSessionKey, accountId, maxAgeMs }) => setChannelConversationBindingMaxAgeBySessionKey({ channelId, targetSessionKey, accountId, maxAgeMs }) }, runtimeContexts: createChannelRuntimeContextRegistry() }; } //#endregion export { createRuntimeChannel as t };