empathy-framework 2.4.0__py3-none-any.whl → 3.8.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. coach_wizards/__init__.py +13 -12
  2. coach_wizards/accessibility_wizard.py +12 -12
  3. coach_wizards/api_wizard.py +12 -12
  4. coach_wizards/base_wizard.py +26 -20
  5. coach_wizards/cicd_wizard.py +15 -13
  6. coach_wizards/code_reviewer_README.md +60 -0
  7. coach_wizards/code_reviewer_wizard.py +180 -0
  8. coach_wizards/compliance_wizard.py +12 -12
  9. coach_wizards/database_wizard.py +12 -12
  10. coach_wizards/debugging_wizard.py +12 -12
  11. coach_wizards/documentation_wizard.py +12 -12
  12. coach_wizards/generate_wizards.py +1 -2
  13. coach_wizards/localization_wizard.py +101 -19
  14. coach_wizards/migration_wizard.py +12 -12
  15. coach_wizards/monitoring_wizard.py +12 -12
  16. coach_wizards/observability_wizard.py +12 -12
  17. coach_wizards/performance_wizard.py +12 -12
  18. coach_wizards/prompt_engineering_wizard.py +661 -0
  19. coach_wizards/refactoring_wizard.py +12 -12
  20. coach_wizards/scaling_wizard.py +12 -12
  21. coach_wizards/security_wizard.py +12 -12
  22. coach_wizards/testing_wizard.py +12 -12
  23. empathy_framework-3.8.2.dist-info/METADATA +1176 -0
  24. empathy_framework-3.8.2.dist-info/RECORD +333 -0
  25. empathy_framework-3.8.2.dist-info/entry_points.txt +22 -0
  26. {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/top_level.txt +5 -1
  27. empathy_healthcare_plugin/__init__.py +1 -2
  28. empathy_healthcare_plugin/monitors/__init__.py +9 -0
  29. empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
  30. empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
  31. empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
  32. empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
  33. empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
  34. empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
  35. empathy_llm_toolkit/__init__.py +7 -7
  36. empathy_llm_toolkit/agent_factory/__init__.py +53 -0
  37. empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
  38. empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
  39. empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
  40. empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
  41. empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
  42. empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
  43. empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
  44. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
  45. empathy_llm_toolkit/agent_factory/base.py +305 -0
  46. empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
  47. empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
  48. empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
  49. empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
  50. empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
  51. empathy_llm_toolkit/agent_factory/decorators.py +286 -0
  52. empathy_llm_toolkit/agent_factory/factory.py +558 -0
  53. empathy_llm_toolkit/agent_factory/framework.py +192 -0
  54. empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
  55. empathy_llm_toolkit/agent_factory/resilient.py +320 -0
  56. empathy_llm_toolkit/claude_memory.py +14 -15
  57. empathy_llm_toolkit/cli/__init__.py +8 -0
  58. empathy_llm_toolkit/cli/sync_claude.py +487 -0
  59. empathy_llm_toolkit/code_health.py +186 -28
  60. empathy_llm_toolkit/config/__init__.py +29 -0
  61. empathy_llm_toolkit/config/unified.py +295 -0
  62. empathy_llm_toolkit/contextual_patterns.py +11 -12
  63. empathy_llm_toolkit/core.py +168 -53
  64. empathy_llm_toolkit/git_pattern_extractor.py +17 -13
  65. empathy_llm_toolkit/levels.py +6 -13
  66. empathy_llm_toolkit/pattern_confidence.py +14 -18
  67. empathy_llm_toolkit/pattern_resolver.py +10 -12
  68. empathy_llm_toolkit/pattern_summary.py +16 -14
  69. empathy_llm_toolkit/providers.py +194 -28
  70. empathy_llm_toolkit/routing/__init__.py +32 -0
  71. empathy_llm_toolkit/routing/model_router.py +362 -0
  72. empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
  73. empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
  74. empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
  75. empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
  76. empathy_llm_toolkit/security/README.md +262 -0
  77. empathy_llm_toolkit/security/__init__.py +62 -0
  78. empathy_llm_toolkit/security/audit_logger.py +929 -0
  79. empathy_llm_toolkit/security/audit_logger_example.py +152 -0
  80. empathy_llm_toolkit/security/pii_scrubber.py +640 -0
  81. empathy_llm_toolkit/security/secrets_detector.py +678 -0
  82. empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
  83. empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
  84. empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
  85. empathy_llm_toolkit/session_status.py +20 -22
  86. empathy_llm_toolkit/state.py +28 -21
  87. empathy_llm_toolkit/wizards/__init__.py +38 -0
  88. empathy_llm_toolkit/wizards/base_wizard.py +364 -0
  89. empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
  90. empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
  91. empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
  92. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
  93. empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
  94. empathy_os/__init__.py +125 -84
  95. empathy_os/adaptive/__init__.py +13 -0
  96. empathy_os/adaptive/task_complexity.py +127 -0
  97. empathy_os/{monitoring.py → agent_monitoring.py} +28 -28
  98. empathy_os/cache/__init__.py +117 -0
  99. empathy_os/cache/base.py +166 -0
  100. empathy_os/cache/dependency_manager.py +253 -0
  101. empathy_os/cache/hash_only.py +248 -0
  102. empathy_os/cache/hybrid.py +390 -0
  103. empathy_os/cache/storage.py +282 -0
  104. empathy_os/cli.py +1516 -70
  105. empathy_os/cli_unified.py +597 -0
  106. empathy_os/config/__init__.py +63 -0
  107. empathy_os/config/xml_config.py +239 -0
  108. empathy_os/config.py +95 -37
  109. empathy_os/coordination.py +72 -68
  110. empathy_os/core.py +94 -107
  111. empathy_os/cost_tracker.py +74 -55
  112. empathy_os/dashboard/__init__.py +15 -0
  113. empathy_os/dashboard/server.py +743 -0
  114. empathy_os/discovery.py +17 -14
  115. empathy_os/emergence.py +21 -22
  116. empathy_os/exceptions.py +18 -30
  117. empathy_os/feedback_loops.py +30 -33
  118. empathy_os/levels.py +32 -35
  119. empathy_os/leverage_points.py +31 -32
  120. empathy_os/logging_config.py +19 -16
  121. empathy_os/memory/__init__.py +195 -0
  122. empathy_os/memory/claude_memory.py +466 -0
  123. empathy_os/memory/config.py +224 -0
  124. empathy_os/memory/control_panel.py +1298 -0
  125. empathy_os/memory/edges.py +179 -0
  126. empathy_os/memory/graph.py +567 -0
  127. empathy_os/memory/long_term.py +1194 -0
  128. empathy_os/memory/nodes.py +179 -0
  129. empathy_os/memory/redis_bootstrap.py +540 -0
  130. empathy_os/memory/security/__init__.py +31 -0
  131. empathy_os/memory/security/audit_logger.py +930 -0
  132. empathy_os/memory/security/pii_scrubber.py +640 -0
  133. empathy_os/memory/security/secrets_detector.py +678 -0
  134. empathy_os/memory/short_term.py +2119 -0
  135. empathy_os/memory/storage/__init__.py +15 -0
  136. empathy_os/memory/summary_index.py +583 -0
  137. empathy_os/memory/unified.py +619 -0
  138. empathy_os/metrics/__init__.py +12 -0
  139. empathy_os/metrics/prompt_metrics.py +190 -0
  140. empathy_os/models/__init__.py +136 -0
  141. empathy_os/models/__main__.py +13 -0
  142. empathy_os/models/cli.py +655 -0
  143. empathy_os/models/empathy_executor.py +354 -0
  144. empathy_os/models/executor.py +252 -0
  145. empathy_os/models/fallback.py +671 -0
  146. empathy_os/models/provider_config.py +563 -0
  147. empathy_os/models/registry.py +382 -0
  148. empathy_os/models/tasks.py +302 -0
  149. empathy_os/models/telemetry.py +548 -0
  150. empathy_os/models/token_estimator.py +378 -0
  151. empathy_os/models/validation.py +274 -0
  152. empathy_os/monitoring/__init__.py +52 -0
  153. empathy_os/monitoring/alerts.py +23 -0
  154. empathy_os/monitoring/alerts_cli.py +268 -0
  155. empathy_os/monitoring/multi_backend.py +271 -0
  156. empathy_os/monitoring/otel_backend.py +363 -0
  157. empathy_os/optimization/__init__.py +19 -0
  158. empathy_os/optimization/context_optimizer.py +272 -0
  159. empathy_os/pattern_library.py +30 -29
  160. empathy_os/persistence.py +35 -37
  161. empathy_os/platform_utils.py +261 -0
  162. empathy_os/plugins/__init__.py +28 -0
  163. empathy_os/plugins/base.py +361 -0
  164. empathy_os/plugins/registry.py +268 -0
  165. empathy_os/project_index/__init__.py +30 -0
  166. empathy_os/project_index/cli.py +335 -0
  167. empathy_os/project_index/crew_integration.py +430 -0
  168. empathy_os/project_index/index.py +425 -0
  169. empathy_os/project_index/models.py +501 -0
  170. empathy_os/project_index/reports.py +473 -0
  171. empathy_os/project_index/scanner.py +538 -0
  172. empathy_os/prompts/__init__.py +61 -0
  173. empathy_os/prompts/config.py +77 -0
  174. empathy_os/prompts/context.py +177 -0
  175. empathy_os/prompts/parser.py +285 -0
  176. empathy_os/prompts/registry.py +313 -0
  177. empathy_os/prompts/templates.py +208 -0
  178. empathy_os/redis_config.py +144 -58
  179. empathy_os/redis_memory.py +79 -77
  180. empathy_os/resilience/__init__.py +56 -0
  181. empathy_os/resilience/circuit_breaker.py +256 -0
  182. empathy_os/resilience/fallback.py +179 -0
  183. empathy_os/resilience/health.py +300 -0
  184. empathy_os/resilience/retry.py +209 -0
  185. empathy_os/resilience/timeout.py +135 -0
  186. empathy_os/routing/__init__.py +43 -0
  187. empathy_os/routing/chain_executor.py +433 -0
  188. empathy_os/routing/classifier.py +217 -0
  189. empathy_os/routing/smart_router.py +234 -0
  190. empathy_os/routing/wizard_registry.py +307 -0
  191. empathy_os/templates.py +19 -14
  192. empathy_os/trust/__init__.py +28 -0
  193. empathy_os/trust/circuit_breaker.py +579 -0
  194. empathy_os/trust_building.py +67 -58
  195. empathy_os/validation/__init__.py +19 -0
  196. empathy_os/validation/xml_validator.py +281 -0
  197. empathy_os/wizard_factory_cli.py +170 -0
  198. empathy_os/{workflows.py → workflow_commands.py} +131 -37
  199. empathy_os/workflows/__init__.py +360 -0
  200. empathy_os/workflows/base.py +1660 -0
  201. empathy_os/workflows/bug_predict.py +962 -0
  202. empathy_os/workflows/code_review.py +960 -0
  203. empathy_os/workflows/code_review_adapters.py +310 -0
  204. empathy_os/workflows/code_review_pipeline.py +720 -0
  205. empathy_os/workflows/config.py +600 -0
  206. empathy_os/workflows/dependency_check.py +648 -0
  207. empathy_os/workflows/document_gen.py +1069 -0
  208. empathy_os/workflows/documentation_orchestrator.py +1205 -0
  209. empathy_os/workflows/health_check.py +679 -0
  210. empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
  211. empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
  212. empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
  213. empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
  214. empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
  215. empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
  216. empathy_os/workflows/manage_documentation.py +804 -0
  217. empathy_os/workflows/new_sample_workflow1.py +146 -0
  218. empathy_os/workflows/new_sample_workflow1_README.md +150 -0
  219. empathy_os/workflows/perf_audit.py +687 -0
  220. empathy_os/workflows/pr_review.py +748 -0
  221. empathy_os/workflows/progress.py +445 -0
  222. empathy_os/workflows/progress_server.py +322 -0
  223. empathy_os/workflows/refactor_plan.py +693 -0
  224. empathy_os/workflows/release_prep.py +808 -0
  225. empathy_os/workflows/research_synthesis.py +404 -0
  226. empathy_os/workflows/secure_release.py +585 -0
  227. empathy_os/workflows/security_adapters.py +297 -0
  228. empathy_os/workflows/security_audit.py +1046 -0
  229. empathy_os/workflows/step_config.py +234 -0
  230. empathy_os/workflows/test5.py +125 -0
  231. empathy_os/workflows/test5_README.md +158 -0
  232. empathy_os/workflows/test_gen.py +1855 -0
  233. empathy_os/workflows/test_lifecycle.py +526 -0
  234. empathy_os/workflows/test_maintenance.py +626 -0
  235. empathy_os/workflows/test_maintenance_cli.py +590 -0
  236. empathy_os/workflows/test_maintenance_crew.py +821 -0
  237. empathy_os/workflows/xml_enhanced_crew.py +285 -0
  238. empathy_software_plugin/__init__.py +1 -2
  239. empathy_software_plugin/cli/__init__.py +120 -0
  240. empathy_software_plugin/cli/inspect.py +362 -0
  241. empathy_software_plugin/cli.py +49 -27
  242. empathy_software_plugin/plugin.py +4 -8
  243. empathy_software_plugin/wizards/__init__.py +42 -0
  244. empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
  245. empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
  246. empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
  247. empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
  248. empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
  249. empathy_software_plugin/wizards/base_wizard.py +288 -0
  250. empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
  251. empathy_software_plugin/wizards/code_review_wizard.py +606 -0
  252. empathy_software_plugin/wizards/debugging/__init__.py +50 -0
  253. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
  254. empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
  255. empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
  256. empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
  257. empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
  258. empathy_software_plugin/wizards/debugging/verification.py +369 -0
  259. empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
  260. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
  261. empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
  262. empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
  263. empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
  264. empathy_software_plugin/wizards/performance/__init__.py +9 -0
  265. empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
  266. empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
  267. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
  268. empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
  269. empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
  270. empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
  271. empathy_software_plugin/wizards/security/__init__.py +32 -0
  272. empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
  273. empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
  274. empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
  275. empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
  276. empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
  277. empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
  278. empathy_software_plugin/wizards/testing/__init__.py +27 -0
  279. empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
  280. empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
  281. empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
  282. empathy_software_plugin/wizards/testing_wizard.py +274 -0
  283. hot_reload/README.md +473 -0
  284. hot_reload/__init__.py +62 -0
  285. hot_reload/config.py +84 -0
  286. hot_reload/integration.py +228 -0
  287. hot_reload/reloader.py +298 -0
  288. hot_reload/watcher.py +179 -0
  289. hot_reload/websocket.py +176 -0
  290. scaffolding/README.md +589 -0
  291. scaffolding/__init__.py +35 -0
  292. scaffolding/__main__.py +14 -0
  293. scaffolding/cli.py +240 -0
  294. test_generator/__init__.py +38 -0
  295. test_generator/__main__.py +14 -0
  296. test_generator/cli.py +226 -0
  297. test_generator/generator.py +325 -0
  298. test_generator/risk_analyzer.py +216 -0
  299. workflow_patterns/__init__.py +33 -0
  300. workflow_patterns/behavior.py +249 -0
  301. workflow_patterns/core.py +76 -0
  302. workflow_patterns/output.py +99 -0
  303. workflow_patterns/registry.py +255 -0
  304. workflow_patterns/structural.py +288 -0
  305. workflow_scaffolding/__init__.py +11 -0
  306. workflow_scaffolding/__main__.py +12 -0
  307. workflow_scaffolding/cli.py +206 -0
  308. workflow_scaffolding/generator.py +265 -0
  309. agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
  310. agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
  311. agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
  312. agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
  313. agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
  314. agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
  315. agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
  316. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
  317. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
  318. agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
  319. agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
  320. agents/compliance_anticipation_agent.py +0 -1427
  321. agents/epic_integration_wizard.py +0 -541
  322. agents/trust_building_behaviors.py +0 -891
  323. empathy_framework-2.4.0.dist-info/METADATA +0 -485
  324. empathy_framework-2.4.0.dist-info/RECORD +0 -102
  325. empathy_framework-2.4.0.dist-info/entry_points.txt +0 -6
  326. empathy_llm_toolkit/htmlcov/status.json +0 -1
  327. empathy_llm_toolkit/security/htmlcov/status.json +0 -1
  328. {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/WHEEL +0 -0
  329. {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,4 @@
1
- """
2
- Pattern Confidence Scoring
1
+ """Pattern Confidence Scoring
3
2
 
4
3
  Tracks how often stored fixes resolve similar issues,
5
4
  building confidence scores over time.
@@ -85,8 +84,7 @@ class PatternUsageStats:
85
84
 
86
85
 
87
86
  class PatternConfidenceTracker:
88
- """
89
- Tracks pattern usage and calculates confidence scores.
87
+ """Tracks pattern usage and calculates confidence scores.
90
88
 
91
89
  Stores usage data in patterns/confidence/usage_stats.json
92
90
  """
@@ -151,8 +149,7 @@ class PatternConfidenceTracker:
151
149
  return self._stats[pattern_id]
152
150
 
153
151
  def record_suggestion(self, pattern_id: str) -> None:
154
- """
155
- Record that a pattern was suggested to the user.
152
+ """Record that a pattern was suggested to the user.
156
153
 
157
154
  Call this when a pattern is shown as a potential fix.
158
155
  """
@@ -168,13 +165,13 @@ class PatternConfidenceTracker:
168
165
  successful: bool = True,
169
166
  notes: str | None = None,
170
167
  ) -> None:
171
- """
172
- Record that a pattern fix was applied.
168
+ """Record that a pattern fix was applied.
173
169
 
174
170
  Args:
175
171
  pattern_id: The pattern that was applied
176
172
  successful: Whether the fix resolved the issue
177
173
  notes: Optional feedback notes
174
+
178
175
  """
179
176
  stats = self._get_or_create_stats(pattern_id)
180
177
  stats.times_applied += 1
@@ -191,7 +188,7 @@ class PatternConfidenceTracker:
191
188
  "date": datetime.now().isoformat(),
192
189
  "successful": successful,
193
190
  "notes": notes,
194
- }
191
+ },
195
192
  )
196
193
 
197
194
  self._save()
@@ -203,11 +200,11 @@ class PatternConfidenceTracker:
203
200
  )
204
201
 
205
202
  def get_pattern_stats(self, pattern_id: str) -> dict[str, Any]:
206
- """
207
- Get usage statistics for a pattern.
203
+ """Get usage statistics for a pattern.
208
204
 
209
205
  Returns:
210
206
  Dict with usage stats and calculated scores
207
+
211
208
  """
212
209
  stats = self._get_or_create_stats(pattern_id)
213
210
  return {
@@ -230,14 +227,14 @@ class PatternConfidenceTracker:
230
227
  return [self.get_pattern_stats(pid) for pid in self._stats]
231
228
 
232
229
  def get_top_patterns(self, limit: int = 10) -> list[dict[str, Any]]:
233
- """
234
- Get top patterns by confidence score.
230
+ """Get top patterns by confidence score.
235
231
 
236
232
  Args:
237
233
  limit: Maximum patterns to return
238
234
 
239
235
  Returns:
240
236
  List of pattern stats, sorted by confidence
237
+
241
238
  """
242
239
  self._ensure_loaded()
243
240
  all_stats = self.get_all_stats()
@@ -249,14 +246,14 @@ class PatternConfidenceTracker:
249
246
  return sorted_stats[:limit]
250
247
 
251
248
  def get_stale_patterns(self, days: int = 90) -> list[dict[str, Any]]:
252
- """
253
- Get patterns that haven't been used recently.
249
+ """Get patterns that haven't been used recently.
254
250
 
255
251
  Args:
256
252
  days: Number of days to consider stale
257
253
 
258
254
  Returns:
259
255
  List of stale pattern stats
256
+
260
257
  """
261
258
  self._ensure_loaded()
262
259
  stale = []
@@ -275,8 +272,7 @@ class PatternConfidenceTracker:
275
272
  return stale
276
273
 
277
274
  def update_pattern_summary(self) -> bool:
278
- """
279
- Update the patterns_summary.md with confidence scores.
275
+ """Update the patterns_summary.md with confidence scores.
280
276
 
281
277
  This adds a confidence section to the generated summary.
282
278
  """
@@ -297,7 +293,7 @@ class PatternConfidenceTracker:
297
293
  icon = "🟢" if score >= 0.8 else "🟡" if score >= 0.5 else "🔴"
298
294
  confidence_section.append(
299
295
  f"- {icon} **{p['pattern_id']}**: {score:.0%} confidence "
300
- f"({p['times_applied']} applied, {p['times_successful']} successful)"
296
+ f"({p['times_applied']} applied, {p['times_successful']} successful)",
301
297
  )
302
298
 
303
299
  confidence_section.append("")
@@ -1,5 +1,4 @@
1
- """
2
- Pattern Resolution Module
1
+ """Pattern Resolution Module
3
2
 
4
3
  Provides CLI workflow for resolving investigating bug patterns
5
4
  by adding root cause, fix, and resolution time.
@@ -40,8 +39,7 @@ logger = logging.getLogger(__name__)
40
39
 
41
40
 
42
41
  class PatternResolver:
43
- """
44
- Resolves investigating bug patterns with root cause and fix information.
42
+ """Resolves investigating bug patterns with root cause and fix information.
45
43
 
46
44
  Searches through pattern directories to find matching bug IDs
47
45
  and updates them with resolution details.
@@ -52,14 +50,14 @@ class PatternResolver:
52
50
  self._debugging_dirs = ["debugging", "debugging_demo", "repo_test/debugging"]
53
51
 
54
52
  def find_bug(self, bug_id: str) -> tuple[Path | None, dict[str, Any] | None]:
55
- """
56
- Find a bug pattern by ID.
53
+ """Find a bug pattern by ID.
57
54
 
58
55
  Args:
59
56
  bug_id: The bug ID to find (e.g., "bug_20251212_3c5b9951")
60
57
 
61
58
  Returns:
62
59
  Tuple of (file_path, pattern_data) or (None, None) if not found
60
+
63
61
  """
64
62
  for debug_dir in self._debugging_dirs:
65
63
  dir_path = self.patterns_dir / debug_dir
@@ -88,11 +86,11 @@ class PatternResolver:
88
86
  return None, None
89
87
 
90
88
  def list_investigating(self) -> list[dict[str, Any]]:
91
- """
92
- List all bugs with status 'investigating'.
89
+ """List all bugs with status 'investigating'.
93
90
 
94
91
  Returns:
95
92
  List of bug patterns that need resolution
93
+
96
94
  """
97
95
  investigating = []
98
96
 
@@ -122,8 +120,7 @@ class PatternResolver:
122
120
  resolution_time_minutes: int = 0,
123
121
  resolved_by: str = "@developer",
124
122
  ) -> bool:
125
- """
126
- Resolve a bug pattern by updating its fields.
123
+ """Resolve a bug pattern by updating its fields.
127
124
 
128
125
  Args:
129
126
  bug_id: The bug ID to resolve
@@ -135,6 +132,7 @@ class PatternResolver:
135
132
 
136
133
  Returns:
137
134
  True if successfully resolved, False otherwise
135
+
138
136
  """
139
137
  file_path, pattern = self.find_bug(bug_id)
140
138
 
@@ -165,11 +163,11 @@ class PatternResolver:
165
163
  return False
166
164
 
167
165
  def regenerate_summary(self) -> bool:
168
- """
169
- Regenerate the patterns_summary.md file.
166
+ """Regenerate the patterns_summary.md file.
170
167
 
171
168
  Returns:
172
169
  True if successful, False otherwise
170
+
173
171
  """
174
172
  try:
175
173
  from empathy_llm_toolkit.pattern_summary import PatternSummaryGenerator
@@ -1,5 +1,4 @@
1
- """
2
- Pattern Summary Generator
1
+ """Pattern Summary Generator
3
2
 
4
3
  Generates a markdown summary of stored patterns for inclusion in CLAUDE.md.
5
4
  This enables Claude Code sessions to have context about historical patterns.
@@ -12,7 +11,7 @@ Usage:
12
11
  generator.write_to_file("./.claude/patterns_summary.md")
13
12
 
14
13
  CLI:
15
- python -m empathy_llm_toolkit.pattern_summary --patterns-dir ./patterns --output ./.claude/patterns_summary.md
14
+ python -m empathy_llm_toolkit.pattern_summary --patterns-dir ./patterns --output patterns.md
16
15
 
17
16
  Author: Empathy Framework Team
18
17
  Version: 2.1.2
@@ -29,8 +28,7 @@ logger = logging.getLogger(__name__)
29
28
 
30
29
 
31
30
  class PatternSummaryGenerator:
32
- """
33
- Generates markdown summaries of stored patterns.
31
+ """Generates markdown summaries of stored patterns.
34
32
 
35
33
  Scans the patterns directory and produces a concise summary
36
34
  suitable for inclusion in CLAUDE.md via @import.
@@ -119,11 +117,11 @@ class PatternSummaryGenerator:
119
117
  return snapshots
120
118
 
121
119
  def generate_markdown(self) -> str:
122
- """
123
- Generate a markdown summary of all patterns.
120
+ """Generate a markdown summary of all patterns.
124
121
 
125
122
  Returns:
126
123
  Markdown string suitable for CLAUDE.md inclusion
124
+
127
125
  """
128
126
  if not any([self._bug_patterns, self._security_decisions, self._tech_debt_history]):
129
127
  self.load_all_patterns()
@@ -153,11 +151,11 @@ class PatternSummaryGenerator:
153
151
  "",
154
152
  "## How to Use These Patterns",
155
153
  "",
156
- "- **Debugging**: When encountering errors, check if similar bugs have been resolved",
157
- "- **Security**: Before flagging security issues, check team decisions for false positives",
154
+ "- **Debugging**: Check if similar bugs have been resolved",
155
+ "- **Security**: Check team decisions for false positives",
158
156
  "- **Tech Debt**: Consider debt trajectory when planning refactoring work",
159
157
  "",
160
- ]
158
+ ],
161
159
  )
