File size: 13,986 Bytes
9846bab
3fcbb60
34a2ea0
9846bab
 
afcb2da
3fcbb60
 
 
f899610
3fcbb60
f899610
3fcbb60
 
f899610
 
3fcbb60
 
 
 
9846bab
3fcbb60
 
9846bab
3fcbb60
9846bab
3fcbb60
9846bab
 
 
3fcbb60
 
9846bab
 
3fcbb60
 
 
 
 
 
9846bab
afcb2da
3fcbb60
afcb2da
 
3fcbb60
 
 
afcb2da
3fcbb60
 
 
34a2ea0
3fcbb60
 
 
 
 
 
 
afcb2da
3fcbb60
 
 
 
 
afcb2da
34a2ea0
 
3fcbb60
afcb2da
3fcbb60
 
 
 
 
 
 
afcb2da
3fcbb60
 
 
 
 
afcb2da
3fcbb60
 
 
 
c547d64
afcb2da
3fcbb60
 
 
 
afcb2da
3fcbb60
 
 
afcb2da
3fcbb60
 
 
 
34a2ea0
3fcbb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9846bab
3fcbb60
 
 
34a2ea0
3fcbb60
 
 
 
 
68150cc
3fcbb60
 
 
 
 
 
34a2ea0
 
3fcbb60
 
 
 
 
 
 
 
68150cc
 
3fcbb60
 
 
 
 
68150cc
3fcbb60
 
 
 
c547d64
68150cc
3fcbb60
 
 
 
68150cc
3fcbb60
 
 
68150cc
3fcbb60
 
 
 
34a2ea0
68150cc
3fcbb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68150cc
3fcbb60
f899610
3fcbb60
 
 
 
 
34a2ea0
f899610
3fcbb60
34a2ea0
3fcbb60
 
 
 
 
34a2ea0
3fcbb60
 
 
 
 
 
 
 
 
 
 
c547d64
3fcbb60
 
 
 
 
 
 
 
34a2ea0
3fcbb60
 
 
9846bab
 
3fcbb60
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
"""
ARF Settings Configuration with Pydantic 2.x Compatibility
Fixed for both OSS and Enterprise deployments - FIXED VERSION CONSISTENCY
"""
import os
import sys
from enum import Enum
from typing import Optional, Dict, Any, List, Union
from datetime import datetime

# Try to import pydantic with version detection
try:
    from pydantic import Field, validator, model_validator
    from pydantic_settings import BaseSettings, SettingsConfigDict
    PYDANTIC_V2 = True
except ImportError:
    # Fallback for pydantic v1
    from pydantic import Field, validator
    from pydantic_settings import BaseSettings
    PYDANTIC_V2 = False

import logging
logger = logging.getLogger(__name__)

# Enums for ARF modes
class ARFMode(str, Enum):
    """ARF Operational Modes"""
    DEMO = "demo"
    OSS = "oss"
    ENTERPRISE = "enterprise"
    HYBRID = "hybrid"
    SIMULATION = "simulation"

class SafetyMode(str, Enum):
    """Safety and Compliance Modes"""
    STANDARD = "standard"
    STRICT = "strict"
    PERMISSIVE = "permissive"
    ENTERPRISE = "enterprise"
    COMPLIANCE = "compliance"

class InstallationStatus(str, Enum):
    """Package Installation Status"""
    NOT_INSTALLED = "not_installed"
    OSS_ONLY = "oss_only"
    ENTERPRISE_ONLY = "enterprise_only"
    FULL_INSTALL = "full_install"
    DEMO_MODE = "demo_mode"

