refactor: centralize inbound mention policy

This commit is contained in:
Peter Steinberger
2026-04-07 07:50:09 +01:00
parent c8b7058058
commit 625fd5b3e3
31 changed files with 857 additions and 225 deletions

View File

@@ -82,7 +82,7 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";',
'export { GoogleChatConfigSchema, type GoogleChatAccountConfig, type GoogleChatConfig } from "openclaw/plugin-sdk/googlechat-runtime-shared";',
'export { extractToolSend } from "openclaw/plugin-sdk/tool-send";',
'export { resolveMentionGatingWithBypass } from "openclaw/plugin-sdk/channel-inbound";',
'export { resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";',
'export { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";',
'export { resolveWebhookPath } from "openclaw/plugin-sdk/webhook-path";',
'export { registerWebhookTargetWithPluginRoute, resolveWebhookTargetWithAuthOrReject, withResolvedWebhookRequestPipeline } from "openclaw/plugin-sdk/webhook-targets";',

View File

@@ -290,6 +290,13 @@ describe("plugin-sdk subpath exports", () => {
]) {
expectSourceMentions(subpath, ["chunkTextForOutbound"]);
}
for (const subpath of ["googlechat", "msteams", "nextcloud-talk", "zalouser"]) {
expectSourceMentions(subpath, [
"resolveInboundMentionDecision",
"resolveMentionGating",
"resolveMentionGatingWithBypass",
]);
}
expectSourceMentions("approval-auth-runtime", [
"createResolvedApproverActionAuthAdapter",
"resolveApprovalApprovers",
@@ -453,6 +460,7 @@ describe("plugin-sdk subpath exports", () => {
"recordInboundSession",
"recordInboundSessionMetaSafe",
"resolveInboundSessionEnvelopeContext",
"resolveInboundMentionDecision",
"resolveMentionGating",
"resolveMentionGatingWithBypass",
"resolveOutboundSendDep",
@@ -536,9 +544,11 @@ describe("plugin-sdk subpath exports", () => {
"formatInboundEnvelope",
"formatInboundFromLabel",
"formatLocationText",
"implicitMentionKindWhen",
"logInboundDrop",
"matchesMentionPatterns",
"matchesMentionWithExplicit",
"resolveInboundMentionDecision",
"normalizeMentionText",
"resolveInboundDebounceMs",
"resolveEnvelopeFormatOptions",

View File

@@ -35,6 +35,10 @@ import { dispatchReplyWithBufferedBlockDispatcher } from "../../auto-reply/reply
import { createReplyDispatcherWithTyping } from "../../auto-reply/reply/reply-dispatcher.js";
import { removeAckReactionAfterReply, shouldAckReaction } from "../../channels/ack-reactions.js";
import { resolveCommandAuthorizedFromAuthorizers } from "../../channels/command-gating.js";
import {
implicitMentionKindWhen,
resolveInboundMentionDecision,
} from "../../channels/mention-gating.js";
import {
setChannelConversationBindingIdleTimeoutBySessionKey,
setChannelConversationBindingMaxAgeBySessionKey,
@@ -128,6 +132,8 @@ export function createRuntimeChannel(): PluginRuntime["channel"] {
buildMentionRegexes,
matchesMentionPatterns,
matchesMentionWithExplicit,
implicitMentionKindWhen,
resolveInboundMentionDecision,
},
reactions: {
shouldAckReaction,

View File

@@ -83,6 +83,8 @@ export type PluginRuntimeChannel = {
buildMentionRegexes: typeof import("../../auto-reply/reply/mentions.js").buildMentionRegexes;
matchesMentionPatterns: typeof import("../../auto-reply/reply/mentions.js").matchesMentionPatterns;
matchesMentionWithExplicit: typeof import("../../auto-reply/reply/mentions.js").matchesMentionWithExplicit;
implicitMentionKindWhen: typeof import("../../channels/mention-gating.js").implicitMentionKindWhen;
resolveInboundMentionDecision: typeof import("../../channels/mention-gating.js").resolveInboundMentionDecision;
};
reactions: {
shouldAckReaction: typeof import("../../channels/ack-reactions.js").shouldAckReaction;