@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/src/viewer/html.ts
CHANGED
|
@@ -414,7 +414,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
414
414
|
|
|
415
415
|
/* ─── Analytics / 统计 ─── */
|
|
416
416
|
.nav-tabs{display:flex;align-items:center;gap:2px;background:rgba(255,255,255,.06);border-radius:10px;padding:3px}
|
|
417
|
-
.nav-tabs .tab{padding:6px 20px;border-radius:8px;font-size:13px;font-weight:600;color:var(--text-sec);background:transparent;border:1px solid
|
|
417
|
+
.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}
|
|
418
418
|
.nav-tabs .tab:hover{color:var(--text)}
|
|
419
419
|
.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)}
|
|
420
420
|
[data-theme="light"] .nav-tabs{background:rgba(0,0,0,.05)}
|
|
@@ -512,6 +512,12 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
512
512
|
.toggle-slider::before{content:'';position:absolute;height:14px;width:14px;left:3px;bottom:3px;background:#fff;border-radius:50%;transition:.2s}
|
|
513
513
|
.toggle-switch input:checked+.toggle-slider{background:var(--pri)}
|
|
514
514
|
.toggle-switch input:checked+.toggle-slider::before{transform:translateX(16px)}
|
|
515
|
+
.test-conn-row{display:flex;align-items:center;gap:10px;margin-top:12px;padding-top:10px;border-top:1px dashed var(--border)}
|
|
516
|
+
.test-conn-row .btn{font-size:11px;padding:5px 14px;border:1px solid var(--border);border-radius:6px}
|
|
517
|
+
.test-result{font-size:12px;line-height:1.5;word-break:break-word}
|
|
518
|
+
.test-result.ok{color:#22c55e}
|
|
519
|
+
.test-result.fail{color:var(--rose)}
|
|
520
|
+
.test-result.loading{color:var(--text-muted)}
|
|
515
521
|
.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)}
|
|
516
522
|
.settings-actions .btn{min-width:110px;padding:10px 20px;font-size:13px}
|
|
517
523
|
.settings-actions .btn-primary{background:rgba(99,102,241,.08);color:var(--pri);border:1px solid rgba(99,102,241,.25);font-weight:600}
|
|
@@ -816,6 +822,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
816
822
|
<div class="task-detail-summary" id="taskDetailSummary"></div>
|
|
817
823
|
<div class="task-detail-chunks-title" data-i18n="tasks.chunks">Related Memories</div>
|
|
818
824
|
<div class="task-detail-chunks" id="taskDetailChunks"></div>
|
|
825
|
+
<div id="taskDetailActions" style="display:flex;gap:8px;margin-top:16px;padding-top:12px;border-top:1px solid var(--border)"></div>
|
|
819
826
|
</div>
|
|
820
827
|
</div>
|
|
821
828
|
</div>
|
|
@@ -864,6 +871,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
864
871
|
<div class="task-detail-chunks" id="skillVersionsList" style="gap:10px"></div>
|
|
865
872
|
<div class="task-detail-chunks-title" style="margin-top:16px" data-i18n="skills.related">Related Tasks</div>
|
|
866
873
|
<div class="task-detail-chunks" id="skillRelatedTasks" style="gap:8px"></div>
|
|
874
|
+
<div id="skillDetailActions" style="display:flex;gap:8px;margin-top:16px;padding-top:12px;border-top:1px solid var(--border)"></div>
|
|
867
875
|
</div>
|
|
868
876
|
</div>
|
|
869
877
|
<div class="analytics-view" id="analyticsView">
|
|
@@ -937,9 +945,12 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
937
945
|
<div class="settings-grid">
|
|
938
946
|
<div class="settings-field">
|
|
939
947
|
<label data-i18n="settings.provider">Provider</label>
|
|
940
|
-
<select id="cfgEmbProvider">
|
|
948
|
+
<select id="cfgEmbProvider" onchange="onProviderChange('embedding')">
|
|
941
949
|
<option value="openai_compatible">OpenAI Compatible</option>
|
|
942
950
|
<option value="openai">OpenAI</option>
|
|
951
|
+
<option value="siliconflow">SiliconFlow (\u7845\u57FA\u6D41\u52A8)</option>
|
|
952
|
+
<option value="zhipu">Zhipu AI (\u667A\u8C31)</option>
|
|
953
|
+
<option value="bailian">Alibaba Bailian (\u767E\u70BC)</option>
|
|
943
954
|
<option value="gemini">Gemini</option>
|
|
944
955
|
<option value="azure_openai">Azure OpenAI</option>
|
|
945
956
|
<option value="cohere">Cohere</option>
|
|
@@ -961,6 +972,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
961
972
|
<input type="password" id="cfgEmbApiKey" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022">
|
|
962
973
|
</div>
|
|
963
974
|
</div>
|
|
975
|
+
<div class="test-conn-row">
|
|
976
|
+
<button class="btn btn-sm btn-ghost" onclick="testModel('embedding')" id="testEmbBtn" data-i18n="settings.test">Test Connection</button>
|
|
977
|
+
<span class="test-result" id="testEmbResult"></span>
|
|
978
|
+
</div>
|
|
964
979
|
</div>
|
|
965
980
|
|
|
966
981
|
<div class="settings-section">
|
|
@@ -968,9 +983,14 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
968
983
|
<div class="settings-grid">
|
|
969
984
|
<div class="settings-field">
|
|
970
985
|
<label data-i18n="settings.provider">Provider</label>
|
|
971
|
-
<select id="cfgSumProvider">
|
|
986
|
+
<select id="cfgSumProvider" onchange="onProviderChange('summarizer')">
|
|
972
987
|
<option value="openai_compatible">OpenAI Compatible</option>
|
|
973
988
|
<option value="openai">OpenAI</option>
|
|
989
|
+
<option value="siliconflow">SiliconFlow (\u7845\u57FA\u6D41\u52A8)</option>
|
|
990
|
+
<option value="zhipu">Zhipu AI (\u667A\u8C31)</option>
|
|
991
|
+
<option value="deepseek">DeepSeek</option>
|
|
992
|
+
<option value="bailian">Alibaba Bailian (\u767E\u70BC)</option>
|
|
993
|
+
<option value="moonshot">Moonshot (Kimi)</option>
|
|
974
994
|
<option value="anthropic">Anthropic</option>
|
|
975
995
|
<option value="gemini">Gemini</option>
|
|
976
996
|
<option value="azure_openai">Azure OpenAI</option>
|
|
@@ -994,6 +1014,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
994
1014
|
<input type="number" id="cfgSumTemp" step="0.1" min="0" max="2" placeholder="0">
|
|
995
1015
|
</div>
|
|
996
1016
|
</div>
|
|
1017
|
+
<div class="test-conn-row">
|
|
1018
|
+
<button class="btn btn-sm btn-ghost" onclick="testModel('summarizer')" id="testSumBtn" data-i18n="settings.test">Test Connection</button>
|
|
1019
|
+
<span class="test-result" id="testSumResult"></span>
|
|
1020
|
+
</div>
|
|
997
1021
|
</div>
|
|
998
1022
|
</div>
|
|
999
1023
|
|
|
@@ -1023,10 +1047,15 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1023
1047
|
<div class="settings-grid">
|
|
1024
1048
|
<div class="settings-field">
|
|
1025
1049
|
<label data-i18n="settings.provider">Provider</label>
|
|
1026
|
-
<select id="cfgSkillProvider">
|
|
1050
|
+
<select id="cfgSkillProvider" onchange="onProviderChange('skill')">
|
|
1027
1051
|
<option value="">— <span data-i18n="settings.skill.usemain">Use main summarizer</span> —</option>
|
|
1028
1052
|
<option value="openai_compatible">OpenAI Compatible</option>
|
|
1029
1053
|
<option value="openai">OpenAI</option>
|
|
1054
|
+
<option value="siliconflow">SiliconFlow (\u7845\u57FA\u6D41\u52A8)</option>
|
|
1055
|
+
<option value="zhipu">Zhipu AI (\u667A\u8C31)</option>
|
|
1056
|
+
<option value="deepseek">DeepSeek</option>
|
|
1057
|
+
<option value="bailian">Alibaba Bailian (\u767E\u70BC)</option>
|
|
1058
|
+
<option value="moonshot">Moonshot (Kimi)</option>
|
|
1030
1059
|
<option value="anthropic">Anthropic</option>
|
|
1031
1060
|
<option value="gemini">Gemini</option>
|
|
1032
1061
|
<option value="azure_openai">Azure OpenAI</option>
|
|
@@ -1046,6 +1075,10 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1046
1075
|
<input type="password" id="cfgSkillApiKey" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022">
|
|
1047
1076
|
</div>
|
|
1048
1077
|
</div>
|
|
1078
|
+
<div class="test-conn-row">
|
|
1079
|
+
<button class="btn btn-sm btn-ghost" onclick="testModel('skill')" id="testSkillBtn" data-i18n="settings.test">Test Connection</button>
|
|
1080
|
+
<span class="test-result" id="testSkillResult"></span>
|
|
1081
|
+
</div>
|
|
1049
1082
|
</div>
|
|
1050
1083
|
</div>
|
|
1051
1084
|
|
|
@@ -1119,8 +1152,20 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1119
1152
|
<div id="migrateActions" style="display:flex;gap:12px;align-items:center;flex-wrap:wrap">
|
|
1120
1153
|
<button class="btn btn-ghost" onclick="migrateScan()" id="migrateScanBtn" data-i18n="migrate.scan">Scan Data Sources</button>
|
|
1121
1154
|
<button class="btn btn-primary" onclick="migrateStart()" id="migrateStartBtn" style="display:none" data-i18n="migrate.start">Start Import</button>
|
|
1155
|
+
<span id="migrateConcurrencyRow" style="display:none;align-items:center;gap:6px">
|
|
1156
|
+
<span style="font-size:11px;color:var(--text-muted)" data-i18n="migrate.concurrency.label">Concurrent agents</span>
|
|
1157
|
+
<select id="migrateConcurrency" class="filter-select" style="min-width:auto;padding:3px 10px;font-size:11px">
|
|
1158
|
+
<option value="1" selected>1</option>
|
|
1159
|
+
<option value="2">2</option>
|
|
1160
|
+
<option value="4">4</option>
|
|
1161
|
+
<option value="8">8</option>
|
|
1162
|
+
</select>
|
|
1163
|
+
</span>
|
|
1122
1164
|
<span id="migrateStatus" style="font-size:11px;color:var(--text-muted)"></span>
|
|
1123
1165
|
</div>
|
|
1166
|
+
<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">
|
|
1167
|
+
<span data-i18n="migrate.concurrency.warn">\u26A0 Increasing concurrency raises LLM API call frequency, which may trigger rate limits and cause failures.</span>
|
|
1168
|
+
</div>
|
|
1124
1169
|
|
|
1125
1170
|
<!-- Post-process section: shown after import completes -->
|
|
1126
1171
|
<div id="postprocessSection" style="display:none;margin-top:16px">
|
|
@@ -1143,11 +1188,23 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1143
1188
|
</div>
|
|
1144
1189
|
</label>
|
|
1145
1190
|
</div>
|
|
1146
|
-
<div style="display:flex;gap:10px;align-items:center">
|
|
1191
|
+
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap">
|
|
1147
1192
|
<button class="btn btn-primary" id="ppStartBtn" onclick="ppStart()" data-i18n="pp.start">Start Processing</button>
|
|
1148
1193
|
<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>
|
|
1194
|
+
<span style="display:inline-flex;align-items:center;gap:6px">
|
|
1195
|
+
<span style="font-size:11px;color:var(--text-muted)" data-i18n="pp.concurrency.label">Concurrent agents</span>
|
|
1196
|
+
<select id="ppConcurrency" class="filter-select" style="min-width:auto;padding:3px 10px;font-size:11px">
|
|
1197
|
+
<option value="1" selected>1</option>
|
|
1198
|
+
<option value="2">2</option>
|
|
1199
|
+
<option value="4">4</option>
|
|
1200
|
+
<option value="8">8</option>
|
|
1201
|
+
</select>
|
|
1202
|
+
</span>
|
|
1149
1203
|
<span id="ppStatus" style="font-size:11px;color:var(--text-muted)"></span>
|
|
1150
1204
|
</div>
|
|
1205
|
+
<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">
|
|
1206
|
+
<span data-i18n="pp.concurrency.warn">\u26A0 Increasing concurrency raises LLM API call frequency, which may trigger rate limits and cause failures.</span>
|
|
1207
|
+
</div>
|
|
1151
1208
|
<div id="ppProgress" style="display:none;margin-top:12px">
|
|
1152
1209
|
<div style="display:flex;align-items:center;gap:12px;margin-bottom:8px">
|
|
1153
1210
|
<div style="font-size:12px;font-weight:600;color:var(--text)" id="ppPhaseLabel"></div>
|
|
@@ -1434,11 +1491,24 @@ const I18N={
|
|
|
1434
1491
|
'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.',
|
|
1435
1492
|
'settings.viewerport':'Viewer Port',
|
|
1436
1493
|
'settings.viewerport.hint':'Requires restart to take effect',
|
|
1494
|
+
'settings.test':'Test Connection',
|
|
1495
|
+
'settings.test.loading':'Testing...',
|
|
1496
|
+
'settings.test.ok':'Connected',
|
|
1497
|
+
'settings.test.fail':'Failed',
|
|
1437
1498
|
'settings.save':'Save Settings',
|
|
1438
1499
|
'settings.reset':'Reset',
|
|
1439
1500
|
'settings.saved':'Saved',
|
|
1440
1501
|
'settings.restart.hint':'Some changes require restarting the OpenClaw gateway to take effect.',
|
|
1441
1502
|
'settings.save.fail':'Failed to save settings',
|
|
1503
|
+
'settings.save.emb.required':'Embedding model is required. Please configure an embedding model before saving.',
|
|
1504
|
+
'settings.save.emb.fail':'Embedding model test failed, cannot save',
|
|
1505
|
+
'settings.save.sum.fail':'Summarizer model test failed, cannot save',
|
|
1506
|
+
'settings.save.skill.fail':'Skill model test failed, cannot save',
|
|
1507
|
+
'settings.save.sum.fallback':'Summarizer model is not configured — will use OpenClaw native model as fallback.',
|
|
1508
|
+
'settings.save.skill.fallback':'Skill dedicated model is not configured — will use OpenClaw native model as fallback.',
|
|
1509
|
+
'settings.save.fallback.model':'Fallback model: ',
|
|
1510
|
+
'settings.save.fallback.none':'Not available (no OpenClaw native model found)',
|
|
1511
|
+
'settings.save.fallback.confirm':'Continue to save?',
|
|
1442
1512
|
'migrate.title':'Import OpenClaw Memory',
|
|
1443
1513
|
'migrate.desc':'Migrate your existing OpenClaw built-in memories and conversation history into this plugin. The import process uses smart deduplication to avoid duplicates.',
|
|
1444
1514
|
'migrate.modes.title':'Three ways to use:',
|
|
@@ -1452,6 +1522,8 @@ const I18N={
|
|
|
1452
1522
|
'migrate.config.warn.desc':'Please configure both Embedding Model and Summarizer Model above before importing. These are required for processing memories.',
|
|
1453
1523
|
'migrate.sqlite.label':'Memory Index (SQLite)',
|
|
1454
1524
|
'migrate.sessions.label':'Conversation History',
|
|
1525
|
+
'migrate.concurrency.label':'Concurrent agents',
|
|
1526
|
+
'migrate.concurrency.warn':'\u26A0 Increasing concurrency raises LLM API call frequency, which may trigger rate limits and cause failures.',
|
|
1455
1527
|
'migrate.scan':'Scan Data Sources',
|
|
1456
1528
|
'migrate.start':'Start Import',
|
|
1457
1529
|
'migrate.scanning':'Scanning...',
|
|
@@ -1475,6 +1547,8 @@ const I18N={
|
|
|
1475
1547
|
'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.',
|
|
1476
1548
|
'pp.skills.label':'Trigger skill evolution',
|
|
1477
1549
|
'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.',
|
|
1550
|
+
'pp.concurrency.label':'Concurrent agents',
|
|
1551
|
+
'pp.concurrency.warn':'\u26A0 Increasing concurrency raises LLM API call frequency, which may trigger rate limits and cause failures.',
|
|
1478
1552
|
'pp.start':'Start Processing',
|
|
1479
1553
|
'pp.resume':'Resume Processing',
|
|
1480
1554
|
'pp.running':'Processing',
|
|
@@ -1523,7 +1597,25 @@ const I18N={
|
|
|
1523
1597
|
'tasks.role.assistant':'Assistant',
|
|
1524
1598
|
'tasks.error':'Error',
|
|
1525
1599
|
'tasks.error.detail':'Failed to load task details',
|
|
1526
|
-
'tasks.untitled.related':'Untitled'
|
|
1600
|
+
'tasks.untitled.related':'Untitled',
|
|
1601
|
+
'task.edit':'Edit',
|
|
1602
|
+
'task.delete':'Delete',
|
|
1603
|
+
'task.save':'Save',
|
|
1604
|
+
'task.cancel':'Cancel',
|
|
1605
|
+
'task.delete.confirm':'Are you sure you want to delete this task? This cannot be undone.',
|
|
1606
|
+
'task.delete.error':'Failed to delete task: ',
|
|
1607
|
+
'task.save.error':'Failed to save task: ',
|
|
1608
|
+
'task.retrySkill':'Retry Skill Generation',
|
|
1609
|
+
'task.retrySkill.short':'Retry Skill',
|
|
1610
|
+
'task.retrySkill.confirm':'Re-trigger skill generation for this task?',
|
|
1611
|
+
'task.retrySkill.error':'Failed to retry skill generation: ',
|
|
1612
|
+
'skill.edit':'Edit',
|
|
1613
|
+
'skill.delete':'Delete',
|
|
1614
|
+
'skill.save':'Save',
|
|
1615
|
+
'skill.cancel':'Cancel',
|
|
1616
|
+
'skill.delete.confirm':'Are you sure you want to delete this skill? This will also remove all associated files and cannot be undone.',
|
|
1617
|
+
'skill.delete.error':'Failed to delete skill: ',
|
|
1618
|
+
'skill.save.error':'Failed to save skill: '
|
|
1527
1619
|
},
|
|
1528
1620
|
zh:{
|
|
1529
1621
|
'title':'OpenClaw 记忆',
|
|
@@ -1705,11 +1797,24 @@ const I18N={
|
|
|
1705
1797
|
'settings.telemetry.hint':'匿名使用统计,帮助改进插件。仅发送工具名称、响应时间和版本信息,不会发送任何记忆内容、搜索查询或个人数据。',
|
|
1706
1798
|
'settings.viewerport':'Viewer 端口',
|
|
1707
1799
|
'settings.viewerport.hint':'修改后需重启网关生效',
|
|
1800
|
+
'settings.test':'测试连接',
|
|
1801
|
+
'settings.test.loading':'测试中...',
|
|
1802
|
+
'settings.test.ok':'连接成功',
|
|
1803
|
+
'settings.test.fail':'连接失败',
|
|
1708
1804
|
'settings.save':'保存设置',
|
|
1709
1805
|
'settings.reset':'重置',
|
|
1710
1806
|
'settings.saved':'已保存',
|
|
1711
1807
|
'settings.restart.hint':'部分设置修改后需要重启 OpenClaw 网关才能生效。',
|
|
1712
1808
|
'settings.save.fail':'保存设置失败',
|
|
1809
|
+
'settings.save.emb.required':'嵌入模型为必填项,请先配置嵌入模型再保存。',
|
|
1810
|
+
'settings.save.emb.fail':'嵌入模型测试失败,无法保存',
|
|
1811
|
+
'settings.save.sum.fail':'摘要模型测试失败,无法保存',
|
|
1812
|
+
'settings.save.skill.fail':'技能模型测试失败,无法保存',
|
|
1813
|
+
'settings.save.sum.fallback':'摘要模型未配置 — 将使用 OpenClaw 原生模型作为降级方案。',
|
|
1814
|
+
'settings.save.skill.fallback':'技能专用模型未配置 — 将使用 OpenClaw 原生模型作为降级方案。',
|
|
1815
|
+
'settings.save.fallback.model':'降级模型:',
|
|
1816
|
+
'settings.save.fallback.none':'不可用(未检测到 OpenClaw 原生模型)',
|
|
1817
|
+
'settings.save.fallback.confirm':'是否继续保存?',
|
|
1713
1818
|
'migrate.title':'导入 OpenClaw 记忆',
|
|
1714
1819
|
'migrate.desc':'将 OpenClaw 内置的记忆数据和对话历史迁移到本插件中。导入过程使用智能去重,避免重复导入。',
|
|
1715
1820
|
'migrate.modes.title':'三种使用方式:',
|
|
@@ -1723,6 +1828,8 @@ const I18N={
|
|
|
1723
1828
|
'migrate.config.warn.desc':'请先在上方配置好 Embedding 模型和 Summarizer 模型,这两项是处理记忆所必需的。',
|
|
1724
1829
|
'migrate.sqlite.label':'记忆索引 (SQLite)',
|
|
1725
1830
|
'migrate.sessions.label':'对话历史',
|
|
1831
|
+
'migrate.concurrency.label':'并行 Agent 数',
|
|
1832
|
+
'migrate.concurrency.warn':'\u26A0 提高并行数会增加 LLM API 调用频率,可能触发限流而导致失败。',
|
|
1726
1833
|
'migrate.scan':'扫描数据源',
|
|
1727
1834
|
'migrate.start':'开始导入',
|
|
1728
1835
|
'migrate.scanning':'扫描中...',
|
|
@@ -1746,6 +1853,8 @@ const I18N={
|
|
|
1746
1853
|
'pp.tasks.hint':'将导入的消息按任务分组,为每个任务生成结构化摘要(标题、目标、步骤、结果),方便日后搜索和回忆。',
|
|
1747
1854
|
'pp.skills.label':'触发技能进化',
|
|
1748
1855
|
'pp.skills.hint':'分析已完成的任务,自动创建或升级可复用的技能(SKILL.md)。需要先启用任务摘要。由于需要 LLM 评估,耗时较长。',
|
|
1856
|
+
'pp.concurrency.label':'并行 Agent 数',
|
|
1857
|
+
'pp.concurrency.warn':'\u26A0 提高并行数会增加 LLM API 调用频率,可能触发限流而导致失败。',
|
|
1749
1858
|
'pp.start':'开始处理',
|
|
1750
1859
|
'pp.resume':'继续处理',
|
|
1751
1860
|
'pp.running':'正在处理',
|
|
@@ -1794,7 +1903,25 @@ const I18N={
|
|
|
1794
1903
|
'tasks.role.assistant':'助手',
|
|
1795
1904
|
'tasks.error':'出错了',
|
|
1796
1905
|
'tasks.error.detail':'加载任务详情失败',
|
|
1797
|
-
'tasks.untitled.related':'未命名'
|
|
1906
|
+
'tasks.untitled.related':'未命名',
|
|
1907
|
+
'task.edit':'编辑',
|
|
1908
|
+
'task.delete':'删除',
|
|
1909
|
+
'task.save':'保存',
|
|
1910
|
+
'task.cancel':'取消',
|
|
1911
|
+
'task.delete.confirm':'确定要删除此任务吗?此操作不可撤销。',
|
|
1912
|
+
'task.delete.error':'删除任务失败:',
|
|
1913
|
+
'task.save.error':'保存任务失败:',
|
|
1914
|
+
'task.retrySkill':'重新生成技能',
|
|
1915
|
+
'task.retrySkill.short':'重试技能',
|
|
1916
|
+
'task.retrySkill.confirm':'确定要为此任务重新触发技能生成吗?',
|
|
1917
|
+
'task.retrySkill.error':'重新生成技能失败:',
|
|
1918
|
+
'skill.edit':'编辑',
|
|
1919
|
+
'skill.delete':'删除',
|
|
1920
|
+
'skill.save':'保存',
|
|
1921
|
+
'skill.cancel':'取消',
|
|
1922
|
+
'skill.delete.confirm':'确定要删除此技能吗?关联的文件也会被删除,此操作不可撤销。',
|
|
1923
|
+
'skill.delete.error':'删除技能失败:',
|
|
1924
|
+
'skill.save.error':'保存技能失败:'
|
|
1798
1925
|
}
|
|
1799
1926
|
};
|
|
1800
1927
|
const LANG_KEY='memos-viewer-lang';
|
|
@@ -2213,6 +2340,11 @@ async function loadTasks(){
|
|
|
2213
2340
|
'<span class="tag"><span class="icon">\\u{1F4DD}</span> '+task.chunkCount+' '+t('tasks.chunks.label')+'</span>'+
|
|
2214
2341
|
'<span class="tag"><span class="icon">\\u{1F4C2}</span> '+(task.sessionKey||'').slice(0,12)+'</span>'+
|
|
2215
2342
|
'</div>'+
|
|
2343
|
+
'<div class="card-actions" onclick="event.stopPropagation()">'+
|
|
2344
|
+
'<button class="btn btn-sm btn-ghost" onclick="openTaskDetail(\\''+task.id+'\\')">'+t('card.expand')+'</button>'+
|
|
2345
|
+
(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>':'')+
|
|
2346
|
+
'<button class="btn btn-sm btn-ghost" style="color:var(--accent)" onclick="deleteTask(\\''+task.id+'\\')">'+t('task.delete')+'</button>'+
|
|
2347
|
+
'</div>'+
|
|
2216
2348
|
'</div>';
|
|
2217
2349
|
}).join('');
|
|
2218
2350
|
|
|
@@ -2237,7 +2369,10 @@ function renderTasksPagination(total){
|
|
|
2237
2369
|
el.innerHTML=html;
|
|
2238
2370
|
}
|
|
2239
2371
|
|
|
2372
|
+
var _currentTaskId=null;
|
|
2373
|
+
var _currentTaskData=null;
|
|
2240
2374
|
async function openTaskDetail(taskId){
|
|
2375
|
+
_currentTaskId=taskId;
|
|
2241
2376
|
const overlay=document.getElementById('taskDetailOverlay');
|
|
2242
2377
|
overlay.classList.add('show');
|
|
2243
2378
|
document.getElementById('taskDetailTitle').textContent=t('tasks.loading');
|
|
@@ -2246,6 +2381,7 @@ async function openTaskDetail(taskId){
|
|
|
2246
2381
|
document.getElementById('taskSkillSection').className='task-skill-section';
|
|
2247
2382
|
document.getElementById('taskDetailSummary').textContent='';
|
|
2248
2383
|
document.getElementById('taskDetailChunks').innerHTML='<div class="spinner"></div>';
|
|
2384
|
+
document.getElementById('taskDetailActions').innerHTML='';
|
|
2249
2385
|
|
|
2250
2386
|
try{
|
|
2251
2387
|
const r=await fetch('/api/task/'+taskId);
|
|
@@ -2263,9 +2399,13 @@ async function openTaskDetail(taskId){
|
|
|
2263
2399
|
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>');
|
|
2264
2400
|
document.getElementById('taskDetailMeta').innerHTML=meta.join('');
|
|
2265
2401
|
|
|
2402
|
+
_currentTaskData=task;
|
|
2403
|
+
|
|
2266
2404
|
// ── Skill status section ──
|
|
2267
2405
|
renderTaskSkillSection(task);
|
|
2268
2406
|
|
|
2407
|
+
document.getElementById('taskDetailActions').innerHTML='';
|
|
2408
|
+
|
|
2269
2409
|
var summaryEl=document.getElementById('taskDetailSummary');
|
|
2270
2410
|
if(task.status==='skipped'){
|
|
2271
2411
|
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>';
|
|
@@ -2319,19 +2459,31 @@ function renderTaskSkillSection(task){
|
|
|
2319
2459
|
}else if(ss==='not_generated'){
|
|
2320
2460
|
section.className='task-skill-section status-not_generated';
|
|
2321
2461
|
section.innerHTML='<div class="skill-status-header">\\u274C \u672A\u751F\u6210\u6280\u80FD</div>'+
|
|
2322
|
-
'<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>'
|
|
2462
|
+
'<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>'+
|
|
2463
|
+
(task.status==='completed'?'<button class="btn btn-primary" onclick="retrySkillGen(\\''+esc(task.id)+'\\')" style="margin-top:8px;font-size:12px">'+t('task.retrySkill')+'</button>':'');
|
|
2323
2464
|
}else if(ss==='skipped'){
|
|
2324
2465
|
section.className='task-skill-section status-skipped';
|
|
2325
2466
|
section.innerHTML='<div class="skill-status-header">\\u23ED \u8DF3\u8FC7\u6280\u80FD\u8BC4\u4F30</div>'+
|
|
2326
|
-
'<div class="skill-status-reason">\u539F\u56E0\uFF1A'+esc(task.skillReason||'')+'</div>'
|
|
2467
|
+
'<div class="skill-status-reason">\u539F\u56E0\uFF1A'+esc(task.skillReason||'')+'</div>'+
|
|
2468
|
+
(task.status==='completed'?'<button class="btn btn-primary" onclick="retrySkillGen(\\''+esc(task.id)+'\\')" style="margin-top:8px;font-size:12px">'+t('task.retrySkill')+'</button>':'');
|
|
2469
|
+
}else if(ss==='queued'){
|
|
2470
|
+
section.className='task-skill-section status-generating';
|
|
2471
|
+
section.innerHTML='<div class="skill-status-header">\\u{1F4CB} \u6392\u961F\u4E2D</div>'+
|
|
2472
|
+
'<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>';
|
|
2327
2473
|
}else if(task.status==='active'){
|
|
2328
2474
|
section.className='task-skill-section status-skipped';
|
|
2329
2475
|
section.innerHTML='<div class="skill-status-header">\\u23F8 \u4EFB\u52A1\u8FDB\u884C\u4E2D</div>'+
|
|
2330
2476
|
'<div class="skill-status-reason">\u6280\u80FD\u8BC4\u4F30\u5728\u4EFB\u52A1\u5B8C\u6210\u540E\u81EA\u52A8\u8FD0\u884C\u3002</div>';
|
|
2477
|
+
}else if(task.status==='completed'){
|
|
2478
|
+
section.className='task-skill-section status-generating';
|
|
2479
|
+
section.innerHTML='<div class="skill-status-header">\\u23F3 \u7B49\u5F85\u8BC4\u4F30</div>'+
|
|
2480
|
+
'<div class="skill-status-reason">\u4EFB\u52A1\u5DF2\u5B8C\u6210\uFF0C\u6280\u80FD\u8BC4\u4F30\u5373\u5C06\u5F00\u59CB\u3002</div>'+
|
|
2481
|
+
'<button class="btn btn-primary" onclick="retrySkillGen(\\''+esc(task.id)+'\\')" style="margin-top:8px;font-size:12px">'+t('task.retrySkill')+'</button>';
|
|
2331
2482
|
}else{
|
|
2332
2483
|
section.className='task-skill-section status-skipped';
|
|
2333
2484
|
section.innerHTML='<div class="skill-status-header">\\u2014 \u65E0\u6280\u80FD\u4FE1\u606F</div>'+
|
|
2334
|
-
'<div class="skill-status-reason">\u8BE5\u4EFB\u52A1\
|
|
2485
|
+
'<div class="skill-status-reason">\u8BE5\u4EFB\u52A1\u672A\u8FDB\u884C\u6280\u80FD\u8BC4\u4F30\u3002</div>'+
|
|
2486
|
+
(task.status==='completed'?'<button class="btn btn-primary" onclick="retrySkillGen(\\''+esc(task.id)+'\\')" style="margin-top:8px;font-size:12px">'+t('task.retrySkill')+'</button>':'');
|
|
2335
2487
|
}
|
|
2336
2488
|
}
|
|
2337
2489
|
|
|
@@ -2340,6 +2492,29 @@ function closeTaskDetail(event){
|
|
|
2340
2492
|
document.getElementById('taskDetailOverlay').classList.remove('show');
|
|
2341
2493
|
}
|
|
2342
2494
|
|
|
2495
|
+
async function retrySkillGen(taskId){
|
|
2496
|
+
if(!confirm(t('task.retrySkill.confirm'))) return;
|
|
2497
|
+
try{
|
|
2498
|
+
const r=await fetch('/api/task/'+taskId+'/retry-skill',{method:'POST'});
|
|
2499
|
+
const d=await r.json();
|
|
2500
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
2501
|
+
openTaskDetail(taskId);
|
|
2502
|
+
}catch(e){ alert(t('task.retrySkill.error')+e.message); }
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
async function deleteTask(taskId){
|
|
2506
|
+
if(!confirm(t('task.delete.confirm'))) return;
|
|
2507
|
+
try{
|
|
2508
|
+
const r=await fetch('/api/task/'+taskId,{method:'DELETE'});
|
|
2509
|
+
const d=await r.json();
|
|
2510
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
2511
|
+
closeTaskDetail();
|
|
2512
|
+
document.getElementById('taskDetailOverlay').classList.remove('show');
|
|
2513
|
+
loadTasks();
|
|
2514
|
+
}catch(e){ alert(t('task.delete.error')+e.message); }
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
|
|
2343
2518
|
/* ─── Skills View Logic ─── */
|
|
2344
2519
|
let skillsStatusFilter='';
|
|
2345
2520
|
|
|
@@ -2397,6 +2572,11 @@ async function loadSkills(){
|
|
|
2397
2572
|
'<span class="tag"><span class="icon">\\u{1F4E6}</span> '+skill.sourceType+'</span>'+
|
|
2398
2573
|
(tags.length>0?'<div class="skill-card-tags">'+tags.map(t=>'<span class="skill-tag">'+esc(t)+'</span>').join('')+'</div>':'')+
|
|
2399
2574
|
'</div>'+
|
|
2575
|
+
'<div class="card-actions" onclick="event.stopPropagation()">'+
|
|
2576
|
+
'<button class="btn btn-sm btn-ghost" onclick="openSkillDetail(\\''+skill.id+'\\')">'+t('card.expand')+'</button>'+
|
|
2577
|
+
(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>')+
|
|
2578
|
+
'<button class="btn btn-sm btn-ghost" style="color:var(--accent)" onclick="deleteSkill(\\''+skill.id+'\\')">'+t('skill.delete')+'</button>'+
|
|
2579
|
+
'</div>'+
|
|
2400
2580
|
'</div>';
|
|
2401
2581
|
}).join('');
|
|
2402
2582
|
}catch(e){
|
|
@@ -2421,6 +2601,7 @@ async function openSkillDetail(skillId){
|
|
|
2421
2601
|
document.getElementById('skillDetailContent').innerHTML='<div class="spinner"></div>';
|
|
2422
2602
|
document.getElementById('skillVersionsList').innerHTML='<div class="spinner"></div>';
|
|
2423
2603
|
document.getElementById('skillRelatedTasks').innerHTML='';
|
|
2604
|
+
document.getElementById('skillDetailActions').innerHTML='';
|
|
2424
2605
|
|
|
2425
2606
|
try{
|
|
2426
2607
|
const r=await fetch('/api/skill/'+skillId);
|
|
@@ -2516,6 +2697,9 @@ async function openSkillDetail(skillId){
|
|
|
2516
2697
|
).join('');
|
|
2517
2698
|
}
|
|
2518
2699
|
|
|
2700
|
+
window._currentSkillData=skill;
|
|
2701
|
+
document.getElementById('skillDetailActions').innerHTML='';
|
|
2702
|
+
|
|
2519
2703
|
}catch(e){
|
|
2520
2704
|
document.getElementById('skillDetailTitle').textContent=t('skills.error');
|
|
2521
2705
|
document.getElementById('skillDetailContent').innerHTML='<div style="color:var(--rose);padding:16px">'+t('skills.error.detail')+esc(String(e))+'</div>';
|
|
@@ -2536,11 +2720,23 @@ async function toggleSkillVisibility(){
|
|
|
2536
2720
|
const newVis=btn.dataset.vis==='public'?'private':'public';
|
|
2537
2721
|
try{
|
|
2538
2722
|
const r=await fetch('/api/skill/'+currentSkillId+'/visibility',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify({visibility:newVis})});
|
|
2539
|
-
if(!r.ok) throw new Error('
|
|
2723
|
+
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);}
|
|
2540
2724
|
openSkillDetail(currentSkillId);
|
|
2541
2725
|
loadSkills();
|
|
2542
2726
|
}catch(e){
|
|
2543
|
-
|
|
2727
|
+
toast('Error: '+e.message,'error');
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2731
|
+
async function toggleSkillPublic(id,setPublic){
|
|
2732
|
+
const newVis=setPublic?'public':'private';
|
|
2733
|
+
try{
|
|
2734
|
+
const r=await fetch('/api/skill/'+id+'/visibility',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify({visibility:newVis})});
|
|
2735
|
+
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);}
|
|
2736
|
+
toast(setPublic?t('toast.setPublic'):t('toast.setPrivate'),'success');
|
|
2737
|
+
loadSkills();
|
|
2738
|
+
}catch(e){
|
|
2739
|
+
toast('Error: '+e.message,'error');
|
|
2544
2740
|
}
|
|
2545
2741
|
}
|
|
2546
2742
|
|
|
@@ -2584,7 +2780,37 @@ async function loadConfig(){
|
|
|
2584
2780
|
}
|
|
2585
2781
|
}
|
|
2586
2782
|
|
|
2783
|
+
var _providerDefaults={
|
|
2784
|
+
siliconflow:{endpoint:'https://api.siliconflow.cn/v1',embModel:'BAAI/bge-m3',chatModel:'Qwen/Qwen2.5-7B-Instruct'},
|
|
2785
|
+
openai:{endpoint:'https://api.openai.com/v1',embModel:'text-embedding-3-small',chatModel:'gpt-4o-mini'},
|
|
2786
|
+
anthropic:{endpoint:'https://api.anthropic.com/v1/messages',chatModel:'claude-3-haiku-20240307'},
|
|
2787
|
+
cohere:{endpoint:'https://api.cohere.com/v2',embModel:'embed-english-v3.0'},
|
|
2788
|
+
mistral:{endpoint:'https://api.mistral.ai/v1',embModel:'mistral-embed'},
|
|
2789
|
+
voyage:{endpoint:'https://api.voyageai.com/v1',embModel:'voyage-3'},
|
|
2790
|
+
gemini:{endpoint:'',embModel:'text-embedding-004',chatModel:'gemini-2.0-flash'},
|
|
2791
|
+
zhipu:{endpoint:'https://open.bigmodel.cn/api/paas/v4',embModel:'embedding-3',chatModel:'glm-4-flash'},
|
|
2792
|
+
deepseek:{endpoint:'https://api.deepseek.com/v1',chatModel:'deepseek-chat'},
|
|
2793
|
+
bailian:{endpoint:'https://dashscope.aliyuncs.com/compatible-mode/v1',embModel:'text-embedding-v3',chatModel:'qwen-max'},
|
|
2794
|
+
moonshot:{endpoint:'https://api.moonshot.cn/v1',chatModel:'moonshot-v1-8k'}
|
|
2795
|
+
};
|
|
2796
|
+
function onProviderChange(section){
|
|
2797
|
+
var map={embedding:['cfgEmbEndpoint','cfgEmbModel','emb'],summarizer:['cfgSumEndpoint','cfgSumModel','chat'],skill:['cfgSkillEndpoint','cfgSkillModel','chat']};
|
|
2798
|
+
var m=map[section];if(!m)return;
|
|
2799
|
+
var sel=document.getElementById(section==='embedding'?'cfgEmbProvider':section==='summarizer'?'cfgSumProvider':'cfgSkillProvider');
|
|
2800
|
+
var pv=sel.value;
|
|
2801
|
+
var def=_providerDefaults[pv];
|
|
2802
|
+
if(!def)return;
|
|
2803
|
+
var epEl=document.getElementById(m[0]);
|
|
2804
|
+
var mdEl=document.getElementById(m[1]);
|
|
2805
|
+
if(def.endpoint&&!epEl.value.trim()) epEl.value=def.endpoint;
|
|
2806
|
+
if(m[2]==='emb'&&def.embModel&&!mdEl.value.trim()) mdEl.value=def.embModel;
|
|
2807
|
+
if(m[2]==='chat'&&def.chatModel&&!mdEl.value.trim()) mdEl.value=def.chatModel;
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2587
2810
|
async function saveConfig(){
|
|
2811
|
+
var saveBtn=document.querySelector('.settings-actions .btn-primary');
|
|
2812
|
+
saveBtn.disabled=true;saveBtn.textContent=t('settings.test.loading');
|
|
2813
|
+
|
|
2588
2814
|
const cfg={};
|
|
2589
2815
|
const embP=document.getElementById('cfgEmbProvider').value;
|
|
2590
2816
|
if(embP){
|
|
@@ -2594,11 +2820,15 @@ async function saveConfig(){
|
|
|
2594
2820
|
const k=document.getElementById('cfgEmbApiKey').value.trim();if(k) cfg.embedding.apiKey=k;
|
|
2595
2821
|
}
|
|
2596
2822
|
const sumP=document.getElementById('cfgSumProvider').value;
|
|
2597
|
-
|
|
2823
|
+
const sumModel=document.getElementById('cfgSumModel').value.trim();
|
|
2824
|
+
const sumEndpoint=document.getElementById('cfgSumEndpoint').value.trim();
|
|
2825
|
+
const sumApiKey=document.getElementById('cfgSumApiKey').value.trim();
|
|
2826
|
+
var hasSumConfig=!!(sumModel||sumEndpoint||sumApiKey);
|
|
2827
|
+
if(hasSumConfig&&sumP){
|
|
2598
2828
|
cfg.summarizer={provider:sumP};
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2829
|
+
if(sumModel) cfg.summarizer.model=sumModel;
|
|
2830
|
+
if(sumEndpoint) cfg.summarizer.endpoint=sumEndpoint;
|
|
2831
|
+
if(sumApiKey) cfg.summarizer.apiKey=sumApiKey;
|
|
2602
2832
|
const tp=document.getElementById('cfgSumTemp').value.trim();if(tp!=='') cfg.summarizer.temperature=Number(tp);
|
|
2603
2833
|
}
|
|
2604
2834
|
cfg.skillEvolution={
|
|
@@ -2609,29 +2839,118 @@ async function saveConfig(){
|
|
|
2609
2839
|
const mk=document.getElementById('cfgSkillMinChunks').value.trim();if(mk) cfg.skillEvolution.minChunksForEval=Number(mk);
|
|
2610
2840
|
|
|
2611
2841
|
const skP=document.getElementById('cfgSkillProvider').value;
|
|
2612
|
-
|
|
2842
|
+
const skModel=document.getElementById('cfgSkillModel').value.trim();
|
|
2843
|
+
const skEndpoint=document.getElementById('cfgSkillEndpoint').value.trim();
|
|
2844
|
+
const skApiKey=document.getElementById('cfgSkillApiKey').value.trim();
|
|
2845
|
+
var hasSkillConfig=!!(skP&&(skModel||skEndpoint||skApiKey));
|
|
2846
|
+
if(hasSkillConfig){
|
|
2613
2847
|
cfg.skillEvolution.summarizer={provider:skP};
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2848
|
+
if(skModel) cfg.skillEvolution.summarizer.model=skModel;
|
|
2849
|
+
if(skEndpoint) cfg.skillEvolution.summarizer.endpoint=skEndpoint;
|
|
2850
|
+
if(skApiKey) cfg.skillEvolution.summarizer.apiKey=skApiKey;
|
|
2617
2851
|
}
|
|
2618
2852
|
|
|
2619
2853
|
const vp=document.getElementById('cfgViewerPort').value.trim();
|
|
2620
2854
|
if(vp) cfg.viewerPort=Number(vp);
|
|
2855
|
+
cfg.telemetry={enabled:document.getElementById('cfgTelemetryEnabled').checked};
|
|
2621
2856
|
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2857
|
+
function done(){saveBtn.disabled=false;saveBtn.textContent=t('settings.save');}
|
|
2858
|
+
|
|
2859
|
+
// 1) Embedding model is required
|
|
2860
|
+
if(!embP||embP===''){done();toast(t('settings.save.emb.required'),'error');return;}
|
|
2861
|
+
|
|
2862
|
+
// 2) Test embedding
|
|
2863
|
+
try{
|
|
2864
|
+
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||''})});
|
|
2865
|
+
var ed=await er.json();
|
|
2866
|
+
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;}
|
|
2867
|
+
document.getElementById('testEmbResult').className='test-result ok';document.getElementById('testEmbResult').innerHTML='\\u2705 '+t('settings.test.ok');
|
|
2868
|
+
}catch(e){done();toast(t('settings.save.emb.fail')+': '+e.message,'error');return;}
|
|
2869
|
+
|
|
2870
|
+
// 3) Test summarizer if user filled it
|
|
2871
|
+
if(hasSumConfig&&cfg.summarizer){
|
|
2872
|
+
try{
|
|
2873
|
+
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||''})});
|
|
2874
|
+
var sd=await sr.json();
|
|
2875
|
+
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;}
|
|
2876
|
+
document.getElementById('testSumResult').className='test-result ok';document.getElementById('testSumResult').innerHTML='\\u2705 '+t('settings.test.ok');
|
|
2877
|
+
}catch(e){done();toast(t('settings.save.sum.fail')+': '+e.message,'error');return;}
|
|
2878
|
+
}
|
|
2879
|
+
|
|
2880
|
+
// 4) Test skill model if user filled it
|
|
2881
|
+
if(hasSkillConfig&&cfg.skillEvolution.summarizer){
|
|
2882
|
+
try{
|
|
2883
|
+
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||''})});
|
|
2884
|
+
var kd=await kr.json();
|
|
2885
|
+
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;}
|
|
2886
|
+
document.getElementById('testSkillResult').className='test-result ok';document.getElementById('testSkillResult').innerHTML='\\u2705 '+t('settings.test.ok');
|
|
2887
|
+
}catch(e){done();toast(t('settings.save.skill.fail')+': '+e.message,'error');return;}
|
|
2888
|
+
}
|
|
2625
2889
|
|
|
2890
|
+
// 5) If summarizer or skill model not configured, check OpenClaw fallback and confirm
|
|
2891
|
+
if(!hasSumConfig||!hasSkillConfig){
|
|
2892
|
+
try{
|
|
2893
|
+
var fr=await fetch('/api/fallback-model');
|
|
2894
|
+
var fb=await fr.json();
|
|
2895
|
+
var msgs=[];
|
|
2896
|
+
if(!hasSumConfig){msgs.push(t('settings.save.sum.fallback'));}
|
|
2897
|
+
if(!hasSkillConfig){msgs.push(t('settings.save.skill.fallback'));}
|
|
2898
|
+
var fbInfo=fb.available?(fb.model+' ('+fb.baseUrl+')'):t('settings.save.fallback.none');
|
|
2899
|
+
var confirmMsg=msgs.join('\\n')+'\\n\\n'+t('settings.save.fallback.model')+fbInfo+'\\n\\n'+t('settings.save.fallback.confirm');
|
|
2900
|
+
if(!confirm(confirmMsg)){done();return;}
|
|
2901
|
+
}catch(e){}
|
|
2902
|
+
}
|
|
2903
|
+
|
|
2904
|
+
// 6) All tests passed, save
|
|
2626
2905
|
try{
|
|
2627
2906
|
const r=await fetch('/api/config',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(cfg)});
|
|
2628
2907
|
if(!r.ok) throw new Error(await r.text());
|
|
2629
2908
|
const el=document.getElementById('settingsSaved');
|
|
2630
2909
|
el.classList.add('show');
|
|
2631
2910
|
setTimeout(()=>el.classList.remove('show'),2500);
|
|
2911
|
+
toast(t('settings.saved'),'success');
|
|
2632
2912
|
}catch(e){
|
|
2633
|
-
|
|
2913
|
+
toast(t('settings.save.fail')+': '+e.message,'error');
|
|
2914
|
+
}finally{done();}
|
|
2915
|
+
}
|
|
2916
|
+
|
|
2917
|
+
async function testModel(type){
|
|
2918
|
+
var ids={embedding:['Emb','cfgEmbProvider','cfgEmbModel','cfgEmbEndpoint','cfgEmbApiKey'],summarizer:['Sum','cfgSumProvider','cfgSumModel','cfgSumEndpoint','cfgSumApiKey'],skill:['Skill','cfgSkillProvider','cfgSkillModel','cfgSkillEndpoint','cfgSkillApiKey']};
|
|
2919
|
+
var c=ids[type];if(!c)return;
|
|
2920
|
+
var resultEl=document.getElementById('test'+c[0]+'Result');
|
|
2921
|
+
var btn=document.getElementById('test'+c[0]+'Btn');
|
|
2922
|
+
var provider=document.getElementById(c[1]).value;
|
|
2923
|
+
var model=document.getElementById(c[2]).value.trim();
|
|
2924
|
+
var endpoint=document.getElementById(c[3]).value.trim();
|
|
2925
|
+
var apiKey=document.getElementById(c[4]).value.trim();
|
|
2926
|
+
if(!provider||(provider!=='local'&&!model)){
|
|
2927
|
+
resultEl.className='test-result fail';
|
|
2928
|
+
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>';
|
|
2929
|
+
return;
|
|
2930
|
+
}
|
|
2931
|
+
if(provider!=='local'&&!apiKey){
|
|
2932
|
+
resultEl.className='test-result fail';
|
|
2933
|
+
resultEl.innerHTML='\\u274C '+t('settings.test.fail')+'<div style="margin-top:4px;font-size:11px;color:var(--text-muted)">API Key is required</div>';
|
|
2934
|
+
return;
|
|
2634
2935
|
}
|
|
2936
|
+
resultEl.className='test-result loading';resultEl.textContent=t('settings.test.loading');
|
|
2937
|
+
btn.disabled=true;
|
|
2938
|
+
try{
|
|
2939
|
+
var body={type:type,provider:provider,model:model,endpoint:endpoint,apiKey:apiKey};
|
|
2940
|
+
var r=await fetch('/api/test-model',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});
|
|
2941
|
+
var d=await r.json();
|
|
2942
|
+
if(d.ok){
|
|
2943
|
+
resultEl.className='test-result ok';
|
|
2944
|
+
resultEl.innerHTML='\\u2705 '+t('settings.test.ok')+'<div style="margin-top:4px;font-size:11px;color:var(--text-muted)">'+esc(d.detail||'')+'</div>';
|
|
2945
|
+
}else{
|
|
2946
|
+
var errMsg=d.error||'Unknown error';
|
|
2947
|
+
resultEl.className='test-result fail';
|
|
2948
|
+
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>';
|
|
2949
|
+
}
|
|
2950
|
+
}catch(e){
|
|
2951
|
+
resultEl.className='test-result fail';
|
|
2952
|
+
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>';
|
|
2953
|
+
}finally{btn.disabled=false;}
|
|
2635
2954
|
}
|
|
2636
2955
|
|
|
2637
2956
|
function renderSkillMarkdown(md){
|
|
@@ -2665,6 +2984,19 @@ function closeSkillDetail(event){
|
|
|
2665
2984
|
document.getElementById('skillDetailOverlay').classList.remove('show');
|
|
2666
2985
|
}
|
|
2667
2986
|
|
|
2987
|
+
async function deleteSkill(skillId){
|
|
2988
|
+
if(!confirm(t('skill.delete.confirm'))) return;
|
|
2989
|
+
try{
|
|
2990
|
+
const r=await fetch('/api/skill/'+skillId,{method:'DELETE'});
|
|
2991
|
+
const d=await r.json();
|
|
2992
|
+
if(!r.ok) throw new Error(d.error||'unknown');
|
|
2993
|
+
closeSkillDetail();
|
|
2994
|
+
document.getElementById('skillDetailOverlay').classList.remove('show');
|
|
2995
|
+
loadSkills();
|
|
2996
|
+
}catch(e){ alert(t('skill.delete.error')+e.message); }
|
|
2997
|
+
}
|
|
2998
|
+
|
|
2999
|
+
|
|
2668
3000
|
function formatDuration(ms){
|
|
2669
3001
|
const s=Math.floor(ms/1000);
|
|
2670
3002
|
if(s<60) return s+'s';
|
|
@@ -3368,6 +3700,19 @@ async function clearAll(){
|
|
|
3368
3700
|
let migrateScanData=null;
|
|
3369
3701
|
let migrateStats={stored:0,skipped:0,merged:0,errors:0};
|
|
3370
3702
|
|
|
3703
|
+
(function(){
|
|
3704
|
+
const sel=document.getElementById('migrateConcurrency');
|
|
3705
|
+
if(sel) sel.addEventListener('change',function(){
|
|
3706
|
+
const w=document.getElementById('migrateConcurrencyWarn');
|
|
3707
|
+
if(w) w.style.display=parseInt(this.value,10)>1?'block':'none';
|
|
3708
|
+
});
|
|
3709
|
+
const ppSel=document.getElementById('ppConcurrency');
|
|
3710
|
+
if(ppSel) ppSel.addEventListener('change',function(){
|
|
3711
|
+
const w=document.getElementById('ppConcurrencyWarn');
|
|
3712
|
+
if(w) w.style.display=parseInt(this.value,10)>1?'block':'none';
|
|
3713
|
+
});
|
|
3714
|
+
})();
|
|
3715
|
+
|
|
3371
3716
|
async function migrateScan(){
|
|
3372
3717
|
const btn=document.getElementById('migrateScanBtn');
|
|
3373
3718
|
btn.disabled=true;
|
|
@@ -3403,6 +3748,7 @@ async function migrateScan(){
|
|
|
3403
3748
|
|
|
3404
3749
|
if(d.totalItems>0 && d.configReady){
|
|
3405
3750
|
document.getElementById('migrateStartBtn').style.display='inline-flex';
|
|
3751
|
+
document.getElementById('migrateConcurrencyRow').style.display='inline-flex';
|
|
3406
3752
|
}
|
|
3407
3753
|
|
|
3408
3754
|
if(d.totalItems===0){
|
|
@@ -3424,10 +3770,15 @@ function migrateStart(){
|
|
|
3424
3770
|
if(!migrateScanData||!migrateScanData.configReady)return;
|
|
3425
3771
|
if(!confirm(t('migrate.start')+'?'))return;
|
|
3426
3772
|
|
|
3773
|
+
const concSel=document.getElementById('migrateConcurrency');
|
|
3774
|
+
const concurrency=concSel?parseInt(concSel.value,10)||1:1;
|
|
3775
|
+
|
|
3427
3776
|
window._migrateRunning=true;
|
|
3428
3777
|
_migrateStatusChecked=false;
|
|
3429
3778
|
document.getElementById('migrateStartBtn').style.display='none';
|
|
3430
3779
|
document.getElementById('migrateScanBtn').disabled=true;
|
|
3780
|
+
document.getElementById('migrateConcurrencyRow').style.display='none';
|
|
3781
|
+
document.getElementById('migrateConcurrencyWarn').style.display='none';
|
|
3431
3782
|
document.getElementById('migrateProgress').style.display='block';
|
|
3432
3783
|
document.getElementById('migrateLiveLog').innerHTML='';
|
|
3433
3784
|
migrateStats={stored:0,skipped:0,merged:0,errors:0};
|
|
@@ -3437,7 +3788,7 @@ function migrateStart(){
|
|
|
3437
3788
|
document.getElementById('migrateBar').style.width='0%';
|
|
3438
3789
|
document.getElementById('migrateBar').style.background='linear-gradient(90deg,#6366f1,#8b5cf6)';
|
|
3439
3790
|
document.getElementById('migrateCounter').textContent='';
|
|
3440
|
-
const body=JSON.stringify({sources:['sqlite','sessions']});
|
|
3791
|
+
const body=JSON.stringify({sources:['sqlite','sessions'],concurrency});
|
|
3441
3792
|
connectMigrateSSE('/api/migrate/start','POST',body);
|
|
3442
3793
|
}
|
|
3443
3794
|
|
|
@@ -3642,6 +3993,9 @@ function ppStart(){
|
|
|
3642
3993
|
var enableSkills=document.getElementById('ppEnableSkills').checked;
|
|
3643
3994
|
if(!enableTasks&&!enableSkills){toast(t('pp.select.warn'),'error');return;}
|
|
3644
3995
|
|
|
3996
|
+
var ppConcSel=document.getElementById('ppConcurrency');
|
|
3997
|
+
var ppConcurrency=ppConcSel?parseInt(ppConcSel.value,10)||1:1;
|
|
3998
|
+
|
|
3645
3999
|
window._ppRunning=true;
|
|
3646
4000
|
_ppSSEConnected=false;
|
|
3647
4001
|
ppStats={tasks:0,skills:0,errors:0,skipped:0};
|
|
@@ -3658,7 +4012,7 @@ function ppStart(){
|
|
|
3658
4012
|
document.getElementById('ppLiveLog').innerHTML='';
|
|
3659
4013
|
updatePPStats();
|
|
3660
4014
|
|
|
3661
|
-
var body=JSON.stringify({enableTasks:enableTasks,enableSkills:enableSkills});
|
|
4015
|
+
var body=JSON.stringify({enableTasks:enableTasks,enableSkills:enableSkills,concurrency:ppConcurrency});
|
|
3662
4016
|
fetch('/api/migrate/postprocess',{method:'POST',headers:{'Content-Type':'application/json'},body:body})
|
|
3663
4017
|
.then(function(r){
|
|
3664
4018
|
if(!r.ok){
|