From 4fa631fffde86c7612f03fb957fd886205d3cda9 Mon Sep 17 00:00:00 2001 From: Mark Sherwinsky Date: Mon, 16 Mar 2026 02:29:28 -0700 Subject: [PATCH] Fix reply-tagged NO_REPLY suppression --- src/auto-reply/tokens.test.ts | 9 +++++++++ src/auto-reply/tokens.ts | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/auto-reply/tokens.test.ts b/src/auto-reply/tokens.test.ts index f610fa35462..8fbde925dad 100644 --- a/src/auto-reply/tokens.test.ts +++ b/src/auto-reply/tokens.test.ts @@ -11,6 +11,15 @@ describe("isSilentReplyText", () => { expect(isSilentReplyText("\nNO_REPLY\n")).toBe(true); }); + it("returns true for reply-tagged silent token", () => { + expect(isSilentReplyText("[[reply_to_current]] NO_REPLY")).toBe(true); + expect(isSilentReplyText("[[ reply_to : 123 ]]\nNO_REPLY")).toBe(true); + }); + + it("returns false for reply-tagged substantive text containing token", () => { + expect(isSilentReplyText("[[reply_to_current]] NO_REPLY but here is more content")).toBe(false); + }); + it("returns false for undefined/empty", () => { expect(isSilentReplyText(undefined)).toBe(false); expect(isSilentReplyText("")).toBe(false); diff --git a/src/auto-reply/tokens.ts b/src/auto-reply/tokens.ts index f5445ad5531..820c5b54435 100644 --- a/src/auto-reply/tokens.ts +++ b/src/auto-reply/tokens.ts @@ -1,4 +1,5 @@ import { escapeRegExp } from "../utils.js"; +import { stripInlineDirectiveTagsForDisplay } from "../utils/directive-tags.js"; export const HEARTBEAT_TOKEN = "HEARTBEAT_OK"; export const SILENT_REPLY_TOKEN = "NO_REPLY"; @@ -37,7 +38,19 @@ export function isSilentReplyText( } // Match only the exact silent token with optional surrounding whitespace. // This prevents substantive replies ending with NO_REPLY from being suppressed (#19537). - return getSilentExactRegex(token).test(text); + if (getSilentExactRegex(token).test(text)) { + return true; + } + // Reply/audio directive tags may prefix otherwise-silent text, e.g. + // [[reply_to_current]] NO_REPLY. Strip directives before the exact-match check + // so silent turns stay silent on chat surfaces that use reply tags. + if (text.includes("[[")) { + const stripped = stripInlineDirectiveTagsForDisplay(text).text; + if (stripped && getSilentExactRegex(token).test(stripped)) { + return true; + } + } + return false; } /**