162
160
 
163
161
  return "\n".join(lines)
@@ -247,7 +245,9 @@ class PatternSummaryGenerator:
247
245
 
248
246
  # Sort by date
249
247
  sorted_snapshots = sorted(
250
- self._tech_debt_history, key=lambda s: s.get("date", ""), reverse=True
248
+ self._tech_debt_history,
249
+ key=lambda s: s.get("date", ""),
250
+ reverse=True,
251
251
  )
252
252
 
253
253
  # Current state (most recent)
@@ -295,11 +295,11 @@ class PatternSummaryGenerator:
295
295
  return lines
296
296
 
297
297
  def write_to_file(self, output_path: str) -> None:
298
- """
299
- Write the markdown summary to a file.
298
+ """Write the markdown summary to a file.
300
299
 
301
300
  Args:
302
301
  output_path: Path to write the summary
302
+
303
303
  """
304
304
  output = Path(output_path)
305
305
  output.parent.mkdir(parents=True, exist_ok=True)
@@ -326,7 +326,9 @@ def main():
326
326
  help="Output file path (default: ./.claude/patterns_summary.md)",
327
327
  )
328
328
  parser.add_argument(
329
- "--print", action="store_true", help="Print to stdout instead of writing to file"
329
+ "--print",
330
+ action="store_true",
331
+ help="Print to stdout instead of writing to file",
330
332
  )
331
333
 
332
334
  args = parser.parse_args()
@@ -1,5 +1,4 @@
1
- """
2
- LLM Provider Adapters
1
+ """LLM Provider Adapters
3
2
 
4
3
  Unified interface for different LLM providers (OpenAI, Anthropic, local models).
5
4
 
@@ -24,8 +23,7 @@ class LLMResponse:
24
23
 
25
24
 
26
25
  class BaseLLMProvider(ABC):
27
- """
28
- Base class for all LLM providers.
26
+ """Base class for all LLM providers.
29
27
 
30
28
  Provides unified interface regardless of backend.
31
29
  """
