refactor: add private channel sdk bridges

This commit is contained in:
Peter Steinberger
2026-03-16 01:34:35 -07:00
parent 7e74adef91
commit 4c8678c0b4
7 changed files with 820 additions and 0 deletions

View File

@@ -0,0 +1,331 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk";
import { parseSlackBlocksInput } from "./blocks-input.js";
import { buildSlackInteractiveBlocks } from "./blocks-render.js";
type SlackActionInvoke = (
action: Record<string, unknown>,
cfg: ChannelMessageActionContext["cfg"],
toolContext?: ChannelMessageActionContext["toolContext"],
) => Promise<AgentToolResult<unknown>>;
type InteractiveButtonStyle = "primary" | "secondary" | "success" | "danger";
type InteractiveReplyButton = {
label: string;
value: string;
style?: InteractiveButtonStyle;
};
type InteractiveReplyOption = {
label: string;
value: string;
};
type InteractiveReplyBlock =
| { type: "text"; text: string }
| { type: "buttons"; buttons: InteractiveReplyButton[] }
| { type: "select"; placeholder?: string; options: InteractiveReplyOption[] };
type InteractiveReply = {
blocks: InteractiveReplyBlock[];
};
function readTrimmedString(value: unknown): string | undefined {
if (typeof value !== "string") {
return undefined;
}
const trimmed = value.trim();
return trimmed || undefined;
}
function normalizeButtonStyle(value: unknown): InteractiveButtonStyle | undefined {
const style = readTrimmedString(value)?.toLowerCase();
return style === "primary" || style === "secondary" || style === "success" || style === "danger"
? style
: undefined;
}
function normalizeInteractiveButton(raw: unknown): InteractiveReplyButton | undefined {
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
return undefined;
}
const record = raw as Record<string, unknown>;
const label = readTrimmedString(record.label) ?? readTrimmedString(record.text);
const value =
readTrimmedString(record.value) ??
readTrimmedString(record.callbackData) ??
readTrimmedString(record.callback_data);
if (!label || !value) {
return undefined;
}
return { label, value, style: normalizeButtonStyle(record.style) };
}
function normalizeInteractiveOption(raw: unknown): InteractiveReplyOption | undefined {
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
return undefined;
}
const record = raw as Record<string, unknown>;
const label = readTrimmedString(record.label) ?? readTrimmedString(record.text);
const value = readTrimmedString(record.value);
return label && value ? { label, value } : undefined;
}
function normalizeInteractiveReply(raw: unknown): InteractiveReply | undefined {
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
return undefined;
}
const record = raw as Record<string, unknown>;
const blocks = Array.isArray(record.blocks)
? record.blocks
.map((entry) => {
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
return undefined;
}
const block = entry as Record<string, unknown>;
const type = readTrimmedString(block.type)?.toLowerCase();
if (type === "text") {
const text = readTrimmedString(block.text);
return text ? ({ type: "text", text } as const) : undefined;
}
if (type === "buttons") {
const buttons = Array.isArray(block.buttons)
? block.buttons
.map((button) => normalizeInteractiveButton(button))
.filter((button): button is InteractiveReplyButton => Boolean(button))
: [];
return buttons.length > 0 ? ({ type: "buttons", buttons } as const) : undefined;
}
if (type === "select") {
const options = Array.isArray(block.options)
? block.options
.map((option) => normalizeInteractiveOption(option))
.filter((option): option is InteractiveReplyOption => Boolean(option))
: [];
return options.length > 0
? ({
type: "select",
placeholder: readTrimmedString(block.placeholder),
options,
} as const)
: undefined;
}
return undefined;
})
.filter((entry): entry is InteractiveReplyBlock => Boolean(entry))
: [];
return blocks.length > 0 ? { blocks } : undefined;
}
function readStringParam(
params: Record<string, unknown>,
key: string,
options: { required?: boolean; trim?: boolean; label?: string; allowEmpty?: boolean } = {},
): string | undefined {
const { required = false, trim = true, label = key, allowEmpty = false } = options;
const raw = params[key];
if (typeof raw !== "string") {
if (required) {
throw new Error(`${label} required`);
}
return undefined;
}
const value = trim ? raw.trim() : raw;
if (!value && !allowEmpty) {
if (required) {
throw new Error(`${label} required`);
}
return undefined;
}
return value;
}
function readNumberParam(
params: Record<string, unknown>,
key: string,
options: { required?: boolean; label?: string; integer?: boolean; strict?: boolean } = {},
): number | undefined {
const { required = false, label = key, integer = false, strict = false } = options;
const raw = params[key];
let value: number | undefined;
if (typeof raw === "number" && Number.isFinite(raw)) {
value = raw;
} else if (typeof raw === "string") {
const trimmed = raw.trim();
if (trimmed) {
const parsed = strict ? Number(trimmed) : Number.parseFloat(trimmed);
if (Number.isFinite(parsed)) {
value = parsed;
}
}
}
if (value === undefined) {
if (required) {
throw new Error(`${label} required`);
}
return undefined;
}
return integer ? Math.trunc(value) : value;
}
function readSlackBlocksParam(actionParams: Record<string, unknown>) {
return parseSlackBlocksInput(actionParams.blocks) as Record<string, unknown>[] | undefined;
}
export async function handleSlackMessageAction(params: {
providerId: string;
ctx: ChannelMessageActionContext;
invoke: SlackActionInvoke;
normalizeChannelId?: (channelId: string) => string;
includeReadThreadId?: boolean;
}): Promise<AgentToolResult<unknown>> {
const { providerId, ctx, invoke, normalizeChannelId, includeReadThreadId = false } = params;
const { action, cfg, params: actionParams } = ctx;
const accountId = ctx.accountId ?? undefined;
const resolveChannelId = () => {
const channelId =
readStringParam(actionParams, "channelId") ??
readStringParam(actionParams, "to", { required: true });
return normalizeChannelId ? normalizeChannelId(channelId) : channelId;
};
if (action === "send") {
const to = readStringParam(actionParams, "to", { required: true });
const content = readStringParam(actionParams, "message", { allowEmpty: true });
const mediaUrl = readStringParam(actionParams, "media", { trim: false });
const interactive = normalizeInteractiveReply(actionParams.interactive);
const interactiveBlocks = interactive ? buildSlackInteractiveBlocks(interactive) : undefined;
const blocks = readSlackBlocksParam(actionParams) ?? interactiveBlocks;
if (!content && !mediaUrl && !blocks) {
throw new Error("Slack send requires message, blocks, or media.");
}
if (mediaUrl && blocks) {
throw new Error("Slack send does not support blocks with media.");
}
const threadId = readStringParam(actionParams, "threadId");
const replyTo = readStringParam(actionParams, "replyTo");
return await invoke(
{
action: "sendMessage",
to,
content: content ?? "",
mediaUrl: mediaUrl ?? undefined,
accountId,
threadTs: threadId ?? replyTo ?? undefined,
...(blocks ? { blocks } : {}),
},
cfg,
ctx.toolContext,
);
}
if (action === "react") {
const messageId = readStringParam(actionParams, "messageId", { required: true });
const emoji = readStringParam(actionParams, "emoji", { allowEmpty: true });
const remove = typeof actionParams.remove === "boolean" ? actionParams.remove : undefined;
return await invoke(
{ action: "react", channelId: resolveChannelId(), messageId, emoji, remove, accountId },
cfg,
);
}
if (action === "reactions") {
const messageId = readStringParam(actionParams, "messageId", { required: true });
const limit = readNumberParam(actionParams, "limit", { integer: true });
return await invoke(
{ action: "reactions", channelId: resolveChannelId(), messageId, limit, accountId },
cfg,
);
}
if (action === "read") {
const limit = readNumberParam(actionParams, "limit", { integer: true });
const readAction: Record<string, unknown> = {
action: "readMessages",
channelId: resolveChannelId(),
limit,
before: readStringParam(actionParams, "before"),
after: readStringParam(actionParams, "after"),
accountId,
};
if (includeReadThreadId) {
readAction.threadId = readStringParam(actionParams, "threadId");
}
return await invoke(readAction, cfg);
}
if (action === "edit") {
const messageId = readStringParam(actionParams, "messageId", { required: true });
const content = readStringParam(actionParams, "message", { allowEmpty: true });
const blocks = readSlackBlocksParam(actionParams);
if (!content && !blocks) {
throw new Error("Slack edit requires message or blocks.");
}
return await invoke(
{
action: "editMessage",
channelId: resolveChannelId(),
messageId,
content: content ?? "",
blocks,
accountId,
},
cfg,
);
}
if (action === "delete") {
const messageId = readStringParam(actionParams, "messageId", { required: true });
return await invoke(
{ action: "deleteMessage", channelId: resolveChannelId(), messageId, accountId },
cfg,
);
}
if (action === "pin" || action === "unpin" || action === "list-pins") {
const messageId =
action === "list-pins"
? undefined
: readStringParam(actionParams, "messageId", { required: true });
return await invoke(
{
action: action === "pin" ? "pinMessage" : action === "unpin" ? "unpinMessage" : "listPins",
channelId: resolveChannelId(),
messageId,
accountId,
},
cfg,
);
}
if (action === "member-info") {
const userId = readStringParam(actionParams, "userId", { required: true });
return await invoke({ action: "memberInfo", userId, accountId }, cfg);
}
if (action === "emoji-list") {
const limit = readNumberParam(actionParams, "limit", { integer: true });
return await invoke({ action: "emojiList", limit, accountId }, cfg);
}
if (action === "download-file") {
const fileId = readStringParam(actionParams, "fileId", { required: true });
const channelId =
readStringParam(actionParams, "channelId") ?? readStringParam(actionParams, "to");
const threadId =
readStringParam(actionParams, "threadId") ?? readStringParam(actionParams, "replyTo");
return await invoke(
{
action: "downloadFile",
fileId,
channelId: channelId ?? undefined,
threadId: threadId ?? undefined,
accountId,
},
cfg,
);
}
throw new Error(`Action ${action} is not supported for provider ${providerId}.`);
}

