fix(channels): thread runtime config through sends

This commit is contained in:
Peter Steinberger
2026-04-22 06:14:12 +01:00
parent e1897419de
commit 95331e5cc5
125 changed files with 1461 additions and 804 deletions

View File

@@ -322,13 +322,15 @@ export const ircPlugin: ChannelPlugin<ResolvedIrcAccount, IrcProbe> = createChat
idLabel: "ircUser",
message: PAIRING_APPROVED_MESSAGE,
normalizeAllowEntry: (entry) => normalizeIrcAllowEntry(entry),
notify: async ({ id, message }) => {
notify: async ({ cfg, id, message }) => {
const target = normalizePairingTarget(id);
if (!target) {
throw new Error(`invalid IRC pairing id: ${id}`);
}
const { sendMessageIrc } = await loadIrcChannelRuntime();
await sendMessageIrc(target, message);
await sendMessageIrc(target, message, {
cfg: cfg as CoreConfig,
});
},
},
},

View File

@@ -58,6 +58,7 @@ function resolveIrcEffectiveAllowlists(params: {
async function deliverIrcReply(params: {
payload: OutboundReplyPayload;
cfg: CoreConfig;
target: string;
accountId: string;
sendReply?: (target: string, text: string, replyToId?: string) => Promise<void>;
@@ -70,6 +71,7 @@ async function deliverIrcReply(params: {
await params.sendReply(params.target, text, replyToId);
} else {
await sendMessageIrc(params.target, text, {
cfg: params.cfg,
accountId: params.accountId,
replyTo: replyToId,
});
@@ -218,6 +220,7 @@ export async function handleIrcInbound(params: {
sendPairingReply: async (text) => {
await deliverIrcReply({
payload: { text },
cfg: config,
target: message.senderNick,
accountId: account.accountId,
sendReply: params.sendReply,
@@ -340,6 +343,7 @@ export async function handleIrcInbound(params: {
deliver: async (payload) => {
await deliverIrcReply({
payload,
cfg: config,
target: peerId,
accountId: account.accountId,
sendReply: params.sendReply,

View File

@@ -108,30 +108,19 @@ describe("sendMessageIrc cfg threading", () => {
expect(result.messageId.length).toBeGreaterThan(0);
});
it("falls back to runtime config when cfg is omitted", async () => {
const runtimeCfg = {
channels: {
irc: {
host: "irc.example.com",
nick: "openclaw",
},
},
} as unknown as CoreConfig;
hoisted.loadConfig.mockReturnValueOnce(runtimeCfg);
it("fails hard when cfg is omitted", async () => {
const client = {
isReady: vi.fn(() => true),
sendPrivmsg: vi.fn(),
} as unknown as IrcClient;
await sendMessageIrc("#ops", "ping", { client });
await expect(sendMessageIrc("#ops", "ping", { client } as never)).rejects.toThrow(
"IRC send requires a resolved runtime config",
);
expect(hoisted.loadConfig).toHaveBeenCalledTimes(1);
expect(client.sendPrivmsg).toHaveBeenCalledWith("#ops", "ping");
expect(hoisted.record).toHaveBeenCalledWith({
channel: "irc",
accountId: "default",
direction: "outbound",
});
expect(hoisted.loadConfig).not.toHaveBeenCalled();
expect(client.sendPrivmsg).not.toHaveBeenCalled();
expect(hoisted.record).not.toHaveBeenCalled();
});
it("sends with provided cfg even when the runtime store is not initialized", async () => {

View File

@@ -1,4 +1,4 @@
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
import { requireRuntimeConfig, resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";
import { resolveIrcAccount } from "./accounts.js";
import type { IrcClient } from "./client.js";
@@ -10,7 +10,7 @@ import { getIrcRuntime } from "./runtime.js";
import type { CoreConfig } from "./types.js";
type SendIrcOptions = {
cfg?: CoreConfig;
cfg: CoreConfig;
accountId?: string;
replyTo?: string;
target?: string;
@@ -51,10 +51,9 @@ function resolveTarget(to: string, opts?: SendIrcOptions): string {
export async function sendMessageIrc(
to: string,
text: string,
opts: SendIrcOptions = {},
opts: SendIrcOptions,
): Promise<SendIrcResult> {
const runtime = getIrcRuntime();
const cfg = (opts.cfg ?? runtime.config.loadConfig()) as CoreConfig;
const cfg = requireRuntimeConfig(opts.cfg, "IRC send") as CoreConfig;
const account = resolveIrcAccount({
cfg,
accountId: opts.accountId,