@@ -43,8 +41,7 @@ class BaseLLMProvider(ABC):
43
41
  max_tokens: int = 1024,
44
42
  **kwargs,
45
43
  ) -> LLMResponse:
46
- """
47
- Generate response from LLM.
44
+ """Generate response from LLM.
48
45
 
49
46
  Args:
50
47
  messages: List of {"role": "user/assistant", "content": "..."}
@@ -55,17 +52,15 @@ class BaseLLMProvider(ABC):
55
52
 
56
53
  Returns:
57
54
  LLMResponse with standardized format
55
+
58
56
  """
59
- pass
60
57
 
61
58
  @abstractmethod
62
59
  def get_model_info(self) -> dict[str, Any]:
63
60
  """Get information about the model being used"""
64
- pass
65
61
 
66
62
  def estimate_tokens(self, text: str) -> int:
67
- """
68
- Estimate token count for text.
63
+ """Estimate token count for text.
69
64
 
70
65
  Rough approximation: ~4 chars per token
71
66
  """
@@ -73,8 +68,7 @@ class BaseLLMProvider(ABC):
73
68
 
74
69
 
75
70
  class AnthropicProvider(BaseLLMProvider):
76
- """
77
- Anthropic (Claude) provider with enhanced features.
71
+ """Anthropic (Claude) provider with enhanced features.
78
72
 
