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:
2026-01-14 18:08:35 +01:00
parent 3d939201f0
commit dbd534d860
60 changed files with 310 additions and 381 deletions

View File

@@ -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