| import { convertMarkdownTables } from "../../../packages/markdown-core/src/tables.js"; |
| import { resolveEffectiveMessagesConfig, resolveHumanDelayConfig } from "../../agents/identity.js"; |
| import { |
| chunkByNewline, |
| chunkMarkdownText, |
| chunkMarkdownTextWithMode, |
| chunkText, |
| chunkTextWithMode, |
| resolveChunkMode, |
| resolveTextChunkLimit, |
| } from "../../auto-reply/chunk.js"; |
| import { |
| hasControlCommand, |
| isControlCommandMessage, |
| shouldComputeCommandAuthorized, |
| } from "../../auto-reply/command-detection.js"; |
| import { shouldHandleTextCommands } from "../../auto-reply/commands-registry.js"; |
| import { |
| settleReplyDispatcher, |
| withReplyDispatcher, |
| } from "../../auto-reply/dispatch-dispatcher.js"; |
| import { formatAgentEnvelope, resolveEnvelopeFormatOptions } from "../../auto-reply/envelope.js"; |
| import { |
| createInboundDebouncer, |
| resolveInboundDebounceMs, |
| } from "../../auto-reply/inbound-debounce.js"; |
| import { finalizeInboundContext } from "../../auto-reply/reply/inbound-context.js"; |
| import { |
| buildMentionRegexes, |
| matchesMentionPatterns, |
| matchesMentionWithExplicit, |
| } from "../../auto-reply/reply/mentions.js"; |
| import { createReplyDispatcherWithTyping } from "../../auto-reply/reply/reply-dispatcher.js"; |
| import { |
| createAckReactionHandle, |
| removeAckReactionAfterReply, |
| removeAckReactionHandleAfterReply, |
| shouldAckReaction, |
| } from "../../channels/ack-reactions.js"; |
| import { resolveCommandAuthorizedFromAuthorizers } from "../../channels/command-gating.js"; |
| import { buildChannelInboundEventContext } from "../../channels/inbound-event/context.js"; |
| import { |
| implicitMentionKindWhen, |
| resolveInboundMentionDecision, |
| } from "../../channels/mention-gating.js"; |
| import { |
| setChannelConversationBindingIdleTimeoutBySessionKey, |
| setChannelConversationBindingMaxAgeBySessionKey, |
| } from "../../channels/plugins/conversation-bindings.js"; |
| import { loadChannelOutboundAdapter } from "../../channels/plugins/outbound/load.js"; |
| import { recordInboundSession } from "../../channels/session.js"; |
| import { |
| resolveChannelGroupPolicy, |
| resolveChannelGroupRequireMention, |
| } from "../../config/group-policy.js"; |
| import { resolveMarkdownTableMode } from "../../config/markdown-tables.js"; |
| import { resolveSessionStorePathCore } from "../../config/sessions.js"; |
| import { resolveSessionEntryResetFreshness } from "../../config/sessions/entry-freshness.js"; |
| import { |
| readSessionUpdatedAtCore, |
| recordInboundSessionMeta, |
| updateSessionLastRoute, |
| } from "../../config/sessions/session-accessor.js"; |
| import { getChannelActivity, recordChannelActivity } from "../../infra/channel-activity.js"; |
| import { readRemoteMediaBuffer, saveRemoteMedia, saveResponseMedia } from "../../media/fetch.js"; |
| import { saveMediaBuffer } from "../../media/store.js"; |
| import { buildPairingReply } from "../../pairing/pairing-messages.js"; |
| import { |
| readChannelAllowFromStore, |
| removeChannelAllowFromStoreEntry, |
| upsertChannelPairingRequest, |
| } from "../../pairing/pairing-store.js"; |
| import { buildAgentSessionKey, resolveAgentRoute } from "../../routing/resolve-route.js"; |
| import { createLazyRuntimeMethod, createLazyRuntimeModule } from "../../shared/lazy-runtime.js"; |
| import { createChannelRuntimeContextRegistry } from "./channel-runtime-contexts.js"; |
| import type { PluginRuntime } from "./types.js"; |
|
|
| |
| const dispatchLowLevelChannelReplyFromConfig = createLazyRuntimeMethod( |
| createLazyRuntimeModule(() => import("../../auto-reply/reply/dispatch-from-config.js")), |
| (runtime) => runtime.dispatchLowLevelChannelReplyFromConfig, |
| ); |
| const dispatchReplyWithBufferedBlockDispatcherCore = createLazyRuntimeMethod( |
| createLazyRuntimeModule(() => import("../../auto-reply/reply/provider-dispatcher.js")), |
| (runtime) => runtime.dispatchReplyWithBufferedBlockDispatcherCore, |
| ); |
| const loadChannelTurnLifecycle = createLazyRuntimeModule( |
| () => import("../../channels/turn/lifecycle.js"), |
| ); |
| const dispatchAssembledChannelTurn = createLazyRuntimeMethod( |
| loadChannelTurnLifecycle, |
| (runtime) => runtime.dispatchAssembledChannelTurn, |
| ); |
| const loadPreparedChannelTurn = createLazyRuntimeModule( |
| () => import("../../channels/turn/execution.js"), |
| ); |
| const runPreparedChannelTurn: PluginRuntime["channel"]["inbound"]["runPreparedReply"] = async ( |
| params, |
| ) => (await loadPreparedChannelTurn()).runPreparedChannelTurn(params); |
| const runChannelTurn = createLazyRuntimeMethod( |
| createLazyRuntimeModule(() => import("../../channels/turn/run-channel-turn.js")), |
| (runtime) => runtime.runChannelTurn, |
| |
| ) as PluginRuntime["channel"]["inbound"]["run"]; |
|
|
| export function createRuntimeChannel(options?: { |
| dispatchReplyFromConfig?: PluginRuntime["channel"]["reply"]["dispatchReplyFromConfig"]; |
| }): PluginRuntime["channel"] { |
| const dispatchInbound: PluginRuntime["channel"]["inbound"]["dispatch"] = async (params) => |
| (await loadChannelTurnLifecycle()).dispatchRoutedChannelTurn({ |
| ...params, |
| ...(options?.dispatchReplyFromConfig |
| ? { dispatchReplyFromConfig: options.dispatchReplyFromConfig } |
| : {}), |
| }); |
| const sessionRuntime = { |
| resolveStorePath: resolveSessionStorePathCore, |
| readSessionUpdatedAt: readSessionUpdatedAtCore, |
| |
| |
| recordSessionMetaFromInbound: recordInboundSessionMeta, |
| recordInboundSession, |
| updateLastRoute: updateSessionLastRoute, |
| resolveEntryResetFreshness: resolveSessionEntryResetFreshness, |
| }; |
| const channelRuntime = { |
| 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(), |
| } satisfies PluginRuntime["channel"]; |
|
|
| return channelRuntime as PluginRuntime["channel"]; |
| } |
|
|