79
73
  Supports Claude 3 family models with advanced capabilities:
80
74
  - Extended context windows (200K tokens)
@@ -100,7 +94,7 @@ class AnthropicProvider(BaseLLMProvider):
100
94
  if not api_key or not api_key.strip():
101
95
  raise ValueError(
102
96
  "API key is required for Anthropic provider. "
103
- "Provide via api_key parameter or ANTHROPIC_API_KEY environment variable"
97
+ "Provide via api_key parameter or ANTHROPIC_API_KEY environment variable",
104
98
  )
105
99
 
106
100
  # Lazy import to avoid requiring anthropic if not used
@@ -110,7 +104,7 @@ class AnthropicProvider(BaseLLMProvider):
110
104
  self.client = anthropic.Anthropic(api_key=api_key)
111
105
  except ImportError as e:
112
106
  raise ImportError(
113
- "anthropic package required. Install with: pip install anthropic"
107
+ "anthropic package required. Install with: pip install anthropic",
114
108
  ) from e
115
109
 
116
110
  async def generate(
@@ -121,15 +115,13 @@ class AnthropicProvider(BaseLLMProvider):
121
115
  max_tokens: int = 1024,
122
116
  **kwargs,
123
117
  ) -> LLMResponse:
124
- """
125
- Generate response using Anthropic API with enhanced features.
118
+ """Generate response using Anthropic API with enhanced features.
126
119
 
