Skip to content

Commit 18a367c

Browse files
fitz123claude
andauthored
docs: add context injection to README (#89)
* recovered: uncommitted changes from crashed session * docs: add context injection section to README architecture Document that each message includes metadata (time, chat type, topic name, sender, reactions) so the agent is context-aware. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: fitz123 <fitz123@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e9f776a commit 18a367c

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ Both platforms share one Session Manager and use the same stream-relay logic via
6161

6262
**Message queue** sits between platform bots and Session Manager. Rapid messages are debounced (3s window) into a single prompt. Messages arriving while Claude is processing are collected (up to 20) and delivered as a combined followup after the current turn completes.
6363

64+
**Context injection:** Each message includes metadata — current time, chat type (DM/group/topic), topic name, sender username, and emoji reactions. The agent knows where it is, when it is, and who it's talking to. Reactions are delivered as messages so the agent can respond to a thumbs-up or a ❤️ without the user typing anything.
65+
6466
**Cron jobs** run separately via launchd plists. Each plist calls `run-cron.sh <task-name>`, which invokes `cron-runner.ts` to spawn a one-shot `claude -p` session with the cron's prompt.
6567

6668
**Config:** `config.yaml` defines agents (workspace + model) and bindings (chatId/channelId -> agentId). User-specific overrides live in `config.local.yaml` (gitignored, deep-merged over `config.yaml`). At least one platform (Telegram or Discord) must be configured. Tokens are read from macOS Keychain at runtime.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Plan: Fix NO_REPLY check to use trim + word-boundary regex
2+
3+
GitHub issue: #80
4+
5+
## Problem
6+
7+
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\b/.test(output.trim())) {
34+
```
35+
36+
Uses `\b` (word boundary) instead of `startsWith` — this catches `NO_REPLY`, `NO_REPLY: reason`, `NO_REPLY\ntext`, but correctly rejects `NO_REPLY_EXTRA` (underscore is a word character, so no boundary).
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+
- [ ] `bot/src/cron-runner.ts` — line 394, fix the check
43+
- [ ] Search all `NO_REPLY` checks in `bot/src/` — apply same fix if exact match found
44+
- [ ] Add/update tests for NO_REPLY with trailing text, whitespace, and clean NO_REPLY
45+
46+
## Tests
47+
48+
- [ ] `NO_REPLY` exact — should be swallowed
49+
- [ ] `NO_REPLY\n\nSome text` — should be swallowed
50+
- [ ] ` NO_REPLY ` — should be swallowed
51+
- [ ] `NO_REPLY_EXTRA` — should NOT be swallowed (`\b` correctly rejects this — underscore is a word character)
52+
- [ ] Regular output — should be delivered

0 commit comments

Comments
 (0)