Merge cc4afb26869e81429f9fc43ebcddb58cefb2f3b4 into 5e417b44e1540f528d2ae63e3e20229a902d1db2
This commit is contained in:
commit
bab5c8575e
@ -414,6 +414,11 @@ export async function handleFeishuMessage(params: {
|
||||
|
||||
({ requireMention } = resolveFeishuReplyPolicy({
|
||||
isDirectMessage: false,
|
||||
isThreadReply:
|
||||
groupSession?.threadReply &&
|
||||
(groupSession?.groupSessionScope === "group_topic" ||
|
||||
groupSession?.groupSessionScope === "group_topic_sender" ||
|
||||
groupSession?.replyInThread),
|
||||
globalConfig: feishuCfg,
|
||||
groupConfig,
|
||||
}));
|
||||
|
||||
@ -141,6 +141,7 @@ const ReplyInThreadSchema = z.enum(["disabled", "enabled"]).optional();
|
||||
export const FeishuGroupSchema = z
|
||||
.object({
|
||||
requireMention: z.boolean().optional(),
|
||||
requireMentionInThread: z.boolean().optional(),
|
||||
tools: ToolPolicySchema,
|
||||
skills: z.array(z.string()).optional(),
|
||||
enabled: z.boolean().optional(),
|
||||
@ -164,6 +165,7 @@ const FeishuSharedConfigShape = {
|
||||
groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
||||
groupSenderAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
||||
requireMention: z.boolean().optional(),
|
||||
requireMentionInThread: z.boolean().optional(),
|
||||
groups: z.record(z.string(), FeishuGroupSchema.optional()).optional(),
|
||||
historyLimit: z.number().int().min(0).optional(),
|
||||
dmHistoryLimit: z.number().int().min(0).optional(),
|
||||
|
||||
@ -3,8 +3,9 @@ import {
|
||||
isFeishuGroupAllowed,
|
||||
resolveFeishuAllowlistMatch,
|
||||
resolveFeishuGroupConfig,
|
||||
resolveFeishuReplyPolicy,
|
||||
} from "./policy.js";
|
||||
import type { FeishuConfig } from "./types.js";
|
||||
import type { FeishuConfig, FeishuGroupConfig } from "./types.js";
|
||||
|
||||
describe("feishu policy", () => {
|
||||
describe("resolveFeishuGroupConfig", () => {
|
||||
@ -100,6 +101,90 @@ describe("feishu policy", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveFeishuReplyPolicy", () => {
|
||||
it("does not require mention for DMs", () => {
|
||||
expect(resolveFeishuReplyPolicy({ isDirectMessage: true })).toEqual({
|
||||
requireMention: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("requires mention in group by default", () => {
|
||||
expect(resolveFeishuReplyPolicy({ isDirectMessage: false })).toEqual({
|
||||
requireMention: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("respects group-level requireMention override", () => {
|
||||
expect(
|
||||
resolveFeishuReplyPolicy({
|
||||
isDirectMessage: false,
|
||||
groupConfig: { requireMention: false } as FeishuGroupConfig,
|
||||
}),
|
||||
).toEqual({ requireMention: false });
|
||||
});
|
||||
|
||||
it("still requires mention for thread replies when no thread override is set", () => {
|
||||
expect(
|
||||
resolveFeishuReplyPolicy({
|
||||
isDirectMessage: false,
|
||||
isThreadReply: true,
|
||||
}),
|
||||
).toEqual({ requireMention: true });
|
||||
});
|
||||
|
||||
it("skips mention for thread replies when requireMentionInThread is false (global)", () => {
|
||||
expect(
|
||||
resolveFeishuReplyPolicy({
|
||||
isDirectMessage: false,
|
||||
isThreadReply: true,
|
||||
globalConfig: { requireMentionInThread: false } as FeishuConfig,
|
||||
}),
|
||||
).toEqual({ requireMention: false });
|
||||
});
|
||||
|
||||
it("skips mention for thread replies when requireMentionInThread is false (group)", () => {
|
||||
expect(
|
||||
resolveFeishuReplyPolicy({
|
||||
isDirectMessage: false,
|
||||
isThreadReply: true,
|
||||
groupConfig: { requireMentionInThread: false } as FeishuGroupConfig,
|
||||
}),
|
||||
).toEqual({ requireMention: false });
|
||||
});
|
||||
|
||||
it("group-level requireMentionInThread overrides global", () => {
|
||||
expect(
|
||||
resolveFeishuReplyPolicy({
|
||||
isDirectMessage: false,
|
||||
isThreadReply: true,
|
||||
globalConfig: { requireMentionInThread: false } as FeishuConfig,
|
||||
groupConfig: { requireMentionInThread: true } as FeishuGroupConfig,
|
||||
}),
|
||||
).toEqual({ requireMention: true });
|
||||
});
|
||||
|
||||
it("requireMentionInThread tightens when base requireMention is false", () => {
|
||||
expect(
|
||||
resolveFeishuReplyPolicy({
|
||||
isDirectMessage: false,
|
||||
isThreadReply: true,
|
||||
globalConfig: { requireMention: false } as FeishuConfig,
|
||||
groupConfig: { requireMentionInThread: true } as FeishuGroupConfig,
|
||||
}),
|
||||
).toEqual({ requireMention: true });
|
||||
});
|
||||
|
||||
it("does not apply thread override for non-thread messages", () => {
|
||||
expect(
|
||||
resolveFeishuReplyPolicy({
|
||||
isDirectMessage: false,
|
||||
isThreadReply: false,
|
||||
globalConfig: { requireMentionInThread: false } as FeishuConfig,
|
||||
}),
|
||||
).toEqual({ requireMention: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe("isFeishuGroupAllowed", () => {
|
||||
it("matches group IDs with chat: prefix", () => {
|
||||
expect(
|
||||
|
||||
@ -105,6 +105,7 @@ export function isFeishuGroupAllowed(params: {
|
||||
|
||||
export function resolveFeishuReplyPolicy(params: {
|
||||
isDirectMessage: boolean;
|
||||
isThreadReply?: boolean;
|
||||
globalConfig?: FeishuConfig;
|
||||
groupConfig?: FeishuGroupConfig;
|
||||
}): { requireMention: boolean } {
|
||||
@ -115,5 +116,13 @@ export function resolveFeishuReplyPolicy(params: {
|
||||
const requireMention =
|
||||
params.groupConfig?.requireMention ?? params.globalConfig?.requireMention ?? true;
|
||||
|
||||
if (params.isThreadReply) {
|
||||
const threadOverride =
|
||||
params.groupConfig?.requireMentionInThread ?? params.globalConfig?.requireMentionInThread;
|
||||
if (threadOverride !== undefined) {
|
||||
return { requireMention: threadOverride };
|
||||
}
|
||||
}
|
||||
|
||||
return { requireMention };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user