superlocalmemory 2.8.0 → 2.8.2
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/ATTRIBUTION.md +50 -0
- package/CHANGELOG.md +8 -0
- package/README.md +24 -15
- package/api_server.py +23 -0
- package/bin/aider-smart +2 -2
- package/bin/slm +35 -15
- package/configs/continue-skills.yaml +4 -4
- package/docs/ARCHITECTURE.md +3 -3
- package/docs/CLI-COMMANDS-REFERENCE.md +18 -18
- package/docs/FRAMEWORK-INTEGRATIONS.md +4 -4
- package/docs/UNIVERSAL-INTEGRATION.md +15 -15
- package/install.sh +19 -4
- package/mcp_server.py +39 -4
- package/package.json +4 -2
- package/skills/slm-list-recent/SKILL.md +1 -1
- package/skills/slm-remember/SKILL.md +1 -1
- package/skills/slm-status/SKILL.md +1 -1
- package/skills/slm-switch-profile/SKILL.md +3 -3
- package/src/graph/graph_core.py +3 -3
- package/src/hnsw_index.py +10 -4
- package/src/lifecycle/lifecycle_engine.py +61 -8
- package/src/lifecycle/lifecycle_evaluator.py +38 -6
- package/src/mcp_tools_v28.py +4 -3
- package/src/memory-profiles.py +1 -0
- package/src/memory_store_v2.py +6 -1
- package/src/qualixar_attribution.py +139 -0
- package/src/qualixar_watermark.py +78 -0
- package/src/setup_validator.py +2 -2
- package/ui/index.html +152 -4
- package/ui/js/behavioral.js +276 -0
- package/ui/js/compliance.js +252 -0
- package/ui/js/init.js +10 -0
- package/ui/js/lifecycle.js +298 -0
- package/ui/js/profiles.js +4 -0
- package/ui_server.py +19 -0
- /package/bin/{superlocalmemoryv2:learning → superlocalmemoryv2-learning} +0 -0
- /package/bin/{superlocalmemoryv2:list → superlocalmemoryv2-list} +0 -0
- /package/bin/{superlocalmemoryv2:patterns → superlocalmemoryv2-patterns} +0 -0
- /package/bin/{superlocalmemoryv2:profile → superlocalmemoryv2-profile} +0 -0
- /package/bin/{superlocalmemoryv2:recall → superlocalmemoryv2-recall} +0 -0
- /package/bin/{superlocalmemoryv2:remember → superlocalmemoryv2-remember} +0 -0
- /package/bin/{superlocalmemoryv2:reset → superlocalmemoryv2-reset} +0 -0
- /package/bin/{superlocalmemoryv2:status → superlocalmemoryv2-status} +0 -0
package/ui/index.html
CHANGED
|
@@ -234,7 +234,7 @@
|
|
|
234
234
|
vertical-align: middle;
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
/*
|
|
237
|
+
/* Project select in navbar */
|
|
238
238
|
.profile-select {
|
|
239
239
|
background: rgba(255,255,255,0.15);
|
|
240
240
|
border: 1px solid rgba(255,255,255,0.3);
|
|
@@ -316,7 +316,7 @@
|
|
|
316
316
|
text-transform: uppercase;
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
-
/*
|
|
319
|
+
/* Project delete button */
|
|
320
320
|
.btn-delete-profile {
|
|
321
321
|
padding: 2px 8px;
|
|
322
322
|
font-size: 0.75rem;
|
|
@@ -546,7 +546,7 @@
|
|
|
546
546
|
padding: 4px 8px;
|
|
547
547
|
}
|
|
548
548
|
|
|
549
|
-
/*
|
|
549
|
+
/* Project select - smaller */
|
|
550
550
|
.profile-select {
|
|
551
551
|
min-width: 90px;
|
|
552
552
|
font-size: 0.75rem;
|
|
@@ -641,7 +641,7 @@
|
|
|
641
641
|
<div class="d-flex align-items-center gap-3">
|
|
642
642
|
<div class="d-flex align-items-center gap-2">
|
|
643
643
|
<i class="bi bi-person-circle text-white-50"></i>
|
|
644
|
-
<select class="form-select form-select-sm profile-select" id="profile-select" title="Switch
|
|
644
|
+
<select class="form-select form-select-sm profile-select" id="profile-select" title="Switch profile">
|
|
645
645
|
<option value="default">default</option>
|
|
646
646
|
</select>
|
|
647
647
|
<button class="btn btn-sm theme-toggle" id="add-profile-btn" title="Create new profile" style="padding:2px 8px;font-size:1rem;line-height:1;">
|
|
@@ -738,6 +738,21 @@
|
|
|
738
738
|
<i class="bi bi-robot"></i> Agents
|
|
739
739
|
</button>
|
|
740
740
|
</li>
|
|
741
|
+
<li class="nav-item" role="presentation">
|
|
742
|
+
<button class="nav-link" id="lifecycle-tab" data-bs-toggle="tab" data-bs-target="#lifecycle-pane" type="button" role="tab">
|
|
743
|
+
<i class="bi bi-hourglass-split"></i> Lifecycle <span class="badge bg-success ms-1">v2.8</span>
|
|
744
|
+
</button>
|
|
745
|
+
</li>
|
|
746
|
+
<li class="nav-item" role="presentation">
|
|
747
|
+
<button class="nav-link" id="behavioral-tab" data-bs-toggle="tab" data-bs-target="#behavioral-pane" type="button" role="tab">
|
|
748
|
+
<i class="bi bi-lightbulb"></i> Behavioral <span class="badge bg-success ms-1">v2.8</span>
|
|
749
|
+
</button>
|
|
750
|
+
</li>
|
|
751
|
+
<li class="nav-item" role="presentation">
|
|
752
|
+
<button class="nav-link" id="compliance-tab" data-bs-toggle="tab" data-bs-target="#compliance-pane" type="button" role="tab">
|
|
753
|
+
<i class="bi bi-shield-lock"></i> Compliance <span class="badge bg-success ms-1">v2.8</span>
|
|
754
|
+
</button>
|
|
755
|
+
</li>
|
|
741
756
|
<li class="nav-item">
|
|
742
757
|
<button class="nav-link" id="settings-tab" data-bs-toggle="tab" data-bs-target="#settings-pane">
|
|
743
758
|
<i class="bi bi-gear"></i> Settings
|
|
@@ -1193,6 +1208,136 @@
|
|
|
1193
1208
|
</div>
|
|
1194
1209
|
</div>
|
|
1195
1210
|
|
|
1211
|
+
<!-- Lifecycle (v2.8) -->
|
|
1212
|
+
<div class="tab-pane fade" id="lifecycle-pane" role="tabpanel">
|
|
1213
|
+
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
1214
|
+
<h5 class="mb-0"><i class="bi bi-hourglass-split text-warning"></i> Memory Lifecycle</h5>
|
|
1215
|
+
<div>
|
|
1216
|
+
<span class="badge bg-secondary me-2" id="lifecycle-profile-badge">default</span>
|
|
1217
|
+
<button class="btn btn-sm btn-outline-info" onclick="compactDryRun()"><i class="bi bi-funnel"></i> Preview Compaction</button>
|
|
1218
|
+
<button class="btn btn-sm btn-outline-warning ms-1" onclick="compactExecute()"><i class="bi bi-lightning"></i> Compact Now</button>
|
|
1219
|
+
</div>
|
|
1220
|
+
</div>
|
|
1221
|
+
<!-- State Distribution -->
|
|
1222
|
+
<div class="row g-3 mb-4" id="lifecycle-states-row">
|
|
1223
|
+
<div class="col-md-2"><div class="card p-3 text-center"><div class="text-success fw-bold fs-3" id="lc-active-count">-</div><small class="text-muted">Active</small></div></div>
|
|
1224
|
+
<div class="col-md-2"><div class="card p-3 text-center"><div class="text-warning fw-bold fs-3" id="lc-warm-count">-</div><small class="text-muted">Warm</small></div></div>
|
|
1225
|
+
<div class="col-md-2"><div class="card p-3 text-center"><div class="text-info fw-bold fs-3" id="lc-cold-count">-</div><small class="text-muted">Cold</small></div></div>
|
|
1226
|
+
<div class="col-md-2"><div class="card p-3 text-center"><div class="text-secondary fw-bold fs-3" id="lc-archived-count">-</div><small class="text-muted">Archived</small></div></div>
|
|
1227
|
+
<div class="col-md-2"><div class="card p-3 text-center"><div class="text-danger fw-bold fs-3" id="lc-tombstoned-count">-</div><small class="text-muted">Tombstoned</small></div></div>
|
|
1228
|
+
<div class="col-md-2"><div class="card p-3 text-center"><div class="fw-bold fs-3" id="lc-total-count">-</div><small class="text-muted">Total</small></div></div>
|
|
1229
|
+
</div>
|
|
1230
|
+
<!-- State Progress Bar -->
|
|
1231
|
+
<div class="card p-3 mb-4">
|
|
1232
|
+
<h6 class="mb-2">State Distribution</h6>
|
|
1233
|
+
<div class="progress" style="height: 24px;" id="lifecycle-progress-bar"></div>
|
|
1234
|
+
</div>
|
|
1235
|
+
<!-- Age Stats -->
|
|
1236
|
+
<div class="card p-3 mb-4" id="lifecycle-age-stats">
|
|
1237
|
+
<h6 class="mb-2">Average Memory Age by State</h6>
|
|
1238
|
+
<div id="lifecycle-age-content"><span class="text-muted">Loading...</span></div>
|
|
1239
|
+
</div>
|
|
1240
|
+
<!-- Recent Transitions -->
|
|
1241
|
+
<div class="card p-3">
|
|
1242
|
+
<h6 class="mb-2">Recent Transitions</h6>
|
|
1243
|
+
<div id="lifecycle-transitions-content"><span class="text-muted">Loading...</span></div>
|
|
1244
|
+
</div>
|
|
1245
|
+
<!-- Compaction Results Modal -->
|
|
1246
|
+
<div id="compaction-results" class="card p-3 mt-3 d-none">
|
|
1247
|
+
<h6 class="mb-2" id="compaction-results-title">Compaction Preview</h6>
|
|
1248
|
+
<div id="compaction-results-content"></div>
|
|
1249
|
+
</div>
|
|
1250
|
+
</div>
|
|
1251
|
+
|
|
1252
|
+
<!-- Behavioral Learning (v2.8) -->
|
|
1253
|
+
<div class="tab-pane fade" id="behavioral-pane" role="tabpanel">
|
|
1254
|
+
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
1255
|
+
<h5 class="mb-0"><i class="bi bi-lightbulb text-info"></i> Behavioral Learning</h5>
|
|
1256
|
+
<span class="badge bg-secondary" id="behavioral-profile-badge">default</span>
|
|
1257
|
+
</div>
|
|
1258
|
+
<!-- Stats Row -->
|
|
1259
|
+
<div class="row g-3 mb-4">
|
|
1260
|
+
<div class="col-md-3"><div class="card p-3 text-center"><div class="fw-bold fs-3 text-success" id="bh-success-count">-</div><small class="text-muted">Successes</small></div></div>
|
|
1261
|
+
<div class="col-md-3"><div class="card p-3 text-center"><div class="fw-bold fs-3 text-danger" id="bh-failure-count">-</div><small class="text-muted">Failures</small></div></div>
|
|
1262
|
+
<div class="col-md-3"><div class="card p-3 text-center"><div class="fw-bold fs-3 text-warning" id="bh-partial-count">-</div><small class="text-muted">Partial</small></div></div>
|
|
1263
|
+
<div class="col-md-3"><div class="card p-3 text-center"><div class="fw-bold fs-3 text-info" id="bh-patterns-count">-</div><small class="text-muted">Patterns Learned</small></div></div>
|
|
1264
|
+
</div>
|
|
1265
|
+
<!-- Report Outcome Form -->
|
|
1266
|
+
<div class="card p-3 mb-4">
|
|
1267
|
+
<h6 class="mb-2"><i class="bi bi-plus-circle"></i> Report Outcome</h6>
|
|
1268
|
+
<div class="row g-2">
|
|
1269
|
+
<div class="col-md-3"><input type="text" class="form-control form-control-sm" id="bh-memory-ids" placeholder="Memory IDs (comma-separated)"></div>
|
|
1270
|
+
<div class="col-md-2"><select class="form-select form-select-sm" id="bh-outcome"><option value="success">Success</option><option value="failure">Failure</option><option value="partial">Partial</option></select></div>
|
|
1271
|
+
<div class="col-md-3"><select class="form-select form-select-sm" id="bh-action-type"><option value="code_written">Code Written</option><option value="decision_made">Decision Made</option><option value="debug_resolved">Debug Resolved</option><option value="architecture_chosen">Architecture Chosen</option><option value="other">Other</option></select></div>
|
|
1272
|
+
<div class="col-md-3"><input type="text" class="form-control form-control-sm" id="bh-context" placeholder="Context (optional)"></div>
|
|
1273
|
+
<div class="col-md-1"><button class="btn btn-sm btn-info w-100" onclick="reportOutcome()"><i class="bi bi-send"></i></button></div>
|
|
1274
|
+
</div>
|
|
1275
|
+
</div>
|
|
1276
|
+
<!-- Learned Patterns -->
|
|
1277
|
+
<div class="card p-3 mb-4">
|
|
1278
|
+
<h6 class="mb-2">Learned Patterns</h6>
|
|
1279
|
+
<div id="behavioral-patterns-content"><span class="text-muted">Loading...</span></div>
|
|
1280
|
+
</div>
|
|
1281
|
+
<!-- Cross-Project Transfers -->
|
|
1282
|
+
<div class="card p-3 mb-4">
|
|
1283
|
+
<h6 class="mb-2">Cross-Project Transfers</h6>
|
|
1284
|
+
<div id="behavioral-transfers-content"><span class="text-muted">Loading...</span></div>
|
|
1285
|
+
</div>
|
|
1286
|
+
<!-- Recent Outcomes -->
|
|
1287
|
+
<div class="card p-3">
|
|
1288
|
+
<h6 class="mb-2">Recent Outcomes</h6>
|
|
1289
|
+
<div id="behavioral-outcomes-content"><span class="text-muted">Loading...</span></div>
|
|
1290
|
+
</div>
|
|
1291
|
+
</div>
|
|
1292
|
+
|
|
1293
|
+
<!-- Compliance & Audit (v2.8) -->
|
|
1294
|
+
<div class="tab-pane fade" id="compliance-pane" role="tabpanel">
|
|
1295
|
+
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
1296
|
+
<h5 class="mb-0"><i class="bi bi-shield-lock text-success"></i> Compliance & Audit</h5>
|
|
1297
|
+
<span class="badge bg-secondary" id="compliance-profile-badge">default</span>
|
|
1298
|
+
</div>
|
|
1299
|
+
<!-- Stats Row -->
|
|
1300
|
+
<div class="row g-3 mb-4">
|
|
1301
|
+
<div class="col-md-4"><div class="card p-3 text-center"><div class="fw-bold fs-3" id="cp-audit-count">-</div><small class="text-muted">Audit Events</small></div></div>
|
|
1302
|
+
<div class="col-md-4"><div class="card p-3 text-center"><div class="fw-bold fs-3" id="cp-retention-count">-</div><small class="text-muted">Retention Policies</small></div></div>
|
|
1303
|
+
<div class="col-md-4"><div class="card p-3 text-center"><div class="fw-bold fs-3" id="cp-abac-count">-</div><small class="text-muted">Access Policies</small></div></div>
|
|
1304
|
+
</div>
|
|
1305
|
+
<!-- Set Retention Policy Form -->
|
|
1306
|
+
<div class="card p-3 mb-4">
|
|
1307
|
+
<h6 class="mb-2"><i class="bi bi-plus-circle"></i> Create Retention Policy</h6>
|
|
1308
|
+
<div class="row g-2">
|
|
1309
|
+
<div class="col-md-3"><input type="text" class="form-control form-control-sm" id="cp-policy-name" placeholder="Policy name"></div>
|
|
1310
|
+
<div class="col-md-2"><input type="number" class="form-control form-control-sm" id="cp-retention-days" placeholder="Days" value="90"></div>
|
|
1311
|
+
<div class="col-md-2"><input type="text" class="form-control form-control-sm" id="cp-category" placeholder="Category (optional)"></div>
|
|
1312
|
+
<div class="col-md-2"><select class="form-select form-select-sm" id="cp-action"><option value="archive">Archive</option><option value="tombstone">Tombstone</option><option value="notify">Notify Only</option></select></div>
|
|
1313
|
+
<div class="col-md-2"><button class="btn btn-sm btn-success w-100" onclick="createRetentionPolicy()"><i class="bi bi-shield-plus"></i> Create</button></div>
|
|
1314
|
+
</div>
|
|
1315
|
+
</div>
|
|
1316
|
+
<!-- Retention Policies List -->
|
|
1317
|
+
<div class="card p-3 mb-4">
|
|
1318
|
+
<h6 class="mb-2">Active Retention Policies</h6>
|
|
1319
|
+
<div id="compliance-policies-content"><span class="text-muted">Loading...</span></div>
|
|
1320
|
+
</div>
|
|
1321
|
+
<!-- Audit Trail -->
|
|
1322
|
+
<div class="card p-3">
|
|
1323
|
+
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
1324
|
+
<h6 class="mb-0">Audit Trail</h6>
|
|
1325
|
+
<div class="d-flex gap-2">
|
|
1326
|
+
<select class="form-select form-select-sm" id="cp-audit-filter" style="width: auto;" onchange="loadCompliance()">
|
|
1327
|
+
<option value="">All Events</option>
|
|
1328
|
+
<option value="recall">Recall</option>
|
|
1329
|
+
<option value="remember">Remember</option>
|
|
1330
|
+
<option value="delete">Delete</option>
|
|
1331
|
+
<option value="lifecycle_transition">Lifecycle</option>
|
|
1332
|
+
<option value="access_denied">Access Denied</option>
|
|
1333
|
+
<option value="retention_enforced">Retention</option>
|
|
1334
|
+
</select>
|
|
1335
|
+
</div>
|
|
1336
|
+
</div>
|
|
1337
|
+
<div id="compliance-audit-content"><span class="text-muted">Loading...</span></div>
|
|
1338
|
+
</div>
|
|
1339
|
+
</div>
|
|
1340
|
+
|
|
1196
1341
|
<!-- Settings & Backup -->
|
|
1197
1342
|
<div class="tab-pane fade" id="settings-pane">
|
|
1198
1343
|
<!-- Profile Management -->
|
|
@@ -1360,6 +1505,9 @@
|
|
|
1360
1505
|
<script src="static/js/agents.js"></script>
|
|
1361
1506
|
<script src="static/js/learning.js"></script>
|
|
1362
1507
|
<script src="static/js/feedback.js"></script>
|
|
1508
|
+
<script src="static/js/lifecycle.js"></script>
|
|
1509
|
+
<script src="static/js/behavioral.js"></script>
|
|
1510
|
+
<script src="static/js/compliance.js"></script>
|
|
1363
1511
|
<script src="static/js/init.js"></script>
|
|
1364
1512
|
|
|
1365
1513
|
<footer>
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2026 SuperLocalMemory (superlocalmemory.com)
|
|
3
|
+
// Behavioral Learning tab — outcomes, patterns, cross-project transfers (v2.8)
|
|
4
|
+
// NOTE: All dynamic values use textContent or escapeHtml() from core.js before DOM insertion.
|
|
5
|
+
|
|
6
|
+
var _behavioralData = null;
|
|
7
|
+
|
|
8
|
+
async function loadBehavioral() {
|
|
9
|
+
try {
|
|
10
|
+
var response = await fetch('/api/behavioral/status');
|
|
11
|
+
var data = await response.json();
|
|
12
|
+
_behavioralData = data;
|
|
13
|
+
|
|
14
|
+
if (!data.available) {
|
|
15
|
+
showEmpty('behavioral-patterns-content', 'lightbulb', 'Behavioral learning not available. Upgrade to v2.8.');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
renderBehavioralStats(data);
|
|
20
|
+
renderBehavioralPatterns(data);
|
|
21
|
+
renderBehavioralTransfers(data);
|
|
22
|
+
renderBehavioralOutcomes(data);
|
|
23
|
+
|
|
24
|
+
var badge = document.getElementById('behavioral-profile-badge');
|
|
25
|
+
if (badge) badge.textContent = data.active_profile || 'default';
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.error('Error loading behavioral:', error);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function renderBehavioralStats(data) {
|
|
32
|
+
var stats = data.stats || {};
|
|
33
|
+
animateCounter('bh-success-count', stats.success_count || 0);
|
|
34
|
+
animateCounter('bh-failure-count', stats.failure_count || 0);
|
|
35
|
+
animateCounter('bh-partial-count', stats.partial_count || 0);
|
|
36
|
+
animateCounter('bh-patterns-count', stats.patterns_count || 0);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function renderBehavioralPatterns(data) {
|
|
40
|
+
var container = document.getElementById('behavioral-patterns-content');
|
|
41
|
+
if (!container) return;
|
|
42
|
+
var patterns = data.patterns || [];
|
|
43
|
+
container.textContent = '';
|
|
44
|
+
|
|
45
|
+
if (patterns.length === 0) {
|
|
46
|
+
var empty = document.createElement('div');
|
|
47
|
+
empty.className = 'text-center text-muted py-3';
|
|
48
|
+
empty.textContent = 'No patterns learned yet. Report outcomes to start learning.';
|
|
49
|
+
container.appendChild(empty);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
for (var i = 0; i < patterns.length; i++) {
|
|
54
|
+
var p = patterns[i];
|
|
55
|
+
var successRate = Math.round((p.success_rate || 0) * 100);
|
|
56
|
+
var confPct = Math.round((p.confidence || 0) * 100);
|
|
57
|
+
var barColor = successRate >= 70 ? 'bg-success' : (successRate >= 40 ? 'bg-warning' : 'bg-danger');
|
|
58
|
+
|
|
59
|
+
var row = document.createElement('div');
|
|
60
|
+
row.className = 'd-flex align-items-center mb-2';
|
|
61
|
+
|
|
62
|
+
// Pattern key label
|
|
63
|
+
var label = document.createElement('div');
|
|
64
|
+
label.style.minWidth = '140px';
|
|
65
|
+
var labelCode = document.createElement('code');
|
|
66
|
+
labelCode.className = 'small';
|
|
67
|
+
labelCode.textContent = p.pattern_key || '';
|
|
68
|
+
label.appendChild(labelCode);
|
|
69
|
+
|
|
70
|
+
// Success rate progress bar
|
|
71
|
+
var barWrap = document.createElement('div');
|
|
72
|
+
barWrap.className = 'flex-grow-1 mx-2';
|
|
73
|
+
var progress = document.createElement('div');
|
|
74
|
+
progress.className = 'progress';
|
|
75
|
+
progress.style.height = '20px';
|
|
76
|
+
progress.style.borderRadius = '10px';
|
|
77
|
+
var barEl = document.createElement('div');
|
|
78
|
+
barEl.className = 'progress-bar ' + barColor;
|
|
79
|
+
barEl.style.width = successRate + '%';
|
|
80
|
+
barEl.style.borderRadius = '10px';
|
|
81
|
+
barEl.style.fontSize = '0.7rem';
|
|
82
|
+
barEl.textContent = successRate + '% success';
|
|
83
|
+
progress.appendChild(barEl);
|
|
84
|
+
barWrap.appendChild(progress);
|
|
85
|
+
|
|
86
|
+
// Evidence count
|
|
87
|
+
var evidence = document.createElement('small');
|
|
88
|
+
evidence.className = 'text-muted';
|
|
89
|
+
evidence.style.minWidth = '50px';
|
|
90
|
+
evidence.style.textAlign = 'right';
|
|
91
|
+
evidence.textContent = (p.evidence_count || 0) + ' ev.';
|
|
92
|
+
|
|
93
|
+
// Confidence badge
|
|
94
|
+
var confBadge = document.createElement('span');
|
|
95
|
+
confBadge.className = 'badge ms-2 ' + (confPct >= 70 ? 'bg-success' : (confPct >= 40 ? 'bg-warning' : 'bg-secondary'));
|
|
96
|
+
confBadge.style.minWidth = '50px';
|
|
97
|
+
confBadge.textContent = confPct + '%';
|
|
98
|
+
|
|
99
|
+
row.appendChild(label);
|
|
100
|
+
row.appendChild(barWrap);
|
|
101
|
+
row.appendChild(evidence);
|
|
102
|
+
row.appendChild(confBadge);
|
|
103
|
+
container.appendChild(row);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function renderBehavioralTransfers(data) {
|
|
108
|
+
var container = document.getElementById('behavioral-transfers-content');
|
|
109
|
+
if (!container) return;
|
|
110
|
+
var transfers = data.transfers || [];
|
|
111
|
+
container.textContent = '';
|
|
112
|
+
|
|
113
|
+
if (transfers.length === 0) {
|
|
114
|
+
var empty = document.createElement('div');
|
|
115
|
+
empty.className = 'text-center text-muted py-3';
|
|
116
|
+
empty.textContent = 'No cross-project transfers yet. Patterns transfer automatically when confidence is high.';
|
|
117
|
+
container.appendChild(empty);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
var table = document.createElement('table');
|
|
122
|
+
table.className = 'table table-sm table-hover mb-0';
|
|
123
|
+
var thead = document.createElement('thead');
|
|
124
|
+
var headRow = document.createElement('tr');
|
|
125
|
+
['Pattern', 'From Project', 'To Project', 'Confidence', 'Date'].forEach(function(h) {
|
|
126
|
+
var th = document.createElement('th');
|
|
127
|
+
th.textContent = h;
|
|
128
|
+
headRow.appendChild(th);
|
|
129
|
+
});
|
|
130
|
+
thead.appendChild(headRow);
|
|
131
|
+
table.appendChild(thead);
|
|
132
|
+
|
|
133
|
+
var tbody = document.createElement('tbody');
|
|
134
|
+
for (var i = 0; i < transfers.length; i++) {
|
|
135
|
+
var t = transfers[i];
|
|
136
|
+
var row = document.createElement('tr');
|
|
137
|
+
|
|
138
|
+
var patternCell = document.createElement('td');
|
|
139
|
+
var patternCode = document.createElement('code');
|
|
140
|
+
patternCode.className = 'small';
|
|
141
|
+
patternCode.textContent = t.pattern_key || '';
|
|
142
|
+
patternCell.appendChild(patternCode);
|
|
143
|
+
row.appendChild(patternCell);
|
|
144
|
+
|
|
145
|
+
var fromCell = document.createElement('td');
|
|
146
|
+
var fromBadge = document.createElement('span');
|
|
147
|
+
fromBadge.className = 'badge bg-secondary';
|
|
148
|
+
fromBadge.textContent = t.from_project || '';
|
|
149
|
+
fromCell.appendChild(fromBadge);
|
|
150
|
+
row.appendChild(fromCell);
|
|
151
|
+
|
|
152
|
+
var toCell = document.createElement('td');
|
|
153
|
+
var toBadge = document.createElement('span');
|
|
154
|
+
toBadge.className = 'badge bg-primary';
|
|
155
|
+
toBadge.textContent = t.to_project || '';
|
|
156
|
+
toCell.appendChild(toBadge);
|
|
157
|
+
row.appendChild(toCell);
|
|
158
|
+
|
|
159
|
+
var confCell = document.createElement('td');
|
|
160
|
+
confCell.textContent = Math.round((t.confidence || 0) * 100) + '%';
|
|
161
|
+
row.appendChild(confCell);
|
|
162
|
+
|
|
163
|
+
var dateCell = document.createElement('td');
|
|
164
|
+
dateCell.className = 'small text-muted';
|
|
165
|
+
dateCell.textContent = formatDate(t.transferred_at || '');
|
|
166
|
+
row.appendChild(dateCell);
|
|
167
|
+
|
|
168
|
+
tbody.appendChild(row);
|
|
169
|
+
}
|
|
170
|
+
table.appendChild(tbody);
|
|
171
|
+
container.appendChild(table);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function renderBehavioralOutcomes(data) {
|
|
175
|
+
var container = document.getElementById('behavioral-outcomes-content');
|
|
176
|
+
if (!container) return;
|
|
177
|
+
var outcomes = data.recent_outcomes || [];
|
|
178
|
+
container.textContent = '';
|
|
179
|
+
|
|
180
|
+
if (outcomes.length === 0) {
|
|
181
|
+
var empty = document.createElement('div');
|
|
182
|
+
empty.className = 'text-center text-muted py-3';
|
|
183
|
+
empty.textContent = 'No outcomes recorded yet. Use the form above or the report_outcome MCP tool.';
|
|
184
|
+
container.appendChild(empty);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
var table = document.createElement('table');
|
|
189
|
+
table.className = 'table table-sm table-hover mb-0';
|
|
190
|
+
var thead = document.createElement('thead');
|
|
191
|
+
var headRow = document.createElement('tr');
|
|
192
|
+
['Memory IDs', 'Outcome', 'Action Type', 'Date'].forEach(function(h) {
|
|
193
|
+
var th = document.createElement('th');
|
|
194
|
+
th.textContent = h;
|
|
195
|
+
headRow.appendChild(th);
|
|
196
|
+
});
|
|
197
|
+
thead.appendChild(headRow);
|
|
198
|
+
table.appendChild(thead);
|
|
199
|
+
|
|
200
|
+
var outcomeBadgeColors = {
|
|
201
|
+
success: 'bg-success',
|
|
202
|
+
failure: 'bg-danger',
|
|
203
|
+
partial: 'bg-warning'
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
var tbody = document.createElement('tbody');
|
|
207
|
+
for (var i = 0; i < outcomes.length; i++) {
|
|
208
|
+
var o = outcomes[i];
|
|
209
|
+
var row = document.createElement('tr');
|
|
210
|
+
|
|
211
|
+
var idsCell = document.createElement('td');
|
|
212
|
+
var memIds = o.memory_ids || [];
|
|
213
|
+
idsCell.textContent = memIds.join(', ');
|
|
214
|
+
row.appendChild(idsCell);
|
|
215
|
+
|
|
216
|
+
var outcomeCell = document.createElement('td');
|
|
217
|
+
var outBadge = document.createElement('span');
|
|
218
|
+
outBadge.className = 'badge ' + (outcomeBadgeColors[o.outcome] || 'bg-secondary');
|
|
219
|
+
outBadge.textContent = o.outcome || '';
|
|
220
|
+
outcomeCell.appendChild(outBadge);
|
|
221
|
+
row.appendChild(outcomeCell);
|
|
222
|
+
|
|
223
|
+
var actionCell = document.createElement('td');
|
|
224
|
+
actionCell.textContent = o.action_type || '';
|
|
225
|
+
row.appendChild(actionCell);
|
|
226
|
+
|
|
227
|
+
var dateCell = document.createElement('td');
|
|
228
|
+
dateCell.className = 'small text-muted';
|
|
229
|
+
dateCell.textContent = formatDate(o.created_at || '');
|
|
230
|
+
row.appendChild(dateCell);
|
|
231
|
+
|
|
232
|
+
tbody.appendChild(row);
|
|
233
|
+
}
|
|
234
|
+
table.appendChild(tbody);
|
|
235
|
+
container.appendChild(table);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function reportOutcome() {
|
|
239
|
+
var memIdsInput = document.getElementById('bh-memory-ids');
|
|
240
|
+
var outcomeSelect = document.getElementById('bh-outcome');
|
|
241
|
+
var actionSelect = document.getElementById('bh-action-type');
|
|
242
|
+
var contextInput = document.getElementById('bh-context');
|
|
243
|
+
|
|
244
|
+
var rawIds = (memIdsInput.value || '').trim();
|
|
245
|
+
if (!rawIds) {
|
|
246
|
+
showToast('Enter at least one memory ID.');
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
var memoryIds = rawIds.split(',').map(function(id) { return id.trim(); }).filter(function(id) { return id.length > 0; });
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
var response = await fetch('/api/behavioral/report-outcome', {
|
|
254
|
+
method: 'POST',
|
|
255
|
+
headers: { 'Content-Type': 'application/json' },
|
|
256
|
+
body: JSON.stringify({
|
|
257
|
+
memory_ids: memoryIds,
|
|
258
|
+
outcome: outcomeSelect.value,
|
|
259
|
+
action_type: actionSelect.value,
|
|
260
|
+
context: contextInput.value.trim() || undefined
|
|
261
|
+
})
|
|
262
|
+
});
|
|
263
|
+
var data = await response.json();
|
|
264
|
+
if (response.ok) {
|
|
265
|
+
showToast('Outcome reported successfully.');
|
|
266
|
+
memIdsInput.value = '';
|
|
267
|
+
contextInput.value = '';
|
|
268
|
+
loadBehavioral(); // Refresh
|
|
269
|
+
} else {
|
|
270
|
+
showToast(data.detail || 'Failed to report outcome.');
|
|
271
|
+
}
|
|
272
|
+
} catch (error) {
|
|
273
|
+
console.error('Error reporting outcome:', error);
|
|
274
|
+
showToast('Error reporting outcome.');
|
|
275
|
+
}
|
|
276
|
+
}
|