# Pydantic 2.x compatible Settings class
if PYDANTIC_V2:
    class Settings(BaseSettings):
        """ARF Settings with Pydantic 2.x compatibility - FIXED: Version consistency"""
        model_config = SettingsConfigDict(
            env_file=".env",
            env_file_encoding="utf-8",
            env_prefix="ARF_",
            case_sensitive=False,
            extra="ignore"
        )
        
        # Core Settings
        arf_mode: ARFMode = Field(default=ARFMode.DEMO, description="ARF operational mode")
        safety_mode: SafetyMode = Field(default=SafetyMode.STANDARD, description="Safety compliance mode")
        debug: bool = Field(default=False, description="Enable debug logging")
        log_level: str = Field(default="INFO", description="Logging level")
        
        # Version Info - FIXED: Updated to v3.3.9 (actual PyPI version)
        arf_version: str = Field(default="3.3.9", description="ARF version")
        demo_version: str = Field(default="3.8.0", description="Demo app version")
        
        # Installation Status
        oss_installed: bool = Field(default=False, description="ARF OSS package installed")
        enterprise_installed: bool = Field(default=False, description="Enterprise package installed")
        installation_status: InstallationStatus = Field(
            default=InstallationStatus.DEMO_MODE,
            description="Overall installation status"
        )
        
        # Feature Flags
        enable_telemetry: bool = Field(default=True, description="Enable telemetry collection")
        enable_anomaly_detection: bool = Field(default=True, description="Enable anomaly detection")
        enable_business_metrics: bool = Field(default=True, description="Enable business metrics")
        enable_audit_trail: bool = Field(default=True, description="Enable audit trail")
        
        # Paths
        data_dir: str = Field(default="./data", description="Data directory")
        log_dir: str = Field(default="./logs", description="Log directory")
        cache_dir: str = Field(default="./cache", description="Cache directory")
        scenario_config_path: str = Field(default="./config/scenarios", description="Path to scenario configuration files")
        
        # API Settings
        api_timeout: int = Field(default=30, description="API timeout in seconds")
        max_retries: int = Field(default=3, description="Maximum API retries")
        rate_limit: int = Field(default=100, description="API rate limit per minute")
        
        # UI Settings
        ui_theme: str = Field(default="dark", description="UI theme")
        refresh_interval: int = Field(default=5, description="UI refresh interval in seconds")
        
        # Business Settings
        default_currency: str = Field(default="USD", description="Default currency")
        cost_per_incident: float = Field(default=10000.0, description="Default cost per incident")
        engineer_hourly_rate: float = Field(default=150.0, description="Engineer hourly rate")
        engineer_annual_cost: float = Field(default=200000.0, description="Engineer annual cost")
        
        @model_validator(mode='before')
        @classmethod
        def validate_enums(cls, data: Any) -> Any:
            """Validate and convert enum fields from strings"""
            if isinstance(data, dict):
                # Convert string values to enums if needed
                if 'arf_mode' in data and isinstance(data['arf_mode'], str):
                    try:
                        data['arf_mode'] = ARFMode(data['arf_mode'].lower())
                    except ValueError:
                        data['arf_mode'] = ARFMode.DEMO
                
                if 'safety_mode' in data and isinstance(data['safety_mode'], str):
                    try:
                        data['safety_mode'] = SafetyMode(data['safety_mode'].lower())
                    except ValueError:
                        data['safety_mode'] = SafetyMode.STANDARD
                
                if 'installation_status' in data and isinstance(data['installation_status'], str):
                    try:
                        data['installation_status'] = InstallationStatus(data['installation_status'].lower())
                    except ValueError:
                        data['installation_status'] = InstallationStatus.DEMO_MODE
            return data
        
        @model_validator(mode='after')
        def check_installation_status(self):
            """Update installation status based on detected packages"""
            # Check if OSS is installed
            try:
                import agentic_reliability_framework
                self.oss_installed = True
            except ImportError:
                self.oss_installed = False
            
            # Check if Enterprise is installed
            try:
                import agentic_reliability_enterprise
                self.enterprise_installed = True
            except ImportError:
                self.enterprise_installed = False
            
            # Update installation status
            if self.oss_installed and self.enterprise_installed:
                self.installation_status = InstallationStatus.FULL_INSTALL
            elif self.oss_installed:
                self.installation_status = InstallationStatus.OSS_ONLY
            elif self.enterprise_installed:
                self.installation_status = InstallationStatus.ENTERPRISE_ONLY
            else:
                self.installation_status = InstallationStatus.DEMO_MODE
            
            return self