127
120
  Claude-specific enhancements:
128
121
  - Prompt caching for repeated system prompts (90% cost reduction)
129
122
  - Extended context (200K tokens) for large codebase analysis
130
123
  - Thinking mode for complex reasoning tasks
131
124
  """
132
-
133
125
  # Build kwargs for Anthropic
134
126
  api_kwargs = {
135
127
  "model": self.model,
@@ -145,7 +137,7 @@ class AnthropicProvider(BaseLLMProvider):
145
137
  "type": "text",
146
138
  "text": system_prompt,
147
139
  "cache_control": {"type": "ephemeral"}, # Cache for 5 minutes
148
- }
140
+ },
149
141
  ]
150
142
  elif system_prompt:
151
143
  api_kwargs["system"] = system_prompt
@@ -202,10 +194,12 @@ class AnthropicProvider(BaseLLMProvider):
202
194
  )
203
195
 
204
196
  async def analyze_large_codebase(
205
- self, codebase_files: list[dict[str, str]], analysis_prompt: str, **kwargs
197
+ self,
198
+ codebase_files: list[dict[str, str]],
199
+ analysis_prompt: str,
200
+ **kwargs,
206
201
  ) -> LLMResponse:
207
- """
208
- Analyze large codebases using Claude's 200K context window.
202
+ """Analyze large codebases using Claude's 200K context window.
209
203
 
210
204
  Claude-specific feature: Can process entire repositories in one call.
211
205
 
@@ -216,10 +210,11 @@ class AnthropicProvider(BaseLLMProvider):
216
210
 
217
211
  Returns:
218
212
  LLMResponse with analysis results
213
+
219
214
  """
