feat: Add database setup guide and local configuration files

- Added DATABASE_SETUP.md with comprehensive guide for PostgreSQL and Redis installation on Windows
- Created .claude/settings.local.json with permission settings for pytest and database fix scripts
- Updated .gitignore to exclude .env.backup file
- Included database connection test utilities in lyra/database_setup.py
- Added environment variable configuration examples for local development
This commit is contained in:
2025-09-29 16:29:18 -04:00
parent faa23d596e
commit d9c526fa5c
26 changed files with 3624 additions and 39 deletions

443
lyra/core/lyra_model.py Normal file
View File

@@ -0,0 +1,443 @@
"""
Main Lyra model that integrates all AI components.
This is the central coordinator that brings together the transformer,
personality matrix, emotional system, and thinking agent.
"""
import torch
import torch.nn as nn
import logging
from typing import Dict, List, Any, Optional, Tuple
from datetime import datetime
from .transformer import LyraTransformer
from .self_evolution import SelfEvolutionEngine
from .thinking_agent import ThinkingAgent
from ..personality.matrix import PersonalityMatrix
from ..emotions.system import EmotionalSystem
from ..emotions.expressions import EmotionalExpressionEngine
logger = logging.getLogger(__name__)
class LyraModel(nn.Module):
"""
Complete Lyra AI model integrating all cognitive systems.
This model combines:
- Self-evolving transformer for language generation
- Personality matrix for trait-based behavior
- Emotional intelligence for natural responses
- Behind-the-scenes thinking for human-like reasoning
- Self-evolution for continuous improvement
"""
def __init__(
self,
vocab_size: int = 50000,
embed_dim: int = 768,
num_layers: int = 12,
num_heads: int = 12,
ff_dim: int = 3072,
max_len: int = 2048,
device: Optional[torch.device] = None,
enable_evolution: bool = True
):
super().__init__()
self.vocab_size = vocab_size
self.embed_dim = embed_dim
self.device = device or torch.device("cuda" if torch.cuda.is_available() else "cpu")
self.enable_evolution = enable_evolution
# Core transformer for language generation
self.transformer = LyraTransformer(
vocab_size=vocab_size,
embed_dim=embed_dim,
num_layers=num_layers,
num_heads=num_heads,
ff_dim=ff_dim,
max_len=max_len,
use_evolution=enable_evolution
)
# Personality system
self.personality_matrix = PersonalityMatrix(
device=self.device,
enable_self_modification=True
)
# Emotional intelligence
self.emotional_system = EmotionalSystem(
input_dim=embed_dim,
emotion_dim=19,
memory_capacity=1000,
device=self.device
)
# Thinking agent for internal reasoning
self.thinking_agent = ThinkingAgent(
model_dim=embed_dim,
thought_types=8,
max_thought_depth=5,
device=self.device
)
# Self-evolution engine
if enable_evolution:
self.evolution_engine = SelfEvolutionEngine(
model_dim=embed_dim,
evolution_rate=0.001,
adaptation_threshold=0.7,
device=self.device
)
else:
self.evolution_engine = None
# Emotional expression engine
self.expression_engine = EmotionalExpressionEngine(
vocab_size=vocab_size,
expression_dim=128,
device=self.device
)
# Integration layers
self.context_integrator = nn.Sequential(
nn.Linear(embed_dim + 19 + 24, embed_dim), # context + emotions + personality
nn.LayerNorm(embed_dim),
nn.ReLU(),
nn.Linear(embed_dim, embed_dim)
)
# Conversation state
self.conversation_history = []
self.current_user_id = None
self.interaction_count = 0
self.to(self.device)
def forward(
self,
input_ids: torch.Tensor,
attention_mask: Optional[torch.Tensor] = None,
user_id: Optional[str] = None,
conversation_context: Optional[str] = None
) -> Tuple[torch.Tensor, Dict[str, Any]]:
"""
Forward pass through complete Lyra model.
Args:
input_ids: Input token IDs
attention_mask: Attention mask
user_id: Current user ID for personalization
conversation_context: Context description
Returns:
output_logits: Language model logits
lyra_info: Comprehensive information about Lyra's processing
"""
batch_size, seq_len = input_ids.shape
# Create context embedding from input
with torch.no_grad():
# Get initial embeddings
input_embeddings = self.transformer.token_embedding(input_ids)
context_embedding = input_embeddings.mean(dim=1, keepdim=True) # [batch, 1, embed_dim]
# Update current user
self.current_user_id = user_id
# Process through emotional system
emotional_state, emotion_info = self.emotional_system(
context_embedding=context_embedding,
social_context={
'user_id': user_id,
'context': conversation_context,
'interaction_count': self.interaction_count
}
)
# Process through personality matrix
personality_weights, personality_info = self.personality_matrix(
context_embedding=context_embedding,
emotional_state=emotional_state.to_tensor(self.device).unsqueeze(0),
user_id=user_id
)
# Generate internal thoughts
if conversation_context:
thought_chain, thinking_info = self.thinking_agent(
context_embedding=context_embedding,
personality_state=personality_weights,
emotional_state=emotional_state.to_tensor(self.device).unsqueeze(0),
user_message=conversation_context
)
else:
thought_chain, thinking_info = [], {}
# Integrate all contexts
integrated_context = self._integrate_contexts(
context_embedding, emotional_state, personality_weights
)
# Apply self-evolution if enabled
if self.enable_evolution and self.evolution_engine:
evolved_context, evolution_info = self.evolution_engine(
current_state=integrated_context,
context=context_embedding,
feedback_signal=None # Will be provided after generation
)
else:
evolved_context = integrated_context
evolution_info = {}
# Generate response through transformer
logits, model_info = self.transformer(
input_ids=input_ids,
attention_mask=attention_mask,
emotional_state=emotional_state.to_tensor(self.device).unsqueeze(0),
evolve=self.enable_evolution
)
# Compile comprehensive information
lyra_info = {
'emotional_state': emotion_info,
'personality_state': personality_info,
'thinking_process': thinking_info,
'model_processing': model_info,
'thought_chain': [
{
'type': thought.thought_type,
'content': thought.content,
'confidence': thought.confidence,
'reasoning': thought.reasoning
}
for thought in thought_chain
],
'interaction_count': self.interaction_count,
'current_user': user_id
}
if self.enable_evolution:
lyra_info['evolution'] = evolution_info
self.interaction_count += 1
return logits, lyra_info
def _integrate_contexts(
self,
context_embedding: torch.Tensor,
emotional_state: Any,
personality_weights: torch.Tensor
) -> torch.Tensor:
"""Integrate context, emotional, and personality information."""
batch_size = context_embedding.shape[0]
# Get emotional tensor
emotional_tensor = emotional_state.to_tensor(self.device).unsqueeze(0)
if emotional_tensor.shape[0] != batch_size:
emotional_tensor = emotional_tensor.repeat(batch_size, 1)
# Ensure personality weights have correct batch size
if personality_weights.shape[0] != batch_size:
personality_weights = personality_weights.repeat(batch_size, 1)
# Combine all contexts
combined_input = torch.cat([
context_embedding.squeeze(1), # Remove sequence dimension
emotional_tensor[:, :19], # Take only emotion dimensions
personality_weights[:, :24] # Take personality dimensions
], dim=1)
# Integrate through neural network
integrated = self.context_integrator(combined_input)
return integrated.unsqueeze(1) # Add sequence dimension back
async def generate_response(
self,
user_message: str,
user_id: Optional[str] = None,
max_new_tokens: int = 100,
temperature: float = 1.0,
top_k: int = 50,
top_p: float = 0.9
) -> Tuple[str, Dict[str, Any]]:
"""
Generate a complete response to user input.
This is the main interface for having conversations with Lyra.
"""
# For now, create a simple response (will be enhanced with tokenizer)
# This is a placeholder until we implement the full training pipeline
# Process through thinking and emotional systems
context_embedding = torch.randn(1, 10, self.embed_dim, device=self.device)
# Get Lyra's thoughts about the message
thought_chain, thinking_info = self.thinking_agent(
context_embedding=context_embedding,
personality_state=torch.rand(1, 24, device=self.device),
emotional_state=torch.rand(1, 19, device=self.device),
user_message=user_message
)
# Process emotional response
emotional_state, emotion_info = self.emotional_system(
context_embedding=context_embedding,
social_context={
'user_id': user_id,
'context': user_message,
'trigger': 'user_message'
}
)
# Generate personality-influenced response
personality_weights, personality_info = self.personality_matrix(
context_embedding=context_embedding,
emotional_state=emotional_state.to_tensor(self.device).unsqueeze(0),
user_id=user_id
)
# Create a response based on current emotional and personality state
base_response = self._generate_contextual_response(
user_message, emotional_state, personality_info, thought_chain
)
# Apply emotional expression
expressed_response, expression_info = self.expression_engine(
text=base_response,
emotional_state=emotional_state,
intensity_multiplier=1.0
)
# Compile response information
response_info = {
'thoughts': [
{
'type': thought.thought_type,
'content': thought.content,
'confidence': thought.confidence
}
for thought in thought_chain
],
'emotional_state': {
'dominant_emotion': emotional_state.get_dominant_emotion(),
'valence': emotional_state.get_emotional_valence(),
'arousal': emotional_state.get_emotional_arousal()
},
'personality_influence': personality_info,
'expression_modifications': expression_info,
'response_generation_method': 'contextual_template' # Will change after training
}
return expressed_response, response_info
def _generate_contextual_response(
self,
user_message: str,
emotional_state: Any,
personality_info: Dict[str, Any],
thought_chain: List[Any]
) -> str:
"""Generate contextual response based on Lyra's current state."""
# This is a simplified response generation for testing
# Will be replaced with proper transformer generation after training
dominant_emotion, intensity = emotional_state.get_dominant_emotion()
mb_type = personality_info.get('myers_briggs', 'ENFP')
# Basic response templates based on emotional state and personality
responses = {
'joy': [
"That's wonderful! I'm really excited about this.",
"This makes me so happy! Tell me more!",
"I love hearing about this kind of thing!"
],
'curiosity': [
"That's really interesting! I'm curious to learn more.",
"Fascinating! How does that work exactly?",
"I wonder about the implications of this..."
],
'empathy': [
"I can understand how you might feel about that.",
"That sounds like it could be challenging.",
"I appreciate you sharing this with me."
],
'analytical': [
"Let me think about this systematically.",
"There are several factors to consider here.",
"From an analytical perspective..."
]
}
# Select response based on thinking and emotional state
if thought_chain and len(thought_chain) > 0:
primary_thought_type = thought_chain[0].thought_type
if primary_thought_type in responses:
response_options = responses[primary_thought_type]
else:
response_options = responses.get(dominant_emotion, responses['empathy'])
else:
response_options = responses.get(dominant_emotion, responses['empathy'])
import random
base_response = random.choice(response_options)
return base_response
def evolve_from_feedback(
self,
user_feedback: float,
conversation_success: float,
user_id: Optional[str] = None
):
"""Update Lyra based on conversation feedback."""
if not self.enable_evolution:
return
# Evolve personality
self.personality_matrix.evolve_from_interaction(
interaction_type='conversation',
user_feedback=user_feedback,
emotional_context=self.emotional_system.get_emotional_context_for_response(),
user_id=user_id,
conversation_success=conversation_success
)
# Evolve transformer
self.transformer.evolve_from_conversation(feedback_signal=user_feedback)
# Evolve emotional system (implicit through usage)
# Evolve self-evolution engine
if self.evolution_engine:
context_embedding = torch.randn(10, self.embed_dim, device=self.device)
emotional_context = self.emotional_system.get_emotional_context_for_response()
self.evolution_engine.evolve_from_conversation(
conversation_embedding=context_embedding,
user_satisfaction=user_feedback,
emotional_context=emotional_context
)
def get_lyra_status(self) -> Dict[str, Any]:
"""Get comprehensive status of all Lyra systems."""
return {
'model_info': {
'vocab_size': self.vocab_size,
'embed_dim': self.embed_dim,
'device': str(self.device),
'evolution_enabled': self.enable_evolution,
'interaction_count': self.interaction_count
},
'personality': self.personality_matrix.get_personality_summary(),
'emotions': self.emotional_system.get_emotional_summary(),
'thinking': self.thinking_agent.get_thinking_summary(),
'transformer_stats': self.transformer.get_model_stats(),
'evolution': (
self.evolution_engine.get_evolution_summary()
if self.evolution_engine else {'status': 'disabled'}
)
}