else:
    # Pydantic v1 compatible Settings class
    class Settings(BaseSettings):
        """ARF Settings with Pydantic v1 compatibility - FIXED: Version consistency"""
        class Config:
            env_file = ".env"
            env_file_encoding = "utf-8"
            env_prefix = "ARF_"
            case_sensitive = False
        
        # Core Settings
        arf_mode: ARFMode = Field(default=ARFMode.DEMO, description="ARF operational mode")
        safety_mode: SafetyMode = Field(default=SafetyMode.STANDARD, description="Safety compliance mode")
        debug: bool = Field(default=False, description="Enable debug logging")
        log_level: str = Field(default="INFO", description="Logging level")
        
        # Version Info - FIXED: Updated to v3.3.9 (actual PyPI version)
        arf_version: str = Field(default="3.3.9", description="ARF version")
        demo_version: str = Field(default="3.8.0", description="Demo app version")
        
        # Installation Status
        oss_installed: bool = Field(default=False, description="ARF OSS package installed")
        enterprise_installed: bool = Field(default=False, description="Enterprise package installed")
        installation_status: InstallationStatus = Field(
            default=InstallationStatus.DEMO_MODE,
            description="Overall installation status"
        )
        
        # Feature Flags
        enable_telemetry: bool = Field(default=True, description="Enable telemetry collection")
        enable_anomaly_detection: bool = Field(default=True, description="Enable anomaly detection")
        enable_business_metrics: bool = Field(default=True, description="Enable business metrics")
        enable_audit_trail: bool = Field(default=True, description="Enable audit trail")
        
        # Paths
        data_dir: str = Field(default="./data", description="Data directory")
        log_dir: str = Field(default="./logs", description="Log directory")
        cache_dir: str = Field(default="./cache", description="Cache directory")
        scenario_config_path: str = Field(default="./config/scenarios", description="Path to scenario configuration files")
        
        # API Settings
        api_timeout: int = Field(default=30, description="API timeout in seconds")
        max_retries: int = Field(default=3, description="Maximum API retries")
        rate_limit: int = Field(default=100, description="API rate limit per minute")
        
        # UI Settings
        ui_theme: str = Field(default="dark", description="UI theme")
        refresh_interval: int = Field(default=5, description="UI refresh interval in seconds")
        
        # Business Settings
        default_currency: str = Field(default="USD", description="Default currency")
        cost_per_incident: float = Field(default=10000.0, description="Default cost per incident")
        engineer_hourly_rate: float = Field(default=150.0, description="Engineer hourly rate")
        engineer_annual_cost: float = Field(default=200000.0, description="Engineer annual cost")
        
        @validator('arf_mode', 'safety_mode', 'installation_status', pre=True)
        def validate_enum_strings(cls, v, field):
            """Convert string values to enums"""
            if isinstance(v, str):
                try:
                    if field.name == 'arf_mode':
                        return ARFMode(v.lower())
                    elif field.name == 'safety_mode':
                        return SafetyMode(v.lower())
                    elif field.name == 'installation_status':
                        return InstallationStatus(v.lower())
                except ValueError:
                    # Return default value
                    if field.name == 'arf_mode':
                        return ARFMode.DEMO
                    elif field.name == 'safety_mode':
                        return SafetyMode.STANDARD
                    elif field.name == 'installation_status':
                        return InstallationStatus.DEMO_MODE
            return v
        
        @validator('installation_status', always=True)
        def update_installation_status(cls, v, values):
            """Update installation status based on detected packages"""
            # Check if OSS is installed
            try:
                import agentic_reliability_framework
                values['oss_installed'] = True
            except ImportError:
                values['oss_installed'] = False
            
            # Check if Enterprise is installed
            try:
                import agentic_reliability_enterprise
                values['enterprise_installed'] = True
            except ImportError:
                values['enterprise_installed'] = False
            
            # Determine installation status
            if values.get('oss_installed') and values.get('enterprise_installed'):
                return InstallationStatus.FULL_INSTALL
            elif values.get('oss_installed'):
                return InstallationStatus.OSS_ONLY
            elif values.get('enterprise_installed'):
                return InstallationStatus.ENTERPRISE_ONLY
            else:
                return InstallationStatus.DEMO_MODE

# Singleton settings instance
try:
    settings = Settings()
    logger.info("✅ Settings initialized successfully")
    logger.info(f"📊 ARF Mode: {settings.arf_mode}")
    logger.info(f"🛡️ Safety Mode: {settings.safety_mode}")
    logger.info(f"📦 Installation Status: {settings.installation_status}")
    logger.info(f"🔖 ARF Version: {settings.arf_version}")  # Added version logging
except Exception as e:
    logger.error(f"❌ Failed to initialize settings: {e}")
    # Create fallback settings - FIXED: Updated version to 3.3.9
    class FallbackSettings:
        arf_mode = ARFMode.DEMO
        safety_mode = SafetyMode.STANDARD
        debug = False
        log_level = "INFO"
        arf_version = "3.3.9"  # FIXED: Updated from 3.3.7 to 3.3.9
        demo_version = "3.8.0"
        oss_installed = False
        enterprise_installed = False
        installation_status = InstallationStatus.DEMO_MODE
        enable_telemetry = True
        enable_anomaly_detection = True
        enable_business_metrics = True
        enable_audit_trail = True
        data_dir = "./data"
        log_dir = "./logs"
        cache_dir = "./cache"
        scenario_config_path = "./config/scenarios"
        api_timeout = 30
        max_retries = 3
        rate_limit = 100
        ui_theme = "dark"
        refresh_interval = 5
        default_currency = "USD"
        cost_per_incident = 10000.0
        engineer_hourly_rate = 150.0
        engineer_annual_cost = 200000.0
    
    settings = FallbackSettings()
    logger.warning("⚠️ Using fallback settings due to initialization error")

def get_settings() -> Settings:
    """Get the settings singleton instance"""
    return settings

# Export everything
__all__ = [
    "Settings",
    "get_settings",
    "ARFMode",
    "SafetyMode",
    "InstallationStatus",
    "settings"
]