220
215
  # Build context from all files
221
216
  file_context = "\n\n".join(
222
- [f"# File: {file['path']}\n{file['content']}" for file in codebase_files]
217
+ [f"# File: {file['path']}\n{file['content']}" for file in codebase_files],
223
218
  )
224
219
 
225
220
  # Create system prompt with caching for file context
@@ -287,8 +282,7 @@ class AnthropicProvider(BaseLLMProvider):
287
282
 
288
283
 
289
284
  class OpenAIProvider(BaseLLMProvider):
290
- """
291
- OpenAI provider.
285
+ """OpenAI provider.
292
286
 
293
287
  Supports GPT-4, GPT-3.5, and other OpenAI models.
294
288
  """
@@ -301,7 +295,7 @@ class OpenAIProvider(BaseLLMProvider):
301
295
  if not api_key or not api_key.strip():
302
296
  raise ValueError(
303
297
  "API key is required for OpenAI provider. "
304
- "Provide via api_key parameter or OPENAI_API_KEY environment variable"
298
+ "Provide via api_key parameter or OPENAI_API_KEY environment variable",
305
299
  )
306
300
 
307
301
  # Lazy import
@@ -321,7 +315,6 @@ class OpenAIProvider(BaseLLMProvider):
321
315
  **kwargs,
322
316
  ) -> LLMResponse:
323
317
  """Generate response using OpenAI API"""
324
-
325
318
  # Add system prompt if provided
326
319
  if system_prompt:
327
320
  messages = [{"role": "system", "content": system_prompt}] + messages
@@ -372,9 +365,182 @@ class OpenAIProvider(BaseLLMProvider):
372
365
  )
373
366
 
374
367
 
375
- class LocalProvider(BaseLLMProvider):
368
+ class GeminiProvider(BaseLLMProvider):
369
+ """Google Gemini provider with cost tracking integration.
370
+
371
+ Supports Gemini models:
372
+ - gemini-2.0-flash-exp: Fast, cheap tier (1M context)
373
+ - gemini-1.5-pro: Balanced, capable tier (2M context)
374
+ - gemini-2.5-pro: Premium reasoning tier
376
375
  """
377
- Local model provider (Ollama, LM Studio, etc.).
376
+
377
+ def __init__(
378
+ self,
379
+ api_key: str | None = None,
380
+ model: str = "gemini-1.5-pro",
381
+ **kwargs,
382
+ ):
383
+ super().__init__(api_key, **kwargs)
384
+ self.model = model
385
+
386
+ # Validate API key is provided
387
+ if not api_key or not api_key.strip():
388
+ raise ValueError(
389
+ "API key is required for Gemini provider. "
390
+ "Provide via api_key parameter or GOOGLE_API_KEY environment variable",
391
+ )
392
+
393
+ # Lazy import to avoid requiring google-generativeai if not used
394
+ try:
395
+ import google.generativeai as genai
396
+
397
+ genai.configure(api_key=api_key)
398
+ self.genai = genai
399
+ self.client = genai.GenerativeModel(model)
400
+ except ImportError as e:
401
+ raise ImportError(
402
+ "google-generativeai package required. Install with: pip install google-generativeai",
403
+ ) from e
404
+
405
+ async def generate(
406
+ self,
407
+ messages: list[dict[str, str]],
408
+ system_prompt: str | None = None,
409
+ temperature: float = 0.7,
410
+ max_tokens: int = 1024,
411
+ **kwargs,
412
+ ) -> LLMResponse:
413
+ """Generate response using Google Gemini API.
414
+
415
+ Gemini-specific features:
416
+ - Large context windows (1M-2M tokens)
417
+ - Multimodal support
418
+ - Grounding with Google Search
419
+ """
420
+ import asyncio
421
+
422
+ # Convert messages to Gemini format
423
+ gemini_messages = []
424
+ for msg in messages:
425
+ role = "user" if msg["role"] == "user" else "model"
426
+ gemini_messages.append({"role": role, "parts": [msg["content"]]})
427
+
428
+ # Build generation config
429
+ generation_config = self.genai.GenerationConfig(
430
+ temperature=temperature,
431
+ max_output_tokens=max_tokens,
432
+ )
433
+
434
+ # Create model with system instruction if provided
435
+ if system_prompt:
436
+ model = self.genai.GenerativeModel(
437
+ self.model,
438
+ system_instruction=system_prompt,
439
+ )
440
+ else:
441
+ model = self.client
442
+
443
+ # Call Gemini API (run sync in thread pool for async compatibility)
444
+ loop = asyncio.get_event_loop()
445
+ response = await loop.run_in_executor(
446
+ None,
447
+ lambda: model.generate_content(
448
+ gemini_messages, # type: ignore[arg-type]
449
+ generation_config=generation_config,
450
+ ),
451
+ )
452
+
453
+ # Extract token counts from usage metadata
454
+ input_tokens = 0
455
+ output_tokens = 0
456
+ if hasattr(response, "usage_metadata"):
457
+ input_tokens = getattr(response.usage_metadata, "prompt_token_count", 0)
458
+ output_tokens = getattr(response.usage_metadata, "candidates_token_count", 0)
459
+
460
+ # Log to cost tracker
461
+ try:
462
+ from empathy_os.cost_tracker import log_request
463
+
464
+ tier = self._get_tier()
465
+ log_request(
466
+ model=self.model,
467
+ input_tokens=input_tokens,
468
+ output_tokens=output_tokens,
469
+ task_type=kwargs.get("task_type", "gemini_generate"),
470
+ tier=tier,
471
+ )
472
+ except ImportError:
473
+ pass # Cost tracking not available
474
+
475
+ # Convert to standardized format
476
+ content = ""
477
+ if response.candidates:
478
+ content = response.candidates[0].content.parts[0].text
479
+
480
+ finish_reason = "stop"
481
+ if response.candidates and hasattr(response.candidates[0], "finish_reason"):
482
+ finish_reason = str(response.candidates[0].finish_reason.name).lower()
483
+
484
+ return LLMResponse(
485
+ content=content,
486
+ model=self.model,
487
+ tokens_used=input_tokens + output_tokens,
488
+ finish_reason=finish_reason,
489
+ metadata={
490
+ "input_tokens": input_tokens,
491
+ "output_tokens": output_tokens,
492
+ "provider": "google",
493
+ "model_family": "gemini",
494
+ },
495
+ )
496
+
497
+ def _get_tier(self) -> str:
498
+ """Determine tier from model name."""
499
+ if "flash" in self.model.lower():
500
+ return "cheap"
501
+ if "2.5" in self.model or "ultra" in self.model.lower():
502
+ return "premium"
503
+ return "capable"
504
+
505
+ def get_model_info(self) -> dict[str, Any]:
506
+ """Get Gemini model information"""
507
+ model_info = {
508
+ "gemini-2.0-flash-exp": {
509
+ "max_tokens": 1000000,
510
+ "cost_per_1m_input": 0.075,
511
+ "cost_per_1m_output": 0.30,
512
+ "supports_vision": True,
513
+ "ideal_for": "Fast responses, simple tasks, large context",
514
+ },
515
+ "gemini-1.5-pro": {
516
+ "max_tokens": 2000000,
517
+ "cost_per_1m_input": 1.25,
518
+ "cost_per_1m_output": 5.00,
519
+ "supports_vision": True,
520
+ "ideal_for": "Complex reasoning, large codebases",
521
+ },
522
+ "gemini-2.5-pro": {
523
+ "max_tokens": 1000000,
524
+ "cost_per_1m_input": 2.50,
525
+ "cost_per_1m_output": 10.00,
526
+ "supports_vision": True,
527
+ "ideal_for": "Advanced reasoning, complex tasks",
528
+ },
529
+ }
530
+
531
+ return model_info.get(
532
+ self.model,
533
+ {
534
+ "max_tokens": 1000000,
535
+ "cost_per_1m_input": 1.25,
536
+ "cost_per_1m_output": 5.00,
537
+ "supports_vision": True,
538
+ },
539
+ )
540
+
541
+
542
+ class LocalProvider(BaseLLMProvider):
543
+ """Local model provider (Ollama, LM Studio, etc.).
378
544
 
