@agentmemory/agentmemory 0.7.0 → 0.7.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.
@@ -727,7 +727,7 @@
727
727
  <div class="app-header">
728
728
  <div class="brand">
729
729
  <h1>agentmemory</h1>
730
- <span class="version">v0.5.0</span>
730
+ <span class="version">v0.7.0</span>
731
731
  </div>
732
732
  <div class="header-right">
733
733
  <span class="dateline" id="dateline"></span>
@@ -741,6 +741,7 @@
741
741
  <button data-tab="memories">Memories</button>
742
742
  <button data-tab="timeline">Timeline</button>
743
743
  <button data-tab="sessions">Sessions</button>
744
+ <button data-tab="lessons">Lessons</button>
744
745
  <button data-tab="audit">Audit</button>
745
746
  <button data-tab="activity">Activity</button>
746
747
  <button data-tab="profile">Profile</button>
@@ -749,6 +750,7 @@
749
750
  <div id="view-dashboard" class="view active"></div>
750
751
  <div id="view-graph" class="view"></div>
751
752
  <div id="view-memories" class="view"></div>
753
+ <div id="view-lessons" class="view"></div>
752
754
  <div id="view-timeline" class="view"></div>
753
755
  <div id="view-sessions" class="view"></div>
754
756
  <div id="view-audit" class="view"></div>
@@ -803,13 +805,14 @@
803
805
 
804
806
  var state = {
805
807
  activeTab: 'dashboard',
806
- dashboard: { loaded: false, health: null, sessions: [], memories: [], graphStats: null, recentAudit: [] },
808
+ dashboard: { loaded: false, health: null, sessions: [], memories: [], graphStats: null, recentAudit: [], lessons: [], crystals: [] },
807
809
  graph: { loaded: false, nodes: [], edges: [], stats: null, filters: {}, selectedNode: null },
808
810
  memories: { loaded: false, items: [], search: '', typeFilter: '' },
809
811
  timeline: { loaded: false, observations: [], sessionId: '', minImportance: 0, page: 0, pageSize: 50 },
810
812
  sessions: { loaded: false, items: [], selectedId: null },
811
813
  audit: { loaded: false, entries: [], opFilter: '' },
812
814
  activity: { loaded: false, observations: [], sessions: [], typeFilter: '' },
815
+ lessons: { loaded: false, items: [], search: '' },
813
816
  profile: { loaded: false, projects: [], selectedProject: '', data: null },
814
817
  ws: null
815
818
  };
@@ -891,6 +894,7 @@
891
894
  case 'memories': if (!state.memories.loaded) await loadMemories(); break;
892
895
  case 'timeline': if (!state.timeline.loaded) await loadTimeline(); break;
893
896
  case 'sessions': if (!state.sessions.loaded) await loadSessions(); break;
897
+ case 'lessons': if (!state.lessons.loaded) await loadLessons(); break;
894
898
  case 'audit': if (!state.audit.loaded) await loadAudit(); break;
895
899
  case 'activity': if (!state.activity.loaded) await loadActivity(); break;
896
900
  case 'profile': if (!state.profile.loaded) await loadProfile(); break;
@@ -908,7 +912,9 @@
908
912
  apiGet('audit?limit=5'),
909
913
  apiGet('semantic'),
910
914
  apiGet('procedural'),
911
- apiGet('relations')
915
+ apiGet('relations'),
916
+ apiGet('lessons'),
917
+ apiGet('crystals')
912
918
  ]);
913
919
  state.dashboard.health = results[0];
914
920
  state.dashboard.sessions = (results[1] && results[1].sessions) || [];
@@ -917,6 +923,8 @@
917
923
  state.dashboard.recentAudit = (results[4] && results[4].entries) || [];
918
924
  state.dashboard.semantic = (results[5] && results[5].facts) || (results[5] && results[5].semantic) || [];
919
925
  state.dashboard.procedural = (results[6] && results[6].procedures) || (results[6] && results[6].procedural) || [];
926
+ state.dashboard.lessons = (results[8] && results[8].lessons) || [];
927
+ state.dashboard.crystals = (results[9] && results[9].crystals) || [];
920
928
  state.dashboard.relations = (results[7] && results[7].relations) || [];
921
929
  state.dashboard.loaded = true;
922
930
  renderDashboard();
@@ -940,6 +948,10 @@
940
948
  var html = '<div class="stats-grid">';
941
949
  html += '<div class="stat-card"><div class="label">Sessions</div><div class="value">' + d.sessions.length + '</div><div class="sub">' + activeSessions + ' active</div></div>';
942
950
  html += '<div class="stat-card"><div class="label">Memories</div><div class="value">' + d.memories.length + '</div><div class="sub">latest versions</div></div>';
951
+ var lessonCount = (d.lessons || []).length;
952
+ var crystalCount = (d.crystals || []).length;
953
+ html += '<div class="stat-card"><div class="label">Lessons</div><div class="value">' + lessonCount + '</div><div class="sub">confidence-scored</div></div>';
954
+ html += '<div class="stat-card"><div class="label">Crystals</div><div class="value">' + crystalCount + '</div><div class="sub">action digests</div></div>';
943
955
  html += '<div class="stat-card"><div class="label">Graph Nodes</div><div class="value">' + nodeCount + '</div><div class="sub">' + edgeCount + ' edges</div></div>';