View File

@@ -0,0 +1,116 @@
export type { ChannelMessageActionAdapter } from "../channels/plugins/types.js";
export type { OpenClawConfig } from "../config/config.js";
export type { DiscordAccountConfig, DiscordActionConfig } from "../config/types.js";
export type { InspectedDiscordAccount } from "../../extensions/discord/src/account-inspect.js";
export type { ResolvedDiscordAccount } from "../../extensions/discord/src/accounts.js";
export type {
DiscordSendComponents,
DiscordSendEmbeds,
} from "../../extensions/discord/src/send.shared.js";
export * from "../plugin-sdk/channel-plugin-common.js";
export {
createDiscordActionGate,
listDiscordAccountIds,
resolveDefaultDiscordAccountId,
resolveDiscordAccount,
} from "../../extensions/discord/src/accounts.js";
export { inspectDiscordAccount } from "../../extensions/discord/src/account-inspect.js";
export {
projectCredentialSnapshotFields,
resolveConfiguredFromCredentialStatuses,
} from "../channels/account-snapshot-fields.js";
export {
listDiscordDirectoryGroupsFromConfig,
listDiscordDirectoryPeersFromConfig,
} from "../channels/plugins/directory-config.js";
export {
looksLikeDiscordTargetId,
normalizeDiscordMessagingTarget,
normalizeDiscordOutboundTarget,
} from "../../extensions/discord/src/normalize.js";
export { collectDiscordAuditChannelIds } from "../../extensions/discord/src/audit.js";
export { collectDiscordStatusIssues } from "../../extensions/discord/src/status-issues.js";
export {
DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS,
DISCORD_DEFAULT_LISTENER_TIMEOUT_MS,
} from "../../extensions/discord/src/monitor/timeouts.js";
export { normalizeExplicitDiscordSessionKey } from "../../extensions/discord/src/session-key-normalization.js";
export type { DiscordPluralKitConfig } from "../../extensions/discord/src/pluralkit.js";
export {
resolveDefaultGroupPolicy,
resolveOpenProviderRuntimeGroupPolicy,
} from "../config/runtime-group-policy.js";
export {
resolveDiscordGroupRequireMention,
resolveDiscordGroupToolPolicy,
} from "../channels/plugins/group-mentions.js";
export { discordSetupWizard } from "../../extensions/discord/src/setup-surface.js";
export { discordSetupAdapter } from "../../extensions/discord/src/setup-core.js";
export { DiscordConfigSchema } from "../config/zod-schema.providers-core.js";
export {
autoBindSpawnedDiscordSubagent,
listThreadBindingsBySessionKey,
unbindThreadBindingsBySessionKey,
} from "../../extensions/discord/src/monitor/thread-bindings.js";
export { getGateway } from "../../extensions/discord/src/monitor/gateway-registry.js";
export { getPresence } from "../../extensions/discord/src/monitor/presence-cache.js";
export { readDiscordComponentSpec } from "../../extensions/discord/src/components.js";
export { resolveDiscordChannelId } from "../../extensions/discord/src/targets.js";
export {
addRoleDiscord,
banMemberDiscord,
createChannelDiscord,
createScheduledEventDiscord,
createThreadDiscord,
deleteChannelDiscord,
deleteMessageDiscord,
editChannelDiscord,
editMessageDiscord,
fetchChannelInfoDiscord,
fetchChannelPermissionsDiscord,
fetchMemberInfoDiscord,
fetchMessageDiscord,
fetchReactionsDiscord,
fetchRoleInfoDiscord,
fetchVoiceStatusDiscord,
hasAnyGuildPermissionDiscord,
kickMemberDiscord,
listGuildChannelsDiscord,
listGuildEmojisDiscord,
listPinsDiscord,
listScheduledEventsDiscord,
listThreadsDiscord,
moveChannelDiscord,
pinMessageDiscord,
reactMessageDiscord,
readMessagesDiscord,
removeChannelPermissionDiscord,
removeOwnReactionsDiscord,
removeReactionDiscord,
removeRoleDiscord,
searchMessagesDiscord,
sendDiscordComponentMessage,
sendMessageDiscord,
sendPollDiscord,
sendStickerDiscord,
sendVoiceMessageDiscord,
setChannelPermissionDiscord,
timeoutMemberDiscord,
unpinMessageDiscord,
uploadEmojiDiscord,
uploadStickerDiscord,
} from "../../extensions/discord/src/send.js";
export { discordMessageActions } from "../../extensions/discord/src/channel-actions.js";
export type {
ThreadBindingManager,
ThreadBindingRecord,
ThreadBindingTargetKind,
} from "../../extensions/discord/src/monitor/thread-bindings.js";
export {
buildComputedAccountStatusSnapshot,
buildTokenChannelStatusSummary,
} from "../plugin-sdk/status-helpers.js";

