| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- """
- Default Configuration Values for Trixy Application
- This module provides default configuration values for all deployment modes.
- It includes factory functions to create default configurations, environment
- variable mappings, and configuration templates.
- All defaults are production-ready but can be overridden through configuration
- files, environment variables, or command line arguments.
- """
- import os
- import platform
- import socket
- from pathlib import Path
- from typing import Dict, Any, Optional
- import uuid
- from .config_models import (
- ServerConfig, ClientConfig, StandaloneConfig,
- NetworkConfig, AudioConfig, MLConfig, PluginConfig,
- SatelliteConfig, SecurityConfig, LoggingConfig,
- LogLevel, DeploymentMode
- )
- # Environment variable prefix for Trixy configurations
- ENV_PREFIX = "TRIXY_"
- # Default paths relative to application root
- DEFAULT_PATHS = {
- "data_directory": "data",
- "config_directory": "config",
- "log_directory": "logs",
- "plugin_directory": "plugins",
- "model_directory": "models",
- "asset_directory": "assets",
- "training_data_directory": "trainer/data",
- }
- # Default network ports
- DEFAULT_PORTS = {
- "command": 2101,
- "audio_input": 2102,
- "audio_output": 2103,
- "music_output": 2104,
- "web_interface": 8080,
- }
- # Default audio settings based on system capabilities
- DEFAULT_AUDIO = {
- "sample_rate": 16000,
- "channels": 1,
- "bit_depth": 16,
- "frame_size": 1024,
- "max_recording_duration": 60,
- "silence_threshold": 0.01,
- "silence_duration": 3.0,
- "pre_recording_buffer": 1.0,
- }
- # Default ML model settings
- DEFAULT_ML = {
- "wakeword_threshold": 0.8,
- "voice_recognition_threshold": 0.7,
- "model_cache_size": 3,
- "batch_size": 1,
- "max_inference_time": 5.0,
- }
- def get_system_defaults() -> Dict[str, Any]:
- """Get system-specific default values."""
- hostname = socket.gethostname()
- system = platform.system().lower()
-
- defaults = {
- "hostname": hostname,
- "system": system,
- "satellite_id": str(uuid.uuid4()),
- "mac_address": get_mac_address(),
- }
-
- # System-specific audio defaults
- if system == "linux":
- defaults["audio_backend"] = "alsa"
- elif system == "windows":
- defaults["audio_backend"] = "wasapi"
- elif system == "darwin": # macOS
- defaults["audio_backend"] = "coreaudio"
- else:
- defaults["audio_backend"] = "default"
-
- return defaults
- def get_mac_address() -> str:
- """Get the system's MAC address."""
- try:
- mac = uuid.getnode()
- return ':'.join(f'{(mac >> i) & 0xFF:02x}' for i in range(0, 48, 8))
- except Exception:
- return "00:00:00:00:00:00"
- def get_env_override(key: str, default: Any = None) -> Any:
- """Get environment variable override with proper type conversion."""
- env_key = f"{ENV_PREFIX}{key.upper()}"
- value = os.getenv(env_key)
-
- if value is None:
- return default
-
- # Type conversion based on default value type
- if isinstance(default, bool):
- return value.lower() in ('true', '1', 'yes', 'on', 'enabled')
- elif isinstance(default, int):
- try:
- return int(value)
- except ValueError:
- return default
- elif isinstance(default, float):
- try:
- return float(value)
- except ValueError:
- return default
- elif isinstance(default, list):
- # Comma-separated values
- return [v.strip() for v in value.split(',') if v.strip()]
-
- return value
- def create_default_network_config() -> NetworkConfig:
- """Create default network configuration."""
- return NetworkConfig(
- command_port=get_env_override("command_port", DEFAULT_PORTS["command"]),
- command_bind_address=get_env_override("bind_address", "0.0.0.0"),
- command_max_connections=get_env_override("max_connections", 50),
- command_timeout=get_env_override("command_timeout", 30),
- command_buffer_size=get_env_override("command_buffer_size", 8192),
-
- raw_audio_input_port=get_env_override("audio_input_port", DEFAULT_PORTS["audio_input"]),
- raw_audio_output_port=get_env_override("audio_output_port", DEFAULT_PORTS["audio_output"]),
- raw_music_output_port=get_env_override("music_output_port", DEFAULT_PORTS["music_output"]),
-
- audio_bind_address=get_env_override("audio_bind_address", "0.0.0.0"),
- audio_timeout=get_env_override("audio_timeout", 10),
- audio_buffer_size=get_env_override("audio_buffer_size", 16384),
-
- heartbeat_interval=get_env_override("heartbeat_interval", 30),
- max_retry_attempts=get_env_override("max_retry_attempts", 5),
- retry_delay=get_env_override("retry_delay", 5),
- connection_timeout=get_env_override("connection_timeout", 10),
-
- enable_encryption=get_env_override("enable_encryption", False),
- encryption_key_file=get_env_override("encryption_key_file", None),
- enable_compression=get_env_override("enable_compression", True),
- compression_level=get_env_override("compression_level", 6),
- )
- def create_default_audio_config() -> AudioConfig:
- """Create default audio configuration."""
- return AudioConfig(
- sample_rate=get_env_override("sample_rate", DEFAULT_AUDIO["sample_rate"]),
- channels=get_env_override("channels", DEFAULT_AUDIO["channels"]),
- bit_depth=get_env_override("bit_depth", DEFAULT_AUDIO["bit_depth"]),
- frame_size=get_env_override("frame_size", DEFAULT_AUDIO["frame_size"]),
-
- max_recording_duration=get_env_override("max_recording_duration", DEFAULT_AUDIO["max_recording_duration"]),
- silence_threshold=get_env_override("silence_threshold", DEFAULT_AUDIO["silence_threshold"]),
- silence_duration=get_env_override("silence_duration", DEFAULT_AUDIO["silence_duration"]),
- pre_recording_buffer=get_env_override("pre_recording_buffer", DEFAULT_AUDIO["pre_recording_buffer"]),
-
- enable_noise_reduction=get_env_override("enable_noise_reduction", True),
- enable_auto_gain=get_env_override("enable_auto_gain", True),
- gain_level=get_env_override("gain_level", 1.0),
-
- vad_enabled=get_env_override("vad_enabled", True),
- vad_aggressiveness=get_env_override("vad_aggressiveness", 2),
- vad_frame_duration=get_env_override("vad_frame_duration", 30),
-
- music_sample_rate=get_env_override("music_sample_rate", 48000),
- music_channels=get_env_override("music_channels", 2),
- music_bit_depth=get_env_override("music_bit_depth", 16),
- )
- def create_default_ml_config() -> MLConfig:
- """Create default ML configuration."""
- return MLConfig(
- wakeword_model_path=get_env_override("wakeword_model_path", "models/wakeword/default.pth"),
- voice_recognition_model_path=get_env_override("voice_recognition_model_path", "models/voice_recognition/default.pth"),
-
- wakeword_threshold=get_env_override("wakeword_threshold", DEFAULT_ML["wakeword_threshold"]),
- voice_recognition_threshold=get_env_override("voice_recognition_threshold", DEFAULT_ML["voice_recognition_threshold"]),
- model_cache_size=get_env_override("model_cache_size", DEFAULT_ML["model_cache_size"]),
-
- enable_gpu=get_env_override("enable_gpu", True),
- gpu_device_id=get_env_override("gpu_device_id", 0),
- batch_size=get_env_override("batch_size", DEFAULT_ML["batch_size"]),
- max_inference_time=get_env_override("max_inference_time", DEFAULT_ML["max_inference_time"]),
-
- training_data_path=get_env_override("training_data_path", DEFAULT_PATHS["training_data_directory"]),
- model_output_path=get_env_override("model_output_path", DEFAULT_PATHS["model_directory"]),
- training_batch_size=get_env_override("training_batch_size", 32),
- training_epochs=get_env_override("training_epochs", 100),
- learning_rate=get_env_override("learning_rate", 0.001),
- )
- def create_default_plugin_config() -> PluginConfig:
- """Create default plugin configuration."""
- return PluginConfig(
- plugin_directories=get_env_override("plugin_directories", [DEFAULT_PATHS["plugin_directory"]]),
- auto_load_plugins=get_env_override("auto_load_plugins", True),
- plugin_timeout=get_env_override("plugin_timeout", 30),
- max_plugin_memory=get_env_override("max_plugin_memory", 512),
-
- enable_plugin_sandboxing=get_env_override("enable_plugin_sandboxing", True),
- allowed_plugin_apis=set(get_env_override("allowed_plugin_apis", [
- "event_handler", "satellite_manager", "asset_manager",
- "config_manager", "scheduler"
- ])),
-
- enable_hot_reload=get_env_override("enable_hot_reload", True),
- reload_check_interval=get_env_override("reload_check_interval", 5),
- max_reload_attempts=get_env_override("max_reload_attempts", 3),
- )
- def create_default_satellite_config() -> SatelliteConfig:
- """Create default satellite configuration."""
- system_defaults = get_system_defaults()
-
- return SatelliteConfig(
- server_host=get_env_override("server_host", "localhost"),
- server_port=get_env_override("server_port", DEFAULT_PORTS["command"]),
- auto_reconnect=get_env_override("auto_reconnect", True),
- reconnect_interval=get_env_override("reconnect_interval", 5),
-
- satellite_id=get_env_override("satellite_id", system_defaults["satellite_id"]),
- room_name=get_env_override("room_name", "default"),
- alias_name=get_env_override("alias_name", f"trixy-{system_defaults['hostname']}"),
- mac_address=get_env_override("mac_address", system_defaults["mac_address"]),
-
- local_wakeword_processing=get_env_override("local_wakeword_processing", True),
- local_voice_recognition=get_env_override("local_voice_recognition", False),
- buffer_audio_locally=get_env_override("buffer_audio_locally", True),
-
- stream_quality=get_env_override("stream_quality", "high"),
- compression_enabled=get_env_override("compression_enabled", True),
- )
- def create_default_security_config() -> SecurityConfig:
- """Create default security configuration."""
- return SecurityConfig(
- enable_encryption=get_env_override("enable_encryption", False),
- encryption_algorithm=get_env_override("encryption_algorithm", "AES-256-GCM"),
- key_rotation_interval=get_env_override("key_rotation_interval", 86400),
-
- require_authentication=get_env_override("require_authentication", False),
- auth_token_expiry=get_env_override("auth_token_expiry", 3600),
- max_auth_attempts=get_env_override("max_auth_attempts", 3),
- auth_lockout_duration=get_env_override("auth_lockout_duration", 300),
-
- allowed_clients=get_env_override("allowed_clients", []),
- blocked_clients=get_env_override("blocked_clients", []),
- max_connections_per_client=get_env_override("max_connections_per_client", 5),
-
- enable_audit_logging=get_env_override("enable_audit_logging", True),
- audit_log_file=get_env_override("audit_log_file", "logs/security_audit.log"),
- enable_intrusion_detection=get_env_override("enable_intrusion_detection", False),
- )
- def create_default_logging_config(debug_mode: bool = False) -> LoggingConfig:
- """Create default logging configuration."""
- log_level = LogLevel.DEBUG if debug_mode else LogLevel.INFO
-
- return LoggingConfig(
- log_level=LogLevel(get_env_override("log_level", log_level.value)),
- log_format=get_env_override("log_format", "%(asctime)s - %(name)s - %(levelname)s - %(message)s"),
- date_format=get_env_override("date_format", "%Y-%m-%d %H:%M:%S"),
-
- enable_file_logging=get_env_override("enable_file_logging", True),
- log_file_path=get_env_override("log_file_path", "logs/trixy.log"),
- max_log_file_size=get_env_override("max_log_file_size", 10485760), # 10MB
- log_file_backup_count=get_env_override("log_file_backup_count", 5),
-
- enable_console_logging=get_env_override("enable_console_logging", True),
- console_log_level=LogLevel(get_env_override("console_log_level", log_level.value)),
-
- enable_event_logging=get_env_override("enable_event_logging", True),
- event_log_file=get_env_override("event_log_file", "logs/events.log"),
- enable_performance_logging=get_env_override("enable_performance_logging", debug_mode),
- performance_log_file=get_env_override("performance_log_file", "logs/performance.log"),
-
- debug_mode=get_env_override("debug_mode", debug_mode),
- verbose_errors=get_env_override("verbose_errors", debug_mode),
- log_stack_traces=get_env_override("log_stack_traces", debug_mode),
- )
- def create_default_server_config(debug_mode: bool = False) -> ServerConfig:
- """Create default server configuration."""
- return ServerConfig(
- mode=DeploymentMode.SERVER,
- debug_mode=debug_mode,
- data_directory=get_env_override("data_directory", DEFAULT_PATHS["data_directory"]),
- config_file=get_env_override("config_file", "config/server_config.json"),
-
- network=create_default_network_config(),
- audio=create_default_audio_config(),
- ml=create_default_ml_config(),
- plugins=create_default_plugin_config(),
- security=create_default_security_config(),
- logging=create_default_logging_config(debug_mode),
-
- registration_mode_timeout=get_env_override("registration_mode_timeout", 60),
- max_satellites=get_env_override("max_satellites", 50),
- satellite_heartbeat_timeout=get_env_override("satellite_heartbeat_timeout", 60),
- enable_web_interface=get_env_override("enable_web_interface", False),
- web_interface_port=get_env_override("web_interface_port", DEFAULT_PORTS["web_interface"]),
-
- asset_profile=get_env_override("asset_profile", "default"),
- asset_cache_size=get_env_override("asset_cache_size", 100),
-
- conversation_timeout=get_env_override("conversation_timeout", 300),
- max_concurrent_conversations=get_env_override("max_concurrent_conversations", 10),
- )
- def create_default_client_config(debug_mode: bool = False) -> ClientConfig:
- """Create default client configuration."""
- return ClientConfig(
- mode=DeploymentMode.CLIENT,
- debug_mode=debug_mode,
- data_directory=get_env_override("data_directory", DEFAULT_PATHS["data_directory"]),
- config_file=get_env_override("config_file", "config/client_config.json"),
-
- satellite=create_default_satellite_config(),
- audio=create_default_audio_config(),
- ml=create_default_ml_config(),
- logging=create_default_logging_config(debug_mode),
-
- enable_local_processing=get_env_override("enable_local_processing", True),
- local_model_cache_size=get_env_override("local_model_cache_size", 50),
- audio_buffer_size=get_env_override("audio_buffer_size", 8192),
-
- status_report_interval=get_env_override("status_report_interval", 30),
- health_check_interval=get_env_override("health_check_interval", 10),
- )
- def create_default_standalone_config(debug_mode: bool = False) -> StandaloneConfig:
- """Create default standalone configuration."""
- return StandaloneConfig(
- mode=DeploymentMode.STANDALONE,
- debug_mode=debug_mode,
- data_directory=get_env_override("data_directory", DEFAULT_PATHS["data_directory"]),
- config_file=get_env_override("config_file", "config/standalone_config.json"),
-
- network=create_default_network_config(),
- audio=create_default_audio_config(),
- ml=create_default_ml_config(),
- plugins=create_default_plugin_config(),
- security=create_default_security_config(),
- logging=create_default_logging_config(debug_mode),
-
- enable_server_sync=get_env_override("enable_server_sync", False),
- sync_server_host=get_env_override("sync_server_host", None),
- sync_server_port=get_env_override("sync_server_port", None),
- sync_interval=get_env_override("sync_interval", 300),
-
- registration_mode_timeout=get_env_override("registration_mode_timeout", 60),
- max_satellites=get_env_override("max_satellites", 10), # Lower for standalone
- satellite_heartbeat_timeout=get_env_override("satellite_heartbeat_timeout", 60),
- enable_web_interface=get_env_override("enable_web_interface", True),
- web_interface_port=get_env_override("web_interface_port", DEFAULT_PORTS["web_interface"]),
-
- asset_profile=get_env_override("asset_profile", "default"),
- asset_cache_size=get_env_override("asset_cache_size", 50), # Lower for standalone
-
- conversation_timeout=get_env_override("conversation_timeout", 300),
- max_concurrent_conversations=get_env_override("max_concurrent_conversations", 5), # Lower for standalone
- )
- # Factory function mapping
- DEFAULT_CONFIG_FACTORIES = {
- DeploymentMode.SERVER: create_default_server_config,
- DeploymentMode.CLIENT: create_default_client_config,
- DeploymentMode.STANDALONE: create_default_standalone_config,
- }
- def create_default_config_for_mode(mode: DeploymentMode, debug_mode: bool = False):
- """Create default configuration for the specified mode."""
- factory = DEFAULT_CONFIG_FACTORIES[mode]
- return factory(debug_mode=debug_mode)
- def get_environment_overrides() -> Dict[str, str]:
- """Get all Trixy environment variables."""
- return {
- key[len(ENV_PREFIX):].lower(): value
- for key, value in os.environ.items()
- if key.startswith(ENV_PREFIX)
- }
- def apply_environment_overrides(config_dict: Dict[str, Any]) -> Dict[str, Any]:
- """Apply environment variable overrides to configuration dictionary."""
- overrides = get_environment_overrides()
-
- # Simple flat override for now - can be enhanced for nested overrides
- for key, value in overrides.items():
- if key in config_dict:
- # Try to maintain type consistency
- original_value = config_dict[key]
- if isinstance(original_value, bool):
- config_dict[key] = value.lower() in ('true', '1', 'yes', 'on', 'enabled')
- elif isinstance(original_value, int):
- try:
- config_dict[key] = int(value)
- except ValueError:
- pass # Keep original value
- elif isinstance(original_value, float):
- try:
- config_dict[key] = float(value)
- except ValueError:
- pass # Keep original value
- else:
- config_dict[key] = value
-
- return config_dict
- def get_config_template(mode: DeploymentMode) -> Dict[str, Any]:
- """Get configuration template for documentation/generation purposes."""
- default_config = create_default_config_for_mode(mode, debug_mode=False)
- return default_config.to_dict()
- def validate_environment() -> Dict[str, str]:
- """Validate environment and return any warnings/errors."""
- issues = {}
-
- # Check for required directories
- required_dirs = [
- DEFAULT_PATHS["data_directory"],
- DEFAULT_PATHS["log_directory"],
- DEFAULT_PATHS["config_directory"],
- ]
-
- for dir_path in required_dirs:
- if not Path(dir_path).exists():
- issues[f"missing_directory_{dir_path}"] = f"Directory {dir_path} does not exist and may need to be created"
-
- # Check environment variable conflicts
- env_overrides = get_environment_overrides()
- conflicting_vars = []
-
- # Check for potentially conflicting port assignments
- port_vars = [k for k in env_overrides.keys() if 'port' in k.lower()]
- if len(port_vars) > 1:
- issues["port_conflicts"] = f"Multiple port environment variables detected: {port_vars}. Ensure no conflicts."
-
- return issues
- # Environment variable documentation
- ENV_VAR_DOCS = {
- "TRIXY_DEBUG_MODE": "Enable debug mode (true/false)",
- "TRIXY_LOG_LEVEL": "Logging level (debug/info/warning/error/critical)",
- "TRIXY_COMMAND_PORT": "Command socket port (default: 2101)",
- "TRIXY_AUDIO_INPUT_PORT": "Audio input stream port (default: 2102)",
- "TRIXY_AUDIO_OUTPUT_PORT": "Audio output stream port (default: 2103)",
- "TRIXY_MUSIC_OUTPUT_PORT": "Music output stream port (default: 2104)",
- "TRIXY_WEB_INTERFACE_PORT": "Web interface port (default: 8080)",
- "TRIXY_SERVER_HOST": "Server host for client mode (default: localhost)",
- "TRIXY_ENABLE_ENCRYPTION": "Enable network encryption (true/false)",
- "TRIXY_ENABLE_GPU": "Enable GPU acceleration for ML models (true/false)",
- "TRIXY_MAX_SATELLITES": "Maximum number of connected satellites",
- "TRIXY_PLUGIN_DIRECTORIES": "Comma-separated list of plugin directories",
- }
- def get_env_var_documentation() -> Dict[str, str]:
- """Get documentation for all supported environment variables."""
- return ENV_VAR_DOCS.copy()
|