superlocalmemory 3.4.9 → 3.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -3
- package/docs/cloud-backup.md +174 -0
- package/docs/skill-evolution.md +256 -0
- package/ide/hooks/tool-event-hook.sh +101 -11
- package/package.json +1 -1
- package/pyproject.toml +3 -2
- package/src/superlocalmemory/cli/commands.py +359 -0
- package/src/superlocalmemory/cli/ingest_cmd.py +81 -29
- package/src/superlocalmemory/cli/main.py +32 -0
- package/src/superlocalmemory/cli/setup_wizard.py +54 -11
- package/src/superlocalmemory/core/config.py +35 -0
- package/src/superlocalmemory/core/consolidation_engine.py +138 -0
- package/src/superlocalmemory/core/embedding_worker.py +1 -1
- package/src/superlocalmemory/core/engine.py +19 -0
- package/src/superlocalmemory/core/fact_consolidator.py +425 -0
- package/src/superlocalmemory/core/graph_pruner.py +290 -0
- package/src/superlocalmemory/core/maintenance_scheduler.py +44 -3
- package/src/superlocalmemory/core/recall_pipeline.py +9 -0
- package/src/superlocalmemory/core/tier_manager.py +325 -0
- package/src/superlocalmemory/encoding/entity_resolver.py +96 -28
- package/src/superlocalmemory/evolution/__init__.py +29 -0
- package/src/superlocalmemory/evolution/blind_verifier.py +115 -0
- package/src/superlocalmemory/evolution/evolution_store.py +302 -0
- package/src/superlocalmemory/evolution/mutation_generator.py +181 -0
- package/src/superlocalmemory/evolution/skill_evolver.py +555 -0
- package/src/superlocalmemory/evolution/triggers.py +367 -0
- package/src/superlocalmemory/evolution/types.py +92 -0
- package/src/superlocalmemory/hooks/hook_handlers.py +13 -0
- package/src/superlocalmemory/infra/backup.py +63 -20
- package/src/superlocalmemory/infra/cloud_backup.py +703 -0
- package/src/superlocalmemory/learning/skill_performance_miner.py +422 -0
- package/src/superlocalmemory/mcp/server.py +4 -0
- package/src/superlocalmemory/mcp/tools_evolution.py +338 -0
- package/src/superlocalmemory/retrieval/engine.py +64 -4
- package/src/superlocalmemory/retrieval/forgetting_filter.py +22 -7
- package/src/superlocalmemory/retrieval/strategy.py +2 -2
- package/src/superlocalmemory/server/routes/backup.py +512 -8
- package/src/superlocalmemory/server/routes/behavioral.py +39 -17
- package/src/superlocalmemory/server/routes/evolution.py +213 -0
- package/src/superlocalmemory/server/routes/tiers.py +195 -0
- package/src/superlocalmemory/server/unified_daemon.py +36 -5
- package/src/superlocalmemory/storage/schema_v3410.py +159 -0
- package/src/superlocalmemory/storage/schema_v3411.py +149 -0
- package/src/superlocalmemory/ui/index.html +59 -3
- package/src/superlocalmemory/ui/js/core.js +3 -0
- package/src/superlocalmemory/ui/js/lifecycle.js +83 -0
- package/src/superlocalmemory/ui/js/ng-entities.js +27 -3
- package/src/superlocalmemory/ui/js/ng-shell.js +33 -0
- package/src/superlocalmemory/ui/js/ng-skills.js +611 -0
- package/src/superlocalmemory/ui/js/settings.js +311 -1
- package/src/superlocalmemory.egg-info/PKG-INFO +16 -1
- package/src/superlocalmemory.egg-info/SOURCES.txt +18 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// SuperLocalMemory
|
|
1
|
+
// SuperLocalMemory V3.4.10 "Fortress" - Settings, Backup & Cloud Sync
|
|
2
2
|
// Depends on: core.js, profiles.js (loadProfilesTable)
|
|
3
3
|
|
|
4
4
|
async function loadSettings() {
|
|
@@ -6,6 +6,7 @@ async function loadSettings() {
|
|
|
6
6
|
loadBackupStatus();
|
|
7
7
|
loadBackupList();
|
|
8
8
|
loadLearningDataStats();
|
|
9
|
+
loadCloudDestinations();
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
async function loadLearningDataStats() {
|
|
@@ -222,3 +223,312 @@ function renderBackupList(backups) {
|
|
|
222
223
|
container.textContent = '';
|
|
223
224
|
container.appendChild(table);
|
|
224
225
|
}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
// ---- Cloud Backup (v3.4.10) ----
|
|
229
|
+
|
|
230
|
+
async function loadCloudDestinations() {
|
|
231
|
+
var container = document.getElementById('cloud-destinations');
|
|
232
|
+
if (!container) return;
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
var response = await fetch('/api/backup/destinations');
|
|
236
|
+
var data = await response.json();
|
|
237
|
+
var destinations = data.destinations || [];
|
|
238
|
+
renderCloudDestinations(destinations, container);
|
|
239
|
+
updateAccountWidget(destinations);
|
|
240
|
+
} catch (error) {
|
|
241
|
+
container.innerHTML = '<div class="text-muted small">Cloud backup not available in this version.</div>';
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function updateAccountWidget(destinations) {
|
|
246
|
+
// Update BOTH widgets: old navbar (if present) and new Neural Glass sidebar
|
|
247
|
+
_updateNavbarWidget(destinations);
|
|
248
|
+
_updateSidebarWidget(destinations);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function _updateSidebarWidget(destinations) {
|
|
252
|
+
var avatar = document.getElementById('ng-account-avatar');
|
|
253
|
+
var name = document.getElementById('ng-account-name');
|
|
254
|
+
var status = document.getElementById('ng-account-status');
|
|
255
|
+
var dot = document.getElementById('ng-account-dot');
|
|
256
|
+
var actions = document.getElementById('ng-account-actions');
|
|
257
|
+
|
|
258
|
+
if (!avatar || !name) return;
|
|
259
|
+
|
|
260
|
+
if (!destinations || destinations.length === 0) {
|
|
261
|
+
avatar.innerHTML = '<i class="bi bi-cloud-slash" style="font-size:13px;opacity:0.4;"></i>';
|
|
262
|
+
name.textContent = 'Not connected';
|
|
263
|
+
status.textContent = 'No cloud backup';
|
|
264
|
+
dot.style.background = '#444';
|
|
265
|
+
if (actions) actions.style.display = 'block';
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
var primary = destinations[0];
|
|
270
|
+
var config = {};
|
|
271
|
+
try { config = JSON.parse(primary.config || '{}'); } catch(e) {}
|
|
272
|
+
|
|
273
|
+
if (primary.destination_type === 'google_drive') {
|
|
274
|
+
var email = config.email || 'Google Drive';
|
|
275
|
+
avatar.innerHTML = '<img src="https://www.google.com/s2/favicons?domain=google.com&sz=32" style="width:28px;height:28px;border-radius:50%;" onerror="this.outerHTML=\'<i class=\\\'bi bi-google\\\' style=\\\'font-size:14px;color:#4285f4;\\\'></i>\'">';
|
|
276
|
+
name.textContent = email.split('@')[0];
|
|
277
|
+
name.title = email;
|
|
278
|
+
} else if (primary.destination_type === 'github') {
|
|
279
|
+
var username = config.username || 'GitHub';
|
|
280
|
+
avatar.innerHTML = '<img src="https://github.com/' + username + '.png?size=56" style="width:28px;height:28px;border-radius:50%;" onerror="this.outerHTML=\'<i class=\\\'bi bi-github\\\' style=\\\'font-size:14px;\\\'></i>\'">';
|
|
281
|
+
name.textContent = username;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Sync status
|
|
285
|
+
var hasSuccess = destinations.some(function(d) { return d.last_sync_status === 'success'; });
|
|
286
|
+
var hasFailed = destinations.some(function(d) { return d.last_sync_status === 'failed'; });
|
|
287
|
+
var allNever = destinations.every(function(d) { return d.last_sync_status === 'never'; });
|
|
288
|
+
|
|
289
|
+
if (hasFailed) {
|
|
290
|
+
dot.style.background = '#ff4757';
|
|
291
|
+
status.textContent = 'Sync failed';
|
|
292
|
+
status.style.color = '#ff4757';
|
|
293
|
+
} else if (hasSuccess) {
|
|
294
|
+
dot.style.background = '#00D4AA';
|
|
295
|
+
status.textContent = destinations.length + ' destination' + (destinations.length > 1 ? 's' : '') + ' synced';
|
|
296
|
+
status.style.color = '#00D4AA';
|
|
297
|
+
} else if (allNever) {
|
|
298
|
+
dot.style.background = '#f39c12';
|
|
299
|
+
status.textContent = 'Connected \u2014 not yet synced';
|
|
300
|
+
status.style.color = '#f39c12';
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Show actions row with disconnect options if connected
|
|
304
|
+
if (actions) actions.style.display = 'block';
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function _updateNavbarWidget(destinations) {
|
|
308
|
+
var avatar = document.getElementById('account-avatar');
|
|
309
|
+
var label = document.getElementById('account-label');
|
|
310
|
+
var syncDot = document.getElementById('account-sync-dot');
|
|
311
|
+
var accountList = document.getElementById('account-list');
|
|
312
|
+
var syncLabel = document.getElementById('account-sync-label');
|
|
313
|
+
|
|
314
|
+
if (!avatar || !label) return;
|
|
315
|
+
|
|
316
|
+
if (!destinations || destinations.length === 0) {
|
|
317
|
+
avatar.innerHTML = '<i class="bi bi-cloud-slash" style="font-size:12px;opacity:0.6;"></i>';
|
|
318
|
+
label.textContent = 'Not connected';
|
|
319
|
+
syncDot.style.background = '#666';
|
|
320
|
+
syncDot.title = 'No cloud backup';
|
|
321
|
+
if (accountList) accountList.innerHTML = '<span style="color:#666;">No accounts connected</span>';
|
|
322
|
+
if (syncLabel) syncLabel.textContent = 'Last sync: Never';
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Find primary destination (first one)
|
|
327
|
+
var primary = destinations[0];
|
|
328
|
+
var config = {};
|
|
329
|
+
try { config = JSON.parse(primary.config || '{}'); } catch(e) {}
|
|
330
|
+
|
|
331
|
+
// Set avatar
|
|
332
|
+
var displayName = '';
|
|
333
|
+
if (primary.destination_type === 'google_drive') {
|
|
334
|
+
displayName = config.email || 'Google Drive';
|
|
335
|
+
avatar.innerHTML = '<i class="bi bi-google" style="font-size:12px;color:#4285f4;"></i>';
|
|
336
|
+
} else if (primary.destination_type === 'github') {
|
|
337
|
+
displayName = config.username || 'GitHub';
|
|
338
|
+
avatar.innerHTML = '<i class="bi bi-github" style="font-size:12px;"></i>';
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Set label (show name or email, truncated)
|
|
342
|
+
var shortName = displayName.split('@')[0];
|
|
343
|
+
if (shortName.length > 15) shortName = shortName.substring(0, 13) + '..';
|
|
344
|
+
label.textContent = shortName;
|
|
345
|
+
|
|
346
|
+
// Sync status dot
|
|
347
|
+
var hasSuccess = destinations.some(function(d) { return d.last_sync_status === 'success'; });
|
|
348
|
+
var hasFailed = destinations.some(function(d) { return d.last_sync_status === 'failed'; });
|
|
349
|
+
var allNever = destinations.every(function(d) { return d.last_sync_status === 'never'; });
|
|
350
|
+
|
|
351
|
+
if (hasFailed) {
|
|
352
|
+
syncDot.style.background = '#ff4757';
|
|
353
|
+
syncDot.title = 'Sync failed — click to fix';
|
|
354
|
+
} else if (hasSuccess) {
|
|
355
|
+
syncDot.style.background = '#00D4AA';
|
|
356
|
+
syncDot.title = 'Cloud backup active';
|
|
357
|
+
} else if (allNever) {
|
|
358
|
+
syncDot.style.background = '#f39c12';
|
|
359
|
+
syncDot.title = 'Connected but not yet synced';
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Build the account list in dropdown
|
|
363
|
+
if (accountList) {
|
|
364
|
+
var html = '';
|
|
365
|
+
destinations.forEach(function(dest) {
|
|
366
|
+
var cfg = {};
|
|
367
|
+
try { cfg = JSON.parse(dest.config || '{}'); } catch(e) {}
|
|
368
|
+
var icon = dest.destination_type === 'google_drive'
|
|
369
|
+
? '<i class="bi bi-google" style="color:#4285f4;font-size:14px;"></i>'
|
|
370
|
+
: '<i class="bi bi-github" style="font-size:14px;"></i>';
|
|
371
|
+
var name = dest.display_name || dest.destination_type;
|
|
372
|
+
var statusCls = dest.last_sync_status === 'success' ? 'synced'
|
|
373
|
+
: dest.last_sync_status === 'failed' ? 'failed' : 'never';
|
|
374
|
+
var statusText = dest.last_sync_status === 'success' ? 'Synced'
|
|
375
|
+
: dest.last_sync_status === 'failed' ? 'Failed' : 'Pending';
|
|
376
|
+
|
|
377
|
+
html += '<div class="account-dest-item">' +
|
|
378
|
+
icon +
|
|
379
|
+
'<span style="flex:1;color:#e0e0e0;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">' + name + '</span>' +
|
|
380
|
+
'<span class="account-dest-badge ' + statusCls + '">' + statusText + '</span>' +
|
|
381
|
+
'<button class="btn btn-sm" onclick="disconnectDestination(\'' + dest.id + '\')" style="padding:0;border:0;color:#555;font-size:12px;" title="Disconnect"><i class="bi bi-x"></i></button>' +
|
|
382
|
+
'</div>';
|
|
383
|
+
});
|
|
384
|
+
accountList.innerHTML = html;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Last sync time
|
|
388
|
+
if (syncLabel) {
|
|
389
|
+
var lastSynced = destinations.filter(function(d) { return d.last_sync_at; })
|
|
390
|
+
.sort(function(a, b) { return (b.last_sync_at || '').localeCompare(a.last_sync_at || ''); });
|
|
391
|
+
if (lastSynced.length > 0 && lastSynced[0].last_sync_at) {
|
|
392
|
+
syncLabel.textContent = 'Last sync: ' + formatDateFull(lastSynced[0].last_sync_at);
|
|
393
|
+
} else {
|
|
394
|
+
syncLabel.textContent = 'Last sync: Never';
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function renderCloudDestinations(destinations, container) {
|
|
400
|
+
container.textContent = '';
|
|
401
|
+
|
|
402
|
+
if (destinations.length === 0) {
|
|
403
|
+
container.innerHTML = '<div class="text-muted small mb-2">No cloud destinations configured. Connect Google Drive or GitHub below.</div>';
|
|
404
|
+
} else {
|
|
405
|
+
destinations.forEach(function(dest) {
|
|
406
|
+
var card = document.createElement('div');
|
|
407
|
+
card.className = 'card mb-2';
|
|
408
|
+
card.style.background = 'rgba(255,255,255,0.03)';
|
|
409
|
+
card.style.border = '1px solid rgba(255,255,255,0.08)';
|
|
410
|
+
|
|
411
|
+
var icon = dest.destination_type === 'google_drive' ? 'cloud' : 'github';
|
|
412
|
+
var statusBadge = dest.last_sync_status === 'success'
|
|
413
|
+
? '<span class="badge bg-success">Synced</span>'
|
|
414
|
+
: dest.last_sync_status === 'failed'
|
|
415
|
+
? '<span class="badge bg-danger">Failed</span>'
|
|
416
|
+
: '<span class="badge bg-secondary">Never synced</span>';
|
|
417
|
+
|
|
418
|
+
var lastSync = dest.last_sync_at ? formatDateFull(dest.last_sync_at) : 'Never';
|
|
419
|
+
|
|
420
|
+
card.innerHTML = '<div class="card-body p-2">' +
|
|
421
|
+
'<div class="d-flex justify-content-between align-items-center">' +
|
|
422
|
+
'<div><i class="bi bi-' + icon + '"></i> <strong>' + dest.display_name + '</strong> ' + statusBadge + '</div>' +
|
|
423
|
+
'<button class="btn btn-outline-danger btn-sm" onclick="disconnectDestination(\'' + dest.id + '\')"><i class="bi bi-x-circle"></i></button>' +
|
|
424
|
+
'</div>' +
|
|
425
|
+
'<div class="small text-muted mt-1">Last sync: ' + lastSync + '</div>' +
|
|
426
|
+
'</div>';
|
|
427
|
+
container.appendChild(card);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
async function connectGitHub() {
|
|
433
|
+
showToast('Opening GitHub login...');
|
|
434
|
+
// Open GitHub OAuth in a popup window
|
|
435
|
+
var w = 600, h = 700;
|
|
436
|
+
var left = (screen.width - w) / 2, top = (screen.height - h) / 2;
|
|
437
|
+
var popup = window.open(
|
|
438
|
+
'/api/backup/oauth/github/start',
|
|
439
|
+
'github_oauth',
|
|
440
|
+
'width=' + w + ',height=' + h + ',left=' + left + ',top=' + top
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
// Poll for completion
|
|
444
|
+
var pollTimer = setInterval(function() {
|
|
445
|
+
if (popup && popup.closed) {
|
|
446
|
+
clearInterval(pollTimer);
|
|
447
|
+
loadCloudDestinations();
|
|
448
|
+
loadBackupStatus();
|
|
449
|
+
}
|
|
450
|
+
}, 1000);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
async function connectGoogleDrive() {
|
|
454
|
+
showToast('Opening Google login...');
|
|
455
|
+
// Open Google OAuth in a popup window
|
|
456
|
+
var w = 600, h = 700;
|
|
457
|
+
var left = (screen.width - w) / 2, top = (screen.height - h) / 2;
|
|
458
|
+
var popup = window.open(
|
|
459
|
+
'/api/backup/oauth/google/start',
|
|
460
|
+
'google_oauth',
|
|
461
|
+
'width=' + w + ',height=' + h + ',left=' + left + ',top=' + top
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
// Poll for completion
|
|
465
|
+
var pollTimer = setInterval(function() {
|
|
466
|
+
if (popup && popup.closed) {
|
|
467
|
+
clearInterval(pollTimer);
|
|
468
|
+
loadCloudDestinations();
|
|
469
|
+
loadBackupStatus();
|
|
470
|
+
}
|
|
471
|
+
}, 1000);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
async function disconnectDestination(destId) {
|
|
475
|
+
if (!confirm('Disconnect this backup destination? Your backups on the cloud will remain.')) return;
|
|
476
|
+
|
|
477
|
+
try {
|
|
478
|
+
var response = await fetch('/api/backup/disconnect/' + destId, { method: 'DELETE' });
|
|
479
|
+
if (response.ok) {
|
|
480
|
+
showToast('Destination disconnected');
|
|
481
|
+
loadCloudDestinations();
|
|
482
|
+
loadBackupStatus();
|
|
483
|
+
} else {
|
|
484
|
+
showToast('Failed to disconnect');
|
|
485
|
+
}
|
|
486
|
+
} catch (error) {
|
|
487
|
+
showToast('Failed to disconnect');
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
async function syncCloudNow() {
|
|
492
|
+
showToast('Starting cloud sync...');
|
|
493
|
+
try {
|
|
494
|
+
var response = await fetch('/api/backup/sync', { method: 'POST' });
|
|
495
|
+
var data = await response.json();
|
|
496
|
+
if (data.success) {
|
|
497
|
+
showToast('Backup created. Upload running in background.');
|
|
498
|
+
// Poll for completion every 10 seconds for 5 minutes
|
|
499
|
+
var polls = 0;
|
|
500
|
+
var pollInterval = setInterval(async function() {
|
|
501
|
+
polls++;
|
|
502
|
+
if (polls > 30) { clearInterval(pollInterval); return; }
|
|
503
|
+
try {
|
|
504
|
+
var statusResp = await fetch('/api/backup/destinations');
|
|
505
|
+
var statusData = await statusResp.json();
|
|
506
|
+
var dests = statusData.destinations || [];
|
|
507
|
+
var allDone = dests.length > 0 && dests.every(function(d) {
|
|
508
|
+
return d.last_sync_status === 'success' || d.last_sync_status === 'failed';
|
|
509
|
+
});
|
|
510
|
+
if (allDone) {
|
|
511
|
+
clearInterval(pollInterval);
|
|
512
|
+
var succeeded = dests.filter(function(d) { return d.last_sync_status === 'success'; }).length;
|
|
513
|
+
showToast('Cloud sync done: ' + succeeded + '/' + dests.length + ' destinations');
|
|
514
|
+
loadCloudDestinations();
|
|
515
|
+
loadBackupStatus();
|
|
516
|
+
}
|
|
517
|
+
} catch(e) { /* ignore polling errors */ }
|
|
518
|
+
}, 10000);
|
|
519
|
+
} else {
|
|
520
|
+
showToast('Cloud sync failed');
|
|
521
|
+
}
|
|
522
|
+
} catch (error) {
|
|
523
|
+
showToast('Cloud sync failed');
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
async function exportBackup() {
|
|
528
|
+
showToast('Preparing backup export...');
|
|
529
|
+
try {
|
|
530
|
+
window.location.href = '/api/backup/export';
|
|
531
|
+
} catch (error) {
|
|
532
|
+
showToast('Export failed');
|
|
533
|
+
}
|
|
534
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superlocalmemory
|
|
3
|
-
Version: 3.4.
|
|
3
|
+
Version: 3.4.11
|
|
4
4
|
Summary: Information-geometric agent memory with mathematical guarantees
|
|
5
5
|
Author-email: Varun Pratap Bhardwaj <admin@superlocalmemory.com>
|
|
6
6
|
License: AGPL-3.0-or-later
|
|
@@ -457,6 +457,16 @@ Auto-capture hooks: `slm hooks install` + `slm observe` + `slm session-context`.
|
|
|
457
457
|
- Auto-learned soft prompts injected into agent context
|
|
458
458
|
- Behavioral pattern detection and outcome tracking
|
|
459
459
|
|
|
460
|
+
### Skill Evolution (NEW in v3.4.10)
|
|
461
|
+
- **Per-skill performance tracking** — automatically tracks which skills succeed and which fail, across sessions (zero-LLM, always on)
|
|
462
|
+
- **Execution trace analysis** — mines tool usage patterns around skill invocations to determine effectiveness
|
|
463
|
+
- **Skill entities in Entity Explorer** — each skill becomes a browsable entity with performance facts and evolution history
|
|
464
|
+
- **Dedicated Skill Evolution dashboard tab** — overview cards, performance assertions, skill correlations
|
|
465
|
+
- **Behavioral assertions for skill routing** — soft prompts recommend high-performing skills in future sessions
|
|
466
|
+
- **LLM-powered skill evolution** — 3-trigger system (post-session + degradation + health check) with blind verification. **Off by default** — opt-in via `slm config set evolution.enabled true`. Supports Ollama (free, local), Anthropic API, and OpenAI API backends.
|
|
467
|
+
- **ECC integration** — enhanced observation support with [Everything Claude Code](https://github.com/affaan-m/everything-claude-code) via `slm ingest --source ecc`
|
|
468
|
+
- **IDE compatibility:** Skill tracking currently works with Claude Code. The `/api/v3/tool-event` endpoint accepts events from any IDE client — adapters for other IDEs in future releases.
|
|
469
|
+
|
|
460
470
|
### Trust & Security
|
|
461
471
|
- Bayesian Beta-distribution trust scoring (per-agent, per-fact)
|
|
462
472
|
- Trust gates (block low-trust agents from writing/deleting)
|
|
@@ -587,6 +597,11 @@ Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar.
|
|
|
587
597
|
|
|
588
598
|
Part of [Qualixar](https://qualixar.com) · Author: [Varun Pratap Bhardwaj](https://varunpratap.com)
|
|
589
599
|
|
|
600
|
+
### Acknowledgments
|
|
601
|
+
|
|
602
|
+
- **[Everything Claude Code (ECC)](https://github.com/affaan-m/everything-claude-code)** — SLM's skill observation patterns were inspired by ECC's continuous learning architecture. SLM supports direct ingestion of ECC observations via `slm ingest --source ecc`, giving ECC users richer skill performance tracking. We recommend ECC for Claude Code users who want the deepest learning experience alongside SLM.
|
|
603
|
+
- **[HKUDS/OpenSpace](https://github.com/HKUDS/OpenSpace)** — The skill evolution research in SLM draws from the EvoSkills co-evolutionary verification concepts (arXiv:2604.01687). We adopted their 3-trigger evolution system and anti-loop guard patterns.
|
|
604
|
+
|
|
590
605
|
---
|
|
591
606
|
|
|
592
607
|
<p align="center">
|
|
@@ -66,7 +66,9 @@ src/superlocalmemory/core/embedding_worker.py
|
|
|
66
66
|
src/superlocalmemory/core/embeddings.py
|
|
67
67
|
src/superlocalmemory/core/engine.py
|
|
68
68
|
src/superlocalmemory/core/engine_wiring.py
|
|
69
|
+
src/superlocalmemory/core/fact_consolidator.py
|
|
69
70
|
src/superlocalmemory/core/graph_analyzer.py
|
|
71
|
+
src/superlocalmemory/core/graph_pruner.py
|
|
70
72
|
src/superlocalmemory/core/health_monitor.py
|
|
71
73
|
src/superlocalmemory/core/hooks.py
|
|
72
74
|
src/superlocalmemory/core/maintenance.py
|
|
@@ -80,6 +82,7 @@ src/superlocalmemory/core/registry.py
|
|
|
80
82
|
src/superlocalmemory/core/reranker_worker.py
|
|
81
83
|
src/superlocalmemory/core/store_pipeline.py
|
|
82
84
|
src/superlocalmemory/core/summarizer.py
|
|
85
|
+
src/superlocalmemory/core/tier_manager.py
|
|
83
86
|
src/superlocalmemory/core/worker_pool.py
|
|
84
87
|
src/superlocalmemory/dynamics/__init__.py
|
|
85
88
|
src/superlocalmemory/dynamics/activation_guided_quantization.py
|
|
@@ -103,6 +106,13 @@ src/superlocalmemory/encoding/signal_inference.py
|
|
|
103
106
|
src/superlocalmemory/encoding/temporal_parser.py
|
|
104
107
|
src/superlocalmemory/encoding/temporal_validator.py
|
|
105
108
|
src/superlocalmemory/encoding/type_router.py
|
|
109
|
+
src/superlocalmemory/evolution/__init__.py
|
|
110
|
+
src/superlocalmemory/evolution/blind_verifier.py
|
|
111
|
+
src/superlocalmemory/evolution/evolution_store.py
|
|
112
|
+
src/superlocalmemory/evolution/mutation_generator.py
|
|
113
|
+
src/superlocalmemory/evolution/skill_evolver.py
|
|
114
|
+
src/superlocalmemory/evolution/triggers.py
|
|
115
|
+
src/superlocalmemory/evolution/types.py
|
|
106
116
|
src/superlocalmemory/hooks/__init__.py
|
|
107
117
|
src/superlocalmemory/hooks/auto_capture.py
|
|
108
118
|
src/superlocalmemory/hooks/auto_invoker.py
|
|
@@ -116,6 +126,7 @@ src/superlocalmemory/infra/__init__.py
|
|
|
116
126
|
src/superlocalmemory/infra/auth_middleware.py
|
|
117
127
|
src/superlocalmemory/infra/backup.py
|
|
118
128
|
src/superlocalmemory/infra/cache_manager.py
|
|
129
|
+
src/superlocalmemory/infra/cloud_backup.py
|
|
119
130
|
src/superlocalmemory/infra/event_bus.py
|
|
120
131
|
src/superlocalmemory/infra/heartbeat_monitor.py
|
|
121
132
|
src/superlocalmemory/infra/pid_manager.py
|
|
@@ -150,6 +161,7 @@ src/superlocalmemory/learning/project_context.py
|
|
|
150
161
|
src/superlocalmemory/learning/quantization_scheduler.py
|
|
151
162
|
src/superlocalmemory/learning/ranker.py
|
|
152
163
|
src/superlocalmemory/learning/signals.py
|
|
164
|
+
src/superlocalmemory/learning/skill_performance_miner.py
|
|
153
165
|
src/superlocalmemory/learning/source_quality.py
|
|
154
166
|
src/superlocalmemory/learning/workflows.py
|
|
155
167
|
src/superlocalmemory/llm/__init__.py
|
|
@@ -172,6 +184,7 @@ src/superlocalmemory/mcp/tools.py
|
|
|
172
184
|
src/superlocalmemory/mcp/tools_active.py
|
|
173
185
|
src/superlocalmemory/mcp/tools_code_graph.py
|
|
174
186
|
src/superlocalmemory/mcp/tools_core.py
|
|
187
|
+
src/superlocalmemory/mcp/tools_evolution.py
|
|
175
188
|
src/superlocalmemory/mcp/tools_learning.py
|
|
176
189
|
src/superlocalmemory/mcp/tools_mesh.py
|
|
177
190
|
src/superlocalmemory/mcp/tools_v28.py
|
|
@@ -219,6 +232,7 @@ src/superlocalmemory/server/routes/compliance.py
|
|
|
219
232
|
src/superlocalmemory/server/routes/data_io.py
|
|
220
233
|
src/superlocalmemory/server/routes/entity.py
|
|
221
234
|
src/superlocalmemory/server/routes/events.py
|
|
235
|
+
src/superlocalmemory/server/routes/evolution.py
|
|
222
236
|
src/superlocalmemory/server/routes/helpers.py
|
|
223
237
|
src/superlocalmemory/server/routes/ingest.py
|
|
224
238
|
src/superlocalmemory/server/routes/insights.py
|
|
@@ -228,6 +242,7 @@ src/superlocalmemory/server/routes/memories.py
|
|
|
228
242
|
src/superlocalmemory/server/routes/mesh.py
|
|
229
243
|
src/superlocalmemory/server/routes/profiles.py
|
|
230
244
|
src/superlocalmemory/server/routes/stats.py
|
|
245
|
+
src/superlocalmemory/server/routes/tiers.py
|
|
231
246
|
src/superlocalmemory/server/routes/timeline.py
|
|
232
247
|
src/superlocalmemory/server/routes/v3_api.py
|
|
233
248
|
src/superlocalmemory/server/routes/ws.py
|
|
@@ -243,6 +258,8 @@ src/superlocalmemory/storage/quantized_store.py
|
|
|
243
258
|
src/superlocalmemory/storage/schema.py
|
|
244
259
|
src/superlocalmemory/storage/schema_code_graph.py
|
|
245
260
|
src/superlocalmemory/storage/schema_v32.py
|
|
261
|
+
src/superlocalmemory/storage/schema_v3410.py
|
|
262
|
+
src/superlocalmemory/storage/schema_v3411.py
|
|
246
263
|
src/superlocalmemory/storage/schema_v343.py
|
|
247
264
|
src/superlocalmemory/storage/schema_v347.py
|
|
248
265
|
src/superlocalmemory/storage/v2_migrator.py
|
|
@@ -283,6 +300,7 @@ src/superlocalmemory/ui/js/ng-health.js
|
|
|
283
300
|
src/superlocalmemory/ui/js/ng-ingestion.js
|
|
284
301
|
src/superlocalmemory/ui/js/ng-mesh.js
|
|
285
302
|
src/superlocalmemory/ui/js/ng-shell.js
|
|
303
|
+
src/superlocalmemory/ui/js/ng-skills.js
|
|
286
304
|
src/superlocalmemory/ui/js/patterns.js
|
|
287
305
|
src/superlocalmemory/ui/js/profiles.js
|
|
288
306
|
src/superlocalmemory/ui/js/quick-actions.js
|