Skip to content

fix: tighten isSilentReplyText to match whole-text only#19576

Merged
obviyus merged 4 commits intoopenclaw:mainfrom
aldoeliacim:fix/silent-reply-too-permissive
Feb 26, 2026
Merged

fix: tighten isSilentReplyText to match whole-text only#19576
obviyus merged 4 commits intoopenclaw:mainfrom
aldoeliacim:fix/silent-reply-too-permissive

Conversation

@aldoeliacim
Copy link
Copy Markdown
Contributor

@aldoeliacim aldoeliacim commented Feb 18, 2026

Problem

isSilentReplyText() uses a suffix regex (\bNO_REPLY\b\W*$) that matches NO_REPLY at the end of any response text, even when preceded by substantive content. This causes legitimate replies to be silently suppressed and never delivered to the user.

Observed with Gemini 3 Pro which appends NO_REPLY to conversational replies, but any model could trigger this.

Fix

Replace the prefix + suffix regex pair with a single whole-string match: ^\s*TOKEN\s*$. Only responses that are entirely the silent token (with optional whitespace) are now treated as silent.

Tests

Added src/auto-reply/tokens.test.ts with 7 test cases covering:

  • Exact token match
  • Whitespace variants
  • Substantive text ending with token (the regression case)
  • Substantive text starting with token
  • Embedded token
  • Custom token parameter

All tests pass: npx vitest run src/auto-reply/tokens.test.ts

Fixes #19537

Greptile Summary

Replaces overly permissive prefix/suffix regex matching with strict whole-string matching for silent reply detection. The old implementation used \bNO_REPLY\b\W*$ suffix pattern that matched NO_REPLY at the end of any text, causing legitimate replies ending with the token to be silently suppressed. The new ^\s*TOKEN\s*$ pattern only treats responses that are entirely the silent token (with optional whitespace) as silent, fixing the regression where models like Gemini 3 Pro append NO_REPLY to conversational responses.

Confidence Score: 5/5

  • This PR is safe to merge with no concerns
  • The fix correctly addresses a critical bug where legitimate replies were being suppressed. The change is minimal, well-tested with 7 comprehensive test cases covering the regression and edge cases, and the logic change is straightforward and correct.
  • No files require special attention

Last reviewed commit: a6e4442

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

This comment was marked as spam.

@vincentkoc
Copy link
Copy Markdown
Member

you have been detected be spamming with unwarranted prs and issues and your issues and prs have been automatically closed. please read contributing guide Contributing.md.

The suffix regex matched NO_REPLY at the end of any response,
suppressing substantive replies when models (e.g. Gemini 3 Pro)
appended NO_REPLY to real content.

Replace prefix+suffix regexes with a single whole-string match.
Only responses that are entirely the silent token (with optional
whitespace) are now suppressed.

Add unit tests for the fix.

Fixes #19537
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Feb 26, 2026

Greptile Summary

Replaces the overly permissive prefix + suffix regex pair in isSilentReplyText() with a single whole-string match (^\s*TOKEN\s*$), fixing a bug where substantive replies ending with NO_REPLY were silently suppressed (issue #19537). The old suffix regex \bNO_REPLY\b\W*$ would match the token at the end of any response, even after real content. The old prefix regex ^\s*NO_REPLY(?=$|\W) similarly matched tokens followed by additional content. Both are now correctly replaced with a strict whole-string check.

  • Bug fix: Only responses consisting entirely of the silent token (with optional surrounding whitespace) are now treated as silent, preventing legitimate replies from being dropped.
  • Tests added: New colocated test file src/auto-reply/tokens.test.ts with 7 cases covering exact match, whitespace variants, and the regression scenario.
  • Dead code removed: isSilentReplyPrefixText was also removed — it had no callers in the codebase.

Confidence Score: 5/5

  • This PR is safe to merge — it's a targeted bug fix with correct logic and good test coverage.
  • The change is small and well-scoped: a single regex replacement in one function with clear before/after behavior. The new regex logic is correct — it only matches whole-string tokens. Tests cover the key edge cases including the specific regression. The function's callers all use it in a way compatible with the tighter matching. No removed code had any callers.
  • No files require special attention.

Last reviewed commit: 8ed852d

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread src/auto-reply/tokens.ts Outdated
@obviyus obviyus force-pushed the fix/silent-reply-too-permissive branch from 8ed852d to b0091d2 Compare February 26, 2026 10:25
@obviyus
Copy link
Copy Markdown
Contributor

obviyus commented Feb 26, 2026

Added follow-up fixes beyond the original regex tightening:

  • Integrated streaming partial-token suppression work from fix: suppress silent-reply partial tokens during streaming #19648 into this PR (guarded isSilentReplyPrefixText path).
  • Applied prefix suppression in streaming/typing flow paths (including heartbeat token partials in runner normalization).
  • Updated regression tests so only exact NO_REPLY is suppressed; substantive text like NO_REPLY -- ... now delivers.
  • Added prefix-helper coverage and NO_/NO_RE streaming partial regression coverage.
  • Rebased onto latest main and resolved merge conflicts in agent-runner-execution.ts and typing.ts.

Current head: 203ec4f6cc2a4c58a6621439d808c0151438dc6d.

@obviyus obviyus merged commit 97fa44d into openclaw:main Feb 26, 2026
@obviyus
Copy link
Copy Markdown
Contributor

obviyus commented Feb 26, 2026

Landed via temp rebase onto main.

  • Gate: pnpm test src/telegram
  • Land commit: d75e2ec
  • Merge commit: 97fa44d

Thanks @aldoeliacim!

robbyczgw-cla pushed a commit to robbyczgw-cla/openclaw that referenced this pull request Feb 26, 2026
execute008 pushed a commit to execute008/openclaw that referenced this pull request Feb 27, 2026
r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
vincentkoc pushed a commit to Sid-Qin/openclaw that referenced this pull request Feb 28, 2026
vincentkoc pushed a commit to rylena/rylen-openclaw that referenced this pull request Feb 28, 2026
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 1, 2026
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 3, 2026
thebenjaminlee pushed a commit to escape-velocity-ventures/openclaw that referenced this pull request Mar 7, 2026
john-ver pushed a commit to apmcoin/apmclaw that referenced this pull request Mar 9, 2026
dustin-olenslager pushed a commit to dustin-olenslager/ironclaw-supreme that referenced this pull request Mar 24, 2026
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isSilentReplyText regex too permissive — suppresses substantive replies ending with NO_REPLY

4 participants