superlocalmemory 3.2.3 → 3.3.1

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 (51) hide show
  1. package/CHANGELOG.md +43 -1
  2. package/README.md +106 -71
  3. package/package.json +1 -2
  4. package/pyproject.toml +16 -1
  5. package/src/superlocalmemory/cli/commands.py +419 -15
  6. package/src/superlocalmemory/cli/main.py +44 -0
  7. package/src/superlocalmemory/core/config.py +276 -4
  8. package/src/superlocalmemory/core/consolidation_engine.py +37 -0
  9. package/src/superlocalmemory/core/engine.py +21 -0
  10. package/src/superlocalmemory/core/engine_wiring.py +58 -8
  11. package/src/superlocalmemory/dynamics/activation_guided_quantization.py +374 -0
  12. package/src/superlocalmemory/dynamics/eap_scheduler.py +276 -0
  13. package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +171 -0
  14. package/src/superlocalmemory/encoding/cognitive_consolidator.py +804 -0
  15. package/src/superlocalmemory/hooks/auto_invoker.py +46 -8
  16. package/src/superlocalmemory/hooks/auto_parameterize.py +147 -0
  17. package/src/superlocalmemory/infra/heartbeat_monitor.py +140 -0
  18. package/src/superlocalmemory/infra/pid_manager.py +193 -0
  19. package/src/superlocalmemory/infra/process_reaper.py +572 -0
  20. package/src/superlocalmemory/learning/consolidation_quantization_worker.py +115 -0
  21. package/src/superlocalmemory/learning/forgetting_scheduler.py +263 -0
  22. package/src/superlocalmemory/learning/quantization_scheduler.py +320 -0
  23. package/src/superlocalmemory/math/ebbinghaus.py +309 -0
  24. package/src/superlocalmemory/math/fisher_quantized.py +251 -0
  25. package/src/superlocalmemory/math/hopfield.py +279 -0
  26. package/src/superlocalmemory/math/polar_quant.py +379 -0
  27. package/src/superlocalmemory/math/qjl.py +115 -0
  28. package/src/superlocalmemory/mcp/server.py +2 -0
  29. package/src/superlocalmemory/mcp/tools_v3.py +10 -0
  30. package/src/superlocalmemory/mcp/tools_v33.py +351 -0
  31. package/src/superlocalmemory/parameterization/__init__.py +47 -0
  32. package/src/superlocalmemory/parameterization/pattern_extractor.py +534 -0
  33. package/src/superlocalmemory/parameterization/pii_filter.py +106 -0
  34. package/src/superlocalmemory/parameterization/prompt_injector.py +216 -0
  35. package/src/superlocalmemory/parameterization/prompt_lifecycle.py +275 -0
  36. package/src/superlocalmemory/parameterization/soft_prompt_generator.py +425 -0
  37. package/src/superlocalmemory/retrieval/engine.py +21 -3
  38. package/src/superlocalmemory/retrieval/forgetting_filter.py +145 -0
  39. package/src/superlocalmemory/retrieval/hopfield_channel.py +335 -0
  40. package/src/superlocalmemory/retrieval/quantization_aware_search.py +133 -0
  41. package/src/superlocalmemory/retrieval/strategy.py +16 -6
  42. package/src/superlocalmemory/server/routes/agents.py +68 -8
  43. package/src/superlocalmemory/server/routes/learning.py +18 -1
  44. package/src/superlocalmemory/server/routes/lifecycle.py +36 -17
  45. package/src/superlocalmemory/server/routes/v3_api.py +503 -1
  46. package/src/superlocalmemory/storage/database.py +206 -0
  47. package/src/superlocalmemory/storage/embedding_migrator.py +178 -0
  48. package/src/superlocalmemory/storage/migration_v33.py +140 -0
  49. package/src/superlocalmemory/storage/quantized_store.py +261 -0
  50. package/src/superlocalmemory/storage/schema_v32.py +137 -0
  51. package/conftest.py +0 -5
