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:
@@ -11,8 +11,8 @@ from sqlalchemy import event
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||
from sqlalchemy.pool import StaticPool
|
||||
|
||||
from daemon_boyfriend.config import Settings
|
||||
from daemon_boyfriend.models.base import Base
|
||||
from loyal_companion.config import Settings
|
||||
from loyal_companion.models.base import Base
|
||||
|
||||
# --- Event Loop Fixture ---
|
||||
|
||||
@@ -140,7 +140,7 @@ def mock_discord_bot() -> MagicMock:
|
||||
@pytest.fixture
|
||||
def mock_ai_response() -> MagicMock:
|
||||
"""Create a mock AI response."""
|
||||
from daemon_boyfriend.services.providers.base import AIResponse
|
||||
from loyal_companion.services.providers.base import AIResponse
|
||||
|
||||
return AIResponse(
|
||||
content="This is a test response from the AI.",
|
||||
@@ -207,7 +207,7 @@ def mock_gemini_client() -> MagicMock:
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_user(db_session: AsyncSession):
|
||||
"""Create a sample user in the database."""
|
||||
from daemon_boyfriend.models import User
|
||||
from loyal_companion.models import User
|
||||
|
||||
user = User(
|
||||
discord_id=123456789,
|
||||
@@ -223,7 +223,7 @@ async def sample_user(db_session: AsyncSession):
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_user_with_facts(db_session: AsyncSession, sample_user):
|
||||
"""Create a sample user with facts."""
|
||||
from daemon_boyfriend.models import UserFact
|
||||
from loyal_companion.models import UserFact
|
||||
|
||||
facts = [
|
||||
UserFact(
|
||||
@@ -252,7 +252,7 @@ async def sample_user_with_facts(db_session: AsyncSession, sample_user):
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_conversation(db_session: AsyncSession, sample_user):
|
||||
"""Create a sample conversation."""
|
||||
from daemon_boyfriend.models import Conversation
|
||||
from loyal_companion.models import Conversation
|
||||
|
||||
conversation = Conversation(
|
||||
user_id=sample_user.id,
|
||||
@@ -268,7 +268,7 @@ async def sample_conversation(db_session: AsyncSession, sample_user):
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_bot_state(db_session: AsyncSession):
|
||||
"""Create a sample bot state."""
|
||||
from daemon_boyfriend.models import BotState
|
||||
from loyal_companion.models import BotState
|
||||
|
||||
bot_state = BotState(
|
||||
guild_id=111222333,
|
||||
@@ -284,7 +284,7 @@ async def sample_bot_state(db_session: AsyncSession):
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_user_relationship(db_session: AsyncSession, sample_user):
|
||||
"""Create a sample user relationship."""
|
||||
from daemon_boyfriend.models import UserRelationship
|
||||
from loyal_companion.models import UserRelationship
|
||||
|
||||
relationship = UserRelationship(
|
||||
user_id=sample_user.id,
|
||||
|
||||
@@ -4,7 +4,7 @@ from datetime import datetime, timedelta, timezone
|
||||
|
||||
import pytest
|
||||
|
||||
from daemon_boyfriend.models import (
|
||||
from loyal_companion.models import (
|
||||
BotOpinion,
|
||||
BotState,
|
||||
Conversation,
|
||||
@@ -20,7 +20,7 @@ from daemon_boyfriend.models import (
|
||||
UserPreference,
|
||||
UserRelationship,
|
||||
)
|
||||
from daemon_boyfriend.models.base import utc_now
|
||||
from loyal_companion.models.base import utc_now
|
||||
|
||||
|
||||
class TestUtcNow:
|
||||
|
||||
@@ -4,16 +4,16 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from daemon_boyfriend.services.providers.anthropic import AnthropicProvider
|
||||
from daemon_boyfriend.services.providers.base import (
|
||||
from loyal_companion.services.providers.anthropic import AnthropicProvider
|
||||
from loyal_companion.services.providers.base import (
|
||||
AIProvider,
|
||||
AIResponse,
|
||||
ImageAttachment,
|
||||
Message,
|
||||
)
|
||||
from daemon_boyfriend.services.providers.gemini import GeminiProvider
|
||||
from daemon_boyfriend.services.providers.openai import OpenAIProvider
|
||||
from daemon_boyfriend.services.providers.openrouter import OpenRouterProvider
|
||||
from loyal_companion.services.providers.gemini import GeminiProvider
|
||||
from loyal_companion.services.providers.openai import OpenAIProvider
|
||||
from loyal_companion.services.providers.openrouter import OpenRouterProvider
|
||||
|
||||
|
||||
class TestMessage:
|
||||
@@ -69,7 +69,7 @@ class TestOpenAIProvider:
|
||||
@pytest.fixture
|
||||
def provider(self, mock_openai_client):
|
||||
"""Create an OpenAI provider with mocked client."""
|
||||
with patch("daemon_boyfriend.services.providers.openai.AsyncOpenAI") as mock_class:
|
||||
with patch("loyal_companion.services.providers.openai.AsyncOpenAI") as mock_class:
|
||||
mock_class.return_value = mock_openai_client
|
||||
provider = OpenAIProvider(api_key="test_key", model="gpt-4o-mini")
|
||||
provider.client = mock_openai_client
|
||||
@@ -143,7 +143,7 @@ class TestAnthropicProvider:
|
||||
def provider(self, mock_anthropic_client):
|
||||
"""Create an Anthropic provider with mocked client."""
|
||||
with patch(
|
||||
"daemon_boyfriend.services.providers.anthropic.anthropic.AsyncAnthropic"
|
||||
"loyal_companion.services.providers.anthropic.anthropic.AsyncAnthropic"
|
||||
) as mock_class:
|
||||
mock_class.return_value = mock_anthropic_client
|
||||
provider = AnthropicProvider(api_key="test_key", model="claude-sonnet-4-20250514")
|
||||
@@ -200,7 +200,7 @@ class TestGeminiProvider:
|
||||
@pytest.fixture
|
||||
def provider(self, mock_gemini_client):
|
||||
"""Create a Gemini provider with mocked client."""
|
||||
with patch("daemon_boyfriend.services.providers.gemini.genai.Client") as mock_class:
|
||||
with patch("loyal_companion.services.providers.gemini.genai.Client") as mock_class:
|
||||
mock_class.return_value = mock_gemini_client
|
||||
provider = GeminiProvider(api_key="test_key", model="gemini-2.0-flash")
|
||||
provider.client = mock_gemini_client
|
||||
@@ -248,7 +248,7 @@ class TestOpenRouterProvider:
|
||||
@pytest.fixture
|
||||
def provider(self, mock_openai_client):
|
||||
"""Create an OpenRouter provider with mocked client."""
|
||||
with patch("daemon_boyfriend.services.providers.openrouter.AsyncOpenAI") as mock_class:
|
||||
with patch("loyal_companion.services.providers.openrouter.AsyncOpenAI") as mock_class:
|
||||
mock_class.return_value = mock_openai_client
|
||||
provider = OpenRouterProvider(api_key="test_key", model="openai/gpt-4o")
|
||||
provider.client = mock_openai_client
|
||||
|
||||
@@ -5,7 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from daemon_boyfriend.models import (
|
||||
from loyal_companion.models import (
|
||||
BotOpinion,
|
||||
BotState,
|
||||
Conversation,
|
||||
@@ -14,14 +14,14 @@ from daemon_boyfriend.models import (
|
||||
UserFact,
|
||||
UserRelationship,
|
||||
)
|
||||
from daemon_boyfriend.services.ai_service import AIService
|
||||
from daemon_boyfriend.services.fact_extraction_service import FactExtractionService
|
||||
from daemon_boyfriend.services.mood_service import MoodLabel, MoodService, MoodState
|
||||
from daemon_boyfriend.services.opinion_service import OpinionService, extract_topics_from_message
|
||||
from daemon_boyfriend.services.persistent_conversation import PersistentConversationManager
|
||||
from daemon_boyfriend.services.relationship_service import RelationshipLevel, RelationshipService
|
||||
from daemon_boyfriend.services.self_awareness_service import SelfAwarenessService
|
||||
from daemon_boyfriend.services.user_service import UserService
|
||||
from loyal_companion.services.ai_service import AIService
|
||||
from loyal_companion.services.fact_extraction_service import FactExtractionService
|
||||
from loyal_companion.services.mood_service import MoodLabel, MoodService, MoodState
|
||||
from loyal_companion.services.opinion_service import OpinionService, extract_topics_from_message
|
||||
from loyal_companion.services.persistent_conversation import PersistentConversationManager
|
||||
from loyal_companion.services.relationship_service import RelationshipLevel, RelationshipService
|
||||
from loyal_companion.services.self_awareness_service import SelfAwarenessService
|
||||
from loyal_companion.services.user_service import UserService
|
||||
|
||||
|
||||
class TestUserService:
|
||||
@@ -577,8 +577,8 @@ class TestAIService:
|
||||
|
||||
def test_get_system_prompt_default(self, mock_settings):
|
||||
"""Test getting default system prompt."""
|
||||
with patch("daemon_boyfriend.services.ai_service.settings", mock_settings):
|
||||
with patch("daemon_boyfriend.services.ai_service.AIService._init_provider"):
|
||||
with patch("loyal_companion.services.ai_service.settings", mock_settings):
|
||||
with patch("loyal_companion.services.ai_service.AIService._init_provider"):
|
||||
service = AIService(mock_settings)
|
||||
service._provider = MagicMock()
|
||||
|
||||
@@ -590,8 +590,8 @@ class TestAIService:
|
||||
def test_get_system_prompt_custom(self, mock_settings):
|
||||
"""Test getting custom system prompt."""
|
||||
mock_settings.system_prompt = "Custom prompt"
|
||||
with patch("daemon_boyfriend.services.ai_service.settings", mock_settings):
|
||||
with patch("daemon_boyfriend.services.ai_service.AIService._init_provider"):
|
||||
with patch("loyal_companion.services.ai_service.settings", mock_settings):
|
||||
with patch("loyal_companion.services.ai_service.AIService._init_provider"):
|
||||
service = AIService(mock_settings)
|
||||
service._provider = MagicMock()
|
||||
|
||||
@@ -601,8 +601,8 @@ class TestAIService:
|
||||
|
||||
def test_provider_name(self, mock_settings):
|
||||
"""Test getting provider name."""
|
||||
with patch("daemon_boyfriend.services.ai_service.settings", mock_settings):
|
||||
with patch("daemon_boyfriend.services.ai_service.AIService._init_provider"):
|
||||
with patch("loyal_companion.services.ai_service.settings", mock_settings):
|
||||
with patch("loyal_companion.services.ai_service.AIService._init_provider"):
|
||||
service = AIService(mock_settings)
|
||||
mock_provider = MagicMock()
|
||||
mock_provider.provider_name = "openai"
|
||||
@@ -612,8 +612,8 @@ class TestAIService:
|
||||
|
||||
def test_model_property(self, mock_settings):
|
||||
"""Test getting model name."""
|
||||
with patch("daemon_boyfriend.services.ai_service.settings", mock_settings):
|
||||
with patch("daemon_boyfriend.services.ai_service.AIService._init_provider"):
|
||||
with patch("loyal_companion.services.ai_service.settings", mock_settings):
|
||||
with patch("loyal_companion.services.ai_service.AIService._init_provider"):
|
||||
service = AIService(mock_settings)
|
||||
service._provider = MagicMock()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user