Coverage for src / moai_adk / hooks / session_start / state_cleanup.py: 0.00%

61 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-20 20:52 +0900

1"""State cleanup module for session_start hook 

2 

3Manages configuration loading, state validation, and cleanup scheduling. 

4 

5Responsibilities: 

6- Load hook timeout from config 

7- Get graceful degradation setting 

8- Load complete configuration 

9- Determine cleanup schedule 

10""" 

11 

12import json 

13import logging 

14from datetime import datetime, timedelta 

15from pathlib import Path 

16from typing import Any, Dict, Optional 

17 

18logger = logging.getLogger(__name__) 

19 

20 

21class StateError(Exception): 

22 """Exception raised for state-related errors""" 

23 

24 pass 

25 

26 

27def load_hook_timeout() -> int: 

28 """Load hook timeout from config.json (default: 3000ms) 

29 

30 Returns: 

31 Timeout in milliseconds (default: 3000) 

32 

33 Raises: 

34 StateError: If config file is corrupted 

35 """ 

36 try: 

37 config_file = Path(".moai/config/config.json") 

38 if config_file.exists(): 

39 with open(config_file, "r", encoding="utf-8") as f: 

40 config = json.load(f) 

41 return config.get("hooks", {}).get("timeout_ms", 3000) 

42 except json.JSONDecodeError as e: 

43 logger.warning(f"Config file corrupted, using default timeout: {e}") 

44 except Exception as e: 

45 logger.warning(f"Failed to load timeout from config: {e}") 

46 

47 return 3000 

48 

49 

50def get_graceful_degradation() -> bool: 

51 """Load graceful_degradation setting from config.json (default: True) 

52 

53 Graceful degradation allows hook to continue even if execution fails. 

54 

55 Returns: 

56 True if graceful degradation enabled (default: True) 

57 

58 Raises: 

59 StateError: If config file is corrupted 

60 """ 

61 try: 

62 config_file = Path(".moai/config/config.json") 

63 if config_file.exists(): 

64 with open(config_file, "r", encoding="utf-8") as f: 

65 config = json.load(f) 

66 return config.get("hooks", {}).get("graceful_degradation", True) 

67 except json.JSONDecodeError as e: 

68 logger.warning(f"Config file corrupted, enabling graceful degradation: {e}") 

69 except Exception as e: 

70 logger.warning(f"Failed to load graceful_degradation from config: {e}") 

71 

72 return True 

73 

74 

75def load_config() -> Dict[str, Any]: 

76 """Load configuration from .moai/config/config.json 

77 

78 Returns: 

79 Configuration dictionary (empty dict if file not found) 

80 

81 Raises: 

82 StateError: If config file is corrupted 

83 """ 

84 try: 

85 config_file = Path(".moai/config/config.json") 

86 if config_file.exists(): 

87 with open(config_file, "r", encoding="utf-8") as f: 

88 return json.load(f) 

89 except json.JSONDecodeError as e: 

90 logger.error(f"Config file corrupted: {e}") 

91 raise StateError(f"Failed to parse config.json: {e}") from e 

92 except Exception as e: 

93 logger.warning(f"Failed to load config: {e}") 

94 

95 return {} 

96 

97 

98def should_cleanup_today( 

99 last_cleanup: Optional[str], cleanup_days: int = 7 

100) -> bool: 

101 """Determine if cleanup is needed today 

102 

103 Args: 

104 last_cleanup: Last cleanup date in YYYY-MM-DD format (None for first run) 

105 cleanup_days: Cleanup interval in days (default: 7) 

106 

107 Returns: 

108 True if cleanup is needed, False otherwise 

109 

110 Raises: 

111 StateError: If date parsing fails 

112 """ 

113 if not last_cleanup: 

114 return True 

115 

116 try: 

117 last_date = datetime.strptime(last_cleanup, "%Y-%m-%d") 

118 next_cleanup = last_date + timedelta(days=cleanup_days) 

119 return datetime.now() >= next_cleanup 

120 except ValueError as e: 

121 logger.warning(f"Invalid date format: {last_cleanup}: {e}") 

122 return True 

123 

124 

125def validate_cleanup_config(config: Dict[str, Any]) -> bool: 

126 """Validate cleanup configuration 

127 

128 Args: 

129 config: Configuration dictionary 

130 

131 Returns: 

132 True if configuration is valid 

133 

134 Raises: 

135 StateError: If configuration is invalid 

136 """ 

137 cleanup_config = config.get("auto_cleanup", {}) 

138 

139 # Check required fields 

140 if not isinstance(cleanup_config.get("cleanup_days"), (int, float)): 

141 logger.warning("cleanup_days not configured, using default 7") 

142 

143 if not isinstance(cleanup_config.get("max_reports"), (int, float)): 

144 logger.warning("max_reports not configured, using default 10") 

145 

146 return True