# Architecture Overview This document provides a comprehensive overview of the Daemon Boyfriend Discord bot architecture. ## Table of Contents - [High-Level Architecture](#high-level-architecture) - [Directory Structure](#directory-structure) - [Core Components](#core-components) - [Data Flow](#data-flow) - [Design Patterns](#design-patterns) - [Component Interaction Diagram](#component-interaction-diagram) --- ## High-Level Architecture ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ Discord API │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Discord Bot (bot.py) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ AIChatCog │ │ MemoryCog │ │ StatusCog │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ ┌───────────────────────┐ ┌─────────────────┐ ┌─────────────────────────────┐ │ Core Services │ │ Living AI │ │ AI Providers │ │ ┌─────────────────┐ │ │ Services │ │ ┌─────────────────────┐ │ │ │ UserService │ │ │ ┌───────────┐ │ │ │ OpenAI Provider │ │ │ │ DatabaseService│ │ │ │ MoodSvc │ │ │ │ OpenRouter Provider│ │ │ │ ConversationMgr│ │ │ │ RelSvc │ │ │ │ Anthropic Provider │ │ │ │ SearXNGService │ │ │ │ FactSvc │ │ │ │ Gemini Provider │ │ │ └─────────────────┘ │ │ │ OpinionSvc│ │ │ └─────────────────────┘ │ └───────────────────────┘ │ │ StyleSvc │ │ └─────────────────────────────┘ │ │ ProactSvc │ │ │ │ AssocSvc │ │ │ │ SelfAware │ │ │ └───────────┘ │ └─────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ PostgreSQL Database │ │ ┌──────────────────────────────┐ ┌──────────────────────────────────────┐ │ │ │ Core Tables │ │ Living AI Tables │ │ │ │ users, guilds, conversations │ │ bot_states, user_relationships, │ │ │ │ messages, user_facts │ │ mood_history, scheduled_events │ │ │ └──────────────────────────────┘ └──────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## Directory Structure ``` daemon-boyfriend/ ├── src/daemon_boyfriend/ │ ├── __main__.py # Entry point │ ├── bot.py # Discord bot setup & cog loading │ ├── config.py # Pydantic settings configuration │ │ │ ├── cogs/ # Discord command handlers │ │ ├── ai_chat.py # @mention response handler │ │ ├── memory.py # Memory management commands │ │ └── status.py # Bot status & health commands │ │ │ ├── models/ # SQLAlchemy ORM models │ │ ├── base.py # Base model with PortableJSON │ │ ├── user.py # User, UserFact, UserPreference │ │ ├── conversation.py # Conversation, Message │ │ ├── guild.py # Guild, GuildMember │ │ └── living_ai.py # All Living AI models │ │ │ └── services/ # Business logic layer │ ├── ai_service.py # AI provider factory │ ├── database.py # Database connection management │ ├── user_service.py # User CRUD operations │ ├── conversation.py # In-memory conversation manager │ ├── persistent_conversation.py # DB-backed conversations │ ├── searxng.py # Web search integration │ ├── monitoring.py # Health & metrics tracking │ │ │ ├── providers/ # AI provider implementations │ │ ├── base.py # Abstract AIProvider │ │ ├── openai.py │ │ ├── openrouter.py │ │ ├── anthropic.py │ │ └── gemini.py │ │ │ └── [Living AI Services] │ ├── mood_service.py │ ├── relationship_service.py │ ├── fact_extraction_service.py │ ├── opinion_service.py │ ├── communication_style_service.py │ ├── proactive_service.py │ ├── association_service.py │ └── self_awareness_service.py │ ├── alembic/ # Database migrations ├── tests/ # Test suite ├── schema.sql # Database schema definition ├── docker-compose.yml # Docker deployment └── requirements.txt # Python dependencies ``` --- ## Core Components ### 1. Discord Bot Layer The bot uses [discord.py](https://discordpy.readthedocs.io/) with a cog-based architecture. **Entry Point (`__main__.py`)** - Creates the bot instance - Initializes database connection - Starts the Discord event loop **Bot Setup (`bot.py`)** - Configures Discord intents - Auto-loads all cogs from `cogs/` directory - Handles bot lifecycle events **Cogs** | Cog | Purpose | Trigger | |-----|---------|---------| | `AIChatCog` | Main conversation handler | `@mention` | | `MemoryCog` | User memory management | `!setname`, `!remember`, etc. | | `StatusCog` | Health & metrics | `!status` (admin) | ### 2. Service Layer Services contain all business logic and are designed to be: - **Stateless**: No instance state, all state in database - **Async-first**: All I/O operations are async - **Testable**: Accept database sessions as parameters **Core Services** | Service | Responsibility | |---------|----------------| | `AIService` | Factory for AI providers, prompt enhancement | | `DatabaseService` | Connection pool, session management | | `UserService` | User CRUD, facts, preferences | | `ConversationManager` | In-memory conversation history | | `PersistentConversationManager` | Database-backed conversations | | `SearXNGService` | Web search for current information | | `MonitoringService` | Health checks, metrics, error tracking | **Living AI Services** (see [Living AI documentation](living-ai/README.md)) | Service | Responsibility | |---------|----------------| | `MoodService` | Emotional state management | | `RelationshipService` | User relationship tracking | | `FactExtractionService` | Autonomous fact learning | | `OpinionService` | Topic sentiment tracking | | `CommunicationStyleService` | User style preferences | | `ProactiveService` | Scheduled events & follow-ups | | `AssociationService` | Cross-user memory linking | | `SelfAwarenessService` | Bot statistics & reflection | ### 3. AI Provider Layer Uses the **Provider Pattern** to support multiple AI backends. ``` ┌────────────────────────────────────────────────────────────┐ │ AIService │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ get_provider() → returns appropriate AIProvider │ │ │ │ chat() → builds context and calls provider.generate │ │ │ └─────────────────────────────────────────────────────┘ │ └────────────────────────────────────────────────────────────┘ │ ┌─────────────────┼─────────────────┐ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ OpenAI Provider │ │ Anthropic Provider│ │ Gemini Provider │ │ (+ OpenRouter) │ │ │ │ │ └──────────────────┘ └──────────────────┘ └──────────────────┘ ``` ### 4. Data Layer **Models** (`models/`) - SQLAlchemy ORM with async support - `PortableJSON` type for PostgreSQL/SQLite compatibility - Timezone-aware UTC timestamps **Database** (`services/database.py`) - Async PostgreSQL via `asyncpg` - Connection pooling - Graceful fallback to in-memory when no database --- ## Data Flow ### Message Processing Flow ``` 1. User sends @mention in Discord │ ▼ 2. AIChatCog.on_message() receives event │ ▼ 3. Get or create User via UserService │ ▼ 4. Get or create Conversation (PersistentConversationManager or ConversationManager) │ ▼ 5. Build conversation history from messages │ ▼ 6. [Optional] Check if web search needed └─► SearXNGService.search() → add results to context │ ▼ 7. Apply Living AI enhancements: ├─► MoodService.get_current_mood() ├─► RelationshipService.get_relationship() ├─► CommunicationStyleService.get_style() └─► OpinionService.get_relevant_opinions() │ ▼ 8. Build enhanced system prompt with all context │ ▼ 9. AIService.chat() → Provider.generate() │ ▼ 10. Post-response processing: ├─► MoodService.update_mood() ├─► RelationshipService.record_interaction() ├─► CommunicationStyleService.record_message() ├─► FactExtractionService.maybe_extract_facts() └─► ProactiveService.check_for_events() │ ▼ 11. Split response if > 2000 chars │ ▼ 12. Send response(s) to Discord ``` ### Database Fallback Flow ``` ┌─────────────────────────────────────────────────┐ │ Application Start │ └─────────────────────────────────────────────────┘ │ ▼ ┌────────────────────────┐ │ DATABASE_URL set? │ └────────────────────────┘ │ │ Yes No │ │ ▼ ▼ ┌───────────────────┐ ┌───────────────────────┐ │ PostgreSQL Mode │ │ In-Memory Mode │ │ - Full persistence│ │ - ConversationManager │ │ - Living AI state │ │ - No persistence │ │ - User facts │ │ - Basic functionality │ └───────────────────┘ └───────────────────────┘ ``` --- ## Design Patterns ### 1. Provider Pattern (AI Services) Abstract base class with multiple implementations. ```python # base.py class AIProvider(ABC): @abstractmethod async def generate( self, messages: list[Message], system_prompt: str | None = None, max_tokens: int = 1024, temperature: float = 0.7, ) -> AIResponse: pass # openai.py class OpenAIProvider(AIProvider): async def generate(...) -> AIResponse: # OpenAI-specific implementation ``` ### 2. Factory Pattern (AIService) Creates the appropriate provider based on configuration. ```python class AIService: def __init__(self): self.provider = self._create_provider() def _create_provider(self) -> AIProvider: match settings.ai_provider: case "openai": return OpenAIProvider() case "anthropic": return AnthropicProvider() # ... ``` ### 3. Repository Pattern (Services) Services encapsulate data access logic. ```python class UserService: @staticmethod async def get_user(session: AsyncSession, discord_id: int) -> User | None: result = await session.execute( select(User).where(User.discord_id == discord_id) ) return result.scalar_one_or_none() ``` ### 4. Cog Pattern (Discord.py) Modular command grouping. ```python class MemoryCog(commands.Cog): def __init__(self, bot): self.bot = bot @commands.command(name="setname") async def set_name(self, ctx, *, name: str): # Command implementation ``` ### 5. Graceful Degradation System works with reduced functionality when components unavailable. ```python # Database fallback if settings.database_url: conversation_manager = PersistentConversationManager() else: conversation_manager = ConversationManager() # In-memory # Feature toggles if settings.living_ai_enabled and settings.mood_enabled: mood = await MoodService.get_current_mood(session, guild_id) else: mood = None ``` --- ## Component Interaction Diagram ``` ┌──────────────────────────────────────────┐ │ User Message │ └──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────────────┐ │ AIChatCog │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ UserService │ │ Conversation│ │ SearXNG │ │ AIService │ │ │ │ │ │ Manager │ │ Service │ │ │ │ │ │ get_user() │ │ get_history │ │ search() │ │ chat() ──────────┐ │ │ │ │ get_context │ │ add_message │ │ │ │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └──────────────────│──┘ │ │ │ │ │ ┌────────────────────────────────────────────────────────────────────┼────┐ │ │ │ Living AI Services │ │ │ │ │ │ │ │ │ │ ┌───────────┐ ┌──────────────┐ ┌───────────────┐ ┌────────────┐ │ │ │ │ │ │ MoodSvc │ │ Relationship │ │ CommStyleSvc │ │ OpinionSvc │ │ │ │ │ │ │ │ │ Svc │ │ │ │ │ │ │ │ │ │ │get_mood() │ │get_relation()│ │ get_style() │ │get_opinions│ │ │ │ │ │ │update() │ │record() │ │ record() │ │ update() │ │ │ │ │ │ └───────────┘ └──────────────┘ └───────────────┘ └────────────┘ │ │ │ │ │ │ │ │ │ │ ┌───────────────┐ ┌────────────────┐ ┌───────────────────────┐ │ │ │ │ │ │ FactExtract │ │ ProactiveSvc │ │ SelfAwarenessSvc │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ extract() │ │ detect_events()│ │ get_stats() │ │ │ │ │ │ └───────────────┘ └────────────────┘ └───────────────────────┘ │ │ │ │ └────────────────────────────────────────────────────────────────────│────┘ │ │ │ │ └────────────────────────────────────────────────────────────────────────│──────┘ │ ▼ ┌──────────────────────────────────────────────┐ │ AI Provider │ │ (OpenAI / Anthropic / Gemini / OpenRouter) │ └──────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────┐ │ Response │ └──────────────────────────────────────────────┘ ``` --- ## Next Steps - [Living AI System](living-ai/README.md) - Deep dive into the personality system - [Services Reference](services/README.md) - Detailed API documentation - [Database Schema](database.md) - Complete schema documentation - [Configuration Reference](configuration.md) - All configuration options - [Developer Guides](guides/README.md) - How to extend the system