View File

@@ -0,0 +1,46 @@
export type { ResolvedIMessageAccount } from "../../extensions/imessage/src/accounts.js";
export type { IMessageAccountConfig } from "../config/types.js";
export * from "../plugin-sdk/channel-plugin-common.js";
export {
listIMessageAccountIds,
resolveDefaultIMessageAccountId,
resolveIMessageAccount,
} from "../../extensions/imessage/src/accounts.js";
export {
formatTrimmedAllowFromEntries,
resolveIMessageConfigAllowFrom,
resolveIMessageConfigDefaultTo,
} from "../plugin-sdk/channel-config-helpers.js";
export {
looksLikeIMessageTargetId,
normalizeIMessageMessagingTarget,
} from "../channels/plugins/normalize/imessage.js";
export {
createAllowedChatSenderMatcher,
parseChatAllowTargetPrefixes,
parseChatTargetPrefixesOrThrow,
resolveServicePrefixedChatTarget,
resolveServicePrefixedAllowTarget,
resolveServicePrefixedOrChatAllowTarget,
resolveServicePrefixedTarget,
} from "../../extensions/imessage/src/target-parsing-helpers.js";
export type {
ChatSenderAllowParams,
ParsedChatTarget,
} from "../../extensions/imessage/src/target-parsing-helpers.js";
export { sendMessageIMessage } from "../../extensions/imessage/src/send.js";
export {
resolveAllowlistProviderRuntimeGroupPolicy,
resolveDefaultGroupPolicy,
} from "../config/runtime-group-policy.js";
export {
resolveIMessageGroupRequireMention,
resolveIMessageGroupToolPolicy,
} from "../channels/plugins/group-mentions.js";
export { imessageSetupWizard } from "../../extensions/imessage/src/setup-surface.js";
export { imessageSetupAdapter } from "../../extensions/imessage/src/setup-core.js";
export { IMessageConfigSchema } from "../config/zod-schema.providers-core.js";
export { resolveChannelMediaMaxBytes } from "../channels/plugins/media-limits.js";
export { collectStatusIssuesFromLastError } from "../plugin-sdk/status-helpers.js";

View File

@@ -0,0 +1,38 @@
export type { ChannelMessageActionAdapter } from "../channels/plugins/types.js";
export type { ResolvedSignalAccount } from "../../extensions/signal/src/accounts.js";
export type { SignalAccountConfig } from "../config/types.js";
export * from "../plugin-sdk/channel-plugin-common.js";
export {
listEnabledSignalAccounts,
listSignalAccountIds,
resolveDefaultSignalAccountId,
resolveSignalAccount,
} from "../../extensions/signal/src/accounts.js";
export { resolveSignalReactionLevel } from "../../extensions/signal/src/reaction-level.js";
export {
removeReactionSignal,
sendReactionSignal,
} from "../../extensions/signal/src/send-reactions.js";
export { sendMessageSignal } from "../../extensions/signal/src/send.js";
export {
looksLikeSignalTargetId,
normalizeSignalMessagingTarget,
} from "../channels/plugins/normalize/signal.js";
export {
resolveAllowlistProviderRuntimeGroupPolicy,
resolveDefaultGroupPolicy,
} from "../config/runtime-group-policy.js";
export { signalSetupWizard } from "../../extensions/signal/src/setup-surface.js";
export { signalSetupAdapter } from "../../extensions/signal/src/setup-core.js";
export { SignalConfigSchema } from "../config/zod-schema.providers-core.js";
export { normalizeE164 } from "../utils.js";
export { resolveChannelMediaMaxBytes } from "../channels/plugins/media-limits.js";
export {
buildBaseAccountStatusSnapshot,
buildBaseChannelStatusSummary,
collectStatusIssuesFromLastError,
createDefaultChannelRuntimeState,
} from "../plugin-sdk/status-helpers.js";

