diff --git a/extensions/imessage/src/channel.ts b/extensions/imessage/src/channel.ts index 2eadc5a8a90..5178f1f883c 100644 --- a/extensions/imessage/src/channel.ts +++ b/extensions/imessage/src/channel.ts @@ -11,14 +11,16 @@ import { formatTrimmedAllowFromEntries, looksLikeIMessageTargetId, normalizeIMessageMessagingTarget, - resolveIMessageGroupRequireMention, - resolveIMessageGroupToolPolicy, type ChannelPlugin, } from "openclaw/plugin-sdk/imessage"; import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime"; import { type RoutePeer } from "openclaw/plugin-sdk/routing"; import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js"; import { resolveIMessageAccount, type ResolvedIMessageAccount } from "./accounts.js"; +import { + resolveIMessageGroupRequireMention, + resolveIMessageGroupToolPolicy, +} from "./group-policy.js"; import { getIMessageRuntime } from "./runtime.js"; import { imessageSetupAdapter } from "./setup-core.js"; import { createIMessagePluginBase, imessageSetupWizard } from "./shared.js"; diff --git a/extensions/imessage/src/group-policy.test.ts b/extensions/imessage/src/group-policy.test.ts new file mode 100644 index 00000000000..c94d76bfd27 --- /dev/null +++ b/extensions/imessage/src/group-policy.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from "vitest"; +import { + resolveIMessageGroupRequireMention, + resolveIMessageGroupToolPolicy, +} from "./group-policy.js"; + +describe("imessage group policy", () => { + it("uses generic channel group policy helpers", () => { + const cfg = { + channels: { + imessage: { + groups: { + "chat:family": { + requireMention: false, + tools: { deny: ["exec"] }, + }, + "*": { + requireMention: true, + tools: { allow: ["message.send"] }, + }, + }, + }, + }, + // oxlint-disable-next-line typescript/no-explicit-any + } as any; + + expect(resolveIMessageGroupRequireMention({ cfg, groupId: "chat:family" })).toBe(false); + expect(resolveIMessageGroupRequireMention({ cfg, groupId: "chat:other" })).toBe(true); + expect(resolveIMessageGroupToolPolicy({ cfg, groupId: "chat:family" })).toEqual({ + deny: ["exec"], + }); + expect(resolveIMessageGroupToolPolicy({ cfg, groupId: "chat:other" })).toEqual({ + allow: ["message.send"], + }); + }); +}); diff --git a/extensions/imessage/src/group-policy.ts b/extensions/imessage/src/group-policy.ts new file mode 100644 index 00000000000..bfb25e77241 --- /dev/null +++ b/extensions/imessage/src/group-policy.ts @@ -0,0 +1,40 @@ +import { + resolveChannelGroupRequireMention, + resolveChannelGroupToolsPolicy, + type GroupToolPolicyConfig, +} from "openclaw/plugin-sdk/channel-policy"; +import type { OpenClawConfig } from "openclaw/plugin-sdk/imessage"; + +type IMessageGroupContext = { + cfg: OpenClawConfig; + accountId?: string | null; + groupId?: string | null; + senderId?: string | null; + senderName?: string | null; + senderUsername?: string | null; + senderE164?: string | null; +}; + +export function resolveIMessageGroupRequireMention(params: IMessageGroupContext): boolean { + return resolveChannelGroupRequireMention({ + cfg: params.cfg, + channel: "imessage", + groupId: params.groupId, + accountId: params.accountId, + }); +} + +export function resolveIMessageGroupToolPolicy( + params: IMessageGroupContext, +): GroupToolPolicyConfig | undefined { + return resolveChannelGroupToolsPolicy({ + cfg: params.cfg, + channel: "imessage", + groupId: params.groupId, + accountId: params.accountId, + senderId: params.senderId, + senderName: params.senderName, + senderUsername: params.senderUsername, + senderE164: params.senderE164, + }); +} diff --git a/src/plugin-sdk/imessage.ts b/src/plugin-sdk/imessage.ts index adad1403eb6..d3007be1eef 100644 --- a/src/plugin-sdk/imessage.ts +++ b/src/plugin-sdk/imessage.ts @@ -37,7 +37,7 @@ export { export { resolveIMessageGroupRequireMention, resolveIMessageGroupToolPolicy, -} from "../channels/plugins/group-mentions.js"; +} from "../../extensions/imessage/src/group-policy.js"; export { IMessageConfigSchema } from "../config/zod-schema.providers-core.js"; export { resolveChannelMediaMaxBytes } from "../channels/plugins/media-limits.js";