#!/usr/bin/env python3 """ Phase 1 Test Script Tests the Discord bridge plugin: 1. Unified user identity (same user across servers/DMs) 2. Metadata enrichment (guild_id, channel_id) 3. Minimal filtering (skip "lol", "k", etc.) 4. Temporary storage (consolidated=false) """ import requests import json import time from datetime import datetime CAT_URL = "http://localhost:1865" TEST_USER_ID = "discord_user_test123" def test_message(text: str, guild_id: str = None, channel_id: str = None, description: str = ""): """Send a message to Cat and return the response""" print(f"\n{'='*80}") print(f"TEST: {description}") print(f"Message: '{text}'") print(f"Guild: {guild_id or 'DM'}, Channel: {channel_id or 'N/A'}") payload = { "text": text, "user_id": TEST_USER_ID } # Add Discord context to working memory if guild_id or channel_id: payload["metadata"] = { "guild_id": guild_id, "channel_id": channel_id } try: response = requests.post( f"{CAT_URL}/message", json=payload, timeout=30 ) if response.status_code == 200: result = response.json() print(f"โœ… Response: {result.get('content', '')[:100]}...") return True else: print(f"โŒ Error: {response.status_code} - {response.text}") return False except Exception as e: print(f"โŒ Exception: {e}") return False def get_memories(user_id: str = TEST_USER_ID): """Retrieve all memories for test user""" try: # Cat API endpoint for memories (may vary based on version) response = requests.get( f"{CAT_URL}/memory/collections", timeout=10 ) if response.status_code == 200: data = response.json() # This is a simplified check - actual API may differ print(f"\n๐Ÿ“Š Memory collections available: {list(data.keys())}") return data else: print(f"โš ๏ธ Could not retrieve memories: {response.status_code}") return None except Exception as e: print(f"โš ๏ธ Exception getting memories: {e}") return None def check_cat_health(): """Check if Cat is running""" try: response = requests.get(f"{CAT_URL}/", timeout=5) if response.status_code == 200: print("โœ… Cheshire Cat is running") return True except: pass print("โŒ Cheshire Cat is not accessible at", CAT_URL) return False def main(): print("="*80) print("PHASE 1 TEST: Discord Bridge Plugin") print("="*80) # Check Cat is running if not check_cat_health(): print("\nโš ๏ธ Start Cheshire Cat first:") print(" cd cheshire-cat") print(" docker-compose -f docker-compose.test.yml up -d") return print(f"\n๐Ÿงช Testing with user ID: {TEST_USER_ID}") print(" (Same user across all contexts - unified identity)") # Wait a bit for Cat to be fully ready time.sleep(2) # Test 1: Message in Server A print("\n" + "="*80) print("TEST SUITE 1: Unified User Identity") print("="*80) test_message( "Hello Miku! I'm in Server A", guild_id="server_a_12345", channel_id="general_111", description="Message in Server A" ) time.sleep(1) test_message( "My favorite color is blue", guild_id="server_a_12345", channel_id="chat_222", description="Share preference in Server A" ) time.sleep(1) # Test 2: Same user in Server B test_message( "Hi Miku! I'm the same person from Server A", guild_id="server_b_67890", channel_id="general_333", description="Message in Server B (should recognize user)" ) time.sleep(1) # Test 3: Same user in DM test_message( "Hey Miku, it's me in a DM now", guild_id=None, channel_id=None, description="Message in DM (should recognize user)" ) time.sleep(1) # Test 4: Miku should remember across contexts test_message( "What's my favorite color?", guild_id="server_b_67890", channel_id="general_333", description="Test cross-server memory recall" ) time.sleep(1) # Test Suite 2: Filtering print("\n" + "="*80) print("TEST SUITE 2: Minimal Filtering") print("="*80) test_message( "lol", guild_id="server_a_12345", channel_id="chat_222", description="Should be filtered (pure reaction)" ) time.sleep(1) test_message( "k", guild_id="server_a_12345", channel_id="chat_222", description="Should be filtered (1-2 chars)" ) time.sleep(1) test_message( "I'm really excited about the upcoming concert!", guild_id="server_a_12345", channel_id="music_444", description="Should be stored (meaningful content)" ) time.sleep(1) # Test Suite 3: Metadata print("\n" + "="*80) print("TEST SUITE 3: Metadata Verification") print("="*80) test_message( "My birthday is coming up next week", guild_id="server_a_12345", channel_id="general_111", description="Important event (should be stored with metadata)" ) time.sleep(1) # Summary print("\n" + "="*80) print("TEST SUMMARY") print("="*80) print("\nโœ… EXPECTED BEHAVIOR:") print(" 1. Same user recognized across Server A, Server B, and DMs") print(" 2. 'lol' and 'k' filtered out (not stored)") print(" 3. Meaningful messages stored with guild_id/channel_id metadata") print(" 4. All memories marked as consolidated=false (pending nightly processing)") print(" 5. Miku remembers 'blue' as favorite color across servers") print("\n๐Ÿ“‹ MANUAL VERIFICATION STEPS:") print(" 1. Check Docker logs:") print(" docker logs miku_cheshire_cat_test | tail -50") print(" 2. Look for:") print(" - '๐Ÿ’พ [Discord Bridge] Storing memory' for kept messages") print(" - '๐Ÿ—‘๏ธ [Discord Bridge] Skipping trivial' for filtered messages") print(" - '๐Ÿง  [Discord Bridge] Recalled X memories' for memory retrieval") print(" 3. Verify Miku responded appropriately to 'What's my favorite color?'") print("\n๐Ÿ” CHECK MEMORIES:") get_memories() print("\nโœจ Phase 1 testing complete!") print("\nNext steps:") print(" 1. Review logs to confirm filtering works") print(" 2. Verify metadata is attached to memories") print(" 3. Confirm unified user identity works (same user across contexts)") print(" 4. Move to Phase 2: Implement nightly consolidation") if __name__ == "__main__": main()