superlocalmemory 3.3.0 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superlocalmemory",
3
- "version": "3.3.0",
3
+ "version": "3.3.1",
4
4
  "description": "Information-geometric agent memory with mathematical guarantees. 4-channel retrieval, Fisher-Rao similarity, zero-LLM mode, EU AI Act compliant. Works with Claude, Cursor, Windsurf, and 17+ AI tools.",
5
5
  "keywords": [
6
6
  "ai-memory",
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "superlocalmemory"
3
- version = "3.3.0"
3
+ version = "3.3.1"
4
4
  description = "Information-geometric agent memory with mathematical guarantees"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
@@ -1129,27 +1129,122 @@ def cmd_hooks(args: Namespace) -> None:
1129
1129
 
1130
1130
 
1131
1131
  def cmd_session_context(args: Namespace) -> None:
1132
- """Print session context (for hook scripts and piping)."""
1133
- from superlocalmemory.hooks.auto_recall import AutoRecall
1132
+ """Print session context (for hook scripts and piping).
1133
+
1134
+ Uses a FAST PATH that queries SQLite directly (no engine/Ollama needed).
1135
+ This ensures the SessionStart hook completes within its 15s timeout even
1136
+ when Ollama requires a 60s+ cold start. The fast path returns:
1137
+ - Core Memory blocks (always-on context)
1138
+ - Recent high-importance memories (last 7 days)
1139
+ - Session summary from last session
1140
+ Falls back to the full engine path only if --full is passed explicitly.
1141
+ """
1142
+ import sqlite3
1143
+ from pathlib import Path
1134
1144
  from superlocalmemory.core.config import SLMConfig
1135
- from superlocalmemory.core.engine import MemoryEngine
1136
1145
 
1146
+ use_full = getattr(args, "full", False)
1147
+
1148
+ if use_full:
1149
+ # Full engine path (slow, requires Ollama) — for explicit CLI use
1150
+ try:
1151
+ from superlocalmemory.hooks.auto_recall import AutoRecall
1152
+ from superlocalmemory.core.engine import MemoryEngine
1153
+ config = SLMConfig.load()
1154
+ engine = MemoryEngine(config)
1155
+ engine.initialize()
1156
+ auto = AutoRecall(
1157
+ engine=engine,
1158
+ config={"enabled": True, "max_memories_injected": 10, "relevance_threshold": 0.3},
1159
+ )
1160
+ context = auto.get_session_context(
1161
+ query=getattr(args, "query", "") or "recent decisions and important context",
1162
+ )
1163
+ if context:
1164
+ print(context)
1165
+ except Exception as exc:
1166
+ logger.debug("session-context (full) failed: %s", exc)
1167
+ return
1168
+
1169
+ # ── FAST PATH: direct SQLite, no engine, <500ms ──────────────
1137
1170
  try:
1138
1171
  config = SLMConfig.load()
1139
- engine = MemoryEngine(config)
1140
- engine.initialize()
1172
+ db_path = config.base_dir / "memory.db"
1173
+ if not db_path.exists():
1174
+ return
1141
1175
 
1142
- auto = AutoRecall(
1143
- engine=engine,
1144
- config={"enabled": True, "max_memories_injected": 10, "relevance_threshold": 0.3},
1145
- )
1146
- context = auto.get_session_context(
1147
- query=getattr(args, "query", "") or "recent decisions and important context",
1148
- )
1149
- if context:
1150
- print(context)
1176
+ pid = config.active_profile
1177
+ conn = sqlite3.connect(str(db_path))
1178
+ conn.row_factory = sqlite3.Row
1179
+ sections = []
1180
+
1181
+ # 1. Core Memory blocks (compiled high-value context)
1182
+ try:
1183
+ rows = conn.execute(
1184
+ "SELECT block_type, content FROM core_memory_blocks "
1185
+ "WHERE profile_id = ? ORDER BY block_type",
1186
+ (pid,),
1187
+ ).fetchall()
1188
+ if rows:
1189
+ blocks = [f"[{r['block_type']}] {r['content']}" for r in rows]
1190
+ sections.append("## Core Memory\n" + "\n".join(blocks))
1191
+ except sqlite3.OperationalError:
1192
+ pass
1193
+
1194
+ # 2. Recent important memories (last 7 days, top 10 by importance)
1195
+ try:
1196
+ rows = conn.execute(
1197
+ "SELECT content, fact_type, created_at FROM atomic_facts "
1198
+ "WHERE profile_id = ? "
1199
+ "AND created_at >= datetime('now', '-7 days') "
1200
+ "AND lifecycle = 'active' "
1201
+ "ORDER BY importance DESC, created_at DESC LIMIT 10",
1202
+ (pid,),
1203
+ ).fetchall()
1204
+ if rows:
1205
+ items = []
1206
+ for r in rows:
1207
+ content = r["content"][:200]
1208
+ items.append(f"- [{r['fact_type'] or 'fact'}] {content}")
1209
+ sections.append("## Recent Context (7 days)\n" + "\n".join(items))
1210
+ except sqlite3.OperationalError:
1211
+ pass
1212
+
1213
+ # 3. Session markers (last session summary)
1214
+ try:
1215
+ rows = conn.execute(
1216
+ "SELECT content, created_at FROM atomic_facts "
1217
+ "WHERE profile_id = ? AND content LIKE 'Session%' "
1218
+ "ORDER BY created_at DESC LIMIT 3",
1219
+ (pid,),
1220
+ ).fetchall()
1221
+ if rows:
1222
+ items = [f"- {r['content'][:150]}" for r in rows]
1223
+ sections.append("## Recent Sessions\n" + "\n".join(items))
1224
+ except sqlite3.OperationalError:
1225
+ pass
1226
+
1227
+ # 4. V3.3 Soft prompts (auto-learned patterns)
1228
+ try:
1229
+ rows = conn.execute(
1230
+ "SELECT category, content FROM soft_prompt_templates "
1231
+ "WHERE profile_id = ? AND active = 1 "
1232
+ "ORDER BY confidence DESC LIMIT 5",
1233
+ (pid,),
1234
+ ).fetchall()
1235
+ if rows:
1236
+ items = [f"- [{r['category']}] {r['content'][:150]}" for r in rows]
1237
+ sections.append("## Learned Patterns\n" + "\n".join(items))
1238
+ except sqlite3.OperationalError:
1239
+ pass
1240
+
1241
+ conn.close()
1242
+
1243
+ if sections:
1244
+ header = f"# SLM Session Context — {config.active_profile}"
1245
+ print(header + "\n\n" + "\n\n".join(sections))
1151
1246
  except Exception as exc:
1152
- logger.debug("session-context failed: %s", exc)
1247
+ logger.debug("session-context (fast) failed: %s", exc)
1153
1248
 
1154
1249
 
1155
1250
  def cmd_observe(args: Namespace) -> None: