refactor(plugin-sdk): remove channel-specific sdk shims

This commit is contained in:
Peter Steinberger
2026-03-30 00:59:53 +01:00
parent bff6a6a9c1
commit 471e059b69
27 changed files with 244 additions and 729 deletions

View File

@@ -1,21 +1,25 @@
import type { OpenClawConfig as RuntimeApiOpenClawConfig } from "openclaw/plugin-sdk/core";
export {
DEFAULT_ACCOUNT_ID,
PAIRING_APPROVED_MESSAGE,
buildComputedAccountStatusSnapshot,
buildChannelConfigSchema,
chunkTextForOutbound,
collectStatusIssuesFromLastError,
formatTrimmedAllowFromEntries,
getChatChannelMeta,
looksLikeIMessageTargetId,
normalizeIMessageMessagingTarget,
resolveChannelMediaMaxBytes,
type ChannelPlugin,
type OpenClawConfig,
} from "openclaw/plugin-sdk/core";
export { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
export {
buildComputedAccountStatusSnapshot,
collectStatusIssuesFromLastError,
} from "openclaw/plugin-sdk/status-helpers";
export {
formatTrimmedAllowFromEntries,
resolveIMessageConfigAllowFrom,
resolveIMessageConfigDefaultTo,
IMessageConfigSchema,
type ChannelPlugin,
type IMessageAccountConfig,
} from "openclaw/plugin-sdk/imessage";
} from "openclaw/plugin-sdk/channel-config-helpers";
export { looksLikeIMessageTargetId, normalizeIMessageMessagingTarget } from "./src/normalize.js";
export { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
export { IMessageConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
export {
resolveIMessageGroupRequireMention,
resolveIMessageGroupToolPolicy,
@@ -26,3 +30,24 @@ export type { MonitorIMessageOpts } from "./src/monitor.js";
export { probeIMessage } from "./src/probe.js";
export type { IMessageProbe } from "./src/probe.js";
export { sendMessageIMessage } from "./src/send.js";
export type IMessageAccountConfig = Omit<
NonNullable<NonNullable<RuntimeApiOpenClawConfig["channels"]>["imessage"]>,
"accounts" | "defaultAccount"
>;
export function chunkTextForOutbound(text: string, limit: number): string[] {
const chunks: string[] = [];
let remaining = text;
while (remaining.length > limit) {
const window = remaining.slice(0, limit);
const splitAt = Math.max(window.lastIndexOf("\n"), window.lastIndexOf(" "));
const breakAt = splitAt > 0 ? splitAt : limit;
chunks.push(remaining.slice(0, breakAt).trimEnd());
remaining = remaining.slice(breakAt).trimStart();
}
if (remaining.length > 0 || text.length === 0) {
chunks.push(remaining);
}
return chunks;
}

View File

@@ -489,18 +489,6 @@
"types": "./dist/plugin-sdk/image-generation-core.d.ts",
"default": "./dist/plugin-sdk/image-generation-core.js"
},
"./plugin-sdk/imessage": {
"types": "./dist/plugin-sdk/imessage.d.ts",
"default": "./dist/plugin-sdk/imessage.js"
},
"./plugin-sdk/imessage-policy": {
"types": "./dist/plugin-sdk/imessage-policy.d.ts",
"default": "./dist/plugin-sdk/imessage-policy.js"
},
"./plugin-sdk/imessage-runtime": {
"types": "./dist/plugin-sdk/imessage-runtime.d.ts",
"default": "./dist/plugin-sdk/imessage-runtime.js"
},
"./plugin-sdk/irc": {
"types": "./dist/plugin-sdk/irc.d.ts",
"default": "./dist/plugin-sdk/irc.js"
@@ -853,10 +841,6 @@
"types": "./dist/plugin-sdk/synthetic.d.ts",
"default": "./dist/plugin-sdk/synthetic.js"
},
"./plugin-sdk/telegram": {
"types": "./dist/plugin-sdk/telegram.d.ts",
"default": "./dist/plugin-sdk/telegram.js"
},
"./plugin-sdk/telegram-account": {
"types": "./dist/plugin-sdk/telegram-account.d.ts",
"default": "./dist/plugin-sdk/telegram-account.js"
@@ -869,14 +853,6 @@
"types": "./dist/plugin-sdk/telegram-core.d.ts",
"default": "./dist/plugin-sdk/telegram-core.js"
},
"./plugin-sdk/telegram-runtime": {
"types": "./dist/plugin-sdk/telegram-runtime.d.ts",
"default": "./dist/plugin-sdk/telegram-runtime.js"
},
"./plugin-sdk/telegram-runtime-surface": {
"types": "./dist/plugin-sdk/telegram-runtime-surface.d.ts",
"default": "./dist/plugin-sdk/telegram-runtime-surface.js"
},
"./plugin-sdk/telegram-surface": {
"types": "./dist/plugin-sdk/telegram-surface.d.ts",
"default": "./dist/plugin-sdk/telegram-surface.js"

View File

@@ -112,9 +112,6 @@
"googlechat",
"image-generation",
"image-generation-core",
"imessage",
"imessage-policy",
"imessage-runtime",
"irc",
"irc-surface",
"kimi-coding",
@@ -203,12 +200,9 @@
"sglang",
"state-paths",
"synthetic",
"telegram",
"telegram-account",
"telegram-allow-from",
"telegram-core",
"telegram-runtime",
"telegram-runtime-surface",
"telegram-surface",
"thread-ownership",
"tlon",

View File

@@ -462,22 +462,6 @@ export const GENERATED_PLUGIN_SDK_FACADES = [
"KILOCODE_MODEL_CATALOG",
],
},
{
subpath: "imessage-policy",
source: pluginSource("imessage", "api.js"),
exports: [
"normalizeIMessageHandle",
"resolveIMessageRuntimeGroupPolicy",
"resolveIMessageGroupRequireMention",
"resolveIMessageGroupToolPolicy",
],
},
{
subpath: "imessage-runtime",
source: pluginSource("imessage", "runtime-api.js"),
exports: ["monitorIMessageProvider", "probeIMessage", "sendMessageIMessage"],
typeExports: ["IMessageProbe"],
},
{
subpath: "irc-surface",
source: pluginSource("irc", "api.js"),
@@ -1027,41 +1011,6 @@ export const GENERATED_PLUGIN_SDK_FACADES = [
source: pluginSource("telegram", "api.js"),
exports: ["isNumericTelegramUserId", "normalizeTelegramAllowFromEntry"],
},
{
subpath: "telegram-runtime-surface",
source: pluginSource("telegram", "runtime-api.js"),
exports: [
"auditTelegramGroupMembership",
"buildTelegramExecApprovalPendingPayload",
"collectTelegramUnmentionedGroupIds",
"createTelegramThreadBindingManager",
"createForumTopicTelegram",
"deleteMessageTelegram",
"editForumTopicTelegram",
"editMessageReplyMarkupTelegram",
"editMessageTelegram",
"monitorTelegramProvider",
"pinMessageTelegram",
"probeTelegram",
"reactMessageTelegram",
"renameForumTopicTelegram",
"resetTelegramThreadBindingsForTests",
"resolveTelegramRuntimeGroupPolicy",
"resolveTelegramToken",
"sendMessageTelegram",
"sendPollTelegram",
"sendStickerTelegram",
"sendTypingTelegram",
"setTelegramThreadBindingIdleTimeoutBySessionKey",
"setTelegramThreadBindingMaxAgeBySessionKey",
"shouldSuppressTelegramExecApprovalForwardingFallback",
"telegramMessageActions",
"TelegramApiOverride",
"TelegramProbe",
"unpinMessageTelegram",
],
typeExports: ["TelegramApiOverride", "TelegramProbe"],
},
{
subpath: "telegram-surface",
source: pluginSource("telegram", "api.js"),

View File

@@ -1,4 +1,4 @@
import { normalizeIMessageHandle } from "../../../plugin-sdk/imessage-policy.js";
import { normalizeE164 } from "../../../plugin-sdk/account-resolution.js";
import { looksLikeHandleOrPhoneTarget, trimMessagingTarget } from "./shared.js";
// Service prefixes that indicate explicit delivery method; must be preserved during normalization
@@ -6,6 +6,39 @@ const SERVICE_PREFIXES = ["imessage:", "sms:", "auto:"] as const;
const CHAT_TARGET_PREFIX_RE =
/^(chat_id:|chatid:|chat:|chat_guid:|chatguid:|guid:|chat_identifier:|chatidentifier:|chatident:)/i;
export function normalizeIMessageHandle(raw: string): string {
const trimmed = raw.trim();
if (!trimmed) {
return "";
}
const lowered = trimmed.toLowerCase();
if (lowered.startsWith("imessage:")) {
return normalizeIMessageHandle(trimmed.slice("imessage:".length));
}
if (lowered.startsWith("sms:")) {
return normalizeIMessageHandle(trimmed.slice("sms:".length));
}
if (lowered.startsWith("auto:")) {
return normalizeIMessageHandle(trimmed.slice("auto:".length));
}
if (CHAT_TARGET_PREFIX_RE.test(trimmed)) {
const prefix = trimmed.match(CHAT_TARGET_PREFIX_RE)?.[0];
if (!prefix) {
return "";
}
const value = trimmed.slice(prefix.length).trim();
return `${prefix.toLowerCase()}${value}`;
}
if (trimmed.includes("@")) {
return trimmed.toLowerCase();
}
const normalized = normalizeE164(trimmed);
if (normalized) {
return normalized;
}
return trimmed.replace(/\s+/g, "");
}
export function normalizeIMessageMessagingTarget(raw: string): string | undefined {
const trimmed = trimMessagingTarget(raw);
if (!trimmed) {

View File

@@ -4,10 +4,48 @@ import { loadModelCatalog } from "../agents/model-catalog.js";
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
import { runSubagentAnnounceFlow } from "../agents/subagent-announce.js";
import { callGateway } from "../gateway/call.js";
import { parseTelegramTarget } from "../plugin-sdk/telegram.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { createOutboundTestPlugin, createTestRegistry } from "../test-utils/channel-plugins.js";
function parseTelegramTargetForTest(raw: string): {
chatId: string;
messageThreadId?: number;
chatType: "direct" | "group" | "unknown";
} {
const trimmed = raw
.trim()
.replace(/^telegram:/i, "")
.replace(/^tg:/i, "");
const match = /^group:([^:]+):topic:(\d+)$/i.exec(trimmed);
if (match) {
return {
chatId: match[1],
messageThreadId: Number.parseInt(match[2], 10),
chatType: "group",
};
}
const topicMatch = /^([^:]+):topic:(\d+)$/i.exec(trimmed);
if (topicMatch) {
return {
chatId: topicMatch[1],
messageThreadId: Number.parseInt(topicMatch[2], 10),
chatType: topicMatch[1].startsWith("-") ? "group" : "direct",
};
}
const colonPair = /^([^:]+):(\d+)$/i.exec(trimmed);
if (colonPair && colonPair[1].startsWith("-")) {
return {
chatId: colonPair[1],
messageThreadId: Number.parseInt(colonPair[2], 10),
chatType: "group",
};
}
return {
chatId: trimmed,
chatType: trimmed.startsWith("-") ? "group" : "unknown",
};
}
export function setupIsolatedAgentTurnMocks(params?: { fast?: boolean }): void {
if (params?.fast) {
vi.stubEnv("OPENCLAW_TEST_FAST", "1");
@@ -25,7 +63,7 @@ export function setupIsolatedAgentTurnMocks(params?: { fast?: boolean }): void {
outbound: telegramOutbound,
messaging: {
parseExplicitTarget: ({ raw }) => {
const target = parseTelegramTarget(raw);
const target = parseTelegramTargetForTest(raw);
return {
to: target.chatId,
threadId: target.messageThreadId,

View File

@@ -253,26 +253,6 @@ export interface PluginSdkFacadeTypeMap {
};
types: {};
};
"imessage-policy": {
module: typeof import("@openclaw/imessage/api.js");
sourceModules: {
source1: {
module: typeof import("@openclaw/imessage/api.js");
};
};
types: {};
};
"imessage-runtime": {
module: typeof import("@openclaw/imessage/runtime-api.js");
sourceModules: {
source1: {
module: typeof import("@openclaw/imessage/runtime-api.js");
};
};
types: {
IMessageProbe: import("@openclaw/imessage/runtime-api.js").IMessageProbe;
};
};
"irc-surface": {
module: typeof import("@openclaw/irc/api.js");
sourceModules: {
@@ -680,18 +660,6 @@ export interface PluginSdkFacadeTypeMap {
};
types: {};
};
"telegram-runtime-surface": {
module: typeof import("@openclaw/telegram/runtime-api.js");
sourceModules: {
source1: {
module: typeof import("@openclaw/telegram/runtime-api.js");
};
};
types: {
TelegramApiOverride: import("@openclaw/telegram/runtime-api.js").TelegramApiOverride;
TelegramProbe: import("@openclaw/telegram/runtime-api.js").TelegramProbe;
};
};
"telegram-surface": {
module: typeof import("@openclaw/telegram/api.js");
sourceModules: {

View File

@@ -3,9 +3,24 @@ import type { ReplyPayload } from "../auto-reply/types.js";
import type { ChannelPlugin } from "../channels/plugins/types.js";
import type { OpenClawConfig } from "../config/config.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { loadBundledPluginTestApiSync } from "../test-utils/bundled-plugin-public-surface.js";
import { createChannelTestPluginBase, createTestRegistry } from "../test-utils/channel-plugins.js";
import { createExecApprovalForwarder } from "./exec-approval-forwarder.js";
const {
buildTelegramExecApprovalPendingPayload,
shouldSuppressTelegramExecApprovalForwardingFallback,
} = loadBundledPluginTestApiSync<{
buildTelegramExecApprovalPendingPayload: (params: {
request: unknown;
nowMs: number;
}) => ReplyPayload | null;
shouldSuppressTelegramExecApprovalForwardingFallback: (params: {
cfg: OpenClawConfig;
target: { channel: string; accountId?: string | null };
}) => boolean;
}>("telegram");
const baseRequest = {
id: "req-1",
request: {

View File

@@ -5,7 +5,6 @@ import { describe, expect, it } from "vitest";
import type { ChannelThreadingToolContext } from "../../channels/plugins/types.js";
import type { OpenClawConfig } from "../../config/config.js";
import { resolveSlackAutoThreadId } from "../../plugin-sdk/slack.js";
import { resolveTelegramAutoThreadId } from "../../plugin-sdk/telegram.js";
import {
hydrateAttachmentParamsForAction,
normalizeSandboxMediaList,
@@ -27,6 +26,38 @@ function createToolContext(
};
}
function resolveTelegramAutoThreadIdForTest(params: {
to: string;
toolContext?: { currentThreadTs?: string; currentChannelId?: string };
}): string | undefined {
const context = params.toolContext;
if (!context?.currentThreadTs || !context.currentChannelId) {
return undefined;
}
const normalizeChatId = (raw: string) => {
const trimmed = raw
.trim()
.replace(/^telegram:/i, "")
.replace(/^tg:/i, "");
const groupTopic = /^group:([^:]+):topic:\d+$/i.exec(trimmed);
if (groupTopic) {
return groupTopic[1].toLowerCase();
}
const topic = /^([^:]+):topic:\d+$/i.exec(trimmed);
if (topic) {
return topic[1].toLowerCase();
}
const colonPair = /^([^:]+):\d+$/i.exec(trimmed);
if (colonPair && colonPair[1].startsWith("-")) {
return colonPair[1].toLowerCase();
}
return trimmed.toLowerCase();
};
return normalizeChatId(params.to) === normalizeChatId(context.currentChannelId)
? context.currentThreadTs
: undefined;
}
describe("message action threading helpers", () => {
it("resolves Slack auto-thread ids only for matching active channels", () => {
expect(
@@ -75,7 +106,7 @@ describe("message action threading helpers", () => {
it("resolves Telegram auto-thread ids for matching chats across target formats", () => {
expect(
resolveTelegramAutoThreadId({
resolveTelegramAutoThreadIdForTest({
to: "telegram:group:-100123:topic:77",
toolContext: createToolContext({
currentChannelId: "tg:group:-100123",
@@ -83,7 +114,7 @@ describe("message action threading helpers", () => {
}),
).toBe("thread-1");
expect(
resolveTelegramAutoThreadId({
resolveTelegramAutoThreadIdForTest({
to: "-100999:77",
toolContext: createToolContext({
currentChannelId: "-100123",
@@ -91,7 +122,7 @@ describe("message action threading helpers", () => {
}),
).toBeUndefined();
expect(
resolveTelegramAutoThreadId({
resolveTelegramAutoThreadIdForTest({
to: "-100123",
toolContext: createToolContext({ currentChannelId: undefined }),
}),

View File

@@ -1,15 +1,53 @@
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { telegramOutbound, whatsappOutbound } from "../../../test/channel-outbounds.js";
import type { OpenClawConfig } from "../../config/config.js";
import { parseTelegramTarget } from "../../plugin-sdk/telegram.js";
import { isWhatsAppGroupJid, normalizeWhatsAppTarget } from "../../plugin-sdk/whatsapp-targets.js";
import { setActivePluginRegistry } from "../../plugins/runtime.js";
import { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js";
import { resolveOutboundTarget } from "./targets.js";
function parseTelegramTargetForTest(raw: string): {
chatId: string;
messageThreadId?: number;
chatType: "direct" | "group" | "unknown";
} {
const trimmed = raw
.trim()
.replace(/^telegram:/i, "")
.replace(/^tg:/i, "");
const prefixedTopic = /^group:([^:]+):topic:(\d+)$/i.exec(trimmed);
if (prefixedTopic) {
return {
chatId: prefixedTopic[1],
messageThreadId: Number.parseInt(prefixedTopic[2], 10),
chatType: "group",
};
}
const topic = /^([^:]+):topic:(\d+)$/i.exec(trimmed);
if (topic) {
return {
chatId: topic[1],
messageThreadId: Number.parseInt(topic[2], 10),
chatType: topic[1].startsWith("-") ? "group" : "direct",
};
}
const colonPair = /^([^:]+):(\d+)$/i.exec(trimmed);
if (colonPair && colonPair[1].startsWith("-")) {
return {
chatId: colonPair[1],
messageThreadId: Number.parseInt(colonPair[2], 10),
chatType: "group",
};
}
return {
chatId: trimmed,
chatType: trimmed.startsWith("-") ? "group" : "unknown",
};
}
const telegramMessaging = {
parseExplicitTarget: ({ raw }: { raw: string }) => {
const target = parseTelegramTarget(raw);
const target = parseTelegramTargetForTest(raw);
return {
to: target.chatId,
threadId: target.messageThreadId,

View File

@@ -2,6 +2,7 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
import { listTelegramAccountIds } from "../channels/read-only-account-inspect.telegram.js";
import type { OpenClawConfig } from "../config/config.js";
import {
resolveLegacyStateDirs,
@@ -15,7 +16,6 @@ import { canonicalizeMainSessionAlias } from "../config/sessions/main-session.js
import type { SessionScope } from "../config/sessions/types.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { resolveChannelAllowFromPath } from "../pairing/pairing-store.js";
import { listTelegramAccountIds } from "../plugin-sdk/telegram-runtime.js";
import {
buildAgentMainSessionKey,
DEFAULT_ACCOUNT_ID,

View File

@@ -1,32 +0,0 @@
// Generated by scripts/generate-plugin-sdk-facades.mjs. Do not edit manually.
import type { PluginSdkFacadeTypeMap } from "../generated/plugin-sdk-facade-type-map.generated.js";
type FacadeEntry = PluginSdkFacadeTypeMap["imessage-policy"];
type FacadeModule = FacadeEntry["module"];
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "imessage",
artifactBasename: "api.js",
});
}
export const normalizeIMessageHandle: FacadeModule["normalizeIMessageHandle"] = ((...args) =>
loadFacadeModule()["normalizeIMessageHandle"](
...args,
)) as FacadeModule["normalizeIMessageHandle"];
export const resolveIMessageRuntimeGroupPolicy: FacadeModule["resolveIMessageRuntimeGroupPolicy"] =
((...args) =>
loadFacadeModule()["resolveIMessageRuntimeGroupPolicy"](
...args,
)) as FacadeModule["resolveIMessageRuntimeGroupPolicy"];
export const resolveIMessageGroupRequireMention: FacadeModule["resolveIMessageGroupRequireMention"] =
((...args) =>
loadFacadeModule()["resolveIMessageGroupRequireMention"](
...args,
)) as FacadeModule["resolveIMessageGroupRequireMention"];
export const resolveIMessageGroupToolPolicy: FacadeModule["resolveIMessageGroupToolPolicy"] = ((
...args
) =>
loadFacadeModule()["resolveIMessageGroupToolPolicy"](
...args,
)) as FacadeModule["resolveIMessageGroupToolPolicy"];

View File

@@ -1,21 +0,0 @@
// Generated by scripts/generate-plugin-sdk-facades.mjs. Do not edit manually.
import type { PluginSdkFacadeTypeMap } from "../generated/plugin-sdk-facade-type-map.generated.js";
type FacadeEntry = PluginSdkFacadeTypeMap["imessage-runtime"];
type FacadeModule = FacadeEntry["module"];
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "imessage",
artifactBasename: "runtime-api.js",
});
}
export const monitorIMessageProvider: FacadeModule["monitorIMessageProvider"] = ((...args) =>
loadFacadeModule()["monitorIMessageProvider"](
...args,
)) as FacadeModule["monitorIMessageProvider"];
export const probeIMessage: FacadeModule["probeIMessage"] = ((...args) =>
loadFacadeModule()["probeIMessage"](...args)) as FacadeModule["probeIMessage"];
export const sendMessageIMessage: FacadeModule["sendMessageIMessage"] = ((...args) =>
loadFacadeModule()["sendMessageIMessage"](...args)) as FacadeModule["sendMessageIMessage"];
export type IMessageProbe = FacadeEntry["types"]["IMessageProbe"];

View File

@@ -1,114 +0,0 @@
import type { OpenClawConfig } from "../config/config.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
export type { IMessageAccountConfig } from "../config/types.js";
export type { IMessageProbe } from "./imessage-runtime.js";
export type { OpenClawConfig } from "../config/config.js";
export type {
ChannelMessageActionContext,
ChannelPlugin,
OpenClawPluginApi,
PluginRuntime,
} from "./channel-plugin-common.js";
export {
DEFAULT_ACCOUNT_ID,
PAIRING_APPROVED_MESSAGE,
applyAccountNameToChannelSection,
buildChannelConfigSchema,
deleteAccountFromConfigSection,
emptyPluginConfigSchema,
formatPairingApproveHint,
getChatChannelMeta,
migrateBaseNameToDefaultAccount,
normalizeAccountId,
setAccountEnabledInConfigSection,
} from "./channel-plugin-common.js";
export { detectBinary } from "../plugins/setup-binary.js";
export { formatDocsLink } from "../terminal/links.js";
export {
formatTrimmedAllowFromEntries,
resolveIMessageConfigAllowFrom,
resolveIMessageConfigDefaultTo,
} from "./channel-config-helpers.js";
export {
looksLikeIMessageTargetId,
normalizeIMessageMessagingTarget,
} from "../channels/plugins/normalize/imessage.js";
export {
createAllowedChatSenderMatcher,
parseChatAllowTargetPrefixes,
parseChatTargetPrefixesOrThrow,
resolveServicePrefixedAllowTarget,
resolveServicePrefixedChatTarget,
resolveServicePrefixedOrChatAllowTarget,
resolveServicePrefixedTarget,
type ChatSenderAllowParams,
type ParsedChatTarget,
} from "./channel-targets.js";
export {
resolveAllowlistProviderRuntimeGroupPolicy,
resolveDefaultGroupPolicy,
} from "../config/runtime-group-policy.js";
export {
normalizeIMessageHandle,
resolveIMessageGroupRequireMention,
resolveIMessageGroupToolPolicy,
} from "./imessage-policy.js";
export { IMessageConfigSchema } from "../config/zod-schema.providers-core.js";
export { resolveChannelMediaMaxBytes } from "../channels/plugins/media-limits.js";
export { chunkTextForOutbound } from "./text-chunking.js";
export {
buildComputedAccountStatusSnapshot,
collectStatusIssuesFromLastError,
} from "./status-helpers.js";
export { monitorIMessageProvider, probeIMessage, sendMessageIMessage } from "./imessage-runtime.js";
export type IMessageConversationBindingManager = {
stop: () => void;
};
type IMessageFacadeModule = {
createIMessageConversationBindingManager: (params: {
accountId?: string;
cfg: OpenClawConfig;
}) => IMessageConversationBindingManager;
matchIMessageAcpConversation: (params: {
bindingConversationId: string;
conversationId: string;
}) => { conversationId: string; matchPriority: number } | null;
normalizeIMessageAcpConversationId: (conversationId: string) => { conversationId: string } | null;
resolveIMessageConversationIdFromTarget: (target: string) => string | undefined;
};
function loadIMessageFacadeModule(): IMessageFacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<IMessageFacadeModule>({
dirName: "imessage",
artifactBasename: "api.js",
});
}
export function createIMessageConversationBindingManager(params: {
accountId?: string;
cfg: OpenClawConfig;
}): IMessageConversationBindingManager {
return loadIMessageFacadeModule().createIMessageConversationBindingManager(params);
}
export function normalizeIMessageAcpConversationId(
conversationId: string,
): { conversationId: string } | null {
return loadIMessageFacadeModule().normalizeIMessageAcpConversationId(conversationId);
}
export function matchIMessageAcpConversation(params: {
bindingConversationId: string;
conversationId: string;
}): { conversationId: string; matchPriority: number } | null {
return loadIMessageFacadeModule().matchIMessageAcpConversation(params);
}
export function resolveIMessageConversationIdFromTarget(target: string): string | undefined {
return loadIMessageFacadeModule().resolveIMessageConversationIdFromTarget(target);
}

View File

@@ -29,13 +29,21 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export * from "./src/send.js";',
],
[bundledPluginFile("imessage", "runtime-api.ts")]: [
'export { DEFAULT_ACCOUNT_ID, PAIRING_APPROVED_MESSAGE, buildComputedAccountStatusSnapshot, buildChannelConfigSchema, chunkTextForOutbound, collectStatusIssuesFromLastError, formatTrimmedAllowFromEntries, getChatChannelMeta, looksLikeIMessageTargetId, normalizeIMessageMessagingTarget, resolveChannelMediaMaxBytes, resolveIMessageConfigAllowFrom, resolveIMessageConfigDefaultTo, IMessageConfigSchema, type ChannelPlugin, type IMessageAccountConfig } from "openclaw/plugin-sdk/imessage";',
'export { DEFAULT_ACCOUNT_ID, buildChannelConfigSchema, getChatChannelMeta, type ChannelPlugin, type OpenClawConfig } from "openclaw/plugin-sdk/core";',
'export { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";',
'export { buildComputedAccountStatusSnapshot, collectStatusIssuesFromLastError } from "openclaw/plugin-sdk/status-helpers";',
'export { formatTrimmedAllowFromEntries, resolveIMessageConfigAllowFrom, resolveIMessageConfigDefaultTo } from "openclaw/plugin-sdk/channel-config-helpers";',
'export { looksLikeIMessageTargetId, normalizeIMessageMessagingTarget } from "./src/normalize.js";',
'export { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";',
'export { IMessageConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";',
'export { resolveIMessageGroupRequireMention, resolveIMessageGroupToolPolicy } from "./src/group-policy.js";',
'export { monitorIMessageProvider } from "./src/monitor.js";',
'export type { MonitorIMessageOpts } from "./src/monitor.js";',
'export { probeIMessage } from "./src/probe.js";',
'export type { IMessageProbe } from "./src/probe.js";',
'export { sendMessageIMessage } from "./src/send.js";',
'export type IMessageAccountConfig = Omit< NonNullable<NonNullable<RuntimeApiOpenClawConfig["channels"]>["imessage"]>, "accounts" | "defaultAccount" >;',
'export function chunkTextForOutbound(text: string, limit: number): string[] { const chunks: string[] = []; let remaining = text; while (remaining.length > limit) { const window = remaining.slice(0, limit); const splitAt = Math.max(window.lastIndexOf("\\n"), window.lastIndexOf(" ")); const breakAt = splitAt > 0 ? splitAt : limit; chunks.push(remaining.slice(0, breakAt).trimEnd()); remaining = remaining.slice(breakAt).trimStart(); } if (remaining.length > 0 || text.length === 0) { chunks.push(remaining); } return chunks; }',
],
[bundledPluginFile("googlechat", "runtime-api.ts")]: [
'export * from "openclaw/plugin-sdk/googlechat";',

View File

@@ -196,19 +196,6 @@ describe("plugin-sdk subpath exports", () => {
"buildTokenChannelStatusSummary",
"resolveConfiguredFromCredentialStatuses",
]);
expectSourceContains("telegram", 'export * from "./telegram-core.js";');
expectSourceContains("telegram", 'export * from "./telegram-runtime.js";');
expectSourceMentions("imessage", [
"normalizeIMessageAcpConversationId",
"matchIMessageAcpConversation",
"normalizeIMessageHandle",
"parseChatAllowTargetPrefixes",
"parseChatTargetPrefixesOrThrow",
"resolveIMessageConversationIdFromTarget",
"resolveServicePrefixedAllowTarget",
"resolveServicePrefixedTarget",
"chunkTextForOutbound",
]);
expectSourceMentions("bluebubbles", [
"normalizeBlueBubblesAcpConversationId",
"matchBlueBubblesAcpConversation",
@@ -459,14 +446,12 @@ describe("plugin-sdk subpath exports", () => {
expectSourceContract("reply-runtime", {
omits: [
"buildMentionRegexes",
"createInboundDebouncer",
"formatInboundEnvelope",
"formatInboundFromLabel",
"matchesMentionPatterns",
"matchesMentionWithExplicit",
"normalizeMentionText",
"resolveEnvelopeFormatOptions",
"resolveInboundDebounceMs",
"hasControlCommand",
"buildCommandTextFromArgs",
"buildCommandsPaginationKeyboard",

View File

@@ -1,109 +0,0 @@
// Generated by scripts/generate-plugin-sdk-facades.mjs. Do not edit manually.
import type { PluginSdkFacadeTypeMap } from "../generated/plugin-sdk-facade-type-map.generated.js";
type FacadeEntry = PluginSdkFacadeTypeMap["telegram-runtime-surface"];
type FacadeModule = FacadeEntry["module"];
import {
createLazyFacadeObjectValue,
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-runtime.js";
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "telegram",
artifactBasename: "runtime-api.js",
});
}
export const auditTelegramGroupMembership: FacadeModule["auditTelegramGroupMembership"] = ((
...args
) =>
loadFacadeModule()["auditTelegramGroupMembership"](
...args,
)) as FacadeModule["auditTelegramGroupMembership"];
export const buildTelegramExecApprovalPendingPayload: FacadeModule["buildTelegramExecApprovalPendingPayload"] =
((...args) =>
loadFacadeModule()["buildTelegramExecApprovalPendingPayload"](
...args,
)) as FacadeModule["buildTelegramExecApprovalPendingPayload"];
export const collectTelegramUnmentionedGroupIds: FacadeModule["collectTelegramUnmentionedGroupIds"] =
((...args) =>
loadFacadeModule()["collectTelegramUnmentionedGroupIds"](
...args,
)) as FacadeModule["collectTelegramUnmentionedGroupIds"];
export const createTelegramThreadBindingManager: FacadeModule["createTelegramThreadBindingManager"] =
((...args) =>
loadFacadeModule()["createTelegramThreadBindingManager"](
...args,
)) as FacadeModule["createTelegramThreadBindingManager"];
export const createForumTopicTelegram: FacadeModule["createForumTopicTelegram"] = ((...args) =>
loadFacadeModule()["createForumTopicTelegram"](
...args,
)) as FacadeModule["createForumTopicTelegram"];
export const deleteMessageTelegram: FacadeModule["deleteMessageTelegram"] = ((...args) =>
loadFacadeModule()["deleteMessageTelegram"](...args)) as FacadeModule["deleteMessageTelegram"];
export const editForumTopicTelegram: FacadeModule["editForumTopicTelegram"] = ((...args) =>
loadFacadeModule()["editForumTopicTelegram"](...args)) as FacadeModule["editForumTopicTelegram"];
export const editMessageReplyMarkupTelegram: FacadeModule["editMessageReplyMarkupTelegram"] = ((
...args
) =>
loadFacadeModule()["editMessageReplyMarkupTelegram"](
...args,
)) as FacadeModule["editMessageReplyMarkupTelegram"];
export const editMessageTelegram: FacadeModule["editMessageTelegram"] = ((...args) =>
loadFacadeModule()["editMessageTelegram"](...args)) as FacadeModule["editMessageTelegram"];
export const monitorTelegramProvider: FacadeModule["monitorTelegramProvider"] = ((...args) =>
loadFacadeModule()["monitorTelegramProvider"](
...args,
)) as FacadeModule["monitorTelegramProvider"];
export const pinMessageTelegram: FacadeModule["pinMessageTelegram"] = ((...args) =>
loadFacadeModule()["pinMessageTelegram"](...args)) as FacadeModule["pinMessageTelegram"];
export const probeTelegram: FacadeModule["probeTelegram"] = ((...args) =>
loadFacadeModule()["probeTelegram"](...args)) as FacadeModule["probeTelegram"];
export const reactMessageTelegram: FacadeModule["reactMessageTelegram"] = ((...args) =>
loadFacadeModule()["reactMessageTelegram"](...args)) as FacadeModule["reactMessageTelegram"];
export const renameForumTopicTelegram: FacadeModule["renameForumTopicTelegram"] = ((...args) =>
loadFacadeModule()["renameForumTopicTelegram"](
...args,
)) as FacadeModule["renameForumTopicTelegram"];
export const resetTelegramThreadBindingsForTests: FacadeModule["resetTelegramThreadBindingsForTests"] =
((...args) =>
loadFacadeModule()["resetTelegramThreadBindingsForTests"](
...args,
)) as FacadeModule["resetTelegramThreadBindingsForTests"];
export const resolveTelegramRuntimeGroupPolicy: FacadeModule["resolveTelegramRuntimeGroupPolicy"] =
((...args) =>
loadFacadeModule()["resolveTelegramRuntimeGroupPolicy"](
...args,
)) as FacadeModule["resolveTelegramRuntimeGroupPolicy"];
export const resolveTelegramToken: FacadeModule["resolveTelegramToken"] = ((...args) =>
loadFacadeModule()["resolveTelegramToken"](...args)) as FacadeModule["resolveTelegramToken"];
export const sendMessageTelegram: FacadeModule["sendMessageTelegram"] = ((...args) =>
loadFacadeModule()["sendMessageTelegram"](...args)) as FacadeModule["sendMessageTelegram"];
export const sendPollTelegram: FacadeModule["sendPollTelegram"] = ((...args) =>
loadFacadeModule()["sendPollTelegram"](...args)) as FacadeModule["sendPollTelegram"];
export const sendStickerTelegram: FacadeModule["sendStickerTelegram"] = ((...args) =>
loadFacadeModule()["sendStickerTelegram"](...args)) as FacadeModule["sendStickerTelegram"];
export const sendTypingTelegram: FacadeModule["sendTypingTelegram"] = ((...args) =>
loadFacadeModule()["sendTypingTelegram"](...args)) as FacadeModule["sendTypingTelegram"];
export const setTelegramThreadBindingIdleTimeoutBySessionKey: FacadeModule["setTelegramThreadBindingIdleTimeoutBySessionKey"] =
((...args) =>
loadFacadeModule()["setTelegramThreadBindingIdleTimeoutBySessionKey"](
...args,
)) as FacadeModule["setTelegramThreadBindingIdleTimeoutBySessionKey"];
export const setTelegramThreadBindingMaxAgeBySessionKey: FacadeModule["setTelegramThreadBindingMaxAgeBySessionKey"] =
((...args) =>
loadFacadeModule()["setTelegramThreadBindingMaxAgeBySessionKey"](
...args,
)) as FacadeModule["setTelegramThreadBindingMaxAgeBySessionKey"];
export const shouldSuppressTelegramExecApprovalForwardingFallback: FacadeModule["shouldSuppressTelegramExecApprovalForwardingFallback"] =
((...args) =>
loadFacadeModule()["shouldSuppressTelegramExecApprovalForwardingFallback"](
...args,
)) as FacadeModule["shouldSuppressTelegramExecApprovalForwardingFallback"];
export const telegramMessageActions: FacadeModule["telegramMessageActions"] =
createLazyFacadeObjectValue(
() => loadFacadeModule()["telegramMessageActions"] as object,
) as FacadeModule["telegramMessageActions"];
export const unpinMessageTelegram: FacadeModule["unpinMessageTelegram"] = ((...args) =>
loadFacadeModule()["unpinMessageTelegram"](...args)) as FacadeModule["unpinMessageTelegram"];
export type TelegramApiOverride = FacadeEntry["types"]["TelegramApiOverride"];
export type TelegramProbe = FacadeEntry["types"]["TelegramProbe"];

View File

@@ -1,68 +0,0 @@
export type { InspectedTelegramAccount, ResolvedTelegramAccount } from "./telegram-surface.js";
export type { TelegramButtonStyle, TelegramInlineButtons } from "./telegram-surface.js";
export type { StickerMetadata } from "./telegram-surface.js";
export type { TelegramProbe } from "./telegram-runtime-surface.js";
export type { TelegramApiOverride } from "./telegram-runtime-surface.js";
export {
buildBrowseProvidersButton,
buildModelsKeyboard,
buildProviderKeyboard,
calculateTotalPages,
createTelegramActionGate,
fetchTelegramChatId,
getCacheStats,
getModelsPageSize,
inspectTelegramAccount,
isTelegramExecApprovalApprover,
isTelegramExecApprovalAuthorizedSender,
isTelegramExecApprovalClientEnabled,
isTelegramExecApprovalTargetRecipient,
listTelegramAccountIds,
listTelegramDirectoryGroupsFromConfig,
listTelegramDirectoryPeersFromConfig,
looksLikeTelegramTargetId,
lookupTelegramChatId,
normalizeTelegramMessagingTarget,
parseTelegramReplyToMessageId,
parseTelegramThreadId,
resolveTelegramAutoThreadId,
resolveTelegramGroupRequireMention,
resolveTelegramGroupToolPolicy,
resolveTelegramInlineButtonsScope,
resolveTelegramPollActionGateState,
resolveTelegramReactionLevel,
resolveTelegramTargetChatType,
searchStickers,
sendTelegramPayloadMessages,
type ProviderInfo,
} from "./telegram-surface.js";
export { isNumericTelegramUserId, normalizeTelegramAllowFromEntry } from "./telegram-allow-from.js";
export {
auditTelegramGroupMembership,
buildTelegramExecApprovalPendingPayload,
collectTelegramUnmentionedGroupIds,
createTelegramThreadBindingManager,
createForumTopicTelegram,
deleteMessageTelegram,
editForumTopicTelegram,
editMessageReplyMarkupTelegram,
editMessageTelegram,
monitorTelegramProvider,
pinMessageTelegram,
probeTelegram,
reactMessageTelegram,
renameForumTopicTelegram,
resolveTelegramToken,
sendMessageTelegram,
sendPollTelegram,
sendStickerTelegram,
sendTypingTelegram,
setTelegramThreadBindingIdleTimeoutBySessionKey,
setTelegramThreadBindingMaxAgeBySessionKey,
shouldSuppressTelegramExecApprovalForwardingFallback,
telegramMessageActions,
unpinMessageTelegram,
} from "./telegram-runtime-surface.js";
export { buildTelegramGroupPeerId } from "./telegram-surface.js";
export { parseTelegramTarget } from "./telegram-surface.js";

View File

@@ -1,2 +0,0 @@
export * from "./telegram-core.js";
export * from "./telegram-runtime.js";

View File

@@ -8,7 +8,6 @@
import { parseExplicitTargetForChannel } from "../channels/plugins/target-parsing.js";
import type { OpenClawConfig } from "../config/config.js";
import { logVerbose } from "../globals.js";
import { parseTelegramTarget } from "../plugin-sdk/telegram-runtime.js";
import {
clearPluginCommands,
clearPluginCommandsForPlugin,
@@ -168,15 +167,14 @@ function resolveBindingConversationFromCommand(params: {
return null;
}
const target = parseExplicitTargetForChannel("telegram", rawTarget);
const fallbackTarget = target ? null : parseTelegramTarget(rawTarget);
if (!target && !fallbackTarget) {
if (!target) {
return null;
}
return {
channel: "telegram",
accountId,
conversationId: target?.to ?? fallbackTarget?.chatId ?? "",
threadId: params.messageThreadId ?? target?.threadId ?? fallbackTarget?.messageThreadId,
conversationId: target.to,
threadId: params.messageThreadId ?? target.threadId,
};
}
if (params.channel === "discord") {

View File

@@ -1,14 +0,0 @@
import {
monitorIMessageProvider,
probeIMessage,
sendMessageIMessage,
} from "../../plugin-sdk/imessage.js";
import type { PluginRuntimeChannel } from "./types-channel.js";
export function createRuntimeIMessage(): PluginRuntimeChannel["imessage"] {
return {
monitorIMessageProvider,
probeIMessage,
sendMessageIMessage,
};
}

View File

@@ -1,56 +0,0 @@
import {
auditTelegramGroupMembership as auditTelegramGroupMembershipImpl,
monitorTelegramProvider as monitorTelegramProviderImpl,
probeTelegram as probeTelegramImpl,
} from "../../plugin-sdk/telegram.js";
import {
deleteMessageTelegram as deleteMessageTelegramImpl,
editMessageReplyMarkupTelegram as editMessageReplyMarkupTelegramImpl,
editMessageTelegram as editMessageTelegramImpl,
pinMessageTelegram as pinMessageTelegramImpl,
renameForumTopicTelegram as renameForumTopicTelegramImpl,
sendMessageTelegram as sendMessageTelegramImpl,
sendPollTelegram as sendPollTelegramImpl,
sendTypingTelegram as sendTypingTelegramImpl,
unpinMessageTelegram as unpinMessageTelegramImpl,
} from "../../plugin-sdk/telegram.js";
import type { PluginRuntimeChannel } from "./types-channel.js";
type RuntimeTelegramOps = Pick<
PluginRuntimeChannel["telegram"],
| "auditGroupMembership"
| "probeTelegram"
| "sendMessageTelegram"
| "sendPollTelegram"
| "monitorTelegramProvider"
> & {
typing: Pick<PluginRuntimeChannel["telegram"]["typing"], "pulse">;
conversationActions: Pick<
PluginRuntimeChannel["telegram"]["conversationActions"],
| "editMessage"
| "editReplyMarkup"
| "deleteMessage"
| "renameTopic"
| "pinMessage"
| "unpinMessage"
>;
};
export const runtimeTelegramOps = {
auditGroupMembership: auditTelegramGroupMembershipImpl,
probeTelegram: probeTelegramImpl,
sendMessageTelegram: sendMessageTelegramImpl,
sendPollTelegram: sendPollTelegramImpl,
monitorTelegramProvider: monitorTelegramProviderImpl,
typing: {
pulse: sendTypingTelegramImpl,
},
conversationActions: {
editMessage: editMessageTelegramImpl,
editReplyMarkup: editMessageReplyMarkupTelegramImpl,
deleteMessage: deleteMessageTelegramImpl,
renameTopic: renameForumTopicTelegramImpl,
pinMessage: pinMessageTelegramImpl,
unpinMessage: unpinMessageTelegramImpl,
},
} satisfies RuntimeTelegramOps;

View File

@@ -1,101 +0,0 @@
import {
collectTelegramUnmentionedGroupIds,
resolveTelegramToken,
setTelegramThreadBindingIdleTimeoutBySessionKey,
setTelegramThreadBindingMaxAgeBySessionKey,
telegramMessageActions,
} from "../../plugin-sdk/telegram.js";
import {
createLazyRuntimeMethodBinder,
createLazyRuntimeSurface,
} from "../../shared/lazy-runtime.js";
import { createTelegramTypingLease } from "./runtime-telegram-typing.js";
import type { PluginRuntimeChannel } from "./types-channel.js";
const loadRuntimeTelegramOps = createLazyRuntimeSurface(
() => import("./runtime-telegram-ops.runtime.js"),
({ runtimeTelegramOps }) => runtimeTelegramOps,
);
const bindTelegramRuntimeMethod = createLazyRuntimeMethodBinder(loadRuntimeTelegramOps);
const auditGroupMembershipLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.auditGroupMembership,
);
const probeTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.probeTelegram,
);
const sendMessageTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.sendMessageTelegram,
);
const sendPollTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.sendPollTelegram,
);
const monitorTelegramProviderLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.monitorTelegramProvider,
);
const sendTypingTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.typing.pulse,
);
const editMessageTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.conversationActions.editMessage,
);
const editMessageReplyMarkupTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.conversationActions.editReplyMarkup,
);
const deleteMessageTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.conversationActions.deleteMessage,
);
const renameForumTopicTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.conversationActions.renameTopic,
);
const pinMessageTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.conversationActions.pinMessage,
);
const unpinMessageTelegramLazy = bindTelegramRuntimeMethod(
(runtimeTelegramOps) => runtimeTelegramOps.conversationActions.unpinMessage,
);
export function createRuntimeTelegram(): PluginRuntimeChannel["telegram"] {
return {
auditGroupMembership: auditGroupMembershipLazy,
collectUnmentionedGroupIds: collectTelegramUnmentionedGroupIds,
probeTelegram: probeTelegramLazy,
resolveTelegramToken,
sendMessageTelegram: sendMessageTelegramLazy,
sendPollTelegram: sendPollTelegramLazy,
monitorTelegramProvider: monitorTelegramProviderLazy,
messageActions: telegramMessageActions,
threadBindings: {
setIdleTimeoutBySessionKey: setTelegramThreadBindingIdleTimeoutBySessionKey,
setMaxAgeBySessionKey: setTelegramThreadBindingMaxAgeBySessionKey,
},
typing: {
pulse: sendTypingTelegramLazy,
start: async ({ to, accountId, cfg, intervalMs, messageThreadId }) =>
await createTelegramTypingLease({
to,
accountId,
cfg,
intervalMs,
messageThreadId,
pulse: async ({ to, accountId, cfg, messageThreadId }) =>
await sendTypingTelegramLazy(to, {
accountId,
cfg,
messageThreadId,
}),
}),
},
conversationActions: {
editMessage: editMessageTelegramLazy,
editReplyMarkup: editMessageReplyMarkupTelegramLazy,
clearReplyMarkup: async (chatIdInput, messageIdInput, opts = {}) =>
await editMessageReplyMarkupTelegramLazy(chatIdInput, messageIdInput, [], opts),
deleteMessage: deleteMessageTelegramLazy,
renameTopic: renameForumTopicTelegramLazy,
pinMessage: pinMessageTelegramLazy,
unpinMessage: unpinMessageTelegramLazy,
},
};
}

View File

@@ -20,6 +20,15 @@ type UpsertChannelPairingRequestForAccount = (
params: Omit<Parameters<UpsertChannelPairingRequest>[0], "accountId"> & { accountId: string },
) => ReturnType<UpsertChannelPairingRequest>;
export type RuntimeThreadBindingLifecycleRecord =
| import("../../infra/outbound/session-binding-service.js").SessionBindingRecord
| {
boundAt: number;
lastActivityAt: number;
idleTimeoutMs?: number;
maxAgeMs?: number;
};
export type PluginRuntimeChannel = {
text: {
chunkByNewline: typeof import("../../auto-reply/chunk.js").chunkByNewline;
@@ -93,6 +102,23 @@ export type PluginRuntimeChannel = {
shouldComputeCommandAuthorized: typeof import("../../auto-reply/command-detection.js").shouldComputeCommandAuthorized;
shouldHandleTextCommands: typeof import("../../auto-reply/commands-registry.js").shouldHandleTextCommands;
};
outbound: {
loadAdapter: typeof import("../../channels/plugins/outbound/load.js").loadChannelOutboundAdapter;
};
threadBindings: {
setIdleTimeoutBySessionKey: (params: {
channelId: "discord" | "matrix" | "telegram";
targetSessionKey: string;
accountId?: string;
idleTimeoutMs: number;
}) => RuntimeThreadBindingLifecycleRecord[];
setMaxAgeBySessionKey: (params: {
channelId: "discord" | "matrix" | "telegram";
targetSessionKey: string;
accountId?: string;
maxAgeMs: number;
}) => RuntimeThreadBindingLifecycleRecord[];
};
discord: {
messageActions: typeof import("../../plugin-sdk/discord.js").discordMessageActions;
auditChannelPermissions: typeof import("../../plugin-sdk/discord.js").auditDiscordChannelPermissions;
@@ -146,53 +172,6 @@ export type PluginRuntimeChannel = {
monitorSlackProvider: typeof import("../../plugin-sdk/slack.js").monitorSlackProvider;
handleSlackAction: typeof import("../../plugin-sdk/slack.js").handleSlackAction;
};
telegram: {
auditGroupMembership: typeof import("../../plugin-sdk/telegram.js").auditTelegramGroupMembership;
collectUnmentionedGroupIds: typeof import("../../plugin-sdk/telegram.js").collectTelegramUnmentionedGroupIds;
probeTelegram: typeof import("../../plugin-sdk/telegram.js").probeTelegram;
resolveTelegramToken: typeof import("../../plugin-sdk/telegram.js").resolveTelegramToken;
sendMessageTelegram: typeof import("../../plugin-sdk/telegram.js").sendMessageTelegram;
sendPollTelegram: typeof import("../../plugin-sdk/telegram.js").sendPollTelegram;
monitorTelegramProvider: typeof import("../../plugin-sdk/telegram.js").monitorTelegramProvider;
messageActions: typeof import("../../plugin-sdk/telegram.js").telegramMessageActions;
threadBindings: {
setIdleTimeoutBySessionKey: typeof import("../../plugin-sdk/telegram.js").setTelegramThreadBindingIdleTimeoutBySessionKey;
setMaxAgeBySessionKey: typeof import("../../plugin-sdk/telegram.js").setTelegramThreadBindingMaxAgeBySessionKey;
};
typing: {
pulse: typeof import("../../plugin-sdk/telegram.js").sendTypingTelegram;
start: (params: {
to: string;
accountId?: string;
cfg?: ReturnType<typeof import("../../config/config.js").loadConfig>;
intervalMs?: number;
messageThreadId?: number;
}) => Promise<{
refresh: () => Promise<void>;
stop: () => void;
}>;
};
conversationActions: {
editMessage: typeof import("../../plugin-sdk/telegram.js").editMessageTelegram;
editReplyMarkup: typeof import("../../plugin-sdk/telegram.js").editMessageReplyMarkupTelegram;
clearReplyMarkup: (
chatIdInput: string | number,
messageIdInput: string | number,
opts?: {
token?: string;
accountId?: string;
verbose?: boolean;
api?: import("../../plugin-sdk/telegram.js").TelegramApiOverride;
retry?: import("../../infra/retry.js").RetryConfig;
cfg?: ReturnType<typeof import("../../config/config.js").loadConfig>;
},
) => Promise<{ ok: true; messageId: string; chatId: string }>;
deleteMessage: typeof import("../../plugin-sdk/telegram.js").deleteMessageTelegram;
renameTopic: typeof import("../../plugin-sdk/telegram.js").renameForumTopicTelegram;
pinMessage: typeof import("../../plugin-sdk/telegram.js").pinMessageTelegram;
unpinMessage: typeof import("../../plugin-sdk/telegram.js").unpinMessageTelegram;
};
};
matrix: {
threadBindings: {
setIdleTimeoutBySessionKey: typeof import("../../plugin-sdk/matrix.js").setMatrixThreadBindingIdleTimeoutBySessionKey;
@@ -205,11 +184,6 @@ export type PluginRuntimeChannel = {
monitorSignalProvider: typeof import("../../plugin-sdk/signal.js").monitorSignalProvider;
messageActions: typeof import("../../plugin-sdk/signal.js").signalMessageActions;
};
imessage: {
monitorIMessageProvider: typeof import("../../plugin-sdk/imessage.js").monitorIMessageProvider;
probeIMessage: typeof import("../../plugin-sdk/imessage.js").probeIMessage;
sendMessageIMessage: typeof import("../../plugin-sdk/imessage.js").sendMessageIMessage;
};
whatsapp: {
getActiveWebListener: typeof import("./runtime-whatsapp-boundary.js").getActiveWebListener;
getWebAuthAgeMs: typeof import("./runtime-whatsapp-boundary.js").getWebAuthAgeMs;

View File

@@ -455,7 +455,7 @@ describe("plugin sdk alias helpers", () => {
const fixture = createPluginSdkAliasFixture({
packageExports: {
"./plugin-sdk/compat": { default: "./dist/plugin-sdk/compat.js" },
"./plugin-sdk/telegram": { default: "./dist/plugin-sdk/telegram.js" },
"./plugin-sdk/core": { default: "./dist/plugin-sdk/core.js" },
"./plugin-sdk/nested/value": { default: "./dist/plugin-sdk/nested/value.js" },
"./plugin-sdk/..\\..\\evil": { default: "./dist/plugin-sdk/evil.js" },
"./plugin-sdk/C:temp": { default: "./dist/plugin-sdk/drive.js" },
@@ -465,7 +465,7 @@ describe("plugin sdk alias helpers", () => {
const subpaths = listPluginSdkExportedSubpaths({
modulePath: path.join(fixture.root, "src", "plugins", "loader.ts"),
});
expect(subpaths).toEqual(["compat", "telegram"]);
expect(subpaths).toEqual(["compat", "core"]);
});
it.each([

View File

@@ -1,7 +1,7 @@
import {
isNumericTelegramUserId,
normalizeTelegramAllowFromEntry,
} from "../plugin-sdk/telegram-runtime.js";
} from "../channels/read-only-account-inspect.telegram.js";
export const auditChannelTelegramRuntime = {
isNumericTelegramUserId,

View File

@@ -1,6 +1,6 @@
import { imessageOutbound } from "../../test/channel-outbounds.js";
import { normalizeIMessageHandle } from "../channels/plugins/normalize/imessage.js";
import type { ChannelOutboundAdapter, ChannelPlugin } from "../channels/plugins/types.js";
import { normalizeIMessageHandle } from "../plugin-sdk/imessage-policy.js";
import { collectStatusIssuesFromLastError } from "../plugin-sdk/status-helpers.js";
export const createIMessageTestPlugin = (params?: {