empathy-framework 4.6.6__py3-none-any.whl → 4.7.1__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 (273) hide show
  1. empathy_framework-4.7.1.dist-info/METADATA +690 -0
  2. empathy_framework-4.7.1.dist-info/RECORD +379 -0
  3. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/top_level.txt +1 -2
  4. empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
  5. empathy_llm_toolkit/agent_factory/__init__.py +6 -6
  6. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
  7. empathy_llm_toolkit/agents_md/__init__.py +22 -0
  8. empathy_llm_toolkit/agents_md/loader.py +218 -0
  9. empathy_llm_toolkit/agents_md/parser.py +271 -0
  10. empathy_llm_toolkit/agents_md/registry.py +307 -0
  11. empathy_llm_toolkit/commands/__init__.py +51 -0
  12. empathy_llm_toolkit/commands/context.py +375 -0
  13. empathy_llm_toolkit/commands/loader.py +301 -0
  14. empathy_llm_toolkit/commands/models.py +231 -0
  15. empathy_llm_toolkit/commands/parser.py +371 -0
  16. empathy_llm_toolkit/commands/registry.py +429 -0
  17. empathy_llm_toolkit/config/__init__.py +8 -8
  18. empathy_llm_toolkit/config/unified.py +3 -7
  19. empathy_llm_toolkit/context/__init__.py +22 -0
  20. empathy_llm_toolkit/context/compaction.py +455 -0
  21. empathy_llm_toolkit/context/manager.py +434 -0
  22. empathy_llm_toolkit/hooks/__init__.py +24 -0
  23. empathy_llm_toolkit/hooks/config.py +306 -0
  24. empathy_llm_toolkit/hooks/executor.py +289 -0
  25. empathy_llm_toolkit/hooks/registry.py +302 -0
  26. empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
  27. empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
  28. empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
  29. empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
  30. empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
  31. empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
  32. empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
  33. empathy_llm_toolkit/learning/__init__.py +30 -0
  34. empathy_llm_toolkit/learning/evaluator.py +438 -0
  35. empathy_llm_toolkit/learning/extractor.py +514 -0
  36. empathy_llm_toolkit/learning/storage.py +560 -0
  37. empathy_llm_toolkit/providers.py +4 -11
  38. empathy_llm_toolkit/security/__init__.py +17 -17
  39. empathy_llm_toolkit/utils/tokens.py +2 -5
  40. empathy_os/__init__.py +202 -70
  41. empathy_os/cache_monitor.py +5 -3
  42. empathy_os/cli/__init__.py +11 -55
  43. empathy_os/cli/__main__.py +29 -15
  44. empathy_os/cli/commands/inspection.py +21 -12
  45. empathy_os/cli/commands/memory.py +4 -12
  46. empathy_os/cli/commands/profiling.py +198 -0
  47. empathy_os/cli/commands/utilities.py +27 -7
  48. empathy_os/cli.py +28 -57
  49. empathy_os/cli_unified.py +525 -1164
  50. empathy_os/cost_tracker.py +9 -3
  51. empathy_os/dashboard/server.py +200 -2
  52. empathy_os/hot_reload/__init__.py +7 -7
  53. empathy_os/hot_reload/config.py +6 -7
  54. empathy_os/hot_reload/integration.py +35 -35
  55. empathy_os/hot_reload/reloader.py +57 -57
  56. empathy_os/hot_reload/watcher.py +28 -28
  57. empathy_os/hot_reload/websocket.py +2 -2
  58. empathy_os/memory/__init__.py +11 -4
  59. empathy_os/memory/claude_memory.py +1 -1
  60. empathy_os/memory/cross_session.py +8 -12
  61. empathy_os/memory/edges.py +6 -6
  62. empathy_os/memory/file_session.py +770 -0
  63. empathy_os/memory/graph.py +30 -30
  64. empathy_os/memory/nodes.py +6 -6
  65. empathy_os/memory/short_term.py +15 -9
  66. empathy_os/memory/unified.py +606 -140
  67. empathy_os/meta_workflows/agent_creator.py +3 -9
  68. empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
  69. empathy_os/meta_workflows/form_engine.py +6 -18
  70. empathy_os/meta_workflows/intent_detector.py +64 -24
  71. empathy_os/meta_workflows/models.py +3 -1
  72. empathy_os/meta_workflows/pattern_learner.py +13 -31
  73. empathy_os/meta_workflows/plan_generator.py +55 -47
  74. empathy_os/meta_workflows/session_context.py +2 -3
  75. empathy_os/meta_workflows/workflow.py +20 -51
  76. empathy_os/models/cli.py +2 -2
  77. empathy_os/models/tasks.py +1 -2
  78. empathy_os/models/telemetry.py +4 -1
  79. empathy_os/models/token_estimator.py +3 -1
  80. empathy_os/monitoring/alerts.py +938 -9
  81. empathy_os/monitoring/alerts_cli.py +346 -183
  82. empathy_os/orchestration/execution_strategies.py +12 -29
  83. empathy_os/orchestration/pattern_learner.py +20 -26
  84. empathy_os/orchestration/real_tools.py +6 -15
  85. empathy_os/platform_utils.py +2 -1
  86. empathy_os/plugins/__init__.py +2 -2
  87. empathy_os/plugins/base.py +64 -64
  88. empathy_os/plugins/registry.py +32 -32
  89. empathy_os/project_index/index.py +49 -15
  90. empathy_os/project_index/models.py +1 -2
  91. empathy_os/project_index/reports.py +1 -1
  92. empathy_os/project_index/scanner.py +1 -0
  93. empathy_os/redis_memory.py +10 -7
  94. empathy_os/resilience/__init__.py +1 -1
  95. empathy_os/resilience/health.py +10 -10
  96. empathy_os/routing/__init__.py +7 -7
  97. empathy_os/routing/chain_executor.py +37 -37
  98. empathy_os/routing/classifier.py +36 -36
  99. empathy_os/routing/smart_router.py +40 -40
  100. empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
  101. empathy_os/scaffolding/__init__.py +8 -8
  102. empathy_os/scaffolding/__main__.py +1 -1
  103. empathy_os/scaffolding/cli.py +28 -28
  104. empathy_os/socratic/__init__.py +3 -19
  105. empathy_os/socratic/ab_testing.py +25 -36
  106. empathy_os/socratic/blueprint.py +38 -38
  107. empathy_os/socratic/cli.py +34 -20
  108. empathy_os/socratic/collaboration.py +30 -28
  109. empathy_os/socratic/domain_templates.py +9 -1
  110. empathy_os/socratic/embeddings.py +17 -13
  111. empathy_os/socratic/engine.py +135 -70
  112. empathy_os/socratic/explainer.py +70 -60
  113. empathy_os/socratic/feedback.py +24 -19
  114. empathy_os/socratic/forms.py +15 -10
  115. empathy_os/socratic/generator.py +51 -35
  116. empathy_os/socratic/llm_analyzer.py +25 -23
  117. empathy_os/socratic/mcp_server.py +99 -159
  118. empathy_os/socratic/session.py +19 -13
  119. empathy_os/socratic/storage.py +98 -67
  120. empathy_os/socratic/success.py +38 -27
  121. empathy_os/socratic/visual_editor.py +51 -39
  122. empathy_os/socratic/web_ui.py +99 -66
  123. empathy_os/telemetry/cli.py +3 -1
  124. empathy_os/telemetry/usage_tracker.py +1 -3
  125. empathy_os/test_generator/__init__.py +3 -3
  126. empathy_os/test_generator/cli.py +28 -28
  127. empathy_os/test_generator/generator.py +64 -66
  128. empathy_os/test_generator/risk_analyzer.py +11 -11
  129. empathy_os/vscode_bridge 2.py +173 -0
  130. empathy_os/vscode_bridge.py +173 -0
  131. empathy_os/workflows/__init__.py +212 -120
  132. empathy_os/workflows/batch_processing.py +8 -24
  133. empathy_os/workflows/bug_predict.py +1 -1
  134. empathy_os/workflows/code_review.py +20 -5
  135. empathy_os/workflows/code_review_pipeline.py +13 -8
  136. empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
  137. empathy_os/workflows/manage_documentation.py +1 -0
  138. empathy_os/workflows/orchestrated_health_check.py +6 -11
  139. empathy_os/workflows/orchestrated_release_prep.py +3 -3
  140. empathy_os/workflows/pr_review.py +18 -10
  141. empathy_os/workflows/progressive/README 2.md +454 -0
  142. empathy_os/workflows/progressive/__init__ 2.py +92 -0
  143. empathy_os/workflows/progressive/__init__.py +2 -12
  144. empathy_os/workflows/progressive/cli 2.py +242 -0
  145. empathy_os/workflows/progressive/cli.py +14 -37
  146. empathy_os/workflows/progressive/core 2.py +488 -0
  147. empathy_os/workflows/progressive/core.py +12 -12
  148. empathy_os/workflows/progressive/orchestrator 2.py +701 -0
  149. empathy_os/workflows/progressive/orchestrator.py +166 -144
  150. empathy_os/workflows/progressive/reports 2.py +528 -0
  151. empathy_os/workflows/progressive/reports.py +22 -31
  152. empathy_os/workflows/progressive/telemetry 2.py +280 -0
  153. empathy_os/workflows/progressive/telemetry.py +8 -14
  154. empathy_os/workflows/progressive/test_gen 2.py +514 -0
  155. empathy_os/workflows/progressive/test_gen.py +29 -48
  156. empathy_os/workflows/progressive/workflow 2.py +628 -0
  157. empathy_os/workflows/progressive/workflow.py +31 -70
  158. empathy_os/workflows/release_prep.py +21 -6
  159. empathy_os/workflows/release_prep_crew.py +1 -0
  160. empathy_os/workflows/secure_release.py +13 -6
  161. empathy_os/workflows/security_audit.py +8 -3
  162. empathy_os/workflows/test_coverage_boost_crew.py +3 -2
  163. empathy_os/workflows/test_maintenance_crew.py +1 -0
  164. empathy_os/workflows/test_runner.py +16 -12
  165. empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
  166. empathy_software_plugin/cli.py +0 -122
  167. patterns/README.md +119 -0
  168. patterns/__init__.py +95 -0
  169. patterns/behavior.py +298 -0
  170. patterns/code_review_memory.json +441 -0
  171. patterns/core.py +97 -0
  172. patterns/debugging.json +3763 -0
  173. patterns/empathy.py +268 -0
  174. patterns/health_check_memory.json +505 -0
  175. patterns/input.py +161 -0
  176. patterns/memory_graph.json +8 -0
  177. patterns/refactoring_memory.json +1113 -0
  178. patterns/registry.py +663 -0
  179. patterns/security_memory.json +8 -0
  180. patterns/structural.py +415 -0
  181. patterns/validation.py +194 -0
  182. coach_wizards/__init__.py +0 -45
  183. coach_wizards/accessibility_wizard.py +0 -91
  184. coach_wizards/api_wizard.py +0 -91
  185. coach_wizards/base_wizard.py +0 -209
  186. coach_wizards/cicd_wizard.py +0 -91
  187. coach_wizards/code_reviewer_README.md +0 -60
  188. coach_wizards/code_reviewer_wizard.py +0 -180
  189. coach_wizards/compliance_wizard.py +0 -91
  190. coach_wizards/database_wizard.py +0 -91
  191. coach_wizards/debugging_wizard.py +0 -91
  192. coach_wizards/documentation_wizard.py +0 -91
  193. coach_wizards/generate_wizards.py +0 -347
  194. coach_wizards/localization_wizard.py +0 -173
  195. coach_wizards/migration_wizard.py +0 -91
  196. coach_wizards/monitoring_wizard.py +0 -91
  197. coach_wizards/observability_wizard.py +0 -91
  198. coach_wizards/performance_wizard.py +0 -91
  199. coach_wizards/prompt_engineering_wizard.py +0 -661
  200. coach_wizards/refactoring_wizard.py +0 -91
  201. coach_wizards/scaling_wizard.py +0 -90
  202. coach_wizards/security_wizard.py +0 -92
  203. coach_wizards/testing_wizard.py +0 -91
  204. empathy_framework-4.6.6.dist-info/METADATA +0 -1597
  205. empathy_framework-4.6.6.dist-info/RECORD +0 -410
  206. empathy_llm_toolkit/wizards/__init__.py +0 -43
  207. empathy_llm_toolkit/wizards/base_wizard.py +0 -364
  208. empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
  209. empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
  210. empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
  211. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
  212. empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
  213. empathy_os/wizard_factory_cli.py +0 -170
  214. empathy_software_plugin/wizards/__init__.py +0 -42
  215. empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
  216. empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
  217. empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
  218. empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
  219. empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
  220. empathy_software_plugin/wizards/base_wizard.py +0 -288
  221. empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
  222. empathy_software_plugin/wizards/code_review_wizard.py +0 -604
  223. empathy_software_plugin/wizards/debugging/__init__.py +0 -50
  224. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
  225. empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
  226. empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
  227. empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
  228. empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
  229. empathy_software_plugin/wizards/debugging/verification.py +0 -369
  230. empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
  231. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
  232. empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
  233. empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
  234. empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
  235. empathy_software_plugin/wizards/performance/__init__.py +0 -9
  236. empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
  237. empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
  238. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
  239. empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
  240. empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
  241. empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
  242. empathy_software_plugin/wizards/security/__init__.py +0 -32
  243. empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
  244. empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
  245. empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
  246. empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
  247. empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
  248. empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
  249. empathy_software_plugin/wizards/testing/__init__.py +0 -27
  250. empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
  251. empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
  252. empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
  253. empathy_software_plugin/wizards/testing_wizard.py +0 -274
  254. wizards/__init__.py +0 -82
  255. wizards/admission_assessment_wizard.py +0 -644
  256. wizards/care_plan.py +0 -321
  257. wizards/clinical_assessment.py +0 -769
  258. wizards/discharge_planning.py +0 -77
  259. wizards/discharge_summary_wizard.py +0 -468
  260. wizards/dosage_calculation.py +0 -497
  261. wizards/incident_report_wizard.py +0 -454
  262. wizards/medication_reconciliation.py +0 -85
  263. wizards/nursing_assessment.py +0 -171
  264. wizards/patient_education.py +0 -654
  265. wizards/quality_improvement.py +0 -705
  266. wizards/sbar_report.py +0 -324
  267. wizards/sbar_wizard.py +0 -608
  268. wizards/shift_handoff_wizard.py +0 -535
  269. wizards/soap_note_wizard.py +0 -679
  270. wizards/treatment_plan.py +0 -15
  271. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/WHEEL +0 -0
  272. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/entry_points.txt +0 -0
  273. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,163 @@
