@memtensor/memos-local-openclaw-plugin 0.3.11 → 0.3.13
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/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +6 -8
- package/dist/capture/index.js.map +1 -1
- package/dist/viewer/html.d.ts +1 -1
- package/dist/viewer/html.d.ts.map +1 -1
- package/dist/viewer/html.js +32 -20
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +58 -28
- package/dist/viewer/server.js.map +1 -1
- package/package.json +1 -1
- package/src/capture/index.ts +9 -12
- package/src/viewer/html.ts +32 -20
- package/src/viewer/server.ts +58 -30
package/src/viewer/html.ts
CHANGED
|
@@ -2868,17 +2868,22 @@ async function loadAll(){
|
|
|
2868
2868
|
}
|
|
2869
2869
|
|
|
2870
2870
|
async function loadStats(){
|
|
2871
|
-
|
|
2872
|
-
|
|
2871
|
+
let d;
|
|
2872
|
+
try{
|
|
2873
|
+
const r=await fetch('/api/stats');
|
|
2874
|
+
d=await r.json();
|
|
2875
|
+
}catch(e){ d={}; }
|
|
2876
|
+
if(!d||typeof d!=='object') d={};
|
|
2877
|
+
const tm=d.totalMemories||0;
|
|
2873
2878
|
const dedupB=d.dedupBreakdown||{};
|
|
2874
|
-
const activeCount=dedupB.active||
|
|
2879
|
+
const activeCount=dedupB.active||tm;
|
|
2875
2880
|
const inactiveCount=(dedupB.duplicate||0)+(dedupB.merged||0);
|
|
2876
|
-
document.getElementById('statTotal').textContent=
|
|
2881
|
+
document.getElementById('statTotal').textContent=tm;
|
|
2877
2882
|
if(inactiveCount>0){
|
|
2878
2883
|
document.getElementById('statTotal').title=activeCount+' '+t('stat.active')+', '+inactiveCount+' '+t('stat.deduped');
|
|
2879
2884
|
}
|
|
2880
|
-
document.getElementById('statSessions').textContent=d.totalSessions;
|
|
2881
|
-
document.getElementById('statEmbeddings').textContent=d.totalEmbeddings;
|
|
2885
|
+
document.getElementById('statSessions').textContent=d.totalSessions||0;
|
|
2886
|
+
document.getElementById('statEmbeddings').textContent=d.totalEmbeddings||0;
|
|
2882
2887
|
let days=0;
|
|
2883
2888
|
if(d.timeRange&&d.timeRange.earliest!=null&&d.timeRange.latest!=null){
|
|
2884
2889
|
let e=Number(d.timeRange.earliest), l=Number(d.timeRange.latest);
|
|
@@ -2900,7 +2905,7 @@ async function loadStats(){
|
|
|
2900
2905
|
}
|
|
2901
2906
|
|
|
2902
2907
|
const sl=document.getElementById('sessionList');
|
|
2903
|
-
sl.innerHTML='<div class="session-item'+(activeSession===null?' active':'')+'" onclick="filterSession(null)"><span>'+t('sidebar.allsessions')+'</span><span class="count">'+
|
|
2908
|
+
sl.innerHTML='<div class="session-item'+(activeSession===null?' active':'')+'" onclick="filterSession(null)"><span>'+t('sidebar.allsessions')+'</span><span class="count">'+tm+'</span></div>';
|
|
2904
2909
|
(d.sessions||[]).forEach(s=>{
|
|
2905
2910
|
const isActive=activeSession===s.session_key;
|
|
2906
2911
|
const name=s.session_key.length>20?s.session_key.slice(0,8)+'...'+s.session_key.slice(-8):s.session_key;
|
|
@@ -2927,16 +2932,23 @@ async function loadMemories(page){
|
|
|
2927
2932
|
if(page) currentPage=page;
|
|
2928
2933
|
const list=document.getElementById('memoryList');
|
|
2929
2934
|
list.innerHTML='<div class="spinner"></div>';
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2935
|
+
try{
|
|
2936
|
+
const p=getFilterParams();
|
|
2937
|
+
p.set('limit',PAGE_SIZE);
|
|
2938
|
+
p.set('page',currentPage);
|
|
2939
|
+
const r=await fetch('/api/memories?'+p.toString());
|
|
2940
|
+
const d=await r.json();
|
|
2941
|
+
totalPages=d.totalPages||1;
|
|
2942
|
+
totalCount=d.total||0;
|
|
2943
|
+
document.getElementById('searchMeta').textContent=totalCount+t('search.meta.total');
|
|
2944
|
+
renderMemories(d.memories||[]);
|
|
2945
|
+
renderPagination();
|
|
2946
|
+
}catch(e){
|
|
2947
|
+
list.innerHTML='';
|
|
2948
|
+
totalPages=1;totalCount=0;
|
|
2949
|
+
renderMemories([]);
|
|
2950
|
+
renderPagination();
|
|
2951
|
+
}
|
|
2940
2952
|
}
|
|
2941
2953
|
|
|
2942
2954
|
async function doSearch(q){
|
|
@@ -3261,11 +3273,11 @@ async function migrateScan(){
|
|
|
3261
3273
|
|
|
3262
3274
|
try{
|
|
3263
3275
|
const r=await fetch('/api/migrate/scan');
|
|
3264
|
-
|
|
3265
|
-
|
|
3276
|
+
const d=await r.json().catch(()=>({}));
|
|
3277
|
+
if(d.error && !d.sqliteFiles) throw new Error(d.error);
|
|
3266
3278
|
migrateScanData=d;
|
|
3267
3279
|
|
|
3268
|
-
const files=d.sqliteFiles
|
|
3280
|
+
const files=Array.isArray(d.sqliteFiles)?d.sqliteFiles:[];
|
|
3269
3281
|
const sess=d.sessions||{count:0,messages:0};
|
|
3270
3282
|
const sqliteTotal=files.reduce((s,f)=>s+f.chunks,0);
|
|
3271
3283
|
document.getElementById('migrateSqliteCount').textContent=sqliteTotal;
|
package/src/viewer/server.ts
CHANGED
|
@@ -447,36 +447,55 @@ export class ViewerServer {
|
|
|
447
447
|
}
|
|
448
448
|
|
|
449
449
|
private serveStats(res: http.ServerResponse): void {
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
let dedupBreakdown: Record<string, number> = {};
|
|
450
|
+
const emptyStats = {
|
|
451
|
+
totalMemories: 0, totalSessions: 0, totalEmbeddings: 0, totalSkills: 0,
|
|
452
|
+
embeddingProvider: this.embedder?.provider ?? "none",
|
|
453
|
+
roleBreakdown: {}, kindBreakdown: {}, dedupBreakdown: {},
|
|
454
|
+
timeRange: { earliest: null, latest: null },
|
|
455
|
+
sessions: [],
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
if (!this.store || !(this.store as any).db) {
|
|
459
|
+
this.jsonResponse(res, emptyStats);
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
|
|
465
463
|
try {
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
|
|
464
|
+
const db = (this.store as any).db;
|
|
465
|
+
const total = db.prepare("SELECT COUNT(*) as count FROM chunks").get() as any;
|
|
466
|
+
const sessions = db.prepare("SELECT COUNT(DISTINCT session_key) as count FROM chunks").get() as any;
|
|
467
|
+
const roles = db.prepare("SELECT role, COUNT(*) as count FROM chunks GROUP BY role").all() as any[];
|
|
468
|
+
const timeRange = db.prepare("SELECT MIN(created_at) as earliest, MAX(created_at) as latest FROM chunks").get() as any;
|
|
469
|
+
let embCount = 0;
|
|
470
|
+
try { embCount = (db.prepare("SELECT COUNT(*) as count FROM embeddings").get() as any).count; } catch { /* table may not exist */ }
|
|
471
|
+
const kinds = db.prepare("SELECT kind, COUNT(*) as count FROM chunks GROUP BY kind").all() as any[];
|
|
472
|
+
const sessionList = db.prepare(
|
|
473
|
+
"SELECT session_key, COUNT(*) as count, MIN(created_at) as earliest, MAX(created_at) as latest FROM chunks GROUP BY session_key ORDER BY latest DESC",
|
|
474
|
+
).all() as any[];
|
|
475
|
+
|
|
476
|
+
let skillCount = 0;
|
|
477
|
+
try { skillCount = (db.prepare("SELECT COUNT(*) as count FROM skills").get() as any).count; } catch { /* table may not exist yet */ }
|
|
478
|
+
|
|
479
|
+
let dedupBreakdown: Record<string, number> = {};
|
|
480
|
+
try {
|
|
481
|
+
const dedupRows = db.prepare("SELECT dedup_status, COUNT(*) as count FROM chunks GROUP BY dedup_status").all() as any[];
|
|
482
|
+
dedupBreakdown = Object.fromEntries(dedupRows.map((d: any) => [d.dedup_status ?? "active", d.count]));
|
|
483
|
+
} catch { /* column may not exist yet */ }
|
|
469
484
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
485
|
+
this.jsonResponse(res, {
|
|
486
|
+
totalMemories: total.count, totalSessions: sessions.count, totalEmbeddings: embCount,
|
|
487
|
+
totalSkills: skillCount,
|
|
488
|
+
embeddingProvider: this.embedder.provider,
|
|
489
|
+
roleBreakdown: Object.fromEntries(roles.map((r: any) => [r.role, r.count])),
|
|
490
|
+
kindBreakdown: Object.fromEntries(kinds.map((k: any) => [k.kind, k.count])),
|
|
491
|
+
dedupBreakdown,
|
|
492
|
+
timeRange: { earliest: timeRange.earliest, latest: timeRange.latest },
|
|
493
|
+
sessions: sessionList,
|
|
494
|
+
});
|
|
495
|
+
} catch (e) {
|
|
496
|
+
this.log.warn(`stats error: ${e}`);
|
|
497
|
+
this.jsonResponse(res, emptyStats);
|
|
498
|
+
}
|
|
480
499
|
}
|
|
481
500
|
|
|
482
501
|
private async serveSearch(_req: http.IncomingMessage, res: http.ServerResponse, url: URL): Promise<void> {
|
|
@@ -943,8 +962,17 @@ export class ViewerServer {
|
|
|
943
962
|
});
|
|
944
963
|
} catch (e) {
|
|
945
964
|
this.log.warn(`migrate/scan error: ${e}`);
|
|
946
|
-
|
|
947
|
-
|
|
965
|
+
this.jsonResponse(res, {
|
|
966
|
+
sqliteFiles: [],
|
|
967
|
+
sessions: { count: 0, messages: 0 },
|
|
968
|
+
totalItems: 0,
|
|
969
|
+
configReady: false,
|
|
970
|
+
hasEmbedding: false,
|
|
971
|
+
hasSummarizer: false,
|
|
972
|
+
hasImportedData: false,
|
|
973
|
+
importedSessionCount: 0,
|
|
974
|
+
error: String(e),
|
|
975
|
+
});
|
|
948
976
|
}
|
|
949
977
|
}
|
|
950
978
|
|