refactor: Transform daemon_boyfriend into Loyal Companion
Rebrand and personalize the bot as 'Bartender' - a companion for those who love deeply and feel intensely. Major changes: - Rename package: daemon_boyfriend -> loyal_companion - New default personality: Bartender - wise, steady, non-judgmental - Grief-aware system prompt (no toxic positivity, attachment-informed) - New relationship levels: New Face -> Close Friend progression - Bartender-style mood modifiers (steady presence) - New fact types: attachment_pattern, grief_context, coping_mechanism - Lower mood decay (0.05) for emotional stability - Higher fact extraction rate (0.4) - Bartender pays attention Updated all imports, configs, Docker files, and documentation.
This commit is contained in:
@@ -142,7 +142,7 @@ OPENAI_API_KEY=your_key
|
||||
### 3. Run
|
||||
|
||||
```bash
|
||||
python -m daemon_boyfriend
|
||||
python -m loyal_companion
|
||||
```
|
||||
|
||||
### 4. Interact
|
||||
|
||||
@@ -61,8 +61,8 @@ This document provides a comprehensive overview of the Daemon Boyfriend Discord
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
daemon-boyfriend/
|
||||
├── src/daemon_boyfriend/
|
||||
loyal-companion/
|
||||
├── src/loyal_companion/
|
||||
│ ├── __main__.py # Entry point
|
||||
│ ├── bot.py # Discord bot setup & cog loading
|
||||
│ ├── config.py # Pydantic settings configuration
|
||||
|
||||
@@ -172,7 +172,7 @@ Custom system prompt. If not set, one is generated from `BOT_NAME` and `BOT_PERS
|
||||
### DATABASE_URL
|
||||
|
||||
```bash
|
||||
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/daemon_boyfriend
|
||||
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/loyal_companion
|
||||
```
|
||||
|
||||
**Default:** `None` (in-memory mode)
|
||||
@@ -453,7 +453,7 @@ Logging verbosity level.
|
||||
### LOG_FILE
|
||||
|
||||
```bash
|
||||
LOG_FILE=/var/log/daemon_boyfriend.log
|
||||
LOG_FILE=/var/log/loyal_companion.log
|
||||
```
|
||||
|
||||
**Default:** `None` (console only)
|
||||
@@ -522,7 +522,7 @@ BOT_STATUS=for @mentions
|
||||
# DATABASE (Optional - runs in-memory if not set)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
DATABASE_URL=postgresql+asyncpg://daemon:password@localhost:5432/daemon_boyfriend
|
||||
DATABASE_URL=postgresql+asyncpg://daemon:password@localhost:5432/loyal_companion
|
||||
# DATABASE_ECHO=false
|
||||
# DATABASE_POOL_SIZE=5
|
||||
# DATABASE_MAX_OVERFLOW=10
|
||||
@@ -579,7 +579,7 @@ COMMANDS_ENABLED=true
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
LOG_LEVEL=INFO
|
||||
# LOG_FILE=/var/log/daemon_boyfriend.log
|
||||
# LOG_FILE=/var/log/loyal_companion.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -32,7 +32,7 @@ This document describes the database schema used by Daemon Boyfriend.
|
||||
|
||||
```bash
|
||||
# PostgreSQL connection string
|
||||
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/daemon_boyfriend
|
||||
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/loyal_companion
|
||||
|
||||
# Optional settings
|
||||
DATABASE_ECHO=false # Log SQL queries
|
||||
@@ -499,7 +499,7 @@ All indexes are created with `IF NOT EXISTS` for idempotency.
|
||||
### From Code
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.database import db
|
||||
from loyal_companion.services.database import db
|
||||
|
||||
# Initialize connection
|
||||
await db.init()
|
||||
@@ -512,10 +512,10 @@ await db.create_tables()
|
||||
|
||||
```bash
|
||||
# Create database
|
||||
createdb daemon_boyfriend
|
||||
createdb loyal_companion
|
||||
|
||||
# Run schema
|
||||
psql -U postgres -d daemon_boyfriend -f schema.sql
|
||||
psql -U postgres -d loyal_companion -f schema.sql
|
||||
```
|
||||
|
||||
### Docker
|
||||
@@ -552,7 +552,7 @@ alembic downgrade -1
|
||||
For JSONB (PostgreSQL) and JSON (SQLite) compatibility:
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.models.base import PortableJSON
|
||||
from loyal_companion.models.base import PortableJSON
|
||||
|
||||
class MyModel(Base):
|
||||
settings = Column(PortableJSON, default={})
|
||||
@@ -563,7 +563,7 @@ class MyModel(Base):
|
||||
Handles timezone-naive datetimes from SQLite:
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.models.base import ensure_utc
|
||||
from loyal_companion.models.base import ensure_utc
|
||||
|
||||
# Safe for both PostgreSQL (already UTC) and SQLite (naive)
|
||||
utc_time = ensure_utc(model.created_at)
|
||||
|
||||
@@ -27,7 +27,7 @@ Practical guides for extending and working with the Daemon Boyfriend codebase.
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone <repository-url>
|
||||
cd daemon-boyfriend
|
||||
cd loyal-companion
|
||||
|
||||
# Create virtual environment
|
||||
python -m venv venv
|
||||
@@ -61,7 +61,7 @@ OPENAI_API_KEY=your_key
|
||||
|
||||
```bash
|
||||
# Run the bot
|
||||
python -m daemon_boyfriend
|
||||
python -m loyal_companion
|
||||
|
||||
# Or with Docker
|
||||
docker-compose up -d
|
||||
@@ -73,7 +73,7 @@ docker-compose up -d
|
||||
|
||||
### Step 1: Create Provider Class
|
||||
|
||||
Create `src/daemon_boyfriend/services/providers/new_provider.py`:
|
||||
Create `src/loyal_companion/services/providers/new_provider.py`:
|
||||
|
||||
```python
|
||||
"""New Provider implementation."""
|
||||
@@ -197,7 +197,7 @@ class Settings(BaseSettings):
|
||||
# In tests/test_providers.py
|
||||
|
||||
import pytest
|
||||
from daemon_boyfriend.services.providers import NewProvider
|
||||
from loyal_companion.services.providers import NewProvider
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_new_provider():
|
||||
@@ -250,8 +250,8 @@ import logging
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
from daemon_boyfriend.config import settings
|
||||
from daemon_boyfriend.services.database import db
|
||||
from loyal_companion.config import settings
|
||||
from loyal_companion.services.database import db
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -313,7 +313,7 @@ from datetime import datetime, timezone
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from daemon_boyfriend.models import User
|
||||
from loyal_companion.models import User
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -399,7 +399,7 @@ class Settings(BaseSettings):
|
||||
```python
|
||||
# In cogs/ai_chat.py
|
||||
|
||||
from daemon_boyfriend.services.new_feature_service import NewFeatureService
|
||||
from loyal_companion.services.new_feature_service import NewFeatureService
|
||||
|
||||
class AIChatCog(commands.Cog):
|
||||
async def _build_enhanced_prompt(self, ...):
|
||||
@@ -427,7 +427,7 @@ pip install -e ".[dev]"
|
||||
python -m pytest tests/ -v
|
||||
|
||||
# Run with coverage
|
||||
python -m pytest tests/ --cov=daemon_boyfriend --cov-report=term-missing
|
||||
python -m pytest tests/ --cov=loyal_companion --cov-report=term-missing
|
||||
|
||||
# Run specific test file
|
||||
python -m pytest tests/test_models.py -v
|
||||
@@ -442,7 +442,7 @@ python -m pytest tests/test_services.py::TestMoodService -v
|
||||
# In tests/test_new_feature.py
|
||||
|
||||
import pytest
|
||||
from daemon_boyfriend.services.new_feature_service import NewFeatureService
|
||||
from loyal_companion.services.new_feature_service import NewFeatureService
|
||||
|
||||
|
||||
class TestNewFeatureService:
|
||||
@@ -517,7 +517,7 @@ docker-compose down
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Run with process manager (e.g., systemd)
|
||||
# Create /etc/systemd/system/daemon-boyfriend.service:
|
||||
# Create /etc/systemd/system/loyal-companion.service:
|
||||
|
||||
[Unit]
|
||||
Description=Daemon Boyfriend Discord Bot
|
||||
@@ -526,10 +526,10 @@ After=network.target postgresql.service
|
||||
[Service]
|
||||
Type=simple
|
||||
User=daemon
|
||||
WorkingDirectory=/opt/daemon-boyfriend
|
||||
Environment="PATH=/opt/daemon-boyfriend/venv/bin"
|
||||
EnvironmentFile=/opt/daemon-boyfriend/.env
|
||||
ExecStart=/opt/daemon-boyfriend/venv/bin/python -m daemon_boyfriend
|
||||
WorkingDirectory=/opt/loyal-companion
|
||||
Environment="PATH=/opt/loyal-companion/venv/bin"
|
||||
EnvironmentFile=/opt/loyal-companion/.env
|
||||
ExecStart=/opt/loyal-companion/venv/bin/python -m loyal_companion
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
@@ -539,18 +539,18 @@ WantedBy=multi-user.target
|
||||
|
||||
```bash
|
||||
# Enable and start
|
||||
sudo systemctl enable daemon-boyfriend
|
||||
sudo systemctl start daemon-boyfriend
|
||||
sudo systemctl enable loyal-companion
|
||||
sudo systemctl start loyal-companion
|
||||
```
|
||||
|
||||
### Database Setup
|
||||
|
||||
```bash
|
||||
# Create database
|
||||
sudo -u postgres createdb daemon_boyfriend
|
||||
sudo -u postgres createdb loyal_companion
|
||||
|
||||
# Run schema
|
||||
psql -U postgres -d daemon_boyfriend -f schema.sql
|
||||
psql -U postgres -d loyal_companion -f schema.sql
|
||||
|
||||
# Or let the bot create tables
|
||||
# (tables are created automatically on first run)
|
||||
|
||||
@@ -328,7 +328,7 @@ class FactExtractionService:
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.fact_extraction_service import FactExtractionService
|
||||
from loyal_companion.services.fact_extraction_service import FactExtractionService
|
||||
|
||||
async with get_session() as session:
|
||||
fact_service = FactExtractionService(session, ai_service)
|
||||
|
||||
@@ -311,7 +311,7 @@ class MoodState:
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.mood_service import MoodService
|
||||
from loyal_companion.services.mood_service import MoodService
|
||||
|
||||
async with get_session() as session:
|
||||
mood_service = MoodService(session)
|
||||
|
||||
@@ -322,7 +322,7 @@ def extract_topics_from_message(message: str) -> list[str]
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.opinion_service import (
|
||||
from loyal_companion.services.opinion_service import (
|
||||
OpinionService,
|
||||
extract_topics_from_message
|
||||
)
|
||||
|
||||
@@ -334,7 +334,7 @@ class RelationshipLevel(Enum):
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.relationship_service import RelationshipService
|
||||
from loyal_companion.services.relationship_service import RelationshipService
|
||||
|
||||
async with get_session() as session:
|
||||
rel_service = RelationshipService(session)
|
||||
|
||||
@@ -28,8 +28,8 @@ Factory and facade for AI providers. Manages provider creation, switching, and p
|
||||
#### Initialization
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.ai_service import AIService
|
||||
from daemon_boyfriend.config import settings
|
||||
from loyal_companion.services.ai_service import AIService
|
||||
from loyal_companion.config import settings
|
||||
|
||||
# Use default settings
|
||||
ai_service = AIService()
|
||||
@@ -53,7 +53,7 @@ ai_service = AIService(config=custom_settings)
|
||||
Generate a chat response.
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.providers import Message
|
||||
from loyal_companion.services.providers import Message
|
||||
|
||||
response = await ai_service.chat(
|
||||
messages=[
|
||||
@@ -109,7 +109,7 @@ Manages database connections and sessions.
|
||||
#### Global Instance
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.database import db, get_db
|
||||
from loyal_companion.services.database import db, get_db
|
||||
|
||||
# Get global instance
|
||||
db_service = get_db()
|
||||
@@ -170,7 +170,7 @@ Service for user-related operations.
|
||||
#### Initialization
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.user_service import UserService
|
||||
from loyal_companion.services.user_service import UserService
|
||||
|
||||
async with db.session() as session:
|
||||
user_service = UserService(session)
|
||||
@@ -297,7 +297,7 @@ In-memory conversation history manager (used when no database).
|
||||
#### Initialization
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.conversation import ConversationManager
|
||||
from loyal_companion.services.conversation import ConversationManager
|
||||
|
||||
conversation_manager = ConversationManager(max_history=50)
|
||||
```
|
||||
@@ -397,7 +397,7 @@ Web search integration using SearXNG.
|
||||
#### Initialization
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.searxng import SearXNGService
|
||||
from loyal_companion.services.searxng import SearXNGService
|
||||
|
||||
searxng = SearXNGService()
|
||||
```
|
||||
@@ -444,7 +444,7 @@ Health checks and metrics tracking.
|
||||
#### Usage
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.monitoring import MonitoringService
|
||||
from loyal_companion.services.monitoring import MonitoringService
|
||||
|
||||
monitoring = MonitoringService()
|
||||
|
||||
@@ -479,7 +479,7 @@ print(status)
|
||||
### Base Classes
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.providers import (
|
||||
from loyal_companion.services.providers import (
|
||||
AIProvider, # Abstract base class
|
||||
Message, # Chat message
|
||||
AIResponse, # Response from provider
|
||||
@@ -541,7 +541,7 @@ class AIProvider(ABC):
|
||||
### Example: Direct Provider Usage
|
||||
|
||||
```python
|
||||
from daemon_boyfriend.services.providers import OpenAIProvider, Message
|
||||
from loyal_companion.services.providers import OpenAIProvider, Message
|
||||
|
||||
provider = OpenAIProvider(
|
||||
api_key="sk-...",
|
||||
|
||||
Reference in New Issue
Block a user