View File

@@ -0,0 +1,68 @@
export type { OpenClawConfig } from "../config/config.js";
export type { SlackAccountConfig } from "../config/types.slack.js";
export type { InspectedSlackAccount } from "../../extensions/slack/src/account-inspect.js";
export type { ResolvedSlackAccount } from "../../extensions/slack/src/accounts.js";
export * from "../plugin-sdk/channel-plugin-common.js";
export {
listEnabledSlackAccounts,
listSlackAccountIds,
resolveDefaultSlackAccountId,
resolveSlackAccount,
resolveSlackReplyToMode,
} from "../../extensions/slack/src/accounts.js";
export { isSlackInteractiveRepliesEnabled } from "../../extensions/slack/src/interactive-replies.js";
export { inspectSlackAccount } from "../../extensions/slack/src/account-inspect.js";
export {
projectCredentialSnapshotFields,
resolveConfiguredFromCredentialStatuses,
resolveConfiguredFromRequiredCredentialStatuses,
} from "../channels/account-snapshot-fields.js";
export {
listSlackDirectoryGroupsFromConfig,
listSlackDirectoryPeersFromConfig,
} from "../channels/plugins/directory-config.js";
export {
looksLikeSlackTargetId,
normalizeSlackMessagingTarget,
} from "../channels/plugins/normalize/slack.js";
export { parseSlackTarget, resolveSlackChannelId } from "../plugin-sdk/slack-targets.js";
export {
extractSlackToolSend,
listSlackMessageActions,
} from "../../extensions/slack/src/message-actions.js";
export { buildSlackThreadingToolContext } from "../../extensions/slack/src/threading-tool-context.js";
export { parseSlackBlocksInput } from "../../extensions/slack/src/blocks-input.js";
export { handleSlackHttpRequest } from "../../extensions/slack/src/http/index.js";
export { sendMessageSlack } from "../../extensions/slack/src/send.js";
export {
deleteSlackMessage,
downloadSlackFile,
editSlackMessage,
getSlackMemberInfo,
listSlackEmojis,
listSlackPins,
listSlackReactions,
pinSlackMessage,
reactSlackMessage,
readSlackMessages,
removeOwnSlackReactions,
removeSlackReaction,
sendSlackMessage,
unpinSlackMessage,
} from "../../extensions/slack/src/actions.js";
export { recordSlackThreadParticipation } from "../../extensions/slack/src/sent-thread-cache.js";
export { buildComputedAccountStatusSnapshot } from "../plugin-sdk/status-helpers.js";
export {
resolveDefaultGroupPolicy,
resolveOpenProviderRuntimeGroupPolicy,
} from "../config/runtime-group-policy.js";
export {
resolveSlackGroupRequireMention,
resolveSlackGroupToolPolicy,
} from "../channels/plugins/group-mentions.js";
export { slackSetupAdapter } from "../../extensions/slack/src/setup-core.js";
export { slackSetupWizard } from "../../extensions/slack/src/setup-surface.js";
export { SlackConfigSchema } from "../config/zod-schema.providers-core.js";
export { handleSlackMessageAction } from "../plugin-sdk/slack-message-actions.js";