944
956
  html += '<div class="stat-card"><div class="label">Health</div><div class="value"><div class="health-bar"><span class="health-dot ' + dotClass + '"></span> ' + esc(healthStatus) + '</div></div>';
945
957
  html += '<div class="sub">' + esc(snap.connectionState || 'unknown') + '</div></div>';
@@ -2210,6 +2222,53 @@
2210
2222
  setTimeout(function() { btn.textContent = 'Summarize'; btn.disabled = false; }, 2000);
2211
2223
  }
2212
2224
 
2225
+ async function loadLessons() {
2226
+ var el = document.getElementById('view-lessons');
2227
+ el.innerHTML = '<div class="loading">Loading lessons...</div>';
2228
+ var result = await apiGet('lessons');
2229
+ state.lessons.items = (result && result.lessons) || [];
2230
+ state.lessons.loaded = true;
2231
+ renderLessons();
2232
+ }
2233
+
2234
+ function renderLessons() {
2235
+ var el = document.getElementById('view-lessons');
2236
+ var items = state.lessons.items;
2237
+ var search = state.lessons.search.toLowerCase();
2238
+
2239
+ if (search) {
2240
+ items = items.filter(function(l) {
2241
+ return (l.content + ' ' + l.context + ' ' + (l.tags || []).join(' ')).toLowerCase().indexOf(search) >= 0;
2242
+ });
2243
+ }
2244
+
2245
+ var html = '<div style="display:flex;gap:8px;margin-bottom:12px;">';
2246
+ html += '<input class="search-input" type="text" placeholder="Search lessons..." value="' + esc(state.lessons.search) + '" oninput="state.lessons.search=this.value;renderLessons()" style="flex:1" />';
2247
+ html += '<span style="font-size:12px;color:var(--ink-faint);align-self:center;">' + items.length + ' lessons</span>';
2248
+ html += '</div>';
2249
+
2250
+ if (items.length === 0) {
2251
+ html += '<div class="empty-state"><div class="empty-icon">&#128161;</div><p>No lessons yet</p><p style="font-size:12px;color:var(--ink-faint);font-style:italic;">Lessons are extracted from crystals or saved manually via memory_lesson_save.</p></div>';
2252
+ } else {
2253
+ html += '<table><thead><tr><th>Lesson</th><th>Confidence</th><th>Reinforcements</th><th>Source</th><th>Project</th><th>Updated</th></tr></thead><tbody>';
2254
+ items.forEach(function(l) {
2255
+ var confPct = Math.round(l.confidence * 100);
2256
+ var confColor = confPct >= 70 ? 'var(--green)' : confPct >= 40 ? 'var(--yellow)' : 'var(--red)';
2257
+ html += '<tr>';
2258
+ html += '<td style="max-width:400px;">' + esc(truncate(l.content, 120)) + (l.context ? '<div style="font-size:11px;color:var(--ink-faint);margin-top:2px;">' + esc(truncate(l.context, 80)) + '</div>' : '') + '</td>';
2259
+ html += '<td><div class="gauge" style="min-width:80px;"><div class="gauge-bar"><div class="gauge-fill" style="width:' + confPct + '%;background:' + confColor + '"></div></div><span class="gauge-value" style="font-size:11px;">' + confPct + '%</span></div></td>';
2260
+ html += '<td style="text-align:center;">' + (l.reinforcements || 0) + '</td>';
2261
+ html += '<td><span class="badge badge-' + (l.source === 'crystal' ? 'purple' : l.source === 'consolidation' ? 'yellow' : 'blue') + '">' + esc(l.source) + '</span></td>';
2262
+ html += '<td style="font-size:12px;color:var(--ink-muted);">' + esc(l.project || '-') + '</td>';
2263
+ html += '<td style="font-size:12px;color:var(--ink-muted);">' + shortTime(l.updatedAt) + '</td>';
2264
+ html += '</tr>';
2265
+ });
2266
+ html += '</tbody></table>';
2267
+ }
2268
+
2269
+ el.innerHTML = html;
2270
+ }
2271
+
2213
2272
  async function loadAudit() {
2214
2273
  var el = document.getElementById('view-audit');
2215
2274
  el.innerHTML = '<div class="loading">Loading audit log...</div>';
@@ -118,7 +118,7 @@ describe("Export/Import Functions", () => {
118
118
  it("export produces valid ExportData structure", async () => {
119
119
  const result = (await sdk.trigger("mem::export", {})) as ExportData;
120
120
 
121
- expect(result.version).toBe("0.7.0");
121
+ expect(result.version).toBe("0.7.2");
122
122
  expect(result.exportedAt).toBeDefined();
123
123
  expect(result.sessions.length).toBe(1);
124
124
  expect(result.sessions[0].id).toBe("ses_1");