superlocalmemory 3.0.23 → 3.0.25
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.0.
|
|
3
|
+
"version": "3.0.25",
|
|
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
|
@@ -12,6 +12,7 @@ import os
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from fastapi import APIRouter, Request
|
|
14
14
|
from fastapi.responses import JSONResponse
|
|
15
|
+
from superlocalmemory.server.ui import SLM_VERSION
|
|
15
16
|
|
|
16
17
|
logger = logging.getLogger(__name__)
|
|
17
18
|
|
|
@@ -27,21 +28,26 @@ async def dashboard(request: Request):
|
|
|
27
28
|
from superlocalmemory.core.config import SLMConfig
|
|
28
29
|
config = SLMConfig.load()
|
|
29
30
|
|
|
30
|
-
#
|
|
31
|
-
|
|
31
|
+
# Read stats directly from SQLite (dashboard doesn't load engine)
|
|
32
|
+
import sqlite3
|
|
32
33
|
memory_count = 0
|
|
33
34
|
fact_count = 0
|
|
34
|
-
|
|
35
|
+
db_path = config.base_dir / "memory.db"
|
|
36
|
+
if db_path.exists():
|
|
35
37
|
try:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
conn = sqlite3.connect(str(db_path))
|
|
39
|
+
cursor = conn.cursor()
|
|
40
|
+
try:
|
|
41
|
+
cursor.execute("SELECT COUNT(*) FROM atomic_facts")
|
|
42
|
+
fact_count = cursor.fetchone()[0]
|
|
43
|
+
except Exception:
|
|
44
|
+
pass
|
|
45
|
+
try:
|
|
46
|
+
cursor.execute("SELECT COUNT(*) FROM memories")
|
|
47
|
+
memory_count = cursor.fetchone()[0]
|
|
48
|
+
except Exception:
|
|
49
|
+
pass
|
|
50
|
+
conn.close()
|
|
45
51
|
except Exception:
|
|
46
52
|
pass
|
|
47
53
|
|
|
@@ -54,7 +60,7 @@ async def dashboard(request: Request):
|
|
|
54
60
|
"fact_count": fact_count,
|
|
55
61
|
"profile": config.active_profile,
|
|
56
62
|
"base_dir": str(config.base_dir),
|
|
57
|
-
"version":
|
|
63
|
+
"version": SLM_VERSION,
|
|
58
64
|
}
|
|
59
65
|
except Exception as e:
|
|
60
66
|
return JSONResponse({"error": str(e)}, status_code=500)
|
|
@@ -26,21 +26,33 @@ logger = logging.getLogger(__name__)
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def _get_version() -> str:
|
|
29
|
-
"""Read version from package metadata,
|
|
29
|
+
"""Read version from package metadata, package.json, or pyproject.toml."""
|
|
30
|
+
import json as _json
|
|
31
|
+
# 1. Try importlib.metadata (works when pip-installed)
|
|
30
32
|
try:
|
|
31
33
|
from importlib.metadata import version
|
|
32
34
|
return version("superlocalmemory")
|
|
33
35
|
except Exception:
|
|
34
36
|
pass
|
|
37
|
+
# 2. Try package.json (works when npm-installed)
|
|
38
|
+
pkg_root = Path(__file__).resolve().parent.parent.parent.parent
|
|
39
|
+
try:
|
|
40
|
+
pkg_json = pkg_root / "package.json"
|
|
41
|
+
if pkg_json.exists():
|
|
42
|
+
with open(pkg_json) as f:
|
|
43
|
+
return _json.load(f).get("version", "")
|
|
44
|
+
except Exception:
|
|
45
|
+
pass
|
|
46
|
+
# 3. Try pyproject.toml
|
|
35
47
|
try:
|
|
36
48
|
import tomllib
|
|
37
|
-
toml_path =
|
|
49
|
+
toml_path = pkg_root / "pyproject.toml"
|
|
38
50
|
if toml_path.exists():
|
|
39
51
|
with open(toml_path, "rb") as f:
|
|
40
52
|
return tomllib.load(f)["project"]["version"]
|
|
41
53
|
except Exception:
|
|
42
54
|
pass
|
|
43
|
-
return "
|
|
55
|
+
return "unknown"
|
|
44
56
|
|
|
45
57
|
|
|
46
58
|
SLM_VERSION = _get_version()
|
|
@@ -111,7 +123,7 @@ def create_app() -> FastAPI:
|
|
|
111
123
|
return JSONResponse(
|
|
112
124
|
status_code=429,
|
|
113
125
|
content={"error": "Too many requests. Please slow down."},
|
|
114
|
-
headers={"Retry-After": str(limiter.
|
|
126
|
+
headers={"Retry-After": str(limiter.window)},
|
|
115
127
|
)
|
|
116
128
|
response = await call_next(request)
|
|
117
129
|
response.headers["X-RateLimit-Remaining"] = str(remaining)
|
package/ui/index.html
CHANGED
|
@@ -641,7 +641,7 @@
|
|
|
641
641
|
<div class="container-fluid">
|
|
642
642
|
<span class="navbar-brand mb-0 h1">
|
|
643
643
|
<i class="bi bi-diagram-3"></i> SuperLocalMemory V3
|
|
644
|
-
<span id="mode-badge" class="badge bg-light text-dark ms-2"
|
|
644
|
+
<span id="mode-badge" class="badge bg-light text-dark ms-2">...</span>
|
|
645
645
|
</span>
|
|
646
646
|
<div class="d-flex align-items-center gap-3">
|
|
647
647
|
<div class="d-flex align-items-center gap-2">
|
|
@@ -807,8 +807,8 @@
|
|
|
807
807
|
<h6 class="card-subtitle text-muted">Operating Mode</h6>
|
|
808
808
|
<i class="bi bi-shield-check stat-icon text-primary"></i>
|
|
809
809
|
</div>
|
|
810
|
-
<h3 id="dashboard-mode" class="stat-value">
|
|
811
|
-
<p id="dashboard-mode-desc" class="text-muted small mb-2">
|
|
810
|
+
<h3 id="dashboard-mode" class="stat-value">Loading...</h3>
|
|
811
|
+
<p id="dashboard-mode-desc" class="text-muted small mb-2">Connecting...</p>
|
|
812
812
|
<div class="btn-group btn-group-sm" role="group">
|
|
813
813
|
<button class="btn btn-outline-primary mode-btn" data-mode="a">A</button>
|
|
814
814
|
<button class="btn btn-outline-primary mode-btn" data-mode="b">B</button>
|
|
@@ -838,7 +838,7 @@
|
|
|
838
838
|
<h6 class="card-subtitle text-muted">LLM Provider</h6>
|
|
839
839
|
<i class="bi bi-cloud stat-icon text-info"></i>
|
|
840
840
|
</div>
|
|
841
|
-
<h3 id="dashboard-provider" class="stat-value">
|
|
841
|
+
<h3 id="dashboard-provider" class="stat-value">Loading...</h3>
|
|
842
842
|
<p id="dashboard-model" class="text-muted small mb-0"></p>
|
|
843
843
|
</div>
|
|
844
844
|
</div>
|
|
@@ -877,7 +877,7 @@
|
|
|
877
877
|
<div class="card-body">
|
|
878
878
|
<h6><i class="bi bi-info-circle"></i> System</h6>
|
|
879
879
|
<div class="row text-muted small">
|
|
880
|
-
<div class="col-md-3">Version: <strong
|
|
880
|
+
<div class="col-md-3">Version: <strong id="dashboard-version">...</strong></div>
|
|
881
881
|
<div class="col-md-3">Profile: <strong id="dashboard-profile">default</strong></div>
|
|
882
882
|
<div class="col-md-3">Base: <strong id="dashboard-basedir">~/.superlocalmemory</strong></div>
|
|
883
883
|
<div class="col-md-3">Math Layers: <strong class="text-success">Active</strong></div>
|
|
@@ -1687,7 +1687,7 @@
|
|
|
1687
1687
|
<p class="small text-muted">Backup: <span id="settings-backup-status">Check with <code>slm migrate --rollback</code></span></p>
|
|
1688
1688
|
</div>
|
|
1689
1689
|
<div class="col-md-6">
|
|
1690
|
-
<p class="small text-muted">Version: <strong
|
|
1690
|
+
<p class="small text-muted">Version: <strong id="settings-version">...</strong></p>
|
|
1691
1691
|
<p class="small text-muted">Engine: <strong class="text-success">V3 Active</strong></p>
|
|
1692
1692
|
</div>
|
|
1693
1693
|
</div>
|
package/ui/js/dashboard.js
CHANGED
|
@@ -29,6 +29,11 @@ async function loadDashboard() {
|
|
|
29
29
|
document.getElementById('dashboard-model').textContent = data.model || '';
|
|
30
30
|
document.getElementById('dashboard-profile').textContent = data.profile || 'default';
|
|
31
31
|
document.getElementById('dashboard-basedir').textContent = data.base_dir || '~/.superlocalmemory';
|
|
32
|
+
var ver = data.version || '';
|
|
33
|
+
var dashVer = document.getElementById('dashboard-version');
|
|
34
|
+
var settVer = document.getElementById('settings-version');
|
|
35
|
+
if (dashVer) dashVer.textContent = ver;
|
|
36
|
+
if (settVer) settVer.textContent = ver;
|
|
32
37
|
|
|
33
38
|
// Update mode badge in navbar
|
|
34
39
|
var badge = document.getElementById('mode-badge');
|