feat: Implement Living AI system

Complete implementation of the Living AI features:

Phase 1 - Foundation:
- MoodService: Valence-arousal mood model with time decay
- RelationshipService: Stranger→Close Friend progression
- Enhanced system prompt with personality modifiers

Phase 2 - Autonomous Learning:
- FactExtractionService: AI-powered fact extraction from conversations
- Rate-limited extraction (configurable, default 30%)
- Deduplication and importance scoring

Phase 3 - Personalization:
- CommunicationStyleService: Learn user preferences
- OpinionService: Bot opinion formation on topics
- SelfAwarenessService: Bot statistics and self-reflection

Phase 4 - Proactive Features:
- ProactiveService: Scheduled events (birthdays, follow-ups)
- Event detection from conversations
- Recurring event support

Phase 5 - Social Features:
- AssociationService: Cross-user memory connections
- Shared interest discovery
- Connection suggestions

New database tables:
- bot_states, bot_opinions, user_relationships
- user_communication_styles, scheduled_events
- fact_associations, mood_history

Configuration:
- Living AI feature toggles
- Individual command enable/disable
- All features work naturally through conversation when commands disabled
This commit is contained in:
2026-01-12 19:51:48 +01:00
parent 7d2fab57c4
commit 0d43b5b29a
17 changed files with 3524 additions and 4 deletions

View File

@@ -11,6 +11,7 @@ from .base import Base
if TYPE_CHECKING:
from .conversation import Conversation, Message
from .guild import GuildMember
from .living_ai import ScheduledEvent, UserCommunicationStyle, UserRelationship
class User(Base):
@@ -42,6 +43,17 @@ class User(Base):
back_populates="user", cascade="all, delete-orphan"
)
# Living AI relationships
relationships: Mapped[list["UserRelationship"]] = relationship(
back_populates="user", cascade="all, delete-orphan"
)
communication_style: Mapped["UserCommunicationStyle | None"] = relationship(
back_populates="user", cascade="all, delete-orphan", uselist=False
)
scheduled_events: Mapped[list["ScheduledEvent"]] = relationship(
back_populates="user", cascade="all, delete-orphan"
)
@property
def display_name(self) -> str:
"""Get the name to use when addressing this user."""