379
545
  For running models locally.
380
546
  """
@@ -0,0 +1,32 @@
1
+ """Empathy Framework Model Routing
2
+
3
+ Smart routing of tasks to appropriate model tiers for cost optimization:
4
+ - CHEAP tier: Triage, summarization, classification (Haiku/GPT-4o-mini)
5
+ - CAPABLE tier: Code generation, analysis, sub-agent work (Sonnet/GPT-4o)
6
+ - PREMIUM tier: Coordination, synthesis, critical decisions (Opus/o1)
7
+
8
+ Example:
9
+ >>> from empathy_llm_toolkit.routing import ModelRouter
10
+ >>>
11
+ >>> router = ModelRouter()
12
+ >>> model = router.route("summarize", provider="anthropic")
13
+ >>> print(model) # claude-3-5-haiku-20241022
14
+ >>>
15
+ >>> model = router.route("coordinate", provider="anthropic")
16
+ >>> print(model) # claude-opus-4-20250514
17
+ >>>
18
+ >>> cost = router.estimate_cost("fix_bug", input_tokens=5000, output_tokens=1000)
19
+ >>> print(f"Estimated cost: ${cost:.4f}")
20
+
21
+ Copyright 2025 Smart AI Memory, LLC
22
+ Licensed under Fair Source 0.9
23
+
24
+ """
25
+
26
+ from .model_router import ModelRouter, ModelTier, TaskRouting
27
+
28
+ __all__ = [
29
+ "ModelRouter",
30
+ "ModelTier",
31
+ "TaskRouting",
32
+ ]