1"""Feature detection and availability checking.

2

3 This module provides the FeatureDetector class for detecting available

4 features and dependencies in the runtime environment.

5"""

6

7 from __future__ import annotations

8

9 import importlib.util

10 import logging

11

12 logger = logging.getLogger(__name__)

13

14

15 class FeatureDetector:

16 """Centralized feature detection for MCP server capabilities."""

17

18 def __init__(self) -> None:

19 """Initialize feature detector with all availability checks."""

20 self.SESSION_MANAGEMENT_AVAILABLE = self._check_session_management()

21 self.REFLECTION_TOOLS_AVAILABLE = self._check_reflection_tools()

22 self.ENHANCED_SEARCH_AVAILABLE = self._check_enhanced_search()

23 self.UTILITY_FUNCTIONS_AVAILABLE = self._check_utility_functions()

24 self.MULTI_PROJECT_AVAILABLE = self._check_multi_project()

25 self.ADVANCED_SEARCH_AVAILABLE = self._check_advanced_search()

26 self.CONFIG_AVAILABLE = self._check_config()

27 self.AUTO_CONTEXT_AVAILABLE = self._check_auto_context()

28 self.MEMORY_OPTIMIZER_AVAILABLE = self._check_memory_optimizer()

29 self.APP_MONITOR_AVAILABLE = self._check_app_monitor()

30 self.LLM_PROVIDERS_AVAILABLE = self._check_llm_providers()

31 self.SERVERLESS_MODE_AVAILABLE = self._check_serverless_mode()

32 self.CRACKERJACK_INTEGRATION_AVAILABLE = self._check_crackerjack()

33

34 @staticmethod

35 def _check_session_management() -> bool:

36 """Check if session management is available."""

37 try:

38 import session_buddy.core

39

40 _ = (

41 session_buddy.core.session_manager

42 ) # Reference to avoid unused import warning during static analysis

43 return True

44 except ImportError:

45 return False

46

47 @staticmethod

48 def _check_reflection_tools() -> bool:

49 """Check if reflection tools are available."""

50 try:

51 import session_buddy.reflection_tools

52

53 _ = (

54 session_buddy.reflection_tools

55 ) # Use the import to avoid unused import warning

56 return True

57 except ImportError:

58 return False

59

60 @staticmethod

61 def _check_enhanced_search() -> bool:

62 """Check if enhanced search is available."""

63 try:

64 return importlib.util.find_spec("session_buddy.search_enhanced") is not None

65 except ImportError:

66 return False

67

68 @staticmethod

69 def _check_utility_functions() -> bool:

70 """Check if utility functions are available."""

71 try:

72 # Check for the general module availability without importing unused functions

73 return (

74 importlib.util.find_spec("session_buddy.tools.search_tools") is not None

75 )

76 except ImportError:

77 return False

78

79 @staticmethod

80 def _check_multi_project() -> bool:

81 """Check if multi-project coordination is available."""

82 try:

83 return (

84 importlib.util.find_spec("session_buddy.multi_project_coordinator")

85 is not None

86 )

87 except ImportError:

88 return False

89

90 @staticmethod

91 def _check_advanced_search() -> bool:

92 """Check if advanced search engine is available."""

93 try:

94 return importlib.util.find_spec("session_buddy.advanced_search") is not None

95 except ImportError:

96 return False

97

98 @staticmethod

99 def _check_config() -> bool:

100 """Check if configuration management is available."""

101 try:

102 return importlib.util.find_spec("session_buddy.settings") is not None

103 except ImportError:

104 return False

105

106 @staticmethod

107 def _check_auto_context() -> bool:

108 """Check if auto-context loading is available."""

109 try:

110 return importlib.util.find_spec("session_buddy.context_manager") is not None

111 except ImportError:

112 return False

113

114 @staticmethod

115 def _check_memory_optimizer() -> bool:

116 """Check if memory optimizer is available."""

117 try:

118 return (

119 importlib.util.find_spec("session_buddy.memory_optimizer") is not None

120 )

121 except ImportError:

122 return False

123

124 @staticmethod

125 def _check_app_monitor() -> bool:

126 """Check if application monitoring is available."""

127 try:

128 return importlib.util.find_spec("session_buddy.app_monitor") is not None

129 except ImportError:

130 return False

131

132 @staticmethod

133 def _check_llm_providers() -> bool:

134 """Check if LLM providers are available."""

135 try:

136 return importlib.util.find_spec("session_buddy.llm_providers") is not None

137 except ImportError:

138 return False

139

140 @staticmethod

141 def _check_serverless_mode() -> bool:

142 """Check if serverless mode is available."""

143 try:

144 return importlib.util.find_spec("session_buddy.serverless_mode") is not None

145 except ImportError:

146 return False

147

148 @staticmethod

149 def _check_crackerjack() -> bool:

150 """Check if crackerjack integration is available."""

151 try:

152 return (

153 importlib.util.find_spec("session_buddy.crackerjack_integration")

154 is not None

155 )

156 except ImportError:

157 return False

158

159 def get_feature_flags(self) -> dict[str, bool]:

160 """Get all feature flags as a dictionary."""

161 return {

162 "SESSION_MANAGEMENT_AVAILABLE": self.SESSION_MANAGEMENT_AVAILABLE,

163 "REFLECTION_TOOLS_AVAILABLE": self.REFLECTION_TOOLS_AVAILABLE,

164 "ENHANCED_SEARCH_AVAILABLE": self.ENHANCED_SEARCH_AVAILABLE,

165 "UTILITY_FUNCTIONS_AVAILABLE": self.UTILITY_FUNCTIONS_AVAILABLE,

166 "MULTI_PROJECT_AVAILABLE": self.MULTI_PROJECT_AVAILABLE,

167 "ADVANCED_SEARCH_AVAILABLE": self.ADVANCED_SEARCH_AVAILABLE,

168 "CONFIG_AVAILABLE": self.CONFIG_AVAILABLE,

169 "AUTO_CONTEXT_AVAILABLE": self.AUTO_CONTEXT_AVAILABLE,

170 "MEMORY_OPTIMIZER_AVAILABLE": self.MEMORY_OPTIMIZER_AVAILABLE,

171 "APP_MONITOR_AVAILABLE": self.APP_MONITOR_AVAILABLE,

172 "LLM_PROVIDERS_AVAILABLE": self.LLM_PROVIDERS_AVAILABLE,

173 "SERVERLESS_MODE_AVAILABLE": self.SERVERLESS_MODE_AVAILABLE,

174 "CRACKERJACK_INTEGRATION_AVAILABLE": self.CRACKERJACK_INTEGRATION_AVAILABLE,

175 }

176

177

178# Create global feature detector instance

179_feature_detector = FeatureDetector()

180

181

182 def get_feature_flags() -> dict[str, bool]:

183 """Get feature availability flags for the MCP server.

184

185 Returns:

186 Dictionary mapping feature names to availability status.

187

188 """

189 return _feature_detector.get_feature_flags()