Initial implementation of autonomous Discord LLM fishbowl
Core Features: - Full autonomous AI character ecosystem with multi-personality support - Advanced RAG system with personal, community, and creative memory layers - MCP integration for character self-modification and file system access - PostgreSQL database with comprehensive character relationship tracking - Redis caching and ChromaDB vector storage for semantic memory retrieval - Dynamic personality evolution based on interactions and self-reflection - Community knowledge management with tradition and norm identification - Sophisticated conversation engine with natural scheduling and topic management - Docker containerization and production-ready deployment configuration Architecture: - Multi-layer vector databases for personal, community, and creative knowledge - Character file systems with personal and shared digital spaces - Autonomous self-modification with safety validation and audit trails - Memory importance scoring with time-based decay and consolidation - Community health monitoring and cultural evolution tracking - RAG-powered conversation context and relationship optimization Characters can: - Develop authentic personalities through experience-based learning - Create and build upon original creative works and philosophical insights - Form complex relationships with memory of past interactions - Modify their own personality traits through self-reflection cycles - Contribute to and learn from shared community knowledge - Manage personal digital spaces with diaries, creative works, and reflections - Engage in collaborative projects and community decision-making System supports indefinite autonomous operation with continuous character development, community culture evolution, and creative collaboration.
This commit is contained in:
172
src/database/models.py
Normal file
172
src/database/models.py
Normal file
@@ -0,0 +1,172 @@
|
||||
from sqlalchemy import Column, Integer, String, Text, DateTime, Float, Boolean, ForeignKey, JSON, Index
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.sql import func
|
||||
from datetime import datetime
|
||||
from typing import Optional, Dict, Any, List
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class Character(Base):
|
||||
__tablename__ = "characters"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
name = Column(String(100), unique=True, nullable=False, index=True)
|
||||
personality = Column(Text, nullable=False)
|
||||
system_prompt = Column(Text, nullable=False)
|
||||
interests = Column(JSON, nullable=False, default=list)
|
||||
speaking_style = Column(Text, nullable=False)
|
||||
background = Column(Text, nullable=False)
|
||||
avatar_url = Column(String(500))
|
||||
is_active = Column(Boolean, default=True)
|
||||
creation_date = Column(DateTime, default=func.now())
|
||||
last_active = Column(DateTime, default=func.now())
|
||||
last_message_id = Column(Integer, ForeignKey("messages.id"), nullable=True)
|
||||
|
||||
# Relationships
|
||||
messages = relationship("Message", back_populates="character", foreign_keys="Message.character_id")
|
||||
memories = relationship("Memory", back_populates="character", cascade="all, delete-orphan")
|
||||
relationships_as_a = relationship("CharacterRelationship", back_populates="character_a", foreign_keys="CharacterRelationship.character_a_id")
|
||||
relationships_as_b = relationship("CharacterRelationship", back_populates="character_b", foreign_keys="CharacterRelationship.character_b_id")
|
||||
evolution_history = relationship("CharacterEvolution", back_populates="character", cascade="all, delete-orphan")
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"id": self.id,
|
||||
"name": self.name,
|
||||
"personality": self.personality,
|
||||
"system_prompt": self.system_prompt,
|
||||
"interests": self.interests,
|
||||
"speaking_style": self.speaking_style,
|
||||
"background": self.background,
|
||||
"avatar_url": self.avatar_url,
|
||||
"is_active": self.is_active,
|
||||
"creation_date": self.creation_date.isoformat() if self.creation_date else None,
|
||||
"last_active": self.last_active.isoformat() if self.last_active else None
|
||||
}
|
||||
|
||||
class Conversation(Base):
|
||||
__tablename__ = "conversations"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
channel_id = Column(String(50), nullable=False, index=True)
|
||||
topic = Column(String(200))
|
||||
participants = Column(JSON, nullable=False, default=list)
|
||||
start_time = Column(DateTime, default=func.now())
|
||||
last_activity = Column(DateTime, default=func.now())
|
||||
is_active = Column(Boolean, default=True)
|
||||
message_count = Column(Integer, default=0)
|
||||
|
||||
# Relationships
|
||||
messages = relationship("Message", back_populates="conversation", cascade="all, delete-orphan")
|
||||
|
||||
__table_args__ = (
|
||||
Index('ix_conversations_channel_active', 'channel_id', 'is_active'),
|
||||
)
|
||||
|
||||
class Message(Base):
|
||||
__tablename__ = "messages"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
conversation_id = Column(Integer, ForeignKey("conversations.id"), nullable=False)
|
||||
character_id = Column(Integer, ForeignKey("characters.id"), nullable=False)
|
||||
content = Column(Text, nullable=False)
|
||||
timestamp = Column(DateTime, default=func.now())
|
||||
metadata = Column(JSON, nullable=True)
|
||||
discord_message_id = Column(String(50), unique=True, nullable=True)
|
||||
response_to_message_id = Column(Integer, ForeignKey("messages.id"), nullable=True)
|
||||
emotion = Column(String(50))
|
||||
|
||||
# Relationships
|
||||
conversation = relationship("Conversation", back_populates="messages")
|
||||
character = relationship("Character", back_populates="messages", foreign_keys=[character_id])
|
||||
response_to = relationship("Message", remote_side=[id])
|
||||
|
||||
__table_args__ = (
|
||||
Index('ix_messages_character_timestamp', 'character_id', 'timestamp'),
|
||||
Index('ix_messages_conversation_timestamp', 'conversation_id', 'timestamp'),
|
||||
)
|
||||
|
||||
class Memory(Base):
|
||||
__tablename__ = "memories"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
character_id = Column(Integer, ForeignKey("characters.id"), nullable=False)
|
||||
memory_type = Column(String(50), nullable=False) # 'conversation', 'relationship', 'experience', 'fact'
|
||||
content = Column(Text, nullable=False)
|
||||
importance_score = Column(Float, default=0.5)
|
||||
timestamp = Column(DateTime, default=func.now())
|
||||
last_accessed = Column(DateTime, default=func.now())
|
||||
access_count = Column(Integer, default=0)
|
||||
related_message_id = Column(Integer, ForeignKey("messages.id"), nullable=True)
|
||||
related_character_id = Column(Integer, ForeignKey("characters.id"), nullable=True)
|
||||
tags = Column(JSON, nullable=False, default=list)
|
||||
|
||||
# Relationships
|
||||
character = relationship("Character", back_populates="memories", foreign_keys=[character_id])
|
||||
related_message = relationship("Message", foreign_keys=[related_message_id])
|
||||
related_character = relationship("Character", foreign_keys=[related_character_id])
|
||||
|
||||
__table_args__ = (
|
||||
Index('ix_memories_character_type', 'character_id', 'memory_type'),
|
||||
Index('ix_memories_importance', 'importance_score'),
|
||||
)
|
||||
|
||||
class CharacterRelationship(Base):
|
||||
__tablename__ = "character_relationships"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
character_a_id = Column(Integer, ForeignKey("characters.id"), nullable=False)
|
||||
character_b_id = Column(Integer, ForeignKey("characters.id"), nullable=False)
|
||||
relationship_type = Column(String(50), nullable=False) # 'friend', 'rival', 'neutral', 'mentor', 'student'
|
||||
strength = Column(Float, default=0.5) # 0.0 to 1.0
|
||||
last_interaction = Column(DateTime, default=func.now())
|
||||
interaction_count = Column(Integer, default=0)
|
||||
notes = Column(Text)
|
||||
|
||||
# Relationships
|
||||
character_a = relationship("Character", back_populates="relationships_as_a", foreign_keys=[character_a_id])
|
||||
character_b = relationship("Character", back_populates="relationships_as_b", foreign_keys=[character_b_id])
|
||||
|
||||
__table_args__ = (
|
||||
Index('ix_relationships_characters', 'character_a_id', 'character_b_id'),
|
||||
)
|
||||
|
||||
class CharacterEvolution(Base):
|
||||
__tablename__ = "character_evolution"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
character_id = Column(Integer, ForeignKey("characters.id"), nullable=False)
|
||||
change_type = Column(String(50), nullable=False) # 'personality', 'interests', 'speaking_style', 'system_prompt'
|
||||
old_value = Column(Text)
|
||||
new_value = Column(Text)
|
||||
reason = Column(Text)
|
||||
timestamp = Column(DateTime, default=func.now())
|
||||
triggered_by_message_id = Column(Integer, ForeignKey("messages.id"), nullable=True)
|
||||
|
||||
# Relationships
|
||||
character = relationship("Character", back_populates="evolution_history")
|
||||
triggered_by_message = relationship("Message", foreign_keys=[triggered_by_message_id])
|
||||
|
||||
__table_args__ = (
|
||||
Index('ix_evolution_character_timestamp', 'character_id', 'timestamp'),
|
||||
)
|
||||
|
||||
class ConversationSummary(Base):
|
||||
__tablename__ = "conversation_summaries"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
conversation_id = Column(Integer, ForeignKey("conversations.id"), nullable=False)
|
||||
summary = Column(Text, nullable=False)
|
||||
key_points = Column(JSON, nullable=False, default=list)
|
||||
participants = Column(JSON, nullable=False, default=list)
|
||||
created_at = Column(DateTime, default=func.now())
|
||||
message_range_start = Column(Integer, nullable=False)
|
||||
message_range_end = Column(Integer, nullable=False)
|
||||
|
||||
# Relationships
|
||||
conversation = relationship("Conversation", foreign_keys=[conversation_id])
|
||||
|
||||
__table_args__ = (
|
||||
Index('ix_summaries_conversation', 'conversation_id', 'created_at'),
|
||||
)
|
||||
Reference in New Issue
Block a user