1
+ """Session Start Hook
2
+
3
+ Loads previous context and patterns on new session start.
4
+ Ported from everything-claude-code/scripts/hooks/session-start.js
5
+
6
+ Copyright 2025 Smart-AI-Memory
7
+ Licensed under Fair Source License 0.9
8
+ """
9
+
10
+ import json
11
+ import logging
12
+ from datetime import datetime, timedelta
13
+ from pathlib import Path
14
+ from typing import Any
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ def get_sessions_dir() -> Path:
20
+ """Get the sessions directory path."""
21
+ return Path.home() / ".empathy" / "sessions"
22
+
23
+
24
+ def get_patterns_dir() -> Path:
25
+ """Get the patterns directory path."""
26
+ return Path.home() / ".empathy" / "patterns"
27
+
28
+
29
+ def get_learned_skills_dir() -> Path:
30
+ """Get the learned skills directory path."""
31
+ return Path.home() / ".empathy" / "skills" / "learned"
32
+
33
+
34
+ def find_recent_files(
35
+ directory: Path,
36
+ pattern: str = "*.json",
37
+ max_age_days: int = 7,
38
+ ) -> list[Path]:
39
+ """Find files matching pattern modified within max_age_days.
40
+
41
+ Args:
42
+ directory: Directory to search
43
+ pattern: Glob pattern for files
44
+ max_age_days: Maximum file age in days
45
+
46
+ Returns:
47
+ List of matching file paths, sorted by modification time (newest first)
48
+
49
+ """
50
+ if not directory.exists():
51
+ return []
52
+
53
+ cutoff = datetime.now() - timedelta(days=max_age_days)
54
+ matching = []
55
+
56
+ for file_path in directory.glob(pattern):
57
+ if file_path.is_file():
58
+ mtime = datetime.fromtimestamp(file_path.stat().st_mtime)
59
+ if mtime >= cutoff:
60
+ matching.append((file_path, mtime))
61
+
62
+ # Sort by modification time, newest first
63
+ matching.sort(key=lambda x: x[1], reverse=True)
64
+ return [path for path, _ in matching]
65
+
66
+
67
+ def load_session_state(session_file: Path) -> dict[str, Any] | None:
68
+ """Load session state from a file.
69
+
70
+ Args:
71
+ session_file: Path to session state file
72
+
73
+ Returns:
74
+ Session state dict or None if failed
75
+
76
+ """
77
+ try:
78
+ with open(session_file) as f:
79
+ return json.load(f)
80
+ except (json.JSONDecodeError, OSError) as e:
81
+ logger.warning("Failed to load session state from %s: %s", session_file, e)
82
+ return None
83
+
84
+
85
+ def main(**context: Any) -> dict[str, Any]:
86
+ """Session start hook main function.
87
+
88
+ Loads:
89
+ - Previous session state (trust level, patterns, preferences)
90
+ - Learned skills from previous sessions
91
+ - Project-specific patterns
92
+
93
+ Args:
94
+ **context: Hook context (session_id, project_path, etc.)
95
+
96
+ Returns:
97
+ Session initialization data
98
+
99
+ """
100
+ sessions_dir = get_sessions_dir()
101
+ patterns_dir = get_patterns_dir()
102
+ learned_dir = get_learned_skills_dir()
103
+
104
+ # Ensure directories exist
105
+ sessions_dir.mkdir(parents=True, exist_ok=True)
106
+ patterns_dir.mkdir(parents=True, exist_ok=True)
107
+ learned_dir.mkdir(parents=True, exist_ok=True)
108
+
109
+ result = {
110
+ "initialized": True,
111
+ "timestamp": datetime.now().isoformat(),
112
+ "loaded_state": None,
113
+ "learned_skills_count": 0,
114
+ "patterns_count": 0,
115
+ "messages": [],
116
+ }
117
+
118
+ # Find and load recent session state
119
+ recent_sessions = find_recent_files(sessions_dir, "*.json", max_age_days=7)
120
+
121
+ if recent_sessions:
122
+ latest = recent_sessions[0]
123
+ state = load_session_state(latest)
124
+
125
+ if state:
126
+ result["loaded_state"] = {
127
+ "file": str(latest),
128
+ "trust_level": state.get("trust_level"),
129
+ "interaction_count": state.get("interaction_count", 0),
130
+ "patterns_detected": len(state.get("detected_patterns", [])),
131
+ }
132
+ result["messages"].append(f"[SessionStart] Restored state from {latest.name}")
133
+ logger.info("Loaded session state from %s", latest)
134
+
135
+ # Count learned skills
136
+ learned_skills = list(learned_dir.glob("*.md"))
137
+ result["learned_skills_count"] = len(learned_skills)
138
+
139
+ if learned_skills:
140
+ result["messages"].append(
141
+ f"[SessionStart] {len(learned_skills)} learned skill(s) available"
142
+ )
143
+
144
+ # Count patterns
145
+ pattern_files = list(patterns_dir.glob("*.json"))
146
+ result["patterns_count"] = len(pattern_files)
147
+
148
+ if pattern_files:
149
+ result["messages"].append(f"[SessionStart] {len(pattern_files)} pattern file(s) loaded")
150
+
151
+ # Log summary
152
+ for msg in result["messages"]:
153
+ logger.info(msg)
154
+
155
+ return result
156
+
157
+
158
+ if __name__ == "__main__":
159
+ # Allow running as a script for testing
160
+
161
+ logging.basicConfig(level=logging.INFO, format="%(message)s")
162
+ result = main()
163
+ print(json.dumps(result, indent=2))
@@ -0,0 +1,225 @@
1
+ """Suggest Compact Hook
2
+
3
+ Suggests strategic compaction at logical breakpoints to manage context window.
4
+ Ported from everything-claude-code/scripts/hooks/suggest-compact.js
5
+
6
+ Copyright 2025 Smart-AI-Memory
7
+ Licensed under Fair Source License 0.9
8
+ """
9
+
10
+ import json
11
+ import logging
12
+ import os
13
+ from datetime import datetime
14
+ from pathlib import Path
15
+ from typing import Any
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ # Configuration
21
+ DEFAULT_COMPACT_THRESHOLD = 50 # Tool calls before first suggestion
22
+ DEFAULT_REMINDER_INTERVAL = 25 # Interval between reminders
23
+
24
+
25
+ def get_compaction_state_file() -> Path:
26
+ """Get the compaction state file path."""
27
+ return Path.home() / ".empathy" / "compaction_state.json"
28
+
29
+
30
+ def load_compaction_state() -> dict[str, Any]:
31
+ """Load compaction tracking state.
32
+
33
+ Returns:
34
+ Current compaction state
35
+
36
+ """
37
+ state_file = get_compaction_state_file()
38
+
39
+ if state_file.exists():
40
+ try:
41
+ with open(state_file) as f:
42
+ return json.load(f)
43
+ except (json.JSONDecodeError, OSError):
44
+ pass
45
+
46
+ return {
47
+ "tool_call_count": 0,
48
+ "last_suggestion": None,
49
+ "last_compaction": None,
50
+ "suggestion_count": 0,
51
+ }
52
+
53
+
54
+ def save_compaction_state(state: dict[str, Any]) -> None:
55
+ """Save compaction tracking state.
56
+
57
+ Args:
58
+ state: State to save
59
+
60
+ """
61
+ state_file = get_compaction_state_file()
62
+ state_file.parent.mkdir(parents=True, exist_ok=True)
63
+
64
+ with open(state_file, "w") as f:
65
+ json.dump(state, f, indent=2)
66
+
67
+
68
+ def should_suggest_compaction(
69
+ state: dict[str, Any],
70
+ threshold: int = DEFAULT_COMPACT_THRESHOLD,
71
+ interval: int = DEFAULT_REMINDER_INTERVAL,
72
+ ) -> tuple[bool, str]:
73
+ """Determine if compaction should be suggested.
74
+
75
+ Args:
76
+ state: Current compaction state
77
+ threshold: Tool calls before first suggestion
78
+ interval: Interval between reminders
79
+
80
+ Returns:
81
+ Tuple of (should_suggest, reason)
82
+
83
+ """
84
+ count = state.get("tool_call_count", 0)
85
+
86
+ # First threshold
87
+ if count == threshold:
88
+ return True, f"Reached {threshold} tool calls - good time to compact"
89
+
90
+ # Periodic reminders after threshold
91
+ if count > threshold and (count - threshold) % interval == 0:
92
+ return True, f"At {count} tool calls - consider compacting"
93
+
94
+ return False, ""
95
+
96
+
97
+ def get_compaction_recommendations(context: dict[str, Any]) -> list[str]:
98
+ """Get recommendations for what to compact.
99
+
100
+ Args:
101
+ context: Current session context
102
+
103
+ Returns:
104
+ List of recommendations
105
+
106
+ """
107
+ recommendations = []
108
+
109
+ # Check completed phases
110
+ completed_phases = context.get("completed_phases", [])
111
+
112
+ if completed_phases:
113
+ recommendations.append(
114
+ f"Completed phases ({', '.join(completed_phases)}) can be summarized"
115
+ )
116
+
117
+ # Check for exploration context
118
+ if context.get("exploration_complete", False):
119
+ recommendations.append("Exploration context can be compacted to findings only")
120
+
121
+ # Check for research context
122
+ if context.get("research_complete", False):
123
+ recommendations.append("Research context can be compacted to conclusions")
124
+
125
+ # General recommendations
126
+ if not recommendations:
127
+ recommendations = [
128
+ "Summarize completed work before starting new tasks",
129
+ "Keep implementation plan, compact exploration details",
130
+ "Preserve critical decisions and constraints",
131
+ ]
132
+
133
+ return recommendations
134
+
135
+
136
+ def main(**context: Any) -> dict[str, Any]:
137
+ """Suggest compact hook main function.
138
+
139
+ Tracks tool usage and suggests compaction at strategic points.
140
+
141
+ Args:
142
+ **context: Hook context (tool name, current phase, etc.)
143
+
144
+ Returns:
145
+ Compaction suggestion result
146
+
147
+ """
148
+ threshold = int(os.environ.get("COMPACT_THRESHOLD", DEFAULT_COMPACT_THRESHOLD))
149
+ interval = int(os.environ.get("COMPACT_INTERVAL", DEFAULT_REMINDER_INTERVAL))
150
+
151
+ # Load and update state
152
+ state = load_compaction_state()
153
+ state["tool_call_count"] = state.get("tool_call_count", 0) + 1
154
+
155
+ result = {
156
+ "tool_call_count": state["tool_call_count"],
157
+ "suggest_compaction": False,
158
+ "reason": "",
159
+ "recommendations": [],
160
+ "messages": [],
161
+ }
162
+
163
+ # Check if we should suggest compaction
164
+ should_suggest, reason = should_suggest_compaction(state, threshold, interval)
165
+
166
+ if should_suggest:
167
+ result["suggest_compaction"] = True
168
+ result["reason"] = reason
169
+ result["recommendations"] = get_compaction_recommendations(context)
170
+
171
+ state["last_suggestion"] = datetime.now().isoformat()
172
+ state["suggestion_count"] = state.get("suggestion_count", 0) + 1
173
+
174
+ result["messages"].append(f"[SuggestCompact] {reason}")
175
+ for rec in result["recommendations"]:
176
+ result["messages"].append(f"[SuggestCompact] - {rec}")
177
+
178
+ # Save updated state
179
+ save_compaction_state(state)
180
+
181
+ # Log messages
182
+ for msg in result["messages"]:
183
+ logger.info(msg)
184
+
185
+ return result
186
+
187
+
188
+ def reset_on_compaction(**context: Any) -> dict[str, Any]:
189
+ """Reset compaction state after a compaction event.
190
+
191
+ Called by PreCompact hook.
192
+
193
+ Args:
194
+ **context: Hook context
195
+
196
+ Returns:
197
+ Reset confirmation
198
+
199
+ """
200
+ state = load_compaction_state()
201
+ state["tool_call_count"] = 0
202
+ state["last_compaction"] = datetime.now().isoformat()
203
+ save_compaction_state(state)
204
+
205
+ logger.info("[SuggestCompact] Reset after compaction")
206
+
207
+ return {
208
+ "reset": True,
209
+ "timestamp": datetime.now().isoformat(),
210
+ }
211
+
212
+
213
+ if __name__ == "__main__":
214
+ # Allow running as a script for testing
215
+
216
+ logging.basicConfig(level=logging.INFO, format="%(message)s")
217
+
218
+ # Simulate tool calls
219
+ for i in range(60):
220
+ result = main(current_phase="implementation")
221
+ if result["suggest_compaction"]:
222
+ print(f"\nCall {i + 1}: SUGGEST COMPACTION")
223
+ print(f" Reason: {result['reason']}")
224
+ for rec in result["recommendations"]:
225
+ print(f" - {rec}")
@@ -0,0 +1,30 @@
1
+ """Continuous Learning Module for Empathy Framework
2
+
3
+ Automatic pattern extraction from sessions to enable learning and improvement.
4
+ Identifies valuable patterns from user interactions for future application.
5
+
6
+ Architectural patterns inspired by everything-claude-code by Affaan Mustafa.
7
+ See: https://github.com/affaan-m/everything-claude-code (MIT License)
8
+ See: ACKNOWLEDGMENTS.md for full attribution.
9
+
10
+ Copyright 2025 Smart AI Memory, LLC
11
+ Licensed under Fair Source 0.9
12
+ """
13
+
14
+ from empathy_llm_toolkit.learning.evaluator import SessionEvaluator, SessionQuality
15
+ from empathy_llm_toolkit.learning.extractor import (
16
+ ExtractedPattern,
17
+ PatternCategory,
18
+ PatternExtractor,
19
+ )
20
+ from empathy_llm_toolkit.learning.storage import LearnedSkill, LearnedSkillsStorage
21
+
22
+ __all__ = [
23
+ "ExtractedPattern",
24
+ "LearnedSkill",
25
+ "LearnedSkillsStorage",
26
+ "PatternCategory",
27
+ "PatternExtractor",
28
+ "SessionEvaluator",
29
+ "SessionQuality",
30
+ ]