refactor(plugins): move outbound dep aliases into extensions

This commit is contained in:
Peter Steinberger
2026-04-03 19:47:25 +01:00
parent f007082e06
commit 1c66a050c2
14 changed files with 52 additions and 28 deletions

View File

@@ -6,6 +6,10 @@ export * from "./src/components.js";
export * from "./src/directory-config.js";
export * from "./src/exec-approvals.js";
export * from "./src/group-policy.js";
export type {
DiscordInteractiveHandlerContext,
DiscordInteractiveHandlerRegistration,
} from "./src/interactive-dispatch.js";
export * from "./src/normalize.js";
export * from "./src/pluralkit.js";
export * from "./src/probe.js";

View File

@@ -2,6 +2,7 @@ export * from "./src/accounts.js";
export * from "./src/conversation-bindings.js";
export * from "./src/conversation-id.js";
export * from "./src/group-policy.js";
export { IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./src/outbound-send-deps.js";
export * from "./src/probe.js";
export * from "./src/target-parsing-helpers.js";
export * from "./src/targets.js";

View File

@@ -2,6 +2,7 @@ import { resolveOutboundSendDep } from "openclaw/plugin-sdk/outbound-runtime";
import { PAIRING_APPROVED_MESSAGE, resolveChannelMediaMaxBytes } from "../runtime-api.js";
import type { ResolvedIMessageAccount } from "./accounts.js";
import { monitorIMessageProvider } from "./monitor.js";
import { IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-send-deps.js";
import { probeIMessage } from "./probe.js";
import { sendMessageIMessage } from "./send.js";
import { imessageSetupWizard } from "./setup-surface.js";
@@ -19,7 +20,9 @@ export async function sendIMessageOutbound(params: {
replyToId?: string;
}) {
const send =
resolveOutboundSendDep<IMessageSendFn>(params.deps, "imessage") ?? sendMessageIMessage;
resolveOutboundSendDep<IMessageSendFn>(params.deps, "imessage", {
legacyKeys: IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS,
}) ?? sendMessageIMessage;
const maxBytes = resolveChannelMediaMaxBytes({
cfg: params.cfg,
resolveChannelLimitMb: ({ cfg, accountId }) =>

View File

@@ -6,11 +6,14 @@ import {
resolveOutboundSendDep,
type OutboundSendDeps,
} from "openclaw/plugin-sdk/outbound-runtime";
import { IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-send-deps.js";
import { sendMessageIMessage } from "./send.js";
function resolveIMessageSender(deps: OutboundSendDeps | undefined) {
return (
resolveOutboundSendDep<typeof sendMessageIMessage>(deps, "imessage") ?? sendMessageIMessage
resolveOutboundSendDep<typeof sendMessageIMessage>(deps, "imessage", {
legacyKeys: IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS,
}) ?? sendMessageIMessage
);
}

View File

@@ -0,0 +1 @@
export const IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS = ["sendIMessage"] as const;

View File

@@ -8,6 +8,10 @@ export * from "./src/channel-type.js";
export * from "./src/client.js";
export * from "./src/directory-config.js";
export * from "./src/http/index.js";
export type {
SlackInteractiveHandlerContext,
SlackInteractiveHandlerRegistration,
} from "./src/interactive-dispatch.js";
export * from "./src/interactive-replies.js";
export * from "./src/message-actions.js";
export * from "./src/group-policy.js";

View File

@@ -9,6 +9,10 @@ export * from "./src/directory-config.js";
export * from "./src/exec-approval-forwarding.js";
export * from "./src/exec-approvals.js";
export * from "./src/group-policy.js";
export type {
TelegramInteractiveHandlerContext,
TelegramInteractiveHandlerRegistration,
} from "./src/interactive-dispatch.js";
export * from "./src/inline-buttons.js";
export * from "./src/model-buttons.js";
export * from "./src/normalize.js";

View File

@@ -2,6 +2,7 @@ export * from "./src/accounts.js";
export * from "./src/auto-reply/constants.js";
export { whatsappCommandPolicy } from "./src/command-policy.js";
export * from "./src/group-policy.js";
export { WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./src/outbound-send-deps.js";
export type * from "./src/auto-reply/types.js";
export type * from "./src/inbound/types.js";
export {

View File

@@ -10,6 +10,7 @@ import {
} from "openclaw/plugin-sdk/reply-payload";
import { chunkText } from "openclaw/plugin-sdk/reply-runtime";
import { shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
import { WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-send-deps.js";
import { resolveWhatsAppOutboundTarget } from "./runtime-api.js";
import { sendMessageWhatsApp, sendPollWhatsApp } from "./send.js";
@@ -52,8 +53,9 @@ export const whatsappOutbound: ChannelOutboundAdapter = {
return createEmptyChannelResult("whatsapp");
}
const send =
resolveOutboundSendDep<typeof import("./send.js").sendMessageWhatsApp>(deps, "whatsapp") ??
(await import("./send.js")).sendMessageWhatsApp;
resolveOutboundSendDep<typeof import("./send.js").sendMessageWhatsApp>(deps, "whatsapp", {
legacyKeys: WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS,
}) ?? (await import("./send.js")).sendMessageWhatsApp;
return await send(to, normalizedText, {
verbose: false,
cfg,
@@ -74,8 +76,9 @@ export const whatsappOutbound: ChannelOutboundAdapter = {
}) => {
const normalizedText = trimLeadingWhitespace(text);
const send =
resolveOutboundSendDep<typeof import("./send.js").sendMessageWhatsApp>(deps, "whatsapp") ??
(await import("./send.js")).sendMessageWhatsApp;
resolveOutboundSendDep<typeof import("./send.js").sendMessageWhatsApp>(deps, "whatsapp", {
legacyKeys: WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS,
}) ?? (await import("./send.js")).sendMessageWhatsApp;
return await send(to, normalizedText, {
verbose: false,
cfg,

View File

@@ -4,6 +4,7 @@ import {
} from "openclaw/plugin-sdk/channel-send-result";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { resolveOutboundSendDep, sanitizeForPlainText } from "openclaw/plugin-sdk/infra-runtime";
import { WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-send-deps.js";
type WhatsAppChunker = NonNullable<ChannelOutboundAdapter["chunker"]>;
type WhatsAppSendTextOptions = {
@@ -77,7 +78,9 @@ export function createWhatsAppOutboundBase({
return { messageId: "" };
}
const send =
resolveOutboundSendDep<WhatsAppSendMessage>(deps, "whatsapp") ?? sendMessageWhatsApp;
resolveOutboundSendDep<WhatsAppSendMessage>(deps, "whatsapp", {
legacyKeys: WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS,
}) ?? sendMessageWhatsApp;
return await send(to, normalizedText, {
verbose: false,
cfg,
@@ -98,7 +101,9 @@ export function createWhatsAppOutboundBase({
gifPlayback,
}) => {
const send =
resolveOutboundSendDep<WhatsAppSendMessage>(deps, "whatsapp") ?? sendMessageWhatsApp;
resolveOutboundSendDep<WhatsAppSendMessage>(deps, "whatsapp", {
legacyKeys: WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS,
}) ?? sendMessageWhatsApp;
return await send(to, normalizeText(text), {
verbose: false,
cfg,

View File

@@ -0,0 +1 @@
export const WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS = ["sendWhatsApp"] as const;

View File

@@ -2,7 +2,7 @@ import { describe, expect, it, vi } from "vitest";
import { createOutboundSendDepsFromCliSource } from "./outbound-send-mapping.js";
describe("createOutboundSendDepsFromCliSource", () => {
it("adds legacy aliases for channel-keyed send deps", () => {
it("adds generic legacy aliases for channel-keyed send deps", () => {
const deps = {
whatsapp: vi.fn(),
telegram: vi.fn(),
@@ -21,12 +21,12 @@ describe("createOutboundSendDepsFromCliSource", () => {
slack: deps.slack,
signal: deps.signal,
imessage: deps.imessage,
sendWhatsApp: deps.whatsapp,
sendWhatsapp: deps.whatsapp,
sendTelegram: deps.telegram,
sendDiscord: deps.discord,
sendSlack: deps.slack,
sendSignal: deps.signal,
sendIMessage: deps.imessage,
sendImessage: deps.imessage,
});
});
});

View File

@@ -32,14 +32,8 @@ function resolveLegacyDepKeysForChannel(channelId: string): string[] {
}
const pascal = compact.charAt(0).toUpperCase() + compact.slice(1);
const keys = new Set<string>();
if (compact === "whatsapp") {
keys.add("sendWhatsApp");
} else if (compact === "imessage") {
keys.add("sendIMessage");
} else {
keys.add(`send${pascal}`);
}
if (compact !== "imessage" && pascal.startsWith("I") && pascal.length > 1) {
keys.add(`send${pascal}`);
if (pascal.startsWith("I") && pascal.length > 1) {
keys.add(`sendI${pascal.slice(1)}`);
}
if (pascal.startsWith("Ms") && pascal.length > 2) {

View File

@@ -12,14 +12,8 @@ function resolveLegacyDepKeysForChannel(channelId: string): string[] {
}
const pascal = compact.charAt(0).toUpperCase() + compact.slice(1);
const keys = new Set<string>();
if (compact === "whatsapp") {
keys.add("sendWhatsApp");
} else if (compact === "imessage") {
keys.add("sendIMessage");
} else {
keys.add(`send${pascal}`);
}
if (compact !== "imessage" && pascal.startsWith("I") && pascal.length > 1) {
keys.add(`send${pascal}`);
if (pascal.startsWith("I") && pascal.length > 1) {
keys.add(`sendI${pascal.slice(1)}`);
}
if (pascal.startsWith("Ms") && pascal.length > 2) {
@@ -28,15 +22,21 @@ function resolveLegacyDepKeysForChannel(channelId: string): string[] {
return [...keys];
}
export type ResolveOutboundSendDepOptions = {
legacyKeys?: readonly string[];
};
export function resolveOutboundSendDep<T>(
deps: OutboundSendDeps | null | undefined,
channelId: string,
options?: ResolveOutboundSendDepOptions,
): T | undefined {
const dynamic = deps?.[channelId];
if (dynamic !== undefined) {
return dynamic as T;
}
for (const legacyKey of resolveLegacyDepKeysForChannel(channelId)) {
const legacyKeys = [...resolveLegacyDepKeysForChannel(channelId), ...(options?.legacyKeys ?? [])];
for (const legacyKey of legacyKeys) {
const legacy = deps?.[legacyKey];
if (legacy !== undefined) {
return legacy as T;