feat: Phase 1 - Discord bridge with unified user identity

Implements unified cross-server memory system for Miku bot:

**Core Changes:**
- discord_bridge plugin with 3 hooks for metadata enrichment
- Unified user identity: discord_user_{id} across servers and DMs
- Minimal filtering: skip only trivial messages (lol, k, 1-2 chars)
- Marks all memories as consolidated=False for Phase 2 processing

**Testing:**
- test_phase1.py validates cross-server memory recall
- PHASE1_TEST_RESULTS.md documents successful validation
- Cross-server test: User says 'blue' in Server A, Miku remembers in Server B 

**Documentation:**
- IMPLEMENTATION_PLAN.md - Complete architecture and roadmap
- Phase 2 (sleep consolidation) ready for implementation

This lays the foundation for human-like memory consolidation.
This commit is contained in:
2026-01-31 18:54:00 +02:00
parent 0a9145728e
commit 323ca753d1
7 changed files with 1921 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
"""
Discord Bridge Plugin for Cheshire Cat
This plugin enriches Cat's memory system with Discord context:
- Unified user identity across all servers and DMs
- Guild/channel metadata for context tracking
- Minimal filtering before storage (only skip obvious junk)
- Marks memories as unconsolidated for nightly processing
Phase 1 Implementation
"""
from cat.mad_hatter.decorators import hook
from datetime import datetime
import re
@hook(priority=100)
def before_cat_reads_message(user_message_json: dict, cat) -> dict:
"""
Enrich incoming message with Discord metadata.
This runs BEFORE the message is processed.
"""
# Extract Discord context from working memory or metadata
# These will be set by the Discord bot when calling the Cat API
guild_id = cat.working_memory.get('guild_id')
channel_id = cat.working_memory.get('channel_id')
# Add to message metadata for later use
if 'metadata' not in user_message_json:
user_message_json['metadata'] = {}
user_message_json['metadata']['guild_id'] = guild_id or 'dm'
user_message_json['metadata']['channel_id'] = channel_id
user_message_json['metadata']['timestamp'] = datetime.now().isoformat()
return user_message_json
@hook(priority=100)
def before_cat_stores_episodic_memory(doc, cat):
"""
Filter and enrich memories before storage.
Phase 1: Minimal filtering
- Skip only obvious junk (1-2 char messages, pure reactions)
- Store everything else temporarily
- Mark as unconsolidated for nightly processing
"""
message = doc.page_content.strip()
# Skip only the most trivial messages
skip_patterns = [
r'^\w{1,2}$', # 1-2 character messages: "k", "ok"
r'^(lol|lmao|haha|hehe|xd|rofl)$', # Pure reactions
r'^:[\w_]+:$', # Discord emoji only: ":smile:"
]
for pattern in skip_patterns:
if re.match(pattern, message.lower()):
print(f"🗑️ [Discord Bridge] Skipping trivial message: {message}")
return None # Don't store at all
# Add Discord metadata to memory
doc.metadata['consolidated'] = False # Needs nightly processing
doc.metadata['stored_at'] = datetime.now().isoformat()
# Get Discord context from working memory
guild_id = cat.working_memory.get('guild_id')
channel_id = cat.working_memory.get('channel_id')
doc.metadata['guild_id'] = guild_id or 'dm'
doc.metadata['channel_id'] = channel_id
doc.metadata['source'] = 'discord'
print(f"💾 [Discord Bridge] Storing memory (unconsolidated): {message[:50]}...")
print(f" User: {cat.user_id}, Guild: {doc.metadata['guild_id']}, Channel: {channel_id}")
return doc
@hook(priority=50)
def after_cat_recalls_memories(memory_docs, cat):
"""
Log memory recall for debugging.
Can be used to filter by guild_id if needed in the future.
"""
if memory_docs:
print(f"🧠 [Discord Bridge] Recalled {len(memory_docs)} memories for user {cat.user_id}")
# Show which guilds the memories are from
guilds = set(doc.metadata.get('guild_id', 'unknown') for doc in memory_docs)
print(f" From guilds: {', '.join(guilds)}")
return memory_docs
# Plugin metadata
__version__ = "1.0.0"
__description__ = "Discord bridge with unified user identity and sleep consolidation support"

View File

@@ -0,0 +1,10 @@
{
"name": "Discord Bridge",
"description": "Discord integration with unified user identity and sleep consolidation support",
"author_name": "Miku Bot Team",
"author_url": "",
"plugin_url": "",
"tags": "discord, memory, consolidation",
"thumb": "",
"version": "1.0.0"
}

View File

@@ -0,0 +1 @@
{}