fix(auto-reply): suppress JSON-wrapped NO_REPLY payloads before channel delivery#56612
Conversation
Greptile SummaryThis PR fixes a bug where models returning Key observations:
Confidence Score: 5/5Safe to merge — targeted bug fix with no regressions and solid regression test coverage across all affected pipelines. All changes are narrow and correct: the new detector is well-guarded, the three call-site updates are consistent, and the previously missing JSON-envelope case is now blocked before channel delivery. No P0 or P1 issues found. No files require special attention.
|
| Filename | Overview |
|---|---|
| src/auto-reply/tokens.ts | Adds isSilentReplyEnvelopeText to detect JSON-wrapped {"action":"NO_REPLY"} payloads, and isSilentReplyPayloadText composing both bare-token and envelope detectors. Implementation is correct. |
| src/auto-reply/reply/reply-directives.ts | Swaps isSilentReplyText for isSilentReplyPayloadText so the JSON envelope form is treated as silent before the directive parse result propagates. |
| src/auto-reply/reply/normalize-reply.ts | Uses isSilentReplyPayloadText for the exact-match check while correctly retaining isSilentReplyText for the trailing-strip code-path handling mixed-content messages. |
| src/agents/pi-embedded-runner/run/payloads.ts | Updates the outbound filter to use isSilentReplyPayloadText, aligning the embedded-runner path with the normalizer and directive-parser changes. |
| src/auto-reply/reply/reply-utils.test.ts | Adds regression tests for JSON envelope suppression and media preservation when text is a silent JSON envelope. |
| src/agents/pi-embedded-runner/run/payloads.test.ts | Adds a test confirming JSON NO_REPLY payloads are suppressed in the embedded-runner pipeline. |
| src/infra/outbound/payloads.test.ts | Covers both compact and pretty-printed JSON NO_REPLY envelopes in the delivery-pipeline filter test. |
Reviews (1): Last reviewed commit: "fix(auto-reply): suppress JSON-wrapped N..." | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 59c7c9486e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…el delivery
Add shared isSilentReplyPayloadText() detector that catches both bare
NO_REPLY tokens and JSON {"action":"NO_REPLY"} envelopes. Apply at the
reply directive parser, reply normalizer, and embedded agent payload
builder so the control payload is stripped before any channel sees it.
Preserves media when text is only a silent control envelope.
Fixes openclaw#37727
59c7c94 to
b8c4a63
Compare
Add missing changelog entries for PRs openclaw#56500, openclaw#56540, openclaw#56555, openclaw#56567, openclaw#56573, openclaw#56587, openclaw#56595, openclaw#56612, openclaw#56620.
…el delivery (openclaw#56612) Add shared isSilentReplyPayloadText() detector that catches both bare NO_REPLY tokens and JSON {"action":"NO_REPLY"} envelopes. Apply at the reply directive parser, reply normalizer, and embedded agent payload builder so the control payload is stripped before any channel sees it. Preserves media when text is only a silent control envelope. Fixes openclaw#37727
Add missing changelog entries for PRs openclaw#56500, openclaw#56540, openclaw#56555, openclaw#56567, openclaw#56573, openclaw#56587, openclaw#56595, openclaw#56612, openclaw#56620.
…el delivery (openclaw#56612) Add shared isSilentReplyPayloadText() detector that catches both bare NO_REPLY tokens and JSON {"action":"NO_REPLY"} envelopes. Apply at the reply directive parser, reply normalizer, and embedded agent payload builder so the control payload is stripped before any channel sees it. Preserves media when text is only a silent control envelope. Fixes openclaw#37727
Add missing changelog entries for PRs openclaw#56500, openclaw#56540, openclaw#56555, openclaw#56567, openclaw#56573, openclaw#56587, openclaw#56595, openclaw#56612, openclaw#56620.
…el delivery (openclaw#56612) Add shared isSilentReplyPayloadText() detector that catches both bare NO_REPLY tokens and JSON {"action":"NO_REPLY"} envelopes. Apply at the reply directive parser, reply normalizer, and embedded agent payload builder so the control payload is stripped before any channel sees it. Preserves media when text is only a silent control envelope. Fixes openclaw#37727
Add missing changelog entries for PRs openclaw#56500, openclaw#56540, openclaw#56555, openclaw#56567, openclaw#56573, openclaw#56587, openclaw#56595, openclaw#56612, openclaw#56620.
…el delivery (openclaw#56612) Add shared isSilentReplyPayloadText() detector that catches both bare NO_REPLY tokens and JSON {"action":"NO_REPLY"} envelopes. Apply at the reply directive parser, reply normalizer, and embedded agent payload builder so the control payload is stripped before any channel sees it. Preserves media when text is only a silent control envelope. Fixes openclaw#37727
Add missing changelog entries for PRs openclaw#56500, openclaw#56540, openclaw#56555, openclaw#56567, openclaw#56573, openclaw#56587, openclaw#56595, openclaw#56612, openclaw#56620.
…el delivery (openclaw#56612) Add shared isSilentReplyPayloadText() detector that catches both bare NO_REPLY tokens and JSON {"action":"NO_REPLY"} envelopes. Apply at the reply directive parser, reply normalizer, and embedded agent payload builder so the control payload is stripped before any channel sees it. Preserves media when text is only a silent control envelope. Fixes openclaw#37727
Add missing changelog entries for PRs openclaw#56500, openclaw#56540, openclaw#56555, openclaw#56567, openclaw#56573, openclaw#56587, openclaw#56595, openclaw#56612, openclaw#56620.
…el delivery (openclaw#56612) Add shared isSilentReplyPayloadText() detector that catches both bare NO_REPLY tokens and JSON {"action":"NO_REPLY"} envelopes. Apply at the reply directive parser, reply normalizer, and embedded agent payload builder so the control payload is stripped before any channel sees it. Preserves media when text is only a silent control envelope. Fixes openclaw#37727
Add missing changelog entries for PRs openclaw#56500, openclaw#56540, openclaw#56555, openclaw#56567, openclaw#56573, openclaw#56587, openclaw#56595, openclaw#56612, openclaw#56620.
…el delivery (openclaw#56612) Add shared isSilentReplyPayloadText() detector that catches both bare NO_REPLY tokens and JSON {"action":"NO_REPLY"} envelopes. Apply at the reply directive parser, reply normalizer, and embedded agent payload builder so the control payload is stripped before any channel sees it. Preserves media when text is only a silent control envelope. Fixes openclaw#37727
Add missing changelog entries for PRs openclaw#56500, openclaw#56540, openclaw#56555, openclaw#56567, openclaw#56573, openclaw#56587, openclaw#56595, openclaw#56612, openclaw#56620.
Summary
isSilentReplyPayloadText()detector that catches both bareNO_REPLYtokens and JSON{"action":"NO_REPLY"}envelopesRoot Cause
parseReplyDirectives()insrc/auto-reply/reply/reply-directives.tsonly treated exactNO_REPLYas silent. When models returned the control payload as raw JSON ({"action":"NO_REPLY"}), it was treated as normal text and delivered to users.This is a shared auto-reply layer issue, not Telegram-specific.
Change Type
Testing
136 tests pass across 4 test files. New regression tests for:
Fixes #37727