superlocalmemory 2.6.0 → 2.6.5
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.
- package/CHANGELOG.md +122 -1806
- package/README.md +142 -410
- package/docs/ACCESSIBILITY.md +291 -0
- package/docs/FRAMEWORK-INTEGRATIONS.md +300 -0
- package/package.json +1 -1
- package/src/learning/__init__.py +201 -0
- package/src/learning/adaptive_ranker.py +826 -0
- package/src/learning/cross_project_aggregator.py +866 -0
- package/src/learning/engagement_tracker.py +638 -0
- package/src/learning/feature_extractor.py +461 -0
- package/src/learning/feedback_collector.py +690 -0
- package/src/learning/learning_db.py +842 -0
- package/src/learning/project_context_manager.py +582 -0
- package/src/learning/source_quality_scorer.py +685 -0
- package/src/learning/workflow_pattern_miner.py +665 -0
- package/ui/index.html +346 -13
- package/ui/js/clusters.js +90 -1
- package/ui/js/graph-core.js +445 -0
- package/ui/js/graph-cytoscape-monolithic-backup.js +1168 -0
- package/ui/js/graph-cytoscape.js +1168 -0
- package/ui/js/graph-d3-backup.js +32 -0
- package/ui/js/graph-filters.js +220 -0
- package/ui/js/graph-interactions.js +354 -0
- package/ui/js/graph-ui.js +214 -0
- package/ui/js/memories.js +52 -0
- package/ui/js/modal.js +104 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
SuperLocalMemory V2 - Learning System (v2.7)
|
|
4
|
+
Copyright (c) 2026 Varun Pratap Bhardwaj
|
|
5
|
+
Licensed under MIT License
|
|
6
|
+
|
|
7
|
+
Repository: https://github.com/varun369/SuperLocalMemoryV2
|
|
8
|
+
Author: Varun Pratap Bhardwaj (Solution Architect)
|
|
9
|
+
|
|
10
|
+
NOTICE: This software is protected by MIT License.
|
|
11
|
+
Attribution must be preserved in all copies or derivatives.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
Learning System — Feature detection and graceful import.
|
|
16
|
+
|
|
17
|
+
This module detects available dependencies and exposes feature flags
|
|
18
|
+
that the rest of the system uses to enable/disable learning features.
|
|
19
|
+
|
|
20
|
+
Design principle: If ANY import fails, the entire learning system
|
|
21
|
+
degrades gracefully to v2.6 behavior. Core memory operations are
|
|
22
|
+
NEVER affected by learning system failures.
|
|
23
|
+
|
|
24
|
+
Dependencies (all optional):
|
|
25
|
+
lightgbm>=4.0.0 — Learning-to-Rank re-ranker
|
|
26
|
+
scipy>=1.9.0 — Statistical functions (temporal decay, KDE)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
import logging
|
|
30
|
+
from pathlib import Path
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger("superlocalmemory.learning")
|
|
33
|
+
|
|
34
|
+
# ============================================================================
|
|
35
|
+
# Feature Detection
|
|
36
|
+
# ============================================================================
|
|
37
|
+
|
|
38
|
+
# Check LightGBM availability (required for ML ranking)
|
|
39
|
+
try:
|
|
40
|
+
import lightgbm # noqa: F401
|
|
41
|
+
HAS_LIGHTGBM = True
|
|
42
|
+
LIGHTGBM_VERSION = lightgbm.__version__
|
|
43
|
+
except ImportError:
|
|
44
|
+
HAS_LIGHTGBM = False
|
|
45
|
+
LIGHTGBM_VERSION = None
|
|
46
|
+
|
|
47
|
+
# Check SciPy availability (required for statistical functions)
|
|
48
|
+
try:
|
|
49
|
+
import scipy # noqa: F401
|
|
50
|
+
HAS_SCIPY = True
|
|
51
|
+
SCIPY_VERSION = scipy.__version__
|
|
52
|
+
except ImportError:
|
|
53
|
+
HAS_SCIPY = False
|
|
54
|
+
SCIPY_VERSION = None
|
|
55
|
+
|
|
56
|
+
# Check scikit-learn availability (already in core, but verify)
|
|
57
|
+
try:
|
|
58
|
+
import sklearn # noqa: F401
|
|
59
|
+
HAS_SKLEARN = True
|
|
60
|
+
except ImportError:
|
|
61
|
+
HAS_SKLEARN = False
|
|
62
|
+
|
|
63
|
+
# ============================================================================
|
|
64
|
+
# Composite Feature Flags
|
|
65
|
+
# ============================================================================
|
|
66
|
+
|
|
67
|
+
# ML ranking requires LightGBM
|
|
68
|
+
ML_RANKING_AVAILABLE = HAS_LIGHTGBM
|
|
69
|
+
|
|
70
|
+
# Full learning requires LightGBM + SciPy
|
|
71
|
+
FULL_LEARNING_AVAILABLE = HAS_LIGHTGBM and HAS_SCIPY
|
|
72
|
+
|
|
73
|
+
# Rule-based ranking works with zero optional deps
|
|
74
|
+
RULE_BASED_RANKING_AVAILABLE = True
|
|
75
|
+
|
|
76
|
+
# ============================================================================
|
|
77
|
+
# Paths
|
|
78
|
+
# ============================================================================
|
|
79
|
+
|
|
80
|
+
MEMORY_DIR = Path.home() / ".claude-memory"
|
|
81
|
+
LEARNING_DB_PATH = MEMORY_DIR / "learning.db"
|
|
82
|
+
MEMORY_DB_PATH = MEMORY_DIR / "memory.db"
|
|
83
|
+
MODELS_DIR = MEMORY_DIR / "models"
|
|
84
|
+
|
|
85
|
+
# ============================================================================
|
|
86
|
+
# Module-level lazy imports
|
|
87
|
+
# ============================================================================
|
|
88
|
+
|
|
89
|
+
# These are imported lazily to avoid circular imports and to allow
|
|
90
|
+
# individual module failures without breaking the whole system.
|
|
91
|
+
|
|
92
|
+
_learning_db = None
|
|
93
|
+
_adaptive_ranker = None
|
|
94
|
+
_feedback_collector = None
|
|
95
|
+
_engagement_tracker = None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def get_learning_db():
|
|
99
|
+
"""Get or create the LearningDB singleton."""
|
|
100
|
+
global _learning_db
|
|
101
|
+
if _learning_db is None:
|
|
102
|
+
try:
|
|
103
|
+
from .learning_db import LearningDB
|
|
104
|
+
_learning_db = LearningDB()
|
|
105
|
+
except Exception as e:
|
|
106
|
+
logger.warning("Failed to initialize LearningDB: %s", e)
|
|
107
|
+
return None
|
|
108
|
+
return _learning_db
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def get_adaptive_ranker():
|
|
112
|
+
"""Get or create the AdaptiveRanker singleton."""
|
|
113
|
+
global _adaptive_ranker
|
|
114
|
+
if _adaptive_ranker is None:
|
|
115
|
+
try:
|
|
116
|
+
from .adaptive_ranker import AdaptiveRanker
|
|
117
|
+
_adaptive_ranker = AdaptiveRanker()
|
|
118
|
+
except Exception as e:
|
|
119
|
+
logger.warning("Failed to initialize AdaptiveRanker: %s", e)
|
|
120
|
+
return None
|
|
121
|
+
return _adaptive_ranker
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def get_feedback_collector():
|
|
125
|
+
"""Get or create the FeedbackCollector singleton."""
|
|
126
|
+
global _feedback_collector
|
|
127
|
+
if _feedback_collector is None:
|
|
128
|
+
try:
|
|
129
|
+
from .feedback_collector import FeedbackCollector
|
|
130
|
+
_feedback_collector = FeedbackCollector()
|
|
131
|
+
except Exception as e:
|
|
132
|
+
logger.warning("Failed to initialize FeedbackCollector: %s", e)
|
|
133
|
+
return None
|
|
134
|
+
return _feedback_collector
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def get_engagement_tracker():
|
|
138
|
+
"""Get or create the EngagementTracker singleton."""
|
|
139
|
+
global _engagement_tracker
|
|
140
|
+
if _engagement_tracker is None:
|
|
141
|
+
try:
|
|
142
|
+
from .engagement_tracker import EngagementTracker
|
|
143
|
+
_engagement_tracker = EngagementTracker()
|
|
144
|
+
except Exception as e:
|
|
145
|
+
logger.warning("Failed to initialize EngagementTracker: %s", e)
|
|
146
|
+
return None
|
|
147
|
+
return _engagement_tracker
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def get_status() -> dict:
|
|
151
|
+
"""Return learning system status for diagnostics."""
|
|
152
|
+
status = {
|
|
153
|
+
"learning_available": FULL_LEARNING_AVAILABLE,
|
|
154
|
+
"ml_ranking_available": ML_RANKING_AVAILABLE,
|
|
155
|
+
"rule_based_available": RULE_BASED_RANKING_AVAILABLE,
|
|
156
|
+
"dependencies": {
|
|
157
|
+
"lightgbm": {
|
|
158
|
+
"installed": HAS_LIGHTGBM,
|
|
159
|
+
"version": LIGHTGBM_VERSION,
|
|
160
|
+
},
|
|
161
|
+
"scipy": {
|
|
162
|
+
"installed": HAS_SCIPY,
|
|
163
|
+
"version": SCIPY_VERSION,
|
|
164
|
+
},
|
|
165
|
+
"sklearn": {
|
|
166
|
+
"installed": HAS_SKLEARN,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
"paths": {
|
|
170
|
+
"learning_db": str(LEARNING_DB_PATH),
|
|
171
|
+
"models_dir": str(MODELS_DIR),
|
|
172
|
+
},
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
# Add learning DB stats if available
|
|
176
|
+
ldb = get_learning_db()
|
|
177
|
+
if ldb:
|
|
178
|
+
try:
|
|
179
|
+
status["learning_db_stats"] = ldb.get_stats()
|
|
180
|
+
except Exception:
|
|
181
|
+
status["learning_db_stats"] = None
|
|
182
|
+
|
|
183
|
+
return status
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# Log feature availability on import
|
|
187
|
+
if FULL_LEARNING_AVAILABLE:
|
|
188
|
+
logger.info(
|
|
189
|
+
"Learning system available: LightGBM %s, SciPy %s",
|
|
190
|
+
LIGHTGBM_VERSION, SCIPY_VERSION
|
|
191
|
+
)
|
|
192
|
+
elif ML_RANKING_AVAILABLE:
|
|
193
|
+
logger.info(
|
|
194
|
+
"Partial learning: LightGBM %s available, SciPy missing",
|
|
195
|
+
LIGHTGBM_VERSION
|
|
196
|
+
)
|
|
197
|
+
else:
|
|
198
|
+
logger.info(
|
|
199
|
+
"Learning dependencies not installed. "
|
|
200
|
+
"Install with: pip3 install -r requirements-learning.txt"
|
|
201
|
+
)
|