View File

@@ -0,0 +1,113 @@
export type {
ChannelAccountSnapshot,
ChannelGatewayContext,
ChannelMessageActionAdapter,
} from "../channels/plugins/types.js";
export type { ChannelPlugin } from "../channels/plugins/types.plugin.js";
export type { OpenClawConfig } from "../config/config.js";
export type { PluginRuntime } from "../plugins/runtime/types.js";
export type { OpenClawPluginApi } from "../plugins/types.js";
export type { TelegramAccountConfig, TelegramActionConfig } from "../config/types.js";
export type { InspectedTelegramAccount } from "../../extensions/telegram/src/account-inspect.js";
export type { ResolvedTelegramAccount } from "../../extensions/telegram/src/accounts.js";
export type { TelegramProbe } from "../../extensions/telegram/src/probe.js";
export type {
TelegramButtonStyle,
TelegramInlineButtons,
} from "../../extensions/telegram/src/button-types.js";
export { emptyPluginConfigSchema } from "../plugins/config-schema.js";
export { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js";
export {
applyAccountNameToChannelSection,
migrateBaseNameToDefaultAccount,
} from "../channels/plugins/setup-helpers.js";
export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js";
export {
deleteAccountFromConfigSection,
clearAccountEntryFields,
setAccountEnabledInConfigSection,
} from "../channels/plugins/config-helpers.js";
export { formatPairingApproveHint } from "../channels/plugins/helpers.js";
export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js";
export { getChatChannelMeta } from "../channels/registry.js";
export {
createTelegramActionGate,
listTelegramAccountIds,
resolveDefaultTelegramAccountId,
resolveTelegramPollActionGateState,
resolveTelegramAccount,
} from "../../extensions/telegram/src/accounts.js";
export { inspectTelegramAccount } from "../../extensions/telegram/src/account-inspect.js";
export {
projectCredentialSnapshotFields,
resolveConfiguredFromCredentialStatuses,
} from "../channels/account-snapshot-fields.js";
export {
listTelegramDirectoryGroupsFromConfig,
listTelegramDirectoryPeersFromConfig,
} from "../channels/plugins/directory-config.js";
export {
looksLikeTelegramTargetId,
normalizeTelegramMessagingTarget,
} from "../../extensions/telegram/src/normalize.js";
export {
parseTelegramReplyToMessageId,
parseTelegramThreadId,
} from "../../extensions/telegram/src/outbound-params.js";
export {
isNumericTelegramUserId,
normalizeTelegramAllowFromEntry,
} from "../../extensions/telegram/src/allow-from.js";
export { fetchTelegramChatId } from "../../extensions/telegram/src/api-fetch.js";
export {
resolveTelegramInlineButtonsScope,
resolveTelegramTargetChatType,
} from "../../extensions/telegram/src/inline-buttons.js";
export { resolveTelegramReactionLevel } from "../../extensions/telegram/src/reaction-level.js";
export {
createForumTopicTelegram,
deleteMessageTelegram,
editForumTopicTelegram,
editMessageTelegram,
reactMessageTelegram,
sendMessageTelegram,
sendPollTelegram,
sendStickerTelegram,
} from "../../extensions/telegram/src/send.js";
export { getCacheStats, searchStickers } from "../../extensions/telegram/src/sticker-cache.js";
export { resolveTelegramToken } from "../../extensions/telegram/src/token.js";
export { telegramMessageActions } from "../../extensions/telegram/src/channel-actions.js";
export { collectTelegramStatusIssues } from "../../extensions/telegram/src/status-issues.js";
export { sendTelegramPayloadMessages } from "../../extensions/telegram/src/outbound-adapter.js";
export {
buildBrowseProvidersButton,
buildModelsKeyboard,
buildProviderKeyboard,
calculateTotalPages,
getModelsPageSize,
type ProviderInfo,
} from "../../extensions/telegram/src/model-buttons.js";
export {
isTelegramExecApprovalApprover,
isTelegramExecApprovalClientEnabled,
} from "../../extensions/telegram/src/exec-approvals.js";
export type { StickerMetadata } from "../../extensions/telegram/src/bot/types.js";
export {
resolveAllowlistProviderRuntimeGroupPolicy,
resolveDefaultGroupPolicy,
} from "../config/runtime-group-policy.js";
export {
resolveTelegramGroupRequireMention,
resolveTelegramGroupToolPolicy,
} from "../channels/plugins/group-mentions.js";
export { telegramSetupWizard } from "../../extensions/telegram/src/setup-surface.js";
export { telegramSetupAdapter } from "../../extensions/telegram/src/setup-core.js";
export { TelegramConfigSchema } from "../config/zod-schema.providers-core.js";
export { buildTokenChannelStatusSummary } from "../plugin-sdk/status-helpers.js";

View File

@@ -0,0 +1,108 @@
export type { ChannelMessageActionName } from "../channels/plugins/types.js";
export type { ChannelPlugin } from "../channels/plugins/types.plugin.js";
export type { OpenClawConfig } from "../config/config.js";
export type { DmPolicy, GroupPolicy, WhatsAppAccountConfig } from "../config/types.js";
export type { PluginRuntime } from "../plugins/runtime/types.js";
export type { OpenClawPluginApi } from "../plugins/types.js";
export { emptyPluginConfigSchema } from "../plugins/config-schema.js";
export { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js";
export {
applyAccountNameToChannelSection,
migrateBaseNameToDefaultAccount,
} from "../channels/plugins/setup-helpers.js";
export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js";
export { formatPairingApproveHint } from "../channels/plugins/helpers.js";
export { getChatChannelMeta } from "../channels/registry.js";
export {
formatWhatsAppConfigAllowFromEntries,
resolveWhatsAppConfigAllowFrom,
resolveWhatsAppConfigDefaultTo,
} from "../plugin-sdk/channel-config-helpers.js";
export {
listWhatsAppDirectoryGroupsFromConfig,
listWhatsAppDirectoryPeersFromConfig,
} from "../channels/plugins/directory-config.js";
export {
hasAnyWhatsAppAuth,
listEnabledWhatsAppAccounts,
resolveWhatsAppAccount,
} from "../../extensions/whatsapp/src/accounts.js";
export {
WA_WEB_AUTH_DIR,
logWebSelfId,
logoutWeb,
pickWebChannel,
webAuthExists,
} from "../../extensions/whatsapp/src/auth-store.js";
export {
DEFAULT_WEB_MEDIA_BYTES,
HEARTBEAT_PROMPT,
HEARTBEAT_TOKEN,
monitorWebChannel,
resolveHeartbeatRecipients,
runWebHeartbeatOnce,
} from "../../extensions/whatsapp/src/auto-reply.js";
export type {
WebChannelStatus,
WebMonitorTuning,
} from "../../extensions/whatsapp/src/auto-reply.js";
export {
extractMediaPlaceholder,
extractText,
monitorWebInbox,
} from "../../extensions/whatsapp/src/inbound.js";
export type {
WebInboundMessage,
WebListenerCloseReason,
} from "../../extensions/whatsapp/src/inbound.js";
export { loginWeb } from "../../extensions/whatsapp/src/login.js";
export {
getDefaultLocalRoots,
loadWebMedia,
loadWebMediaRaw,
optimizeImageToJpeg,
} from "../../extensions/whatsapp/src/media.js";
export {
sendMessageWhatsApp,
sendPollWhatsApp,
sendReactionWhatsApp,
} from "../../extensions/whatsapp/src/send.js";
export {
createWaSocket,
formatError,
getStatusCode,
waitForWaConnection,
} from "../../extensions/whatsapp/src/session.js";
export { createWhatsAppLoginTool } from "../../extensions/whatsapp/src/agent-tools-login.js";
export { normalizeWhatsAppAllowFromEntries } from "../channels/plugins/normalize/whatsapp.js";
export {
collectAllowlistProviderGroupPolicyWarnings,
collectOpenGroupPolicyRouteAllowlistWarnings,
} from "../channels/plugins/group-policy-warnings.js";
export { buildAccountScopedDmSecurityPolicy } from "../channels/plugins/helpers.js";
export { resolveWhatsAppOutboundTarget } from "../whatsapp/resolve-outbound-target.js";
export {
resolveAllowlistProviderRuntimeGroupPolicy,
resolveDefaultGroupPolicy,
} from "../config/runtime-group-policy.js";
export {
resolveWhatsAppGroupRequireMention,
resolveWhatsAppGroupToolPolicy,
} from "../channels/plugins/group-mentions.js";
export {
createWhatsAppOutboundBase,
resolveWhatsAppGroupIntroHint,
resolveWhatsAppMentionStripRegexes,
} from "../channels/plugins/whatsapp-shared.js";
export { resolveWhatsAppHeartbeatRecipients } from "../channels/plugins/whatsapp-heartbeat.js";
export { WhatsAppConfigSchema } from "../config/zod-schema.providers-whatsapp.js";
export { createActionGate, readStringParam } from "../agents/tools/common.js";
export { createPluginRuntimeStore } from "../plugin-sdk/runtime-store.js";
export { normalizeE164 } from "../utils.js";