Coverage for session_buddy / tools / protocols.py: 100.00%

4 statements  

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

1"""Protocol definitions for crackerjack workflow components. 

2 

3These protocols define interfaces for dependency injection and testing. 

4""" 

5 

6from typing import Any, Protocol 

7 

8from .agent_analyzer import AgentRecommendation 

9from .quality_metrics import QualityMetrics 

10from .recommendation_engine import AgentEffectiveness 

11 

12 

13class QualityMetricsExtractorProtocol(Protocol): 

14 """Protocol for extracting quality metrics from crackerjack output.""" 

15 

16 @classmethod 

17 def extract(cls, stdout: str, stderr: str) -> QualityMetrics: 

18 """Extract metrics from crackerjack output. 

19 

20 Args: 

21 stdout: Standard output from crackerjack execution 

22 stderr: Standard error from crackerjack execution 

23 

24 Returns: 

25 QualityMetrics object with extracted values 

26 

27 """ 

28 ... 

29 

30 

31class AgentAnalyzerProtocol(Protocol): 

32 """Protocol for analyzing failures and recommending agents.""" 

33 

34 @classmethod 

35 def analyze( 

36 cls, 

37 stdout: str, 

38 stderr: str, 

39 exit_code: int, 

40 ) -> list[AgentRecommendation]: 

41 """Analyze crackerjack output and recommend agents. 

42 

43 Args: 

44 stdout: Standard output from crackerjack 

45 stderr: Standard error from crackerjack 

46 exit_code: Process exit code 

47 

48 Returns: 

49 List of agent recommendations sorted by confidence 

50 

51 """ 

52 ... 

53 

54 @classmethod 

55 def format_recommendations(cls, recommendations: list[AgentRecommendation]) -> str: 

56 """Format recommendations for display. 

57 

58 Args: 

59 recommendations: List of agent recommendations 

60 

61 Returns: 

62 Formatted string for user display 

63 

64 """ 

65 ... 

66 

67 

68class RecommendationEngineProtocol(Protocol): 

69 """Protocol for learning from execution history.""" 

70 

71 @classmethod 

72 async def analyze_history( 

73 cls, 

74 db: Any, 

75 project: str, 

76 days: int = 30, 

77 ) -> dict[str, Any]: 

78 """Analyze execution history for patterns and effectiveness. 

79 

80 Args: 

81 db: ReflectionDatabase instance 

82 project: Project name 

83 days: Number of days to analyze 

84 

85 Returns: 

86 Dictionary with patterns, agent effectiveness, and insights 

87 

88 """ 

89 ... 

90 

91 @classmethod 

92 def adjust_confidence( 

93 cls, 

94 recommendations: list[AgentRecommendation], 

95 effectiveness: list[AgentEffectiveness], 

96 ) -> list[AgentRecommendation]: 

97 """Adjust recommendation confidence scores based on historical effectiveness. 

98 

99 Args: 

100 recommendations: Original recommendations from AgentAnalyzer 

101 effectiveness: Historical effectiveness data 

102 

103 Returns: 

104 Recommendations with adjusted confidence scores 

105 

106 """ 

107 ... 

108 

109 

110class ReflectionDatabaseProtocol(Protocol): 

111 """Protocol for reflection database operations.""" 

112 

113 async def search_conversations( 

114 self, 

115 query: str, 

116 project: str | None = None, 

117 limit: int = 50, 

118 min_score: float = 0.7, 

119 ) -> list[dict[str, Any]]: 

120 """Search for conversations in the database. 

121 

122 Args: 

123 query: Search query text 

124 project: Optional project filter 

125 limit: Maximum number of results 

126 min_score: Minimum similarity score 

127 

128 Returns: 

129 List of conversation results 

130 

131 """ 

132 ... 

133 

134 async def store_conversation( 

135 self, 

136 content: str, 

137 metadata: dict[str, Any] | None = None, 

138 ) -> None: 

139 """Store a conversation in the database. 

140 

141 Args: 

142 content: Conversation content 

143 metadata: Optional metadata dictionary 

144 

145 """ 

146 ... 

147 

148 async def __aenter__(self) -> "ReflectionDatabaseProtocol": 

149 """Async context manager entry.""" 

150 ... 

151 

152 async def __aexit__(self, *args: object) -> None: 

153 """Async context manager exit.""" 

154 ... 

155 

156 

157class CrackerjackResultProtocol(Protocol): 

158 """Protocol for crackerjack execution results.""" 

159 

160 @property 

161 def exit_code(self) -> int: 

162 """Process exit code.""" 

163 ... 

164 

165 @property 

166 def stdout(self) -> str: 

167 """Standard output.""" 

168 ... 

169 

170 @property 

171 def stderr(self) -> str: 

172 """Standard error.""" 

173 ... 

174 

175 @property 

176 def execution_time(self) -> float: 

177 """Execution time in seconds.""" 

178 ... 

179 

180 

181class CrackerjackIntegrationProtocol(Protocol): 

182 """Protocol for crackerjack integration.""" 

183 

184 async def execute_crackerjack_command( 

185 self, 

186 command: str, 

187 args: list[str] | None = None, 

188 working_directory: str = ".", 

189 timeout: int = 300, 

190 ai_agent_mode: bool = False, 

191 ) -> CrackerjackResultProtocol: 

192 """Execute a crackerjack command. 

193 

194 Args: 

195 command: Command to execute 

196 args: Optional command arguments 

197 working_directory: Working directory 

198 timeout: Timeout in seconds 

199 ai_agent_mode: Whether to enable AI agent mode 

200 

201 Returns: 

202 CrackerjackResult with execution details 

203 

204 """ 

205 ...