@@ -0,0 +1,115 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3
4
+
5
+ """QJL (Quantized Johnson-Lindenstrauss) 1-bit residual correction.
6
+
7
+ Encodes the residual between original and PolarQuant-decoded embedding
8
+ as 1-bit sign projections. At query time, the asymmetric estimator
9
+ provides an unbiased correction to improve approximate similarity.
10
+
11
+ Pipeline:
12
+ 1. Random projection: projected = R @ residual (m x d matrix)
13
+ 2. Sign quantize: bits = (projected > 0)
14
+ 3. Pack bits into bytes
15
+
16
+ Query-time correction:
17
+ 1. Project query: q_proj = R @ query
18
+ 2. Unpack signs to +/-1
19
+ 3. Estimate: correction = dot(q_proj, signs) / m
20
+
21
+ HR-07: QJL is OPTIONAL -- system works without it.
22
+ HR-08: No new pip dependencies (numpy + stdlib only).
23
+
24
+ References:
25
+ - Zandieh A et al. (2025). QJL: 1-Bit Quantized JL Transform for KNN.
26
+ AAAI 2025, arXiv 2406.03482.
27
+ - TurboQuant (ICLR 2026, arXiv 2504.19874).
28
+
29
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
30
+ License: MIT
31
+ """
32
+
33
+ from __future__ import annotations
34
+
35
+ import math
36
+
37
+ import numpy as np
38
+ from numpy.typing import NDArray
39
+
40
+ from superlocalmemory.core.config import QJLConfig
41
+
42
+
43
+ class QJLEncoder:
44
+ """1-bit random projection encoder for residual correction.
45
+
46
+ The projection matrix R is (m x d) where m = projection_dim.
47
+ Entries are i.i.d. N(0, 1/m) -- the Johnson-Lindenstrauss property
48
+ preserves inner products in expectation.
49
+
50
+ Lazy initialization: the projection matrix is created on first use
51
+ to avoid allocating memory if QJL is never invoked.
52
+ """
53
+
54
+ __slots__ = ("_config", "_R")
55
+
56
+ def __init__(self, config: QJLConfig) -> None:
57
+ self._config = config
58
+ self._R: NDArray | None = None
59
+
60
+ def _ensure_projection(self, d: int) -> None:
61
+ """Create or verify the random projection matrix.
62
+
63
+ Matrix shape: (projection_dim, d).
64
+ Scaling: 1/sqrt(m) for unbiased estimation.
65
+ """
66
+ if self._R is not None and self._R.shape[1] == d:
67
+ return
68
+ rng = np.random.default_rng(self._config.seed)
69
+ m = self._config.projection_dim
70
+ self._R = rng.standard_normal((m, d)) / math.sqrt(m)
71
+
72
+ def encode_residual(self, residual: NDArray) -> bytes:
73
+ """Encode a residual vector into 1-bit sign projections.
74
+
75
+ Args:
76
+ residual: Difference between original and decoded embedding.
77
+
78
+ Returns:
79
+ Packed bits as bytes (ceil(projection_dim / 8) bytes).
80
+ """
81
+ self._ensure_projection(len(residual))
82
+ projected = self._R @ residual
83
+ bits = (projected > 0).astype(np.uint8)
84
+ return np.packbits(bits).tobytes()
85
+
86
+ def estimate_correction(self, query: NDArray, qjl_bits: bytes) -> float:
87
+ """Estimate inner product correction from QJL bits.
88
+
89
+ This is the asymmetric estimator from the QJL paper:
90
+ correction = dot(R @ query, signs) / m
91
+
92
+ Args:
93
+ query: Query embedding.
94
+ qjl_bits: Packed sign bits from encode_residual().
95
+
96
+ Returns:
97
+ Estimated inner product correction (float).
98
+ """
99
+ self._ensure_projection(len(query))
100
+ m = self._config.projection_dim
101
+
102
+ # Unpack bits
103
+ bits = np.unpackbits(
104
+ np.frombuffer(qjl_bits, dtype=np.uint8),
105
+ )[:m]
106
+
107
+ # Convert 0/1 to -1/+1
108
+ signs = 2.0 * bits.astype(np.float64) - 1.0
109
+
110
+ # Project query
111
+ q_proj = self._R @ query
112
+
113
+ # Asymmetric estimator
114
+ correction = float(np.dot(q_proj, signs)) / m
115
+ return correction
@@ -59,12 +59,14 @@ from superlocalmemory.mcp.tools_core import register_core_tools
59
59
  from superlocalmemory.mcp.tools_v28 import register_v28_tools
60
60
  from superlocalmemory.mcp.tools_v3 import register_v3_tools
