# Next Session: WhatsApp Agent — Phase 5 (Hardening + Full Pipeline)

**Date:** 2026-04-07
**Status:** READY — Phases 1-4 deployed, E2E verified (first live message received)

---

## What's Done

**Phases 1-4 COMPLETE + DEPLOYED + E2E VERIFIED:**
- 10 files under `services/whatsapp-agent/`: config, dedup, mutex, receiver, context_mgr, compaction, context_client, agent, trigger, responder
- Bidirectional screen.lock in phone_loop.py
- start.sh/stop.sh integrated (`./start.sh whatsapp`)
- Tasker on Pixel configured: "Notification WhatsApp → Forward to Annie"
- **First live message received 2026-04-07 03:32**: `"Buffered message from Rajesh (7 chars)"`
- Group filter removed — Annie's dedicated Pixel accepts all chats (DMs + groups)
- 140 new tests + 2817 AV = 2957 total, 0 failed

## What's NOT Working Yet

1. **Sender extraction is hardcoded** — Tasker body has `"sender":"Rajesh"`. All messages show as from "Rajesh" regardless of actual sender. Need to parse `%antitle` (DMs = sender name, groups = "Sender @ Group" or group name).

2. **Hourly compaction fails** — `Connection error` when calling LLM. The `GEMMA4_BASE_URL` in config.py defaults to `http://192.168.68.55:8003/v1` (Titan) but Panda may not be reaching it. Verify connectivity and fix.

3. **Trigger/responder untested live** — The trigger (regex + LLM classify) and responder (generate + u2 send) haven't been tested with real messages yet. Need to verify: send "Annie, what time is it?" from main phone → Annie responds in WhatsApp.

4. **Dashboard creature "sphinx" not added** — No observability for the WhatsApp agent in the dashboard yet.

5. **No Tasker heartbeat monitoring** — If Tasker stops or Pixel disconnects, nobody knows.

## Plan

```
~/.claude/plans/typed-bouncing-emerson.md
```

The original plan's Phase 5 (Hardening) covers items 4-5 above. Items 1-3 are bugs/gaps discovered during deployment.

## What To Do (in priority order)

### 1. Fix sender extraction (HIGH — data quality)
The Tasker notification variables for WhatsApp:
- **DMs**: `%antitle` = sender name (e.g., "Rajesh"), `%antext` = message text
- **Groups**: `%antitle` = group name (e.g., "Holliday"), `%antext` = "Sender: message text"

Options:
- **Option A**: Change Tasker body to `{"group":"%antitle","sender":"%antitle","text":"%antext"}` — simple but loses sender info in groups
- **Option B**: Parse sender from `%antext` in receiver.py — group messages have "Sender: text" format in notifications
- **Option C**: Use Tasker's `%ansender` variable if available (may not be on all Android versions)

Research which Tasker variables are available for WhatsApp notifications, then fix the body template + receiver parsing.

### 2. Fix hourly compaction LLM connection (HIGH — core feature)
```
ERROR | compaction:_llm_summarize:64 - [COMPACT] LLM summarization failed: Connection error.
```
- Verify Panda can reach Titan:8003: `curl http://192.168.68.55:8003/v1/models`
- If reachable: check the GEMMA4_BASE_URL is correct in agent's runtime env
- If not reachable: add GEMMA4_BASE_URL to Panda's .env or fix network

### 3. Test trigger + responder live (HIGH — Phase 4 validation)
- Send "Annie, what time is it?" from main phone to Pixel's WhatsApp
- Verify: trigger regex fires → LLM classifies as direct_request → response generated → u2 sends in WhatsApp
- If u2 send fails: check screen state, WhatsApp UI selectors, mutex behavior
- Test cadence: send 6 requests → 5th should respond, 6th should be rate-limited

### 4. Add dashboard creature "sphinx" (MEDIUM — observability)
- Add to dashboard's creature registry
- Events: message_received, message_filtered, trigger_detected, response_sent, compaction_hourly, compaction_daily
- Zone: OBSERVING
- Service: whatsapp-agent, Process: whatsapp-daemon

### 5. Tasker heartbeat + reliability (MEDIUM — hardening)
- Add heartbeat check: if no Tasker events in 30 min, log warning
- USB/ADB watchdog: check ADB connectivity every 60s
- Circuit breaker for LLM calls: if LLM down, emergency context trim without LLM
- Tasker battery optimization: verify it's disabled (critical for reliability)

### 6. Adversarial testing (LOW — security)
- Rate limit: flood 200+ messages → verify 429
- Malformed JSON → verify 422
- Prompt injection in group messages → verify compaction guard works
- Concurrent access: phone call + WhatsApp send → verify mutex priority

## Environment

- **Panda** (192.168.68.57): WhatsApp agent on port 8780, phone services
- **Titan** (192.168.68.55): Gemma 4 on port 8003, Context Engine on port 8100
- **Pixel** (192.168.68.60): WhatsApp + Tasker

## Start Command

```bash
# 1. Read memory:
cat ~/.claude/projects/-home-rajesh-workplace-her-her-os/memory/project_whatsapp_observer.md

# 2. Fix sender extraction (#1 above)
# 3. Fix compaction LLM connection (#2)
# 4. Test trigger + responder live (#3)
# 5. Add dashboard creature (#4)
# 6. Hardening (#5-6)
```

## Key Files

| File | What |
|------|------|
| `services/whatsapp-agent/agent.py` | Main daemon |
| `services/whatsapp-agent/receiver.py` | FastAPI webhook receiver |
| `services/whatsapp-agent/trigger.py` | Two-phase trigger detection |
| `services/whatsapp-agent/responder.py` | Response generation + u2 delivery |
| `services/whatsapp-agent/compaction.py` | Hourly + daily LLM digests |
| `services/whatsapp-agent/config.py` | All constants and env vars |
| `services/whatsapp-agent/context_mgr.py` | 128K budget manager |
| `services/annie-voice/phone_loop.py` | Modified: bidirectional screen.lock |
| `start.sh` / `stop.sh` | Service management |
