mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-26 16:06:16 +00:00
refactor: de-duplicate channel runtime and payload helpers
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
import {
|
||||
buildBaseAccountStatusSnapshot,
|
||||
buildBaseChannelStatusSummary,
|
||||
buildChannelConfigSchema,
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
deleteAccountFromConfigSection,
|
||||
formatPairingApproveHint,
|
||||
getChatChannelMeta,
|
||||
PAIRING_APPROVED_MESSAGE,
|
||||
resolveAllowlistProviderRuntimeGroupPolicy,
|
||||
resolveDefaultGroupPolicy,
|
||||
setAccountEnabledInConfigSection,
|
||||
deleteAccountFromConfigSection,
|
||||
type ChannelPlugin,
|
||||
} from "openclaw/plugin-sdk";
|
||||
import {
|
||||
@@ -319,37 +321,23 @@ export const ircPlugin: ChannelPlugin<ResolvedIrcAccount, IrcProbe> = {
|
||||
lastError: null,
|
||||
},
|
||||
buildChannelSummary: ({ account, snapshot }) => ({
|
||||
configured: snapshot.configured ?? false,
|
||||
...buildBaseChannelStatusSummary(snapshot),
|
||||
host: account.host,
|
||||
port: snapshot.port,
|
||||
tls: account.tls,
|
||||
nick: account.nick,
|
||||
running: snapshot.running ?? false,
|
||||
lastStartAt: snapshot.lastStartAt ?? null,
|
||||
lastStopAt: snapshot.lastStopAt ?? null,
|
||||
lastError: snapshot.lastError ?? null,
|
||||
probe: snapshot.probe,
|
||||
lastProbeAt: snapshot.lastProbeAt ?? null,
|
||||
}),
|
||||
probeAccount: async ({ cfg, account, timeoutMs }) =>
|
||||
probeIrc(cfg as CoreConfig, { accountId: account.accountId, timeoutMs }),
|
||||
buildAccountSnapshot: ({ account, runtime, probe }) => ({
|
||||
accountId: account.accountId,
|
||||
name: account.name,
|
||||
enabled: account.enabled,
|
||||
configured: account.configured,
|
||||
...buildBaseAccountStatusSnapshot({ account, runtime, probe }),
|
||||
host: account.host,
|
||||
port: account.port,
|
||||
tls: account.tls,
|
||||
nick: account.nick,
|
||||
passwordSource: account.passwordSource,
|
||||
running: runtime?.running ?? false,
|
||||
lastStartAt: runtime?.lastStartAt ?? null,
|
||||
lastStopAt: runtime?.lastStopAt ?? null,
|
||||
lastError: runtime?.lastError ?? null,
|
||||
probe,
|
||||
lastInboundAt: runtime?.lastInboundAt ?? null,
|
||||
lastOutboundAt: runtime?.lastOutboundAt ?? null,
|
||||
}),
|
||||
},
|
||||
gateway: {
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
DmPolicySchema,
|
||||
GroupPolicySchema,
|
||||
MarkdownConfigSchema,
|
||||
ReplyRuntimeConfigSchemaShape,
|
||||
ToolPolicySchema,
|
||||
requireOpenAllowFrom,
|
||||
} from "openclaw/plugin-sdk";
|
||||
@@ -62,15 +63,7 @@ export const IrcAccountSchemaBase = z
|
||||
channels: z.array(z.string()).optional(),
|
||||
mentionPatterns: z.array(z.string()).optional(),
|
||||
markdown: MarkdownConfigSchema,
|
||||
historyLimit: z.number().int().min(0).optional(),
|
||||
dmHistoryLimit: z.number().int().min(0).optional(),
|
||||
dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
|
||||
textChunkLimit: z.number().int().positive().optional(),
|
||||
chunkMode: z.enum(["length", "newline"]).optional(),
|
||||
blockStreaming: z.boolean().optional(),
|
||||
blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
|
||||
responsePrefix: z.string().optional(),
|
||||
mediaMaxMb: z.number().positive().optional(),
|
||||
...ReplyRuntimeConfigSchemaShape,
|
||||
})
|
||||
.strict();
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import {
|
||||
GROUP_POLICY_BLOCKED_LABEL,
|
||||
createNormalizedOutboundDeliverer,
|
||||
createReplyPrefixOptions,
|
||||
formatTextWithAttachmentLinks,
|
||||
logInboundDrop,
|
||||
resolveControlCommandGate,
|
||||
resolveOutboundMediaUrls,
|
||||
resolveAllowlistProviderRuntimeGroupPolicy,
|
||||
resolveDefaultGroupPolicy,
|
||||
warnMissingProviderGroupPolicyFallbackOnce,
|
||||
type OutboundReplyPayload,
|
||||
type OpenClawConfig,
|
||||
type RuntimeEnv,
|
||||
} from "openclaw/plugin-sdk";
|
||||
@@ -27,32 +31,20 @@ const CHANNEL_ID = "irc" as const;
|
||||
const escapeIrcRegexLiteral = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
|
||||
async function deliverIrcReply(params: {
|
||||
payload: { text?: string; mediaUrls?: string[]; mediaUrl?: string; replyToId?: string };
|
||||
payload: OutboundReplyPayload;
|
||||
target: string;
|
||||
accountId: string;
|
||||
sendReply?: (target: string, text: string, replyToId?: string) => Promise<void>;
|
||||
statusSink?: (patch: { lastOutboundAt?: number }) => void;
|
||||
}) {
|
||||
const text = params.payload.text ?? "";
|
||||
const mediaList = params.payload.mediaUrls?.length
|
||||
? params.payload.mediaUrls
|
||||
: params.payload.mediaUrl
|
||||
? [params.payload.mediaUrl]
|
||||
: [];
|
||||
|
||||
if (!text.trim() && mediaList.length === 0) {
|
||||
const combined = formatTextWithAttachmentLinks(
|
||||
params.payload.text,
|
||||
resolveOutboundMediaUrls(params.payload),
|
||||
);
|
||||
if (!combined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mediaBlock = mediaList.length
|
||||
? mediaList.map((url) => `Attachment: ${url}`).join("\n")
|
||||
: "";
|
||||
const combined = text.trim()
|
||||
? mediaBlock
|
||||
? `${text.trim()}\n\n${mediaBlock}`
|
||||
: text.trim()
|
||||
: mediaBlock;
|
||||
|
||||
if (params.sendReply) {
|
||||
await params.sendReply(params.target, combined, params.payload.replyToId);
|
||||
} else {
|
||||
@@ -317,26 +309,22 @@ export async function handleIrcInbound(params: {
|
||||
channel: CHANNEL_ID,
|
||||
accountId: account.accountId,
|
||||
});
|
||||
const deliverReply = createNormalizedOutboundDeliverer(async (payload) => {
|
||||
await deliverIrcReply({
|
||||
payload,
|
||||
target: peerId,
|
||||
accountId: account.accountId,
|
||||
sendReply: params.sendReply,
|
||||
statusSink,
|
||||
});
|
||||
});
|
||||
|
||||
await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
||||
ctx: ctxPayload,
|
||||
cfg: config as OpenClawConfig,
|
||||
dispatcherOptions: {
|
||||
...prefixOptions,
|
||||
deliver: async (payload) => {
|
||||
await deliverIrcReply({
|
||||
payload: payload as {
|
||||
text?: string;
|
||||
mediaUrls?: string[];
|
||||
mediaUrl?: string;
|
||||
replyToId?: string;
|
||||
},
|
||||
target: peerId,
|
||||
accountId: account.accountId,
|
||||
sendReply: params.sendReply,
|
||||
statusSink,
|
||||
});
|
||||
},
|
||||
deliver: deliverReply,
|
||||
onError: (err, info) => {
|
||||
runtime.error?.(`irc ${info.kind} reply failed: ${String(err)}`);
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk";
|
||||
import { createLoggerBackedRuntime, type RuntimeEnv } from "openclaw/plugin-sdk";
|
||||
import { resolveIrcAccount } from "./accounts.js";
|
||||
import { connectIrcClient, type IrcClient } from "./client.js";
|
||||
import { buildIrcConnectOptions } from "./connect-options.js";
|
||||
@@ -39,13 +39,12 @@ export async function monitorIrcProvider(opts: IrcMonitorOptions): Promise<{ sto
|
||||
accountId: opts.accountId,
|
||||
});
|
||||
|
||||
const runtime: RuntimeEnv = opts.runtime ?? {
|
||||
log: (...args: unknown[]) => core.logging.getChildLogger().info(args.map(String).join(" ")),
|
||||
error: (...args: unknown[]) => core.logging.getChildLogger().error(args.map(String).join(" ")),
|
||||
exit: () => {
|
||||
throw new Error("Runtime exit not available");
|
||||
},
|
||||
};
|
||||
const runtime: RuntimeEnv =
|
||||
opts.runtime ??
|
||||
createLoggerBackedRuntime({
|
||||
logger: core.logging.getChildLogger(),
|
||||
exitError: () => new Error("Runtime exit not available"),
|
||||
});
|
||||
|
||||
if (!account.configured) {
|
||||
throw new Error(
|
||||
|
||||
Reference in New Issue
Block a user