@memtensor/memos-local-openclaw-plugin 1.0.4-beta.2 → 1.0.4-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/ensure-binding.d.ts +12 -0
- package/dist/storage/ensure-binding.d.ts.map +1 -0
- package/dist/storage/ensure-binding.js +53 -0
- package/dist/storage/ensure-binding.js.map +1 -0
- package/dist/viewer/html.d.ts.map +1 -1
- package/dist/viewer/html.js +439 -189
- package/dist/viewer/html.js.map +1 -1
- package/index.ts +3 -0
- package/package.json +2 -1
- package/src/index.ts +3 -0
- package/src/storage/ensure-binding.ts +52 -0
- package/src/viewer/html.ts +439 -189
package/dist/viewer/html.js
CHANGED
|
@@ -109,7 +109,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
109
109
|
|
|
110
110
|
/* ─── App Layout (dark dashboard, same as www) ─── */
|
|
111
111
|
.app{display:none;flex-direction:column;min-height:100vh}
|
|
112
|
-
.topbar{background:rgba(11,13,17,.88);border-bottom:1px solid var(--border);padding:0
|
|
112
|
+
.topbar{background:rgba(11,13,17,.88);border-bottom:1px solid var(--border);padding:0 max(32px,calc((100% - 1400px)/2 + 32px));height:56px;display:flex;align-items:center;position:sticky;top:0;z-index:100;backdrop-filter:blur(12px)}
|
|
113
113
|
.topbar .brand{display:flex;align-items:center;gap:8px;font-weight:700;font-size:15px;color:var(--text);letter-spacing:-.02em;flex-shrink:0}
|
|
114
114
|
.topbar .brand .icon{width:24px;height:24px;display:flex;align-items:center;justify-content:center;font-size:18px;background:none;border-radius:0}
|
|
115
115
|
.topbar .brand .brand-title{font-size:13px;font-weight:500;opacity:.7}
|
|
@@ -715,9 +715,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
715
715
|
.settings-tab-btn.active{background:var(--bg-card);color:var(--text);font-weight:600;box-shadow:0 2px 8px rgba(0,0,0,.06),0 0 0 1px rgba(99,102,241,.1)}
|
|
716
716
|
.settings-tab-btn .stab-icon{font-size:15px;line-height:1}
|
|
717
717
|
.settings-tab-btn .stab-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
|
|
718
|
-
.settings-tab-btn[data-tab="
|
|
719
|
-
.settings-tab-btn[data-tab="summarizer"] .stab-dot{background:#8b5cf6}
|
|
720
|
-
.settings-tab-btn[data-tab="skill"] .stab-dot{background:#f59e0b}
|
|
718
|
+
.settings-tab-btn[data-tab="models"] .stab-dot{background:#6366f1}
|
|
721
719
|
.settings-tab-btn[data-tab="hub"] .stab-dot{background:#06b6d4}
|
|
722
720
|
.settings-tab-btn[data-tab="general"] .stab-dot{background:#10b981}
|
|
723
721
|
.settings-tab-btn.active .stab-dot{box-shadow:0 0 6px currentColor}
|
|
@@ -729,9 +727,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
729
727
|
.settings-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;opacity:.5;transition:opacity .3s}
|
|
730
728
|
.settings-card:hover{border-color:rgba(99,102,241,.25);box-shadow:0 0 24px rgba(99,102,241,.06),0 8px 32px rgba(0,0,0,.1)}
|
|
731
729
|
.settings-card:hover::before{opacity:1}
|
|
732
|
-
.settings-card.card-
|
|
733
|
-
.settings-card.card-summarizer::before{background:linear-gradient(90deg,#8b5cf6,#a78bfa,#c4b5fd)}
|
|
734
|
-
.settings-card.card-skill::before{background:linear-gradient(90deg,#f59e0b,#fbbf24,#fcd34d)}
|
|
730
|
+
.settings-card.card-models::before{background:linear-gradient(90deg,#6366f1,#8b5cf6,#f59e0b)}
|
|
735
731
|
.settings-card.card-hub::before{background:linear-gradient(90deg,#06b6d4,#22d3ee,#67e8f9)}
|
|
736
732
|
.settings-card.card-general::before{background:linear-gradient(90deg,#10b981,#34d399,#6ee7b7)}
|
|
737
733
|
.settings-card-header{display:flex;align-items:center;gap:14px;padding:22px 28px 0}
|
|
@@ -805,6 +801,28 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
805
801
|
[data-theme="light"] .settings-actions .btn-primary:hover{background:rgba(79,70,229,.1);border-color:#4f46e5}
|
|
806
802
|
.settings-saved{display:inline-flex;align-items:center;gap:6px;color:var(--green);font-size:12px;font-weight:600;opacity:0;transition:opacity .3s}
|
|
807
803
|
.settings-saved.show{opacity:1}
|
|
804
|
+
.team-guide{margin-bottom:20px;border:1px solid rgba(6,182,212,.2);border-radius:12px;background:linear-gradient(135deg,rgba(6,182,212,.04),rgba(99,102,241,.03));position:relative;overflow:hidden;padding:20px 22px 18px;display:none}
|
|
805
|
+
.team-guide::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,#06b6d4,#6366f1,#8b5cf6);opacity:.6}
|
|
806
|
+
.team-guide-title{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:700;color:var(--text);margin-bottom:4px}
|
|
807
|
+
.team-guide-subtitle{font-size:11.5px;color:var(--text-muted);line-height:1.6;margin-bottom:16px}
|
|
808
|
+
.team-guide-options{display:grid;grid-template-columns:1fr 1fr;gap:14px}
|
|
809
|
+
@media(max-width:800px){.team-guide-options{grid-template-columns:1fr}}
|
|
810
|
+
.team-guide-opt{border:1px solid var(--border);border-radius:10px;padding:16px;background:var(--bg-card);transition:border-color .2s,box-shadow .2s;cursor:default}
|
|
811
|
+
.team-guide-opt:hover{border-color:rgba(99,102,241,.3);box-shadow:0 4px 16px rgba(0,0,0,.06)}
|
|
812
|
+
.team-guide-opt-header{display:flex;align-items:center;gap:10px;margin-bottom:8px}
|
|
813
|
+
.team-guide-opt-icon{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:8px;font-size:16px;flex-shrink:0}
|
|
814
|
+
.team-guide-opt-title{font-size:13px;font-weight:700;color:var(--text)}
|
|
815
|
+
.team-guide-opt-desc{font-size:11px;color:var(--text-sec);line-height:1.7;margin-bottom:12px}
|
|
816
|
+
.team-guide-steps{padding:0 0 0 20px;margin:0 0 12px;counter-reset:none}
|
|
817
|
+
.team-guide-steps li{font-size:11px;color:var(--text-muted);line-height:1.9}
|
|
818
|
+
.team-guide-steps li::marker{color:var(--pri);font-weight:700;font-size:11px}
|
|
819
|
+
.team-guide-opt .btn-guide{font-size:11px;padding:5px 14px;border-radius:6px;font-weight:600;border:1px solid rgba(99,102,241,.25);background:rgba(99,102,241,.08);color:var(--pri);cursor:pointer;transition:background .15s,border-color .15s}
|
|
820
|
+
.team-guide-opt .btn-guide:hover{background:rgba(99,102,241,.14);border-color:var(--pri)}
|
|
821
|
+
.team-guide-dismiss{position:absolute;top:10px;right:12px;background:none;border:none;color:var(--text-muted);font-size:15px;cursor:pointer;padding:4px;line-height:1;opacity:.5;transition:opacity .15s}
|
|
822
|
+
.team-guide-dismiss:hover{opacity:1}
|
|
823
|
+
[data-theme="light"] .team-guide{background:linear-gradient(135deg,rgba(6,182,212,.03),rgba(79,70,229,.02));border-color:rgba(6,182,212,.15)}
|
|
824
|
+
[data-theme="light"] .team-guide-opt{box-shadow:0 1px 3px rgba(0,0,0,.03)}
|
|
825
|
+
[data-theme="light"] .team-guide-opt:hover{box-shadow:0 4px 16px rgba(0,0,0,.04)}
|
|
808
826
|
.model-health-bar{margin-bottom:20px;border-radius:var(--radius-lg);overflow:visible}
|
|
809
827
|
.mh-table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}
|
|
810
828
|
.mh-table th{text-align:left;padding:6px 12px;font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em;background:var(--bg);border-bottom:1px solid var(--border)}
|
|
@@ -864,9 +882,9 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
864
882
|
.analytics-section::before{display:none}
|
|
865
883
|
.analytics-section h3{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.08em;margin-bottom:16px;display:flex;align-items:center;gap:8px}
|
|
866
884
|
.analytics-section h3 .icon{font-size:14px;opacity:.6}
|
|
867
|
-
.chart-bars{display:flex;align-items:flex-end;gap:
|
|
885
|
+
.chart-bars{display:flex;align-items:flex-end;gap:0;padding:12px 0 4px;min-height:200px;position:relative;width:100%}
|
|
868
886
|
.chart-bars::before{content:'';position:absolute;left:0;right:0;bottom:24px;height:1px;background:var(--border);opacity:.4}
|
|
869
|
-
.chart-bar-wrap{flex:1 1 0;min-width:0;
|
|
887
|
+
.chart-bar-wrap{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;gap:4px;position:relative;cursor:pointer}
|
|
870
888
|
.chart-bar-col{width:100%;height:160px;display:flex;flex-direction:column;justify-content:flex-end;align-items:center}
|
|
871
889
|
.chart-bar-wrap:hover .chart-bar{opacity:1;filter:brightness(1.2);transform:scaleY(1.02);transform-origin:bottom}
|
|
872
890
|
.chart-bar-wrap:hover .chart-bar-label{color:var(--text)}
|
|
@@ -877,7 +895,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
877
895
|
.chart-bar.violet{background:linear-gradient(180deg,#8b5cf6 0%,#6366f1 100%)}
|
|
878
896
|
.chart-bar.green{background:linear-gradient(180deg,#34d399 0%,#10b981 100%);box-shadow:0 1px 4px rgba(16,185,129,.12)}
|
|
879
897
|
.chart-bar.zero{width:100%;max-width:20px;min-width:4px;height:2px!important;background:var(--border);opacity:.25;border-radius:1px;box-shadow:none}
|
|
880
|
-
.chart-bar-label{font-size:8px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:40px;text-align:center;transition:color .15s;letter-spacing:0}
|
|
898
|
+
.chart-bar-label{font-size:8px;line-height:1;min-height:10px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:40px;text-align:center;transition:color .15s;letter-spacing:0}
|
|
881
899
|
.chart-legend{display:flex;gap:14px;margin-top:12px;flex-wrap:wrap;font-size:11px;color:var(--text-sec);font-weight:500}
|
|
882
900
|
.chart-legend span{display:inline-flex;align-items:center;gap:5px}
|
|
883
901
|
.chart-legend .dot{width:8px;height:8px;border-radius:2px}
|
|
@@ -1028,7 +1046,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1028
1046
|
<button class="tab" data-view="analytics" onclick="switchView('analytics')" data-i18n="tab.analytics">\u{1F4CA} Analytics</button>
|
|
1029
1047
|
<button class="tab" data-view="logs" onclick="switchView('logs')" data-i18n="tab.logs">\u{1F4DD} Logs</button>
|
|
1030
1048
|
<button class="tab" data-view="import" onclick="switchView('import')" data-i18n="tab.import">\u{1F4E5} Import</button>
|
|
1031
|
-
<button class="tab" data-view="admin" onclick="switchView('admin')"
|
|
1049
|
+
<button class="tab" data-view="admin" onclick="switchView('admin')" data-i18n="tab.admin">\u{1F6E1} Admin</button>
|
|
1032
1050
|
<button class="tab" data-view="settings" onclick="switchView('settings')" data-i18n="tab.settings">\u2699 Settings</button>
|
|
1033
1051
|
</nav>
|
|
1034
1052
|
</div>
|
|
@@ -1268,24 +1286,25 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1268
1286
|
<!-- ─── Settings View ─── -->
|
|
1269
1287
|
<div class="settings-view" id="settingsView">
|
|
1270
1288
|
<div class="settings-tabs-bar">
|
|
1271
|
-
<button class="settings-tab-btn active" data-tab="
|
|
1272
|
-
<button class="settings-tab-btn" data-tab="summarizer" onclick="switchSettingsTab('summarizer',this)"><span class="stab-dot"></span><span data-i18n="settings.summarizer">Summarizer Model</span></button>
|
|
1273
|
-
<button class="settings-tab-btn" data-tab="skill" onclick="switchSettingsTab('skill',this)"><span class="stab-dot"></span><span data-i18n="settings.skill">Skill Evolution</span></button>
|
|
1289
|
+
<button class="settings-tab-btn active" data-tab="models" onclick="switchSettingsTab('models',this)"><span class="stab-dot"></span><span data-i18n="settings.models">AI Models</span></button>
|
|
1274
1290
|
<button class="settings-tab-btn" data-tab="hub" onclick="switchSettingsTab('hub',this)"><span class="stab-dot"></span><span data-i18n="settings.hub">Hub & Team</span></button>
|
|
1275
1291
|
<button class="settings-tab-btn" data-tab="general" onclick="switchSettingsTab('general',this)"><span class="stab-dot"></span><span data-i18n="settings.general">General</span></button>
|
|
1276
1292
|
</div>
|
|
1277
1293
|
<div class="settings-cards-grid">
|
|
1278
1294
|
|
|
1279
|
-
<!-- ══ Card: Embedding
|
|
1280
|
-
<div class="settings-card card-
|
|
1295
|
+
<!-- ══ Card: AI Models (Embedding + Summarizer + Skill) ══ -->
|
|
1296
|
+
<div class="settings-card card-models stab-active" data-stab="models">
|
|
1281
1297
|
<div class="settings-card-header">
|
|
1282
|
-
<div class="settings-card-icon" style="background:rgba(99,102,241,.1);border-color:rgba(99,102,241,.15)">\u{
|
|
1298
|
+
<div class="settings-card-icon" style="background:rgba(99,102,241,.1);border-color:rgba(99,102,241,.15)">\u{1F9E0}</div>
|
|
1283
1299
|
<div class="settings-card-title-wrap">
|
|
1284
|
-
<div class="settings-card-title" data-i18n="settings.
|
|
1285
|
-
<div class="settings-card-desc" data-i18n="settings.
|
|
1300
|
+
<div class="settings-card-title" data-i18n="settings.models">AI Models</div>
|
|
1301
|
+
<div class="settings-card-desc" data-i18n="settings.models.desc">Configure embedding, summarizer and skill evolution models</div>
|
|
1286
1302
|
</div>
|
|
1287
1303
|
</div>
|
|
1288
1304
|
<div class="settings-card-body">
|
|
1305
|
+
<!-- Embedding Model section -->
|
|
1306
|
+
<div class="settings-card-subtitle">\u{1F4E1} <span data-i18n="settings.embedding">Embedding Model</span></div>
|
|
1307
|
+
<div class="field-hint" style="margin-bottom:10px" data-i18n="settings.embedding.desc">Vector embedding model for memory search and retrieval</div>
|
|
1289
1308
|
<div class="settings-grid">
|
|
1290
1309
|
<div class="settings-field">
|
|
1291
1310
|
<label data-i18n="settings.provider">Provider</label>
|
|
@@ -1321,19 +1340,12 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1321
1340
|
<button class="btn btn-sm btn-ghost" onclick="testModel('embedding')" id="testEmbBtn" data-i18n="settings.test">Test Connection</button>
|
|
1322
1341
|
<span class="test-result" id="testEmbResult"></span>
|
|
1323
1342
|
</div>
|
|
1324
|
-
</div>
|
|
1325
|
-
</div>
|
|
1326
1343
|
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
<div class="settings-card-
|
|
1331
|
-
<div class="
|
|
1332
|
-
<div class="settings-card-title" data-i18n="settings.summarizer">Summarizer Model</div>
|
|
1333
|
-
<div class="settings-card-desc" data-i18n="settings.summarizer.desc">LLM for memory summarization, deduplication and analysis</div>
|
|
1334
|
-
</div>
|
|
1335
|
-
</div>
|
|
1336
|
-
<div class="settings-card-body">
|
|
1344
|
+
<div class="settings-card-divider"></div>
|
|
1345
|
+
|
|
1346
|
+
<!-- Summarizer Model section -->
|
|
1347
|
+
<div class="settings-card-subtitle">\u{1F4DD} <span data-i18n="settings.summarizer">Summarizer Model</span></div>
|
|
1348
|
+
<div class="field-hint" style="margin-bottom:10px" data-i18n="settings.summarizer.desc">LLM for memory summarization, deduplication and analysis</div>
|
|
1337
1349
|
<div class="settings-grid">
|
|
1338
1350
|
<div class="settings-field">
|
|
1339
1351
|
<label data-i18n="settings.provider">Provider</label>
|
|
@@ -1373,19 +1385,12 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1373
1385
|
<button class="btn btn-sm btn-ghost" onclick="testModel('summarizer')" id="testSumBtn" data-i18n="settings.test">Test Connection</button>
|
|
1374
1386
|
<span class="test-result" id="testSumResult"></span>
|
|
1375
1387
|
</div>
|
|
1376
|
-
</div>
|
|
1377
|
-
</div>
|
|
1378
1388
|
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
<div class="settings-card-
|
|
1383
|
-
<div class="
|
|
1384
|
-
<div class="settings-card-title" data-i18n="settings.skill">Skill Evolution</div>
|
|
1385
|
-
<div class="settings-card-desc" data-i18n="settings.skill.desc">Auto-extract reusable skills from conversation patterns</div>
|
|
1386
|
-
</div>
|
|
1387
|
-
</div>
|
|
1388
|
-
<div class="settings-card-body">
|
|
1389
|
+
<div class="settings-card-divider"></div>
|
|
1390
|
+
|
|
1391
|
+
<!-- Skill Evolution section -->
|
|
1392
|
+
<div class="settings-card-subtitle">\u{1F527} <span data-i18n="settings.skill">Skill Evolution</span></div>
|
|
1393
|
+
<div class="field-hint" style="margin-bottom:10px" data-i18n="settings.skill.desc">Auto-extract reusable skills from conversation patterns</div>
|
|
1389
1394
|
<div class="settings-grid">
|
|
1390
1395
|
<div class="settings-toggle">
|
|
1391
1396
|
<label class="toggle-switch"><input type="checkbox" id="cfgSkillEnabled"><span class="toggle-slider"></span></label>
|
|
@@ -1404,45 +1409,54 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1404
1409
|
<input type="number" id="cfgSkillMinChunks" placeholder="6">
|
|
1405
1410
|
</div>
|
|
1406
1411
|
</div>
|
|
1407
|
-
<div
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1412
|
+
<div style="margin-top:14px">
|
|
1413
|
+
<div class="settings-card-subtitle" style="margin-bottom:4px" data-i18n="settings.skill.model">Skill Dedicated Model</div>
|
|
1414
|
+
<div class="field-hint" style="margin-bottom:12px" data-i18n="settings.skill.model.hint">If not configured, the main Summarizer Model above will be used for skill generation. Configure a dedicated model here for higher quality skill output.</div>
|
|
1415
|
+
<div class="settings-grid">
|
|
1416
|
+
<div class="settings-field">
|
|
1417
|
+
<label data-i18n="settings.provider">Provider</label>
|
|
1418
|
+
<select id="cfgSkillProvider" onchange="onProviderChange('skill')">
|
|
1419
|
+
<option value="">\u2014 <span data-i18n="settings.skill.usemain">Use main summarizer</span> \u2014</option>
|
|
1420
|
+
<option value="openai_compatible">OpenAI Compatible</option>
|
|
1421
|
+
<option value="openai">OpenAI</option>
|
|
1422
|
+
<option value="siliconflow">SiliconFlow (\u7845\u57FA\u6D41\u52A8)</option>
|
|
1423
|
+
<option value="zhipu">Zhipu AI (\u667A\u8C31)</option>
|
|
1424
|
+
<option value="deepseek">DeepSeek</option>
|
|
1425
|
+
<option value="bailian">Alibaba Bailian (\u767E\u70BC)</option>
|
|
1426
|
+
<option value="moonshot">Moonshot (Kimi)</option>
|
|
1427
|
+
<option value="anthropic">Anthropic</option>
|
|
1428
|
+
<option value="gemini">Gemini</option>
|
|
1429
|
+
<option value="azure_openai">Azure OpenAI</option>
|
|
1430
|
+
<option value="bedrock">Bedrock</option>
|
|
1431
|
+
<option value="openclaw">OpenClaw Host</option>
|
|
1432
|
+
</select>
|
|
1433
|
+
</div>
|
|
1434
|
+
<div class="settings-field">
|
|
1435
|
+
<label data-i18n="settings.model">Model</label>
|
|
1436
|
+
<input type="text" id="cfgSkillModel" placeholder="e.g. claude-4.6-opus">
|
|
1437
|
+
</div>
|
|
1438
|
+
<div class="settings-field full-width">
|
|
1439
|
+
<label>Endpoint</label>
|
|
1440
|
+
<input type="text" id="cfgSkillEndpoint" placeholder="https://...">
|
|
1441
|
+
</div>
|
|
1442
|
+
<div class="settings-field">
|
|
1443
|
+
<label>API Key</label>
|
|
1444
|
+
<input type="password" id="cfgSkillApiKey" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022">
|
|
1445
|
+
</div>
|
|
1436
1446
|
</div>
|
|
1437
|
-
<div class="
|
|
1438
|
-
<
|
|
1439
|
-
<
|
|
1447
|
+
<div class="test-conn-row">
|
|
1448
|
+
<button class="btn btn-sm btn-ghost" onclick="testModel('skill')" id="testSkillBtn" data-i18n="settings.test">Test Connection</button>
|
|
1449
|
+
<span class="test-result" id="testSkillResult"></span>
|
|
1440
1450
|
</div>
|
|
1441
1451
|
</div>
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1452
|
+
|
|
1453
|
+
<div class="settings-card-divider"></div>
|
|
1454
|
+
<div class="settings-actions">
|
|
1455
|
+
<span class="settings-saved" id="modelsSaved">\u2713 <span data-i18n="settings.saved">Saved</span></span>
|
|
1456
|
+
<button class="btn btn-ghost" onclick="loadConfig()" data-i18n="settings.reset">Reset</button>
|
|
1457
|
+
<button class="btn btn-primary" onclick="saveModelsConfig()" data-i18n="settings.save">Save Settings</button>
|
|
1445
1458
|
</div>
|
|
1459
|
+
<div style="font-size:11px;color:var(--text-muted);text-align:right;margin-top:4px" data-i18n="settings.restart.hint">Some changes require restarting the OpenClaw gateway to take effect.</div>
|
|
1446
1460
|
</div>
|
|
1447
1461
|
</div>
|
|
1448
1462
|
|
|
@@ -1456,6 +1470,43 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1456
1470
|
</div>
|
|
1457
1471
|
</div>
|
|
1458
1472
|
<div class="settings-card-body">
|
|
1473
|
+
<!-- team setup guide (inside Hub card) -->
|
|
1474
|
+
<div class="team-guide" id="teamSetupGuide">
|
|
1475
|
+
<button class="team-guide-dismiss" onclick="dismissTeamGuide()" title="Dismiss">×</button>
|
|
1476
|
+
<div class="team-guide-title">\u{1F680} <span data-i18n="guide.title">Get Started with Team Collaboration</span></div>
|
|
1477
|
+
<div class="team-guide-subtitle" data-i18n="guide.subtitle">MemOS supports team memory sharing. Choose one of the following options to enable collaboration, or continue using local-only mode.</div>
|
|
1478
|
+
<div class="team-guide-options">
|
|
1479
|
+
<div class="team-guide-opt">
|
|
1480
|
+
<div class="team-guide-opt-header">
|
|
1481
|
+
<div class="team-guide-opt-icon" style="background:rgba(6,182,212,.1);border:1px solid rgba(6,182,212,.15)">\u{1F310}</div>
|
|
1482
|
+
<div class="team-guide-opt-title" data-i18n="guide.join.title">Join a Remote Team</div>
|
|
1483
|
+
</div>
|
|
1484
|
+
<div class="team-guide-opt-desc" data-i18n="guide.join.desc">Your team already has a Hub running? Join it to share memories, tasks and skills with team members.</div>
|
|
1485
|
+
<ol class="team-guide-steps">
|
|
1486
|
+
<li><span data-i18n="guide.join.s1">Ask your Hub admin for the Hub Address and Team Token</span></li>
|
|
1487
|
+
<li><span data-i18n="guide.join.s2">Enable sharing above, select "Client" mode</span></li>
|
|
1488
|
+
<li><span data-i18n="guide.join.s3">Fill in Hub Address and Team Token, click "Test Connection"</span></li>
|
|
1489
|
+
<li><span data-i18n="guide.join.s4">Save settings, restart the OpenClaw gateway, then refresh this page</span></li>
|
|
1490
|
+
</ol>
|
|
1491
|
+
<button class="btn-guide" onclick="guideGoToHub('client')" data-i18n="guide.join.btn">\u2192 Configure Client Mode</button>
|
|
1492
|
+
</div>
|
|
1493
|
+
<div class="team-guide-opt">
|
|
1494
|
+
<div class="team-guide-opt-header">
|
|
1495
|
+
<div class="team-guide-opt-icon" style="background:rgba(139,92,246,.1);border:1px solid rgba(139,92,246,.15)">\u{1F5A5}\uFE0F</div>
|
|
1496
|
+
<div class="team-guide-opt-title" data-i18n="guide.hub.title">Start Your Own Hub</div>
|
|
1497
|
+
</div>
|
|
1498
|
+
<div class="team-guide-opt-desc" data-i18n="guide.hub.desc">Be the team server. Run a Hub on this device so others can connect and share memories with you.</div>
|
|
1499
|
+
<ol class="team-guide-steps">
|
|
1500
|
+
<li><span data-i18n="guide.hub.s1">Enable sharing above, select "Hub" mode</span></li>
|
|
1501
|
+
<li><span data-i18n="guide.hub.s2">Set a team name, save settings, restart the gateway, then refresh this page</span></li>
|
|
1502
|
+
<li><span data-i18n="guide.hub.s3">Share the Hub Address and Team Token with your team members</span></li>
|
|
1503
|
+
<li><span data-i18n="guide.hub.s4">Approve join requests in the Admin Panel</span></li>
|
|
1504
|
+
</ol>
|
|
1505
|
+
<button class="btn-guide" onclick="guideGoToHub('hub')" data-i18n="guide.hub.btn">\u2192 Configure Hub Mode</button>
|
|
1506
|
+
</div>
|
|
1507
|
+
</div>
|
|
1508
|
+
</div>
|
|
1509
|
+
|
|
1459
1510
|
<div class="field-hint" style="margin-bottom:12px" data-i18n="settings.hub.enable.hint">Enable to share memories, tasks and skills with your team. When disabled, all features work normally in local-only mode.</div>
|
|
1460
1511
|
<div class="settings-toggle" style="margin-bottom:16px">
|
|
1461
1512
|
<label class="toggle-switch">
|
|
@@ -1503,7 +1554,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1503
1554
|
<div style="font-weight:700;color:var(--text);margin-bottom:4px" data-i18n="settings.hub.clientSteps.title">Quick Setup (3 steps)</div>
|
|
1504
1555
|
<div><span style="color:var(--accent)">1.</span> <span data-i18n="settings.hub.clientSteps.s1">Ask your Hub admin for Hub Address and Team Token</span></div>
|
|
1505
1556
|
<div><span style="color:var(--accent)">2.</span> <span data-i18n="settings.hub.clientSteps.s2">Fill them in below, click "Test Connection" to verify</span></div>
|
|
1506
|
-
<div><span style="color:var(--accent)">3.</span> <span data-i18n="settings.hub.clientSteps.s3">Click "Save Settings",
|
|
1557
|
+
<div><span style="color:var(--accent)">3.</span> <span data-i18n="settings.hub.clientSteps.s3">Click "Save Settings", restart OpenClaw gateway, then refresh this page</span></div>
|
|
1507
1558
|
</div>
|
|
1508
1559
|
<div class="settings-grid">
|
|
1509
1560
|
<div class="settings-field full-width">
|
|
@@ -1525,10 +1576,20 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1525
1576
|
</div>
|
|
1526
1577
|
</div>
|
|
1527
1578
|
|
|
1579
|
+
<div id="sharingPanelsWrap" style="display:none">
|
|
1580
|
+
<div class="settings-card-divider"></div>
|
|
1581
|
+
<div id="sharingStatusPanel"></div>
|
|
1582
|
+
<div id="sharingTeamPanel"></div>
|
|
1583
|
+
<div id="sharingAdminPanel"></div>
|
|
1584
|
+
</div>
|
|
1585
|
+
|
|
1528
1586
|
<div class="settings-card-divider"></div>
|
|
1529
|
-
<div
|
|
1530
|
-
|
|
1531
|
-
|
|
1587
|
+
<div class="settings-actions">
|
|
1588
|
+
<span class="settings-saved" id="hubSaved">\u2713 <span data-i18n="settings.saved">Saved</span></span>
|
|
1589
|
+
<button class="btn btn-ghost" onclick="loadConfig()" data-i18n="settings.reset">Reset</button>
|
|
1590
|
+
<button class="btn btn-primary" onclick="saveHubConfig()" data-i18n="settings.save">Save Settings</button>
|
|
1591
|
+
</div>
|
|
1592
|
+
<div style="font-size:11px;color:var(--text-muted);text-align:right;margin-top:4px" data-i18n="settings.restart.hint">Some changes require restarting the OpenClaw gateway to take effect.</div>
|
|
1532
1593
|
</div>
|
|
1533
1594
|
</div>
|
|
1534
1595
|
|
|
@@ -1560,39 +1621,44 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1560
1621
|
<label data-i18n="settings.telemetry.enabled">Enable Anonymous Telemetry</label>
|
|
1561
1622
|
</div>
|
|
1562
1623
|
<div class="field-hint" style="margin-top:6px" data-i18n="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.</div>
|
|
1624
|
+
|
|
1625
|
+
<div class="settings-card-divider"></div>
|
|
1626
|
+
<div class="settings-actions">
|
|
1627
|
+
<span class="settings-saved" id="generalSaved">\u2713 <span data-i18n="settings.saved">Saved</span></span>
|
|
1628
|
+
<button class="btn btn-ghost" onclick="loadConfig()" data-i18n="settings.reset">Reset</button>
|
|
1629
|
+
<button class="btn btn-primary" onclick="saveGeneralConfig()" data-i18n="settings.save">Save Settings</button>
|
|
1630
|
+
</div>
|
|
1563
1631
|
</div>
|
|
1564
1632
|
</div>
|
|
1565
1633
|
|
|
1566
1634
|
</div>
|
|
1567
1635
|
|
|
1568
|
-
|
|
1569
|
-
<span class="settings-saved" id="settingsSaved">\u2713 <span data-i18n="settings.saved">Saved</span></span>
|
|
1570
|
-
<button class="btn btn-ghost" onclick="loadConfig()" data-i18n="settings.reset">Reset</button>
|
|
1571
|
-
<button class="btn btn-primary" onclick="saveConfig()" data-i18n="settings.save">Save Settings</button>
|
|
1572
|
-
</div>
|
|
1573
|
-
<div style="font-size:11px;color:var(--text-muted);text-align:right;margin-top:4px" data-i18n="settings.restart.hint">Some changes require restarting the OpenClaw gateway to take effect.</div>
|
|
1636
|
+
|
|
1574
1637
|
</div>
|
|
1575
1638
|
|
|
1576
1639
|
<!-- ─── Admin Page ─── -->
|
|
1577
1640
|
<div class="admin-view" id="adminView">
|
|
1578
|
-
<div
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
<
|
|
1641
|
+
<div id="adminNotEnabled" style="display:none"></div>
|
|
1642
|
+
<div id="adminMainContent">
|
|
1643
|
+
<div class="admin-header">
|
|
1644
|
+
<div class="admin-header-top">
|
|
1645
|
+
<h2><span class="ah-icon">\u{1F6E1}</span> <span data-i18n="admin.title">Hub Admin Panel</span></h2>
|
|
1646
|
+
<button class="btn btn-sm btn-ghost" onclick="loadAdminData()" style="backdrop-filter:blur(8px)" data-i18n="admin.refresh">\u21BB Refresh</button>
|
|
1647
|
+
</div>
|
|
1648
|
+
<div class="admin-header-sub" data-i18n="admin.subtitle">Manage team members, groups, and shared resources</div>
|
|
1649
|
+
<div class="admin-stat-row" id="adminStats"></div>
|
|
1582
1650
|
</div>
|
|
1583
|
-
<div class="admin-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
<
|
|
1590
|
-
<
|
|
1651
|
+
<div class="admin-tabs" id="adminTabsBar">
|
|
1652
|
+
<button class="admin-tab active" onclick="switchAdminTab('users',this)"><span class="at-icon">\u{1F465}</span> <span data-i18n="admin.tab.users">Users</span> <span class="at-count" id="adminTabCountUsers">0</span></button>
|
|
1653
|
+
<button class="admin-tab" onclick="switchAdminTab('sharedMemories',this)"><span class="at-icon">\u{1F4AD}</span> <span data-i18n="admin.tab.sharedMemories">Shared Memories</span> <span class="at-count" id="adminTabCountMemories">0</span></button>
|
|
1654
|
+
<button class="admin-tab" onclick="switchAdminTab('memories',this)"><span class="at-icon">\u{1F4CB}</span> <span data-i18n="admin.tab.memories">Shared Tasks</span> <span class="at-count" id="adminTabCountTasks">0</span></button>
|
|
1655
|
+
<button class="admin-tab" onclick="switchAdminTab('skills',this)"><span class="at-icon">\u{1F9E0}</span> <span data-i18n="admin.tab.skills">Shared Skills</span> <span class="at-count" id="adminTabCountSkills">0</span></button>
|
|
1656
|
+
</div>
|
|
1657
|
+
<div class="admin-panel active" id="adminUsersPanel"></div>
|
|
1658
|
+
<div class="admin-panel" id="adminSharedMemoriesPanel"></div>
|
|
1659
|
+
<div class="admin-panel" id="adminMemoriesPanel"></div>
|
|
1660
|
+
<div class="admin-panel" id="adminSkillsPanel"></div>
|
|
1591
1661
|
</div>
|
|
1592
|
-
<div class="admin-panel active" id="adminUsersPanel"></div>
|
|
1593
|
-
<div class="admin-panel" id="adminSharedMemoriesPanel"></div>
|
|
1594
|
-
<div class="admin-panel" id="adminMemoriesPanel"></div>
|
|
1595
|
-
<div class="admin-panel" id="adminSkillsPanel"></div>
|
|
1596
1662
|
</div>
|
|
1597
1663
|
|
|
1598
1664
|
<!-- ─── Import Page ─── -->
|
|
@@ -1961,6 +2027,8 @@ const I18N={
|
|
|
1961
2027
|
'tab.import':'\u{1F4E5} Import',
|
|
1962
2028
|
'tab.settings':'\u2699 Settings',
|
|
1963
2029
|
'settings.modelconfig':'Model Configuration',
|
|
2030
|
+
'settings.models':'AI Models',
|
|
2031
|
+
'settings.models.desc':'Configure embedding, summarizer and skill evolution models',
|
|
1964
2032
|
'settings.modelhealth':'Model Health',
|
|
1965
2033
|
'settings.embedding':'Embedding Model',
|
|
1966
2034
|
'settings.summarizer':'Summarizer Model',
|
|
@@ -1999,7 +2067,7 @@ const I18N={
|
|
|
1999
2067
|
'settings.save':'Save Settings',
|
|
2000
2068
|
'settings.reset':'Reset',
|
|
2001
2069
|
'settings.saved':'Saved',
|
|
2002
|
-
'settings.restart.hint':'Some changes require restarting the OpenClaw gateway to take effect.',
|
|
2070
|
+
'settings.restart.hint':'Some changes require restarting the OpenClaw gateway to take effect. After restarting, please refresh this page.',
|
|
2003
2071
|
'settings.save.fail':'Failed to save settings',
|
|
2004
2072
|
'settings.save.emb.required':'Embedding model is required. Please configure an embedding model before saving.',
|
|
2005
2073
|
'settings.save.emb.fail':'Embedding model test failed, cannot save',
|
|
@@ -2129,11 +2197,11 @@ const I18N={
|
|
|
2129
2197
|
'settings.hub.clientSteps.title':'Quick Setup (3 steps)',
|
|
2130
2198
|
'settings.hub.clientSteps.s1':'Ask your Hub admin for Hub Address and Team Token',
|
|
2131
2199
|
'settings.hub.clientSteps.s2':'Fill them in below, click "Test Connection" to verify',
|
|
2132
|
-
'settings.hub.clientSteps.s3':'Click "Save Settings",
|
|
2200
|
+
'settings.hub.clientSteps.s3':'Click "Save Settings", restart OpenClaw gateway, then refresh this page',
|
|
2133
2201
|
'settings.hub.shareInfo.title':'Share this info with your team members:',
|
|
2134
2202
|
'settings.hub.shareInfo.yourIP':'your-IP',
|
|
2135
2203
|
'settings.hub.shareInfo.clickCopy':'Click to copy',
|
|
2136
|
-
'settings.hub.restartAlert':'Hub sharing config saved! Please restart the OpenClaw gateway for changes to take effect.\\n\\nRun: openclaw gateway stop && openclaw gateway',
|
|
2204
|
+
'settings.hub.restartAlert':'Hub sharing config saved! Please restart the OpenClaw gateway for changes to take effect, then refresh this page.\\n\\nRun: openclaw gateway stop && openclaw gateway start',
|
|
2137
2205
|
'settings.hub.hubAddress':'Hub Address',
|
|
2138
2206
|
'settings.hub.hubAddress.hint':'Hub server address, e.g. 192.168.1.100:18800',
|
|
2139
2207
|
'settings.hub.teamTokenClient':'Team Token',
|
|
@@ -2346,8 +2414,37 @@ const I18N={
|
|
|
2346
2414
|
'update.installing':'Installing...',
|
|
2347
2415
|
'update.success':'Updated!',
|
|
2348
2416
|
'update.failed':'Update failed',
|
|
2349
|
-
'update.restarting':'Restarting service...',
|
|
2350
|
-
'update.dismiss':'Dismiss'
|
|
2417
|
+
'update.restarting':'Restarting service, page will refresh automatically...',
|
|
2418
|
+
'update.dismiss':'Dismiss',
|
|
2419
|
+
'sharing.disable.confirm.hub':'You are about to shut down the Hub server.\\n\\nWhat will happen:\\n\\u2022 All connected team members will be disconnected\\n\\u2022 They will no longer be able to sync memories, tasks, or skills\\n\\u2022 Shared data is preserved and will be available when you re-enable\\n\\nAre you sure?',
|
|
2420
|
+
'sharing.disable.confirm.client':'You are about to disconnect from the team Hub.\\n\\nWhat will happen:\\n\\u2022 You will no longer receive shared memories, tasks, or skills from the team\\n\\u2022 Your local data is preserved and will not be affected\\n\\u2022 You can reconnect later by re-enabling sharing\\n\\nAre you sure?',
|
|
2421
|
+
'sharing.disable.restartAlert':'Sharing has been disabled. Please restart the OpenClaw gateway for the change to take effect, then refresh this page.\\n\\nRun: openclaw gateway stop && openclaw gateway start',
|
|
2422
|
+
'admin.notEnabled.title':'Team sharing is not enabled',
|
|
2423
|
+
'admin.notEnabled.desc':'The Admin Panel is used to manage team members, shared memories, tasks, and skills. To use this feature, you need to enable Hub sharing first.',
|
|
2424
|
+
'admin.notEnabled.setupHub':'Set Up as Hub Server',
|
|
2425
|
+
'admin.notEnabled.joinTeam':'Join an Existing Team',
|
|
2426
|
+
'admin.notEnabled.hint':'If you have previously configured sharing, your data is still preserved. Re-enabling sharing will restore access to all shared content.',
|
|
2427
|
+
'sharing.disconnected.hint':'Unable to reach the Hub server. The Hub may be offline or the network is unavailable.',
|
|
2428
|
+
'sharing.retryConnection':'Retry Connection',
|
|
2429
|
+
'sharing.retryConnection.loading':'Connecting...',
|
|
2430
|
+
'sharing.retryConnection.success':'Connected successfully!',
|
|
2431
|
+
'sharing.retryConnection.fail':'Still unable to connect. Check if the Hub is online.',
|
|
2432
|
+
'guide.title':'Get Started with Team Collaboration',
|
|
2433
|
+
'guide.subtitle':'MemOS supports team memory sharing. Choose one of the following options to enable collaboration, or continue using local-only mode.',
|
|
2434
|
+
'guide.join.title':'Join a Remote Team',
|
|
2435
|
+
'guide.join.desc':'Your team already has a Hub running? Join it to share memories, tasks and skills with team members.',
|
|
2436
|
+
'guide.join.s1':'Ask your Hub admin for the Hub Address and Team Token',
|
|
2437
|
+
'guide.join.s2':'Go to Settings \u2192 Hub & Team, enable sharing, select "Client" mode',
|
|
2438
|
+
'guide.join.s3':'Fill in Hub Address and Team Token, click "Test Connection"',
|
|
2439
|
+
'guide.join.s4':'Save settings, restart the OpenClaw gateway, then refresh this page',
|
|
2440
|
+
'guide.join.btn':'\u2192 Configure Client Mode',
|
|
2441
|
+
'guide.hub.title':'Start Your Own Hub',
|
|
2442
|
+
'guide.hub.desc':'Be the team server. Run a Hub on this device so others can connect and share memories with you.',
|
|
2443
|
+
'guide.hub.s1':'Go to Settings \u2192 Hub & Team, enable sharing, select "Hub" mode',
|
|
2444
|
+
'guide.hub.s2':'Set a team name, save settings, restart the gateway, then refresh this page',
|
|
2445
|
+
'guide.hub.s3':'Share the Hub Address and Team Token with your team members',
|
|
2446
|
+
'guide.hub.s4':'Approve join requests in the Admin Panel',
|
|
2447
|
+
'guide.hub.btn':'\u2192 Configure Hub Mode'
|
|
2351
2448
|
},
|
|
2352
2449
|
zh:{
|
|
2353
2450
|
'title':'MemOS 记忆',
|
|
@@ -2517,6 +2614,8 @@ const I18N={
|
|
|
2517
2614
|
'tab.import':'\u{1F4E5} 导入',
|
|
2518
2615
|
'tab.settings':'\u2699 设置',
|
|
2519
2616
|
'settings.modelconfig':'模型配置',
|
|
2617
|
+
'settings.models':'AI 模型',
|
|
2618
|
+
'settings.models.desc':'配置嵌入模型、摘要模型和技能进化模型',
|
|
2520
2619
|
'settings.modelhealth':'模型健康',
|
|
2521
2620
|
'settings.embedding':'嵌入模型',
|
|
2522
2621
|
'settings.summarizer':'摘要模型',
|
|
@@ -2555,7 +2654,7 @@ const I18N={
|
|
|
2555
2654
|
'settings.save':'保存设置',
|
|
2556
2655
|
'settings.reset':'重置',
|
|
2557
2656
|
'settings.saved':'已保存',
|
|
2558
|
-
'settings.restart.hint':'部分设置修改后需要重启 OpenClaw
|
|
2657
|
+
'settings.restart.hint':'部分设置修改后需要重启 OpenClaw 网关才能生效。重启后请刷新此页面。',
|
|
2559
2658
|
'settings.save.fail':'保存设置失败',
|
|
2560
2659
|
'settings.save.emb.required':'嵌入模型为必填项,请先配置嵌入模型再保存。',
|
|
2561
2660
|
'settings.save.emb.fail':'嵌入模型测试失败,无法保存',
|
|
@@ -2685,11 +2784,11 @@ const I18N={
|
|
|
2685
2784
|
'settings.hub.clientSteps.title':'快速配置(3 步)',
|
|
2686
2785
|
'settings.hub.clientSteps.s1':'向 Hub 管理员获取 Hub 地址和团队令牌',
|
|
2687
2786
|
'settings.hub.clientSteps.s2':'填入下方,点击"测试连接"验证连通性',
|
|
2688
|
-
'settings.hub.clientSteps.s3':'
|
|
2787
|
+
'settings.hub.clientSteps.s3':'点击「保存设置」,重启 OpenClaw 网关,然后刷新此页面',
|
|
2689
2788
|
'settings.hub.shareInfo.title':'请将以下信息分享给团队成员:',
|
|
2690
2789
|
'settings.hub.shareInfo.yourIP':'你的IP',
|
|
2691
2790
|
'settings.hub.shareInfo.clickCopy':'点击复制',
|
|
2692
|
-
'settings.hub.restartAlert':'Hub 共享配置已保存!请重启 OpenClaw
|
|
2791
|
+
'settings.hub.restartAlert':'Hub 共享配置已保存!请重启 OpenClaw 网关使配置生效,重启后请刷新此页面。\\n\\n执行命令:openclaw gateway stop && openclaw gateway start',
|
|
2693
2792
|
'settings.hub.hubAddress':'Hub 地址',
|
|
2694
2793
|
'settings.hub.hubAddress.hint':'Hub 服务器地址,如 192.168.1.100:18800',
|
|
2695
2794
|
'settings.hub.teamTokenClient':'团队令牌',
|
|
@@ -2902,8 +3001,37 @@ const I18N={
|
|
|
2902
3001
|
'update.installing':'安装中...',
|
|
2903
3002
|
'update.success':'更新完成',
|
|
2904
3003
|
'update.failed':'更新失败',
|
|
2905
|
-
'update.restarting':'
|
|
2906
|
-
'update.dismiss':'关闭'
|
|
3004
|
+
'update.restarting':'正在重启服务,页面将自动刷新...',
|
|
3005
|
+
'update.dismiss':'关闭',
|
|
3006
|
+
'sharing.disable.confirm.hub':'你即将关闭 Hub 服务。\\n\\n关闭后将会:\\n\\u2022 所有已连接的团队成员将断开连接\\n\\u2022 他们将无法继续同步记忆、任务和技能\\n\\u2022 已共享的数据会保留,重新开启后仍可使用\\n\\n确定要关闭吗?',
|
|
3007
|
+
'sharing.disable.confirm.client':'你即将断开与团队 Hub 的连接。\\n\\n断开后将会:\\n\\u2022 你将无法再接收团队共享的记忆、任务和技能\\n\\u2022 你的本地数据不受影响,会完整保留\\n\\u2022 之后可以随时重新开启共享来恢复连接\\n\\n确定要断开吗?',
|
|
3008
|
+
'sharing.disable.restartAlert':'共享已关闭。请重启 OpenClaw 网关使更改生效,重启后请刷新此页面。\\n\\n执行命令:openclaw gateway stop && openclaw gateway start',
|
|
3009
|
+
'admin.notEnabled.title':'团队共享尚未开启',
|
|
3010
|
+
'admin.notEnabled.desc':'管理面板用于管理团队成员、共享的记忆、任务和技能。使用此功能前,需要先开启 Hub 共享。',
|
|
3011
|
+
'admin.notEnabled.setupHub':'配置为 Hub 服务端',
|
|
3012
|
+
'admin.notEnabled.joinTeam':'加入已有团队',
|
|
3013
|
+
'admin.notEnabled.hint':'如果之前配置过共享,你的数据仍然保留。重新开启共享即可恢复访问所有共享内容。',
|
|
3014
|
+
'sharing.disconnected.hint':'无法连接到 Hub 服务器,Hub 可能已下线或网络不可用。',
|
|
3015
|
+
'sharing.retryConnection':'重试连接',
|
|
3016
|
+
'sharing.retryConnection.loading':'连接中...',
|
|
3017
|
+
'sharing.retryConnection.success':'连接成功!',
|
|
3018
|
+
'sharing.retryConnection.fail':'仍然无法连接,请检查 Hub 是否在线。',
|
|
3019
|
+
'guide.title':'开始团队协作',
|
|
3020
|
+
'guide.subtitle':'MemOS 支持团队记忆共享。选择以下方式之一开启协作,或继续使用纯本地模式。',
|
|
3021
|
+
'guide.join.title':'加入远程团队',
|
|
3022
|
+
'guide.join.desc':'你的团队已有 Hub 在运行?加入即可与团队成员共享记忆、任务和技能。',
|
|
3023
|
+
'guide.join.s1':'向 Hub 管理员索取 Hub 地址和 Team Token',
|
|
3024
|
+
'guide.join.s2':'前往「设置 → Hub & Team」,开启共享,选择「Client」模式',
|
|
3025
|
+
'guide.join.s3':'填写 Hub 地址和 Team Token,点击「测试连接」',
|
|
3026
|
+
'guide.join.s4':'保存设置,重启 OpenClaw 网关,然后刷新此页面',
|
|
3027
|
+
'guide.join.btn':'\u2192 配置 Client 模式',
|
|
3028
|
+
'guide.hub.title':'自建 Hub 服务',
|
|
3029
|
+
'guide.hub.desc':'将本机作为团队服务端,让其他成员连接过来共享记忆。',
|
|
3030
|
+
'guide.hub.s1':'前往「设置 → Hub & Team」,开启共享,选择「Hub」模式',
|
|
3031
|
+
'guide.hub.s2':'设置团队名称,保存设置后重启网关,然后刷新此页面',
|
|
3032
|
+
'guide.hub.s3':'将 Hub 地址和 Team Token 分享给团队成员',
|
|
3033
|
+
'guide.hub.s4':'在管理面板中审批加入请求',
|
|
3034
|
+
'guide.hub.btn':'\u2192 配置 Hub 模式'
|
|
2907
3035
|
}
|
|
2908
3036
|
};
|
|
2909
3037
|
const LANG_KEY='memos-viewer-lang';
|
|
@@ -3028,8 +3156,6 @@ function selectSharingRole(role){
|
|
|
3028
3156
|
if(sp) sp.style.display='none';
|
|
3029
3157
|
if(tp) tp.style.display='none';
|
|
3030
3158
|
if(ap) ap.style.display='none';
|
|
3031
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3032
|
-
if(adminTab) adminTab.style.display='none';
|
|
3033
3159
|
}else{
|
|
3034
3160
|
if(sp) sp.style.display='';
|
|
3035
3161
|
if(tp) tp.style.display='';
|
|
@@ -3186,10 +3312,12 @@ async function loadSharingStatus(forcePending){
|
|
|
3186
3312
|
sharingStatusCache=d;
|
|
3187
3313
|
renderSharingSidebar(d);
|
|
3188
3314
|
renderSharingSettings(d);
|
|
3315
|
+
updateTeamGuide(d);
|
|
3189
3316
|
if(forcePending && d && d.admin && d.admin.canManageUsers) loadSharingPendingUsers();
|
|
3190
3317
|
}catch(e){
|
|
3191
3318
|
renderSharingSidebar(null);
|
|
3192
3319
|
renderSharingSettings(null);
|
|
3320
|
+
updateTeamGuide(null);
|
|
3193
3321
|
}
|
|
3194
3322
|
}
|
|
3195
3323
|
|
|
@@ -3214,8 +3342,6 @@ function renderSharingSidebar(data){
|
|
|
3214
3342
|
setBadge('#34d399',t('sharing.sidebar.connected'),true);
|
|
3215
3343
|
statusEl.innerHTML='';
|
|
3216
3344
|
hintEl.textContent='';
|
|
3217
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3218
|
-
if(adminTab) adminTab.style.display='';
|
|
3219
3345
|
}else if(conn.pendingApproval&&conn.user){
|
|
3220
3346
|
setBadge('#fbbf24',t('sharing.sidebar.pending'),false);
|
|
3221
3347
|
var html='<div class="info-grid">';
|
|
@@ -3224,8 +3350,6 @@ function renderSharingSidebar(data){
|
|
|
3224
3350
|
html+='</div>';
|
|
3225
3351
|
statusEl.innerHTML=html;
|
|
3226
3352
|
hintEl.textContent=t('sharing.pendingApproval.hint');
|
|
3227
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3228
|
-
if(adminTab) adminTab.style.display='none';
|
|
3229
3353
|
}else if(conn.rejected&&conn.user){
|
|
3230
3354
|
setBadge('#ef4444',t('sharing.sidebar.rejected'),false);
|
|
3231
3355
|
var html='<div class="info-grid">';
|
|
@@ -3234,8 +3358,6 @@ function renderSharingSidebar(data){
|
|
|
3234
3358
|
html+='</div>';
|
|
3235
3359
|
statusEl.innerHTML=html;
|
|
3236
3360
|
hintEl.textContent=t('sharing.rejected.hint');
|
|
3237
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3238
|
-
if(adminTab) adminTab.style.display='none';
|
|
3239
3361
|
}else if(conn.connected&&conn.user){
|
|
3240
3362
|
var isAdmin=conn.user.role==='admin';
|
|
3241
3363
|
setBadge('#34d399',t('sharing.sidebar.connected'),true);
|
|
@@ -3245,12 +3367,10 @@ function renderSharingSidebar(data){
|
|
|
3245
3367
|
html+='</div>';
|
|
3246
3368
|
statusEl.innerHTML=html;
|
|
3247
3369
|
hintEl.innerHTML='';
|
|
3248
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3249
|
-
if(adminTab) adminTab.style.display=isAdmin?'':'none';
|
|
3250
3370
|
}else if(data.clientConfigured){
|
|
3251
3371
|
setBadge('#ef4444',t('sharing.sidebar.disconnected'),false);
|
|
3252
3372
|
statusEl.innerHTML='<div style="font-size:11px;color:var(--text-muted)">'+t('sharing.sidebar.targetHub')+' '+esc(data.hubUrl||'')+'</div>';
|
|
3253
|
-
hintEl.
|
|
3373
|
+
hintEl.innerHTML=esc(t('sharing.clientDisconnected.hint'))+'<br><a href="#" onclick="retryConnection();return false;" style="color:var(--pri);font-size:11px;text-decoration:none">'+t('sharing.retryConnection')+'</a>';
|
|
3254
3374
|
}else{
|
|
3255
3375
|
setBadge('#888',t('sharing.sidebar.notConfigured'),false);
|
|
3256
3376
|
statusEl.innerHTML='';
|
|
@@ -3262,19 +3382,20 @@ function renderSharingSettings(data){
|
|
|
3262
3382
|
var statusEl=document.getElementById('sharingStatusPanel');
|
|
3263
3383
|
var teamEl=document.getElementById('sharingTeamPanel');
|
|
3264
3384
|
var adminEl=document.getElementById('sharingAdminPanel');
|
|
3385
|
+
var panelsWrap=document.getElementById('sharingPanelsWrap');
|
|
3265
3386
|
if(!statusEl||!teamEl||!adminEl) return;
|
|
3266
3387
|
if(!data||!data.enabled){
|
|
3267
3388
|
statusEl.innerHTML='';teamEl.innerHTML='';adminEl.innerHTML='';
|
|
3389
|
+
if(panelsWrap) panelsWrap.style.display='none';
|
|
3268
3390
|
return;
|
|
3269
3391
|
}
|
|
3392
|
+
if(panelsWrap) panelsWrap.style.display='';
|
|
3270
3393
|
var conn=data.connection||{};
|
|
3271
3394
|
var user=conn.user||{};
|
|
3272
3395
|
var actualRole=data.role||_sharingRole||'client';
|
|
3273
3396
|
if(data.role) _sharingRole=data.role;
|
|
3274
3397
|
var isAdmin=(data.admin&&data.admin.canManageUsers)||(conn.connected&&user.role==='admin')||(actualRole==='hub');
|
|
3275
3398
|
window._isHubAdmin=isAdmin;
|
|
3276
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3277
|
-
if(adminTab) adminTab.style.display=isAdmin?'':'none';
|
|
3278
3399
|
var hubAdminBtn=document.getElementById('hubAdminEntryBtn');
|
|
3279
3400
|
|
|
3280
3401
|
if(actualRole==='hub'){
|
|
@@ -3285,7 +3406,6 @@ function renderSharingSettings(data){
|
|
|
3285
3406
|
|
|
3286
3407
|
if(actualRole==='client'){
|
|
3287
3408
|
statusEl.style.display='none';teamEl.style.display='none';adminEl.style.display='none';
|
|
3288
|
-
if(adminTab) adminTab.style.display='none';
|
|
3289
3409
|
if(hubAdminBtn) hubAdminBtn.style.display='none';
|
|
3290
3410
|
|
|
3291
3411
|
var connBadge;
|
|
@@ -3316,7 +3436,9 @@ function renderSharingSettings(data){
|
|
|
3316
3436
|
sh+='<span class="hic-label">'+t('sharing.team')+'</span><span class="hic-value">'+esc(conn.teamName||'-')+'</span>';
|
|
3317
3437
|
sh+='</div></div>';
|
|
3318
3438
|
}else{
|
|
3319
|
-
sh+='</div
|
|
3439
|
+
sh+='</div><div class="hic-empty" style="color:var(--text-muted)">'+t('sharing.disconnected.hint')+'</div>'+
|
|
3440
|
+
'<div style="margin-top:10px;padding:0 16px 14px"><button class="btn btn-sm btn-primary" id="btnRetryConn" onclick="retryConnection()">'+t('sharing.retryConnection')+'</button>'+
|
|
3441
|
+
'<span id="retryConnResult" style="margin-left:10px;font-size:11px"></span></div></div>';
|
|
3320
3442
|
}
|
|
3321
3443
|
statusEl.innerHTML=sh;
|
|
3322
3444
|
teamEl.innerHTML='';adminEl.innerHTML='';
|
|
@@ -3326,6 +3448,26 @@ function renderSharingSettings(data){
|
|
|
3326
3448
|
statusEl.innerHTML='';teamEl.innerHTML='';adminEl.innerHTML='';
|
|
3327
3449
|
}
|
|
3328
3450
|
|
|
3451
|
+
async function retryConnection(){
|
|
3452
|
+
var btn=document.getElementById('btnRetryConn');
|
|
3453
|
+
var result=document.getElementById('retryConnResult');
|
|
3454
|
+
if(btn){btn.disabled=true;btn.textContent=t('sharing.retryConnection.loading');}
|
|
3455
|
+
if(result) result.innerHTML='<span style="color:var(--text-muted)">'+t('sharing.retryConnection.loading')+'</span>';
|
|
3456
|
+
try{
|
|
3457
|
+
await loadSharingStatus(false);
|
|
3458
|
+
var d=sharingStatusCache;
|
|
3459
|
+
if(d&&d.connection&&d.connection.connected){
|
|
3460
|
+
toast(t('sharing.retryConnection.success'),'success');
|
|
3461
|
+
if(result) result.innerHTML='<span style="color:#22c55e">\\u2705 '+t('sharing.retryConnection.success')+'</span>';
|
|
3462
|
+
}else{
|
|
3463
|
+
if(result) result.innerHTML='<span style="color:#ef4444">'+t('sharing.retryConnection.fail')+'</span>';
|
|
3464
|
+
}
|
|
3465
|
+
}catch(e){
|
|
3466
|
+
if(result) result.innerHTML='<span style="color:#ef4444">'+t('sharing.retryConnection.fail')+'</span>';
|
|
3467
|
+
}
|
|
3468
|
+
if(btn){btn.disabled=false;btn.textContent=t('sharing.retryConnection');}
|
|
3469
|
+
}
|
|
3470
|
+
|
|
3329
3471
|
async function retryHubJoin(){
|
|
3330
3472
|
if(!confirm(t('sharing.retryJoin.confirm'))) return;
|
|
3331
3473
|
try{
|
|
@@ -3424,6 +3566,29 @@ async function rejectSharingUser(userId,username){
|
|
|
3424
3566
|
}catch(e){toast(t('toast.rejectFail')+': '+e.message,'error');}
|
|
3425
3567
|
}
|
|
3426
3568
|
|
|
3569
|
+
/* ─── Team Setup Guide ─── */
|
|
3570
|
+
var TEAM_GUIDE_DISMISSED_KEY='memos-team-guide-dismissed';
|
|
3571
|
+
function updateTeamGuide(sharingData){
|
|
3572
|
+
var el=document.getElementById('teamSetupGuide');
|
|
3573
|
+
if(!el) return;
|
|
3574
|
+
if(localStorage.getItem(TEAM_GUIDE_DISMISSED_KEY)==='1'){el.style.display='none';return;}
|
|
3575
|
+
var isConfigured=sharingData&&sharingData.enabled;
|
|
3576
|
+
el.style.display=isConfigured?'none':'block';
|
|
3577
|
+
}
|
|
3578
|
+
function dismissTeamGuide(){
|
|
3579
|
+
localStorage.setItem(TEAM_GUIDE_DISMISSED_KEY,'1');
|
|
3580
|
+
var el=document.getElementById('teamSetupGuide');
|
|
3581
|
+
if(el) el.style.display='none';
|
|
3582
|
+
}
|
|
3583
|
+
function guideGoToHub(role){
|
|
3584
|
+
switchSettingsTab('hub',document.querySelector('.settings-tab-btn[data-tab="hub"]'));
|
|
3585
|
+
var chk=document.getElementById('cfgSharingEnabled');
|
|
3586
|
+
if(chk&&!chk.checked){chk.checked=true;onSharingToggle();}
|
|
3587
|
+
selectSharingRole(role);
|
|
3588
|
+
var card=document.getElementById('settingsSharingConfig');
|
|
3589
|
+
if(card) card.scrollIntoView({behavior:'smooth',block:'start'});
|
|
3590
|
+
}
|
|
3591
|
+
|
|
3427
3592
|
/* ─── Group Manager ─── */
|
|
3428
3593
|
var groupManagerUsers=[];
|
|
3429
3594
|
async function loadGroupManager(){
|
|
@@ -3578,7 +3743,35 @@ function switchAdminTab(tab,btn){
|
|
|
3578
3743
|
if(panel) panel.classList.add('active');
|
|
3579
3744
|
}
|
|
3580
3745
|
|
|
3746
|
+
function adminGoSetup(role){
|
|
3747
|
+
switchView('settings');
|
|
3748
|
+
setTimeout(function(){guideGoToHub(role);},200);
|
|
3749
|
+
}
|
|
3750
|
+
|
|
3581
3751
|
async function loadAdminData(){
|
|
3752
|
+
var notEnabledEl=document.getElementById('adminNotEnabled');
|
|
3753
|
+
var mainEl=document.getElementById('adminMainContent');
|
|
3754
|
+
var sharingOn=sharingStatusCache&&sharingStatusCache.enabled;
|
|
3755
|
+
if(!sharingOn){
|
|
3756
|
+
if(mainEl) mainEl.style.display='none';
|
|
3757
|
+
if(notEnabledEl){
|
|
3758
|
+
notEnabledEl.style.display='block';
|
|
3759
|
+
notEnabledEl.innerHTML=
|
|
3760
|
+
'<div style="text-align:center;padding:60px 32px;max-width:520px;margin:0 auto">'+
|
|
3761
|
+
'<div style="font-size:48px;margin-bottom:16px">\u{1F6E1}</div>'+
|
|
3762
|
+
'<div style="font-size:18px;font-weight:700;color:var(--text);margin-bottom:8px">'+t('admin.notEnabled.title')+'</div>'+
|
|
3763
|
+
'<div style="font-size:13px;color:var(--text-sec);line-height:1.7;margin-bottom:24px">'+t('admin.notEnabled.desc')+'</div>'+
|
|
3764
|
+
'<div style="display:flex;gap:12px;justify-content:center;flex-wrap:wrap">'+
|
|
3765
|
+
'<button class="btn btn-primary" style="padding:8px 20px;font-size:13px" onclick="adminGoSetup("hub")">'+t('admin.notEnabled.setupHub')+'</button>'+
|
|
3766
|
+
'<button class="btn btn-ghost" style="padding:8px 20px;font-size:13px" onclick="adminGoSetup("client")">'+t('admin.notEnabled.joinTeam')+'</button>'+
|
|
3767
|
+
'</div>'+
|
|
3768
|
+
'<div style="font-size:11px;color:var(--text-muted);margin-top:20px;line-height:1.6">'+t('admin.notEnabled.hint')+'</div>'+
|
|
3769
|
+
'</div>';
|
|
3770
|
+
}
|
|
3771
|
+
return;
|
|
3772
|
+
}
|
|
3773
|
+
if(notEnabledEl) notEnabledEl.style.display='none';
|
|
3774
|
+
if(mainEl) mainEl.style.display='';
|
|
3582
3775
|
if(!window._isHubAdmin){
|
|
3583
3776
|
var statsEl=document.getElementById('adminStats');
|
|
3584
3777
|
if(statsEl) statsEl.innerHTML='<div class="admin-empty">'+t('admin.noPermission')+'</div>';
|
|
@@ -5274,9 +5467,36 @@ function onProviderChange(section){
|
|
|
5274
5467
|
if(m[2]==='chat'&&def.chatModel&&!mdEl.value.trim()) mdEl.value=def.chatModel;
|
|
5275
5468
|
}
|
|
5276
5469
|
|
|
5277
|
-
|
|
5278
|
-
var
|
|
5470
|
+
function flashSaved(id){
|
|
5471
|
+
var el=document.getElementById(id);
|
|
5472
|
+
if(!el)return;
|
|
5473
|
+
el.classList.add('show');
|
|
5474
|
+
setTimeout(function(){el.classList.remove('show');},2500);
|
|
5475
|
+
}
|
|
5476
|
+
|
|
5477
|
+
async function doSaveConfig(cfg, btnEl, savedId){
|
|
5478
|
+
btnEl.disabled=true;btnEl.textContent=t('settings.test.loading');
|
|
5479
|
+
function done(){btnEl.disabled=false;btnEl.textContent=t('settings.save');}
|
|
5480
|
+
try{
|
|
5481
|
+
const r=await fetch('/api/config',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(cfg)});
|
|
5482
|
+
if(r.status===401){done();toast(t('settings.session.expired'),'error');return false;}
|
|
5483
|
+
if(!r.ok) throw new Error(await r.text());
|
|
5484
|
+
flashSaved(savedId);
|
|
5485
|
+
toast(t('settings.saved'),'success');
|
|
5486
|
+
done();
|
|
5487
|
+
return true;
|
|
5488
|
+
}catch(e){
|
|
5489
|
+
toast(t('settings.save.fail')+': '+e.message,'error');
|
|
5490
|
+
done();
|
|
5491
|
+
return false;
|
|
5492
|
+
}
|
|
5493
|
+
}
|
|
5494
|
+
|
|
5495
|
+
async function saveModelsConfig(){
|
|
5496
|
+
var card=document.querySelector('.card-models');
|
|
5497
|
+
var saveBtn=card.querySelector('.settings-actions .btn-primary');
|
|
5279
5498
|
saveBtn.disabled=true;saveBtn.textContent=t('settings.test.loading');
|
|
5499
|
+
function done(){saveBtn.disabled=false;saveBtn.textContent=t('settings.save');}
|
|
5280
5500
|
|
|
5281
5501
|
const cfg={};
|
|
5282
5502
|
const embP=document.getElementById('cfgEmbProvider').value;
|
|
@@ -5317,52 +5537,8 @@ async function saveConfig(){
|
|
|
5317
5537
|
if(skApiKey) cfg.skillEvolution.summarizer.apiKey=skApiKey;
|
|
5318
5538
|
}
|
|
5319
5539
|
|
|
5320
|
-
const vp=document.getElementById('cfgViewerPort').value.trim();
|
|
5321
|
-
if(vp) cfg.viewerPort=Number(vp);
|
|
5322
|
-
cfg.telemetry={enabled:document.getElementById('cfgTelemetryEnabled').checked};
|
|
5323
|
-
|
|
5324
|
-
function done(){saveBtn.disabled=false;saveBtn.textContent=t('settings.save');}
|
|
5325
|
-
|
|
5326
|
-
var sharingEnabled=document.getElementById('cfgSharingEnabled').checked;
|
|
5327
|
-
cfg.sharing={
|
|
5328
|
-
enabled:sharingEnabled,
|
|
5329
|
-
role:_sharingRole,
|
|
5330
|
-
capabilities:{}
|
|
5331
|
-
};
|
|
5332
|
-
if(sharingEnabled&&_sharingRole==='hub'){
|
|
5333
|
-
var hubPort=document.getElementById('cfgHubPort').value.trim();
|
|
5334
|
-
var hubTeamName=document.getElementById('cfgHubTeamName').value.trim();
|
|
5335
|
-
var hubTeamToken=document.getElementById('cfgHubTeamToken').value.trim();
|
|
5336
|
-
cfg.sharing.hub={port:hubPort?Number(hubPort):18800};
|
|
5337
|
-
if(hubTeamName) cfg.sharing.hub.teamName=hubTeamName;
|
|
5338
|
-
if(hubTeamToken) cfg.sharing.hub.teamToken=hubTeamToken;
|
|
5339
|
-
cfg.sharing.client={hubAddress:'',userToken:'',teamToken:''};
|
|
5340
|
-
}
|
|
5341
|
-
if(sharingEnabled&&_sharingRole==='client'){
|
|
5342
|
-
var clientAddr=document.getElementById('cfgClientHubAddress').value.trim();
|
|
5343
|
-
var clientTeamToken=document.getElementById('cfgClientTeamToken').value.trim();
|
|
5344
|
-
var clientUserToken=document.getElementById('cfgClientUserToken').value.trim();
|
|
5345
|
-
cfg.sharing.client={};
|
|
5346
|
-
if(clientAddr) cfg.sharing.client.hubAddress=clientAddr;
|
|
5347
|
-
if(clientTeamToken) cfg.sharing.client.teamToken=clientTeamToken;
|
|
5348
|
-
if(clientUserToken) cfg.sharing.client.userToken=clientUserToken;
|
|
5349
|
-
cfg.sharing.hub={port:18800,teamName:'',teamToken:''};
|
|
5350
|
-
if(clientAddr){
|
|
5351
|
-
try{
|
|
5352
|
-
var ips=await fetch('/api/local-ips').then(function(r){return r.json();});
|
|
5353
|
-
var localAddrs=['127.0.0.1','localhost','0.0.0.0'].concat(ips.ips||[]);
|
|
5354
|
-
var parsed=new URL(clientAddr.indexOf('://')>-1?clientAddr:'http://'+clientAddr);
|
|
5355
|
-
if(localAddrs.indexOf(parsed.hostname)>=0){
|
|
5356
|
-
done();toast(t('sharing.cannotJoinSelf'),'error');return;
|
|
5357
|
-
}
|
|
5358
|
-
}catch(e){}
|
|
5359
|
-
}
|
|
5360
|
-
}
|
|
5361
|
-
|
|
5362
|
-
// 1) Embedding model is required
|
|
5363
5540
|
if(!embP||embP===''){done();toast(t('settings.save.emb.required'),'error');return;}
|
|
5364
5541
|
|
|
5365
|
-
// 2) Test embedding
|
|
5366
5542
|
try{
|
|
5367
5543
|
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||''})});
|
|
5368
5544
|
if(er.status===401){done();toast(t('settings.session.expired'),'error');return;}
|
|
@@ -5371,7 +5547,6 @@ async function saveConfig(){
|
|
|
5371
5547
|
document.getElementById('testEmbResult').className='test-result ok';document.getElementById('testEmbResult').innerHTML='\\u2705 '+t('settings.test.ok');
|
|
5372
5548
|
}catch(e){done();toast(t('settings.save.emb.fail')+': '+e.message,'error');return;}
|
|
5373
5549
|
|
|
5374
|
-
// 3) Test summarizer if user filled it
|
|
5375
5550
|
if(hasSumConfig&&cfg.summarizer){
|
|
5376
5551
|
try{
|
|
5377
5552
|
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||''})});
|
|
@@ -5382,7 +5557,6 @@ async function saveConfig(){
|
|
|
5382
5557
|
}catch(e){done();toast(t('settings.save.sum.fail')+': '+e.message,'error');return;}
|
|
5383
5558
|
}
|
|
5384
5559
|
|
|
5385
|
-
// 4) Test skill model if user filled it
|
|
5386
5560
|
if(hasSkillConfig&&cfg.skillEvolution.summarizer){
|
|
5387
5561
|
try{
|
|
5388
5562
|
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||''})});
|
|
@@ -5393,7 +5567,6 @@ async function saveConfig(){
|
|
|
5393
5567
|
}catch(e){done();toast(t('settings.save.skill.fail')+': '+e.message,'error');return;}
|
|
5394
5568
|
}
|
|
5395
5569
|
|
|
5396
|
-
// 5) If summarizer or skill model not configured, check OpenClaw fallback and confirm
|
|
5397
5570
|
if(!hasSumConfig||!hasSkillConfig){
|
|
5398
5571
|
try{
|
|
5399
5572
|
var fr=await fetch('/api/fallback-model');
|
|
@@ -5407,22 +5580,86 @@ async function saveConfig(){
|
|
|
5407
5580
|
}catch(e){}
|
|
5408
5581
|
}
|
|
5409
5582
|
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5583
|
+
await doSaveConfig(cfg, saveBtn, 'modelsSaved');
|
|
5584
|
+
}
|
|
5585
|
+
|
|
5586
|
+
async function saveHubConfig(){
|
|
5587
|
+
var card=document.getElementById('settingsSharingConfig');
|
|
5588
|
+
var saveBtn=card.querySelector('.settings-actions .btn-primary');
|
|
5589
|
+
saveBtn.disabled=true;saveBtn.textContent=t('settings.test.loading');
|
|
5590
|
+
function done(){saveBtn.disabled=false;saveBtn.textContent=t('settings.save');}
|
|
5591
|
+
|
|
5592
|
+
const cfg={};
|
|
5593
|
+
var sharingEnabled=document.getElementById('cfgSharingEnabled').checked;
|
|
5594
|
+
cfg.sharing={
|
|
5595
|
+
enabled:sharingEnabled,
|
|
5596
|
+
role:_sharingRole,
|
|
5597
|
+
capabilities:{}
|
|
5598
|
+
};
|
|
5599
|
+
if(sharingEnabled&&_sharingRole==='hub'){
|
|
5600
|
+
var hubPort=document.getElementById('cfgHubPort').value.trim();
|
|
5601
|
+
var hubTeamName=document.getElementById('cfgHubTeamName').value.trim();
|
|
5602
|
+
var hubTeamToken=document.getElementById('cfgHubTeamToken').value.trim();
|
|
5603
|
+
cfg.sharing.hub={port:hubPort?Number(hubPort):18800};
|
|
5604
|
+
if(hubTeamName) cfg.sharing.hub.teamName=hubTeamName;
|
|
5605
|
+
if(hubTeamToken) cfg.sharing.hub.teamToken=hubTeamToken;
|
|
5606
|
+
cfg.sharing.client={hubAddress:'',userToken:'',teamToken:''};
|
|
5607
|
+
}
|
|
5608
|
+
if(sharingEnabled&&_sharingRole==='client'){
|
|
5609
|
+
var clientAddr=document.getElementById('cfgClientHubAddress').value.trim();
|
|
5610
|
+
var clientTeamToken=document.getElementById('cfgClientTeamToken').value.trim();
|
|
5611
|
+
var clientUserToken=document.getElementById('cfgClientUserToken').value.trim();
|
|
5612
|
+
cfg.sharing.client={};
|
|
5613
|
+
if(clientAddr) cfg.sharing.client.hubAddress=clientAddr;
|
|
5614
|
+
if(clientTeamToken) cfg.sharing.client.teamToken=clientTeamToken;
|
|
5615
|
+
if(clientUserToken) cfg.sharing.client.userToken=clientUserToken;
|
|
5616
|
+
cfg.sharing.hub={port:18800,teamName:'',teamToken:''};
|
|
5617
|
+
if(clientAddr){
|
|
5618
|
+
try{
|
|
5619
|
+
var ips=await fetch('/api/local-ips').then(function(r){return r.json();});
|
|
5620
|
+
var localAddrs=['127.0.0.1','localhost','0.0.0.0'].concat(ips.ips||[]);
|
|
5621
|
+
var parsed=new URL(clientAddr.indexOf('://')>-1?clientAddr:'http://'+clientAddr);
|
|
5622
|
+
if(localAddrs.indexOf(parsed.hostname)>=0){
|
|
5623
|
+
done();toast(t('sharing.cannotJoinSelf'),'error');return;
|
|
5624
|
+
}
|
|
5625
|
+
}catch(e){}
|
|
5626
|
+
}
|
|
5627
|
+
}
|
|
5628
|
+
|
|
5629
|
+
var prevSharingEnabled=sharingStatusCache&&sharingStatusCache.enabled;
|
|
5630
|
+
var prevRole=sharingStatusCache&&sharingStatusCache.role;
|
|
5631
|
+
if(prevSharingEnabled&&!sharingEnabled){
|
|
5632
|
+
var confirmMsg=prevRole==='hub'?t('sharing.disable.confirm.hub'):t('sharing.disable.confirm.client');
|
|
5633
|
+
if(!confirm(confirmMsg)){done();return;}
|
|
5634
|
+
}
|
|
5635
|
+
|
|
5636
|
+
var ok=await doSaveConfig(cfg, saveBtn, 'hubSaved');
|
|
5637
|
+
if(ok){
|
|
5418
5638
|
loadSharingStatus(false);
|
|
5419
5639
|
if(sharingEnabled){
|
|
5420
5640
|
updateHubShareInfo();
|
|
5421
5641
|
setTimeout(function(){alert(t('settings.hub.restartAlert'));},300);
|
|
5422
5642
|
}
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5643
|
+
if(prevSharingEnabled&&!sharingEnabled){
|
|
5644
|
+
setTimeout(function(){alert(t('sharing.disable.restartAlert'));},300);
|
|
5645
|
+
}
|
|
5646
|
+
}
|
|
5647
|
+
}
|
|
5648
|
+
|
|
5649
|
+
async function saveGeneralConfig(){
|
|
5650
|
+
var card=document.querySelector('.card-general');
|
|
5651
|
+
var saveBtn=card.querySelector('.settings-actions .btn-primary');
|
|
5652
|
+
|
|
5653
|
+
const cfg={};
|
|
5654
|
+
const vp=document.getElementById('cfgViewerPort').value.trim();
|
|
5655
|
+
if(vp) cfg.viewerPort=Number(vp);
|
|
5656
|
+
cfg.telemetry={enabled:document.getElementById('cfgTelemetryEnabled').checked};
|
|
5657
|
+
|
|
5658
|
+
await doSaveConfig(cfg, saveBtn, 'generalSaved');
|
|
5659
|
+
}
|
|
5660
|
+
|
|
5661
|
+
async function saveConfig(){
|
|
5662
|
+
await saveModelsConfig();
|
|
5426
5663
|
}
|
|
5427
5664
|
|
|
5428
5665
|
async function testModel(type){
|
|
@@ -5784,12 +6021,25 @@ function renderToolAgg(data){
|
|
|
5784
6021
|
'</tbody></table>';
|
|
5785
6022
|
}
|
|
5786
6023
|
|
|
6024
|
+
/* ─── Sharing status polling ─── */
|
|
6025
|
+
var _sharingPollTimer=null;
|
|
6026
|
+
function startSharingPoll(){
|
|
6027
|
+
stopSharingPoll();
|
|
6028
|
+
_sharingPollTimer=setInterval(function(){
|
|
6029
|
+
if(sharingStatusCache&&sharingStatusCache.enabled) loadSharingStatus(false);
|
|
6030
|
+
},30000);
|
|
6031
|
+
}
|
|
6032
|
+
function stopSharingPoll(){
|
|
6033
|
+
if(_sharingPollTimer){clearInterval(_sharingPollTimer);_sharingPollTimer=null;}
|
|
6034
|
+
}
|
|
6035
|
+
|
|
5787
6036
|
/* ─── Data loading ─── */
|
|
5788
6037
|
async function loadAll(){
|
|
5789
6038
|
await Promise.all([loadStats(),loadMemories(),loadSharingStatus(false)]);
|
|
5790
6039
|
checkMigrateStatus();
|
|
5791
6040
|
connectPPSSE();
|
|
5792
6041
|
checkForUpdate();
|
|
6042
|
+
startSharingPoll();
|
|
5793
6043
|
}
|
|
5794
6044
|
|
|
5795
6045
|
async function loadStats(ownerFilter){
|