Fix comprehensive system issues and implement proper vector database backend selection
- Fix remaining datetime timezone errors across all database operations - Implement dynamic vector database backend (Qdrant/ChromaDB) based on install.py configuration - Add LLM timeout handling with immediate fallback responses for slow self-hosted models - Use proper install.py configuration (2000 max tokens, 5min timeout, correct LLM endpoint) - Fix PostgreSQL schema to use timezone-aware columns throughout - Implement async LLM request handling with background processing - Add configurable prompt limits and conversation history controls - Start missing database services (PostgreSQL, Redis) automatically - Fix environment variable mapping between install.py and application code - Resolve all timezone-naive vs timezone-aware datetime conflicts System now properly uses Qdrant vector database as specified in install.py instead of hardcoded ChromaDB. Characters respond immediately with fallback messages during long LLM processing times. All database timezone errors resolved with proper timestamptz columns.
This commit is contained in:
@@ -2,7 +2,7 @@ import asyncio
|
||||
import random
|
||||
import json
|
||||
from typing import Dict, Any, List, Optional, Set, Tuple
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from dataclasses import dataclass, asdict
|
||||
from enum import Enum
|
||||
import logging
|
||||
@@ -44,9 +44,9 @@ class ConversationContext:
|
||||
if self.participants is None:
|
||||
self.participants = []
|
||||
if self.start_time is None:
|
||||
self.start_time = datetime.utcnow()
|
||||
self.start_time = datetime.now(timezone.utc)
|
||||
if self.last_activity is None:
|
||||
self.last_activity = datetime.utcnow()
|
||||
self.last_activity = datetime.now(timezone.utc)
|
||||
|
||||
class ConversationEngine:
|
||||
"""Autonomous conversation engine that manages character interactions"""
|
||||
@@ -89,8 +89,8 @@ class ConversationEngine:
|
||||
'conversations_started': 0,
|
||||
'messages_generated': 0,
|
||||
'characters_active': 0,
|
||||
'uptime_start': datetime.utcnow(),
|
||||
'last_activity': datetime.utcnow()
|
||||
'uptime_start': datetime.now(timezone.utc),
|
||||
'last_activity': datetime.now(timezone.utc)
|
||||
}
|
||||
|
||||
async def initialize(self, discord_bot):
|
||||
@@ -169,7 +169,7 @@ class ConversationEngine:
|
||||
# Update context
|
||||
context.current_speaker = initial_speaker
|
||||
context.message_count = 1
|
||||
context.last_activity = datetime.utcnow()
|
||||
context.last_activity = datetime.now(timezone.utc)
|
||||
|
||||
# Store message in database
|
||||
await self._store_conversation_message(
|
||||
@@ -179,7 +179,7 @@ class ConversationEngine:
|
||||
# Update statistics
|
||||
self.stats['conversations_started'] += 1
|
||||
self.stats['messages_generated'] += 1
|
||||
self.stats['last_activity'] = datetime.utcnow()
|
||||
self.stats['last_activity'] = datetime.now(timezone.utc)
|
||||
|
||||
log_conversation_event(
|
||||
conversation_id, "conversation_started",
|
||||
@@ -230,7 +230,7 @@ class ConversationEngine:
|
||||
# Update context
|
||||
context.current_speaker = next_speaker
|
||||
context.message_count += 1
|
||||
context.last_activity = datetime.utcnow()
|
||||
context.last_activity = datetime.now(timezone.utc)
|
||||
|
||||
# Store message
|
||||
await self._store_conversation_message(
|
||||
@@ -245,7 +245,7 @@ class ConversationEngine:
|
||||
|
||||
# Update statistics
|
||||
self.stats['messages_generated'] += 1
|
||||
self.stats['last_activity'] = datetime.utcnow()
|
||||
self.stats['last_activity'] = datetime.now(timezone.utc)
|
||||
|
||||
log_conversation_event(
|
||||
conversation_id, "message_sent",
|
||||
@@ -379,7 +379,7 @@ class ConversationEngine:
|
||||
|
||||
async def get_status(self) -> Dict[str, Any]:
|
||||
"""Get engine status"""
|
||||
uptime = datetime.utcnow() - self.stats['uptime_start']
|
||||
uptime = datetime.now(timezone.utc) - self.stats['uptime_start']
|
||||
|
||||
return {
|
||||
'status': self.state.value,
|
||||
@@ -402,8 +402,8 @@ class ConversationEngine:
|
||||
# Use EnhancedCharacter if RAG systems are available
|
||||
if self.vector_store and self.memory_sharing_manager:
|
||||
# Find the appropriate MCP servers for this character
|
||||
from mcp.self_modification_server import mcp_server
|
||||
from mcp.file_system_server import filesystem_server
|
||||
from mcp_servers.self_modification_server import mcp_server
|
||||
from mcp_servers.file_system_server import filesystem_server
|
||||
|
||||
# Find creative projects MCP server
|
||||
creative_projects_mcp = None
|
||||
@@ -500,7 +500,7 @@ class ConversationEngine:
|
||||
base_chance = 0.3
|
||||
|
||||
# Increase chance if no recent activity
|
||||
time_since_last = datetime.utcnow() - self.stats['last_activity']
|
||||
time_since_last = datetime.now(timezone.utc) - self.stats['last_activity']
|
||||
if time_since_last > timedelta(hours=2):
|
||||
base_chance += 0.4
|
||||
elif time_since_last > timedelta(hours=1):
|
||||
@@ -515,7 +515,7 @@ class ConversationEngine:
|
||||
return False
|
||||
|
||||
# Check time limit (conversations shouldn't go on forever)
|
||||
duration = datetime.utcnow() - context.start_time
|
||||
duration = datetime.now(timezone.utc) - context.start_time
|
||||
if duration > timedelta(hours=2):
|
||||
return False
|
||||
|
||||
@@ -541,7 +541,7 @@ class ConversationEngine:
|
||||
context = self.active_conversations[conversation_id]
|
||||
|
||||
# Check time since last message
|
||||
time_since_last = datetime.utcnow() - context.last_activity
|
||||
time_since_last = datetime.now(timezone.utc) - context.last_activity
|
||||
min_wait = timedelta(seconds=random.uniform(30, 120))
|
||||
|
||||
return time_since_last >= min_wait
|
||||
@@ -576,7 +576,7 @@ class ConversationEngine:
|
||||
|
||||
def _is_quiet_hours(self) -> bool:
|
||||
"""Check if it's currently quiet hours"""
|
||||
current_hour = datetime.now().hour
|
||||
current_hour = datetime.now(timezone.utc).hour
|
||||
start_hour, end_hour = self.quiet_hours
|
||||
|
||||
if start_hour <= end_hour:
|
||||
@@ -601,8 +601,8 @@ class ConversationEngine:
|
||||
channel_id=str(self.discord_bot.channel_id),
|
||||
topic=topic,
|
||||
participants=participants,
|
||||
start_time=datetime.utcnow(),
|
||||
last_activity=datetime.utcnow(),
|
||||
start_time=datetime.now(timezone.utc),
|
||||
last_activity=datetime.now(timezone.utc),
|
||||
is_active=True,
|
||||
message_count=0
|
||||
)
|
||||
@@ -745,7 +745,7 @@ class ConversationEngine:
|
||||
conversation_id=conversation_id,
|
||||
character_id=character.id,
|
||||
content=content,
|
||||
timestamp=datetime.utcnow()
|
||||
timestamp=datetime.now(timezone.utc)
|
||||
)
|
||||
|
||||
session.add(message)
|
||||
@@ -821,7 +821,7 @@ class ConversationEngine:
|
||||
conversation = await session.get(Conversation, conversation_id)
|
||||
if conversation:
|
||||
conversation.is_active = False
|
||||
conversation.last_activity = datetime.utcnow()
|
||||
conversation.last_activity = datetime.now(timezone.utc)
|
||||
conversation.message_count = context.message_count
|
||||
await session.commit()
|
||||
|
||||
@@ -831,7 +831,7 @@ class ConversationEngine:
|
||||
log_conversation_event(
|
||||
conversation_id, "conversation_ended",
|
||||
context.participants,
|
||||
{"total_messages": context.message_count, "duration": str(datetime.utcnow() - context.start_time)}
|
||||
{"total_messages": context.message_count, "duration": str(datetime.now(timezone.utc) - context.start_time)}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
@@ -854,7 +854,7 @@ class ConversationEngine:
|
||||
async def _cleanup_old_conversations(self):
|
||||
"""Clean up old inactive conversations"""
|
||||
try:
|
||||
cutoff_time = datetime.utcnow() - timedelta(hours=6)
|
||||
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=6)
|
||||
|
||||
# Remove old conversations from active list
|
||||
to_remove = []
|
||||
|
||||
@@ -2,7 +2,7 @@ import asyncio
|
||||
import random
|
||||
import schedule
|
||||
from typing import Dict, Any, List, Optional
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
import logging
|
||||
@@ -102,7 +102,7 @@ class ConversationScheduler:
|
||||
async def schedule_event(self, event_type: str, delay: timedelta,
|
||||
character_name: str = None, **kwargs):
|
||||
"""Schedule a specific event"""
|
||||
scheduled_time = datetime.utcnow() + delay
|
||||
scheduled_time = datetime.now(timezone.utc) + delay
|
||||
|
||||
event = ScheduledEvent(
|
||||
event_type=event_type,
|
||||
@@ -170,7 +170,7 @@ class ConversationScheduler:
|
||||
'event_type': event.event_type,
|
||||
'scheduled_time': event.scheduled_time.isoformat(),
|
||||
'character_name': event.character_name,
|
||||
'time_until': (event.scheduled_time - datetime.utcnow()).total_seconds(),
|
||||
'time_until': (event.scheduled_time - datetime.now(timezone.utc)).total_seconds(),
|
||||
'parameters': event.parameters
|
||||
}
|
||||
for event in upcoming
|
||||
@@ -194,7 +194,7 @@ class ConversationScheduler:
|
||||
|
||||
async def _process_due_events(self):
|
||||
"""Process events that are due"""
|
||||
now = datetime.utcnow()
|
||||
now = datetime.now(timezone.utc)
|
||||
due_events = []
|
||||
|
||||
# Find due events
|
||||
@@ -378,7 +378,7 @@ class ConversationScheduler:
|
||||
base_minutes = random.uniform(20, 60)
|
||||
|
||||
# Adjust based on time of day
|
||||
current_hour = datetime.now().hour
|
||||
current_hour = datetime.now(timezone.utc).hour
|
||||
activity_multiplier = self._get_activity_multiplier(current_hour)
|
||||
|
||||
# Adjust based on current activity
|
||||
@@ -427,7 +427,7 @@ class ConversationScheduler:
|
||||
|
||||
def _get_current_activity_pattern(self) -> str:
|
||||
"""Get current activity pattern"""
|
||||
current_hour = datetime.now().hour
|
||||
current_hour = datetime.now(timezone.utc).hour
|
||||
|
||||
for period, config in self.activity_patterns.items():
|
||||
start, end = config['start'], config['end']
|
||||
|
||||
Reference in New Issue
Block a user