seren-memory 2.2.1__tar.gz → 2.2.2__tar.gz
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.
- {seren_memory-2.2.1 → seren_memory-2.2.2}/PKG-INFO +1 -1
- {seren_memory-2.2.1 → seren_memory-2.2.2}/SerenMemory.pyproj +1 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/_version.py +3 -3
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/app.py +1 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/viewer/halls.html +140 -24
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory.egg-info/PKG-INFO +1 -1
- {seren_memory-2.2.1 → seren_memory-2.2.2}/pyproject.toml +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren-memory.service.sample +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren-memory.yaml.sample +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/__init__.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/__main__.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/_supervised.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/collections.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/config.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/consolidator/__init__.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/consolidator/service.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/embedder.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/mcp/__init__.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/mcp/server.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/mcp/tools.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/models/__init__.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/models/schemas.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/routes/__init__.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/routes/long.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/routes/near.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/routes/search.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory/routes/short.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory.egg-info/SOURCES.txt +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory.egg-info/dependency_links.txt +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory.egg-info/entry_points.txt +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory.egg-info/requires.txt +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/seren_memory.egg-info/top_level.txt +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/setup.cfg +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/__init__.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/conftest.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_auth.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_brief.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_drafts.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_embedder.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_mcp_endpoint.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_mcp_fallback.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_mcp_mount.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_mcp_tools.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_near_listing.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_search.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_smoke.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_tls.py +0 -0
- {seren_memory-2.2.1 → seren_memory-2.2.2}/tests/test_validation.py +0 -0
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
<Content Include="seren_memory\mcp\__pycache__\tools.cpython-311.pyc" />
|
|
81
81
|
<Content Include="seren_memory\mcp\__pycache__\__init__.cpython-311.pyc" />
|
|
82
82
|
<Content Include="seren_memory\viewer\halls.html" />
|
|
83
|
+
<Content Include="seren_memory\viewer\loci.html" />
|
|
83
84
|
<Content Include="tests\__pycache__\test_smoke.cpython-311-pytest-9.0.3.pyc" />
|
|
84
85
|
<Content Include="tests\__pycache__\__init__.cpython-311.pyc" />
|
|
85
86
|
</ItemGroup>
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '2.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (2, 2,
|
|
21
|
+
__version__ = version = '2.2.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (2, 2, 2)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g12a1081ca'
|
|
@@ -250,6 +250,7 @@ def create_app(config: MemoryConfig | None = None, embedding_function=None,
|
|
|
250
250
|
"service": "SerenMemory",
|
|
251
251
|
"version": APP_VERSION,
|
|
252
252
|
"tiers": store.counts(),
|
|
253
|
+
"embedding_model": cfg.storage.embedding_model or "all-MiniLM-L6-v2 (default)",
|
|
253
254
|
"consolidator": {
|
|
254
255
|
"enabled": cfg.consolidator.enabled,
|
|
255
256
|
"mode": cfg.consolidator.mode,
|
|
@@ -51,8 +51,13 @@
|
|
|
51
51
|
height: 100%;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
html {
|
|
55
|
+
background: radial-gradient(1200px 600px at 70% -10%, #2a1d2e 0%, var(--bg) 55%) no-repeat fixed;
|
|
56
|
+
background-color: var(--bg);
|
|
57
|
+
}
|
|
58
|
+
|
|
54
59
|
body {
|
|
55
|
-
background:
|
|
60
|
+
background: transparent;
|
|
56
61
|
color: var(--ink);
|
|
57
62
|
font-family: var(--sans);
|
|
58
63
|
font-size: 14px;
|
|
@@ -438,6 +443,86 @@
|
|
|
438
443
|
color: var(--muted);
|
|
439
444
|
}
|
|
440
445
|
|
|
446
|
+
/* -- overview ----------------------------------------------------- */
|
|
447
|
+
.stat-row {
|
|
448
|
+
display: flex;
|
|
449
|
+
gap: 14px;
|
|
450
|
+
flex-wrap: wrap;
|
|
451
|
+
margin-bottom: 20px;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.stat {
|
|
455
|
+
background: var(--panel);
|
|
456
|
+
border: 1px solid var(--line);
|
|
457
|
+
border-radius: 12px;
|
|
458
|
+
padding: 16px 20px;
|
|
459
|
+
min-width: 120px;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.stat .big {
|
|
463
|
+
font-size: 28px;
|
|
464
|
+
font-weight: 700;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.stat .lbl {
|
|
468
|
+
color: var(--faint);
|
|
469
|
+
font-size: 12px;
|
|
470
|
+
font-family: var(--mono);
|
|
471
|
+
margin-top: 2px;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.stat.tier-short .big { color: var(--short); }
|
|
475
|
+
.stat.tier-near .big { color: var(--near); }
|
|
476
|
+
.stat.tier-long .big { color: var(--long); }
|
|
477
|
+
.stat.tier-brief .big { color: var(--brief); }
|
|
478
|
+
.stat.tier-draft .big { color: var(--draft); }
|
|
479
|
+
|
|
480
|
+
.overview-meta {
|
|
481
|
+
margin-top: 20px;
|
|
482
|
+
padding: 14px 16px;
|
|
483
|
+
background: var(--panel);
|
|
484
|
+
border: 1px solid var(--line);
|
|
485
|
+
border-radius: 10px;
|
|
486
|
+
font-size: 13px;
|
|
487
|
+
display: flex;
|
|
488
|
+
flex-direction: column;
|
|
489
|
+
gap: 8px;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.overview-meta .row {
|
|
493
|
+
display: flex;
|
|
494
|
+
gap: 10px;
|
|
495
|
+
align-items: baseline;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.overview-meta .k {
|
|
499
|
+
color: var(--faint);
|
|
500
|
+
font-family: var(--mono);
|
|
501
|
+
font-size: 11px;
|
|
502
|
+
min-width: 120px;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
.overview-meta .v {
|
|
506
|
+
color: var(--ink);
|
|
507
|
+
font-family: var(--mono);
|
|
508
|
+
font-size: 12px;
|
|
509
|
+
word-break: break-all;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/* embedder pill in header */
|
|
513
|
+
.embedder-pill {
|
|
514
|
+
font-family: var(--mono);
|
|
515
|
+
font-size: 11px;
|
|
516
|
+
padding: 4px 10px;
|
|
517
|
+
border-radius: 999px;
|
|
518
|
+
border: 1px solid var(--accent-dim);
|
|
519
|
+
color: var(--accent);
|
|
520
|
+
white-space: nowrap;
|
|
521
|
+
max-width: 240px;
|
|
522
|
+
overflow: hidden;
|
|
523
|
+
text-overflow: ellipsis;
|
|
524
|
+
}
|
|
525
|
+
|
|
441
526
|
/* -- auth gate ---------------------------------------------------- */
|
|
442
527
|
.locked #tabs,
|
|
443
528
|
.locked main {
|
|
@@ -689,11 +774,11 @@
|
|
|
689
774
|
<body class="locked">
|
|
690
775
|
<header>
|
|
691
776
|
<div class="brand">
|
|
692
|
-
<h1>Seren<b>Memory</b> · Halls of
|
|
693
|
-
<span class="sub" id="subtitle">
|
|
777
|
+
<h1>Seren<b>Memory</b> · Halls of Right Brain</h1>
|
|
778
|
+
<span class="sub" id="subtitle">episodic, consolidated, gated</span>
|
|
694
779
|
</div>
|
|
695
780
|
<div class="grow"></div>
|
|
696
|
-
<
|
|
781
|
+
<span class="embedder-pill" id="embedder-pill" title="embedding model"></span>
|
|
697
782
|
<button class="iconbtn" id="connectBtn" title="Connection / bearer token">🔑 connect</button>
|
|
698
783
|
<button class="iconbtn" id="refresh" title="Reload">⟳</button>
|
|
699
784
|
</header>
|
|
@@ -707,6 +792,7 @@
|
|
|
707
792
|
<div class="tab" data-tier="briefs"><span class="dot"></span>Briefs</div>
|
|
708
793
|
<div class="tab" data-tier="drafts"><span class="dot"></span>Drafts</div>
|
|
709
794
|
<div class="tab" data-tier="search"><span class="dot"></span>Search</div>
|
|
795
|
+
<div class="tab" data-tier="overview"><span class="dot"></span>Overview</div>
|
|
710
796
|
</nav>
|
|
711
797
|
|
|
712
798
|
<main>
|
|
@@ -730,6 +816,7 @@
|
|
|
730
816
|
</div>
|
|
731
817
|
|
|
732
818
|
<div class="entries" id="entries"></div>
|
|
819
|
+
<div id="overview-section" style="display:none;"></div>
|
|
733
820
|
</main>
|
|
734
821
|
|
|
735
822
|
<div class="modal-bg" id="connBg">
|
|
@@ -821,15 +908,37 @@
|
|
|
821
908
|
// ----------------------------------------------------------------------
|
|
822
909
|
// Rendering
|
|
823
910
|
// ----------------------------------------------------------------------
|
|
824
|
-
function
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
911
|
+
function renderEmbedder(model) {
|
|
912
|
+
const pill = $('embedder-pill');
|
|
913
|
+
if (!pill) return;
|
|
914
|
+
pill.textContent = model || '';
|
|
915
|
+
pill.title = model || '';
|
|
916
|
+
pill.style.display = model ? '' : 'none';
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function loadOverview(root) {
|
|
920
|
+
const tiers = root.tiers || {};
|
|
921
|
+
const stat = (label, n, cls) =>
|
|
922
|
+
`<div class="stat ${cls}"><div class="big">${n ?? '?'}</div><div class="lbl">${label}</div></div>`;
|
|
923
|
+
const statsHtml = [
|
|
924
|
+
stat('short-term', tiers.short, 'tier-short'),
|
|
925
|
+
stat('near-term', tiers.near, 'tier-near'),
|
|
926
|
+
stat('long-term', tiers.long, 'tier-long'),
|
|
927
|
+
stat('briefs', tiers.briefs ?? '?', 'tier-brief'),
|
|
928
|
+
stat('drafts', tiers.drafts ?? '?', 'tier-draft'),
|
|
929
|
+
tiers.pruned != null ? stat('pruned', tiers.pruned, '') : '',
|
|
930
|
+
].join('');
|
|
931
|
+
|
|
932
|
+
const con = root.consolidator || {};
|
|
933
|
+
const metaRows = [
|
|
934
|
+
['version', root.version || '?'],
|
|
935
|
+
['embedder', root.embedding_model || '?'],
|
|
936
|
+
['consolidator',con.enabled ? `enabled · ${con.mode || '?'} · every ${con.interval_seconds ?? '?'}s` : 'disabled'],
|
|
937
|
+
].map(([k, v]) => `<div class="row"><span class="k">${k}</span><span class="v">${escapeHtml(String(v))}</span></div>`).join('');
|
|
938
|
+
|
|
939
|
+
$('overview-section').innerHTML = `
|
|
940
|
+
<div class="stat-row">${statsHtml}</div>
|
|
941
|
+
<div class="overview-meta">${metaRows}</div>`;
|
|
833
942
|
}
|
|
834
943
|
|
|
835
944
|
function entryCard(tier, content, meta, opts = {}) {
|
|
@@ -1042,17 +1151,21 @@
|
|
|
1042
1151
|
async function switchTab(tier) {
|
|
1043
1152
|
state.tab = tier;
|
|
1044
1153
|
document.querySelectorAll('.tab').forEach(t => t.classList.toggle('active', t.dataset.tier === tier));
|
|
1045
|
-
const isSearch
|
|
1046
|
-
|
|
1047
|
-
$('
|
|
1154
|
+
const isSearch = tier === 'search';
|
|
1155
|
+
const isOverview = tier === 'overview';
|
|
1156
|
+
$('searchbar').style.display = isSearch ? 'flex' : 'none';
|
|
1157
|
+
$('list-toolbar').style.display = (isSearch || isOverview) ? 'none' : 'flex';
|
|
1158
|
+
$('entries').style.display = isOverview ? 'none' : 'flex';
|
|
1159
|
+
$('overview-section').style.display = isOverview ? 'block' : 'none';
|
|
1048
1160
|
clearError();
|
|
1049
1161
|
try {
|
|
1050
|
-
if (tier === 'short')
|
|
1051
|
-
else if (tier === 'near')
|
|
1052
|
-
else if (tier === 'long')
|
|
1053
|
-
else if (tier === 'briefs')
|
|
1054
|
-
else if (tier === 'drafts')
|
|
1055
|
-
else if (tier === 'search')
|
|
1162
|
+
if (tier === 'short') await loadShort();
|
|
1163
|
+
else if (tier === 'near') await loadNear();
|
|
1164
|
+
else if (tier === 'long') await loadLong();
|
|
1165
|
+
else if (tier === 'briefs') await loadBriefs();
|
|
1166
|
+
else if (tier === 'drafts') await loadDrafts();
|
|
1167
|
+
else if (tier === 'search') renderEntries(`<div class="empty">enter a query and hit search</div>`);
|
|
1168
|
+
else if (tier === 'overview') { const r = await api('/'); loadOverview(r); }
|
|
1056
1169
|
} catch (e) { showError(e.message); renderEntries(''); }
|
|
1057
1170
|
}
|
|
1058
1171
|
|
|
@@ -1077,15 +1190,18 @@
|
|
|
1077
1190
|
clearError();
|
|
1078
1191
|
try {
|
|
1079
1192
|
const root = await api('/');
|
|
1080
|
-
|
|
1193
|
+
renderEmbedder(root.embedding_model);
|
|
1194
|
+
$('subtitle').textContent = `v${root.version ?? '?'} · episodic, consolidated, gated`;
|
|
1081
1195
|
sessionStorage.setItem('seren_token', state.token);
|
|
1082
1196
|
unlock();
|
|
1083
1197
|
// Embedder-mismatch gate: safe-mode raises the migration modal and
|
|
1084
1198
|
// owns the screen until accepted/denied.
|
|
1085
1199
|
if (window.checkMigrationGate && await window.checkMigrationGate()) { return; }
|
|
1200
|
+
// Pre-populate overview so it's ready when the user clicks it.
|
|
1201
|
+
loadOverview(root);
|
|
1086
1202
|
} catch (e) {
|
|
1087
1203
|
showError(e.message);
|
|
1088
|
-
|
|
1204
|
+
renderEmbedder(null);
|
|
1089
1205
|
sessionStorage.removeItem('seren_token');
|
|
1090
1206
|
lock();
|
|
1091
1207
|
return;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|