You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: NO_REPLY check should use trim + word-boundary regex (#86)
* add plan: no-reply-trim
* fix: use trim/startsWith for NO_REPLY checks (#80)
NO_REPLY with trailing text or whitespace was bypassing exact match and
getting delivered to users. Changed both cron-runner.ts and stream-relay.ts
to use output.trim().startsWith("NO_REPLY").
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address code review findings
- Tighten NO_REPLY match from startsWith to word-boundary regex
/^NO_REPLY(\s|$)/ to avoid false positives on NO_REPLY_EXTRA etc.
- Add negative test for NO_REPLY substring prefix (NO_REPLY_EXTRA)
- Remove unnecessary null-coalescing on non-nullable accumulated var
- Fix sendTyping to skip DM chats (pre-existing test failure)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address code review findings
- Add content assertion to NO_REPLY_EXTRA boundary test
- Update plan to reflect regex approach (was stale from startsWith era)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* session end: uncommitted changes
---------
Co-authored-by: fitz123 <fitz123@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
When a cron LLM response starts with `NO_REPLY` but includes additional text (e.g. `NO_REPLY\n\nExplanation...`), the exact match `output === "NO_REPLY"` fails and the entire response gets delivered to the user.
8
+
9
+
Real example from bedtime-reminder cron:
10
+
```
11
+
NO_REPLY
12
+
13
+
Завтра (1 апреля) нет событий с конкретным временем...
14
+
```
15
+
16
+
## Root cause
17
+
18
+
`bot/src/cron-runner.ts:394`:
19
+
```ts
20
+
if (cron.type==="llm"&&output==="NO_REPLY") {
21
+
```
22
+
23
+
Exact match doesn't handle trailing whitespace or extra text after `NO_REPLY`.
24
+
25
+
## Fix
26
+
27
+
Change line 394 from:
28
+
```ts
29
+
if (cron.type==="llm"&&output==="NO_REPLY") {
30
+
```
31
+
to:
32
+
```ts
33
+
if (cron.type==="llm"&&/^NO_REPLY(\s|$)/.test(output.trim())) {
34
+
```
35
+
36
+
Regex requires word boundary (`\s` or end-of-string) after `NO_REPLY` to avoid false matches on strings like `NO_REPLY_EXTRA`.
37
+
38
+
Also check `bot/src/stream-relay.ts` and `bot/src/message-queue.ts` for similar NO_REPLY checks — apply the same pattern everywhere.
39
+
40
+
## Files to change
41
+
42
+
- [x] `bot/src/cron-runner.ts` — line 394, fix the check
43
+
- [x] Search all `NO_REPLY` checks in `bot/src/` — apply same fix if exact match found
44
+
- [x] Add/update tests for NO_REPLY with trailing text, whitespace, and clean NO_REPLY
45
+
46
+
## Tests
47
+
48
+
- [x] `NO_REPLY` exact — should be swallowed
49
+
- [x] `NO_REPLY\n\nSometext` — should be swallowed
50
+
- [x] `NO_REPLY` — should be swallowed
51
+
- [x] `NO_REPLY_EXTRA` — should NOT be swallowed (regex word boundary correctly rejects this)
0 commit comments