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

@@ -41,8 +41,11 @@ export async function sendIMessageOutbound(params: {
});
}
export async function notifyIMessageApproval(id: string): Promise<void> {
await sendMessageIMessage(id, PAIRING_APPROVED_MESSAGE);
export async function notifyIMessageApproval(params: {
cfg: Parameters<typeof import("./accounts.js").resolveIMessageAccount>[0]["cfg"];
id: string;
}): Promise<void> {
await sendMessageIMessage(params.id, PAIRING_APPROVED_MESSAGE, { config: params.cfg });
}
export async function probeIMessageAccount(params?: {

View File

@@ -233,8 +233,8 @@ export const imessagePlugin: ChannelPlugin<ResolvedIMessageAccount, IMessageProb
text: {
idLabel: "imessageSenderId",
message: "OpenClaw: your access has been approved.",
notify: async ({ id }) =>
await (await loadIMessageChannelRuntime()).notifyIMessageApproval(id),
notify: async ({ id, cfg }) =>
await (await loadIMessageChannelRuntime()).notifyIMessageApproval({ id, cfg }),
},
},
security: imessageSecurityAdapter,

View File

@@ -1,3 +1,3 @@
export { loadConfig, resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
export { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
export { chunkTextWithMode, resolveChunkMode } from "openclaw/plugin-sdk/reply-runtime";
export { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";

View File

@@ -18,7 +18,6 @@ vi.mock("../send.js", () => ({
}));
vi.mock("./deliver.runtime.js", () => ({
loadConfig: vi.fn(() => ({})),
resolveMarkdownTableMode: vi.fn(() => resolveMarkdownTableModeMock()),
chunkTextWithMode: (text: string) => chunkTextWithModeMock(text),
resolveChunkMode: vi.fn(() => resolveChunkModeMock()),
@@ -28,6 +27,7 @@ vi.mock("./deliver.runtime.js", () => ({
let deliverReplies: typeof import("./deliver.js").deliverReplies;
describe("deliverReplies", () => {
const IMESSAGE_TEST_CFG = { channels: { imessage: { accounts: { default: {} } } } };
const runtime = { log: vi.fn(), error: vi.fn() } as unknown as RuntimeEnv;
const client = {} as Awaited<ReturnType<typeof import("../client.js").createIMessageRpcClient>>;
@@ -44,6 +44,7 @@ describe("deliverReplies", () => {
chunkTextWithModeMock.mockImplementation((text: string) => text.split("|"));
await deliverReplies({
cfg: IMESSAGE_TEST_CFG,
replies: [{ text: "first|second", replyToId: "reply-1" }],
target: "chat_id:10",
client,
@@ -60,6 +61,7 @@ describe("deliverReplies", () => {
"first",
expect.objectContaining({
client,
config: IMESSAGE_TEST_CFG,
maxBytes: 4096,
accountId: "default",
replyToId: "reply-1",
@@ -71,6 +73,7 @@ describe("deliverReplies", () => {
"second",
expect.objectContaining({
client,
config: IMESSAGE_TEST_CFG,
maxBytes: 4096,
accountId: "default",
replyToId: "reply-1",
@@ -80,6 +83,7 @@ describe("deliverReplies", () => {
it("propagates payload replyToId through media sends", async () => {
await deliverReplies({
cfg: IMESSAGE_TEST_CFG,
replies: [
{
text: "caption",
@@ -103,6 +107,7 @@ describe("deliverReplies", () => {
expect.objectContaining({
mediaUrl: "https://example.com/a.jpg",
client,
config: IMESSAGE_TEST_CFG,
maxBytes: 8192,
accountId: "acct-2",
replyToId: "reply-2",
@@ -115,6 +120,7 @@ describe("deliverReplies", () => {
expect.objectContaining({
mediaUrl: "https://example.com/b.jpg",
client,
config: IMESSAGE_TEST_CFG,
maxBytes: 8192,
accountId: "acct-2",
replyToId: "reply-2",
@@ -133,6 +139,7 @@ describe("deliverReplies", () => {
.mockResolvedValueOnce({ messageId: "imsg-2", sentText: "second" });
await deliverReplies({
cfg: IMESSAGE_TEST_CFG,
replies: [{ text: "first|second" }],
target: "chat_id:30",
client,
@@ -163,6 +170,7 @@ describe("deliverReplies", () => {
});
await deliverReplies({
cfg: IMESSAGE_TEST_CFG,
replies: [{ mediaUrls: ["https://example.com/a.jpg"] }],
target: "chat_id:40",
client,

View File

@@ -1,3 +1,4 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import {
deliverTextOrMediaReply,
resolveSendableOutboundReplyParts,
@@ -9,7 +10,6 @@ import { sendMessageIMessage } from "../send.js";
import {
chunkTextWithMode,
convertMarkdownTables,
loadConfig,
resolveChunkMode,
resolveMarkdownTableMode,
} from "./deliver.runtime.js";
@@ -17,6 +17,7 @@ import type { SentMessageCache } from "./echo-cache.js";
import { sanitizeOutboundText } from "./sanitize-outbound.js";
export async function deliverReplies(params: {
cfg: OpenClawConfig;
replies: ReplyPayload[];
target: string;
client: Awaited<ReturnType<typeof createIMessageRpcClient>>;
@@ -29,7 +30,7 @@ export async function deliverReplies(params: {
const { replies, target, client, runtime, maxBytes, textLimit, accountId, sentMessageCache } =
params;
const scope = `${accountId ?? ""}:${target}`;
const cfg = loadConfig();
const { cfg } = params;
const tableMode = resolveMarkdownTableMode({
cfg,
channel: "imessage",
@@ -47,6 +48,7 @@ export async function deliverReplies(params: {
chunkText: (value) => chunkTextWithMode(value, textLimit, chunkMode),
sendText: async (chunk) => {
const sent = await sendMessageIMessage(target, chunk, {
config: params.cfg,
maxBytes,
client,
accountId,
@@ -60,6 +62,7 @@ export async function deliverReplies(params: {
},
sendMedia: async ({ mediaUrl, caption }) => {
const sent = await sendMessageIMessage(target, caption ?? "", {
config: params.cfg,
mediaUrl,
maxBytes,
client,

View File

@@ -352,6 +352,7 @@ export async function monitorIMessageProvider(opts: MonitorIMessageOpts = {}): P
},
sendPairingReply: async (text) => {
await sendMessageIMessage(sender, text, {
config: cfg,
client: getActiveClient(),
maxBytes: mediaMaxBytes,
accountId: accountInfo.accountId,
@@ -450,6 +451,7 @@ export async function monitorIMessageProvider(opts: MonitorIMessageOpts = {}): P
return;
}
await deliverReplies({
cfg,
replies: [payload],
target,
client: getActiveClient(),

View File

@@ -1,4 +1,4 @@
import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
import { requireRuntimeConfig, type OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
import { kindFromMime } from "openclaw/plugin-sdk/media-runtime";
import { resolveOutboundAttachmentFromUrl } from "openclaw/plugin-sdk/media-runtime";
@@ -22,7 +22,7 @@ export type IMessageSendOpts = {
timeoutMs?: number;
chatId?: number;
client?: IMessageRpcClient;
config?: ReturnType<typeof loadConfig>;
config: OpenClawConfig;
account?: ResolvedIMessageAccount;
resolveAttachmentImpl?: (
mediaUrl: string,
@@ -97,9 +97,9 @@ function resolveDeliveredIMessageText(text: string, mediaContentType?: string):
export async function sendMessageIMessage(
to: string,
text: string,
opts: IMessageSendOpts = {},
opts: IMessageSendOpts,
): Promise<IMessageSendResult> {
const cfg = opts.config ?? loadConfig();
const cfg = requireRuntimeConfig(opts.config, "iMessage send");
const account =
opts.account ??
resolveIMessageAccount({