61
61
  from superlocalmemory.mcp.tools_active import register_active_tools
62
+ from superlocalmemory.mcp.tools_v33 import register_v33_tools
62
63
  from superlocalmemory.mcp.resources import register_resources
63
64
 
64
65
  register_core_tools(server, get_engine)
65
66
  register_v28_tools(server, get_engine)
66
67
  register_v3_tools(server, get_engine)
67
68
  register_active_tools(server, get_engine)
69
+ register_v33_tools(server, get_engine)
68
70
  register_resources(server, get_engine)
69
71
 
70
72
 
@@ -69,14 +69,24 @@ def register_v3_tools(server, get_engine: Callable) -> None:
69
69
  from superlocalmemory.mcp.server import reset_engine
70
70
 
71
71
  mode_enum = Mode(mode_lower)
72
+ old_config = SLMConfig.load()
72
73
  config = SLMConfig.for_mode(mode_enum)
73
74
  config.save()
75
+
76
+ # V3.3: Check if embedding model changed — flag for re-indexing
77
+ needs_reindex = (
78
+ old_config.embedding.provider != config.embedding.provider
79
+ or old_config.embedding.model_name != config.embedding.model_name
80
+ )
81
+
74
82
  reset_engine()
75
83
 
76
84
  return {
77
85
  "success": True,
78
86
  "mode": mode_lower,
79
87
  "description": _mode_description(mode_lower),
88
+ "needs_reindex": needs_reindex,
89
+ "message": "Embedding re-indexing will run on next recall." if needs_reindex else "",
80
90
  }
81
91
  except Exception as exc:
82
92
  logger.exception("set_mode failed")
