PersonaFlow is a lightweight Python library designed for creating and managing AI personas with dynamic memory capabilities. It enables developers to build interactive characters that can maintain context and remember past interactions.
pip install -r requirements.txt
from personaflow.core import PersonaSystem # Initialize a new persona system # This is the main controller for managing all characters and their interactions system = PersonaSystem() # Create a basic character with minimal configuration # Here we only specify the essential parameters: name and prompt basic_character = system.create_character( name="BasicAssistant", prompt="You are a helpful AI assistant named BasicAssistant" ) # Let's add a simple interaction to the character's memory # This stores both the user's input and the character's response system.add_interaction( character_name="BasicAssistant", # The character receiving the memory content={ "user": "What's your name?", # User's message "response": "I'm BasicAssistant" # Character's response } ) # Retrieve the character's context including recent memories # This shows us the character's current state and memory context = basic_character.get_context() # Print the context to see what the character knows print(context)
An example with an embedded LLM implementation is available in example.py.
1. Character Management
# Create a more sophisticated character with full configuration advanced_character = system.create_character( # Unique identifier for the character name="TechExpert", # Base personality and behavior definition prompt="You are a technology expert specializing in Python and AI", # Additional character information and traits background={ "expertise": ["Python", "AI", "Machine Learning"], "personality": "Professional but friendly", "experience": "10 years in software development" }, # Memory system configuration memory_config={ "max_memories": 500, # Maximum number of memories to store "summary_threshold": 50, # When to start summarizing old memories "auto_summarize": True # Automatically compress old memories } ) # Switch the active character in the system # This is useful when managing multiple characters system.switch_active_character("TechExpert") # Retrieve a specific character from the system tech_expert = system.get_character("TechExpert") # Get character context with specific memory filters context = tech_expert.get_context( include_memories=True, # Include memory in the context memory_limit=10, # Only get the 10 most recent memories memory_types=["interaction", "event"] # Only get specific types of memories )
2. Memory Management
# Add a standard interaction memory character.add_memory( # The content of the memory - typically a conversation content={ "user": "How can I improve my Python skills?", "response": "Practice coding regularly and work on real projects" }, # Type of memory being stored memory_type="interaction", # Additional information about the memory metadata={ "topic": "programming", "importance": "high", "engagement": "positive" } ) # Add a system event memory # This is useful for tracking important system changes or updates character.add_memory( # Record an important event or system change content={ "event": "Knowledge Base Update", "details": "Added new programming tutorials and resources" }, memory_type="event", metadata={ "category": "system_update", "impact": "significant" } ) # Broadcast an announcement to all characters # Useful for system-wide notifications or shared knowledge system.broadcast_interaction( # Content that all characters should remember content={ "announcement": "New Feature Release", "details": "Added support for code execution" }, # Specify this as a broadcast type memory memory_type="broadcast", # Additional context about the broadcast metadata={ "priority": "high", "requires_action": False } ) # Retrieve specific memories with filters # This helps in getting relevant context for responses recent_memories = character.memory_manager.get_memories( limit=5, # Only get 5 memories memory_types=["interaction"] # Only get conversation memories ) # Example of memory configuration for advanced use cases memory_config = { # Set maximum number of memories before triggering cleanup "max_memories": 2000, # Number of memories that trigger summarization "summary_threshold": 100, # Enable automatic memory summarization "auto_summarize": True } # Create character with advanced memory configuration advanced_memory_character = system.create_character( name="MemoryExpert", prompt="AI with enhanced memory capabilities", memory_config=memory_config ) # Add a complex memory with detailed metadata advanced_memory_character.add_memory( # Detailed conversation content content={ "user": "Tell me about our previous discussion on AI", "response": "We covered neural networks and deep learning", "context": { "previous_topics": ["Machine Learning", "Neural Networks"], "user_knowledge_level": "intermediate" } }, memory_type="interaction", # Rich metadata for better context retrieval metadata={ "conversation_id": "12345", "topics": ["AI", "deep learning"], "importance_score": 0.8, "user_engagement": "high", "follow_up_required": True } )
3. Prompt Management
from personaflow.utils import PromptManager # Initialize the prompt manager # This helps maintain consistent character responses through templates prompt_manager = PromptManager() # Add a basic greeting template # ${variable_name} syntax is used for dynamic content prompt_manager.add_template( "greeting", """ Hello ${user_name}! I'm ${bot_name}, ${role}. ${custom_greeting} """ ) # Add a more complex template for technical responses prompt_manager.add_template( "technical_response", """ Regarding your question about ${topic}: Based on my ${expertise} background, here's a detailed explanation: ${explanation} Technical details: ${technical_details} Would you like me to elaborate on any specific aspect? """ ) # Using the templates with specific values basic_greeting = prompt_manager.get_prompt( "greeting", # Fill in template variables user_name="Alice", bot_name="TechBot", role="your technical advisor", custom_greeting="How can I help with your technical questions today?" ) technical_answer = prompt_manager.get_prompt( "technical_response", # Provide detailed technical content topic="Python Decorators", expertise="Python development", explanation="Decorators are a way to modify function behavior", technical_details=""" 1. They use the @syntax 2. Common use cases include logging and authentication 3. They can be stacked on a single function """ )
4. Logging System
from personaflow.utils import Logger # Initialize logger with both console and file output # This helps track system operations and debug issues logger = Logger( name="PersonaFlow", # Logger identifier level="INFO", # Logging level log_file="persona_flow.log" # Output file for logs ) # Example of different logging levels for various situations # Info for general operational messages logger.info("Successfully created new character: TechBot") # Debug for detailed technical information logger.debug("Processing memory retrieval request for character: TechBot") # Warning for potential issues logger.warning("Character memory approaching configured limit (90% full)") # Error for serious issues that need attention logger.error("Failed to load character state from file: character_backup.json")
5. Serialization
from personaflow.utils import Serializer # Save the entire system state # Useful for backing up or transferring the system system_data = system.to_dict() Serializer.to_json( # Convert system state to JSON format data=system_data, file_path="system_backup.json" # Where to save the backup ) # Load a previously saved system state # Restore system from backup loaded_data = Serializer.from_json("system_backup.json") restored_system = PersonaSystem.from_dict(loaded_data) # Save individual character state # Useful for character-specific backups character_data = character.to_dict() Serializer.to_json( data=character_data, file_path="character_backup.json" ) # Example of saving specific character memories memory_backup = { "character_name": character.name, "memories": character.memory_manager.get_memories(), "timestamp": "2024-03-21T10:00:00" } Serializer.to_json( data=memory_backup, file_path="memories_backup.json" )
6. Input Validation
from personaflow.utils import validators # Validate a prompt template # Ensures the template syntax is correct before using it template = "Hello ${name}, welcome to ${service}!" is_valid = validators.validate_prompt_template(template) if is_valid: # Template is valid, safe to use prompt_manager.add_template("welcome", template) else: # Template has syntax errors logger.error(f"Invalid template syntax: {template}") # Validate memory content structure # Ensures memory content meets required format memory_content = { "user": "What's the weather like?", "response": "I don't have access to weather data." } # Check if content structure is valid if validators.validate_memory_content(memory_content): # Content is valid, safe to add to memory character.add_memory(content=memory_content) else: # Content is missing required fields logger.error("Invalid memory content structure") # Validate memory configuration # Ensures memory settings are properly formatted memory_config = { "max_memories": 1000, "summary_threshold": 10, "auto_summarize": True } # Check if configuration is valid if validators.validate_memory_config(memory_config): # Configuration is valid, safe to use character = system.create_character( name="ValidatedChar", prompt="Basic prompt", memory_config=memory_config ) else: # Configuration has invalid values or missing fields logger.error("Invalid memory configuration")
7. Complete System Example
from personaflow.core import PersonaSystem from personaflow.utils import PromptManager, Logger, Serializer # Initialize all system components # Set up the main system and utilities system = PersonaSystem() prompt_manager = PromptManager() logger = Logger("PersonaSystem", log_file="system.log") # Create prompt templates for the character # Define various response patterns prompt_manager.add_template( "tech_assistant", """ You are ${name}, an AI assistant with the following traits: - Primary expertise: ${expertise} - Background: ${background} - Current context: ${context} Please provide assistance while maintaining these characteristics. """ ) # Create a character with complete configuration tech_assistant = system.create_character( # Basic character information name="TechHelper", # Generate character prompt from template prompt=prompt_manager.get_prompt( "tech_assistant", name="TechHelper", expertise="Python & AI Development", background="10 years of software development", context="Initial setup" ), # Detailed background information background={ "skills": ["Python", "AI", "Machine Learning", "Software Architecture"], "personality_traits": ["Patient", "Detail-oriented", "Analytical"], "communication_style": "Professional but friendly", "specializations": { "primary": "Python Development", "secondary": ["AI Systems", "Code Optimization"] } }, # Memory system configuration memory_config={ "max_memories": 1000, "summary_threshold": 50, "auto_summarize": True } ) # Simulate a conversation with memory tracking # First user interaction system.add_interaction( character_name="TechHelper", content={ "user": "Can you help me understand Python decorators?", "response": "I'd be happy to explain decorators. They're a powerful Python feature..." }, metadata={ "topic": "Python", "subtopic": "decorators", "complexity": "intermediate" } ) # Follow-up interaction system.add_interaction( character_name="TechHelper", content={ "user": "Can you show me an example?", "response": "Here's a simple decorator example:\n\n@timer\ndef my_function()..." }, metadata={ "topic": "Python", "subtopic": "decorators", "content_type": "code_example" } ) # Get updated context for next interaction context = tech_assistant.get_context( include_memories=True, memory_limit=5 ) # Save system state periodically try: Serializer.to_json(system.to_dict(), "system_state.json") logger.info("System state saved successfully") except IOError as e: logger.error(f"Failed to save system state: {str(e)}") # Example of processing user request with full context def process_user_request(user_input: str, character_name: str): """ Process a user request with full context and memory """ # Get the character character = system.get_character(character_name) # Get relevant context context = character.get_context( include_memories=True, memory_limit=5, memory_types=["interaction"] ) # Log the interaction logger.info(f"Processing request for {character_name}: {user_input[:50]}...") # Add the new interaction system.add_interaction( character_name=character_name, content={ "user": user_input, "response": "Generated response based on context..." }, metadata={ "timestamp": "2024-03-21T10:00:00", "session_id": "unique_session_id" } ) return "Generated response based on context..." # Example usage of the process_user_request function response = process_user_request( user_input="How do I optimize my Python code?", character_name="TechHelper" )
This project is licensed under the MIT License - see the LICENSE file for details.