superlocalmemory 3.8.3 → 3.8.6
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 +76 -0
- package/README.md +3 -2
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-governance-advisor.md +1 -1
- package/plugin/agents/slm-loop-runner.md +1 -1
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/agents/slm-optimize-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-cache/SKILL.md +1 -1
- package/plugin/skills/slm-compress/SKILL.md +1 -1
- package/plugin/skills/slm-governance/SKILL.md +1 -1
- package/plugin/skills/slm-graph/SKILL.md +1 -1
- package/plugin/skills/slm-loop/SKILL.md +1 -1
- package/plugin/skills/slm-mesh/SKILL.md +1 -1
- package/plugin/skills/slm-profile/SKILL.md +1 -1
- package/plugin/skills/slm-recall/SKILL.md +1 -1
- package/plugin/skills/slm-remember/SKILL.md +1 -1
- package/plugin/skills/slm-scope/SKILL.md +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin/skills/slm-status/SKILL.md +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/plugin-src/skills/slm-cache/SKILL.md +1 -1
- package/plugin-src/skills/slm-compress/SKILL.md +1 -1
- package/plugin-src/skills/slm-graph/SKILL.md +1 -1
- package/plugin-src/skills/slm-recall/SKILL.md +1 -1
- package/plugin-src/skills/slm-remember/SKILL.md +1 -1
- package/plugin-src/skills/slm-session/SKILL.md +1 -1
- package/plugin-src/skills/slm-status/SKILL.md +1 -1
- package/pyproject.toml +9 -4
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/access/rbac.py +68 -76
- package/src/superlocalmemory/cli/commands.py +158 -404
- package/src/superlocalmemory/cli/ingest_cmd.py +11 -1
- package/src/superlocalmemory/cli/main.py +30 -0
- package/src/superlocalmemory/cli/pending_store.py +39 -14
- package/src/superlocalmemory/core/backend_orchestrator.py +93 -0
- package/src/superlocalmemory/core/component_registry.py +4 -2
- package/src/superlocalmemory/core/config.py +78 -0
- package/src/superlocalmemory/core/consolidation_engine.py +79 -73
- package/src/superlocalmemory/core/embeddings.py +33 -6
- package/src/superlocalmemory/core/engine.py +186 -60
- package/src/superlocalmemory/core/engine_ingestion.py +150 -63
- package/src/superlocalmemory/core/fact_consolidator.py +148 -30
- package/src/superlocalmemory/core/graph_pruner.py +436 -39
- package/src/superlocalmemory/core/ingestion_command.py +273 -32
- package/src/superlocalmemory/core/maintenance_scheduler.py +61 -1
- package/src/superlocalmemory/core/mutations.py +32 -10
- package/src/superlocalmemory/core/recall_pipeline.py +111 -74
- package/src/superlocalmemory/core/registry.py +5 -1
- package/src/superlocalmemory/core/remember_admission.py +152 -0
- package/src/superlocalmemory/core/remember_runtime.py +712 -0
- package/src/superlocalmemory/core/remote_mode.py +3 -1
- package/src/superlocalmemory/core/scale_engine.py +41 -18
- package/src/superlocalmemory/core/store_pipeline.py +18 -4
- package/src/superlocalmemory/encoding/entity_resolver.py +18 -11
- package/src/superlocalmemory/graph/cozo_backend.py +5 -5
- package/src/superlocalmemory/hooks/_outcome_common.py +9 -2
- package/src/superlocalmemory/hooks/adapter_base.py +58 -44
- package/src/superlocalmemory/hooks/ide_connector.py +26 -8
- package/src/superlocalmemory/hooks/portable_kit.py +105 -9
- package/src/superlocalmemory/hooks/prewarm_auth.py +21 -2
- package/src/superlocalmemory/infra/auth_middleware.py +3 -1
- package/src/superlocalmemory/infra/cloud_backup.py +26 -27
- package/src/superlocalmemory/infra/event_bus.py +250 -88
- package/src/superlocalmemory/learning/bandit.py +50 -1
- package/src/superlocalmemory/learning/consolidation_cycle.py +33 -16
- package/src/superlocalmemory/learning/entity_compiler.py +148 -132
- package/src/superlocalmemory/learning/memory_merge.py +97 -82
- package/src/superlocalmemory/learning/reward_archive.py +98 -90
- package/src/superlocalmemory/learning/reward_boost.py +40 -30
- package/src/superlocalmemory/learning/source_quality.py +38 -35
- package/src/superlocalmemory/mcp/_daemon_proxy.py +38 -15
- package/src/superlocalmemory/mcp/http_transport.py +335 -3
- package/src/superlocalmemory/mcp/tools_active.py +4 -41
- package/src/superlocalmemory/mcp/tools_core.py +26 -87
- package/src/superlocalmemory/mcp/tools_evolution.py +5 -10
- package/src/superlocalmemory/optimize/proxy/capture.py +196 -8
- package/src/superlocalmemory/retrieval/engine.py +15 -4
- package/src/superlocalmemory/retrieval/entity_channel.py +25 -1
- package/src/superlocalmemory/retrieval/reranker.py +130 -22
- package/src/superlocalmemory/retrieval/spreading_activation.py +20 -12
- package/src/superlocalmemory/retrieval/vector_store.py +84 -69
- package/src/superlocalmemory/server/loopback.py +85 -0
- package/src/superlocalmemory/server/origin.py +9 -4
- package/src/superlocalmemory/server/profile_runtime.py +14 -0
- package/src/superlocalmemory/server/routes/abstraction.py +2 -4
- package/src/superlocalmemory/server/routes/agents.py +3 -5
- package/src/superlocalmemory/server/routes/backup.py +6 -2
- package/src/superlocalmemory/server/routes/behavioral.py +11 -25
- package/src/superlocalmemory/server/routes/brain.py +6 -9
- package/src/superlocalmemory/server/routes/compliance.py +20 -23
- package/src/superlocalmemory/server/routes/config_api.py +83 -0
- package/src/superlocalmemory/server/routes/entity.py +3 -7
- package/src/superlocalmemory/server/routes/evolution.py +3 -5
- package/src/superlocalmemory/server/routes/helpers.py +57 -25
- package/src/superlocalmemory/server/routes/insights.py +2 -4
- package/src/superlocalmemory/server/routes/learning.py +2 -5
- package/src/superlocalmemory/server/routes/lifecycle.py +2 -4
- package/src/superlocalmemory/server/routes/memories.py +119 -98
- package/src/superlocalmemory/server/routes/mesh.py +7 -2
- package/src/superlocalmemory/server/routes/profiles.py +20 -21
- package/src/superlocalmemory/server/routes/rbac.py +0 -1
- package/src/superlocalmemory/server/routes/tiers.py +28 -35
- package/src/superlocalmemory/server/routes/timeline.py +2 -4
- package/src/superlocalmemory/server/routes/v3_api.py +85 -93
- package/src/superlocalmemory/server/unified_daemon.py +400 -140
- package/src/superlocalmemory/server/write_identity.py +22 -4
- package/src/superlocalmemory/storage/admission_codec.py +119 -0
- package/src/superlocalmemory/storage/admission_journal.py +728 -0
- package/src/superlocalmemory/storage/database.py +168 -19
- package/src/superlocalmemory/storage/deferred_writes.py +209 -0
- package/src/superlocalmemory/storage/embedding_migrator.py +19 -0
- package/src/superlocalmemory/storage/memory_write.py +115 -0
- package/src/superlocalmemory/storage/migration_runner.py +44 -0
- package/src/superlocalmemory/storage/migrations/M028_fact_entity_associations.py +113 -78
- package/src/superlocalmemory/storage/migrations/M031_dead_letter_operations.py +80 -0
- package/src/superlocalmemory/storage/migrations/M032_write_coordinator_admission.py +188 -0
- package/src/superlocalmemory/storage/read_connection.py +115 -0
- package/src/superlocalmemory/storage/write_coordinator.py +756 -0
- package/src/superlocalmemory/storage/write_lock.py +88 -0
- package/src/superlocalmemory/ui/index.html +1 -1
- package/src/superlocalmemory/ui/js/auto-settings.js +14 -1
- package/src/superlocalmemory/ui/js/od-settings.js +9 -3
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
+
# Licensed under AGPL-3.0-or-later - see LICENSE file
|
|
3
|
+
# Part of SuperLocalMemory V3 | https://qualixar.com
|
|
4
|
+
|
|
5
|
+
"""Physically read-only SQLite snapshots for canonical ``memory.db``.
|
|
6
|
+
|
|
7
|
+
The factory is deliberately small: a query path must receive a connection
|
|
8
|
+
which SQLite itself refuses to mutate. This is the storage half of the
|
|
9
|
+
Command-Query Separation contract; higher layers must not use it to perform
|
|
10
|
+
telemetry, access tracking, or any other side effect.
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import sqlite3
|
|
15
|
+
from contextlib import AbstractContextManager, contextmanager
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Iterator
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ReadConnectionError(RuntimeError):
|
|
21
|
+
"""Raised when a read snapshot cannot be opened safely."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ReadConnectionFactory:
|
|
25
|
+
"""Open short-lived query-only snapshots of one canonical database path."""
|
|
26
|
+
|
|
27
|
+
def __init__(self, memory_db: str | Path, timeout_ms: int = 250) -> None:
|
|
28
|
+
if timeout_ms < 0:
|
|
29
|
+
raise ValueError("timeout_ms must be greater than or equal to zero")
|
|
30
|
+
self._memory_db = Path(memory_db).expanduser().resolve()
|
|
31
|
+
self._timeout_ms = timeout_ms
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def memory_db(self) -> Path:
|
|
35
|
+
"""Return the resolved canonical database path."""
|
|
36
|
+
return self._memory_db
|
|
37
|
+
|
|
38
|
+
@contextmanager
|
|
39
|
+
def snapshot(self) -> Iterator[sqlite3.Connection]:
|
|
40
|
+
"""Yield a SQLite connection that cannot issue a write statement.
|
|
41
|
+
|
|
42
|
+
``immutable=1`` is intentionally not used: a live WAL database may
|
|
43
|
+
have valid state in its WAL file. ``mode=ro`` retains normal WAL
|
|
44
|
+
visibility while prohibiting a writable open, and ``query_only`` is a
|
|
45
|
+
second SQLite-enforced guard against accidental DML or DDL.
|
|
46
|
+
"""
|
|
47
|
+
if not self._memory_db.exists():
|
|
48
|
+
raise ReadConnectionError(f"canonical database does not exist: {self._memory_db}")
|
|
49
|
+
|
|
50
|
+
uri = f"{self._memory_db.as_uri()}?mode=ro"
|
|
51
|
+
try:
|
|
52
|
+
conn = sqlite3.connect(
|
|
53
|
+
uri,
|
|
54
|
+
uri=True,
|
|
55
|
+
timeout=self._timeout_ms / 1000.0,
|
|
56
|
+
)
|
|
57
|
+
except sqlite3.Error as exc:
|
|
58
|
+
raise ReadConnectionError(
|
|
59
|
+
f"could not open read-only snapshot for {self._memory_db}"
|
|
60
|
+
) from exc
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
conn.row_factory = sqlite3.Row
|
|
64
|
+
conn.execute("PRAGMA query_only=ON")
|
|
65
|
+
conn.execute("PRAGMA foreign_keys=ON")
|
|
66
|
+
conn.execute(f"PRAGMA busy_timeout={self._timeout_ms}")
|
|
67
|
+
yield conn
|
|
68
|
+
finally:
|
|
69
|
+
conn.close()
|
|
70
|
+
|
|
71
|
+
def open(self) -> "ReadConnectionLease":
|
|
72
|
+
"""Return a manually-closeable read-only lease for legacy query code.
|
|
73
|
+
|
|
74
|
+
New code should use :meth:`snapshot`; the lease is a small compatibility
|
|
75
|
+
bridge for client paths that still use ``try/finally: conn.close()``.
|
|
76
|
+
Closing it exits this same context manager, preserving both ``mode=ro``
|
|
77
|
+
and ``PRAGMA query_only`` rather than reopening SQLite directly.
|
|
78
|
+
"""
|
|
79
|
+
return ReadConnectionLease(self.snapshot())
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class ReadConnectionLease:
|
|
83
|
+
"""A legacy-compatible facade around one read-only snapshot."""
|
|
84
|
+
|
|
85
|
+
def __init__(self, snapshot: AbstractContextManager[sqlite3.Connection]) -> None:
|
|
86
|
+
object.__setattr__(self, "_snapshot", snapshot)
|
|
87
|
+
object.__setattr__(self, "_connection", snapshot.__enter__())
|
|
88
|
+
object.__setattr__(self, "_closed", False)
|
|
89
|
+
|
|
90
|
+
def __getattr__(self, name: str):
|
|
91
|
+
return getattr(self._connection, name)
|
|
92
|
+
|
|
93
|
+
def __setattr__(self, name: str, value: object) -> None:
|
|
94
|
+
if name.startswith("_"):
|
|
95
|
+
object.__setattr__(self, name, value)
|
|
96
|
+
else:
|
|
97
|
+
setattr(self._connection, name, value)
|
|
98
|
+
|
|
99
|
+
def __enter__(self) -> sqlite3.Connection:
|
|
100
|
+
return self._connection
|
|
101
|
+
|
|
102
|
+
def __exit__(self, exc_type, exc, traceback) -> None:
|
|
103
|
+
self._close(exc_type, exc, traceback)
|
|
104
|
+
|
|
105
|
+
def close(self) -> None:
|
|
106
|
+
"""Close this lease once, including its context-manager cleanup."""
|
|
107
|
+
self._close(None, None, None)
|
|
108
|
+
|
|
109
|
+
def _close(self, exc_type, exc, traceback) -> None:
|
|
110
|
+
if not self._closed:
|
|
111
|
+
object.__setattr__(self, "_closed", True)
|
|
112
|
+
self._snapshot.__exit__(exc_type, exc, traceback)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
__all__ = ["ReadConnectionError", "ReadConnectionFactory", "ReadConnectionLease"]
|