fix: normalize Feishu delivery.to before comparing with messaging tool targets

- Add normalizeDeliveryTarget helper to strip user:/chat: prefixes for Feishu
- Apply normalization in matchesMessagingToolDeliveryTarget before comparison
- This ensures cron duplicate suppression works when session uses prefixed targets
  (user:ou_xxx) but messaging tool extract uses normalized bare IDs (ou_xxx)

Fixes review comment on PR #32755

(cherry picked from commit fc20106f16)
This commit is contained in:
Xu Zimo
2026-03-03 22:10:30 +08:00
committed by Tak Hoffman
parent 45cef46bc4
commit 3f0f658080

View File

@@ -21,6 +21,21 @@ import {
waitForDescendantSubagentSummary,
} from "./subagent-followup.js";
function normalizeDeliveryTarget(channel: string, to: string): string {
const channelLower = channel.trim().toLowerCase();
const toTrimmed = to.trim();
if (channelLower === "feishu" || channelLower === "lark") {
const lowered = toTrimmed.toLowerCase();
if (lowered.startsWith("user:")) {
return toTrimmed.slice("user:".length).trim();
}
if (lowered.startsWith("chat:")) {
return toTrimmed.slice("chat:".length).trim();
}
}
return toTrimmed;
}
export function matchesMessagingToolDeliveryTarget(
target: { provider?: string; to?: string; accountId?: string },
delivery: { channel?: string; to?: string; accountId?: string },
@@ -36,11 +51,11 @@ export function matchesMessagingToolDeliveryTarget(
if (target.accountId && delivery.accountId && target.accountId !== delivery.accountId) {
return false;
}
// Strip :topic:NNN suffix from target.to before comparing — the cron delivery.to
// is already stripped to chatId only, but the agent's message tool may pass a
// topic-qualified target (e.g. "-1003597428309:topic:462").
const normalizedTargetTo = target.to.replace(/:topic:\d+$/, "");
return normalizedTargetTo === delivery.to;
// Strip :topic:NNN from message targets and normalize Feishu/Lark prefixes on
// both sides so cron duplicate suppression compares canonical IDs.
const normalizedTargetTo = normalizeDeliveryTarget(channel, target.to.replace(/:topic:\d+$/, ""));
const normalizedDeliveryTo = normalizeDeliveryTarget(channel, delivery.to);
return normalizedTargetTo === normalizedDeliveryTo;
}
export function resolveCronDeliveryBestEffort(job: CronJob): boolean {