""" Trixy Asset Management System This module provides comprehensive asset management for the Trixy voice assistant application, including profile-based asset loading, caching, validation, and integrity checking as specified in CLAUDE.md. The asset management system is designed to handle various types of assets used throughout the Trixy application: - Audio assets: Success sounds, error notifications, wakeword confirmations - Image assets: Icons, status indicators, UI elements - Text assets: Templates, messages, response texts - Configuration assets: Settings templates, profile configurations - Model assets: ML models, training data references - Binary assets: Compressed files, executables Key Features: - Profile-based asset resolution with fallback to default profile - High-performance caching with configurable policies - Comprehensive validation and integrity checking - Hot-reload capabilities for development - Thread-safe operations for multi-satellite support - Integration with application container and event system Asset Resolution Path: 1. Primary: ./assets/{profile}/path/to/asset 2. Fallback: ./assets/default/path/to/asset 3. Returns False if not found in either location Usage Examples: Basic Usage: from trixy_core.assets import AssetManager, create_asset_manager # Create asset manager asset_manager = create_asset_manager( assets_directory="./assets", profile="production", cache_enabled=True ) # Get asset path (main API as per CLAUDE.md) audio_path = asset_manager.get_path("audio/success.wav") if audio_path: print(f"Found asset at: {audio_path}") else: print("Asset not found") Advanced Configuration: from trixy_core.assets import AssetManager, AssetManagerConfig config = AssetManagerConfig( assets_directory="./assets", current_profile="development", cache_enabled=True, validation_enabled=True, hot_reload_enabled=True, preload_patterns=["audio/*.wav", "images/*.png"] ) asset_manager = AssetManager(config=config) Integration with Application Container: # The asset manager is automatically available through the application container application = get_application_container() asset_manager = application.get_asset_manager() # Use in plugins or components success_sound = asset_manager.get_path("audio/success.wav") Public API: AssetManager: Main asset management class AssetManagerConfig: Configuration for asset manager AssetType: Enumeration of supported asset types AssetCache: High-performance caching system AssetValidator: Comprehensive validation system create_asset_manager(): Convenience factory function """ # Import core asset management classes from .asset_manager import ( # Main classes AssetManager, AssetManagerConfig, AssetInfo, # Enums and types AssetStatus, ProfileMode, # Exceptions AssetLoadError, AssetValidationError, AssetNotFoundError, AssetManagerError, # Factory function create_asset_manager, ) # Import asset type system from .asset_types import ( # Core types AssetType, AssetConstraints, AssetMetadata, # Functions get_asset_type_from_path, get_asset_constraints, validate_asset_type, extract_asset_metadata, get_asset_category, is_asset_type_supported, get_supported_extensions, get_extensions_for_type, # Constants ASSET_TYPE_CONSTRAINTS, EXTENSION_TO_TYPE, ASSET_TYPE_CATEGORIES, ) # Import caching system from .asset_cache import ( # Core classes AssetCache, CachePolicy, CacheEntry, CacheStats, # Enums CacheEntryStatus, CacheEvictionStrategy, # Factory functions create_memory_cache, create_persistent_cache, ) # Import validation system from .asset_validator import ( # Core classes AssetValidator, AssetIntegrityChecker, AssetValidationResult, ValidationIssue, # Enums ValidationSeverity, ValidationCategory, # Functions quick_validate, batch_validate, ) # Module version and metadata __version__ = "1.0.0" __author__ = "Trixy Development Team" __description__ = "Professional asset management system for Trixy voice assistant" # Public API - explicitly define what gets imported with "from trixy_core.assets import *" __all__ = [ # Main asset manager "AssetManager", "AssetManagerConfig", "AssetInfo", "AssetStatus", "ProfileMode", "create_asset_manager", # Asset types "AssetType", "AssetConstraints", "AssetMetadata", "get_asset_type_from_path", "get_asset_constraints", "validate_asset_type", "extract_asset_metadata", "get_asset_category", "is_asset_type_supported", "get_supported_extensions", "get_extensions_for_type", # Caching "AssetCache", "CachePolicy", "CacheEntry", "CacheStats", "CacheEntryStatus", "CacheEvictionStrategy", "create_memory_cache", "create_persistent_cache", # Validation "AssetValidator", "AssetIntegrityChecker", "AssetValidationResult", "ValidationIssue", "ValidationSeverity", "ValidationCategory", "quick_validate", "batch_validate", # Exceptions "AssetLoadError", "AssetValidationError", "AssetNotFoundError", "AssetManagerError", # Constants "ASSET_TYPE_CONSTRAINTS", "EXTENSION_TO_TYPE", "ASSET_TYPE_CATEGORIES", ] # Logging function for the assets module def pprint(message: str) -> None: """ Asset management logging function that adapts based on mode. Uses the same pattern as specified in CLAUDE.md. """ print(f"[ASSETS] {message}") # Module initialization def _init_assets_module(): """Initialize the assets module.""" pprint(f"Asset management system loaded (version {__version__})") # Log available asset types try: supported_extensions = get_supported_extensions() pprint(f"Supporting {len(supported_extensions)} file extensions") # Log asset type categories categories = list(ASSET_TYPE_CATEGORIES.keys()) pprint(f"Asset categories: {', '.join(categories)}") except Exception as e: pprint(f"Warning: Could not initialize asset type information: {e}") # Initialize the module _init_assets_module() # Convenience functions for common operations def get_default_asset_manager() -> AssetManager: """ Get a default asset manager instance with reasonable settings. Returns: AssetManager instance configured with defaults """ return create_asset_manager( assets_directory="./assets", cache_enabled=True, validation_enabled=True, hot_reload_enabled=False ) def validate_asset_file(file_path: str, asset_type: str = None) -> AssetValidationResult: """ Convenience function to quickly validate an asset file. Args: file_path: Path to the asset file asset_type: Expected asset type (optional) Returns: AssetValidationResult with validation details """ return quick_validate(file_path, asset_type) def create_development_asset_manager(assets_dir: str = "./assets") -> AssetManager: """ Create an asset manager optimized for development. Features enabled: - Hot-reload for file changes - Detailed validation - Debug logging - Reduced caching for faster iteration Args: assets_dir: Assets directory path Returns: AssetManager configured for development """ config = AssetManagerConfig( assets_directory=assets_dir, cache_enabled=True, cache_max_size=50, # Smaller cache for development validation_enabled=True, hot_reload_enabled=True, hot_reload_debounce=0.2, # Quick response to changes enable_integrity_checks=True, auto_create_directories=True ) return AssetManager(config=config) def create_production_asset_manager( assets_dir: str = "./assets", profile: str = "default", cache_size_mb: int = 100 ) -> AssetManager: """ Create an asset manager optimized for production. Features enabled: - Aggressive caching for performance - Validation with integrity checks - No hot-reload for stability - Preloading of common assets Args: assets_dir: Assets directory path profile: Asset profile to use cache_size_mb: Cache size in megabytes Returns: AssetManager configured for production """ config = AssetManagerConfig( assets_directory=assets_dir, current_profile=profile, cache_enabled=True, cache_max_size=500, cache_max_memory=cache_size_mb * 1024 * 1024, validation_enabled=True, hot_reload_enabled=False, enable_integrity_checks=True, compress_cached_assets=True, preload_patterns=[ "audio/success.wav", "audio/error.wav", "audio/notification.wav", "images/icons/*.png" ] ) return AssetManager(config=config) def get_asset_info(file_path: str) -> dict: """ Get comprehensive information about an asset file. Args: file_path: Path to the asset file Returns: Dictionary with asset information including type, metadata, validation results """ try: # Detect asset type asset_type = get_asset_type_from_path(file_path) # Extract metadata metadata = extract_asset_metadata(file_path, asset_type) # Validate asset validation_result = quick_validate(file_path, asset_type.value if hasattr(asset_type, 'value') else str(asset_type)) return { 'file_path': file_path, 'asset_type': asset_type.value if hasattr(asset_type, 'value') else str(asset_type), 'category': get_asset_category(asset_type), 'is_supported': is_asset_type_supported(asset_type), 'metadata': metadata.to_dict() if hasattr(metadata, 'to_dict') else metadata, 'validation': validation_result.to_dict() if hasattr(validation_result, 'to_dict') else validation_result, 'constraints': get_asset_constraints(asset_type) } except Exception as e: return { 'file_path': file_path, 'error': str(e), 'asset_type': 'unknown' } # Add convenience exports __all__.extend([ 'pprint', 'get_default_asset_manager', 'validate_asset_file', 'create_development_asset_manager', 'create_production_asset_manager', 'get_asset_info', ]) def get_version() -> str: """Get the asset management system version.""" return __version__ def get_supported_asset_types() -> list: """Get a list of all supported asset types.""" try: return [asset_type.value for asset_type in AssetType] except Exception: return [] def get_asset_statistics() -> dict: """Get statistics about the asset management system.""" return { 'version': __version__, 'supported_extensions': len(get_supported_extensions()), 'asset_categories': len(ASSET_TYPE_CATEGORIES), 'total_asset_types': len(list(AssetType)), 'validation_available': True, 'caching_available': True, 'hot_reload_available': True } # Final exports __all__.extend([ 'get_version', 'get_supported_asset_types', 'get_asset_statistics' ])