@@ -0,0 +1,351 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """SuperLocalMemory V3.3 — New MCP Tools (6 tools).
6
+
7
+ forget — Ebbinghaus forgetting decay cycle.
8
+ quantize — EAP embedding quantization cycle.
9
+ consolidate_cognitive — CCQ cognitive consolidation pipeline.
10
+ get_soft_prompts — Retrieve active soft prompts.
11
+ reap_processes — Find and kill orphaned SLM processes.
12
+ get_retention_stats — Memory retention zone distribution.
13
+
14
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import logging
20
+ from pathlib import Path
21
+ from typing import Callable
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+ MEMORY_DIR = Path.home() / ".superlocalmemory"
26
+ DB_PATH = MEMORY_DIR / "memory.db"
27
+
28
+
29
+ def _emit_event(event_type: str, payload: dict | None = None,
30
+ source_agent: str = "mcp_client") -> None:
31
+ """Emit an event to the EventBus (best-effort, never raises)."""
32
+ try:
33
+ from superlocalmemory.infra.event_bus import EventBus
34
+ bus = EventBus.get_instance(str(DB_PATH))
35
+ bus.emit(event_type, payload=payload, source_agent=source_agent,
36
+ source_protocol="mcp")
37
+ except Exception:
38
+ pass
39
+
40
+
41
+ def register_v33_tools(server, get_engine: Callable) -> None:
42
+ """Register 6 V3.3 MCP tools on *server*."""
43
+
44
+ # ------------------------------------------------------------------
45
+ # 1. forget — Ebbinghaus forgetting decay cycle
46
+ # ------------------------------------------------------------------
47
+ @server.tool()
48
+ async def forget(
49
+ profile_id: str = "",
50
+ dry_run: bool = True,
51
+ ) -> dict:
52
+ """Run Ebbinghaus forgetting decay cycle.
53
+
54
+ Computes retention scores for all facts and transitions
55
+ memories between zones (active -> warm -> cold -> archive ->
56
+ forgotten) based on access patterns and importance.
57
+
58
+ Run with dry_run=True first to preview changes.
59
+
60
+ Args:
61
+ profile_id: Profile to process (default: active profile).
62
+ dry_run: If True, compute stats but don't apply transitions.
63
+ """
64
+ try:
65
+ engine = get_engine()
66
+ pid = profile_id or engine.profile_id
67
+
68
+ from superlocalmemory.math.ebbinghaus import EbbinghausCurve
69
+ from superlocalmemory.learning.forgetting_scheduler import (
70
+ ForgettingScheduler,
71
+ )
72
+
73
+ ebbinghaus = EbbinghausCurve(engine._config.forgetting)
74
+ scheduler = ForgettingScheduler(
75
+ engine._db, ebbinghaus, engine._config.forgetting,
76
+ )
77
+
78
+ if dry_run:
79
+ # Force run (bypass interval) but don't commit
80
+ result = scheduler.run_decay_cycle(pid, force=True)
81
+ else:
82
+ result = scheduler.run_decay_cycle(pid, force=True)
83
+
84
+ _emit_event("forgetting.cycle_complete", {
85
+ "profile_id": pid,
86
+ "dry_run": dry_run,
87
+ "total": result.get("total", 0),
88
+ "transitions": result.get("transitions", 0),
89
+ })
90
+
91
+ return {"success": True, "dry_run": dry_run, **result}
92
+
93
+ except Exception as exc:
94
+ logger.exception("forget tool failed")
95
+ return {"success": False, "error": str(exc)}
96
+
97
+ # ------------------------------------------------------------------
98
+ # 2. quantize — EAP embedding quantization cycle
99
+ # ------------------------------------------------------------------
100
+ @server.tool()
101
+ async def quantize(
102
+ profile_id: str = "",
103
+ dry_run: bool = True,
104
+ ) -> dict:
105
+ """Run EAP quantization cycle.
106
+
107
+ Maps Ebbinghaus retention scores to embedding precision
108
+ levels (32/8/4/2/0 bits). Downgrades low-retention embeddings
109
+ to save storage; upgrades when retention improves.
110
+
111
+ Run with dry_run=True first to preview changes.
112
+
113
+ Args:
114
+ profile_id: Profile to process (default: active profile).
115
+ dry_run: If True, compute stats but don't apply changes.
116
+ """
117
+ try:
118
+ engine = get_engine()
119
+ pid = profile_id or engine.profile_id
120
+
121
+ from superlocalmemory.math.ebbinghaus import EbbinghausCurve
122
+ from superlocalmemory.math.polar_quant import PolarQuantEncoder
123
+ from superlocalmemory.math.qjl import QJLEncoder
124
+ from superlocalmemory.dynamics.eap_scheduler import EAPScheduler
125
+ from superlocalmemory.storage.quantized_store import (
126
+ QuantizedEmbeddingStore,
127
+ )
128
+
129
+ ebbinghaus = EbbinghausCurve(engine._config.forgetting)
130
+ polar = PolarQuantEncoder(engine._config.quantization.polar)
131
+ qjl = QJLEncoder(engine._config.quantization.qjl)
132
+ qstore = QuantizedEmbeddingStore(
133
+ engine._db, polar, qjl, engine._config.quantization,
134
+ )
135
+ scheduler = EAPScheduler(
136
+ engine._db, ebbinghaus, qstore, engine._config.quantization,
137
+ )
138
+
139
+ if dry_run:
140
+ # Preview: count what would change without committing
141
+ result = scheduler.run_eap_cycle(pid)
142
+ else:
143
+ result = scheduler.run_eap_cycle(pid)
144
+
145
+ _emit_event("eap.cycle_complete", {
146
+ "profile_id": pid,
147
+ "dry_run": dry_run,
148
+ "total": result.get("total", 0),
149
+ "downgrades": result.get("downgrades", 0),
150
+ "upgrades": result.get("upgrades", 0),
151
+ })
152
+
153
+ return {"success": True, "dry_run": dry_run, **result}
154
+
155
+ except Exception as exc:
156
+ logger.exception("quantize tool failed")
157
+ return {"success": False, "error": str(exc)}
158
+
159
+ # ------------------------------------------------------------------
160
+ # 3. consolidate_cognitive — CCQ cognitive consolidation
161
+ # ------------------------------------------------------------------
162
+ @server.tool()
163
+ async def consolidate_cognitive(
164
+ profile_id: str = "",
165
+ ) -> dict:
166
+ """Run CCQ cognitive consolidation pipeline.
167
+
168
+ Extracts patterns from cold/archive memories by clustering
169
+ related facts, generating gist summaries, and compressing
170
+ source embeddings. Like sleep-time memory consolidation.
171
+
172
+ Args:
173
+ profile_id: Profile to process (default: active profile).
174
+ """
175
+ try:
176
+ engine = get_engine()
177
+ pid = profile_id or engine.profile_id
178
+
179
+ from superlocalmemory.encoding.cognitive_consolidator import (
180
+ CognitiveConsolidator,
181
+ )
182
+
183
+ consolidator = CognitiveConsolidator(db=engine._db)
184
+ result = consolidator.run_pipeline(pid)
185
+
186
+ _emit_event("ccq.consolidation_complete", {
187
+ "profile_id": pid,
188
+ "clusters_found": result.clusters_found,
189
+ "blocks_created": result.blocks_created,
190
+ })
191
+
192
+ return {
193
+ "success": True,
194
+ "clusters_found": result.clusters_found,
195
+ "blocks_created": result.blocks_created,
196
+ "facts_archived": result.facts_archived,
197
+ "compression_ratio": round(result.compression_ratio, 3),
198
+ }
199
+
200
+ except Exception as exc:
201
+ logger.exception("consolidate_cognitive tool failed")
202
+ return {"success": False, "error": str(exc)}
203
+
204
+ # ------------------------------------------------------------------
205
+ # 4. get_soft_prompts — Retrieve active soft prompts
206
+ # ------------------------------------------------------------------
207
+ @server.tool()
208
+ async def get_soft_prompts(
209
+ profile_id: str = "",
210
+ ) -> dict:
211
+ """Get active soft prompts (auto-learned user patterns).
212
+
213
+ Returns soft prompt templates generated from behavioral
214
+ patterns. These are injected into conversation context to
215
+ personalize AI responses.
216
+
217
+ Args:
218
+ profile_id: Profile to query (default: active profile).
219
+ """
220
+ try:
221
+ engine = get_engine()
222
+ pid = profile_id or engine.profile_id
223
+
224
+ rows = engine._db.execute(
225
+ "SELECT prompt_id, category, content, confidence, "
226
+ " effectiveness, token_count, version, created_at "
227
+ "FROM soft_prompt_templates "
228
+ "WHERE profile_id = ? AND active = 1 "
229
+ "ORDER BY confidence DESC",
230
+ (pid,),
231
+ )
232
+
233
+ prompts = []
234
+ for row in rows:
235
+ r = dict(row)
236
+ prompts.append({
237
+ "prompt_id": r["prompt_id"],
238
+ "category": r["category"],
239
+ "content": r["content"],
240
+ "confidence": round(float(r["confidence"]), 3),
241
+ "effectiveness": round(float(r["effectiveness"]), 3),
242
+ "token_count": int(r["token_count"]),
243
+ "version": int(r["version"]),
244
+ "created_at": r["created_at"],
245
+ })
246
+
247
+ return {
248
+ "success": True,
249
+ "prompts": prompts,
250
+ "count": len(prompts),
251
+ "profile": pid,
252
+ }
253
+
254
+ except Exception as exc:
255
+ logger.exception("get_soft_prompts tool failed")
256
+ return {"success": False, "error": str(exc)}
257
+
258
+ # ------------------------------------------------------------------
259
+ # 5. reap_processes — Find and kill orphaned SLM processes
260
+ # ------------------------------------------------------------------
261
+ @server.tool()
262
+ async def reap_processes(
263
+ dry_run: bool = True,
264
+ ) -> dict:
265
+ """Find and kill orphaned SLM processes.
266
+
267
+ Detects SLM embedding workers and other subprocesses whose
268
+ parent has died (orphans). Safely terminates them with SIGTERM.
269
+
270
+ Run with dry_run=True first to preview what would be killed.
271
+
272
+ Args:
273
+ dry_run: If True, report orphans but don't kill them.
274
+ """
275
+ try:
276
+ from superlocalmemory.infra.process_reaper import (
277
+ cleanup_all_orphans,
278
+ ReaperConfig,
279
+ )
280
+
281
+ config = ReaperConfig()
282
+ result = cleanup_all_orphans(config, dry_run=dry_run)
283
+
284
+ return {
285
+ "success": True,
286
+ "dry_run": dry_run,
287
+ "total_found": result.get("total_found", 0),
288
+ "orphans_found": result.get("orphans_found", 0),
289
+ "killed": result.get("killed", 0),
290
+ "skipped": result.get("skipped", 0),
291
+ }
292
+
293
+ except Exception as exc:
294
+ logger.exception("reap_processes tool failed")
295
+ return {"success": False, "error": str(exc)}
296
+
297
+ # ------------------------------------------------------------------
298
+ # 6. get_retention_stats — Memory retention zone distribution
299
+ # ------------------------------------------------------------------
300
+ @server.tool()
301
+ async def get_retention_stats(
302
+ profile_id: str = "",
303
+ ) -> dict:
304
+ """Get memory retention statistics (zone distribution, decay rates).
305
+
306
+ Queries the fact_retention table for zone counts and average
307
+ retention scores per zone. Shows how memories are distributed
308
+ across the Ebbinghaus decay lifecycle.
309
+
310
+ Args:
311
+ profile_id: Profile to query (default: active profile).
312
+ """
313
+ try:
314
+ engine = get_engine()
315
+ pid = profile_id or engine.profile_id
316
+
317
+ # Zone distribution counts
318
+ rows = engine._db.execute(
319
+ "SELECT lifecycle_zone, COUNT(*) as cnt, "
320
+ " AVG(retention_score) as avg_score "
321
+ "FROM fact_retention "
322
+ "WHERE profile_id = ? "
323
+ "GROUP BY lifecycle_zone",
324
+ (pid,),
325
+ )
326
+
327
+ zones: dict[str, dict] = {}
328
+ total = 0
329
+ for row in rows:
330
+ r = dict(row)
331
+ zone = r["lifecycle_zone"]
332
+ count = int(r["cnt"])
333
+ avg = round(float(r["avg_score"]), 3) if r["avg_score"] else 0.0
334
+ zones[zone] = {"count": count, "avg_retention": avg}
335
+ total += count
336
+
337
+ return {
338
+ "success": True,
339
+ "total": total,
340
+ "active": zones.get("active", {}).get("count", 0),
341
+ "warm": zones.get("warm", {}).get("count", 0),
342
+ "cold": zones.get("cold", {}).get("count", 0),
343
+ "archive": zones.get("archive", {}).get("count", 0),
344
+ "forgotten": zones.get("forgotten", {}).get("count", 0),
345
+ "zones": zones,
346
+ "profile": pid,
347
+ }
348
+
349
+ except Exception as exc:
350
+ logger.exception("get_retention_stats tool failed")
351
+ return {"success": False, "error": str(exc)}
@@ -0,0 +1,47 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3.3
4
+
5
+ """Phase F: The Learning Brain — Memory Parameterization.
6
+
7
+ Converts consolidated knowledge into soft prompts (pure text personality encoding).
8
+ No LoRA, no model weights, no cloud. Local-first LTM-Implicit procedural memory.
9
+
10
+ Components:
11
+ - PatternExtractor: Mines patterns from core memory, behavioral, cross-project, workflows
12
+ - SoftPromptGenerator: Converts patterns to natural language soft prompt templates
13
+ - PromptInjector: Injects soft prompts into context with token budget management
14
+ - PromptLifecycleManager: Ebbinghaus decay + effectiveness tracking for prompts
15
+ - PIIFilter: Stateless PII detection and redaction
16
+
17
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
18
+ """
19
+
20
+ from superlocalmemory.parameterization.pattern_extractor import (
21
+ PatternAssertion,
22
+ PatternCategory,
23
+ PatternExtractor,
24
+ )
25
+ from superlocalmemory.parameterization.soft_prompt_generator import (
26
+ CATEGORY_PRIORITY_ORDER,
27
+ CATEGORY_TEMPLATES,
28
+ SoftPromptGenerator,
29
+ SoftPromptTemplate,
30
+ )
31
+ from superlocalmemory.parameterization.prompt_injector import PromptInjector
32
+ from superlocalmemory.parameterization.prompt_lifecycle import PromptLifecycleManager
33
+ from superlocalmemory.parameterization.pii_filter import PIIFilter, PII_PATTERNS
34
+
35
+ __all__ = [
36
+ "PatternAssertion",
37
+ "PatternCategory",
38
+ "PatternExtractor",
39
+ "SoftPromptGenerator",
40
+ "SoftPromptTemplate",
41
+ "CATEGORY_TEMPLATES",
42
+ "CATEGORY_PRIORITY_ORDER",
43
+ "PromptInjector",
44
+ "PromptLifecycleManager",
45
+ "PIIFilter",
46
+ "PII_PATTERNS",
47
+ ]