# Conversation History System V2

## Overview

The new conversation history system provides centralized, intelligent management of conversation context across all bot interactions.

## Key Improvements

### 1. **Per-Channel History** (Was: Per-User Globally)
- **Servers**: History tracked per `guild_id` - all users in a server share conversation context
- **DMs**: History tracked per `user_id` - each DM has its own conversation thread
- **Benefit**: Miku can follow multi-user conversations in servers and remember context across users

### 2. **Rich Message Metadata**
Each message stores:
- `author_name`: Display name of the speaker
- `content`: Message text
- `timestamp`: When the message was sent
- `is_bot`: Whether it's from Miku or a user

### 3. **Intelligent Formatting**
The system formats messages differently based on context:
- **Multi-user servers**: `"Alice: Hello!"` format to distinguish speakers
- **DMs**: Simple content without author prefix
- **LLM output**: OpenAI-compatible `{"role": "user"|"assistant", "content": "..."}` format

### 4. **Automatic Filtering**
- Empty messages automatically skipped
- Messages truncated to 500 characters to prevent context overflow
- Vision analysis context preserved inline

### 5. **Backward Compatibility**
- Still writes to `globals.conversation_history` for legacy code
- Uses same `user_id` parameter in `query_llama()`
- Autonomous functions work without modification

## Architecture

### Core Class: `ConversationHistory`

Located in: `bot/utils/conversation_history.py`

```python
from utils.conversation_history import conversation_history

# Add a message
conversation_history.add_message(
    channel_id="123456789",      # guild_id or user_id
    author_name="Alice",          # Display name
    content="Hello Miku!",        # Message text
    is_bot=False                  # True if from Miku
)

# Get recent messages
messages = conversation_history.get_recent_messages("123456789", max_messages=8)
# Returns: [(author, content, is_bot), ...]

# Format for LLM
llm_messages = conversation_history.format_for_llm("123456789", max_messages=8)
# Returns: [{"role": "user", "content": "Alice: Hello!"}, ...]

# Get statistics
stats = conversation_history.get_channel_stats("123456789")
# Returns: {"total_messages": 10, "bot_messages": 5, "user_messages": 5}
```

## Usage in `query_llama()`

### Updated Signature

```python
async def query_llama(
    user_prompt,
    user_id,                  # For DMs: actual user ID; For servers: can be anything
    guild_id=None,            # Server ID (None for DMs)
    response_type="dm_response",
    model=None,
    author_name=None          # NEW: Display name for multi-user context
):
```

### Channel ID Logic

```python
channel_id = str(guild_id) if guild_id else str(user_id)
```

- **Server messages**: `channel_id = guild_id` → All server users share history
- **DM messages**: `channel_id = user_id` → Each DM has separate history

### Example Calls

**Server message:**
```python
response = await query_llama(
    prompt="What's the weather?",
    user_id=str(message.author.id),
    guild_id=message.guild.id,           # Server context
    response_type="server_response",
    author_name=message.author.display_name  # "Alice"
)
# History saved to channel_id=guild_id
```

**DM message:**
```python
response = await query_llama(
    prompt="Tell me a joke",
    user_id=str(message.author.id),
    guild_id=None,                       # No server
    response_type="dm_response",
    author_name=message.author.display_name
)
# History saved to channel_id=user_id
```

**Autonomous message:**
```python
message = await query_llama(
    prompt="Say something fun!",
    user_id=f"miku-autonomous-{guild_id}",  # Consistent ID
    guild_id=guild_id,                      # Server context
    response_type="autonomous_general"
)
# History saved to channel_id=guild_id
```

## Image/Video Analysis

### Updated `rephrase_as_miku()`

```python
async def rephrase_as_miku(
    vision_output,
    user_prompt,
    guild_id=None,
    user_id=None,        # NEW: Actual user ID
    author_name=None     # NEW: Display name
):
```

### How It Works

1. **Vision analysis injected into history**:
   ```python
   conversation_history.add_message(
       channel_id=channel_id,
       author_name="Vision System",
       content=f"[Image/Video Analysis: {vision_output}]",
       is_bot=False
   )
   ```

2. **Follow-up questions remember the image**:
   - User sends image → Vision analysis added to history
   - User asks "What color is the car?" → Miku sees the vision analysis in history
   - User asks "Who made this meme?" → Still has vision context

