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:
247
src/main.py
Normal file
247
src/main.py
Normal file
@@ -0,0 +1,247 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Discord Fishbowl - Autonomous AI Character Chat System
|
||||
Main entry point for the application
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import signal
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Add src to Python path
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
from utils.config import get_settings, validate_environment, setup_logging
|
||||
from utils.logging import setup_logging_interceptor
|
||||
from database.connection import init_database, create_tables, close_database
|
||||
from bot.discord_client import FishbowlBot
|
||||
from bot.message_handler import MessageHandler, CommandHandler
|
||||
from conversation.engine import ConversationEngine
|
||||
from conversation.scheduler import ConversationScheduler
|
||||
from llm.client import llm_client
|
||||
from rag.vector_store import vector_store_manager
|
||||
from rag.community_knowledge import initialize_community_knowledge_rag
|
||||
from mcp.self_modification_server import mcp_server
|
||||
from mcp.file_system_server import filesystem_server
|
||||
import logging
|
||||
|
||||
# Setup logging first
|
||||
logger = setup_logging()
|
||||
setup_logging_interceptor()
|
||||
|
||||
class FishbowlApplication:
|
||||
"""Main application class"""
|
||||
|
||||
def __init__(self):
|
||||
self.settings = None
|
||||
self.conversation_engine = None
|
||||
self.scheduler = None
|
||||
self.discord_bot = None
|
||||
self.message_handler = None
|
||||
self.command_handler = None
|
||||
self.shutdown_event = asyncio.Event()
|
||||
|
||||
# RAG and MCP systems
|
||||
self.vector_store = None
|
||||
self.community_knowledge = None
|
||||
self.mcp_servers = []
|
||||
|
||||
async def initialize(self):
|
||||
"""Initialize all components"""
|
||||
try:
|
||||
logger.info("Starting Discord Fishbowl initialization...")
|
||||
|
||||
# Validate environment
|
||||
validate_environment()
|
||||
|
||||
# Load settings
|
||||
self.settings = get_settings()
|
||||
logger.info("Configuration loaded successfully")
|
||||
|
||||
# Initialize database
|
||||
await init_database()
|
||||
await create_tables()
|
||||
logger.info("Database initialized")
|
||||
|
||||
# Check LLM availability
|
||||
is_available = await llm_client.check_model_availability()
|
||||
if not is_available:
|
||||
logger.error("LLM model not available. Please check your LLM service.")
|
||||
raise RuntimeError("LLM service unavailable")
|
||||
|
||||
logger.info(f"LLM model '{llm_client.model}' is available")
|
||||
|
||||
# Initialize RAG systems
|
||||
logger.info("Initializing RAG systems...")
|
||||
|
||||
# Initialize vector store
|
||||
self.vector_store = vector_store_manager
|
||||
character_names = ["Alex", "Sage", "Luna", "Echo"] # From config
|
||||
await self.vector_store.initialize(character_names)
|
||||
logger.info("Vector store initialized")
|
||||
|
||||
# Initialize community knowledge RAG
|
||||
self.community_knowledge = initialize_community_knowledge_rag(self.vector_store)
|
||||
await self.community_knowledge.initialize(character_names)
|
||||
logger.info("Community knowledge RAG initialized")
|
||||
|
||||
# Initialize MCP servers
|
||||
logger.info("Initializing MCP servers...")
|
||||
|
||||
# Initialize file system server
|
||||
await filesystem_server.initialize(self.vector_store, character_names)
|
||||
self.mcp_servers.append(filesystem_server)
|
||||
logger.info("File system MCP server initialized")
|
||||
|
||||
# Initialize conversation engine
|
||||
self.conversation_engine = ConversationEngine()
|
||||
logger.info("Conversation engine created")
|
||||
|
||||
# Initialize scheduler
|
||||
self.scheduler = ConversationScheduler(self.conversation_engine)
|
||||
logger.info("Conversation scheduler created")
|
||||
|
||||
# Initialize Discord bot
|
||||
self.discord_bot = FishbowlBot(self.conversation_engine)
|
||||
|
||||
# Initialize message and command handlers
|
||||
self.message_handler = MessageHandler(self.discord_bot, self.conversation_engine)
|
||||
self.command_handler = CommandHandler(self.discord_bot, self.conversation_engine)
|
||||
|
||||
logger.info("Discord bot and handlers initialized")
|
||||
|
||||
logger.info("✅ All components initialized successfully")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to initialize application: {e}")
|
||||
raise
|
||||
|
||||
async def start(self):
|
||||
"""Start the application"""
|
||||
try:
|
||||
logger.info("🚀 Starting Discord Fishbowl...")
|
||||
|
||||
# Start conversation engine
|
||||
await self.conversation_engine.initialize(self.discord_bot)
|
||||
logger.info("Conversation engine started")
|
||||
|
||||
# Start scheduler
|
||||
await self.scheduler.start()
|
||||
logger.info("Conversation scheduler started")
|
||||
|
||||
# Start Discord bot
|
||||
bot_task = asyncio.create_task(
|
||||
self.discord_bot.start(self.settings.discord.token)
|
||||
)
|
||||
|
||||
# Setup signal handlers
|
||||
self._setup_signal_handlers()
|
||||
|
||||
logger.info("🎉 Discord Fishbowl is now running!")
|
||||
logger.info("Characters will start chatting autonomously...")
|
||||
|
||||
# Wait for shutdown signal or bot completion
|
||||
done, pending = await asyncio.wait(
|
||||
[bot_task, asyncio.create_task(self.shutdown_event.wait())],
|
||||
return_when=asyncio.FIRST_COMPLETED
|
||||
)
|
||||
|
||||
# Cancel pending tasks
|
||||
for task in pending:
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error during application startup: {e}")
|
||||
raise
|
||||
|
||||
async def shutdown(self):
|
||||
"""Graceful shutdown"""
|
||||
try:
|
||||
logger.info("🛑 Shutting down Discord Fishbowl...")
|
||||
|
||||
# Stop scheduler
|
||||
if self.scheduler:
|
||||
await self.scheduler.stop()
|
||||
logger.info("Conversation scheduler stopped")
|
||||
|
||||
# Stop conversation engine
|
||||
if self.conversation_engine:
|
||||
await self.conversation_engine.stop()
|
||||
logger.info("Conversation engine stopped")
|
||||
|
||||
# Close Discord bot
|
||||
if self.discord_bot:
|
||||
await self.discord_bot.close()
|
||||
logger.info("Discord bot disconnected")
|
||||
|
||||
# Close database connections
|
||||
await close_database()
|
||||
logger.info("Database connections closed")
|
||||
|
||||
logger.info("✅ Shutdown completed successfully")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error during shutdown: {e}")
|
||||
|
||||
def _setup_signal_handlers(self):
|
||||
"""Setup signal handlers for graceful shutdown"""
|
||||
def signal_handler(signum, frame):
|
||||
logger.info(f"Received signal {signum}, initiating shutdown...")
|
||||
self.shutdown_event.set()
|
||||
|
||||
# Handle common shutdown signals
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
# On Windows, handle CTRL+C
|
||||
if os.name == 'nt':
|
||||
signal.signal(signal.SIGBREAK, signal_handler)
|
||||
|
||||
async def main():
|
||||
"""Main entry point"""
|
||||
app = FishbowlApplication()
|
||||
|
||||
try:
|
||||
# Initialize application
|
||||
await app.initialize()
|
||||
|
||||
# Start application
|
||||
await app.start()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Received keyboard interrupt")
|
||||
except Exception as e:
|
||||
logger.error(f"Application error: {e}")
|
||||
return 1
|
||||
finally:
|
||||
# Ensure cleanup
|
||||
await app.shutdown()
|
||||
|
||||
return 0
|
||||
|
||||
def cli_main():
|
||||
"""CLI entry point"""
|
||||
try:
|
||||
# Check Python version
|
||||
if sys.version_info < (3, 8):
|
||||
print("Error: Python 3.8 or higher is required")
|
||||
return 1
|
||||
|
||||
# Run the async main function
|
||||
return asyncio.run(main())
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nApplication interrupted by user")
|
||||
return 1
|
||||
except Exception as e:
|
||||
print(f"Fatal error: {e}")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(cli_main())
|
||||
Reference in New Issue
Block a user