mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-27 09:02:15 +00:00
refactor: apply context visibility across channels
This commit is contained in:
@@ -1148,7 +1148,7 @@ describe("handleFeishuMessage command authorization", () => {
|
||||
expect(mockDispatchReplyFromConfig).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("drops quoted group context from senders outside the group sender allowlist", async () => {
|
||||
it("drops quoted group context from senders outside the group sender allowlist in allowlist mode", async () => {
|
||||
mockShouldComputeCommandAuthorized.mockReturnValue(false);
|
||||
mockGetMessageFeishu.mockResolvedValueOnce({
|
||||
messageId: "om_parent_blocked",
|
||||
@@ -1164,6 +1164,7 @@ describe("handleFeishuMessage command authorization", () => {
|
||||
feishu: {
|
||||
groupPolicy: "open",
|
||||
groupSenderAllowFrom: ["ou-allowed"],
|
||||
contextVisibility: "allowlist",
|
||||
groups: {
|
||||
"oc-group": {
|
||||
requireMention: false,
|
||||
@@ -1199,6 +1200,57 @@ describe("handleFeishuMessage command authorization", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps quoted group context from non-allowlisted senders in default all mode", async () => {
|
||||
mockShouldComputeCommandAuthorized.mockReturnValue(false);
|
||||
mockGetMessageFeishu.mockResolvedValueOnce({
|
||||
messageId: "om_parent_visible",
|
||||
chatId: "oc-group",
|
||||
senderId: "ou-blocked",
|
||||
senderType: "user",
|
||||
content: "visible quoted content",
|
||||
contentType: "text",
|
||||
});
|
||||
|
||||
const cfg: ClawdbotConfig = {
|
||||
channels: {
|
||||
feishu: {
|
||||
groupPolicy: "open",
|
||||
groupSenderAllowFrom: ["ou-allowed"],
|
||||
groups: {
|
||||
"oc-group": {
|
||||
requireMention: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ClawdbotConfig;
|
||||
|
||||
const event: FeishuMessageEvent = {
|
||||
sender: {
|
||||
sender_id: {
|
||||
open_id: "ou-allowed",
|
||||
},
|
||||
},
|
||||
message: {
|
||||
message_id: "msg-group-quoted-visible",
|
||||
parent_id: "om_parent_visible",
|
||||
chat_id: "oc-group",
|
||||
chat_type: "group",
|
||||
message_type: "text",
|
||||
content: JSON.stringify({ text: "hello" }),
|
||||
},
|
||||
};
|
||||
|
||||
await dispatchMessage({ cfg, event });
|
||||
|
||||
expect(mockFinalizeInboundContext).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
ReplyToId: "om_parent_visible",
|
||||
ReplyToBody: "visible quoted content",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("dispatches group image message when groupPolicy is open (requireMention defaults to false)", async () => {
|
||||
mockShouldComputeCommandAuthorized.mockReturnValue(false);
|
||||
|
||||
@@ -2552,6 +2604,7 @@ describe("handleFeishuMessage command authorization", () => {
|
||||
feishu: {
|
||||
groupPolicy: "open",
|
||||
groupSenderAllowFrom: ["ou-allowed"],
|
||||
contextVisibility: "allowlist",
|
||||
groups: {
|
||||
"oc-group": {
|
||||
requireMention: false,
|
||||
|
||||
@@ -12,9 +12,12 @@ import {
|
||||
clearHistoryEntriesIfEnabled,
|
||||
createChannelPairingController,
|
||||
DEFAULT_GROUP_HISTORY_LIMIT,
|
||||
evaluateSupplementalContextVisibility,
|
||||
filterSupplementalContextItems,
|
||||
type HistoryEntry,
|
||||
normalizeAgentId,
|
||||
recordPendingHistoryEntryIfEnabled,
|
||||
resolveChannelContextVisibilityMode,
|
||||
resolveAgentOutboundIdentity,
|
||||
resolveOpenProviderRuntimeGroupPolicy,
|
||||
resolveDefaultGroupPolicy,
|
||||
@@ -218,7 +221,7 @@ export function buildFeishuAgentBody(params: {
|
||||
return messageBody;
|
||||
}
|
||||
|
||||
function shouldIncludeFetchedGroupContextMessage(params: {
|
||||
function isFetchedGroupContextSenderAllowed(params: {
|
||||
isGroup: boolean;
|
||||
allowFrom: Array<string | number>;
|
||||
senderId?: string;
|
||||
@@ -231,15 +234,36 @@ function shouldIncludeFetchedGroupContextMessage(params: {
|
||||
return true;
|
||||
}
|
||||
const senderId = params.senderId?.trim();
|
||||
if (!senderId) {
|
||||
return false;
|
||||
}
|
||||
return isFeishuGroupAllowed({
|
||||
groupPolicy: "allowlist",
|
||||
const senderAllowed =
|
||||
!!senderId &&
|
||||
isFeishuGroupAllowed({
|
||||
groupPolicy: "allowlist",
|
||||
allowFrom: params.allowFrom,
|
||||
senderId,
|
||||
senderName: undefined,
|
||||
});
|
||||
return senderAllowed;
|
||||
}
|
||||
|
||||
function shouldIncludeFetchedGroupContextMessage(params: {
|
||||
isGroup: boolean;
|
||||
allowFrom: Array<string | number>;
|
||||
mode: "all" | "allowlist" | "allowlist_quote";
|
||||
kind: "quote" | "thread" | "history";
|
||||
senderId?: string;
|
||||
senderType?: string;
|
||||
}): boolean {
|
||||
const senderAllowed = isFetchedGroupContextSenderAllowed({
|
||||
isGroup: params.isGroup,
|
||||
allowFrom: params.allowFrom,
|
||||
senderId,
|
||||
senderName: undefined,
|
||||
senderId: params.senderId,
|
||||
senderType: params.senderType,
|
||||
});
|
||||
return evaluateSupplementalContextVisibility({
|
||||
mode: params.mode,
|
||||
kind: params.kind,
|
||||
senderAllowed,
|
||||
}).include;
|
||||
}
|
||||
|
||||
function filterFetchedGroupContextMessages<
|
||||
@@ -249,16 +273,22 @@ function filterFetchedGroupContextMessages<
|
||||
params: {
|
||||
isGroup: boolean;
|
||||
allowFrom: Array<string | number>;
|
||||
mode: "all" | "allowlist" | "allowlist_quote";
|
||||
kind: "quote" | "thread" | "history";
|
||||
},
|
||||
): T[] {
|
||||
return messages.filter((message) =>
|
||||
shouldIncludeFetchedGroupContextMessage({
|
||||
isGroup: params.isGroup,
|
||||
allowFrom: params.allowFrom,
|
||||
senderId: message.senderId,
|
||||
senderType: message.senderType,
|
||||
}),
|
||||
);
|
||||
return filterSupplementalContextItems({
|
||||
items: messages,
|
||||
mode: params.mode,
|
||||
kind: params.kind,
|
||||
isSenderAllowed: (message) =>
|
||||
isFetchedGroupContextSenderAllowed({
|
||||
isGroup: params.isGroup,
|
||||
allowFrom: params.allowFrom,
|
||||
senderId: message.senderId,
|
||||
senderType: message.senderType,
|
||||
}),
|
||||
}).items;
|
||||
}
|
||||
|
||||
export async function handleFeishuMessage(params: {
|
||||
@@ -706,6 +736,11 @@ export async function handleFeishuMessage(params: {
|
||||
const inboundLabel = isGroup
|
||||
? `Feishu[${account.accountId}] message in group ${ctx.chatId}`
|
||||
: `Feishu[${account.accountId}] DM from ${ctx.senderOpenId}`;
|
||||
const contextVisibilityMode = resolveChannelContextVisibilityMode({
|
||||
cfg: effectiveCfg,
|
||||
channel: "feishu",
|
||||
accountId: account.accountId,
|
||||
});
|
||||
|
||||
// Do not enqueue inbound user previews as system events.
|
||||
// System events are prepended to future prompts and can be misread as
|
||||
@@ -740,6 +775,8 @@ export async function handleFeishuMessage(params: {
|
||||
shouldIncludeFetchedGroupContextMessage({
|
||||
isGroup,
|
||||
allowFrom: effectiveGroupSenderAllowFrom,
|
||||
mode: contextVisibilityMode,
|
||||
kind: "quote",
|
||||
senderId: quotedMessageInfo.senderId,
|
||||
senderType: quotedMessageInfo.senderType,
|
||||
})
|
||||
@@ -750,7 +787,7 @@ export async function handleFeishuMessage(params: {
|
||||
);
|
||||
} else if (quotedMessageInfo) {
|
||||
log(
|
||||
`feishu[${account.accountId}]: skipped quoted message from sender ${quotedMessageInfo.senderId ?? "unknown"} due to group sender allowlist`,
|
||||
`feishu[${account.accountId}]: skipped quoted message from sender ${quotedMessageInfo.senderId ?? "unknown"} (mode=${contextVisibilityMode})`,
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -851,12 +888,14 @@ export async function handleFeishuMessage(params: {
|
||||
!shouldIncludeFetchedGroupContextMessage({
|
||||
isGroup,
|
||||
allowFrom: effectiveGroupSenderAllowFrom,
|
||||
mode: contextVisibilityMode,
|
||||
kind: "thread",
|
||||
senderId: rootMessageInfo.senderId,
|
||||
senderType: rootMessageInfo.senderType,
|
||||
})
|
||||
) {
|
||||
log(
|
||||
`feishu[${account.accountId}]: skipped thread starter from sender ${rootMessageInfo.senderId ?? "unknown"} due to group sender allowlist`,
|
||||
`feishu[${account.accountId}]: skipped thread starter from sender ${rootMessageInfo.senderId ?? "unknown"} (mode=${contextVisibilityMode})`,
|
||||
);
|
||||
rootMessageInfo = null;
|
||||
}
|
||||
@@ -929,6 +968,8 @@ export async function handleFeishuMessage(params: {
|
||||
const allowlistedMessages = filterFetchedGroupContextMessages(threadMessages, {
|
||||
isGroup,
|
||||
allowFrom: effectiveGroupSenderAllowFrom,
|
||||
mode: contextVisibilityMode,
|
||||
kind: "history",
|
||||
});
|
||||
const relevantMessages =
|
||||
(senderScoped
|
||||
|
||||
Reference in New Issue
Block a user