# Personalizing Daily Briefings from Partner Conversation Data

## When to Use This

When a user wants to make automated morning briefings (or other recurring
messages) more personal by mining a long conversation history with their
partner. This pattern works for WhatsApp exports, Telegram exports, Signal
backups, or any timestamped chat transcript.

## Overview

1. Parse the chat export into structured messages (by sender, timestamp, text).
2. Filter out media placeholders (image omitted, audio omitted, etc.).
3. Extract themes: family, health, hobbies, food preferences, dreams, career,
   communication style, nicknames, inside jokes.
4. Build a themed compliment pool tailored to the partner's interests and
   your relationship dynamics.
5. Generate date ideas and gift ideas aligned with those themes.
6. Update the briefing script to import the external compliment pool.
7. Save outputs (compliment module, date ideas, gift ideas) as separate files
   so the user can reference them independently.

## Parsing a WhatsApp Export

WhatsApp exports use this line format:

```
[DD/MM/YYYY, HH:MM:SS] Sender Name: message text
```

Some messages span multiple lines. A simple regex parser:

```python
import re

messages = []
current_msg = None

for line in lines:
    line = line.rstrip('\n')
    match = re.match(
        r'\[(\d{2}/\d{2}/\d{4}, \d{2}:\d{2}:\d{2})\] (.*?): (.*)',
        line
    )
    if match:
        if current_msg:
            messages.append(current_msg)
        current_msg = {
            'datetime': match.group(1),
            'sender': match.group(2),
            'text': match.group(3)
        }
    else:
        if current_msg:
            current_msg['text'] += '\n' + line

if current_msg:
    messages.append(current_msg)
```

## Filtering Media Placeholders

Remove lines that are only media placeholders so they don't pollute word counts:

```python
media_patterns = [
    'image omitted', 'video omitted', 'audio omitted',
    'sticker omitted', 'GIF omitted'
]

def is_media(text):
    return any(p in text for p in media_patterns)

text_msgs = [m for m in messages if not is_media(m['text'])]
```

## Theme Extraction via Keyword Context Search

Search both partners' texts for keywords and collect surrounding context:

```python
def find_contexts(text, keywords, context_chars=120):
    results = []
    text_lower = text.lower()
    for kw in keywords:
        for m in re.finditer(kw, text_lower):
            start = max(0, m.start() - context_chars)
            end = min(len(text), m.end() + context_chars)
            snippet = text[start:end].replace('\n', ' ')
            results.append((kw, snippet.strip()))
    return results
```

Common keyword groups to search:

| Category | Keywords |
|----------|----------|
| Family | mum, dad, mother, father, sister, brother, family |
| Health | migraine, headache, doctor, hospital, scan, tired |
| Career | work, job, interview, vacancy, office, exams, school |
| Hobbies | book, read, ballet, dance, dnd, game, anime, museum |
| Food | sushi, spaghetti, salmon, bbq, pancake, chinese |
| Pets | dog, puppy, cat, pet |
| Travel | trip, flight, hotel, beach, holiday |
| Dreams | dream, dreamt |
| Affection | love, miss you, goodnight, good morning, my love |

## Building a Themed Compliment Pool

Group compliments into categories that match the partner's identity:

- **General warmth** - smile, laugh, presence, strength
- **Heritage** - Scottish, Celtic, Gaelic references
- **Career/achievements** - encouragement for interviews, exams, work wins
- **Hobbies** - ballet, DnD, books, fantasy, gaming
- **Relationship-specific** - inside jokes, nicknames, shared memories
- **Dreams** - since she shares dreams daily
- **Health support** - migraine encouragement, self-care reminders

Store the pool in a separate Python module so the briefing script can import it:

```python
# caoil_compliments.py (place next to morning_briefing.py)
COMPLIMENTS_POOL = [
    "Your smile is literally the best part of my morning.",
    "If we were in a campaign, you'd be the legendary item everyone wants.",
    "I hope your dreams are as wonderful as you are.",
    # ... 80+ themed compliments
]
```

Wire the briefing script to import it:

```python
import sys, os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from caoil_compliments import COMPLIMENTS_POOL

def get_daily_compliment():
    return random.choice(COMPLIMENTS_POOL)
```

Save the compliment module in the same directory as the briefing script (e.g. `~/.hermes/scripts/`).

## Generating Date Ideas

Based on extracted themes, generate date ideas in categories:

| Category | Example |
|----------|---------|
| Fantasy & Books | Bookstore crawl, fantasy escape room, DnD one-shot |
| Ballet & Dance | Performance tickets, dance workshop, movie night |
| DnD & Geek | Convention visit, character building night, game cafe |
| Scottish/Cultural | Scottish dinner night, plan Scotland trip |
| Creative/Artsy | Museum date with backstory game, sketch together |
| Archery | Range date, themed picnic |
| Active/Outdoor | Easy hike, canoeing, swimming/spa day |
| At-Home/Cozy | Cook together, read aloud, stargazing |
| Budget-Friendly | Park picnic, free museum day, city exploration |

Save as a plain text file the user can reference anytime.

## Generating Gift Ideas

Similarly, generate gift ideas by category:

| Category | Example |
|----------|---------|
| Books | Special edition of a book she recommended you |
| DnD | Fae-themed dice set, custom character art |
| Scottish | Shortbread, tartan item, Gaelic phrasebook |
| Ballet | Performance tickets, dance workshop for two |
| Creative | Sketchbook, watercolor set, cosplay materials |
| Personal | Playlist of songs that remind you of her, "Open When" letters |
| Practical | Migraine care kit, water bottle |
| Experience | Spa day, archery lesson, weekend trip |

## Free Instant Wins

No-money gestures that land well:
- Voice memo in a silly voice
- Photo of something that made you think of her
- Song recommendation with a note why
- Funny dream recount (she loves dreams)
- Stick-figure drawing of her DnD character
- "Would you rather" fantasy scenario
- Research a topic she mentioned and send cool facts

## Pitfalls

**Privacy:** Chat exports contain sensitive data. Never echo raw messages back in full. Summarize themes only. Don't save raw chat content to public skills.

**Overfitting:** A compliment pool of 20 items gets repetitive quickly. Aim for 60-100+ themed compliments for daily rotation.

**Seasonal drift:** Compliments about "summer" or specific events get stale. Refresh the pool every few months or automate rotation.

**One-sided analysis:** Mine both partners' messages. The user's writing style and shared inside jokes are just as important as the partner's profile.

**Memory storage limits:** When saving partner profiles to agent memory, you may hit the character limit. Prioritize compact facts ("Caoil: Scottish-Belgian, ballet dancer, DnD player, prone to migraines") over long prose. Move detailed analysis (date ideas, gift lists, full compliment pools) to files on disk and reference them by path.

**Calendar completeness:** If the briefing only shows events from some calendars, the search method may not work for all calendar types (shared calendars, recurring series, birthday calendars). See `daily-briefing-apple-caldav.md` for the multi-strategy fallback approach.
