# Next Session: Cross-Channel Proactive Annie (WhatsApp + Telegram) + Pending Message Recovery

**Priority:** HIGH — Rajesh explicitly requested this. Annie ignoring messages after restart is rude.
**Estimated effort:** Discussion (20 min) + Implementation (2-3 hours)

## Problem 1: Missed Messages After Restart

When the WhatsApp agent restarts, the seen-hashes checkpoint mechanism marks all visible DOM messages as "seen" (catch-up mode). This means any message Rajesh sent DURING downtime is silently ignored — Annie never responds.

**Current behavior (broken):**
1. Rajesh asks "What's the weather?" at 10:17
2. Agent restarts at 10:21 (cadence fix deploy)
3. Stale checkpoint catch-up: "0 DOM hashes in seen set → catch-up, skip all"
4. Weather question is now in seen_hashes → never processed
5. Rajesh waits. Annie never responds. **Rude.**

**Desired behavior:**
1. Agent restarts
2. Scans recent messages for any from Rajesh that weren't answered
3. Processes and responds to pending messages

### Implementation Options

**Option A: Timestamp-based recovery (RECOMMENDED)**
- On startup, after catch-up, check the last N messages
- If any are from TRIGGER_SENDER and newer than the last response timestamp → process them
- Simple: compare `msg.timestamp` > `last_response_at` (persisted in cadence state)

**Option B: Response tracking**
- Track which messages Annie has responded to (not just seen)
- On restart, find messages without a corresponding Annie response
- More complex but more accurate

**Option C: Skip catch-up for TRIGGER_SENDER messages**
- During first-run catch-up, don't skip messages from Rajesh
- Process them normally through the trigger pipeline
- Risk: could replay old messages if restart happens hours later

### Key files
- `services/whatsapp-agent/wa_web.py` — `poll_new_messages()` lines 375-381 (catch-up logic)
- `services/whatsapp-agent/agent.py` — `_poll_loop()` (where messages are processed)
- `services/whatsapp-agent/trigger.py` — `cadence.last_response_at` (timestamp reference)

---

## Problem 2: Proactive Annie on WhatsApp

Currently Annie is purely reactive — she only speaks when spoken to. Rajesh wants her to be proactive: initiate conversations, share relevant info, check in.

**Examples of proactive behavior:**
- Morning briefing: "Good morning Rajesh! Weather is 28°C, AQI 85 (satisfactory). You have no pending tasks."
- Contextual: After detecting Rajesh mentioned travel plans → "I checked Skandagiri weather for Saturday — 22°C, clear skies."
- Follow-up: Rajesh asked about weather but Annie couldn't answer (LLM down) → retry when LLM recovers
- Nudge: "You mentioned wanting to go for a run — AQI is good right now (45)"

### Design Questions for Rajesh

1. **What triggers proactive messages?**
   - Time-based (morning briefing, evening summary)?
   - Event-based (weather change, context engine insight)?
   - Follow-up (unanswered question recovery)?
   - All of the above?

2. **Frequency/timing?**
   - How many proactive messages per day is comfortable?
   - Preferred times? (e.g., 7 AM briefing, 9 PM summary)
   - Should Annie be silent during certain hours?

3. **Which channel?**
   - WhatsApp DM only?
   - Or also Telegram / voice?

4. **Personality when proactive:**
   - Warm and chatty ("Hey! Just wanted to let you know...")
   - Efficient and brief ("Weather update: 28°C, AQI 85")
   - Mix depending on context?

### Implementation Architecture — CROSS-CHANNEL (WhatsApp + Telegram)

**Rajesh's requirement:** Proactive behavior should work on BOTH WhatsApp and Telegram. This is NOT a WhatsApp-only feature — it's a new cross-channel engine.

```
┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│  Scheduler   │────▶│  Proactive    │────▶│  wa_sender  │  (WhatsApp via wa-js)
│ (cron/async) │     │  Engine       │     └─────────────┘
└─────────────┘     │  - briefing   │     ┌─────────────┐
                    │  - follow-up  │────▶│  tg_sender   │  (Telegram via bot API)
┌─────────────┐     │  - nudge      │     └─────────────┘
│  Context     │────▶│  - event      │
│  Engine      │     └──────────────┘
└─────────────┘           │
                    ┌─────┴─────┐
                    │ Creature  │  (#52 — new creature for observability)
                    │ Registry  │  (ToolSpec + capability registry)
                    └───────────┘
```

**Where should this live?** Options to discuss:
- A) In `services/whatsapp-agent/` — but it's not WhatsApp-specific anymore
- B) In `services/annie-voice/` — the "brain" that already has tools, LLM, context
- C) New `services/proactive-engine/` — clean separation, channel-agnostic
- D) In `services/annie-voice/` as a new tool/module that dispatches to both channels

**Registration needed:**
1. New **creature** (#52) for observability tracking
2. New **ToolSpec** if proactive scheduling is exposed as a tool ("schedule a morning briefing")
3. **Capability registry** entry in `/v1/capabilities`
4. Dashboard panel for proactive message stats

### Key files to modify/create
- `services/annie-voice/proactive.py` — NEW: proactive message generation + scheduling (likely lives here since Annie is the brain)
- `services/whatsapp-agent/agent.py` — Expose send endpoint or import proactive module
- `services/telegram-bot/` — Add proactive dispatch method
- `services/annie-voice/config.py` — Proactive schedule config
- Observability: register creature #52

---

## Start Command

Start with Problem 1 (pending message recovery) — it's a concrete bug fix. Then discuss Problem 2 (proactive behavior) design with Rajesh before implementing.

## Verification

**Problem 1:**
1. Send Annie a message
2. Restart agent (`stop.sh whatsapp && start.sh whatsapp`)
3. Annie should respond to the pending message after restart

**Problem 2:**
1. Configure a morning briefing time
2. Wait for it to fire
3. Annie sends weather + summary without being asked
