Coverage for session_buddy / config / feature_flags.py: 92.31%

24 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-04 00:43 -0800

1""" 

2Feature flags for Memori-inspired features and staged rollout. 

3 

4Flags default to False for safe rollouts and can be enabled via: 

5- Environment variables (e.g., SESSION_BUDDY_USE_SCHEMA_V2=true) 

6- YAML settings (settings/session-buddy.yaml or local.yaml) 

7 

8Usage: 

9 from session_buddy.config.feature_flags import get_feature_flags 

10 flags = get_feature_flags() 

11 if flags.use_schema_v2: 

12 ... 

13""" 

14 

15from __future__ import annotations 

16 

17import os 

18import typing as t 

19from dataclasses import dataclass 

20 

21from session_buddy.settings import get_settings 

22 

23 

24@dataclass(slots=True) 

25class FeatureFlags: 

26 """Typed feature flags for staged enablement.""" 

27 

28 # Storage + schema 

29 use_schema_v2: bool = False 

30 

31 # Extraction cascade 

32 enable_llm_entity_extraction: bool = False 

33 enable_anthropic: bool = False 

34 enable_ollama: bool = False 

35 

36 # Background optimization 

37 enable_conscious_agent: bool = False 

38 

39 # Filesystem integration 

40 enable_filesystem_extraction: bool = False 

41 

42 

43_ENV_BOOL = { 

44 "true": True, 

45 "1": True, 

46 "yes": True, 

47 "on": True, 

48 "false": False, 

49 "0": False, 

50 "no": False, 

51 "off": False, 

52} 

53 

54 

55def _get_env_bool(name: str, default: bool) -> bool: 

56 val = os.getenv(name) 

57 if val is None: 57 ↛ 59line 57 didn't jump to line 59 because the condition on line 57 was always true

58 return default 

59 return _ENV_BOOL.get(val.strip().lower(), default) 

60 

61 

62def get_feature_flags() -> FeatureFlags: 

63 """Load flags from settings with env overrides. 

64 

65 Order of precedence: 

66 1) Environment variables (SESSION_MGMT_*) 

67 2) YAML settings via MCPBaseSettings 

68 3) Defaults (all False) 

69 """ 

70 settings = get_settings() 

71 

72 # Base flags from settings if present (fallback False) 

73 base = FeatureFlags( 

74 use_schema_v2=bool(getattr(settings, "use_schema_v2", False)), 

75 enable_llm_entity_extraction=bool( 

76 getattr(settings, "enable_llm_entity_extraction", False) 

77 ), 

78 enable_anthropic=bool(getattr(settings, "enable_anthropic", False)), 

79 enable_ollama=bool(getattr(settings, "enable_ollama", False)), 

80 enable_conscious_agent=bool(getattr(settings, "enable_conscious_agent", False)), 

81 enable_filesystem_extraction=bool( 

82 getattr(settings, "enable_filesystem_extraction", False) 

83 ), 

84 ) 

85 

86 # Env overrides 

87 return FeatureFlags( 

88 use_schema_v2=_get_env_bool("SESSION_MGMT_USE_SCHEMA_V2", base.use_schema_v2), 

89 enable_llm_entity_extraction=_get_env_bool( 

90 "SESSION_MGMT_ENABLE_LLM_ENTITY_EXTRACTION", 

91 base.enable_llm_entity_extraction, 

92 ), 

93 enable_anthropic=_get_env_bool( 

94 "SESSION_MGMT_ENABLE_ANTHROPIC", base.enable_anthropic 

95 ), 

96 enable_ollama=_get_env_bool("SESSION_MGMT_ENABLE_OLLAMA", base.enable_ollama), 

97 enable_conscious_agent=_get_env_bool( 

98 "SESSION_MGMT_ENABLE_CONSCIOUS_AGENT", base.enable_conscious_agent 

99 ), 

100 enable_filesystem_extraction=_get_env_bool( 

101 "SESSION_MGMT_ENABLE_FILESYSTEM_EXTRACTION", 

102 base.enable_filesystem_extraction, 

103 ), 

104 ) 

105 

106 

107__all__ = ["FeatureFlags", "get_feature_flags"]