@memtensor/memos-local-openclaw-plugin 0.3.20 → 1.0.1
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 +239 -22
- package/dist/capture/index.d.ts +1 -1
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +33 -8
- package/dist/capture/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/ingest/providers/anthropic.d.ts.map +1 -1
- package/dist/ingest/providers/anthropic.js +22 -8
- 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 +22 -8
- 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 +22 -8
- package/dist/ingest/providers/gemini.js.map +1 -1
- package/dist/ingest/providers/index.d.ts +13 -18
- package/dist/ingest/providers/index.d.ts.map +1 -1
- package/dist/ingest/providers/index.js +213 -139
- package/dist/ingest/providers/index.js.map +1 -1
- package/dist/ingest/providers/openai.d.ts +1 -1
- package/dist/ingest/providers/openai.d.ts.map +1 -1
- package/dist/ingest/providers/openai.js +37 -17
- package/dist/ingest/providers/openai.js.map +1 -1
- package/dist/ingest/task-processor.d.ts +28 -3
- package/dist/ingest/task-processor.d.ts.map +1 -1
- package/dist/ingest/task-processor.js +166 -67
- package/dist/ingest/task-processor.js.map +1 -1
- package/dist/ingest/worker.d.ts.map +1 -1
- package/dist/ingest/worker.js +97 -75
- package/dist/ingest/worker.js.map +1 -1
- package/dist/shared/llm-call.d.ts +26 -0
- package/dist/shared/llm-call.d.ts.map +1 -0
- package/dist/shared/llm-call.js +163 -0
- package/dist/shared/llm-call.js.map +1 -0
- package/dist/skill/evaluator.d.ts +0 -3
- package/dist/skill/evaluator.d.ts.map +1 -1
- package/dist/skill/evaluator.js +34 -59
- package/dist/skill/evaluator.js.map +1 -1
- package/dist/skill/evolver.d.ts +22 -1
- package/dist/skill/evolver.d.ts.map +1 -1
- package/dist/skill/evolver.js +191 -32
- package/dist/skill/evolver.js.map +1 -1
- package/dist/skill/generator.d.ts +0 -3
- package/dist/skill/generator.d.ts.map +1 -1
- package/dist/skill/generator.js +15 -50
- package/dist/skill/generator.js.map +1 -1
- package/dist/skill/upgrader.d.ts +0 -2
- package/dist/skill/upgrader.d.ts.map +1 -1
- package/dist/skill/upgrader.js +4 -39
- package/dist/skill/upgrader.js.map +1 -1
- package/dist/skill/validator.d.ts +0 -2
- package/dist/skill/validator.d.ts.map +1 -1
- package/dist/skill/validator.js +14 -44
- package/dist/skill/validator.js.map +1 -1
- package/dist/storage/sqlite.d.ts +13 -2
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +92 -15
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/tools/memory-get.d.ts.map +1 -1
- package/dist/tools/memory-get.js +5 -1
- package/dist/tools/memory-get.js.map +1 -1
- package/dist/tools/memory-search.d.ts.map +1 -1
- package/dist/tools/memory-search.js +5 -0
- package/dist/tools/memory-search.js.map +1 -1
- package/dist/tools/memory-timeline.d.ts.map +1 -1
- package/dist/tools/memory-timeline.js +11 -2
- package/dist/tools/memory-timeline.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- 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 +380 -26
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts +9 -0
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +549 -184
- package/dist/viewer/server.js.map +1 -1
- package/index.ts +9 -3
- package/package.json +2 -1
- package/src/capture/index.ts +39 -10
- package/src/index.ts +3 -2
- package/src/ingest/providers/anthropic.ts +22 -8
- package/src/ingest/providers/bedrock.ts +22 -8
- package/src/ingest/providers/gemini.ts +22 -8
- package/src/ingest/providers/index.ts +192 -142
- package/src/ingest/providers/openai.ts +37 -17
- package/src/ingest/task-processor.ts +183 -65
- package/src/ingest/worker.ts +98 -77
- package/src/shared/llm-call.ts +144 -0
- package/src/skill/evaluator.ts +35 -64
- package/src/skill/evolver.ts +201 -33
- package/src/skill/generator.ts +16 -59
- package/src/skill/upgrader.ts +5 -43
- package/src/skill/validator.ts +15 -47
- package/src/storage/sqlite.ts +107 -15
- package/src/tools/memory-get.ts +6 -1
- package/src/tools/memory-search.ts +6 -0
- package/src/tools/memory-timeline.ts +13 -1
- package/src/types.ts +2 -1
- package/src/viewer/html.ts +380 -26
- package/src/viewer/server.ts +535 -197
package/dist/viewer/html.js
CHANGED
|
@@ -417,7 +417,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
417
417
|
|
|
418
418
|
/* ─── Analytics / 统计 ─── */
|
|
419
419
|
.nav-tabs{display:flex;align-items:center;gap:2px;background:rgba(255,255,255,.06);border-radius:10px;padding:3px}
|
|
420
|
-
.nav-tabs .tab{padding:6px 20px;border-radius:8px;font-size:13px;font-weight:600;color:var(--text-sec);background:transparent;border:1px solid
|
|
420
|
+
.nav-tabs .tab{padding:6px 20px;border-radius:8px;font-size:13px;font-weight:600;color:var(--text-sec);background:transparent;border:1px solid rgba(0,0,0,0);cursor:pointer;transition:color .2s,background .2s,box-shadow .2s;white-space:nowrap}
|
|
421
421
|
.nav-tabs .tab:hover{color:var(--text)}
|
|
422
422
|
.nav-tabs .tab.active{color:var(--text);background:rgba(255,255,255,.1);border-color:var(--border);box-shadow:0 1px 4px rgba(0,0,0,.15)}
|
|
423
423
|
[data-theme="light"] .nav-tabs{background:rgba(0,0,0,.05)}
|
|
@@ -515,6 +515,12 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
515
515
|
.toggle-slider::before{content:'';position:absolute;height:14px;width:14px;left:3px;bottom:3px;background:#fff;border-radius:50%;transition:.2s}
|
|
516
516
|
.toggle-switch input:checked+.toggle-slider{background:var(--pri)}
|
|
517
517
|
.toggle-switch input:checked+.toggle-slider::before{transform:translateX(16px)}
|
|
518
|
+
.test-conn-row{display:flex;align-items:center;gap:10px;margin-top:12px;padding-top:10px;border-top:1px dashed var(--border)}
|
|
519
|
+
.test-conn-row .btn{font-size:11px;padding:5px 14px;border:1px solid var(--border);border-radius:6px}
|
|
520
|
+
.test-result{font-size:12px;line-height:1.5;word-break:break-word}
|
|
521
|
+
.test-result.ok{color:#22c55e}
|
|
522
|
+
.test-result.fail{color:var(--rose)}
|
|
523
|
+
.test-result.loading{color:var(--text-muted)}
|
|
518
524
|
.settings-actions{display:flex;gap:12px;justify-content:flex-end;align-items:center;margin-top:16px;padding-top:16px;border-top:1px solid var(--border)}
|
|
519
525
|
.settings-actions .btn{min-width:110px;padding:10px 20px;font-size:13px}
|
|
520
526
|
.settings-actions .btn-primary{background:rgba(99,102,241,.08);color:var(--pri);border:1px solid rgba(99,102,241,.25);font-weight:600}
|
|
@@ -819,6 +825,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
819
825
|
<div class="task-detail-summary" id="taskDetailSummary"></div>
|
|
820
826
|
<div class="task-detail-chunks-title" data-i18n="tasks.chunks">Related Memories</div>
|
|
821
827
|
<div class="task-detail-chunks" id="taskDetailChunks"></div>
|
|
828
|
+
<div id="taskDetailActions" style="display:flex;gap:8px;margin-top:16px;padding-top:12px;border-top:1px solid var(--border)"></div>
|
|
822
829
|
</div>
|
|
823
830
|
</div>
|
|
824
831
|
</div>
|
|
@@ -867,6 +874,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
867
874
|
<div class="task-detail-chunks" id="skillVersionsList" style="gap:10px"></div>
|
|
868
875
|
<div class="task-detail-chunks-title" style="margin-top:16px" data-i18n="skills.related">Related Tasks</div>
|
|
869
876
|
<div class="task-detail-chunks" id="skillRelatedTasks" style="gap:8px"></div>
|
|
877
|
+
<div id="skillDetailActions" style="display:flex;gap:8px;margin-top:16px;padding-top:12px;border-top:1px solid var(--border)"></div>
|
|
870
878
|
</div>
|
|
871
879
|
</div>
|
|
872
880
|
<div class="analytics-view" id="analyticsView">
|
|
@@ -940,9 +948,12 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
940
948
|
<div class="settings-grid">
|
|
941
949
|
<div class="settings-field">
|
|
942
950
|
<label data-i18n="settings.provider">Provider</label>
|
|
943
|
-
<select id="cfgEmbProvider">
|
|
951
|
+
<select id="cfgEmbProvider" onchange="onProviderChange('embedding')">
|
|
944
952
|
<option value="openai_compatible">OpenAI Compatible</option>
|
|
945
953
|
<option value="openai">OpenAI</option>
|
|
954
|
+
<option value="siliconflow">SiliconFlow (\u7845\u57FA\u6D41\u52A8)</option>
|
|
955
|
+
<option value="zhipu">Zhipu AI (\u667A\u8C31)</option>
|
|
956
|
+
<option value="bailian">Alibaba Bailian (\u767E\u70BC)</option>
|
|
946
957
|
<option value="gemini">Gemini</option>
|
|
947
958
|
<option value="azure_openai">Azure OpenAI</option>
|
|
948
959
|
<option value="cohere">Cohere</option>
|
|
@@ -964,6 +975,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
964
975
|
<input type="password" id="cfgEmbApiKey" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022">
|
|
965
976
|
</div>
|
|
966
977
|
</div>
|
|
978
|
+
<div class="test-conn-row">
|
|
979
|
+
<button class="btn btn-sm btn-ghost" onclick="testModel('embedding')" id="testEmbBtn" data-i18n="settings.test">Test Connection</button>
|
|
980
|
+
<span class="test-result" id="testEmbResult"></span>
|
|
981
|
+
</div>
|
|
967
982
|
</div>
|
|
968
983
|
|
|
969
984
|
<div class="settings-section">
|
|
@@ -971,9 +986,14 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
971
986
|
<div class="settings-grid">
|
|
972
987
|
<div class="settings-field">
|
|
973
988
|
<label data-i18n="settings.provider">Provider</label>
|
|
974
|
-
<select id="cfgSumProvider">
|
|
989
|
+
<select id="cfgSumProvider" onchange="onProviderChange('summarizer')">
|
|
975
990
|
<option value="openai_compatible">OpenAI Compatible</option>
|
|
976
991
|
<option value="openai">OpenAI</option>
|
|
992
|
+
<option value="siliconflow">SiliconFlow (\u7845\u57FA\u6D41\u52A8)</option>
|
|
993
|
+
<option value="zhipu">Zhipu AI (\u667A\u8C31)</option>
|
|
994
|
+
<option value="deepseek">DeepSeek</option>
|
|
995
|
+
<option value="bailian">Alibaba Bailian (\u767E\u70BC)</option>
|
|
996
|
+
<option value="moonshot">Moonshot (Kimi)</option>
|
|
977
997
|
<option value="anthropic">Anthropic</option>
|
|
978
998
|
<option value="gemini">Gemini</option>
|
|
979
999
|
<option value="azure_openai">Azure OpenAI</option>
|
|
@@ -997,6 +1017,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
997
1017
|
<input type="number" id="cfgSumTemp" step="0.1" min="0" max="2" placeholder="0">
|
|
998
1018
|
</div>
|
|
999
1019
|
</div>
|
|
1020
|
+
<div class="test-conn-row">
|
|
1021
|
+
<button class="btn btn-sm btn-ghost" onclick="testModel('summarizer')" id="testSumBtn" data-i18n="settings.test">Test Connection</button>
|
|
1022
|
+
<span class="test-result" id="testSumResult"></span>
|
|
1023
|
+
</div>
|
|
1000
1024
|
</div>
|
|
1001
1025
|
</div>
|
|
1002
1026
|
|
|
@@ -1026,10 +1050,15 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1026
1050
|
<div class="settings-grid">
|
|
1027
1051
|
<div class="settings-field">
|
|
1028
1052
|
<label data-i18n="settings.provider">Provider</label>
|
|
1029
|
-
<select id="cfgSkillProvider">
|
|
1053
|
+
<select id="cfgSkillProvider" onchange="onProviderChange('skill')">
|
|
1030
1054
|
<option value="">— <span data-i18n="settings.skill.usemain">Use main summarizer</span> —</option>
|
|
1031
1055
|
<option value="openai_compatible">OpenAI Compatible</option>
|
|
1032
1056
|
<option value="openai">OpenAI</option>
|
|
1057
|
+
<option value="siliconflow">SiliconFlow (\u7845\u57FA\u6D41\u52A8)</option>
|
|
1058
|
+
<option value="zhipu">Zhipu AI (\u667A\u8C31)</option>
|
|
1059
|
+
<option value="deepseek">DeepSeek</option>
|
|
1060
|
+
<option value="bailian">Alibaba Bailian (\u767E\u70BC)</option>
|
|
1061
|
+
<option value="moonshot">Moonshot (Kimi)</option>
|
|
1033
1062
|
<option value="anthropic">Anthropic</option>
|
|
1034
1063
|
<option value="gemini">Gemini</option>
|
|
1035
1064
|
<option value="azure_openai">Azure OpenAI</option>
|
|
@@ -1049,6 +1078,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1049
1078
|
<input type="password" id="cfgSkillApiKey" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022">
|
|
1050
1079
|
</div>
|
|
1051
1080
|
</div>
|
|
1081
|
+
<div class="test-conn-row">
|
|
1082
|
+
<button class="btn btn-sm btn-ghost" onclick="testModel('skill')" id="testSkillBtn" data-i18n="settings.test">Test Connection</button>
|
|
1083
|
+
<span class="test-result" id="testSkillResult"></span>
|
|
1084
|
+
</div>
|
|
1052
1085
|
</div>
|
|
1053
1086
|
</div>
|
|
1054
1087
|
|
|
@@ -1122,8 +1155,20 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1122
1155
|
<div id="migrateActions" style="display:flex;gap:12px;align-items:center;flex-wrap:wrap">
|
|
1123
1156
|
<button class="btn btn-ghost" onclick="migrateScan()" id="migrateScanBtn" data-i18n="migrate.scan">Scan Data Sources</button>
|
|
1124
1157
|
<button class="btn btn-primary" onclick="migrateStart()" id="migrateStartBtn" style="display:none" data-i18n="migrate.start">Start Import</button>
|
|
1158
|
+
<span id="migrateConcurrencyRow" style="display:none;align-items:center;gap:6px">
|
|
1159
|
+
<span style="font-size:11px;color:var(--text-muted)" data-i18n="migrate.concurrency.label">Concurrent agents</span>
|
|
1160
|
+
<select id="migrateConcurrency" class="filter-select" style="min-width:auto;padding:3px 10px;font-size:11px">
|
|
1161
|
+
<option value="1" selected>1</option>
|
|
1162
|
+
<option value="2">2</option>
|
|
1163
|
+
<option value="4">4</option>
|
|
1164
|
+
<option value="8">8</option>
|
|
1165
|
+
</select>
|
|
1166
|
+
</span>
|
|
1125
1167
|
<span id="migrateStatus" style="font-size:11px;color:var(--text-muted)"></span>
|
|
1126
1168
|
</div>
|
|
1169
|
+
<div id="migrateConcurrencyWarn" style="display:none;margin-top:8px;padding:8px 12px;background:rgba(245,158,11,.06);border:1px solid rgba(245,158,11,.2);border-radius:8px;font-size:11px;color:#f59e0b;line-height:1.5">
|
|
1170
|
+
<span data-i18n="migrate.concurrency.warn">\u26A0 Increasing concurrency raises LLM API call frequency, which may trigger rate limits and cause failures.</span>
|
|
1171
|
+
</div>
|
|
1127
1172
|
|
|
1128
1173
|
<!-- Post-process section: shown after import completes -->
|
|
1129
1174
|
<div id="postprocessSection" style="display:none;margin-top:16px">
|
|
@@ -1146,11 +1191,23 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1146
1191
|
</div>
|
|
1147
1192
|
</label>
|
|
1148
1193
|
</div>
|
|
1149
|
-
<div style="display:flex;gap:10px;align-items:center">
|
|
1194
|
+
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap">
|
|
1150
1195
|
<button class="btn btn-primary" id="ppStartBtn" onclick="ppStart()" data-i18n="pp.start">Start Processing</button>
|
|
1151
1196
|
<button class="btn btn-sm" id="ppStopBtn" onclick="ppStop()" style="display:none;background:rgba(239,68,68,.12);color:#ef4444;border:1px solid rgba(239,68,68,.3);font-size:12px;padding:5px 16px;font-weight:600" data-i18n="migrate.stop">\u25A0 Stop</button>
|
|
1197
|
+
<span style="display:inline-flex;align-items:center;gap:6px">
|
|
1198
|
+
<span style="font-size:11px;color:var(--text-muted)" data-i18n="pp.concurrency.label">Concurrent agents</span>
|
|
1199
|
+
<select id="ppConcurrency" class="filter-select" style="min-width:auto;padding:3px 10px;font-size:11px">
|
|
1200
|
+
<option value="1" selected>1</option>
|
|
1201
|
+
<option value="2">2</option>
|
|
1202
|
+
<option value="4">4</option>
|
|
1203
|
+
<option value="8">8</option>
|
|
1204
|
+
</select>
|
|
1205
|
+
</span>
|
|
1152
1206
|
<span id="ppStatus" style="font-size:11px;color:var(--text-muted)"></span>
|
|
1153
1207
|
</div>
|
|
1208
|
+
<div id="ppConcurrencyWarn" style="display:none;margin-top:8px;padding:8px 12px;background:rgba(245,158,11,.06);border:1px solid rgba(245,158,11,.2);border-radius:8px;font-size:11px;color:#f59e0b;line-height:1.5">
|
|
1209
|
+
<span data-i18n="pp.concurrency.warn">\u26A0 Increasing concurrency raises LLM API call frequency, which may trigger rate limits and cause failures.</span>
|
|
1210
|
+
</div>
|
|
1154
1211
|
<div id="ppProgress" style="display:none;margin-top:12px">
|
|
1155
1212
|
<div style="display:flex;align-items:center;gap:12px;margin-bottom:8px">
|
|
1156
1213
|
<div style="font-size:12px;font-weight:600;color:var(--text)" id="ppPhaseLabel"></div>
|
|
@@ -1437,11 +1494,24 @@ const I18N={
|
|
|
1437
1494
|
'settings.telemetry.hint':'Anonymous usage analytics to help improve the plugin. Only sends tool names, latencies, and version info. No memory content, queries, or personal data is ever sent.',
|
|
1438
1495
|
'settings.viewerport':'Viewer Port',
|
|
1439
1496
|
'settings.viewerport.hint':'Requires restart to take effect',
|
|
1497
|
+
'settings.test':'Test Connection',
|
|
1498
|
+
'settings.test.loading':'Testing...',
|
|
1499
|
+
'settings.test.ok':'Connected',
|
|
1500
|
+
'settings.test.fail':'Failed',
|
|
1440
1501
|
'settings.save':'Save Settings',
|
|
1441
1502
|
'settings.reset':'Reset',
|
|
1442
1503
|
'settings.saved':'Saved',
|
|
1443
1504
|
'settings.restart.hint':'Some changes require restarting the OpenClaw gateway to take effect.',
|
|
1444
1505
|
'settings.save.fail':'Failed to save settings',
|
|
1506
|
+
'settings.save.emb.required':'Embedding model is required. Please configure an embedding model before saving.',
|
|
1507
|
+
'settings.save.emb.fail':'Embedding model test failed, cannot save',
|
|
1508
|
+
'settings.save.sum.fail':'Summarizer model test failed, cannot save',
|
|
1509
|
+
'settings.save.skill.fail':'Skill model test failed, cannot save',
|
|
1510
|
+
'settings.save.sum.fallback':'Summarizer model is not configured — will use OpenClaw native model as fallback.',
|
|
1511
|
+
'settings.save.skill.fallback':'Skill dedicated model is not configured — will use OpenClaw native model as fallback.',
|
|
1512
|
+
'settings.save.fallback.model':'Fallback model: ',
|
|
1513
|
+
'settings.save.fallback.none':'Not available (no OpenClaw native model found)',
|
|
1514
|
+
'settings.save.fallback.confirm':'Continue to save?',
|
|
1445
1515
|
'migrate.title':'Import OpenClaw Memory',
|
|
1446
1516
|
'migrate.desc':'Migrate your existing OpenClaw built-in memories and conversation history into this plugin. The import process uses smart deduplication to avoid duplicates.',
|
|
1447
1517
|
'migrate.modes.title':'Three ways to use:',
|
|
@@ -1455,6 +1525,8 @@ const I18N={
|
|
|
1455
1525
|
'migrate.config.warn.desc':'Please configure both Embedding Model and Summarizer Model above before importing. These are required for processing memories.',
|
|
1456
1526
|
'migrate.sqlite.label':'Memory Index (SQLite)',
|
|
1457
1527
|
'migrate.sessions.label':'Conversation History',
|
|
1528
|
+
'migrate.concurrency.label':'Concurrent agents',
|
|
1529
|
+
'migrate.concurrency.warn':'\u26A0 Increasing concurrency raises LLM API call frequency, which may trigger rate limits and cause failures.',
|
|
1458
1530
|
'migrate.scan':'Scan Data Sources',
|
|
1459
1531
|
'migrate.start':'Start Import',
|
|
1460
1532
|
'migrate.scanning':'Scanning...',
|
|
@@ -1478,6 +1550,8 @@ const I18N={
|
|
|
1478
1550
|
'pp.tasks.hint':'Group imported messages into tasks and generate a structured summary (title, goal, steps, result) for each one. Makes it easier to search and recall past work.',
|
|
1479
1551
|
'pp.skills.label':'Trigger skill evolution',
|
|
1480
1552
|
'pp.skills.hint':'Analyze completed tasks and automatically create or upgrade reusable skills (SKILL.md). Requires task summaries to be enabled. May take longer due to LLM evaluation.',
|
|
1553
|
+
'pp.concurrency.label':'Concurrent agents',
|
|
1554
|
+
'pp.concurrency.warn':'\u26A0 Increasing concurrency raises LLM API call frequency, which may trigger rate limits and cause failures.',
|
|
1481
1555
|
'pp.start':'Start Processing',
|
|
1482
1556
|
'pp.resume':'Resume Processing',
|
|
1483
1557
|
'pp.running':'Processing',
|
|
@@ -1526,7 +1600,25 @@ const I18N={
|
|
|
1526
1600
|
'tasks.role.assistant':'Assistant',
|
|
1527
1601
|
'tasks.error':'Error',
|
|
1528
1602
|
'tasks.error.detail':'Failed to load task details',
|
|
1529
|
-
'tasks.untitled.related':'Untitled'
|
|
1603
|
+
'tasks.untitled.related':'Untitled',
|
|
1604
|
+
'task.edit':'Edit',
|
|
1605
|
+
'task.delete':'Delete',
|
|
1606
|
+
'task.save':'Save',
|
|
1607
|
+
'task.cancel':'Cancel',
|
|
1608
|
+
'task.delete.confirm':'Are you sure you want to delete this task? This cannot be undone.',
|
|
1609
|
+
'task.delete.error':'Failed to delete task: ',
|
|
1610
|
+
'task.save.error':'Failed to save task: ',
|
|
1611
|
+
'task.retrySkill':'Retry Skill Generation',
|
|
1612
|
+
'task.retrySkill.short':'Retry Skill',
|
|
1613
|
+
'task.retrySkill.confirm':'Re-trigger skill generation for this task?',
|
|
1614
|
+
'task.retrySkill.error':'Failed to retry skill generation: ',
|
|
1615
|
+
'skill.edit':'Edit',
|
|
1616
|
+
'skill.delete':'Delete',
|
|
1617
|
+
'skill.save':'Save',
|
|
1618
|
+
'skill.cancel':'Cancel',
|
|
1619
|
+
'skill.delete.confirm':'Are you sure you want to delete this skill? This will also remove all associated files and cannot be undone.',
|
|
1620
|
+
'skill.delete.error':'Failed to delete skill: ',
|
|
1621
|
+
'skill.save.error':'Failed to save skill: '
|
|
1530
1622
|
},
|
|
1531
1623
|
zh:{
|
|
1532
1624
|
'title':'OpenClaw 记忆',
|
|
@@ -1708,11 +1800,24 @@ const I18N={
|
|
|
1708
1800
|
'settings.telemetry.hint':'匿名使用统计,帮助改进插件。仅发送工具名称、响应时间和版本信息,不会发送任何记忆内容、搜索查询或个人数据。',
|
|
1709
1801
|
'settings.viewerport':'Viewer 端口',
|
|
1710
1802
|
'settings.viewerport.hint':'修改后需重启网关生效',
|
|
1803
|
+
'settings.test':'测试连接',
|
|
1804
|
+
'settings.test.loading':'测试中...',
|
|
1805
|
+
'settings.test.ok':'连接成功',
|
|
1806
|
+
'settings.test.fail':'连接失败',
|
|
1711
1807
|
'settings.save':'保存设置',
|
|
1712
1808
|
'settings.reset':'重置',
|
|
1713
1809
|
'settings.saved':'已保存',
|
|
1714
1810
|
'settings.restart.hint':'部分设置修改后需要重启 OpenClaw 网关才能生效。',
|
|
1715
1811
|
'settings.save.fail':'保存设置失败',
|
|
1812
|
+
'settings.save.emb.required':'嵌入模型为必填项,请先配置嵌入模型再保存。',
|
|
1813
|
+
'settings.save.emb.fail':'嵌入模型测试失败,无法保存',
|
|
1814
|
+
'settings.save.sum.fail':'摘要模型测试失败,无法保存',
|
|
1815
|
+
'settings.save.skill.fail':'技能模型测试失败,无法保存',
|
|
1816
|
+
'settings.save.sum.fallback':'摘要模型未配置 — 将使用 OpenClaw 原生模型作为降级方案。',
|
|
1817
|
+
'settings.save.skill.fallback':'技能专用模型未配置 — 将使用 OpenClaw 原生模型作为降级方案。',
|
|
1818
|
+
'settings.save.fallback.model':'降级模型:',
|
|
1819
|
+
'settings.save.fallback.none':'不可用(未检测到 OpenClaw 原生模型)',
|
|
1820
|
+
'settings.save.fallback.confirm':'是否继续保存?',
|
|
1716
1821
|
'migrate.title':'导入 OpenClaw 记忆',
|
|
1717
1822
|
'migrate.desc':'将 OpenClaw 内置的记忆数据和对话历史迁移到本插件中。导入过程使用智能去重,避免重复导入。',
|
|
1718
1823
|
'migrate.modes.title':'三种使用方式:',
|
|
@@ -1726,6 +1831,8 @@ const I18N={
|
|
|
1726
1831
|
'migrate.config.warn.desc':'请先在上方配置好 Embedding 模型和 Summarizer 模型,这两项是处理记忆所必需的。',
|
|
1727
1832
|
'migrate.sqlite.label':'记忆索引 (SQLite)',
|
|
1728
1833
|
'migrate.sessions.label':'对话历史',
|
|
1834
|
+
'migrate.concurrency.label':'并行 Agent 数',
|
|
1835
|
+
'migrate.concurrency.warn':'\u26A0 提高并行数会增加 LLM API 调用频率,可能触发限流而导致失败。',
|
|
1729
1836
|
'migrate.scan':'扫描数据源',
|
|
1730
1837
|
'migrate.start':'开始导入',
|
|
1731
1838
|
'migrate.scanning':'扫描中...',
|
|
@@ -1749,6 +1856,8 @@ const I18N={
|
|
|
1749
1856
|
'pp.tasks.hint':'将导入的消息按任务分组,为每个任务生成结构化摘要(标题、目标、步骤、结果),方便日后搜索和回忆。',
|
|
1750
1857
|
'pp.skills.label':'触发技能进化',
|
|
1751
1858
|
'pp.skills.hint':'分析已完成的任务,自动创建或升级可复用的技能(SKILL.md)。需要先启用任务摘要。由于需要 LLM 评估,耗时较长。',
|
|
1859
|
+
'pp.concurrency.label':'并行 Agent 数',
|
|
1860
|
+
'pp.concurrency.warn':'\u26A0 提高并行数会增加 LLM API 调用频率,可能触发限流而导致失败。',
|
|
1752
1861
|
'pp.start':'开始处理',
|
|
1753
1862
|
'pp.resume':'继续处理',
|
|
1754
1863
|
'pp.running':'正在处理',
|
|
@@ -1797,7 +1906,25 @@ const I18N={
|
|
|
1797
1906
|
'tasks.role.assistant':'助手',
|
|
1798
1907
|
'tasks.error':'出错了',
|
|
1799
1908
|
'tasks.error.detail':'加载任务详情失败',
|
|
1800
|
-
'tasks.untitled.related':'未命名'
|
|
1909
|
+
'tasks.untitled.related':'未命名',
|
|
1910
|
+
'task.edit':'编辑',
|
|
1911
|
+
'task.delete':'删除',
|
|
1912
|
+
'task.save':'保存',
|
|
1913
|
+
'task.cancel':'取消',
|
|
1914
|
+
'task.delete.confirm':'确定要删除此任务吗?此操作不可撤销。',
|
|
1915
|
+
'task.delete.error':'删除任务失败:',
|
|
1916
|
+
'task.save.error':'保存任务失败:',
|
|
1917
|
+
'task.retrySkill':'重新生成技能',
|
|
1918
|
+
'task.retrySkill.short':'重试技能',
|
|
1919
|
+
'task.retrySkill.confirm':'确定要为此任务重新触发技能生成吗?',
|
|
1920
|
+
'task.retrySkill.error':'重新生成技能失败:',
|
|
1921
|
+
'skill.edit':'编辑',
|
|
1922
|
+
'skill.delete':'删除',
|
|
1923
|
+
'skill.save':'保存',
|
|
1924
|
+
'skill.cancel':'取消',
|
|
1925
|
+
'skill.delete.confirm':'确定要删除此技能吗?关联的文件也会被删除,此操作不可撤销。',
|
|
1926
|
+
'skill.delete.error':'删除技能失败:',
|
|
1927
|
+
'skill.save.error':'保存技能失败:'
|
|
1801
1928
|
}
|
|
1802
1929
|
};
|
|
1803
1930
|
const LANG_KEY='memos-viewer-lang';
|
|
@@ -2216,6 +2343,11 @@ async function loadTasks(){
|
|
|
2216
2343
|
'<span class="tag"><span class="icon">\\u{1F4DD}</span> '+task.chunkCount+' '+t('tasks.chunks.label')+'</span>'+
|
|
2217
2344
|
'<span class="tag"><span class="icon">\\u{1F4C2}</span> '+(task.sessionKey||'').slice(0,12)+'</span>'+
|
|
2218
2345
|
'</div>'+
|
|
2346
|
+
'<div class="card-actions" onclick="event.stopPropagation()">'+
|
|
2347
|
+
'<button class="btn btn-sm btn-ghost" onclick="openTaskDetail(\\''+task.id+'\\')">'+t('card.expand')+'</button>'+
|
|
2348
|
+
(task.status==='completed'&&(!task.skillStatus||task.skillStatus==='not_generated'||task.skillStatus==='skipped')?'<button class="btn btn-sm btn-ghost" onclick="retrySkillGen(\\''+task.id+'\\')">'+t('task.retrySkill.short')+'</button>':'')+
|
|
2349
|
+
'<button class="btn btn-sm btn-ghost" style="color:var(--accent)" onclick="deleteTask(\\''+task.id+'\\')">'+t('task.delete')+'</button>'+
|
|
2350
|
+
'</div>'+
|
|
2219
2351
|
'</div>';
|
|
2220
2352
|
}).join('');
|
|
2221
2353
|
|
|
@@ -2240,7 +2372,10 @@ function renderTasksPagination(total){
|
|
|
2240
2372
|
el.innerHTML=html;
|
|
2241
2373
|
}
|
|
2242
2374
|
|
|
2375
|
+
var _currentTaskId=null;
|
|
2376
|
+
var _currentTaskData=null;
|
|
2243
2377
|
async function openTaskDetail(taskId){
|
|
2378
|
+
_currentTaskId=taskId;
|
|
2244
2379
|
const overlay=document.getElementById('taskDetailOverlay');
|
|
2245
2380
|
overlay.classList.add('show');
|
|
2246
2381
|
document.getElementById('taskDetailTitle').textContent=t('tasks.loading');
|
|
@@ -2249,6 +2384,7 @@ async function openTaskDetail(taskId){
|
|
|
2249
2384
|
document.getElementById('taskSkillSection').className='task-skill-section';
|
|
2250
2385
|
document.getElementById('taskDetailSummary').textContent='';
|
|
2251
2386
|
document.getElementById('taskDetailChunks').innerHTML='<div class="spinner"></div>';
|
|
2387
|
+
document.getElementById('taskDetailActions').innerHTML='';
|
|
2252
2388
|
|
|
2253
2389
|
try{
|
|
2254
2390
|
const r=await fetch('/api/task/'+taskId);
|
|
@@ -2266,9 +2402,13 @@ async function openTaskDetail(taskId){
|
|
|
2266
2402
|
meta.push('<div style="width:100%;margin-top:4px"><span class="meta-item" style="width:100%">'+t('tasks.taskid')+'<span class="task-id-full">'+esc(task.id)+'</span></span></div>');
|
|
2267
2403
|
document.getElementById('taskDetailMeta').innerHTML=meta.join('');
|
|
2268
2404
|
|
|
2405
|
+
_currentTaskData=task;
|
|
2406
|
+
|
|
2269
2407
|
// ── Skill status section ──
|
|
2270
2408
|
renderTaskSkillSection(task);
|
|
2271
2409
|
|
|
2410
|
+
document.getElementById('taskDetailActions').innerHTML='';
|
|
2411
|
+
|
|
2272
2412
|
var summaryEl=document.getElementById('taskDetailSummary');
|
|
2273
2413
|
if(task.status==='skipped'){
|
|
2274
2414
|
summaryEl.innerHTML='<div style="color:var(--text-muted);font-style:italic;display:flex;align-items:flex-start;gap:8px"><span style="font-size:18px">\\u26A0\\uFE0F</span><span>'+esc(task.summary||t('tasks.skipped.default'))+'</span></div>';
|
|
@@ -2322,19 +2462,31 @@ function renderTaskSkillSection(task){
|
|
|
2322
2462
|
}else if(ss==='not_generated'){
|
|
2323
2463
|
section.className='task-skill-section status-not_generated';
|
|
2324
2464
|
section.innerHTML='<div class="skill-status-header">\\u274C \u672A\u751F\u6210\u6280\u80FD</div>'+
|
|
2325
|
-
'<div class="skill-status-reason">\u539F\u56E0\uFF1A'+esc(task.skillReason||'\u7ECF LLM \u8BC4\u4F30\uFF0C\u8BE5\u4EFB\u52A1\u4E0D\u9002\u5408\u63D0\u70BC\u4E3A\u53EF\u590D\u7528\u6280\u80FD\u3002')+'</div>'
|
|
2465
|
+
'<div class="skill-status-reason">\u539F\u56E0\uFF1A'+esc(task.skillReason||'\u7ECF LLM \u8BC4\u4F30\uFF0C\u8BE5\u4EFB\u52A1\u4E0D\u9002\u5408\u63D0\u70BC\u4E3A\u53EF\u590D\u7528\u6280\u80FD\u3002')+'</div>'+
|
|
2466
|
+
(task.status==='completed'?'<button class="btn btn-primary" onclick="retrySkillGen(\\''+esc(task.id)+'\\')" style="margin-top:8px;font-size:12px">'+t('task.retrySkill')+'</button>':'');
|
|
2326
2467
|
}else if(ss==='skipped'){
|
|
2327
2468
|
section.className='task-skill-section status-skipped';
|
|
2328
2469
|
section.innerHTML='<div class="skill-status-header">\\u23ED \u8DF3\u8FC7\u6280\u80FD\u8BC4\u4F30</div>'+
|
|
2329
|
-
'<div class="skill-status-reason">\u539F\u56E0\uFF1A'+esc(task.skillReason||'')+'</div>'
|
|
2470
|
+
'<div class="skill-status-reason">\u539F\u56E0\uFF1A'+esc(task.skillReason||'')+'</div>'+
|
|
2471
|
+
(task.status==='completed'?'<button class="btn btn-primary" onclick="retrySkillGen(\\''+esc(task.id)+'\\')" style="margin-top:8px;font-size:12px">'+t('task.retrySkill')+'</button>':'');
|
|
2472
|
+
}else if(ss==='queued'){
|
|
2473
|
+
section.className='task-skill-section status-generating';
|
|
2474
|
+
section.innerHTML='<div class="skill-status-header">\\u{1F4CB} \u6392\u961F\u4E2D</div>'+
|
|
2475
|
+
'<div class="skill-status-reason">'+esc(task.skillReason||'\u7B49\u5F85\u6280\u80FD\u8BC4\u4F30\uFF0C\u524D\u65B9\u4EFB\u52A1\u5904\u7406\u5B8C\u6210\u540E\u81EA\u52A8\u5F00\u59CB\u3002')+'</div>';
|
|
2330
2476
|
}else if(task.status==='active'){
|
|
2331
2477
|
section.className='task-skill-section status-skipped';
|
|
2332
2478
|
section.innerHTML='<div class="skill-status-header">\\u23F8 \u4EFB\u52A1\u8FDB\u884C\u4E2D</div>'+
|
|
2333
2479
|
'<div class="skill-status-reason">\u6280\u80FD\u8BC4\u4F30\u5728\u4EFB\u52A1\u5B8C\u6210\u540E\u81EA\u52A8\u8FD0\u884C\u3002</div>';
|
|
2480
|
+
}else if(task.status==='completed'){
|
|
2481
|
+
section.className='task-skill-section status-generating';
|
|
2482
|
+
section.innerHTML='<div class="skill-status-header">\\u23F3 \u7B49\u5F85\u8BC4\u4F30</div>'+
|
|
2483
|
+
'<div class="skill-status-reason">\u4EFB\u52A1\u5DF2\u5B8C\u6210\uFF0C\u6280\u80FD\u8BC4\u4F30\u5373\u5C06\u5F00\u59CB\u3002</div>'+
|
|
2484
|
+
'<button class="btn btn-primary" onclick="retrySkillGen(\\''+esc(task.id)+'\\')" style="margin-top:8px;font-size:12px">'+t('task.retrySkill')+'</button>';
|
|
2334
2485
|
}else{
|
|
2335
2486
|
section.className='task-skill-section status-skipped';
|
|
2336
2487
|
section.innerHTML='<div class="skill-status-header">\\u2014 \u65E0\u6280\u80FD\u4FE1\u606F</div>'+
|
|
2337
|
-
'<div class="skill-status-reason">\u8BE5\u4EFB\u52A1\
|
|
2488
|
+
'<div class="skill-status-reason">\u8BE5\u4EFB\u52A1\u672A\u8FDB\u884C\u6280\u80FD\u8BC4\u4F30\u3002</div>'+
|
|
2489
|
+
(task.status==='completed'?'<button class="btn btn-primary" onclick="retrySkillGen(\\''+esc(task.id)+'\\')" style="margin-top:8px;font-size:12px">'+t('task.retrySkill')+'</button>':'');
|
|
2338
2490
|
}
|
|
2339
2491
|
}
|
|
2340
2492
|
|
|
@@ -2343,6 +2495,29 @@ function closeTaskDetail(event){
|
|
|
2343
2495
|
document.getElementById('taskDetailOverlay').classList.remove('show');
|
|
2344
2496
|
}
|
|
2345
2497
|
|
|
2498
|
+
async function retrySkillGen(taskId){
|
|
2499
|
+
if(!confirm(t('task.retrySkill.confirm'))) return;
|
|
2500
|
+
try{
|
|
2501
|
+
const r=await fetch('/api/task/'+taskId+'/retry-skill',{method:'POST'});
|
|
2502
|
+
const d=await r.json();
|
|
2503
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
2504
|
+
openTaskDetail(taskId);
|
|
2505
|
+
}catch(e){ alert(t('task.retrySkill.error')+e.message); }
|
|
2506
|
+
}
|
|
2507
|
+
|
|
2508
|
+
async function deleteTask(taskId){
|
|
2509
|
+
if(!confirm(t('task.delete.confirm'))) return;
|
|
2510
|
+
try{
|
|
2511
|
+
const r=await fetch('/api/task/'+taskId,{method:'DELETE'});
|
|
2512
|
+
const d=await r.json();
|
|
2513
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
2514
|
+
closeTaskDetail();
|
|
2515
|
+
document.getElementById('taskDetailOverlay').classList.remove('show');
|
|
2516
|
+
loadTasks();
|
|
2517
|
+
}catch(e){ alert(t('task.delete.error')+e.message); }
|
|
2518
|
+
}
|
|
2519
|
+
|
|
2520
|
+
|
|
2346
2521
|
/* ─── Skills View Logic ─── */
|
|
2347
2522
|
let skillsStatusFilter='';
|
|
2348
2523
|
|
|
@@ -2400,6 +2575,11 @@ async function loadSkills(){
|
|
|
2400
2575
|
'<span class="tag"><span class="icon">\\u{1F4E6}</span> '+skill.sourceType+'</span>'+
|
|
2401
2576
|
(tags.length>0?'<div class="skill-card-tags">'+tags.map(t=>'<span class="skill-tag">'+esc(t)+'</span>').join('')+'</div>':'')+
|
|
2402
2577
|
'</div>'+
|
|
2578
|
+
'<div class="card-actions" onclick="event.stopPropagation()">'+
|
|
2579
|
+
'<button class="btn btn-sm btn-ghost" onclick="openSkillDetail(\\''+skill.id+'\\')">'+t('card.expand')+'</button>'+
|
|
2580
|
+
(skill.visibility==='public'?'<button class="btn btn-sm btn-ghost" onclick="toggleSkillPublic(\\''+skill.id+'\\',false)">\\u{1F512} '+t('skills.setPrivate')+'</button>':'<button class="btn btn-sm btn-ghost" onclick="toggleSkillPublic(\\''+skill.id+'\\',true)">\\u{1F310} '+t('skills.setPublic')+'</button>')+
|
|
2581
|
+
'<button class="btn btn-sm btn-ghost" style="color:var(--accent)" onclick="deleteSkill(\\''+skill.id+'\\')">'+t('skill.delete')+'</button>'+
|
|
2582
|
+
'</div>'+
|
|
2403
2583
|
'</div>';
|
|
2404
2584
|
}).join('');
|
|
2405
2585
|
}catch(e){
|
|
@@ -2424,6 +2604,7 @@ async function openSkillDetail(skillId){
|
|
|
2424
2604
|
document.getElementById('skillDetailContent').innerHTML='<div class="spinner"></div>';
|
|
2425
2605
|
document.getElementById('skillVersionsList').innerHTML='<div class="spinner"></div>';
|
|
2426
2606
|
document.getElementById('skillRelatedTasks').innerHTML='';
|
|
2607
|
+
document.getElementById('skillDetailActions').innerHTML='';
|
|
2427
2608
|
|
|
2428
2609
|
try{
|
|
2429
2610
|
const r=await fetch('/api/skill/'+skillId);
|
|
@@ -2519,6 +2700,9 @@ async function openSkillDetail(skillId){
|
|
|
2519
2700
|
).join('');
|
|
2520
2701
|
}
|
|
2521
2702
|
|
|
2703
|
+
window._currentSkillData=skill;
|
|
2704
|
+
document.getElementById('skillDetailActions').innerHTML='';
|
|
2705
|
+
|
|
2522
2706
|
}catch(e){
|
|
2523
2707
|
document.getElementById('skillDetailTitle').textContent=t('skills.error');
|
|
2524
2708
|
document.getElementById('skillDetailContent').innerHTML='<div style="color:var(--rose);padding:16px">'+t('skills.error.detail')+esc(String(e))+'</div>';
|
|
@@ -2539,11 +2723,23 @@ async function toggleSkillVisibility(){
|
|
|
2539
2723
|
const newVis=btn.dataset.vis==='public'?'private':'public';
|
|
2540
2724
|
try{
|
|
2541
2725
|
const r=await fetch('/api/skill/'+currentSkillId+'/visibility',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify({visibility:newVis})});
|
|
2542
|
-
if(!r.ok) throw new Error('
|
|
2726
|
+
if(!r.ok){var errBody='';try{var ej=await r.json();errBody=ej.error||JSON.stringify(ej);}catch(x){errBody=await r.text();}throw new Error(r.status+': '+errBody);}
|
|
2543
2727
|
openSkillDetail(currentSkillId);
|
|
2544
2728
|
loadSkills();
|
|
2545
2729
|
}catch(e){
|
|
2546
|
-
|
|
2730
|
+
toast('Error: '+e.message,'error');
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2734
|
+
async function toggleSkillPublic(id,setPublic){
|
|
2735
|
+
const newVis=setPublic?'public':'private';
|
|
2736
|
+
try{
|
|
2737
|
+
const r=await fetch('/api/skill/'+id+'/visibility',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify({visibility:newVis})});
|
|
2738
|
+
if(!r.ok){var errBody='';try{var ej=await r.json();errBody=ej.error||JSON.stringify(ej);}catch(x){errBody=await r.text();}throw new Error(r.status+': '+errBody);}
|
|
2739
|
+
toast(setPublic?t('toast.setPublic'):t('toast.setPrivate'),'success');
|
|
2740
|
+
loadSkills();
|
|
2741
|
+
}catch(e){
|
|
2742
|
+
toast('Error: '+e.message,'error');
|
|
2547
2743
|
}
|
|
2548
2744
|
}
|
|
2549
2745
|
|
|
@@ -2587,7 +2783,37 @@ async function loadConfig(){
|
|
|
2587
2783
|
}
|
|
2588
2784
|
}
|
|
2589
2785
|
|
|
2786
|
+
var _providerDefaults={
|
|
2787
|
+
siliconflow:{endpoint:'https://api.siliconflow.cn/v1',embModel:'BAAI/bge-m3',chatModel:'Qwen/Qwen2.5-7B-Instruct'},
|
|
2788
|
+
openai:{endpoint:'https://api.openai.com/v1',embModel:'text-embedding-3-small',chatModel:'gpt-4o-mini'},
|
|
2789
|
+
anthropic:{endpoint:'https://api.anthropic.com/v1/messages',chatModel:'claude-3-haiku-20240307'},
|
|
2790
|
+
cohere:{endpoint:'https://api.cohere.com/v2',embModel:'embed-english-v3.0'},
|
|
2791
|
+
mistral:{endpoint:'https://api.mistral.ai/v1',embModel:'mistral-embed'},
|
|
2792
|
+
voyage:{endpoint:'https://api.voyageai.com/v1',embModel:'voyage-3'},
|
|
2793
|
+
gemini:{endpoint:'',embModel:'text-embedding-004',chatModel:'gemini-2.0-flash'},
|
|
2794
|
+
zhipu:{endpoint:'https://open.bigmodel.cn/api/paas/v4',embModel:'embedding-3',chatModel:'glm-4-flash'},
|
|
2795
|
+
deepseek:{endpoint:'https://api.deepseek.com/v1',chatModel:'deepseek-chat'},
|
|
2796
|
+
bailian:{endpoint:'https://dashscope.aliyuncs.com/compatible-mode/v1',embModel:'text-embedding-v3',chatModel:'qwen-max'},
|
|
2797
|
+
moonshot:{endpoint:'https://api.moonshot.cn/v1',chatModel:'moonshot-v1-8k'}
|
|
2798
|
+
};
|
|
2799
|
+
function onProviderChange(section){
|
|
2800
|
+
var map={embedding:['cfgEmbEndpoint','cfgEmbModel','emb'],summarizer:['cfgSumEndpoint','cfgSumModel','chat'],skill:['cfgSkillEndpoint','cfgSkillModel','chat']};
|
|
2801
|
+
var m=map[section];if(!m)return;
|
|
2802
|
+
var sel=document.getElementById(section==='embedding'?'cfgEmbProvider':section==='summarizer'?'cfgSumProvider':'cfgSkillProvider');
|
|
2803
|
+
var pv=sel.value;
|
|
2804
|
+
var def=_providerDefaults[pv];
|
|
2805
|
+
if(!def)return;
|
|
2806
|
+
var epEl=document.getElementById(m[0]);
|
|
2807
|
+
var mdEl=document.getElementById(m[1]);
|
|
2808
|
+
if(def.endpoint&&!epEl.value.trim()) epEl.value=def.endpoint;
|
|
2809
|
+
if(m[2]==='emb'&&def.embModel&&!mdEl.value.trim()) mdEl.value=def.embModel;
|
|
2810
|
+
if(m[2]==='chat'&&def.chatModel&&!mdEl.value.trim()) mdEl.value=def.chatModel;
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2590
2813
|
async function saveConfig(){
|
|
2814
|
+
var saveBtn=document.querySelector('.settings-actions .btn-primary');
|
|
2815
|
+
saveBtn.disabled=true;saveBtn.textContent=t('settings.test.loading');
|
|
2816
|
+
|
|
2591
2817
|
const cfg={};
|
|
2592
2818
|
const embP=document.getElementById('cfgEmbProvider').value;
|
|
2593
2819
|
if(embP){
|
|
@@ -2597,11 +2823,15 @@ async function saveConfig(){
|
|
|
2597
2823
|
const k=document.getElementById('cfgEmbApiKey').value.trim();if(k) cfg.embedding.apiKey=k;
|
|
2598
2824
|
}
|
|
2599
2825
|
const sumP=document.getElementById('cfgSumProvider').value;
|
|
2600
|
-
|
|
2826
|
+
const sumModel=document.getElementById('cfgSumModel').value.trim();
|
|
2827
|
+
const sumEndpoint=document.getElementById('cfgSumEndpoint').value.trim();
|
|
2828
|
+
const sumApiKey=document.getElementById('cfgSumApiKey').value.trim();
|
|
2829
|
+
var hasSumConfig=!!(sumModel||sumEndpoint||sumApiKey);
|
|
2830
|
+
if(hasSumConfig&&sumP){
|
|
2601
2831
|
cfg.summarizer={provider:sumP};
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2832
|
+
if(sumModel) cfg.summarizer.model=sumModel;
|
|
2833
|
+
if(sumEndpoint) cfg.summarizer.endpoint=sumEndpoint;
|
|
2834
|
+
if(sumApiKey) cfg.summarizer.apiKey=sumApiKey;
|
|
2605
2835
|
const tp=document.getElementById('cfgSumTemp').value.trim();if(tp!=='') cfg.summarizer.temperature=Number(tp);
|
|
2606
2836
|
}
|
|
2607
2837
|
cfg.skillEvolution={
|
|
@@ -2612,29 +2842,118 @@ async function saveConfig(){
|
|
|
2612
2842
|
const mk=document.getElementById('cfgSkillMinChunks').value.trim();if(mk) cfg.skillEvolution.minChunksForEval=Number(mk);
|
|
2613
2843
|
|
|
2614
2844
|
const skP=document.getElementById('cfgSkillProvider').value;
|
|
2615
|
-
|
|
2845
|
+
const skModel=document.getElementById('cfgSkillModel').value.trim();
|
|
2846
|
+
const skEndpoint=document.getElementById('cfgSkillEndpoint').value.trim();
|
|
2847
|
+
const skApiKey=document.getElementById('cfgSkillApiKey').value.trim();
|
|
2848
|
+
var hasSkillConfig=!!(skP&&(skModel||skEndpoint||skApiKey));
|
|
2849
|
+
if(hasSkillConfig){
|
|
2616
2850
|
cfg.skillEvolution.summarizer={provider:skP};
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2851
|
+
if(skModel) cfg.skillEvolution.summarizer.model=skModel;
|
|
2852
|
+
if(skEndpoint) cfg.skillEvolution.summarizer.endpoint=skEndpoint;
|
|
2853
|
+
if(skApiKey) cfg.skillEvolution.summarizer.apiKey=skApiKey;
|
|
2620
2854
|
}
|
|
2621
2855
|
|
|
2622
2856
|
const vp=document.getElementById('cfgViewerPort').value.trim();
|
|
2623
2857
|
if(vp) cfg.viewerPort=Number(vp);
|
|
2858
|
+
cfg.telemetry={enabled:document.getElementById('cfgTelemetryEnabled').checked};
|
|
2624
2859
|
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2860
|
+
function done(){saveBtn.disabled=false;saveBtn.textContent=t('settings.save');}
|
|
2861
|
+
|
|
2862
|
+
// 1) Embedding model is required
|
|
2863
|
+
if(!embP||embP===''){done();toast(t('settings.save.emb.required'),'error');return;}
|
|
2864
|
+
|
|
2865
|
+
// 2) Test embedding
|
|
2866
|
+
try{
|
|
2867
|
+
var er=await fetch('/api/test-model',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({type:'embedding',provider:cfg.embedding.provider,model:cfg.embedding.model||'',endpoint:cfg.embedding.endpoint||'',apiKey:cfg.embedding.apiKey||''})});
|
|
2868
|
+
var ed=await er.json();
|
|
2869
|
+
if(!ed.ok){done();toast(t('settings.save.emb.fail')+': '+ed.error,'error');document.getElementById('testEmbResult').className='test-result fail';document.getElementById('testEmbResult').innerHTML='\\u274C '+ed.error;return;}
|
|
2870
|
+
document.getElementById('testEmbResult').className='test-result ok';document.getElementById('testEmbResult').innerHTML='\\u2705 '+t('settings.test.ok');
|
|
2871
|
+
}catch(e){done();toast(t('settings.save.emb.fail')+': '+e.message,'error');return;}
|
|
2872
|
+
|
|
2873
|
+
// 3) Test summarizer if user filled it
|
|
2874
|
+
if(hasSumConfig&&cfg.summarizer){
|
|
2875
|
+
try{
|
|
2876
|
+
var sr=await fetch('/api/test-model',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({type:'summarizer',provider:cfg.summarizer.provider,model:cfg.summarizer.model||'',endpoint:cfg.summarizer.endpoint||'',apiKey:cfg.summarizer.apiKey||''})});
|
|
2877
|
+
var sd=await sr.json();
|
|
2878
|
+
if(!sd.ok){done();toast(t('settings.save.sum.fail')+': '+sd.error,'error');document.getElementById('testSumResult').className='test-result fail';document.getElementById('testSumResult').innerHTML='\\u274C '+sd.error;return;}
|
|
2879
|
+
document.getElementById('testSumResult').className='test-result ok';document.getElementById('testSumResult').innerHTML='\\u2705 '+t('settings.test.ok');
|
|
2880
|
+
}catch(e){done();toast(t('settings.save.sum.fail')+': '+e.message,'error');return;}
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
// 4) Test skill model if user filled it
|
|
2884
|
+
if(hasSkillConfig&&cfg.skillEvolution.summarizer){
|
|
2885
|
+
try{
|
|
2886
|
+
var kr=await fetch('/api/test-model',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({type:'summarizer',provider:cfg.skillEvolution.summarizer.provider,model:cfg.skillEvolution.summarizer.model||'',endpoint:cfg.skillEvolution.summarizer.endpoint||'',apiKey:cfg.skillEvolution.summarizer.apiKey||''})});
|
|
2887
|
+
var kd=await kr.json();
|
|
2888
|
+
if(!kd.ok){done();toast(t('settings.save.skill.fail')+': '+kd.error,'error');document.getElementById('testSkillResult').className='test-result fail';document.getElementById('testSkillResult').innerHTML='\\u274C '+kd.error;return;}
|
|
2889
|
+
document.getElementById('testSkillResult').className='test-result ok';document.getElementById('testSkillResult').innerHTML='\\u2705 '+t('settings.test.ok');
|
|
2890
|
+
}catch(e){done();toast(t('settings.save.skill.fail')+': '+e.message,'error');return;}
|
|
2891
|
+
}
|
|
2628
2892
|
|
|
2893
|
+
// 5) If summarizer or skill model not configured, check OpenClaw fallback and confirm
|
|
2894
|
+
if(!hasSumConfig||!hasSkillConfig){
|
|
2895
|
+
try{
|
|
2896
|
+
var fr=await fetch('/api/fallback-model');
|
|
2897
|
+
var fb=await fr.json();
|
|
2898
|
+
var msgs=[];
|
|
2899
|
+
if(!hasSumConfig){msgs.push(t('settings.save.sum.fallback'));}
|
|
2900
|
+
if(!hasSkillConfig){msgs.push(t('settings.save.skill.fallback'));}
|
|
2901
|
+
var fbInfo=fb.available?(fb.model+' ('+fb.baseUrl+')'):t('settings.save.fallback.none');
|
|
2902
|
+
var confirmMsg=msgs.join('\\n')+'\\n\\n'+t('settings.save.fallback.model')+fbInfo+'\\n\\n'+t('settings.save.fallback.confirm');
|
|
2903
|
+
if(!confirm(confirmMsg)){done();return;}
|
|
2904
|
+
}catch(e){}
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
// 6) All tests passed, save
|
|
2629
2908
|
try{
|
|
2630
2909
|
const r=await fetch('/api/config',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(cfg)});
|
|
2631
2910
|
if(!r.ok) throw new Error(await r.text());
|
|
2632
2911
|
const el=document.getElementById('settingsSaved');
|
|
2633
2912
|
el.classList.add('show');
|
|
2634
2913
|
setTimeout(()=>el.classList.remove('show'),2500);
|
|
2914
|
+
toast(t('settings.saved'),'success');
|
|
2635
2915
|
}catch(e){
|
|
2636
|
-
|
|
2916
|
+
toast(t('settings.save.fail')+': '+e.message,'error');
|
|
2917
|
+
}finally{done();}
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
async function testModel(type){
|
|
2921
|
+
var ids={embedding:['Emb','cfgEmbProvider','cfgEmbModel','cfgEmbEndpoint','cfgEmbApiKey'],summarizer:['Sum','cfgSumProvider','cfgSumModel','cfgSumEndpoint','cfgSumApiKey'],skill:['Skill','cfgSkillProvider','cfgSkillModel','cfgSkillEndpoint','cfgSkillApiKey']};
|
|
2922
|
+
var c=ids[type];if(!c)return;
|
|
2923
|
+
var resultEl=document.getElementById('test'+c[0]+'Result');
|
|
2924
|
+
var btn=document.getElementById('test'+c[0]+'Btn');
|
|
2925
|
+
var provider=document.getElementById(c[1]).value;
|
|
2926
|
+
var model=document.getElementById(c[2]).value.trim();
|
|
2927
|
+
var endpoint=document.getElementById(c[3]).value.trim();
|
|
2928
|
+
var apiKey=document.getElementById(c[4]).value.trim();
|
|
2929
|
+
if(!provider||(provider!=='local'&&!model)){
|
|
2930
|
+
resultEl.className='test-result fail';
|
|
2931
|
+
resultEl.innerHTML='\\u274C '+t('settings.test.fail')+'<div style="margin-top:4px;font-size:11px;color:var(--text-muted)">Provider and Model are required</div>';
|
|
2932
|
+
return;
|
|
2933
|
+
}
|
|
2934
|
+
if(provider!=='local'&&!apiKey){
|
|
2935
|
+
resultEl.className='test-result fail';
|
|
2936
|
+
resultEl.innerHTML='\\u274C '+t('settings.test.fail')+'<div style="margin-top:4px;font-size:11px;color:var(--text-muted)">API Key is required</div>';
|
|
2937
|
+
return;
|
|
2637
2938
|
}
|
|
2939
|
+
resultEl.className='test-result loading';resultEl.textContent=t('settings.test.loading');
|
|
2940
|
+
btn.disabled=true;
|
|
2941
|
+
try{
|
|
2942
|
+
var body={type:type,provider:provider,model:model,endpoint:endpoint,apiKey:apiKey};
|
|
2943
|
+
var r=await fetch('/api/test-model',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});
|
|
2944
|
+
var d=await r.json();
|
|
2945
|
+
if(d.ok){
|
|
2946
|
+
resultEl.className='test-result ok';
|
|
2947
|
+
resultEl.innerHTML='\\u2705 '+t('settings.test.ok')+'<div style="margin-top:4px;font-size:11px;color:var(--text-muted)">'+esc(d.detail||'')+'</div>';
|
|
2948
|
+
}else{
|
|
2949
|
+
var errMsg=d.error||'Unknown error';
|
|
2950
|
+
resultEl.className='test-result fail';
|
|
2951
|
+
resultEl.innerHTML='\\u274C '+t('settings.test.fail')+'<div style="margin-top:6px;font-size:11px;padding:8px 10px;background:rgba(239,68,68,.06);border:1px solid rgba(239,68,68,.15);border-radius:6px;white-space:pre-wrap;word-break:break-all;max-height:120px;overflow-y:auto;font-family:SF Mono,Monaco,Consolas,monospace">'+esc(errMsg)+'</div>';
|
|
2952
|
+
}
|
|
2953
|
+
}catch(e){
|
|
2954
|
+
resultEl.className='test-result fail';
|
|
2955
|
+
resultEl.innerHTML='\\u274C '+t('settings.test.fail')+'<div style="margin-top:6px;font-size:11px;padding:8px 10px;background:rgba(239,68,68,.06);border:1px solid rgba(239,68,68,.15);border-radius:6px;white-space:pre-wrap;word-break:break-all">'+esc(e.message)+'</div>';
|
|
2956
|
+
}finally{btn.disabled=false;}
|
|
2638
2957
|
}
|
|
2639
2958
|
|
|
2640
2959
|
function renderSkillMarkdown(md){
|
|
@@ -2668,6 +2987,19 @@ function closeSkillDetail(event){
|
|
|
2668
2987
|
document.getElementById('skillDetailOverlay').classList.remove('show');
|
|
2669
2988
|
}
|
|
2670
2989
|
|
|
2990
|
+
async function deleteSkill(skillId){
|
|
2991
|
+
if(!confirm(t('skill.delete.confirm'))) return;
|
|
2992
|
+
try{
|
|
2993
|
+
const r=await fetch('/api/skill/'+skillId,{method:'DELETE'});
|
|
2994
|
+
const d=await r.json();
|
|
2995
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
2996
|
+
closeSkillDetail();
|
|
2997
|
+
document.getElementById('skillDetailOverlay').classList.remove('show');
|
|
2998
|
+
loadSkills();
|
|
2999
|
+
}catch(e){ alert(t('skill.delete.error')+e.message); }
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
|
|
2671
3003
|
function formatDuration(ms){
|
|
2672
3004
|
const s=Math.floor(ms/1000);
|
|
2673
3005
|
if(s<60) return s+'s';
|
|
@@ -3371,6 +3703,19 @@ async function clearAll(){
|
|
|
3371
3703
|
let migrateScanData=null;
|
|
3372
3704
|
let migrateStats={stored:0,skipped:0,merged:0,errors:0};
|
|
3373
3705
|
|
|
3706
|
+
(function(){
|
|
3707
|
+
const sel=document.getElementById('migrateConcurrency');
|
|
3708
|
+
if(sel) sel.addEventListener('change',function(){
|
|
3709
|
+
const w=document.getElementById('migrateConcurrencyWarn');
|
|
3710
|
+
if(w) w.style.display=parseInt(this.value,10)>1?'block':'none';
|
|
3711
|
+
});
|
|
3712
|
+
const ppSel=document.getElementById('ppConcurrency');
|
|
3713
|
+
if(ppSel) ppSel.addEventListener('change',function(){
|
|
3714
|
+
const w=document.getElementById('ppConcurrencyWarn');
|
|
3715
|
+
if(w) w.style.display=parseInt(this.value,10)>1?'block':'none';
|
|
3716
|
+
});
|
|
3717
|
+
})();
|
|
3718
|
+
|
|
3374
3719
|
async function migrateScan(){
|
|
3375
3720
|
const btn=document.getElementById('migrateScanBtn');
|
|
3376
3721
|
btn.disabled=true;
|
|
@@ -3406,6 +3751,7 @@ async function migrateScan(){
|
|
|
3406
3751
|
|
|
3407
3752
|
if(d.totalItems>0 && d.configReady){
|
|
3408
3753
|
document.getElementById('migrateStartBtn').style.display='inline-flex';
|
|
3754
|
+
document.getElementById('migrateConcurrencyRow').style.display='inline-flex';
|
|
3409
3755
|
}
|
|
3410
3756
|
|
|
3411
3757
|
if(d.totalItems===0){
|
|
@@ -3427,10 +3773,15 @@ function migrateStart(){
|
|
|
3427
3773
|
if(!migrateScanData||!migrateScanData.configReady)return;
|
|
3428
3774
|
if(!confirm(t('migrate.start')+'?'))return;
|
|
3429
3775
|
|
|
3776
|
+
const concSel=document.getElementById('migrateConcurrency');
|
|
3777
|
+
const concurrency=concSel?parseInt(concSel.value,10)||1:1;
|
|
3778
|
+
|
|
3430
3779
|
window._migrateRunning=true;
|
|
3431
3780
|
_migrateStatusChecked=false;
|
|
3432
3781
|
document.getElementById('migrateStartBtn').style.display='none';
|
|
3433
3782
|
document.getElementById('migrateScanBtn').disabled=true;
|
|
3783
|
+
document.getElementById('migrateConcurrencyRow').style.display='none';
|
|
3784
|
+
document.getElementById('migrateConcurrencyWarn').style.display='none';
|
|
3434
3785
|
document.getElementById('migrateProgress').style.display='block';
|
|
3435
3786
|
document.getElementById('migrateLiveLog').innerHTML='';
|
|
3436
3787
|
migrateStats={stored:0,skipped:0,merged:0,errors:0};
|
|
@@ -3440,7 +3791,7 @@ function migrateStart(){
|
|
|
3440
3791
|
document.getElementById('migrateBar').style.width='0%';
|
|
3441
3792
|
document.getElementById('migrateBar').style.background='linear-gradient(90deg,#6366f1,#8b5cf6)';
|
|
3442
3793
|
document.getElementById('migrateCounter').textContent='';
|
|
3443
|
-
const body=JSON.stringify({sources:['sqlite','sessions']});
|
|
3794
|
+
const body=JSON.stringify({sources:['sqlite','sessions'],concurrency});
|
|
3444
3795
|
connectMigrateSSE('/api/migrate/start','POST',body);
|
|
3445
3796
|
}
|
|
3446
3797
|
|
|
@@ -3645,6 +3996,9 @@ function ppStart(){
|
|
|
3645
3996
|
var enableSkills=document.getElementById('ppEnableSkills').checked;
|
|
3646
3997
|
if(!enableTasks&&!enableSkills){toast(t('pp.select.warn'),'error');return;}
|
|
3647
3998
|
|
|
3999
|
+
var ppConcSel=document.getElementById('ppConcurrency');
|
|
4000
|
+
var ppConcurrency=ppConcSel?parseInt(ppConcSel.value,10)||1:1;
|
|
4001
|
+
|
|
3648
4002
|
window._ppRunning=true;
|
|
3649
4003
|
_ppSSEConnected=false;
|
|
3650
4004
|
ppStats={tasks:0,skills:0,errors:0,skipped:0};
|
|
@@ -3661,7 +4015,7 @@ function ppStart(){
|
|
|
3661
4015
|
document.getElementById('ppLiveLog').innerHTML='';
|
|
3662
4016
|
updatePPStats();
|
|
3663
4017
|
|
|
3664
|
-
var body=JSON.stringify({enableTasks:enableTasks,enableSkills:enableSkills});
|
|
4018
|
+
var body=JSON.stringify({enableTasks:enableTasks,enableSkills:enableSkills,concurrency:ppConcurrency});
|
|
3665
4019
|
fetch('/api/migrate/postprocess',{method:'POST',headers:{'Content-Type':'application/json'},body:body})
|
|
3666
4020
|
.then(function(r){
|
|
3667
4021
|
if(!r.ok){
|