@memtensor/memos-local-openclaw-plugin 1.0.2-beta.2 → 1.0.2-beta.4
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 +41 -1
- package/dist/capture/index.js.map +1 -1
- package/dist/embedding/index.d.ts.map +1 -1
- package/dist/embedding/index.js +20 -7
- package/dist/embedding/index.js.map +1 -1
- package/dist/ingest/providers/anthropic.d.ts.map +1 -1
- package/dist/ingest/providers/anthropic.js +28 -13
- package/dist/ingest/providers/anthropic.js.map +1 -1
- package/dist/ingest/providers/bedrock.d.ts.map +1 -1
- package/dist/ingest/providers/bedrock.js +28 -13
- package/dist/ingest/providers/bedrock.js.map +1 -1
- package/dist/ingest/providers/gemini.d.ts.map +1 -1
- package/dist/ingest/providers/gemini.js +28 -13
- package/dist/ingest/providers/gemini.js.map +1 -1
- package/dist/ingest/providers/index.d.ts +19 -0
- package/dist/ingest/providers/index.d.ts.map +1 -1
- package/dist/ingest/providers/index.js +98 -10
- package/dist/ingest/providers/index.js.map +1 -1
- package/dist/ingest/providers/openai.d.ts.map +1 -1
- package/dist/ingest/providers/openai.js +28 -13
- package/dist/ingest/providers/openai.js.map +1 -1
- package/dist/ingest/worker.d.ts.map +1 -1
- package/dist/ingest/worker.js +8 -14
- package/dist/ingest/worker.js.map +1 -1
- package/dist/storage/sqlite.d.ts +14 -0
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +42 -0
- package/dist/storage/sqlite.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 +113 -0
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts +3 -0
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +104 -21
- package/dist/viewer/server.js.map +1 -1
- package/index.ts +38 -85
- package/package.json +1 -1
- package/scripts/postinstall.cjs +16 -3
- package/src/capture/index.ts +56 -1
- package/src/embedding/index.ts +13 -7
- package/src/ingest/providers/anthropic.ts +28 -13
- package/src/ingest/providers/bedrock.ts +28 -13
- package/src/ingest/providers/gemini.ts +28 -13
- package/src/ingest/providers/index.ts +112 -9
- package/src/ingest/providers/openai.ts +28 -13
- package/src/ingest/worker.ts +8 -15
- package/src/storage/sqlite.ts +49 -0
- package/src/viewer/html.ts +113 -0
- package/src/viewer/server.ts +101 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,w1yQAkxIf,CAAC"}
|
package/dist/viewer/html.js
CHANGED
|
@@ -529,6 +529,28 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
529
529
|
[data-theme="light"] .settings-actions .btn-primary:hover{background:rgba(79,70,229,.1);border-color:#4f46e5}
|
|
530
530
|
.settings-saved{display:inline-flex;align-items:center;gap:6px;color:var(--green);font-size:12px;font-weight:600;opacity:0;transition:opacity .3s}
|
|
531
531
|
.settings-saved.show{opacity:1}
|
|
532
|
+
.model-health-bar{margin-bottom:20px;border-radius:var(--radius-lg);overflow:hidden}
|
|
533
|
+
.mh-table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}
|
|
534
|
+
.mh-table th{text-align:left;padding:6px 12px;font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em;background:var(--bg);border-bottom:1px solid var(--border)}
|
|
535
|
+
.mh-table td{padding:8px 12px;border-bottom:1px solid var(--border);vertical-align:middle}
|
|
536
|
+
.mh-table tr:last-child td{border-bottom:none}
|
|
537
|
+
.mh-table tr:hover td{background:rgba(99,102,241,.025)}
|
|
538
|
+
.mh-table .mh-cell-name{display:flex;align-items:center;gap:8px;font-weight:500;color:var(--text)}
|
|
539
|
+
.mh-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}
|
|
540
|
+
.mh-dot.ok{background:#22c55e;box-shadow:0 0 0 2px rgba(34,197,94,.15)}
|
|
541
|
+
.mh-dot.degraded{background:#f59e0b;box-shadow:0 0 0 2px rgba(245,158,11,.15)}
|
|
542
|
+
.mh-dot.error{background:#ef4444;box-shadow:0 0 0 2px rgba(239,68,68,.15);animation:healthPulse 2s ease infinite}
|
|
543
|
+
.mh-dot.unknown{background:#94a3b8;box-shadow:0 0 0 2px rgba(148,163,184,.15)}
|
|
544
|
+
.mh-badge{display:inline-block;padding:2px 7px;border-radius:10px;font-size:10px;font-weight:600;letter-spacing:.02em}
|
|
545
|
+
.mh-badge.ok{background:rgba(34,197,94,.1);color:#16a34a}
|
|
546
|
+
.mh-badge.degraded{background:rgba(245,158,11,.1);color:#d97706}
|
|
547
|
+
.mh-badge.error{background:rgba(239,68,68,.1);color:#dc2626}
|
|
548
|
+
.mh-badge.unknown{background:rgba(148,163,184,.1);color:#64748b}
|
|
549
|
+
.mh-model-name{color:var(--text-muted);font-size:11px;font-family:var(--font-mono,'SFMono-Regular',Consolas,monospace)}
|
|
550
|
+
.mh-err-text{font-size:11px;color:var(--rose);max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:help}
|
|
551
|
+
.mh-time{font-size:10px;color:var(--text-muted);white-space:nowrap}
|
|
552
|
+
.mh-empty{padding:16px;font-size:12px;color:var(--text-muted);text-align:center}
|
|
553
|
+
@keyframes healthPulse{0%,100%{opacity:1}50%{opacity:.4}}
|
|
532
554
|
.migrate-log-item{display:flex;align-items:flex-start;gap:10px;padding:8px 14px;border-bottom:1px solid var(--border);animation:migrateFadeIn .3s ease}
|
|
533
555
|
.migrate-log-item:last-child{border-bottom:none}
|
|
534
556
|
.migrate-log-item .log-icon{flex-shrink:0;width:18px;height:18px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:10px;margin-top:2px}
|
|
@@ -943,6 +965,9 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
943
965
|
<div class="settings-view" id="settingsView">
|
|
944
966
|
<div class="settings-group" id="settingsModelConfig">
|
|
945
967
|
<h2 class="settings-group-title"><span data-i18n="settings.modelconfig">Model Configuration</span></h2>
|
|
968
|
+
<div class="model-health-bar" id="modelHealthBar">
|
|
969
|
+
<div style="font-size:12px;color:var(--text-muted);width:100%">Loading model status...</div>
|
|
970
|
+
</div>
|
|
946
971
|
<div class="settings-section">
|
|
947
972
|
<h3><span class="icon">\u{1F4E1}</span> <span data-i18n="settings.embedding">Embedding Model</span></h3>
|
|
948
973
|
<div class="settings-grid">
|
|
@@ -2068,6 +2093,7 @@ function switchView(view){
|
|
|
2068
2093
|
} else if(view==='settings'){
|
|
2069
2094
|
settingsView.classList.add('show');
|
|
2070
2095
|
loadConfig();
|
|
2096
|
+
loadModelHealth();
|
|
2071
2097
|
} else if(view==='import'){
|
|
2072
2098
|
migrateView.classList.add('show');
|
|
2073
2099
|
if(!window._migrateRunning) migrateScan();
|
|
@@ -2749,6 +2775,93 @@ async function toggleSkillPublic(id,setPublic){
|
|
|
2749
2775
|
}
|
|
2750
2776
|
}
|
|
2751
2777
|
|
|
2778
|
+
/* ─── Model Health Status ─── */
|
|
2779
|
+
|
|
2780
|
+
const HEALTH_ROLE_LABELS={
|
|
2781
|
+
'embedding':'Embedding',
|
|
2782
|
+
'summarize':'Summarizer',
|
|
2783
|
+
'filterRelevant':'Memory Filter',
|
|
2784
|
+
'judgeDedup':'Dedup Judge',
|
|
2785
|
+
'summarizeTask':'Task Summarizer',
|
|
2786
|
+
'judgeNewTopic':'Topic Judge'
|
|
2787
|
+
};
|
|
2788
|
+
|
|
2789
|
+
function classifyError(msg){
|
|
2790
|
+
if(!msg) return '';
|
|
2791
|
+
if(msg.indexOf('\u989D\u5EA6\u5DF2\u7528\u5C3D')>=0||msg.indexOf('quota')>=0||msg.indexOf('RemainQuota')>=0) return 'API quota exhausted';
|
|
2792
|
+
if(msg.indexOf('401')>=0||msg.indexOf('Unauthorized')>=0) return 'Auth failed (401)';
|
|
2793
|
+
if(msg.indexOf('timeout')>=0||msg.indexOf('Timeout')>=0) return 'Request timed out';
|
|
2794
|
+
if(msg.indexOf('429')>=0) return 'Rate limited (429)';
|
|
2795
|
+
if(msg.indexOf('ECONNREFUSED')>=0) return 'Connection refused';
|
|
2796
|
+
if(msg.indexOf('ENOTFOUND')>=0) return 'DNS resolution failed';
|
|
2797
|
+
if(msg.indexOf('403')>=0) return 'Forbidden (403)';
|
|
2798
|
+
return msg.length>50?msg.slice(0,47)+'...':msg;
|
|
2799
|
+
}
|
|
2800
|
+
|
|
2801
|
+
function shortenModel(s){return s?s.replace('openai_compatible/','').replace('openai/',''):'\u2014';}
|
|
2802
|
+
|
|
2803
|
+
async function loadModelHealth(){
|
|
2804
|
+
var bar=document.getElementById('modelHealthBar');
|
|
2805
|
+
if(!bar) return;
|
|
2806
|
+
try{
|
|
2807
|
+
var r=await fetch('/api/model-health');
|
|
2808
|
+
if(!r.ok){bar.innerHTML='<div class="mh-empty">Health data unavailable</div>';return;}
|
|
2809
|
+
var d=await r.json();
|
|
2810
|
+
var models=d.models||[];
|
|
2811
|
+
if(models.length===0){
|
|
2812
|
+
bar.innerHTML='<div class="mh-empty">No model calls recorded yet</div>';
|
|
2813
|
+
return;
|
|
2814
|
+
}
|
|
2815
|
+
var order=['embedding','summarize','filterRelevant','judgeDedup','summarizeTask','judgeNewTopic'];
|
|
2816
|
+
models.sort(function(a,b){var ai=order.indexOf(a.role),bi=order.indexOf(b.role);if(ai<0)ai=99;if(bi<0)bi=99;return ai-bi;});
|
|
2817
|
+
|
|
2818
|
+
var h='<table class="mh-table"><thead><tr>';
|
|
2819
|
+
h+='<th style="width:30px"></th><th>Role</th><th>Status</th><th>Model</th><th>Issue</th><th style="text-align:right">Updated</th>';
|
|
2820
|
+
h+='</tr></thead><tbody>';
|
|
2821
|
+
|
|
2822
|
+
for(var i=0;i<models.length;i++){
|
|
2823
|
+
var m=models[i];
|
|
2824
|
+
var st=m.status||'unknown';
|
|
2825
|
+
var label=HEALTH_ROLE_LABELS[m.role]||m.role;
|
|
2826
|
+
var badgeText=st==='ok'?'OK':st==='degraded'?'Degraded':st==='error'?'Error':'\u2014';
|
|
2827
|
+
var ago='';
|
|
2828
|
+
if(st==='ok'&&m.lastSuccess) ago=timeAgo(m.lastSuccess);
|
|
2829
|
+
else if(m.lastError) ago=timeAgo(m.lastError);
|
|
2830
|
+
|
|
2831
|
+
h+='<tr>';
|
|
2832
|
+
h+='<td><span class="mh-dot '+st+'"></span></td>';
|
|
2833
|
+
h+='<td><span style="font-weight:500">'+escapeHtml(label)+'</span></td>';
|
|
2834
|
+
h+='<td><span class="mh-badge '+st+'">'+badgeText+'</span></td>';
|
|
2835
|
+
h+='<td><span class="mh-model-name">'+escapeHtml(shortenModel(m.model))+'</span></td>';
|
|
2836
|
+
|
|
2837
|
+
var issue='';
|
|
2838
|
+
if((st==='error'||st==='degraded')&&m.lastErrorMessage){
|
|
2839
|
+
var shortErr=classifyError(m.lastErrorMessage);
|
|
2840
|
+
if(m.failedModel&&m.failedModel!==m.model) issue=shortenModel(m.failedModel)+': ';
|
|
2841
|
+
issue+=shortErr;
|
|
2842
|
+
if(m.consecutiveErrors>1) issue+=' ('+m.consecutiveErrors+'x)';
|
|
2843
|
+
}
|
|
2844
|
+
if(issue) h+='<td><span class="mh-err-text" title="'+escapeHtml(m.lastErrorMessage||'')+'">'+escapeHtml(issue)+'</span></td>';
|
|
2845
|
+
else h+='<td><span style="color:var(--text-muted);font-size:11px">\u2014</span></td>';
|
|
2846
|
+
|
|
2847
|
+
h+='<td style="text-align:right"><span class="mh-time">'+(ago||'\u2014')+'</span></td>';
|
|
2848
|
+
h+='</tr>';
|
|
2849
|
+
}
|
|
2850
|
+
h+='</tbody></table>';
|
|
2851
|
+
bar.innerHTML=h;
|
|
2852
|
+
}catch(e){
|
|
2853
|
+
bar.innerHTML='<div class="mh-empty">Failed to load model health</div>';
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
function timeAgo(ts){
|
|
2858
|
+
var diff=Date.now()-ts;
|
|
2859
|
+
if(diff<60000) return 'just now';
|
|
2860
|
+
if(diff<3600000) return Math.floor(diff/60000)+'m ago';
|
|
2861
|
+
if(diff<86400000) return Math.floor(diff/3600000)+'h ago';
|
|
2862
|
+
return Math.floor(diff/86400000)+'d ago';
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2752
2865
|
/* ─── Settings / Config ─── */
|
|
2753
2866
|
async function loadConfig(){
|
|
2754
2867
|
try{
|
package/dist/viewer/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,UAAU,GAAG
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkxIlB,CAAC"}
|
package/dist/viewer/server.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare class ViewerServer {
|
|
|
31
31
|
private ppSSEClients;
|
|
32
32
|
constructor(opts: ViewerServerOptions);
|
|
33
33
|
start(): Promise<string>;
|
|
34
|
+
private autoCleanupPolluted;
|
|
34
35
|
stop(): void;
|
|
35
36
|
getResetToken(): string;
|
|
36
37
|
private loadAuth;
|
|
@@ -73,6 +74,7 @@ export declare class ViewerServer {
|
|
|
73
74
|
private serveConfig;
|
|
74
75
|
private handleSaveConfig;
|
|
75
76
|
private handleTestModel;
|
|
77
|
+
private serveModelHealth;
|
|
76
78
|
private serveFallbackModel;
|
|
77
79
|
private findPluginPackageJson;
|
|
78
80
|
private handleUpdateCheck;
|
|
@@ -81,6 +83,7 @@ export declare class ViewerServer {
|
|
|
81
83
|
private serveLogs;
|
|
82
84
|
private serveLogTools;
|
|
83
85
|
private getOpenClawHome;
|
|
86
|
+
private handleCleanupPolluted;
|
|
84
87
|
private handleMigrateScan;
|
|
85
88
|
private broadcastSSE;
|
|
86
89
|
private handleMigrateStatus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/viewer/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAQ7C,OAAO,KAAK,EAAE,MAAM,EAAS,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/viewer/server.ts"],"names":[],"mappings":"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"}
|
package/dist/viewer/server.js
CHANGED
|
@@ -19,6 +19,11 @@ const engine_1 = require("../recall/engine");
|
|
|
19
19
|
const evolver_1 = require("../skill/evolver");
|
|
20
20
|
const html_1 = require("./html");
|
|
21
21
|
const uuid_1 = require("uuid");
|
|
22
|
+
function normalizeTimestamp(ts) {
|
|
23
|
+
if (ts < 1e12)
|
|
24
|
+
return ts * 1000;
|
|
25
|
+
return ts;
|
|
26
|
+
}
|
|
22
27
|
class ViewerServer {
|
|
23
28
|
server = null;
|
|
24
29
|
store;
|
|
@@ -66,10 +71,28 @@ class ViewerServer {
|
|
|
66
71
|
this.server.listen(this.port, "127.0.0.1", () => {
|
|
67
72
|
const addr = this.server.address();
|
|
68
73
|
const actualPort = typeof addr === "object" && addr ? addr.port : this.port;
|
|
74
|
+
this.autoCleanupPolluted();
|
|
69
75
|
resolve(`http://127.0.0.1:${actualPort}`);
|
|
70
76
|
});
|
|
71
77
|
});
|
|
72
78
|
}
|
|
79
|
+
autoCleanupPolluted() {
|
|
80
|
+
try {
|
|
81
|
+
const polluted = this.store.findPollutedUserChunks();
|
|
82
|
+
let deleted = 0;
|
|
83
|
+
for (const { id } of polluted) {
|
|
84
|
+
if (this.store.deleteChunk(id))
|
|
85
|
+
deleted++;
|
|
86
|
+
}
|
|
87
|
+
const fixed = this.store.fixMixedUserChunks();
|
|
88
|
+
if (deleted > 0 || fixed > 0) {
|
|
89
|
+
this.log.info(`Auto-cleanup: removed ${deleted} polluted chunks, fixed ${fixed} mixed user+assistant chunks`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
this.log.warn(`Auto-cleanup failed: ${err}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
73
96
|
stop() {
|
|
74
97
|
this.server?.close();
|
|
75
98
|
this.server = null;
|
|
@@ -212,12 +235,16 @@ class ViewerServer {
|
|
|
212
235
|
this.handleSaveConfig(req, res);
|
|
213
236
|
else if (p === "/api/test-model" && req.method === "POST")
|
|
214
237
|
this.handleTestModel(req, res);
|
|
238
|
+
else if (p === "/api/model-health" && req.method === "GET")
|
|
239
|
+
this.serveModelHealth(res);
|
|
215
240
|
else if (p === "/api/fallback-model" && req.method === "GET")
|
|
216
241
|
this.serveFallbackModel(res);
|
|
217
242
|
else if (p === "/api/update-check" && req.method === "GET")
|
|
218
243
|
this.handleUpdateCheck(res);
|
|
219
244
|
else if (p === "/api/auth/logout" && req.method === "POST")
|
|
220
245
|
this.handleLogout(req, res);
|
|
246
|
+
else if (p === "/api/cleanup-polluted" && req.method === "POST")
|
|
247
|
+
this.handleCleanupPolluted(res);
|
|
221
248
|
else if (p === "/api/migrate/scan" && req.method === "GET")
|
|
222
249
|
this.handleMigrateScan(res);
|
|
223
250
|
else if (p === "/api/migrate/start" && req.method === "POST")
|
|
@@ -491,7 +518,15 @@ class ViewerServer {
|
|
|
491
518
|
const total = db.prepare("SELECT COUNT(*) as count FROM chunks").get();
|
|
492
519
|
const sessions = db.prepare("SELECT COUNT(DISTINCT session_key) as count FROM chunks").get();
|
|
493
520
|
const roles = db.prepare("SELECT role, COUNT(*) as count FROM chunks GROUP BY role").all();
|
|
494
|
-
const timeRange = db.prepare("SELECT MIN(created_at) as earliest, MAX(created_at) as latest FROM chunks").get();
|
|
521
|
+
const timeRange = db.prepare("SELECT MIN(created_at) as earliest, MAX(created_at) as latest FROM chunks WHERE dedup_status = 'active'").get();
|
|
522
|
+
const MIN_VALID_TS = 1704067200000; // 2024-01-01
|
|
523
|
+
if (timeRange.earliest != null && timeRange.earliest < MIN_VALID_TS) {
|
|
524
|
+
timeRange.earliest = db.prepare("SELECT MIN(created_at) as v FROM chunks WHERE dedup_status = 'active' AND created_at >= ?").get(MIN_VALID_TS);
|
|
525
|
+
timeRange.earliest = timeRange.earliest?.v ?? null;
|
|
526
|
+
}
|
|
527
|
+
if (timeRange.latest != null && timeRange.latest < MIN_VALID_TS) {
|
|
528
|
+
timeRange.latest = null;
|
|
529
|
+
}
|
|
495
530
|
let embCount = 0;
|
|
496
531
|
try {
|
|
497
532
|
embCount = db.prepare("SELECT COUNT(*) as count FROM embeddings").get().count;
|
|
@@ -1003,11 +1038,13 @@ class ViewerServer {
|
|
|
1003
1038
|
const raw = JSON.parse(node_fs_1.default.readFileSync(cfgPath, "utf-8"));
|
|
1004
1039
|
const entries = raw?.plugins?.entries ?? {};
|
|
1005
1040
|
const pluginEntry = entries["memos-local-openclaw-plugin"]?.config
|
|
1041
|
+
?? entries["memos-local"]?.config
|
|
1006
1042
|
?? entries["memos-lite-openclaw-plugin"]?.config
|
|
1007
1043
|
?? entries["memos-lite"]?.config
|
|
1008
1044
|
?? {};
|
|
1009
1045
|
const result = { ...pluginEntry };
|
|
1010
1046
|
const topEntry = entries["memos-local-openclaw-plugin"]
|
|
1047
|
+
?? entries["memos-local"]
|
|
1011
1048
|
?? entries["memos-lite-openclaw-plugin"]
|
|
1012
1049
|
?? entries["memos-lite"]
|
|
1013
1050
|
?? {};
|
|
@@ -1037,9 +1074,10 @@ class ViewerServer {
|
|
|
1037
1074
|
plugins.entries = {};
|
|
1038
1075
|
const entries = plugins.entries;
|
|
1039
1076
|
const entryKey = entries["memos-local-openclaw-plugin"] ? "memos-local-openclaw-plugin"
|
|
1040
|
-
: entries["memos-
|
|
1041
|
-
: entries["memos-lite"] ? "memos-lite"
|
|
1042
|
-
: "memos-
|
|
1077
|
+
: entries["memos-local"] ? "memos-local"
|
|
1078
|
+
: entries["memos-lite-openclaw-plugin"] ? "memos-lite-openclaw-plugin"
|
|
1079
|
+
: entries["memos-lite"] ? "memos-lite"
|
|
1080
|
+
: "memos-local-openclaw-plugin";
|
|
1043
1081
|
if (!entries[entryKey])
|
|
1044
1082
|
entries[entryKey] = { enabled: true };
|
|
1045
1083
|
const entry = entries[entryKey];
|
|
@@ -1077,8 +1115,8 @@ class ViewerServer {
|
|
|
1077
1115
|
return;
|
|
1078
1116
|
}
|
|
1079
1117
|
if (type === "embedding") {
|
|
1080
|
-
await this.testEmbeddingModel(provider, model, endpoint, apiKey);
|
|
1081
|
-
this.jsonResponse(res, { ok: true, detail: `${provider}/${model}
|
|
1118
|
+
const dims = await this.testEmbeddingModel(provider, model, endpoint, apiKey);
|
|
1119
|
+
this.jsonResponse(res, { ok: true, detail: `${provider}/${model}`, dimensions: dims });
|
|
1082
1120
|
}
|
|
1083
1121
|
else {
|
|
1084
1122
|
await this.testChatModel(provider, model, endpoint, apiKey);
|
|
@@ -1092,6 +1130,9 @@ class ViewerServer {
|
|
|
1092
1130
|
}
|
|
1093
1131
|
});
|
|
1094
1132
|
}
|
|
1133
|
+
serveModelHealth(res) {
|
|
1134
|
+
this.jsonResponse(res, { models: providers_1.modelHealth.getAll() });
|
|
1135
|
+
}
|
|
1095
1136
|
serveFallbackModel(res) {
|
|
1096
1137
|
try {
|
|
1097
1138
|
const cfgPath = this.getOpenClawConfigPath();
|
|
@@ -1174,7 +1215,7 @@ class ViewerServer {
|
|
|
1174
1215
|
}
|
|
1175
1216
|
async testEmbeddingModel(provider, model, endpoint, apiKey) {
|
|
1176
1217
|
if (provider === "local") {
|
|
1177
|
-
return;
|
|
1218
|
+
return 384;
|
|
1178
1219
|
}
|
|
1179
1220
|
const baseUrl = (endpoint || "https://api.openai.com/v1").replace(/\/+$/, "");
|
|
1180
1221
|
const embUrl = baseUrl.endsWith("/embeddings") ? baseUrl : `${baseUrl}/embeddings`;
|
|
@@ -1187,39 +1228,59 @@ class ViewerServer {
|
|
|
1187
1228
|
const resp = await fetch(baseUrl.replace(/\/v\d+.*/, "/v2/embed"), {
|
|
1188
1229
|
method: "POST",
|
|
1189
1230
|
headers,
|
|
1190
|
-
body: JSON.stringify({ texts: ["test"], model: model || "embed-english-v3.0", input_type: "search_query", embedding_types: ["float"] }),
|
|
1231
|
+
body: JSON.stringify({ texts: ["test embedding vector"], model: model || "embed-english-v3.0", input_type: "search_query", embedding_types: ["float"] }),
|
|
1191
1232
|
signal: AbortSignal.timeout(15_000),
|
|
1192
1233
|
});
|
|
1193
1234
|
if (!resp.ok) {
|
|
1194
1235
|
const txt = await resp.text();
|
|
1195
1236
|
throw new Error(`Cohere embed ${resp.status}: ${txt}`);
|
|
1196
1237
|
}
|
|
1197
|
-
|
|
1238
|
+
const json = await resp.json();
|
|
1239
|
+
const vecs = json?.embeddings?.float;
|
|
1240
|
+
if (!Array.isArray(vecs) || vecs.length === 0 || !Array.isArray(vecs[0]) || vecs[0].length === 0) {
|
|
1241
|
+
throw new Error("Cohere returned empty embedding vector");
|
|
1242
|
+
}
|
|
1243
|
+
return vecs[0].length;
|
|
1198
1244
|
}
|
|
1199
1245
|
if (provider === "gemini") {
|
|
1200
1246
|
const url = `https://generativelanguage.googleapis.com/v1/models/${model || "text-embedding-004"}:embedContent?key=${apiKey}`;
|
|
1201
1247
|
const resp = await fetch(url, {
|
|
1202
1248
|
method: "POST",
|
|
1203
1249
|
headers: { "Content-Type": "application/json" },
|
|
1204
|
-
body: JSON.stringify({ content: { parts: [{ text: "test" }] } }),
|
|
1250
|
+
body: JSON.stringify({ content: { parts: [{ text: "test embedding vector" }] } }),
|
|
1205
1251
|
signal: AbortSignal.timeout(15_000),
|
|
1206
1252
|
});
|
|
1207
1253
|
if (!resp.ok) {
|
|
1208
1254
|
const txt = await resp.text();
|
|
1209
1255
|
throw new Error(`Gemini embed ${resp.status}: ${txt}`);
|
|
1210
1256
|
}
|
|
1211
|
-
|
|
1257
|
+
const json = await resp.json();
|
|
1258
|
+
const vec = json?.embedding?.values;
|
|
1259
|
+
if (!Array.isArray(vec) || vec.length === 0) {
|
|
1260
|
+
throw new Error("Gemini returned empty embedding vector");
|
|
1261
|
+
}
|
|
1262
|
+
return vec.length;
|
|
1212
1263
|
}
|
|
1213
1264
|
const resp = await fetch(embUrl, {
|
|
1214
1265
|
method: "POST",
|
|
1215
1266
|
headers,
|
|
1216
|
-
body: JSON.stringify({ input: ["test"], model: model || "text-embedding-3-small" }),
|
|
1267
|
+
body: JSON.stringify({ input: ["test embedding vector"], model: model || "text-embedding-3-small" }),
|
|
1217
1268
|
signal: AbortSignal.timeout(15_000),
|
|
1218
1269
|
});
|
|
1219
1270
|
if (!resp.ok) {
|
|
1220
1271
|
const txt = await resp.text();
|
|
1221
1272
|
throw new Error(`${resp.status}: ${txt}`);
|
|
1222
1273
|
}
|
|
1274
|
+
const json = await resp.json();
|
|
1275
|
+
const data = json?.data;
|
|
1276
|
+
if (!Array.isArray(data) || data.length === 0) {
|
|
1277
|
+
throw new Error("API returned no embedding data");
|
|
1278
|
+
}
|
|
1279
|
+
const vec = data[0]?.embedding;
|
|
1280
|
+
if (!Array.isArray(vec) || vec.length === 0) {
|
|
1281
|
+
throw new Error(`API returned empty embedding vector (got ${JSON.stringify(vec)?.slice(0, 100)})`);
|
|
1282
|
+
}
|
|
1283
|
+
return vec.length;
|
|
1223
1284
|
}
|
|
1224
1285
|
async testChatModel(provider, model, endpoint, apiKey) {
|
|
1225
1286
|
const baseUrl = (endpoint || "https://api.openai.com/v1").replace(/\/+$/, "");
|
|
@@ -1288,6 +1349,28 @@ class ViewerServer {
|
|
|
1288
1349
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
1289
1350
|
return node_path_1.default.join(home, ".openclaw");
|
|
1290
1351
|
}
|
|
1352
|
+
handleCleanupPolluted(res) {
|
|
1353
|
+
try {
|
|
1354
|
+
const polluted = this.store.findPollutedUserChunks();
|
|
1355
|
+
let deleted = 0;
|
|
1356
|
+
for (const { id, reason } of polluted) {
|
|
1357
|
+
if (this.store.deleteChunk(id)) {
|
|
1358
|
+
deleted++;
|
|
1359
|
+
this.log.info(`Cleaned polluted chunk ${id}: ${reason}`);
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
const fixed = this.store.fixMixedUserChunks();
|
|
1363
|
+
this.log.info(`Cleanup: removed ${deleted} polluted, fixed ${fixed} mixed chunks`);
|
|
1364
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1365
|
+
res.end(JSON.stringify({ deleted, fixed, total: polluted.length }));
|
|
1366
|
+
}
|
|
1367
|
+
catch (err) {
|
|
1368
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1369
|
+
this.log.error(`handleCleanupPolluted error: ${msg}`);
|
|
1370
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
1371
|
+
res.end(JSON.stringify({ error: msg }));
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1291
1374
|
handleMigrateScan(res) {
|
|
1292
1375
|
try {
|
|
1293
1376
|
const ocHome = this.getOpenClawHome();
|
|
@@ -1351,8 +1434,9 @@ class ViewerServer {
|
|
|
1351
1434
|
try {
|
|
1352
1435
|
const raw = JSON.parse(node_fs_1.default.readFileSync(cfgPath, "utf-8"));
|
|
1353
1436
|
const pluginCfg = raw?.plugins?.entries?.["memos-local-openclaw-plugin"]?.config ??
|
|
1354
|
-
raw?.plugins?.entries?.["memos-
|
|
1355
|
-
raw?.plugins?.entries?.["memos-lite-openclaw-plugin"]?.config ??
|
|
1437
|
+
raw?.plugins?.entries?.["memos-local"]?.config ??
|
|
1438
|
+
raw?.plugins?.entries?.["memos-lite-openclaw-plugin"]?.config ??
|
|
1439
|
+
raw?.plugins?.entries?.["memos-lite"]?.config ?? {};
|
|
1356
1440
|
const emb = pluginCfg.embedding;
|
|
1357
1441
|
hasEmbedding = !!(emb && emb.provider);
|
|
1358
1442
|
const sum = pluginCfg.summarizer;
|
|
@@ -1536,17 +1620,16 @@ class ViewerServer {
|
|
|
1536
1620
|
let totalErrors = 0;
|
|
1537
1621
|
const cfgPath = this.getOpenClawConfigPath();
|
|
1538
1622
|
let summarizerCfg;
|
|
1539
|
-
let strongCfg;
|
|
1540
1623
|
try {
|
|
1541
1624
|
const raw = JSON.parse(node_fs_1.default.readFileSync(cfgPath, "utf-8"));
|
|
1542
1625
|
const pluginCfg = raw?.plugins?.entries?.["memos-local-openclaw-plugin"]?.config ??
|
|
1543
|
-
raw?.plugins?.entries?.["memos-
|
|
1544
|
-
raw?.plugins?.entries?.["memos-lite-openclaw-plugin"]?.config ??
|
|
1626
|
+
raw?.plugins?.entries?.["memos-local"]?.config ??
|
|
1627
|
+
raw?.plugins?.entries?.["memos-lite-openclaw-plugin"]?.config ??
|
|
1628
|
+
raw?.plugins?.entries?.["memos-lite"]?.config ?? {};
|
|
1545
1629
|
summarizerCfg = pluginCfg.summarizer;
|
|
1546
|
-
strongCfg = pluginCfg.skillEvolution?.summarizer;
|
|
1547
1630
|
}
|
|
1548
1631
|
catch { /* no config */ }
|
|
1549
|
-
const summarizer = new providers_1.Summarizer(summarizerCfg, this.log
|
|
1632
|
+
const summarizer = new providers_1.Summarizer(summarizerCfg, this.log);
|
|
1550
1633
|
// Phase 1: Import SQLite memory chunks
|
|
1551
1634
|
if (importSqlite) {
|
|
1552
1635
|
const memoryDir = node_path_1.default.join(ocHome, "memory");
|
|
@@ -1665,8 +1748,8 @@ class ViewerServer {
|
|
|
1665
1748
|
mergeCount: 0,
|
|
1666
1749
|
lastHitAt: null,
|
|
1667
1750
|
mergeHistory: "[]",
|
|
1668
|
-
createdAt: row.updated_at
|
|
1669
|
-
updatedAt: row.updated_at
|
|
1751
|
+
createdAt: normalizeTimestamp(row.updated_at),
|
|
1752
|
+
updatedAt: normalizeTimestamp(row.updated_at),
|
|
1670
1753
|
};
|
|
1671
1754
|
this.store.insertChunk(chunk);
|
|
1672
1755
|
if (embedding && dedupStatus === "active") {
|