openclaw/src/channels/plugins/runtime-forwarders.ts
2026-03-18 16:37:27 +00:00

118 lines
4.1 KiB
TypeScript

import type { ChannelDirectoryAdapter, ChannelOutboundAdapter } from "./types.adapters.js";
type MaybePromise<T> = T | Promise<T>;
type DirectoryListMethod = "listPeersLive" | "listGroupsLive" | "listGroupMembers";
type OutboundMethod = "sendText" | "sendMedia" | "sendPoll";
type DirectoryListParams = Parameters<NonNullable<ChannelDirectoryAdapter["listPeersLive"]>>[0];
type DirectoryGroupMembersParams = Parameters<
NonNullable<ChannelDirectoryAdapter["listGroupMembers"]>
>[0];
type SendTextParams = Parameters<NonNullable<ChannelOutboundAdapter["sendText"]>>[0];
type SendMediaParams = Parameters<NonNullable<ChannelOutboundAdapter["sendMedia"]>>[0];
type SendPollParams = Parameters<NonNullable<ChannelOutboundAdapter["sendPoll"]>>[0];
async function resolveForwardedMethod<Runtime, Fn>(params: {
getRuntime: () => MaybePromise<Runtime>;
resolve: (runtime: Runtime) => Fn | null | undefined;
unavailableMessage?: string;
}): Promise<Fn> {
const runtime = await params.getRuntime();
const method = params.resolve(runtime);
if (method) {
return method;
}
throw new Error(params.unavailableMessage ?? "Runtime method is unavailable");
}
export function createRuntimeDirectoryLiveAdapter<Runtime>(params: {
getRuntime: () => MaybePromise<Runtime>;
listPeersLive?: (runtime: Runtime) => ChannelDirectoryAdapter["listPeersLive"] | null | undefined;
listGroupsLive?: (
runtime: Runtime,
) => ChannelDirectoryAdapter["listGroupsLive"] | null | undefined;
listGroupMembers?: (
runtime: Runtime,
) => ChannelDirectoryAdapter["listGroupMembers"] | null | undefined;
}): Pick<ChannelDirectoryAdapter, DirectoryListMethod> {
return {
listPeersLive: params.listPeersLive
? async (ctx: DirectoryListParams) =>
await (
await resolveForwardedMethod({
getRuntime: params.getRuntime,
resolve: params.listPeersLive!,
})
)(ctx)
: undefined,
listGroupsLive: params.listGroupsLive
? async (ctx: DirectoryListParams) =>
await (
await resolveForwardedMethod({
getRuntime: params.getRuntime,
resolve: params.listGroupsLive!,
})
)(ctx)
: undefined,
listGroupMembers: params.listGroupMembers
? async (ctx: DirectoryGroupMembersParams) =>
await (
await resolveForwardedMethod({
getRuntime: params.getRuntime,
resolve: params.listGroupMembers!,
})
)(ctx)
: undefined,
};
}
export function createRuntimeOutboundDelegates<Runtime>(params: {
getRuntime: () => MaybePromise<Runtime>;
sendText?: {
resolve: (runtime: Runtime) => ChannelOutboundAdapter["sendText"] | null | undefined;
unavailableMessage?: string;
};
sendMedia?: {
resolve: (runtime: Runtime) => ChannelOutboundAdapter["sendMedia"] | null | undefined;
unavailableMessage?: string;
};
sendPoll?: {
resolve: (runtime: Runtime) => ChannelOutboundAdapter["sendPoll"] | null | undefined;
unavailableMessage?: string;
};
}): Pick<ChannelOutboundAdapter, OutboundMethod> {
return {
sendText: params.sendText
? async (ctx: SendTextParams) =>
await (
await resolveForwardedMethod({
getRuntime: params.getRuntime,
resolve: params.sendText!.resolve,
unavailableMessage: params.sendText!.unavailableMessage,
})
)(ctx)
: undefined,
sendMedia: params.sendMedia
? async (ctx: SendMediaParams) =>
await (
await resolveForwardedMethod({
getRuntime: params.getRuntime,
resolve: params.sendMedia!.resolve,
unavailableMessage: params.sendMedia!.unavailableMessage,
})
)(ctx)
: undefined,
sendPoll: params.sendPoll
? async (ctx: SendPollParams) =>
await (
await resolveForwardedMethod({
getRuntime: params.getRuntime,
resolve: params.sendPoll!.resolve,
unavailableMessage: params.sendPoll!.unavailableMessage,
})
)(ctx)
: undefined,
};
}