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.
172 lines
7.8 KiB
Python
172 lines
7.8 KiB
Python
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'),
|
|
) |