fix: Make tests pass and update documentation
- Fix config.py to ignore extra environment variables (docker-compose compatibility) - Create PortableJSON type for SQLite/PostgreSQL compatibility in tests - Replace JSONB and ARRAY types with PortableJSON in models - Add ensure_utc() helper to handle timezone-naive datetimes from SQLite - Fix timezone issues in mood_service, relationship_service, and self_awareness_service - Fix duplicate code in test_providers.py - Update CLAUDE.md with comprehensive Living AI documentation - Add testing section with commands and setup details - All 112 tests now pass successfully
This commit is contained in:
103
CLAUDE.md
103
CLAUDE.md
@@ -8,6 +8,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Install in development mode (required for testing)
|
||||
pip install -e .
|
||||
|
||||
# Run the bot (requires .env with DISCORD_TOKEN and AI provider key)
|
||||
python -m daemon_boyfriend
|
||||
|
||||
@@ -21,9 +24,33 @@ alembic upgrade head
|
||||
python -m py_compile src/daemon_boyfriend/**/*.py
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Install dev dependencies
|
||||
pip install -e ".[dev]"
|
||||
|
||||
# Run all tests
|
||||
python -m pytest tests/ -v
|
||||
|
||||
# Run tests with coverage
|
||||
python -m pytest tests/ --cov=daemon_boyfriend --cov-report=term-missing
|
||||
|
||||
# Run specific test file
|
||||
python -m pytest tests/test_models.py -v
|
||||
|
||||
# Run specific test class
|
||||
python -m pytest tests/test_services.py::TestMoodService -v
|
||||
```
|
||||
|
||||
The test suite uses:
|
||||
- `pytest` with `pytest-asyncio` for async test support
|
||||
- SQLite in-memory database for testing (via `aiosqlite`)
|
||||
- Mock fixtures for Discord objects and AI providers in `tests/conftest.py`
|
||||
|
||||
## Architecture
|
||||
|
||||
This is a Discord bot that responds to @mentions with AI-generated responses (multi-provider support).
|
||||
This is a Discord bot that responds to @mentions with AI-generated responses (multi-provider support). It features a "Living AI" system that gives the bot personality, mood, and relationship tracking.
|
||||
|
||||
### Provider Pattern
|
||||
The AI system uses a provider abstraction pattern:
|
||||
@@ -44,6 +71,7 @@ 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)
|
||||
- `models/living_ai.py` - Living AI models (BotState, BotOpinion, UserRelationship, etc.)
|
||||
- `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
|
||||
@@ -55,6 +83,42 @@ Key features:
|
||||
- Persistent conversations: Chat history survives restarts
|
||||
- Conversation timeout: New conversation starts after 60 minutes of inactivity
|
||||
|
||||
### Living AI System
|
||||
The bot implements a "Living AI" system with emotional depth and relationship tracking:
|
||||
|
||||
#### Services (`services/`)
|
||||
- `mood_service.py` - Valence-arousal mood model with time decay
|
||||
- `relationship_service.py` - Relationship scoring (stranger to close friend)
|
||||
- `fact_extraction_service.py` - Autonomous fact learning from conversations
|
||||
- `opinion_service.py` - Bot develops opinions on topics over time
|
||||
- `self_awareness_service.py` - Bot statistics and self-reflection
|
||||
- `communication_style_service.py` - Learns user communication preferences
|
||||
- `proactive_service.py` - Scheduled events (birthdays, follow-ups)
|
||||
- `association_service.py` - Cross-user memory associations
|
||||
|
||||
#### Models (`models/living_ai.py`)
|
||||
- `BotState` - Global mood state and statistics per guild
|
||||
- `BotOpinion` - Topic sentiments and preferences
|
||||
- `UserRelationship` - Per-user relationship scores and metrics
|
||||
- `UserCommunicationStyle` - Learned communication preferences
|
||||
- `ScheduledEvent` - Birthdays, follow-ups, reminders
|
||||
- `FactAssociation` - Cross-user memory links
|
||||
- `MoodHistory` - Mood changes over time
|
||||
|
||||
#### Mood System
|
||||
Uses a valence-arousal model:
|
||||
- Valence: -1 (sad) to +1 (happy)
|
||||
- Arousal: -1 (calm) to +1 (excited)
|
||||
- Labels: excited, happy, calm, neutral, bored, annoyed, curious
|
||||
- Time decay: Mood gradually returns to neutral
|
||||
|
||||
#### Relationship Levels
|
||||
- Stranger (0-20): Polite, formal
|
||||
- Acquaintance (21-40): Friendly but reserved
|
||||
- Friend (41-60): Casual, warm
|
||||
- Good Friend (61-80): Personal, references past talks
|
||||
- Close Friend (81-100): Very casual, inside jokes
|
||||
|
||||
### 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.
|
||||
|
||||
@@ -72,6 +136,8 @@ The bot can search the web for current information via SearXNG:
|
||||
- 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
|
||||
- `PortableJSON` type in `models/base.py` allows models to work with both PostgreSQL (JSONB) and SQLite (JSON)
|
||||
- `ensure_utc()` helper handles timezone-naive datetimes from SQLite
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@@ -82,15 +148,44 @@ Optional:
|
||||
- `POSTGRES_PASSWORD` - Used by docker-compose for the PostgreSQL container
|
||||
- `SEARXNG_URL` - SearXNG instance URL for web search capability
|
||||
|
||||
## Memory Commands
|
||||
### Living AI Configuration
|
||||
- `LIVING_AI_ENABLED` - Master switch for Living AI features (default: true)
|
||||
- `MOOD_ENABLED` - Enable mood system (default: true)
|
||||
- `RELATIONSHIP_ENABLED` - Enable relationship tracking (default: true)
|
||||
- `FACT_EXTRACTION_ENABLED` - Enable autonomous fact extraction (default: true)
|
||||
- `FACT_EXTRACTION_RATE` - Probability of extracting facts (default: 0.3)
|
||||
- `PROACTIVE_ENABLED` - Enable proactive messages (default: true)
|
||||
- `CROSS_USER_ENABLED` - Enable cross-user memory associations (default: false)
|
||||
- `OPINION_FORMATION_ENABLED` - Enable bot opinion formation (default: true)
|
||||
- `STYLE_LEARNING_ENABLED` - Enable communication style learning (default: true)
|
||||
- `MOOD_DECAY_RATE` - How fast mood returns to neutral per hour (default: 0.1)
|
||||
|
||||
User commands:
|
||||
### Command Toggles
|
||||
- `COMMANDS_ENABLED` - Master switch for all commands (default: true)
|
||||
- `CMD_RELATIONSHIP_ENABLED` - Enable `!relationship` command
|
||||
- `CMD_MOOD_ENABLED` - Enable `!mood` command
|
||||
- `CMD_BOTSTATS_ENABLED` - Enable `!botstats` command
|
||||
- `CMD_OURHISTORY_ENABLED` - Enable `!ourhistory` command
|
||||
- `CMD_BIRTHDAY_ENABLED` - Enable `!birthday` command
|
||||
- `CMD_REMEMBER_ENABLED` - Enable `!remember` command
|
||||
- `CMD_SETNAME_ENABLED` - Enable `!setname` command
|
||||
- `CMD_WHATDOYOUKNOW_ENABLED` - Enable `!whatdoyouknow` command
|
||||
- `CMD_FORGETME_ENABLED` - Enable `!forgetme` command
|
||||
|
||||
## 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
|
||||
- `!relationship` - See your relationship level with the bot
|
||||
- `!mood` - See the bot's current emotional state
|
||||
- `!botstats` - Bot shares its self-awareness statistics
|
||||
- `!ourhistory` - See your history with the bot
|
||||
- `!birthday <date>` - Set your birthday for the bot to remember
|
||||
|
||||
Admin commands:
|
||||
### Admin commands
|
||||
- `!setusername @user <name>` - Set name for another user
|
||||
- `!teachbot @user <fact>` - Add a fact about a user
|
||||
|
||||
Reference in New Issue
Block a user