mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(outbound): unify resolved cfg threading across send paths (#33987)
This commit is contained in:
@@ -296,16 +296,18 @@ export const ircPlugin: ChannelPlugin<ResolvedIrcAccount, IrcProbe> = {
|
||||
chunker: (text, limit) => getIrcRuntime().channel.text.chunkMarkdownText(text, limit),
|
||||
chunkerMode: "markdown",
|
||||
textChunkLimit: 350,
|
||||
sendText: async ({ to, text, accountId, replyToId }) => {
|
||||
sendText: async ({ cfg, to, text, accountId, replyToId }) => {
|
||||
const result = await sendMessageIrc(to, text, {
|
||||
cfg: cfg as CoreConfig,
|
||||
accountId: accountId ?? undefined,
|
||||
replyTo: replyToId ?? undefined,
|
||||
});
|
||||
return { channel: "irc", ...result };
|
||||
},
|
||||
sendMedia: async ({ to, text, mediaUrl, accountId, replyToId }) => {
|
||||
sendMedia: async ({ cfg, to, text, mediaUrl, accountId, replyToId }) => {
|
||||
const combined = mediaUrl ? `${text}\n\nAttachment: ${mediaUrl}` : text;
|
||||
const result = await sendMessageIrc(to, combined, {
|
||||
cfg: cfg as CoreConfig,
|
||||
accountId: accountId ?? undefined,
|
||||
replyTo: replyToId ?? undefined,
|
||||
});
|
||||
|
||||
116
extensions/irc/src/send.test.ts
Normal file
116
extensions/irc/src/send.test.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { IrcClient } from "./client.js";
|
||||
import type { CoreConfig } from "./types.js";
|
||||
|
||||
const hoisted = vi.hoisted(() => {
|
||||
const loadConfig = vi.fn();
|
||||
const resolveMarkdownTableMode = vi.fn(() => "preserve");
|
||||
const convertMarkdownTables = vi.fn((text: string) => text);
|
||||
const record = vi.fn();
|
||||
return {
|
||||
loadConfig,
|
||||
resolveMarkdownTableMode,
|
||||
convertMarkdownTables,
|
||||
record,
|
||||
resolveIrcAccount: vi.fn(() => ({
|
||||
configured: true,
|
||||
accountId: "default",
|
||||
host: "irc.example.com",
|
||||
nick: "openclaw",
|
||||
port: 6697,
|
||||
tls: true,
|
||||
})),
|
||||
normalizeIrcMessagingTarget: vi.fn((value: string) => value.trim()),
|
||||
connectIrcClient: vi.fn(),
|
||||
buildIrcConnectOptions: vi.fn(() => ({})),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./runtime.js", () => ({
|
||||
getIrcRuntime: () => ({
|
||||
config: {
|
||||
loadConfig: hoisted.loadConfig,
|
||||
},
|
||||
channel: {
|
||||
text: {
|
||||
resolveMarkdownTableMode: hoisted.resolveMarkdownTableMode,
|
||||
convertMarkdownTables: hoisted.convertMarkdownTables,
|
||||
},
|
||||
activity: {
|
||||
record: hoisted.record,
|
||||
},
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("./accounts.js", () => ({
|
||||
resolveIrcAccount: hoisted.resolveIrcAccount,
|
||||
}));
|
||||
|
||||
vi.mock("./normalize.js", () => ({
|
||||
normalizeIrcMessagingTarget: hoisted.normalizeIrcMessagingTarget,
|
||||
}));
|
||||
|
||||
vi.mock("./client.js", () => ({
|
||||
connectIrcClient: hoisted.connectIrcClient,
|
||||
}));
|
||||
|
||||
vi.mock("./connect-options.js", () => ({
|
||||
buildIrcConnectOptions: hoisted.buildIrcConnectOptions,
|
||||
}));
|
||||
|
||||
vi.mock("./protocol.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("./protocol.js")>("./protocol.js");
|
||||
return {
|
||||
...actual,
|
||||
makeIrcMessageId: () => "irc-msg-1",
|
||||
};
|
||||
});
|
||||
|
||||
import { sendMessageIrc } from "./send.js";
|
||||
|
||||
describe("sendMessageIrc cfg threading", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("uses explicitly provided cfg without loading runtime config", async () => {
|
||||
const providedCfg = { source: "provided" } as unknown as CoreConfig;
|
||||
const client = {
|
||||
isReady: vi.fn(() => true),
|
||||
sendPrivmsg: vi.fn(),
|
||||
} as unknown as IrcClient;
|
||||
|
||||
const result = await sendMessageIrc("#room", "hello", {
|
||||
cfg: providedCfg,
|
||||
client,
|
||||
accountId: "work",
|
||||
});
|
||||
|
||||
expect(hoisted.loadConfig).not.toHaveBeenCalled();
|
||||
expect(hoisted.resolveIrcAccount).toHaveBeenCalledWith({
|
||||
cfg: providedCfg,
|
||||
accountId: "work",
|
||||
});
|
||||
expect(client.sendPrivmsg).toHaveBeenCalledWith("#room", "hello");
|
||||
expect(result).toEqual({ messageId: "irc-msg-1", target: "#room" });
|
||||
});
|
||||
|
||||
it("falls back to runtime config when cfg is omitted", async () => {
|
||||
const runtimeCfg = { source: "runtime" } as unknown as CoreConfig;
|
||||
hoisted.loadConfig.mockReturnValueOnce(runtimeCfg);
|
||||
const client = {
|
||||
isReady: vi.fn(() => true),
|
||||
sendPrivmsg: vi.fn(),
|
||||
} as unknown as IrcClient;
|
||||
|
||||
await sendMessageIrc("#ops", "ping", { client });
|
||||
|
||||
expect(hoisted.loadConfig).toHaveBeenCalledTimes(1);
|
||||
expect(hoisted.resolveIrcAccount).toHaveBeenCalledWith({
|
||||
cfg: runtimeCfg,
|
||||
accountId: undefined,
|
||||
});
|
||||
expect(client.sendPrivmsg).toHaveBeenCalledWith("#ops", "ping");
|
||||
});
|
||||
});
|
||||
@@ -8,6 +8,7 @@ import { getIrcRuntime } from "./runtime.js";
|
||||
import type { CoreConfig } from "./types.js";
|
||||
|
||||
type SendIrcOptions = {
|
||||
cfg?: CoreConfig;
|
||||
accountId?: string;
|
||||
replyTo?: string;
|
||||
target?: string;
|
||||
@@ -37,7 +38,7 @@ export async function sendMessageIrc(
|
||||
opts: SendIrcOptions = {},
|
||||
): Promise<SendIrcResult> {
|
||||
const runtime = getIrcRuntime();
|
||||
const cfg = runtime.config.loadConfig() as CoreConfig;
|
||||
const cfg = (opts.cfg ?? runtime.config.loadConfig()) as CoreConfig;
|
||||
const account = resolveIrcAccount({
|
||||
cfg,
|
||||
accountId: opts.accountId,
|
||||
|
||||
Reference in New Issue
Block a user