@gamaze/hicortex 0.3.16 → 0.3.17
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/consolidate.js +25 -1
- package/dist/db.js +5 -1
- package/dist/storage.js +5 -4
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/consolidate.js
CHANGED
|
@@ -307,9 +307,10 @@ async function stageLinks(db, memories, embedFn, dryRun) {
|
|
|
307
307
|
for (const neighbor of neighbors) {
|
|
308
308
|
const similarity = 1.0 - neighbor.distance;
|
|
309
309
|
if (similarity > CONSOLIDATE_LINK_THRESHOLD) {
|
|
310
|
+
const relationship = classifyRelationship(mem, neighbor, similarity);
|
|
310
311
|
if (!dryRun) {
|
|
311
312
|
try {
|
|
312
|
-
storage.addLink(db, mem.id, neighbor.id,
|
|
313
|
+
storage.addLink(db, mem.id, neighbor.id, relationship, similarity);
|
|
313
314
|
autoLinked++;
|
|
314
315
|
}
|
|
315
316
|
catch {
|
|
@@ -328,6 +329,29 @@ async function stageLinks(db, memories, embedFn, dryRun) {
|
|
|
328
329
|
}
|
|
329
330
|
return { auto_linked: autoLinked, failed };
|
|
330
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* Classify the relationship between two memories based on type, temporal ordering, and similarity.
|
|
334
|
+
*/
|
|
335
|
+
function classifyRelationship(source, target, similarity) {
|
|
336
|
+
// Lesson derived from episode(s)
|
|
337
|
+
if (source.memory_type === "lesson" && target.memory_type === "episode")
|
|
338
|
+
return "derives";
|
|
339
|
+
if (target.memory_type === "lesson" && source.memory_type === "episode")
|
|
340
|
+
return "derives";
|
|
341
|
+
// Same type + very high similarity + different timestamps → newer updates older
|
|
342
|
+
if (source.memory_type === target.memory_type &&
|
|
343
|
+
similarity > 0.8 &&
|
|
344
|
+
source.created_at !== target.created_at) {
|
|
345
|
+
return "updates";
|
|
346
|
+
}
|
|
347
|
+
// Same project, moderate similarity → extends
|
|
348
|
+
if (source.project && target.project &&
|
|
349
|
+
source.project === target.project &&
|
|
350
|
+
similarity > 0.55 && similarity <= 0.8) {
|
|
351
|
+
return "extends";
|
|
352
|
+
}
|
|
353
|
+
return "relates_to";
|
|
354
|
+
}
|
|
331
355
|
// ---------------------------------------------------------------------------
|
|
332
356
|
// Stage 4: Decay & Prune
|
|
333
357
|
// ---------------------------------------------------------------------------
|
package/dist/db.js
CHANGED
|
@@ -103,7 +103,8 @@ CREATE TABLE IF NOT EXISTS memories (
|
|
|
103
103
|
source_session TEXT,
|
|
104
104
|
project TEXT,
|
|
105
105
|
privacy TEXT DEFAULT 'WORK',
|
|
106
|
-
memory_type TEXT DEFAULT 'episode'
|
|
106
|
+
memory_type TEXT DEFAULT 'episode',
|
|
107
|
+
updated_at TIMESTAMP
|
|
107
108
|
);
|
|
108
109
|
|
|
109
110
|
CREATE TABLE IF NOT EXISTS memory_links (
|
|
@@ -184,6 +185,9 @@ function migrate(db) {
|
|
|
184
185
|
db.exec("UPDATE memories SET ingested_at = created_at");
|
|
185
186
|
db.exec("CREATE INDEX IF NOT EXISTS idx_memories_ingested ON memories(ingested_at)");
|
|
186
187
|
}
|
|
188
|
+
if (!colNames.has("updated_at")) {
|
|
189
|
+
db.exec("ALTER TABLE memories ADD COLUMN updated_at TIMESTAMP");
|
|
190
|
+
}
|
|
187
191
|
}
|
|
188
192
|
/**
|
|
189
193
|
* Return database statistics.
|
package/dist/storage.js
CHANGED
|
@@ -77,21 +77,22 @@ const ALLOWED_UPDATE_FIELDS = new Set([
|
|
|
77
77
|
"project",
|
|
78
78
|
"privacy",
|
|
79
79
|
"memory_type",
|
|
80
|
+
"updated_at",
|
|
80
81
|
]);
|
|
81
82
|
/**
|
|
82
83
|
* Update specific fields on a memory.
|
|
83
84
|
*/
|
|
84
85
|
function updateMemory(db, memoryId, fields) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
// Auto-set updated_at timestamp
|
|
87
|
+
const fieldsWithTimestamp = { ...fields, updated_at: new Date().toISOString() };
|
|
88
|
+
const keys = Object.keys(fieldsWithTimestamp);
|
|
88
89
|
for (const k of keys) {
|
|
89
90
|
if (!ALLOWED_UPDATE_FIELDS.has(k)) {
|
|
90
91
|
throw new Error(`Cannot update field: ${k}`);
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
const setClause = keys.map((k) => `"${k}" = ?`).join(", ");
|
|
94
|
-
const values = keys.map((k) =>
|
|
95
|
+
const values = keys.map((k) => fieldsWithTimestamp[k]);
|
|
95
96
|
values.push(memoryId);
|
|
96
97
|
db.prepare(`UPDATE memories SET ${setClause} WHERE id = ?`).run(...values);
|
|
97
98
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export interface Memory {
|
|
|
16
16
|
project: string | null;
|
|
17
17
|
privacy: "PUBLIC" | "WORK" | "PERSONAL" | "SENSITIVE";
|
|
18
18
|
memory_type: "episode" | "lesson" | "fact" | "decision";
|
|
19
|
+
updated_at: string | null;
|
|
19
20
|
}
|
|
20
21
|
/** A link between two memories. */
|
|
21
22
|
export interface MemoryLink {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gamaze/hicortex",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.17",
|
|
4
4
|
"description": "Human-like memory for self-improving AI agents. Automatic capturing, nightly reflection, and cross-agent learning. Works with Claude Code and OpenClaw.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|