@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/src/viewer/html.ts
CHANGED
|
@@ -106,7 +106,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
106
106
|
|
|
107
107
|
/* ─── App Layout (dark dashboard, same as www) ─── */
|
|
108
108
|
.app{display:none;flex-direction:column;min-height:100vh}
|
|
109
|
-
.topbar{background:rgba(11,13,17,.88);border-bottom:1px solid var(--border);padding:0
|
|
109
|
+
.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)}
|
|
110
110
|
.topbar .brand{display:flex;align-items:center;gap:8px;font-weight:700;font-size:15px;color:var(--text);letter-spacing:-.02em;flex-shrink:0}
|
|
111
111
|
.topbar .brand .icon{width:24px;height:24px;display:flex;align-items:center;justify-content:center;font-size:18px;background:none;border-radius:0}
|
|
112
112
|
.topbar .brand .brand-title{font-size:13px;font-weight:500;opacity:.7}
|
|
@@ -712,9 +712,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
712
712
|
.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)}
|
|
713
713
|
.settings-tab-btn .stab-icon{font-size:15px;line-height:1}
|
|
714
714
|
.settings-tab-btn .stab-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
|
|
715
|
-
.settings-tab-btn[data-tab="
|
|
716
|
-
.settings-tab-btn[data-tab="summarizer"] .stab-dot{background:#8b5cf6}
|
|
717
|
-
.settings-tab-btn[data-tab="skill"] .stab-dot{background:#f59e0b}
|
|
715
|
+
.settings-tab-btn[data-tab="models"] .stab-dot{background:#6366f1}
|
|
718
716
|
.settings-tab-btn[data-tab="hub"] .stab-dot{background:#06b6d4}
|
|
719
717
|
.settings-tab-btn[data-tab="general"] .stab-dot{background:#10b981}
|
|
720
718
|
.settings-tab-btn.active .stab-dot{box-shadow:0 0 6px currentColor}
|
|
@@ -726,9 +724,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
726
724
|
.settings-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;opacity:.5;transition:opacity .3s}
|
|
727
725
|
.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)}
|
|
728
726
|
.settings-card:hover::before{opacity:1}
|
|
729
|
-
.settings-card.card-
|
|
730
|
-
.settings-card.card-summarizer::before{background:linear-gradient(90deg,#8b5cf6,#a78bfa,#c4b5fd)}
|
|
731
|
-
.settings-card.card-skill::before{background:linear-gradient(90deg,#f59e0b,#fbbf24,#fcd34d)}
|
|
727
|
+
.settings-card.card-models::before{background:linear-gradient(90deg,#6366f1,#8b5cf6,#f59e0b)}
|
|
732
728
|
.settings-card.card-hub::before{background:linear-gradient(90deg,#06b6d4,#22d3ee,#67e8f9)}
|
|
733
729
|
.settings-card.card-general::before{background:linear-gradient(90deg,#10b981,#34d399,#6ee7b7)}
|
|
734
730
|
.settings-card-header{display:flex;align-items:center;gap:14px;padding:22px 28px 0}
|
|
@@ -802,6 +798,28 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
802
798
|
[data-theme="light"] .settings-actions .btn-primary:hover{background:rgba(79,70,229,.1);border-color:#4f46e5}
|
|
803
799
|
.settings-saved{display:inline-flex;align-items:center;gap:6px;color:var(--green);font-size:12px;font-weight:600;opacity:0;transition:opacity .3s}
|
|
804
800
|
.settings-saved.show{opacity:1}
|
|
801
|
+
.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}
|
|
802
|
+
.team-guide::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,#06b6d4,#6366f1,#8b5cf6);opacity:.6}
|
|
803
|
+
.team-guide-title{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:700;color:var(--text);margin-bottom:4px}
|
|
804
|
+
.team-guide-subtitle{font-size:11.5px;color:var(--text-muted);line-height:1.6;margin-bottom:16px}
|
|
805
|
+
.team-guide-options{display:grid;grid-template-columns:1fr 1fr;gap:14px}
|
|
806
|
+
@media(max-width:800px){.team-guide-options{grid-template-columns:1fr}}
|
|
807
|
+
.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}
|
|
808
|
+
.team-guide-opt:hover{border-color:rgba(99,102,241,.3);box-shadow:0 4px 16px rgba(0,0,0,.06)}
|
|
809
|
+
.team-guide-opt-header{display:flex;align-items:center;gap:10px;margin-bottom:8px}
|
|
810
|
+
.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}
|
|
811
|
+
.team-guide-opt-title{font-size:13px;font-weight:700;color:var(--text)}
|
|
812
|
+
.team-guide-opt-desc{font-size:11px;color:var(--text-sec);line-height:1.7;margin-bottom:12px}
|
|
813
|
+
.team-guide-steps{padding:0 0 0 20px;margin:0 0 12px;counter-reset:none}
|
|
814
|
+
.team-guide-steps li{font-size:11px;color:var(--text-muted);line-height:1.9}
|
|
815
|
+
.team-guide-steps li::marker{color:var(--pri);font-weight:700;font-size:11px}
|
|
816
|
+
.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}
|
|
817
|
+
.team-guide-opt .btn-guide:hover{background:rgba(99,102,241,.14);border-color:var(--pri)}
|
|
818
|
+
.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}
|
|
819
|
+
.team-guide-dismiss:hover{opacity:1}
|
|
820
|
+
[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)}
|
|
821
|
+
[data-theme="light"] .team-guide-opt{box-shadow:0 1px 3px rgba(0,0,0,.03)}
|
|
822
|
+
[data-theme="light"] .team-guide-opt:hover{box-shadow:0 4px 16px rgba(0,0,0,.04)}
|
|
805
823
|
.model-health-bar{margin-bottom:20px;border-radius:var(--radius-lg);overflow:visible}
|
|
806
824
|
.mh-table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}
|
|
807
825
|
.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)}
|
|
@@ -861,9 +879,9 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
861
879
|
.analytics-section::before{display:none}
|
|
862
880
|
.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}
|
|
863
881
|
.analytics-section h3 .icon{font-size:14px;opacity:.6}
|
|
864
|
-
.chart-bars{display:flex;align-items:flex-end;gap:
|
|
882
|
+
.chart-bars{display:flex;align-items:flex-end;gap:0;padding:12px 0 4px;min-height:200px;position:relative;width:100%}
|
|
865
883
|
.chart-bars::before{content:'';position:absolute;left:0;right:0;bottom:24px;height:1px;background:var(--border);opacity:.4}
|
|
866
|
-
.chart-bar-wrap{flex:1 1 0;min-width:0;
|
|
884
|
+
.chart-bar-wrap{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;gap:4px;position:relative;cursor:pointer}
|
|
867
885
|
.chart-bar-col{width:100%;height:160px;display:flex;flex-direction:column;justify-content:flex-end;align-items:center}
|
|
868
886
|
.chart-bar-wrap:hover .chart-bar{opacity:1;filter:brightness(1.2);transform:scaleY(1.02);transform-origin:bottom}
|
|
869
887
|
.chart-bar-wrap:hover .chart-bar-label{color:var(--text)}
|
|
@@ -874,7 +892,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
874
892
|
.chart-bar.violet{background:linear-gradient(180deg,#8b5cf6 0%,#6366f1 100%)}
|
|
875
893
|
.chart-bar.green{background:linear-gradient(180deg,#34d399 0%,#10b981 100%);box-shadow:0 1px 4px rgba(16,185,129,.12)}
|
|
876
894
|
.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}
|
|
877
|
-
.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}
|
|
895
|
+
.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}
|
|
878
896
|
.chart-legend{display:flex;gap:14px;margin-top:12px;flex-wrap:wrap;font-size:11px;color:var(--text-sec);font-weight:500}
|
|
879
897
|
.chart-legend span{display:inline-flex;align-items:center;gap:5px}
|
|
880
898
|
.chart-legend .dot{width:8px;height:8px;border-radius:2px}
|
|
@@ -1025,7 +1043,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1025
1043
|
<button class="tab" data-view="analytics" onclick="switchView('analytics')" data-i18n="tab.analytics">\u{1F4CA} Analytics</button>
|
|
1026
1044
|
<button class="tab" data-view="logs" onclick="switchView('logs')" data-i18n="tab.logs">\u{1F4DD} Logs</button>
|
|
1027
1045
|
<button class="tab" data-view="import" onclick="switchView('import')" data-i18n="tab.import">\u{1F4E5} Import</button>
|
|
1028
|
-
<button class="tab" data-view="admin" onclick="switchView('admin')"
|
|
1046
|
+
<button class="tab" data-view="admin" onclick="switchView('admin')" data-i18n="tab.admin">\u{1F6E1} Admin</button>
|
|
1029
1047
|
<button class="tab" data-view="settings" onclick="switchView('settings')" data-i18n="tab.settings">\u2699 Settings</button>
|
|
1030
1048
|
</nav>
|
|
1031
1049
|
</div>
|
|
@@ -1265,24 +1283,25 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1265
1283
|
<!-- ─── Settings View ─── -->
|
|
1266
1284
|
<div class="settings-view" id="settingsView">
|
|
1267
1285
|
<div class="settings-tabs-bar">
|
|
1268
|
-
<button class="settings-tab-btn active" data-tab="
|
|
1269
|
-
<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>
|
|
1270
|
-
<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>
|
|
1286
|
+
<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>
|
|
1271
1287
|
<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>
|
|
1272
1288
|
<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>
|
|
1273
1289
|
</div>
|
|
1274
1290
|
<div class="settings-cards-grid">
|
|
1275
1291
|
|
|
1276
|
-
<!-- ══ Card: Embedding
|
|
1277
|
-
<div class="settings-card card-
|
|
1292
|
+
<!-- ══ Card: AI Models (Embedding + Summarizer + Skill) ══ -->
|
|
1293
|
+
<div class="settings-card card-models stab-active" data-stab="models">
|
|
1278
1294
|
<div class="settings-card-header">
|
|
1279
|
-
<div class="settings-card-icon" style="background:rgba(99,102,241,.1);border-color:rgba(99,102,241,.15)">\u{
|
|
1295
|
+
<div class="settings-card-icon" style="background:rgba(99,102,241,.1);border-color:rgba(99,102,241,.15)">\u{1F9E0}</div>
|
|
1280
1296
|
<div class="settings-card-title-wrap">
|
|
1281
|
-
<div class="settings-card-title" data-i18n="settings.
|
|
1282
|
-
<div class="settings-card-desc" data-i18n="settings.
|
|
1297
|
+
<div class="settings-card-title" data-i18n="settings.models">AI Models</div>
|
|
1298
|
+
<div class="settings-card-desc" data-i18n="settings.models.desc">Configure embedding, summarizer and skill evolution models</div>
|
|
1283
1299
|
</div>
|
|
1284
1300
|
</div>
|
|
1285
1301
|
<div class="settings-card-body">
|
|
1302
|
+
<!-- Embedding Model section -->
|
|
1303
|
+
<div class="settings-card-subtitle">\u{1F4E1} <span data-i18n="settings.embedding">Embedding Model</span></div>
|
|
1304
|
+
<div class="field-hint" style="margin-bottom:10px" data-i18n="settings.embedding.desc">Vector embedding model for memory search and retrieval</div>
|
|
1286
1305
|
<div class="settings-grid">
|
|
1287
1306
|
<div class="settings-field">
|
|
1288
1307
|
<label data-i18n="settings.provider">Provider</label>
|
|
@@ -1318,19 +1337,12 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1318
1337
|
<button class="btn btn-sm btn-ghost" onclick="testModel('embedding')" id="testEmbBtn" data-i18n="settings.test">Test Connection</button>
|
|
1319
1338
|
<span class="test-result" id="testEmbResult"></span>
|
|
1320
1339
|
</div>
|
|
1321
|
-
</div>
|
|
1322
|
-
</div>
|
|
1323
1340
|
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
<div class="settings-card-
|
|
1328
|
-
<div class="
|
|
1329
|
-
<div class="settings-card-title" data-i18n="settings.summarizer">Summarizer Model</div>
|
|
1330
|
-
<div class="settings-card-desc" data-i18n="settings.summarizer.desc">LLM for memory summarization, deduplication and analysis</div>
|
|
1331
|
-
</div>
|
|
1332
|
-
</div>
|
|
1333
|
-
<div class="settings-card-body">
|
|
1341
|
+
<div class="settings-card-divider"></div>
|
|
1342
|
+
|
|
1343
|
+
<!-- Summarizer Model section -->
|
|
1344
|
+
<div class="settings-card-subtitle">\u{1F4DD} <span data-i18n="settings.summarizer">Summarizer Model</span></div>
|
|
1345
|
+
<div class="field-hint" style="margin-bottom:10px" data-i18n="settings.summarizer.desc">LLM for memory summarization, deduplication and analysis</div>
|
|
1334
1346
|
<div class="settings-grid">
|
|
1335
1347
|
<div class="settings-field">
|
|
1336
1348
|
<label data-i18n="settings.provider">Provider</label>
|
|
@@ -1370,19 +1382,12 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1370
1382
|
<button class="btn btn-sm btn-ghost" onclick="testModel('summarizer')" id="testSumBtn" data-i18n="settings.test">Test Connection</button>
|
|
1371
1383
|
<span class="test-result" id="testSumResult"></span>
|
|
1372
1384
|
</div>
|
|
1373
|
-
</div>
|
|
1374
|
-
</div>
|
|
1375
1385
|
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
<div class="settings-card-
|
|
1380
|
-
<div class="
|
|
1381
|
-
<div class="settings-card-title" data-i18n="settings.skill">Skill Evolution</div>
|
|
1382
|
-
<div class="settings-card-desc" data-i18n="settings.skill.desc">Auto-extract reusable skills from conversation patterns</div>
|
|
1383
|
-
</div>
|
|
1384
|
-
</div>
|
|
1385
|
-
<div class="settings-card-body">
|
|
1386
|
+
<div class="settings-card-divider"></div>
|
|
1387
|
+
|
|
1388
|
+
<!-- Skill Evolution section -->
|
|
1389
|
+
<div class="settings-card-subtitle">\u{1F527} <span data-i18n="settings.skill">Skill Evolution</span></div>
|
|
1390
|
+
<div class="field-hint" style="margin-bottom:10px" data-i18n="settings.skill.desc">Auto-extract reusable skills from conversation patterns</div>
|
|
1386
1391
|
<div class="settings-grid">
|
|
1387
1392
|
<div class="settings-toggle">
|
|
1388
1393
|
<label class="toggle-switch"><input type="checkbox" id="cfgSkillEnabled"><span class="toggle-slider"></span></label>
|
|
@@ -1401,45 +1406,54 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1401
1406
|
<input type="number" id="cfgSkillMinChunks" placeholder="6">
|
|
1402
1407
|
</div>
|
|
1403
1408
|
</div>
|
|
1404
|
-
<div
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
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
|
-
|
|
1409
|
+
<div style="margin-top:14px">
|
|
1410
|
+
<div class="settings-card-subtitle" style="margin-bottom:4px" data-i18n="settings.skill.model">Skill Dedicated Model</div>
|
|
1411
|
+
<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>
|
|
1412
|
+
<div class="settings-grid">
|
|
1413
|
+
<div class="settings-field">
|
|
1414
|
+
<label data-i18n="settings.provider">Provider</label>
|
|
1415
|
+
<select id="cfgSkillProvider" onchange="onProviderChange('skill')">
|
|
1416
|
+
<option value="">\u2014 <span data-i18n="settings.skill.usemain">Use main summarizer</span> \u2014</option>
|
|
1417
|
+
<option value="openai_compatible">OpenAI Compatible</option>
|
|
1418
|
+
<option value="openai">OpenAI</option>
|
|
1419
|
+
<option value="siliconflow">SiliconFlow (\u7845\u57FA\u6D41\u52A8)</option>
|
|
1420
|
+
<option value="zhipu">Zhipu AI (\u667A\u8C31)</option>
|
|
1421
|
+
<option value="deepseek">DeepSeek</option>
|
|
1422
|
+
<option value="bailian">Alibaba Bailian (\u767E\u70BC)</option>
|
|
1423
|
+
<option value="moonshot">Moonshot (Kimi)</option>
|
|
1424
|
+
<option value="anthropic">Anthropic</option>
|
|
1425
|
+
<option value="gemini">Gemini</option>
|
|
1426
|
+
<option value="azure_openai">Azure OpenAI</option>
|
|
1427
|
+
<option value="bedrock">Bedrock</option>
|
|
1428
|
+
<option value="openclaw">OpenClaw Host</option>
|
|
1429
|
+
</select>
|
|
1430
|
+
</div>
|
|
1431
|
+
<div class="settings-field">
|
|
1432
|
+
<label data-i18n="settings.model">Model</label>
|
|
1433
|
+
<input type="text" id="cfgSkillModel" placeholder="e.g. claude-4.6-opus">
|
|
1434
|
+
</div>
|
|
1435
|
+
<div class="settings-field full-width">
|
|
1436
|
+
<label>Endpoint</label>
|
|
1437
|
+
<input type="text" id="cfgSkillEndpoint" placeholder="https://...">
|
|
1438
|
+
</div>
|
|
1439
|
+
<div class="settings-field">
|
|
1440
|
+
<label>API Key</label>
|
|
1441
|
+
<input type="password" id="cfgSkillApiKey" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022">
|
|
1442
|
+
</div>
|
|
1433
1443
|
</div>
|
|
1434
|
-
<div class="
|
|
1435
|
-
<
|
|
1436
|
-
<
|
|
1444
|
+
<div class="test-conn-row">
|
|
1445
|
+
<button class="btn btn-sm btn-ghost" onclick="testModel('skill')" id="testSkillBtn" data-i18n="settings.test">Test Connection</button>
|
|
1446
|
+
<span class="test-result" id="testSkillResult"></span>
|
|
1437
1447
|
</div>
|
|
1438
1448
|
</div>
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1449
|
+
|
|
1450
|
+
<div class="settings-card-divider"></div>
|
|
1451
|
+
<div class="settings-actions">
|
|
1452
|
+
<span class="settings-saved" id="modelsSaved">\u2713 <span data-i18n="settings.saved">Saved</span></span>
|
|
1453
|
+
<button class="btn btn-ghost" onclick="loadConfig()" data-i18n="settings.reset">Reset</button>
|
|
1454
|
+
<button class="btn btn-primary" onclick="saveModelsConfig()" data-i18n="settings.save">Save Settings</button>
|
|
1442
1455
|
</div>
|
|
1456
|
+
<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>
|
|
1443
1457
|
</div>
|
|
1444
1458
|
</div>
|
|
1445
1459
|
|
|
@@ -1453,6 +1467,43 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1453
1467
|
</div>
|
|
1454
1468
|
</div>
|
|
1455
1469
|
<div class="settings-card-body">
|
|
1470
|
+
<!-- team setup guide (inside Hub card) -->
|
|
1471
|
+
<div class="team-guide" id="teamSetupGuide">
|
|
1472
|
+
<button class="team-guide-dismiss" onclick="dismissTeamGuide()" title="Dismiss">×</button>
|
|
1473
|
+
<div class="team-guide-title">\u{1F680} <span data-i18n="guide.title">Get Started with Team Collaboration</span></div>
|
|
1474
|
+
<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>
|
|
1475
|
+
<div class="team-guide-options">
|
|
1476
|
+
<div class="team-guide-opt">
|
|
1477
|
+
<div class="team-guide-opt-header">
|
|
1478
|
+
<div class="team-guide-opt-icon" style="background:rgba(6,182,212,.1);border:1px solid rgba(6,182,212,.15)">\u{1F310}</div>
|
|
1479
|
+
<div class="team-guide-opt-title" data-i18n="guide.join.title">Join a Remote Team</div>
|
|
1480
|
+
</div>
|
|
1481
|
+
<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>
|
|
1482
|
+
<ol class="team-guide-steps">
|
|
1483
|
+
<li><span data-i18n="guide.join.s1">Ask your Hub admin for the Hub Address and Team Token</span></li>
|
|
1484
|
+
<li><span data-i18n="guide.join.s2">Enable sharing above, select "Client" mode</span></li>
|
|
1485
|
+
<li><span data-i18n="guide.join.s3">Fill in Hub Address and Team Token, click "Test Connection"</span></li>
|
|
1486
|
+
<li><span data-i18n="guide.join.s4">Save settings, restart the OpenClaw gateway, then refresh this page</span></li>
|
|
1487
|
+
</ol>
|
|
1488
|
+
<button class="btn-guide" onclick="guideGoToHub('client')" data-i18n="guide.join.btn">\u2192 Configure Client Mode</button>
|
|
1489
|
+
</div>
|
|
1490
|
+
<div class="team-guide-opt">
|
|
1491
|
+
<div class="team-guide-opt-header">
|
|
1492
|
+
<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>
|
|
1493
|
+
<div class="team-guide-opt-title" data-i18n="guide.hub.title">Start Your Own Hub</div>
|
|
1494
|
+
</div>
|
|
1495
|
+
<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>
|
|
1496
|
+
<ol class="team-guide-steps">
|
|
1497
|
+
<li><span data-i18n="guide.hub.s1">Enable sharing above, select "Hub" mode</span></li>
|
|
1498
|
+
<li><span data-i18n="guide.hub.s2">Set a team name, save settings, restart the gateway, then refresh this page</span></li>
|
|
1499
|
+
<li><span data-i18n="guide.hub.s3">Share the Hub Address and Team Token with your team members</span></li>
|
|
1500
|
+
<li><span data-i18n="guide.hub.s4">Approve join requests in the Admin Panel</span></li>
|
|
1501
|
+
</ol>
|
|
1502
|
+
<button class="btn-guide" onclick="guideGoToHub('hub')" data-i18n="guide.hub.btn">\u2192 Configure Hub Mode</button>
|
|
1503
|
+
</div>
|
|
1504
|
+
</div>
|
|
1505
|
+
</div>
|
|
1506
|
+
|
|
1456
1507
|
<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>
|
|
1457
1508
|
<div class="settings-toggle" style="margin-bottom:16px">
|
|
1458
1509
|
<label class="toggle-switch">
|
|
@@ -1500,7 +1551,7 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1500
1551
|
<div style="font-weight:700;color:var(--text);margin-bottom:4px" data-i18n="settings.hub.clientSteps.title">Quick Setup (3 steps)</div>
|
|
1501
1552
|
<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>
|
|
1502
1553
|
<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>
|
|
1503
|
-
<div><span style="color:var(--accent)">3.</span> <span data-i18n="settings.hub.clientSteps.s3">Click "Save Settings",
|
|
1554
|
+
<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>
|
|
1504
1555
|
</div>
|
|
1505
1556
|
<div class="settings-grid">
|
|
1506
1557
|
<div class="settings-field full-width">
|
|
@@ -1522,10 +1573,20 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1522
1573
|
</div>
|
|
1523
1574
|
</div>
|
|
1524
1575
|
|
|
1576
|
+
<div id="sharingPanelsWrap" style="display:none">
|
|
1577
|
+
<div class="settings-card-divider"></div>
|
|
1578
|
+
<div id="sharingStatusPanel"></div>
|
|
1579
|
+
<div id="sharingTeamPanel"></div>
|
|
1580
|
+
<div id="sharingAdminPanel"></div>
|
|
1581
|
+
</div>
|
|
1582
|
+
|
|
1525
1583
|
<div class="settings-card-divider"></div>
|
|
1526
|
-
<div
|
|
1527
|
-
|
|
1528
|
-
|
|
1584
|
+
<div class="settings-actions">
|
|
1585
|
+
<span class="settings-saved" id="hubSaved">\u2713 <span data-i18n="settings.saved">Saved</span></span>
|
|
1586
|
+
<button class="btn btn-ghost" onclick="loadConfig()" data-i18n="settings.reset">Reset</button>
|
|
1587
|
+
<button class="btn btn-primary" onclick="saveHubConfig()" data-i18n="settings.save">Save Settings</button>
|
|
1588
|
+
</div>
|
|
1589
|
+
<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>
|
|
1529
1590
|
</div>
|
|
1530
1591
|
</div>
|
|
1531
1592
|
|
|
@@ -1557,39 +1618,44 @@ input,textarea,select{font-family:inherit;font-size:inherit}
|
|
|
1557
1618
|
<label data-i18n="settings.telemetry.enabled">Enable Anonymous Telemetry</label>
|
|
1558
1619
|
</div>
|
|
1559
1620
|
<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>
|
|
1621
|
+
|
|
1622
|
+
<div class="settings-card-divider"></div>
|
|
1623
|
+
<div class="settings-actions">
|
|
1624
|
+
<span class="settings-saved" id="generalSaved">\u2713 <span data-i18n="settings.saved">Saved</span></span>
|
|
1625
|
+
<button class="btn btn-ghost" onclick="loadConfig()" data-i18n="settings.reset">Reset</button>
|
|
1626
|
+
<button class="btn btn-primary" onclick="saveGeneralConfig()" data-i18n="settings.save">Save Settings</button>
|
|
1627
|
+
</div>
|
|
1560
1628
|
</div>
|
|
1561
1629
|
</div>
|
|
1562
1630
|
|
|
1563
1631
|
</div>
|
|
1564
1632
|
|
|
1565
|
-
|
|
1566
|
-
<span class="settings-saved" id="settingsSaved">\u2713 <span data-i18n="settings.saved">Saved</span></span>
|
|
1567
|
-
<button class="btn btn-ghost" onclick="loadConfig()" data-i18n="settings.reset">Reset</button>
|
|
1568
|
-
<button class="btn btn-primary" onclick="saveConfig()" data-i18n="settings.save">Save Settings</button>
|
|
1569
|
-
</div>
|
|
1570
|
-
<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>
|
|
1633
|
+
|
|
1571
1634
|
</div>
|
|
1572
1635
|
|
|
1573
1636
|
<!-- ─── Admin Page ─── -->
|
|
1574
1637
|
<div class="admin-view" id="adminView">
|
|
1575
|
-
<div
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
<
|
|
1638
|
+
<div id="adminNotEnabled" style="display:none"></div>
|
|
1639
|
+
<div id="adminMainContent">
|
|
1640
|
+
<div class="admin-header">
|
|
1641
|
+
<div class="admin-header-top">
|
|
1642
|
+
<h2><span class="ah-icon">\u{1F6E1}</span> <span data-i18n="admin.title">Hub Admin Panel</span></h2>
|
|
1643
|
+
<button class="btn btn-sm btn-ghost" onclick="loadAdminData()" style="backdrop-filter:blur(8px)" data-i18n="admin.refresh">\u21BB Refresh</button>
|
|
1644
|
+
</div>
|
|
1645
|
+
<div class="admin-header-sub" data-i18n="admin.subtitle">Manage team members, groups, and shared resources</div>
|
|
1646
|
+
<div class="admin-stat-row" id="adminStats"></div>
|
|
1579
1647
|
</div>
|
|
1580
|
-
<div class="admin-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
<
|
|
1587
|
-
<
|
|
1648
|
+
<div class="admin-tabs" id="adminTabsBar">
|
|
1649
|
+
<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>
|
|
1650
|
+
<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>
|
|
1651
|
+
<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>
|
|
1652
|
+
<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>
|
|
1653
|
+
</div>
|
|
1654
|
+
<div class="admin-panel active" id="adminUsersPanel"></div>
|
|
1655
|
+
<div class="admin-panel" id="adminSharedMemoriesPanel"></div>
|
|
1656
|
+
<div class="admin-panel" id="adminMemoriesPanel"></div>
|
|
1657
|
+
<div class="admin-panel" id="adminSkillsPanel"></div>
|
|
1588
1658
|
</div>
|
|
1589
|
-
<div class="admin-panel active" id="adminUsersPanel"></div>
|
|
1590
|
-
<div class="admin-panel" id="adminSharedMemoriesPanel"></div>
|
|
1591
|
-
<div class="admin-panel" id="adminMemoriesPanel"></div>
|
|
1592
|
-
<div class="admin-panel" id="adminSkillsPanel"></div>
|
|
1593
1659
|
</div>
|
|
1594
1660
|
|
|
1595
1661
|
<!-- ─── Import Page ─── -->
|
|
@@ -1958,6 +2024,8 @@ const I18N={
|
|
|
1958
2024
|
'tab.import':'\u{1F4E5} Import',
|
|
1959
2025
|
'tab.settings':'\u2699 Settings',
|
|
1960
2026
|
'settings.modelconfig':'Model Configuration',
|
|
2027
|
+
'settings.models':'AI Models',
|
|
2028
|
+
'settings.models.desc':'Configure embedding, summarizer and skill evolution models',
|
|
1961
2029
|
'settings.modelhealth':'Model Health',
|
|
1962
2030
|
'settings.embedding':'Embedding Model',
|
|
1963
2031
|
'settings.summarizer':'Summarizer Model',
|
|
@@ -1996,7 +2064,7 @@ const I18N={
|
|
|
1996
2064
|
'settings.save':'Save Settings',
|
|
1997
2065
|
'settings.reset':'Reset',
|
|
1998
2066
|
'settings.saved':'Saved',
|
|
1999
|
-
'settings.restart.hint':'Some changes require restarting the OpenClaw gateway to take effect.',
|
|
2067
|
+
'settings.restart.hint':'Some changes require restarting the OpenClaw gateway to take effect. After restarting, please refresh this page.',
|
|
2000
2068
|
'settings.save.fail':'Failed to save settings',
|
|
2001
2069
|
'settings.save.emb.required':'Embedding model is required. Please configure an embedding model before saving.',
|
|
2002
2070
|
'settings.save.emb.fail':'Embedding model test failed, cannot save',
|
|
@@ -2126,11 +2194,11 @@ const I18N={
|
|
|
2126
2194
|
'settings.hub.clientSteps.title':'Quick Setup (3 steps)',
|
|
2127
2195
|
'settings.hub.clientSteps.s1':'Ask your Hub admin for Hub Address and Team Token',
|
|
2128
2196
|
'settings.hub.clientSteps.s2':'Fill them in below, click "Test Connection" to verify',
|
|
2129
|
-
'settings.hub.clientSteps.s3':'Click "Save Settings",
|
|
2197
|
+
'settings.hub.clientSteps.s3':'Click "Save Settings", restart OpenClaw gateway, then refresh this page',
|
|
2130
2198
|
'settings.hub.shareInfo.title':'Share this info with your team members:',
|
|
2131
2199
|
'settings.hub.shareInfo.yourIP':'your-IP',
|
|
2132
2200
|
'settings.hub.shareInfo.clickCopy':'Click to copy',
|
|
2133
|
-
'settings.hub.restartAlert':'Hub sharing config saved! Please restart the OpenClaw gateway for changes to take effect.\\n\\nRun: openclaw gateway stop && openclaw gateway',
|
|
2201
|
+
'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',
|
|
2134
2202
|
'settings.hub.hubAddress':'Hub Address',
|
|
2135
2203
|
'settings.hub.hubAddress.hint':'Hub server address, e.g. 192.168.1.100:18800',
|
|
2136
2204
|
'settings.hub.teamTokenClient':'Team Token',
|
|
@@ -2343,8 +2411,37 @@ const I18N={
|
|
|
2343
2411
|
'update.installing':'Installing...',
|
|
2344
2412
|
'update.success':'Updated!',
|
|
2345
2413
|
'update.failed':'Update failed',
|
|
2346
|
-
'update.restarting':'Restarting service...',
|
|
2347
|
-
'update.dismiss':'Dismiss'
|
|
2414
|
+
'update.restarting':'Restarting service, page will refresh automatically...',
|
|
2415
|
+
'update.dismiss':'Dismiss',
|
|
2416
|
+
'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?',
|
|
2417
|
+
'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?',
|
|
2418
|
+
'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',
|
|
2419
|
+
'admin.notEnabled.title':'Team sharing is not enabled',
|
|
2420
|
+
'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.',
|
|
2421
|
+
'admin.notEnabled.setupHub':'Set Up as Hub Server',
|
|
2422
|
+
'admin.notEnabled.joinTeam':'Join an Existing Team',
|
|
2423
|
+
'admin.notEnabled.hint':'If you have previously configured sharing, your data is still preserved. Re-enabling sharing will restore access to all shared content.',
|
|
2424
|
+
'sharing.disconnected.hint':'Unable to reach the Hub server. The Hub may be offline or the network is unavailable.',
|
|
2425
|
+
'sharing.retryConnection':'Retry Connection',
|
|
2426
|
+
'sharing.retryConnection.loading':'Connecting...',
|
|
2427
|
+
'sharing.retryConnection.success':'Connected successfully!',
|
|
2428
|
+
'sharing.retryConnection.fail':'Still unable to connect. Check if the Hub is online.',
|
|
2429
|
+
'guide.title':'Get Started with Team Collaboration',
|
|
2430
|
+
'guide.subtitle':'MemOS supports team memory sharing. Choose one of the following options to enable collaboration, or continue using local-only mode.',
|
|
2431
|
+
'guide.join.title':'Join a Remote Team',
|
|
2432
|
+
'guide.join.desc':'Your team already has a Hub running? Join it to share memories, tasks and skills with team members.',
|
|
2433
|
+
'guide.join.s1':'Ask your Hub admin for the Hub Address and Team Token',
|
|
2434
|
+
'guide.join.s2':'Go to Settings \u2192 Hub & Team, enable sharing, select "Client" mode',
|
|
2435
|
+
'guide.join.s3':'Fill in Hub Address and Team Token, click "Test Connection"',
|
|
2436
|
+
'guide.join.s4':'Save settings, restart the OpenClaw gateway, then refresh this page',
|
|
2437
|
+
'guide.join.btn':'\u2192 Configure Client Mode',
|
|
2438
|
+
'guide.hub.title':'Start Your Own Hub',
|
|
2439
|
+
'guide.hub.desc':'Be the team server. Run a Hub on this device so others can connect and share memories with you.',
|
|
2440
|
+
'guide.hub.s1':'Go to Settings \u2192 Hub & Team, enable sharing, select "Hub" mode',
|
|
2441
|
+
'guide.hub.s2':'Set a team name, save settings, restart the gateway, then refresh this page',
|
|
2442
|
+
'guide.hub.s3':'Share the Hub Address and Team Token with your team members',
|
|
2443
|
+
'guide.hub.s4':'Approve join requests in the Admin Panel',
|
|
2444
|
+
'guide.hub.btn':'\u2192 Configure Hub Mode'
|
|
2348
2445
|
},
|
|
2349
2446
|
zh:{
|
|
2350
2447
|
'title':'MemOS 记忆',
|
|
@@ -2514,6 +2611,8 @@ const I18N={
|
|
|
2514
2611
|
'tab.import':'\u{1F4E5} 导入',
|
|
2515
2612
|
'tab.settings':'\u2699 设置',
|
|
2516
2613
|
'settings.modelconfig':'模型配置',
|
|
2614
|
+
'settings.models':'AI 模型',
|
|
2615
|
+
'settings.models.desc':'配置嵌入模型、摘要模型和技能进化模型',
|
|
2517
2616
|
'settings.modelhealth':'模型健康',
|
|
2518
2617
|
'settings.embedding':'嵌入模型',
|
|
2519
2618
|
'settings.summarizer':'摘要模型',
|
|
@@ -2552,7 +2651,7 @@ const I18N={
|
|
|
2552
2651
|
'settings.save':'保存设置',
|
|
2553
2652
|
'settings.reset':'重置',
|
|
2554
2653
|
'settings.saved':'已保存',
|
|
2555
|
-
'settings.restart.hint':'部分设置修改后需要重启 OpenClaw
|
|
2654
|
+
'settings.restart.hint':'部分设置修改后需要重启 OpenClaw 网关才能生效。重启后请刷新此页面。',
|
|
2556
2655
|
'settings.save.fail':'保存设置失败',
|
|
2557
2656
|
'settings.save.emb.required':'嵌入模型为必填项,请先配置嵌入模型再保存。',
|
|
2558
2657
|
'settings.save.emb.fail':'嵌入模型测试失败,无法保存',
|
|
@@ -2682,11 +2781,11 @@ const I18N={
|
|
|
2682
2781
|
'settings.hub.clientSteps.title':'快速配置(3 步)',
|
|
2683
2782
|
'settings.hub.clientSteps.s1':'向 Hub 管理员获取 Hub 地址和团队令牌',
|
|
2684
2783
|
'settings.hub.clientSteps.s2':'填入下方,点击"测试连接"验证连通性',
|
|
2685
|
-
'settings.hub.clientSteps.s3':'
|
|
2784
|
+
'settings.hub.clientSteps.s3':'点击「保存设置」,重启 OpenClaw 网关,然后刷新此页面',
|
|
2686
2785
|
'settings.hub.shareInfo.title':'请将以下信息分享给团队成员:',
|
|
2687
2786
|
'settings.hub.shareInfo.yourIP':'你的IP',
|
|
2688
2787
|
'settings.hub.shareInfo.clickCopy':'点击复制',
|
|
2689
|
-
'settings.hub.restartAlert':'Hub 共享配置已保存!请重启 OpenClaw
|
|
2788
|
+
'settings.hub.restartAlert':'Hub 共享配置已保存!请重启 OpenClaw 网关使配置生效,重启后请刷新此页面。\\n\\n执行命令:openclaw gateway stop && openclaw gateway start',
|
|
2690
2789
|
'settings.hub.hubAddress':'Hub 地址',
|
|
2691
2790
|
'settings.hub.hubAddress.hint':'Hub 服务器地址,如 192.168.1.100:18800',
|
|
2692
2791
|
'settings.hub.teamTokenClient':'团队令牌',
|
|
@@ -2899,8 +2998,37 @@ const I18N={
|
|
|
2899
2998
|
'update.installing':'安装中...',
|
|
2900
2999
|
'update.success':'更新完成',
|
|
2901
3000
|
'update.failed':'更新失败',
|
|
2902
|
-
'update.restarting':'
|
|
2903
|
-
'update.dismiss':'关闭'
|
|
3001
|
+
'update.restarting':'正在重启服务,页面将自动刷新...',
|
|
3002
|
+
'update.dismiss':'关闭',
|
|
3003
|
+
'sharing.disable.confirm.hub':'你即将关闭 Hub 服务。\\n\\n关闭后将会:\\n\\u2022 所有已连接的团队成员将断开连接\\n\\u2022 他们将无法继续同步记忆、任务和技能\\n\\u2022 已共享的数据会保留,重新开启后仍可使用\\n\\n确定要关闭吗?',
|
|
3004
|
+
'sharing.disable.confirm.client':'你即将断开与团队 Hub 的连接。\\n\\n断开后将会:\\n\\u2022 你将无法再接收团队共享的记忆、任务和技能\\n\\u2022 你的本地数据不受影响,会完整保留\\n\\u2022 之后可以随时重新开启共享来恢复连接\\n\\n确定要断开吗?',
|
|
3005
|
+
'sharing.disable.restartAlert':'共享已关闭。请重启 OpenClaw 网关使更改生效,重启后请刷新此页面。\\n\\n执行命令:openclaw gateway stop && openclaw gateway start',
|
|
3006
|
+
'admin.notEnabled.title':'团队共享尚未开启',
|
|
3007
|
+
'admin.notEnabled.desc':'管理面板用于管理团队成员、共享的记忆、任务和技能。使用此功能前,需要先开启 Hub 共享。',
|
|
3008
|
+
'admin.notEnabled.setupHub':'配置为 Hub 服务端',
|
|
3009
|
+
'admin.notEnabled.joinTeam':'加入已有团队',
|
|
3010
|
+
'admin.notEnabled.hint':'如果之前配置过共享,你的数据仍然保留。重新开启共享即可恢复访问所有共享内容。',
|
|
3011
|
+
'sharing.disconnected.hint':'无法连接到 Hub 服务器,Hub 可能已下线或网络不可用。',
|
|
3012
|
+
'sharing.retryConnection':'重试连接',
|
|
3013
|
+
'sharing.retryConnection.loading':'连接中...',
|
|
3014
|
+
'sharing.retryConnection.success':'连接成功!',
|
|
3015
|
+
'sharing.retryConnection.fail':'仍然无法连接,请检查 Hub 是否在线。',
|
|
3016
|
+
'guide.title':'开始团队协作',
|
|
3017
|
+
'guide.subtitle':'MemOS 支持团队记忆共享。选择以下方式之一开启协作,或继续使用纯本地模式。',
|
|
3018
|
+
'guide.join.title':'加入远程团队',
|
|
3019
|
+
'guide.join.desc':'你的团队已有 Hub 在运行?加入即可与团队成员共享记忆、任务和技能。',
|
|
3020
|
+
'guide.join.s1':'向 Hub 管理员索取 Hub 地址和 Team Token',
|
|
3021
|
+
'guide.join.s2':'前往「设置 → Hub & Team」,开启共享,选择「Client」模式',
|
|
3022
|
+
'guide.join.s3':'填写 Hub 地址和 Team Token,点击「测试连接」',
|
|
3023
|
+
'guide.join.s4':'保存设置,重启 OpenClaw 网关,然后刷新此页面',
|
|
3024
|
+
'guide.join.btn':'\u2192 配置 Client 模式',
|
|
3025
|
+
'guide.hub.title':'自建 Hub 服务',
|
|
3026
|
+
'guide.hub.desc':'将本机作为团队服务端,让其他成员连接过来共享记忆。',
|
|
3027
|
+
'guide.hub.s1':'前往「设置 → Hub & Team」,开启共享,选择「Hub」模式',
|
|
3028
|
+
'guide.hub.s2':'设置团队名称,保存设置后重启网关,然后刷新此页面',
|
|
3029
|
+
'guide.hub.s3':'将 Hub 地址和 Team Token 分享给团队成员',
|
|
3030
|
+
'guide.hub.s4':'在管理面板中审批加入请求',
|
|
3031
|
+
'guide.hub.btn':'\u2192 配置 Hub 模式'
|
|
2904
3032
|
}
|
|
2905
3033
|
};
|
|
2906
3034
|
const LANG_KEY='memos-viewer-lang';
|
|
@@ -3025,8 +3153,6 @@ function selectSharingRole(role){
|
|
|
3025
3153
|
if(sp) sp.style.display='none';
|
|
3026
3154
|
if(tp) tp.style.display='none';
|
|
3027
3155
|
if(ap) ap.style.display='none';
|
|
3028
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3029
|
-
if(adminTab) adminTab.style.display='none';
|
|
3030
3156
|
}else{
|
|
3031
3157
|
if(sp) sp.style.display='';
|
|
3032
3158
|
if(tp) tp.style.display='';
|
|
@@ -3183,10 +3309,12 @@ async function loadSharingStatus(forcePending){
|
|
|
3183
3309
|
sharingStatusCache=d;
|
|
3184
3310
|
renderSharingSidebar(d);
|
|
3185
3311
|
renderSharingSettings(d);
|
|
3312
|
+
updateTeamGuide(d);
|
|
3186
3313
|
if(forcePending && d && d.admin && d.admin.canManageUsers) loadSharingPendingUsers();
|
|
3187
3314
|
}catch(e){
|
|
3188
3315
|
renderSharingSidebar(null);
|
|
3189
3316
|
renderSharingSettings(null);
|
|
3317
|
+
updateTeamGuide(null);
|
|
3190
3318
|
}
|
|
3191
3319
|
}
|
|
3192
3320
|
|
|
@@ -3211,8 +3339,6 @@ function renderSharingSidebar(data){
|
|
|
3211
3339
|
setBadge('#34d399',t('sharing.sidebar.connected'),true);
|
|
3212
3340
|
statusEl.innerHTML='';
|
|
3213
3341
|
hintEl.textContent='';
|
|
3214
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3215
|
-
if(adminTab) adminTab.style.display='';
|
|
3216
3342
|
}else if(conn.pendingApproval&&conn.user){
|
|
3217
3343
|
setBadge('#fbbf24',t('sharing.sidebar.pending'),false);
|
|
3218
3344
|
var html='<div class="info-grid">';
|
|
@@ -3221,8 +3347,6 @@ function renderSharingSidebar(data){
|
|
|
3221
3347
|
html+='</div>';
|
|
3222
3348
|
statusEl.innerHTML=html;
|
|
3223
3349
|
hintEl.textContent=t('sharing.pendingApproval.hint');
|
|
3224
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3225
|
-
if(adminTab) adminTab.style.display='none';
|
|
3226
3350
|
}else if(conn.rejected&&conn.user){
|
|
3227
3351
|
setBadge('#ef4444',t('sharing.sidebar.rejected'),false);
|
|
3228
3352
|
var html='<div class="info-grid">';
|
|
@@ -3231,8 +3355,6 @@ function renderSharingSidebar(data){
|
|
|
3231
3355
|
html+='</div>';
|
|
3232
3356
|
statusEl.innerHTML=html;
|
|
3233
3357
|
hintEl.textContent=t('sharing.rejected.hint');
|
|
3234
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3235
|
-
if(adminTab) adminTab.style.display='none';
|
|
3236
3358
|
}else if(conn.connected&&conn.user){
|
|
3237
3359
|
var isAdmin=conn.user.role==='admin';
|
|
3238
3360
|
setBadge('#34d399',t('sharing.sidebar.connected'),true);
|
|
@@ -3242,12 +3364,10 @@ function renderSharingSidebar(data){
|
|
|
3242
3364
|
html+='</div>';
|
|
3243
3365
|
statusEl.innerHTML=html;
|
|
3244
3366
|
hintEl.innerHTML='';
|
|
3245
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3246
|
-
if(adminTab) adminTab.style.display=isAdmin?'':'none';
|
|
3247
3367
|
}else if(data.clientConfigured){
|
|
3248
3368
|
setBadge('#ef4444',t('sharing.sidebar.disconnected'),false);
|
|
3249
3369
|
statusEl.innerHTML='<div style="font-size:11px;color:var(--text-muted)">'+t('sharing.sidebar.targetHub')+' '+esc(data.hubUrl||'')+'</div>';
|
|
3250
|
-
hintEl.
|
|
3370
|
+
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>';
|
|
3251
3371
|
}else{
|
|
3252
3372
|
setBadge('#888',t('sharing.sidebar.notConfigured'),false);
|
|
3253
3373
|
statusEl.innerHTML='';
|
|
@@ -3259,19 +3379,20 @@ function renderSharingSettings(data){
|
|
|
3259
3379
|
var statusEl=document.getElementById('sharingStatusPanel');
|
|
3260
3380
|
var teamEl=document.getElementById('sharingTeamPanel');
|
|
3261
3381
|
var adminEl=document.getElementById('sharingAdminPanel');
|
|
3382
|
+
var panelsWrap=document.getElementById('sharingPanelsWrap');
|
|
3262
3383
|
if(!statusEl||!teamEl||!adminEl) return;
|
|
3263
3384
|
if(!data||!data.enabled){
|
|
3264
3385
|
statusEl.innerHTML='';teamEl.innerHTML='';adminEl.innerHTML='';
|
|
3386
|
+
if(panelsWrap) panelsWrap.style.display='none';
|
|
3265
3387
|
return;
|
|
3266
3388
|
}
|
|
3389
|
+
if(panelsWrap) panelsWrap.style.display='';
|
|
3267
3390
|
var conn=data.connection||{};
|
|
3268
3391
|
var user=conn.user||{};
|
|
3269
3392
|
var actualRole=data.role||_sharingRole||'client';
|
|
3270
3393
|
if(data.role) _sharingRole=data.role;
|
|
3271
3394
|
var isAdmin=(data.admin&&data.admin.canManageUsers)||(conn.connected&&user.role==='admin')||(actualRole==='hub');
|
|
3272
3395
|
window._isHubAdmin=isAdmin;
|
|
3273
|
-
var adminTab=document.querySelector('.tab[data-view="admin"]');
|
|
3274
|
-
if(adminTab) adminTab.style.display=isAdmin?'':'none';
|
|
3275
3396
|
var hubAdminBtn=document.getElementById('hubAdminEntryBtn');
|
|
3276
3397
|
|
|
3277
3398
|
if(actualRole==='hub'){
|
|
@@ -3282,7 +3403,6 @@ function renderSharingSettings(data){
|
|
|
3282
3403
|
|
|
3283
3404
|
if(actualRole==='client'){
|
|
3284
3405
|
statusEl.style.display='none';teamEl.style.display='none';adminEl.style.display='none';
|
|
3285
|
-
if(adminTab) adminTab.style.display='none';
|
|
3286
3406
|
if(hubAdminBtn) hubAdminBtn.style.display='none';
|
|
3287
3407
|
|
|
3288
3408
|
var connBadge;
|
|
@@ -3313,7 +3433,9 @@ function renderSharingSettings(data){
|
|
|
3313
3433
|
sh+='<span class="hic-label">'+t('sharing.team')+'</span><span class="hic-value">'+esc(conn.teamName||'-')+'</span>';
|
|
3314
3434
|
sh+='</div></div>';
|
|
3315
3435
|
}else{
|
|
3316
|
-
sh+='</div
|
|
3436
|
+
sh+='</div><div class="hic-empty" style="color:var(--text-muted)">'+t('sharing.disconnected.hint')+'</div>'+
|
|
3437
|
+
'<div style="margin-top:10px;padding:0 16px 14px"><button class="btn btn-sm btn-primary" id="btnRetryConn" onclick="retryConnection()">'+t('sharing.retryConnection')+'</button>'+
|
|
3438
|
+
'<span id="retryConnResult" style="margin-left:10px;font-size:11px"></span></div></div>';
|
|
3317
3439
|
}
|
|
3318
3440
|
statusEl.innerHTML=sh;
|
|
3319
3441
|
teamEl.innerHTML='';adminEl.innerHTML='';
|
|
@@ -3323,6 +3445,26 @@ function renderSharingSettings(data){
|
|
|
3323
3445
|
statusEl.innerHTML='';teamEl.innerHTML='';adminEl.innerHTML='';
|
|
3324
3446
|
}
|
|
3325
3447
|
|
|
3448
|
+
async function retryConnection(){
|
|
3449
|
+
var btn=document.getElementById('btnRetryConn');
|
|
3450
|
+
var result=document.getElementById('retryConnResult');
|
|
3451
|
+
if(btn){btn.disabled=true;btn.textContent=t('sharing.retryConnection.loading');}
|
|
3452
|
+
if(result) result.innerHTML='<span style="color:var(--text-muted)">'+t('sharing.retryConnection.loading')+'</span>';
|
|
3453
|
+
try{
|
|
3454
|
+
await loadSharingStatus(false);
|
|
3455
|
+
var d=sharingStatusCache;
|
|
3456
|
+
if(d&&d.connection&&d.connection.connected){
|
|
3457
|
+
toast(t('sharing.retryConnection.success'),'success');
|
|
3458
|
+
if(result) result.innerHTML='<span style="color:#22c55e">\\u2705 '+t('sharing.retryConnection.success')+'</span>';
|
|
3459
|
+
}else{
|
|
3460
|
+
if(result) result.innerHTML='<span style="color:#ef4444">'+t('sharing.retryConnection.fail')+'</span>';
|
|
3461
|
+
}
|
|
3462
|
+
}catch(e){
|
|
3463
|
+
if(result) result.innerHTML='<span style="color:#ef4444">'+t('sharing.retryConnection.fail')+'</span>';
|
|
3464
|
+
}
|
|
3465
|
+
if(btn){btn.disabled=false;btn.textContent=t('sharing.retryConnection');}
|
|
3466
|
+
}
|
|
3467
|
+
|
|
3326
3468
|
async function retryHubJoin(){
|
|
3327
3469
|
if(!confirm(t('sharing.retryJoin.confirm'))) return;
|
|
3328
3470
|
try{
|
|
@@ -3421,6 +3563,29 @@ async function rejectSharingUser(userId,username){
|
|
|
3421
3563
|
}catch(e){toast(t('toast.rejectFail')+': '+e.message,'error');}
|
|
3422
3564
|
}
|
|
3423
3565
|
|
|
3566
|
+
/* ─── Team Setup Guide ─── */
|
|
3567
|
+
var TEAM_GUIDE_DISMISSED_KEY='memos-team-guide-dismissed';
|
|
3568
|
+
function updateTeamGuide(sharingData){
|
|
3569
|
+
var el=document.getElementById('teamSetupGuide');
|
|
3570
|
+
if(!el) return;
|
|
3571
|
+
if(localStorage.getItem(TEAM_GUIDE_DISMISSED_KEY)==='1'){el.style.display='none';return;}
|
|
3572
|
+
var isConfigured=sharingData&&sharingData.enabled;
|
|
3573
|
+
el.style.display=isConfigured?'none':'block';
|
|
3574
|
+
}
|
|
3575
|
+
function dismissTeamGuide(){
|
|
3576
|
+
localStorage.setItem(TEAM_GUIDE_DISMISSED_KEY,'1');
|
|
3577
|
+
var el=document.getElementById('teamSetupGuide');
|
|
3578
|
+
if(el) el.style.display='none';
|
|
3579
|
+
}
|
|
3580
|
+
function guideGoToHub(role){
|
|
3581
|
+
switchSettingsTab('hub',document.querySelector('.settings-tab-btn[data-tab="hub"]'));
|
|
3582
|
+
var chk=document.getElementById('cfgSharingEnabled');
|
|
3583
|
+
if(chk&&!chk.checked){chk.checked=true;onSharingToggle();}
|
|
3584
|
+
selectSharingRole(role);
|
|
3585
|
+
var card=document.getElementById('settingsSharingConfig');
|
|
3586
|
+
if(card) card.scrollIntoView({behavior:'smooth',block:'start'});
|
|
3587
|
+
}
|
|
3588
|
+
|
|
3424
3589
|
/* ─── Group Manager ─── */
|
|
3425
3590
|
var groupManagerUsers=[];
|
|
3426
3591
|
async function loadGroupManager(){
|
|
@@ -3575,7 +3740,35 @@ function switchAdminTab(tab,btn){
|
|
|
3575
3740
|
if(panel) panel.classList.add('active');
|
|
3576
3741
|
}
|
|
3577
3742
|
|
|
3743
|
+
function adminGoSetup(role){
|
|
3744
|
+
switchView('settings');
|
|
3745
|
+
setTimeout(function(){guideGoToHub(role);},200);
|
|
3746
|
+
}
|
|
3747
|
+
|
|
3578
3748
|
async function loadAdminData(){
|
|
3749
|
+
var notEnabledEl=document.getElementById('adminNotEnabled');
|
|
3750
|
+
var mainEl=document.getElementById('adminMainContent');
|
|
3751
|
+
var sharingOn=sharingStatusCache&&sharingStatusCache.enabled;
|
|
3752
|
+
if(!sharingOn){
|
|
3753
|
+
if(mainEl) mainEl.style.display='none';
|
|
3754
|
+
if(notEnabledEl){
|
|
3755
|
+
notEnabledEl.style.display='block';
|
|
3756
|
+
notEnabledEl.innerHTML=
|
|
3757
|
+
'<div style="text-align:center;padding:60px 32px;max-width:520px;margin:0 auto">'+
|
|
3758
|
+
'<div style="font-size:48px;margin-bottom:16px">\u{1F6E1}</div>'+
|
|
3759
|
+
'<div style="font-size:18px;font-weight:700;color:var(--text);margin-bottom:8px">'+t('admin.notEnabled.title')+'</div>'+
|
|
3760
|
+
'<div style="font-size:13px;color:var(--text-sec);line-height:1.7;margin-bottom:24px">'+t('admin.notEnabled.desc')+'</div>'+
|
|
3761
|
+
'<div style="display:flex;gap:12px;justify-content:center;flex-wrap:wrap">'+
|
|
3762
|
+
'<button class="btn btn-primary" style="padding:8px 20px;font-size:13px" onclick="adminGoSetup("hub")">'+t('admin.notEnabled.setupHub')+'</button>'+
|
|
3763
|
+
'<button class="btn btn-ghost" style="padding:8px 20px;font-size:13px" onclick="adminGoSetup("client")">'+t('admin.notEnabled.joinTeam')+'</button>'+
|
|
3764
|
+
'</div>'+
|
|
3765
|
+
'<div style="font-size:11px;color:var(--text-muted);margin-top:20px;line-height:1.6">'+t('admin.notEnabled.hint')+'</div>'+
|
|
3766
|
+
'</div>';
|
|
3767
|
+
}
|
|
3768
|
+
return;
|
|
3769
|
+
}
|
|
3770
|
+
if(notEnabledEl) notEnabledEl.style.display='none';
|
|
3771
|
+
if(mainEl) mainEl.style.display='';
|
|
3579
3772
|
if(!window._isHubAdmin){
|
|
3580
3773
|
var statsEl=document.getElementById('adminStats');
|
|
3581
3774
|
if(statsEl) statsEl.innerHTML='<div class="admin-empty">'+t('admin.noPermission')+'</div>';
|
|
@@ -5271,9 +5464,36 @@ function onProviderChange(section){
|
|
|
5271
5464
|
if(m[2]==='chat'&&def.chatModel&&!mdEl.value.trim()) mdEl.value=def.chatModel;
|
|
5272
5465
|
}
|
|
5273
5466
|
|
|
5274
|
-
|
|
5275
|
-
var
|
|
5467
|
+
function flashSaved(id){
|
|
5468
|
+
var el=document.getElementById(id);
|
|
5469
|
+
if(!el)return;
|
|
5470
|
+
el.classList.add('show');
|
|
5471
|
+
setTimeout(function(){el.classList.remove('show');},2500);
|
|
5472
|
+
}
|
|
5473
|
+
|
|
5474
|
+
async function doSaveConfig(cfg, btnEl, savedId){
|
|
5475
|
+
btnEl.disabled=true;btnEl.textContent=t('settings.test.loading');
|
|
5476
|
+
function done(){btnEl.disabled=false;btnEl.textContent=t('settings.save');}
|
|
5477
|
+
try{
|
|
5478
|
+
const r=await fetch('/api/config',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(cfg)});
|
|
5479
|
+
if(r.status===401){done();toast(t('settings.session.expired'),'error');return false;}
|
|
5480
|
+
if(!r.ok) throw new Error(await r.text());
|
|
5481
|
+
flashSaved(savedId);
|
|
5482
|
+
toast(t('settings.saved'),'success');
|
|
5483
|
+
done();
|
|
5484
|
+
return true;
|
|
5485
|
+
}catch(e){
|
|
5486
|
+
toast(t('settings.save.fail')+': '+e.message,'error');
|
|
5487
|
+
done();
|
|
5488
|
+
return false;
|
|
5489
|
+
}
|
|
5490
|
+
}
|
|
5491
|
+
|
|
5492
|
+
async function saveModelsConfig(){
|
|
5493
|
+
var card=document.querySelector('.card-models');
|
|
5494
|
+
var saveBtn=card.querySelector('.settings-actions .btn-primary');
|
|
5276
5495
|
saveBtn.disabled=true;saveBtn.textContent=t('settings.test.loading');
|
|
5496
|
+
function done(){saveBtn.disabled=false;saveBtn.textContent=t('settings.save');}
|
|
5277
5497
|
|
|
5278
5498
|
const cfg={};
|
|
5279
5499
|
const embP=document.getElementById('cfgEmbProvider').value;
|
|
@@ -5314,52 +5534,8 @@ async function saveConfig(){
|
|
|
5314
5534
|
if(skApiKey) cfg.skillEvolution.summarizer.apiKey=skApiKey;
|
|
5315
5535
|
}
|
|
5316
5536
|
|
|
5317
|
-
const vp=document.getElementById('cfgViewerPort').value.trim();
|
|
5318
|
-
if(vp) cfg.viewerPort=Number(vp);
|
|
5319
|
-
cfg.telemetry={enabled:document.getElementById('cfgTelemetryEnabled').checked};
|
|
5320
|
-
|
|
5321
|
-
function done(){saveBtn.disabled=false;saveBtn.textContent=t('settings.save');}
|
|
5322
|
-
|
|
5323
|
-
var sharingEnabled=document.getElementById('cfgSharingEnabled').checked;
|
|
5324
|
-
cfg.sharing={
|
|
5325
|
-
enabled:sharingEnabled,
|
|
5326
|
-
role:_sharingRole,
|
|
5327
|
-
capabilities:{}
|
|
5328
|
-
};
|
|
5329
|
-
if(sharingEnabled&&_sharingRole==='hub'){
|
|
5330
|
-
var hubPort=document.getElementById('cfgHubPort').value.trim();
|
|
5331
|
-
var hubTeamName=document.getElementById('cfgHubTeamName').value.trim();
|
|
5332
|
-
var hubTeamToken=document.getElementById('cfgHubTeamToken').value.trim();
|
|
5333
|
-
cfg.sharing.hub={port:hubPort?Number(hubPort):18800};
|
|
5334
|
-
if(hubTeamName) cfg.sharing.hub.teamName=hubTeamName;
|
|
5335
|
-
if(hubTeamToken) cfg.sharing.hub.teamToken=hubTeamToken;
|
|
5336
|
-
cfg.sharing.client={hubAddress:'',userToken:'',teamToken:''};
|
|
5337
|
-
}
|
|
5338
|
-
if(sharingEnabled&&_sharingRole==='client'){
|
|
5339
|
-
var clientAddr=document.getElementById('cfgClientHubAddress').value.trim();
|
|
5340
|
-
var clientTeamToken=document.getElementById('cfgClientTeamToken').value.trim();
|
|
5341
|
-
var clientUserToken=document.getElementById('cfgClientUserToken').value.trim();
|
|
5342
|
-
cfg.sharing.client={};
|
|
5343
|
-
if(clientAddr) cfg.sharing.client.hubAddress=clientAddr;
|
|
5344
|
-
if(clientTeamToken) cfg.sharing.client.teamToken=clientTeamToken;
|
|
5345
|
-
if(clientUserToken) cfg.sharing.client.userToken=clientUserToken;
|
|
5346
|
-
cfg.sharing.hub={port:18800,teamName:'',teamToken:''};
|
|
5347
|
-
if(clientAddr){
|
|
5348
|
-
try{
|
|
5349
|
-
var ips=await fetch('/api/local-ips').then(function(r){return r.json();});
|
|
5350
|
-
var localAddrs=['127.0.0.1','localhost','0.0.0.0'].concat(ips.ips||[]);
|
|
5351
|
-
var parsed=new URL(clientAddr.indexOf('://')>-1?clientAddr:'http://'+clientAddr);
|
|
5352
|
-
if(localAddrs.indexOf(parsed.hostname)>=0){
|
|
5353
|
-
done();toast(t('sharing.cannotJoinSelf'),'error');return;
|
|
5354
|
-
}
|
|
5355
|
-
}catch(e){}
|
|
5356
|
-
}
|
|
5357
|
-
}
|
|
5358
|
-
|
|
5359
|
-
// 1) Embedding model is required
|
|
5360
5537
|
if(!embP||embP===''){done();toast(t('settings.save.emb.required'),'error');return;}
|
|
5361
5538
|
|
|
5362
|
-
// 2) Test embedding
|
|
5363
5539
|
try{
|
|
5364
5540
|
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||''})});
|
|
5365
5541
|
if(er.status===401){done();toast(t('settings.session.expired'),'error');return;}
|
|
@@ -5368,7 +5544,6 @@ async function saveConfig(){
|
|
|
5368
5544
|
document.getElementById('testEmbResult').className='test-result ok';document.getElementById('testEmbResult').innerHTML='\\u2705 '+t('settings.test.ok');
|
|
5369
5545
|
}catch(e){done();toast(t('settings.save.emb.fail')+': '+e.message,'error');return;}
|
|
5370
5546
|
|
|
5371
|
-
// 3) Test summarizer if user filled it
|
|
5372
5547
|
if(hasSumConfig&&cfg.summarizer){
|
|
5373
5548
|
try{
|
|
5374
5549
|
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||''})});
|
|
@@ -5379,7 +5554,6 @@ async function saveConfig(){
|
|
|
5379
5554
|
}catch(e){done();toast(t('settings.save.sum.fail')+': '+e.message,'error');return;}
|
|
5380
5555
|
}
|
|
5381
5556
|
|
|
5382
|
-
// 4) Test skill model if user filled it
|
|
5383
5557
|
if(hasSkillConfig&&cfg.skillEvolution.summarizer){
|
|
5384
5558
|
try{
|
|
5385
5559
|
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||''})});
|
|
@@ -5390,7 +5564,6 @@ async function saveConfig(){
|
|
|
5390
5564
|
}catch(e){done();toast(t('settings.save.skill.fail')+': '+e.message,'error');return;}
|
|
5391
5565
|
}
|
|
5392
5566
|
|
|
5393
|
-
// 5) If summarizer or skill model not configured, check OpenClaw fallback and confirm
|
|
5394
5567
|
if(!hasSumConfig||!hasSkillConfig){
|
|
5395
5568
|
try{
|
|
5396
5569
|
var fr=await fetch('/api/fallback-model');
|
|
@@ -5404,22 +5577,86 @@ async function saveConfig(){
|
|
|
5404
5577
|
}catch(e){}
|
|
5405
5578
|
}
|
|
5406
5579
|
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5580
|
+
await doSaveConfig(cfg, saveBtn, 'modelsSaved');
|
|
5581
|
+
}
|
|
5582
|
+
|
|
5583
|
+
async function saveHubConfig(){
|
|
5584
|
+
var card=document.getElementById('settingsSharingConfig');
|
|
5585
|
+
var saveBtn=card.querySelector('.settings-actions .btn-primary');
|
|
5586
|
+
saveBtn.disabled=true;saveBtn.textContent=t('settings.test.loading');
|
|
5587
|
+
function done(){saveBtn.disabled=false;saveBtn.textContent=t('settings.save');}
|
|
5588
|
+
|
|
5589
|
+
const cfg={};
|
|
5590
|
+
var sharingEnabled=document.getElementById('cfgSharingEnabled').checked;
|
|
5591
|
+
cfg.sharing={
|
|
5592
|
+
enabled:sharingEnabled,
|
|
5593
|
+
role:_sharingRole,
|
|
5594
|
+
capabilities:{}
|
|
5595
|
+
};
|
|
5596
|
+
if(sharingEnabled&&_sharingRole==='hub'){
|
|
5597
|
+
var hubPort=document.getElementById('cfgHubPort').value.trim();
|
|
5598
|
+
var hubTeamName=document.getElementById('cfgHubTeamName').value.trim();
|
|
5599
|
+
var hubTeamToken=document.getElementById('cfgHubTeamToken').value.trim();
|
|
5600
|
+
cfg.sharing.hub={port:hubPort?Number(hubPort):18800};
|
|
5601
|
+
if(hubTeamName) cfg.sharing.hub.teamName=hubTeamName;
|
|
5602
|
+
if(hubTeamToken) cfg.sharing.hub.teamToken=hubTeamToken;
|
|
5603
|
+
cfg.sharing.client={hubAddress:'',userToken:'',teamToken:''};
|
|
5604
|
+
}
|
|
5605
|
+
if(sharingEnabled&&_sharingRole==='client'){
|
|
5606
|
+
var clientAddr=document.getElementById('cfgClientHubAddress').value.trim();
|
|
5607
|
+
var clientTeamToken=document.getElementById('cfgClientTeamToken').value.trim();
|
|
5608
|
+
var clientUserToken=document.getElementById('cfgClientUserToken').value.trim();
|
|
5609
|
+
cfg.sharing.client={};
|
|
5610
|
+
if(clientAddr) cfg.sharing.client.hubAddress=clientAddr;
|
|
5611
|
+
if(clientTeamToken) cfg.sharing.client.teamToken=clientTeamToken;
|
|
5612
|
+
if(clientUserToken) cfg.sharing.client.userToken=clientUserToken;
|
|
5613
|
+
cfg.sharing.hub={port:18800,teamName:'',teamToken:''};
|
|
5614
|
+
if(clientAddr){
|
|
5615
|
+
try{
|
|
5616
|
+
var ips=await fetch('/api/local-ips').then(function(r){return r.json();});
|
|
5617
|
+
var localAddrs=['127.0.0.1','localhost','0.0.0.0'].concat(ips.ips||[]);
|
|
5618
|
+
var parsed=new URL(clientAddr.indexOf('://')>-1?clientAddr:'http://'+clientAddr);
|
|
5619
|
+
if(localAddrs.indexOf(parsed.hostname)>=0){
|
|
5620
|
+
done();toast(t('sharing.cannotJoinSelf'),'error');return;
|
|
5621
|
+
}
|
|
5622
|
+
}catch(e){}
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5625
|
+
|
|
5626
|
+
var prevSharingEnabled=sharingStatusCache&&sharingStatusCache.enabled;
|
|
5627
|
+
var prevRole=sharingStatusCache&&sharingStatusCache.role;
|
|
5628
|
+
if(prevSharingEnabled&&!sharingEnabled){
|
|
5629
|
+
var confirmMsg=prevRole==='hub'?t('sharing.disable.confirm.hub'):t('sharing.disable.confirm.client');
|
|
5630
|
+
if(!confirm(confirmMsg)){done();return;}
|
|
5631
|
+
}
|
|
5632
|
+
|
|
5633
|
+
var ok=await doSaveConfig(cfg, saveBtn, 'hubSaved');
|
|
5634
|
+
if(ok){
|
|
5415
5635
|
loadSharingStatus(false);
|
|
5416
5636
|
if(sharingEnabled){
|
|
5417
5637
|
updateHubShareInfo();
|
|
5418
5638
|
setTimeout(function(){alert(t('settings.hub.restartAlert'));},300);
|
|
5419
5639
|
}
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5640
|
+
if(prevSharingEnabled&&!sharingEnabled){
|
|
5641
|
+
setTimeout(function(){alert(t('sharing.disable.restartAlert'));},300);
|
|
5642
|
+
}
|
|
5643
|
+
}
|
|
5644
|
+
}
|
|
5645
|
+
|
|
5646
|
+
async function saveGeneralConfig(){
|
|
5647
|
+
var card=document.querySelector('.card-general');
|
|
5648
|
+
var saveBtn=card.querySelector('.settings-actions .btn-primary');
|
|
5649
|
+
|
|
5650
|
+
const cfg={};
|
|
5651
|
+
const vp=document.getElementById('cfgViewerPort').value.trim();
|
|
5652
|
+
if(vp) cfg.viewerPort=Number(vp);
|
|
5653
|
+
cfg.telemetry={enabled:document.getElementById('cfgTelemetryEnabled').checked};
|
|
5654
|
+
|
|
5655
|
+
await doSaveConfig(cfg, saveBtn, 'generalSaved');
|
|
5656
|
+
}
|
|
5657
|
+
|
|
5658
|
+
async function saveConfig(){
|
|
5659
|
+
await saveModelsConfig();
|
|
5423
5660
|
}
|
|
5424
5661
|
|
|
5425
5662
|
async function testModel(type){
|
|
@@ -5781,12 +6018,25 @@ function renderToolAgg(data){
|
|
|
5781
6018
|
'</tbody></table>';
|
|
5782
6019
|
}
|
|
5783
6020
|
|
|
6021
|
+
/* ─── Sharing status polling ─── */
|
|
6022
|
+
var _sharingPollTimer=null;
|
|
6023
|
+
function startSharingPoll(){
|
|
6024
|
+
stopSharingPoll();
|
|
6025
|
+
_sharingPollTimer=setInterval(function(){
|
|
6026
|
+
if(sharingStatusCache&&sharingStatusCache.enabled) loadSharingStatus(false);
|
|
6027
|
+
},30000);
|
|
6028
|
+
}
|
|
6029
|
+
function stopSharingPoll(){
|
|
6030
|
+
if(_sharingPollTimer){clearInterval(_sharingPollTimer);_sharingPollTimer=null;}
|
|
6031
|
+
}
|
|
6032
|
+
|
|
5784
6033
|
/* ─── Data loading ─── */
|
|
5785
6034
|
async function loadAll(){
|
|
5786
6035
|
await Promise.all([loadStats(),loadMemories(),loadSharingStatus(false)]);
|
|
5787
6036
|
checkMigrateStatus();
|
|
5788
6037
|
connectPPSSE();
|
|
5789
6038
|
checkForUpdate();
|
|
6039
|
+
startSharingPoll();
|
|
5790
6040
|
}
|
|
5791
6041
|
|
|
5792
6042
|
async function loadStats(ownerFilter){
|