@memtensor/memos-local-openclaw-plugin 0.3.3 → 0.3.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/README.md +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/recall/engine.d.ts.map +1 -1
- package/dist/recall/engine.js +4 -1
- package/dist/recall/engine.js.map +1 -1
- package/dist/storage/sqlite.d.ts +6 -0
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +21 -0
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/storage/vector.d.ts +3 -4
- package/dist/storage/vector.d.ts.map +1 -1
- package/dist/storage/vector.js +6 -5
- package/dist/storage/vector.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.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 +64 -1
- package/dist/viewer/html.js.map +1 -1
- package/index.ts +1 -0
- package/package.json +1 -1
- package/src/config.ts +1 -0
- package/src/recall/engine.ts +4 -1
- package/src/storage/sqlite.ts +25 -0
- package/src/storage/vector.ts +6 -4
- package/src/types.ts +3 -0
- package/src/viewer/html.ts +64 -1
|
@@ -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,ohlOA0qHf,CAAC"}
|
package/dist/viewer/html.js
CHANGED
|
@@ -478,6 +478,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
478
478
|
.log-io-section+.log-io-section{border-top:1px dashed var(--border)}
|
|
479
479
|
[data-theme="light"] .log-io-content{background:rgba(0,0,0,.04)}
|
|
480
480
|
[data-theme="light"] .log-summary-query{background:rgba(59,130,246,.06)}
|
|
481
|
+
.settings-group{margin-bottom:8px}
|
|
482
|
+
.settings-group-title{font-size:15px;font-weight:700;color:var(--text);margin:0 0 12px 0;padding:0;letter-spacing:.02em}
|
|
483
|
+
.settings-group .settings-section{margin-bottom:16px}
|
|
484
|
+
.settings-group .settings-section:last-child{margin-bottom:0}
|
|
481
485
|
.settings-section{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:24px 28px}
|
|
482
486
|
.settings-section h3{font-size:13px;font-weight:700;color:var(--text);margin-bottom:16px;display:flex;align-items:center;gap:8px}
|
|
483
487
|
.settings-section h3 .icon{font-size:16px;opacity:.8}
|
|
@@ -903,6 +907,8 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
903
907
|
|
|
904
908
|
<!-- ─── Settings View ─── -->
|
|
905
909
|
<div class="settings-view" id="settingsView">
|
|
910
|
+
<div class="settings-group" id="settingsModelConfig">
|
|
911
|
+
<h2 class="settings-group-title"><span data-i18n="settings.modelconfig">Model Configuration</span></h2>
|
|
906
912
|
<div class="settings-section">
|
|
907
913
|
<h3><span class="icon">\u{1F4E1}</span> <span data-i18n="settings.embedding">Embedding Model</span></h3>
|
|
908
914
|
<div class="settings-grid">
|
|
@@ -966,6 +972,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
966
972
|
</div>
|
|
967
973
|
</div>
|
|
968
974
|
</div>
|
|
975
|
+
</div>
|
|
969
976
|
|
|
970
977
|
<div class="settings-section">
|
|
971
978
|
<h3><span class="icon">\u{1F527}</span> <span data-i18n="settings.skill">Skill Evolution</span></h3>
|
|
@@ -987,6 +994,36 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
987
994
|
<input type="number" id="cfgSkillMinChunks" placeholder="6">
|
|
988
995
|
</div>
|
|
989
996
|
</div>
|
|
997
|
+
<div style="margin-top:16px;padding-top:16px;border-top:1px solid var(--border)">
|
|
998
|
+
<h4 style="font-size:12px;font-weight:600;color:var(--text-sec);margin-bottom:12px"><span data-i18n="settings.skill.model">Skill Dedicated Model</span></h4>
|
|
999
|
+
<div class="field-hint" style="margin-bottom:12px" data-i18n="settings.skill.model.hint">If not configured, the main Summarizer Model above will be used for skill generation. Configure a dedicated model here for higher quality skill output.</div>
|
|
1000
|
+
<div class="settings-grid">
|
|
1001
|
+
<div class="settings-field">
|
|
1002
|
+
<label data-i18n="settings.provider">Provider</label>
|
|
1003
|
+
<select id="cfgSkillProvider">
|
|
1004
|
+
<option value="">— <span data-i18n="settings.skill.usemain">Use main summarizer</span> —</option>
|
|
1005
|
+
<option value="openai_compatible">OpenAI Compatible</option>
|
|
1006
|
+
<option value="openai">OpenAI</option>
|
|
1007
|
+
<option value="anthropic">Anthropic</option>
|
|
1008
|
+
<option value="gemini">Gemini</option>
|
|
1009
|
+
<option value="azure_openai">Azure OpenAI</option>
|
|
1010
|
+
<option value="bedrock">Bedrock</option>
|
|
1011
|
+
</select>
|
|
1012
|
+
</div>
|
|
1013
|
+
<div class="settings-field">
|
|
1014
|
+
<label data-i18n="settings.model">Model</label>
|
|
1015
|
+
<input type="text" id="cfgSkillModel" placeholder="e.g. claude-4.6-opus">
|
|
1016
|
+
</div>
|
|
1017
|
+
<div class="settings-field full-width">
|
|
1018
|
+
<label>Endpoint</label>
|
|
1019
|
+
<input type="text" id="cfgSkillEndpoint" placeholder="https://...">
|
|
1020
|
+
</div>
|
|
1021
|
+
<div class="settings-field">
|
|
1022
|
+
<label>API Key</label>
|
|
1023
|
+
<input type="password" id="cfgSkillApiKey" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022">
|
|
1024
|
+
</div>
|
|
1025
|
+
</div>
|
|
1026
|
+
</div>
|
|
990
1027
|
</div>
|
|
991
1028
|
|
|
992
1029
|
<div class="settings-section">
|
|
@@ -1342,6 +1379,7 @@ const I18N={
|
|
|
1342
1379
|
'logs.ago':'ago',
|
|
1343
1380
|
'tab.import':'\u{1F4E5} Import',
|
|
1344
1381
|
'tab.settings':'\u2699 Settings',
|
|
1382
|
+
'settings.modelconfig':'Model Configuration',
|
|
1345
1383
|
'settings.embedding':'Embedding Model',
|
|
1346
1384
|
'settings.summarizer':'Summarizer Model',
|
|
1347
1385
|
'settings.skill':'Skill Evolution',
|
|
@@ -1601,6 +1639,7 @@ const I18N={
|
|
|
1601
1639
|
'logs.ago':'前',
|
|
1602
1640
|
'tab.import':'\u{1F4E5} 导入',
|
|
1603
1641
|
'tab.settings':'\u2699 设置',
|
|
1642
|
+
'settings.modelconfig':'模型配置',
|
|
1604
1643
|
'settings.embedding':'嵌入模型',
|
|
1605
1644
|
'settings.summarizer':'摘要模型',
|
|
1606
1645
|
'settings.skill':'技能进化',
|
|
@@ -2452,6 +2491,12 @@ async function loadConfig(){
|
|
|
2452
2491
|
document.getElementById('cfgSkillConfidence').value=sk.minConfidence||'';
|
|
2453
2492
|
document.getElementById('cfgSkillMinChunks').value=sk.minChunksForEval||'';
|
|
2454
2493
|
|
|
2494
|
+
const skSum=sk.summarizer||{};
|
|
2495
|
+
document.getElementById('cfgSkillProvider').value=skSum.provider||'';
|
|
2496
|
+
document.getElementById('cfgSkillModel').value=skSum.model||'';
|
|
2497
|
+
document.getElementById('cfgSkillEndpoint').value=skSum.endpoint||'';
|
|
2498
|
+
document.getElementById('cfgSkillApiKey').value=skSum.apiKey||'';
|
|
2499
|
+
|
|
2455
2500
|
document.getElementById('cfgViewerPort').value=cfg.viewerPort||'';
|
|
2456
2501
|
|
|
2457
2502
|
const tel=cfg.telemetry||{};
|
|
@@ -2485,6 +2530,14 @@ async function saveConfig(){
|
|
|
2485
2530
|
const mc=document.getElementById('cfgSkillConfidence').value.trim();if(mc) cfg.skillEvolution.minConfidence=Number(mc);
|
|
2486
2531
|
const mk=document.getElementById('cfgSkillMinChunks').value.trim();if(mk) cfg.skillEvolution.minChunksForEval=Number(mk);
|
|
2487
2532
|
|
|
2533
|
+
const skP=document.getElementById('cfgSkillProvider').value;
|
|
2534
|
+
if(skP){
|
|
2535
|
+
cfg.skillEvolution.summarizer={provider:skP};
|
|
2536
|
+
const sv=document.getElementById('cfgSkillModel').value.trim();if(sv) cfg.skillEvolution.summarizer.model=sv;
|
|
2537
|
+
const se=document.getElementById('cfgSkillEndpoint').value.trim();if(se) cfg.skillEvolution.summarizer.endpoint=se;
|
|
2538
|
+
const sk=document.getElementById('cfgSkillApiKey').value.trim();if(sk) cfg.skillEvolution.summarizer.apiKey=sk;
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2488
2541
|
const vp=document.getElementById('cfgViewerPort').value.trim();
|
|
2489
2542
|
if(vp) cfg.viewerPort=Number(vp);
|
|
2490
2543
|
|
|
@@ -2828,7 +2881,17 @@ async function loadStats(){
|
|
|
2828
2881
|
}
|
|
2829
2882
|
document.getElementById('statSessions').textContent=d.totalSessions;
|
|
2830
2883
|
document.getElementById('statEmbeddings').textContent=d.totalEmbeddings;
|
|
2831
|
-
|
|
2884
|
+
let days=0;
|
|
2885
|
+
if(d.timeRange&&d.timeRange.earliest!=null&&d.timeRange.latest!=null){
|
|
2886
|
+
let e=Number(d.timeRange.earliest), l=Number(d.timeRange.latest);
|
|
2887
|
+
if(Number.isFinite(e)&&Number.isFinite(l)){
|
|
2888
|
+
if(e<1e12) e*=1000;
|
|
2889
|
+
if(l<1e12) l*=1000;
|
|
2890
|
+
days=Math.round((l-e)/86400000);
|
|
2891
|
+
days=Math.max(0,Math.min(36500,days));
|
|
2892
|
+
if(days===0) days=1;
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2832
2895
|
document.getElementById('statTimeSpan').textContent=days;
|
|
2833
2896
|
|
|
2834
2897
|
const provEl=document.getElementById('embeddingStatus');
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA0qHlB,CAAC"}
|
package/index.ts
CHANGED
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -41,6 +41,7 @@ export function resolveConfig(raw: Partial<MemosLocalConfig> | undefined, stateD
|
|
|
41
41
|
rrfK: cfg.recall?.rrfK ?? DEFAULTS.rrfK,
|
|
42
42
|
mmrLambda: cfg.recall?.mmrLambda ?? DEFAULTS.mmrLambda,
|
|
43
43
|
recencyHalfLifeDays: cfg.recall?.recencyHalfLifeDays ?? DEFAULTS.recencyHalfLifeDays,
|
|
44
|
+
vectorSearchMaxChunks: cfg.recall?.vectorSearchMaxChunks ?? DEFAULTS.vectorSearchMaxChunks,
|
|
44
45
|
},
|
|
45
46
|
dedup: {
|
|
46
47
|
similarityThreshold: cfg.dedup?.similarityThreshold ?? DEFAULTS.dedupSimilarityThreshold,
|
package/src/recall/engine.ts
CHANGED
|
@@ -46,7 +46,10 @@ export class RecallEngine {
|
|
|
46
46
|
if (query) {
|
|
47
47
|
try {
|
|
48
48
|
const queryVec = await this.embedder.embedQuery(query);
|
|
49
|
-
|
|
49
|
+
const maxChunks = recallCfg.vectorSearchMaxChunks && recallCfg.vectorSearchMaxChunks > 0
|
|
50
|
+
? recallCfg.vectorSearchMaxChunks
|
|
51
|
+
: undefined;
|
|
52
|
+
vecCandidates = vectorSearch(this.store, queryVec, candidatePool, maxChunks);
|
|
50
53
|
} catch (err) {
|
|
51
54
|
this.ctx.log.warn(`Vector search failed, using FTS only: ${err}`);
|
|
52
55
|
}
|
package/src/storage/sqlite.ts
CHANGED
|
@@ -38,6 +38,8 @@ export class SqliteStore {
|
|
|
38
38
|
ON chunks(session_key, turn_id, seq);
|
|
39
39
|
CREATE INDEX IF NOT EXISTS idx_chunks_created
|
|
40
40
|
ON chunks(created_at);
|
|
41
|
+
CREATE INDEX IF NOT EXISTS idx_chunks_session_created
|
|
42
|
+
ON chunks(session_key, created_at, seq);
|
|
41
43
|
|
|
42
44
|
CREATE VIRTUAL TABLE IF NOT EXISTS chunks_fts USING fts5(
|
|
43
45
|
summary,
|
|
@@ -103,9 +105,14 @@ export class SqliteStore {
|
|
|
103
105
|
this.migrateMergeFields();
|
|
104
106
|
this.migrateApiLogs();
|
|
105
107
|
this.migrateDedupStatus();
|
|
108
|
+
this.migrateChunksIndexesForRecall();
|
|
106
109
|
this.log.debug("Database schema initialized");
|
|
107
110
|
}
|
|
108
111
|
|
|
112
|
+
private migrateChunksIndexesForRecall(): void {
|
|
113
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS idx_chunks_dedup_created ON chunks(dedup_status, created_at DESC)");
|
|
114
|
+
}
|
|
115
|
+
|
|
109
116
|
private migrateTaskId(): void {
|
|
110
117
|
const cols = this.db.prepare("PRAGMA table_info(chunks)").all() as Array<{ name: string }>;
|
|
111
118
|
if (!cols.some((c) => c.name === "task_id")) {
|
|
@@ -648,6 +655,24 @@ export class SqliteStore {
|
|
|
648
655
|
}));
|
|
649
656
|
}
|
|
650
657
|
|
|
658
|
+
/** Like getAllEmbeddings but only for the most recent N chunks (uses idx_chunks_dedup_created). Use for vector search cap to avoid full scan. */
|
|
659
|
+
getRecentEmbeddings(limit: number): Array<{ chunkId: string; vector: number[] }> {
|
|
660
|
+
if (limit <= 0) return this.getAllEmbeddings();
|
|
661
|
+
const rows = this.db.prepare(
|
|
662
|
+
`SELECT e.chunk_id, e.vector, e.dimensions
|
|
663
|
+
FROM chunks c
|
|
664
|
+
JOIN embeddings e ON e.chunk_id = c.id
|
|
665
|
+
WHERE c.dedup_status = 'active'
|
|
666
|
+
ORDER BY c.created_at DESC
|
|
667
|
+
LIMIT ?`,
|
|
668
|
+
).all(limit) as Array<{ chunk_id: string; vector: Buffer; dimensions: number }>;
|
|
669
|
+
|
|
670
|
+
return rows.map((r) => ({
|
|
671
|
+
chunkId: r.chunk_id,
|
|
672
|
+
vector: Array.from(new Float32Array(r.vector.buffer, r.vector.byteOffset, r.dimensions)),
|
|
673
|
+
}));
|
|
674
|
+
}
|
|
675
|
+
|
|
651
676
|
getEmbedding(chunkId: string): number[] | null {
|
|
652
677
|
const row = this.db.prepare(
|
|
653
678
|
"SELECT vector, dimensions FROM embeddings WHERE chunk_id = ?",
|
package/src/storage/vector.ts
CHANGED
|
@@ -20,16 +20,18 @@ export interface VectorHit {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Brute-force vector search over
|
|
24
|
-
*
|
|
25
|
-
* a full scan with SIMD-friendly Float32 math is sufficient.
|
|
23
|
+
* Brute-force vector search over stored embeddings.
|
|
24
|
+
* When maxChunks > 0, only searches the most recent maxChunks chunks (uses index; avoids full scan as data grows).
|
|
26
25
|
*/
|
|
27
26
|
export function vectorSearch(
|
|
28
27
|
store: SqliteStore,
|
|
29
28
|
queryVec: number[],
|
|
30
29
|
topK: number,
|
|
30
|
+
maxChunks?: number,
|
|
31
31
|
): VectorHit[] {
|
|
32
|
-
const all =
|
|
32
|
+
const all = maxChunks != null && maxChunks > 0
|
|
33
|
+
? store.getRecentEmbeddings(maxChunks)
|
|
34
|
+
: store.getAllEmbeddings();
|
|
33
35
|
const scored: VectorHit[] = all.map((row) => ({
|
|
34
36
|
chunkId: row.chunkId,
|
|
35
37
|
score: cosineSimilarity(queryVec, row.vector),
|
package/src/types.ts
CHANGED
|
@@ -251,6 +251,8 @@ export interface MemosLocalConfig {
|
|
|
251
251
|
rrfK?: number;
|
|
252
252
|
mmrLambda?: number;
|
|
253
253
|
recencyHalfLifeDays?: number;
|
|
254
|
+
/** Cap vector search to this many most recent chunks. 0 = no cap (search all; may get slower with 200k+ chunks). If you set a cap for performance, use a large value (e.g. 200000–300000) so older memories are still in the window; FTS always searches all. */
|
|
255
|
+
vectorSearchMaxChunks?: number;
|
|
254
256
|
};
|
|
255
257
|
dedup?: {
|
|
256
258
|
similarityThreshold?: number;
|
|
@@ -272,6 +274,7 @@ export const DEFAULTS = {
|
|
|
272
274
|
rrfK: 60,
|
|
273
275
|
mmrLambda: 0.7,
|
|
274
276
|
recencyHalfLifeDays: 14,
|
|
277
|
+
vectorSearchMaxChunks: 0,
|
|
275
278
|
dedupSimilarityThreshold: 0.93,
|
|
276
279
|
evidenceWrapperTag: "STORED_MEMORY",
|
|
277
280
|
excerptMinChars: 200,
|
package/src/viewer/html.ts
CHANGED
|
@@ -475,6 +475,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
475
475
|
.log-io-section+.log-io-section{border-top:1px dashed var(--border)}
|
|
476
476
|
[data-theme="light"] .log-io-content{background:rgba(0,0,0,.04)}
|
|
477
477
|
[data-theme="light"] .log-summary-query{background:rgba(59,130,246,.06)}
|
|
478
|
+
.settings-group{margin-bottom:8px}
|
|
479
|
+
.settings-group-title{font-size:15px;font-weight:700;color:var(--text);margin:0 0 12px 0;padding:0;letter-spacing:.02em}
|
|
480
|
+
.settings-group .settings-section{margin-bottom:16px}
|
|
481
|
+
.settings-group .settings-section:last-child{margin-bottom:0}
|
|
478
482
|
.settings-section{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:24px 28px}
|
|
479
483
|
.settings-section h3{font-size:13px;font-weight:700;color:var(--text);margin-bottom:16px;display:flex;align-items:center;gap:8px}
|
|
480
484
|
.settings-section h3 .icon{font-size:16px;opacity:.8}
|
|
@@ -900,6 +904,8 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
900
904
|
|
|
901
905
|
<!-- ─── Settings View ─── -->
|
|
902
906
|
<div class="settings-view" id="settingsView">
|
|
907
|
+
<div class="settings-group" id="settingsModelConfig">
|
|
908
|
+
<h2 class="settings-group-title"><span data-i18n="settings.modelconfig">Model Configuration</span></h2>
|
|
903
909
|
<div class="settings-section">
|
|
904
910
|
<h3><span class="icon">\u{1F4E1}</span> <span data-i18n="settings.embedding">Embedding Model</span></h3>
|
|
905
911
|
<div class="settings-grid">
|
|
@@ -963,6 +969,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
963
969
|
</div>
|
|
964
970
|
</div>
|
|
965
971
|
</div>
|
|
972
|
+
</div>
|
|
966
973
|
|
|
967
974
|
<div class="settings-section">
|
|
968
975
|
<h3><span class="icon">\u{1F527}</span> <span data-i18n="settings.skill">Skill Evolution</span></h3>
|
|
@@ -984,6 +991,36 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
984
991
|
<input type="number" id="cfgSkillMinChunks" placeholder="6">
|
|
985
992
|
</div>
|
|
986
993
|
</div>
|
|
994
|
+
<div style="margin-top:16px;padding-top:16px;border-top:1px solid var(--border)">
|
|
995
|
+
<h4 style="font-size:12px;font-weight:600;color:var(--text-sec);margin-bottom:12px"><span data-i18n="settings.skill.model">Skill Dedicated Model</span></h4>
|
|
996
|
+
<div class="field-hint" style="margin-bottom:12px" data-i18n="settings.skill.model.hint">If not configured, the main Summarizer Model above will be used for skill generation. Configure a dedicated model here for higher quality skill output.</div>
|
|
997
|
+
<div class="settings-grid">
|
|
998
|
+
<div class="settings-field">
|
|
999
|
+
<label data-i18n="settings.provider">Provider</label>
|
|
1000
|
+
<select id="cfgSkillProvider">
|
|
1001
|
+
<option value="">— <span data-i18n="settings.skill.usemain">Use main summarizer</span> —</option>
|
|
1002
|
+
<option value="openai_compatible">OpenAI Compatible</option>
|
|
1003
|
+
<option value="openai">OpenAI</option>
|
|
1004
|
+
<option value="anthropic">Anthropic</option>
|
|
1005
|
+
<option value="gemini">Gemini</option>
|
|
1006
|
+
<option value="azure_openai">Azure OpenAI</option>
|
|
1007
|
+
<option value="bedrock">Bedrock</option>
|
|
1008
|
+
</select>
|
|
1009
|
+
</div>
|
|
1010
|
+
<div class="settings-field">
|
|
1011
|
+
<label data-i18n="settings.model">Model</label>
|
|
1012
|
+
<input type="text" id="cfgSkillModel" placeholder="e.g. claude-4.6-opus">
|
|
1013
|
+
</div>
|
|
1014
|
+
<div class="settings-field full-width">
|
|
1015
|
+
<label>Endpoint</label>
|
|
1016
|
+
<input type="text" id="cfgSkillEndpoint" placeholder="https://...">
|
|
1017
|
+
</div>
|
|
1018
|
+
<div class="settings-field">
|
|
1019
|
+
<label>API Key</label>
|
|
1020
|
+
<input type="password" id="cfgSkillApiKey" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022">
|
|
1021
|
+
</div>
|
|
1022
|
+
</div>
|
|
1023
|
+
</div>
|
|
987
1024
|
</div>
|
|
988
1025
|
|
|
989
1026
|
<div class="settings-section">
|
|
@@ -1339,6 +1376,7 @@ const I18N={
|
|
|
1339
1376
|
'logs.ago':'ago',
|
|
1340
1377
|
'tab.import':'\u{1F4E5} Import',
|
|
1341
1378
|
'tab.settings':'\u2699 Settings',
|
|
1379
|
+
'settings.modelconfig':'Model Configuration',
|
|
1342
1380
|
'settings.embedding':'Embedding Model',
|
|
1343
1381
|
'settings.summarizer':'Summarizer Model',
|
|
1344
1382
|
'settings.skill':'Skill Evolution',
|
|
@@ -1598,6 +1636,7 @@ const I18N={
|
|
|
1598
1636
|
'logs.ago':'前',
|
|
1599
1637
|
'tab.import':'\u{1F4E5} 导入',
|
|
1600
1638
|
'tab.settings':'\u2699 设置',
|
|
1639
|
+
'settings.modelconfig':'模型配置',
|
|
1601
1640
|
'settings.embedding':'嵌入模型',
|
|
1602
1641
|
'settings.summarizer':'摘要模型',
|
|
1603
1642
|
'settings.skill':'技能进化',
|
|
@@ -2449,6 +2488,12 @@ async function loadConfig(){
|
|
|
2449
2488
|
document.getElementById('cfgSkillConfidence').value=sk.minConfidence||'';
|
|
2450
2489
|
document.getElementById('cfgSkillMinChunks').value=sk.minChunksForEval||'';
|
|
2451
2490
|
|
|
2491
|
+
const skSum=sk.summarizer||{};
|
|
2492
|
+
document.getElementById('cfgSkillProvider').value=skSum.provider||'';
|
|
2493
|
+
document.getElementById('cfgSkillModel').value=skSum.model||'';
|
|
2494
|
+
document.getElementById('cfgSkillEndpoint').value=skSum.endpoint||'';
|
|
2495
|
+
document.getElementById('cfgSkillApiKey').value=skSum.apiKey||'';
|
|
2496
|
+
|
|
2452
2497
|
document.getElementById('cfgViewerPort').value=cfg.viewerPort||'';
|
|
2453
2498
|
|
|
2454
2499
|
const tel=cfg.telemetry||{};
|
|
@@ -2482,6 +2527,14 @@ async function saveConfig(){
|
|
|
2482
2527
|
const mc=document.getElementById('cfgSkillConfidence').value.trim();if(mc) cfg.skillEvolution.minConfidence=Number(mc);
|
|
2483
2528
|
const mk=document.getElementById('cfgSkillMinChunks').value.trim();if(mk) cfg.skillEvolution.minChunksForEval=Number(mk);
|
|
2484
2529
|
|
|
2530
|
+
const skP=document.getElementById('cfgSkillProvider').value;
|
|
2531
|
+
if(skP){
|
|
2532
|
+
cfg.skillEvolution.summarizer={provider:skP};
|
|
2533
|
+
const sv=document.getElementById('cfgSkillModel').value.trim();if(sv) cfg.skillEvolution.summarizer.model=sv;
|
|
2534
|
+
const se=document.getElementById('cfgSkillEndpoint').value.trim();if(se) cfg.skillEvolution.summarizer.endpoint=se;
|
|
2535
|
+
const sk=document.getElementById('cfgSkillApiKey').value.trim();if(sk) cfg.skillEvolution.summarizer.apiKey=sk;
|
|
2536
|
+
}
|
|
2537
|
+
|
|
2485
2538
|
const vp=document.getElementById('cfgViewerPort').value.trim();
|
|
2486
2539
|
if(vp) cfg.viewerPort=Number(vp);
|
|
2487
2540
|
|
|
@@ -2825,7 +2878,17 @@ async function loadStats(){
|
|
|
2825
2878
|
}
|
|
2826
2879
|
document.getElementById('statSessions').textContent=d.totalSessions;
|
|
2827
2880
|
document.getElementById('statEmbeddings').textContent=d.totalEmbeddings;
|
|
2828
|
-
|
|
2881
|
+
let days=0;
|
|
2882
|
+
if(d.timeRange&&d.timeRange.earliest!=null&&d.timeRange.latest!=null){
|
|
2883
|
+
let e=Number(d.timeRange.earliest), l=Number(d.timeRange.latest);
|
|
2884
|
+
if(Number.isFinite(e)&&Number.isFinite(l)){
|
|
2885
|
+
if(e<1e12) e*=1000;
|
|
2886
|
+
if(l<1e12) l*=1000;
|
|
2887
|
+
days=Math.round((l-e)/86400000);
|
|
2888
|
+
days=Math.max(0,Math.min(36500,days));
|
|
2889
|
+
if(days===0) days=1;
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2829
2892
|
document.getElementById('statTimeSpan').textContent=days;
|
|
2830
2893
|
|
|
2831
2894
|
const provEl=document.getElementById('embeddingStatus');
|