- Add PostgreSQL database with SQLAlchemy async support - Create models: User, UserFact, UserPreference, Conversation, Message, Guild, GuildMember - Add custom name support so bot knows 'who is who' - Add user facts system for remembering things about users - Add persistent conversation history that survives restarts - Add memory commands cog (!setname, !remember, !whatdoyouknow, !forgetme) - Add admin commands (!setusername, !teachbot) - Set up Alembic for database migrations - Update docker-compose with PostgreSQL service - Gracefully falls back to in-memory storage when DB not configured
97 lines
4.1 KiB
Markdown
97 lines
4.1 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Build & Run Commands
|
|
|
|
```bash
|
|
# Install dependencies
|
|
pip install -r requirements.txt
|
|
|
|
# Run the bot (requires .env with DISCORD_TOKEN and AI provider key)
|
|
python -m daemon_boyfriend
|
|
|
|
# Run with Docker (includes PostgreSQL)
|
|
docker-compose up -d
|
|
|
|
# Run database migrations
|
|
alembic upgrade head
|
|
|
|
# Syntax check all Python files
|
|
python -m py_compile src/daemon_boyfriend/**/*.py
|
|
```
|
|
|
|
## Architecture
|
|
|
|
This is a Discord bot that responds to @mentions with AI-generated responses (multi-provider support).
|
|
|
|
### Provider Pattern
|
|
The AI system uses a provider abstraction pattern:
|
|
- `services/providers/base.py` defines `AIProvider` abstract class with `generate()` method
|
|
- `services/providers/openai.py`, `openrouter.py`, `anthropic.py`, `gemini.py` implement the interface
|
|
- `services/ai_service.py` is the factory that creates the correct provider based on `AI_PROVIDER` env var
|
|
- OpenRouter uses OpenAI's client with a different base URL
|
|
- Gemini uses the `google-genai` SDK
|
|
|
|
### Cog System
|
|
Discord functionality is in `cogs/`:
|
|
- `ai_chat.py` - `@mention` handler (responds when bot is mentioned)
|
|
- `memory.py` - Memory management commands (`!setname`, `!remember`, etc.)
|
|
- `status.py` - Bot health and status commands
|
|
|
|
Cogs are auto-loaded by `bot.py` from the `cogs/` directory.
|
|
|
|
### Database & Memory System
|
|
The bot uses PostgreSQL for persistent memory (optional, falls back to in-memory):
|
|
- `models/` - SQLAlchemy models (User, UserFact, Conversation, Message, Guild, GuildMember)
|
|
- `services/database.py` - Connection pool and async session management
|
|
- `services/user_service.py` - User CRUD, custom names, facts management
|
|
- `services/persistent_conversation.py` - Database-backed conversation history
|
|
- `alembic/` - Database migrations
|
|
|
|
Key features:
|
|
- Custom names: Set preferred names for users so the bot knows "who is who"
|
|
- User facts: Bot remembers things about users (hobbies, preferences, etc.)
|
|
- Persistent conversations: Chat history survives restarts
|
|
- Conversation timeout: New conversation starts after 60 minutes of inactivity
|
|
|
|
### Configuration
|
|
All config flows through `config.py` using pydantic-settings. The `settings` singleton is created at module load, so env vars must be set before importing.
|
|
|
|
### Web Search
|
|
The bot can search the web for current information via SearXNG:
|
|
- `services/searxng.py` provides `SearXNGService` for web queries
|
|
- `ai_chat.py` uses a two-step approach: first asks AI if search is needed, then provides results as context
|
|
- Search is triggered automatically when the AI determines the query needs current information
|
|
- Configured via `SEARXNG_URL`, `SEARXNG_ENABLED`, and `SEARXNG_MAX_RESULTS` env vars
|
|
|
|
### Key Design Decisions
|
|
- `PersistentConversationManager` stores conversations in PostgreSQL when `DATABASE_URL` is set
|
|
- `ConversationManager` is the in-memory fallback when database is not configured
|
|
- Long AI responses are split via `split_message()` in `ai_chat.py` to respect Discord's 2000 char limit
|
|
- The bot responds only to @mentions via `on_message` listener
|
|
- Web search uses AI to decide when to search, avoiding unnecessary API calls for general knowledge questions
|
|
- User context (custom name + known facts) is included in AI prompts for personalized responses
|
|
|
|
## Environment Variables
|
|
|
|
Required: `DISCORD_TOKEN`, plus one of `OPENAI_API_KEY`, `OPENROUTER_API_KEY`, `ANTHROPIC_API_KEY`, or `GEMINI_API_KEY` depending on `AI_PROVIDER` setting.
|
|
|
|
Optional:
|
|
- `DATABASE_URL` - PostgreSQL connection string (e.g., `postgresql+asyncpg://user:pass@host:5432/db`)
|
|
- `POSTGRES_PASSWORD` - Used by docker-compose for the PostgreSQL container
|
|
- `SEARXNG_URL` - SearXNG instance URL for web search capability
|
|
|
|
## Memory Commands
|
|
|
|
User commands:
|
|
- `!setname <name>` - Set your preferred name
|
|
- `!clearname` - Reset to Discord display name
|
|
- `!remember <fact>` - Tell the bot something about you
|
|
- `!whatdoyouknow` - See what the bot remembers about you
|
|
- `!forgetme` - Clear all facts about you
|
|
|
|
Admin commands:
|
|
- `!setusername @user <name>` - Set name for another user
|
|
- `!teachbot @user <fact>` - Add a fact about a user
|