### Example Flow

```
[USER] Bob: *sends meme.gif*
[Vision System]: [Image/Video Analysis: A cat wearing sunglasses with text "deal with it"]
[BOT] Miku: Haha, that's a classic meme! The cat looks so cool! 😎
[USER] Bob: Who made this meme?
[BOT] Miku: The "Deal With It" meme originated from...
```

## Migration from Old System

### What Changed

| **Old System** | **New System** |
|----------------|----------------|
| `globals.conversation_history[user_id]` | `conversation_history.add_message(channel_id, ...)` |
| Per-user globally | Per-server or per-DM |
| `[(user_msg, bot_msg), ...]` tuples | Rich metadata with author, timestamp, role |
| Manual filtering in `llm.py` | Automatic filtering in `ConversationHistory` |
| Image analysis used `user_id="image_analysis"` | Uses actual user's channel_id |
| Reply feature added `("", message)` tuples | No manual reply handling needed |

### Backward Compatibility

The new system still writes to `globals.conversation_history` for any code that might depend on it:

```python
# In llm.py after getting LLM response
globals.conversation_history[user_id].append((user_prompt, reply))
```

This ensures existing code doesn't break during migration.

## Testing

Run the test suite:

```bash
cd /home/koko210Serve/docker/ollama-discord/bot
python test_conversation_history.py
```

Tests cover:
- ✅ Adding messages to server channels
- ✅ Adding messages to DM channels
- ✅ Formatting for LLM (OpenAI messages)
- ✅ Empty message filtering
- ✅ Message truncation (500 char limit)
- ✅ Channel statistics

## Benefits

### 1. **Context Preservation**
- Multi-user conversations tracked properly
- Image/video descriptions persist across follow-up questions
- No more lost context when using Discord reply feature

### 2. **Token Efficiency**
- Automatic truncation prevents context overflow
- Empty messages filtered out
- Configurable message limits (default: 8 messages)

### 3. **Better Multi-User Support**
- Server conversations include author names: `"Alice: Hello!"`
- Miku understands who said what
- Enables natural group chat dynamics

### 4. **Debugging & Analytics**
- Rich metadata for each message
- Channel statistics (total, bot, user message counts)
- Timestamp tracking for future features

### 5. **Maintainability**
- Single source of truth for conversation history
- Clean API: `add_message()`, `get_recent_messages()`, `format_for_llm()`
- Centralized filtering and formatting logic

## Future Enhancements

Possible improvements:
- [ ] Persistent storage (save history to disk/database)
- [ ] Conversation summarization for very long threads
- [ ] Per-user preferences (some users want more/less context)
- [ ] Automatic context pruning based on relevance
- [ ] Export conversation history for analysis
- [ ] Integration with dm_interaction_analyzer

## Code Locations

| **File** | **Changes** |
|----------|-------------|
| `bot/utils/conversation_history.py` | **NEW** - Core history management class |
| `bot/utils/llm.py` | Updated to use new system, added `author_name` parameter |
| `bot/bot.py` | Pass `author_name` to `query_llama()`, removed reply pollution |
| `bot/utils/image_handling.py` | `rephrase_as_miku()` accepts `user_id` and `author_name` |
| `bot/utils/autonomous_v1_legacy.py` | No changes needed (already guild-based) |
| `bot/test_conversation_history.py` | **NEW** - Test suite |

## Summary

The new conversation history system provides:
- ✅ **Per-channel tracking** (server-wide or DM-specific)
- ✅ **Rich metadata** (author, timestamp, role)
- ✅ **Intelligent formatting** (with author names in servers)
- ✅ **Automatic filtering** (empty messages, truncation)
- ✅ **Image/video context** (vision analysis persists)
- ✅ **Backward compatibility** (legacy code still works)
- ✅ **Clean API** (simple, testable functions)

This solves the original problems:
1. ❌ ~~Video descriptions lost~~ → ✅ Now preserved in channel history
2. ❌ ~~Reply feature polluted history~~ → ✅ No manual reply handling
3. ❌ ~~Image analysis separate user_id~~ → ✅ Uses actual channel_id
4. ❌ ~~Autonomous actions broke history~~ → ✅ Guild-based IDs work naturally
