@gamaze/hicortex 0.13.3 → 0.14.0

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/storage.js CHANGED
@@ -9,6 +9,7 @@ exports.insertMemory = insertMemory;
9
9
  exports.getMemory = getMemory;
10
10
  exports.updateMemory = updateMemory;
11
11
  exports.strengthenMemory = strengthenMemory;
12
+ exports.touchMemoriesShown = touchMemoriesShown;
12
13
  exports.deleteMemory = deleteMemory;
13
14
  exports.setMemoryTags = setMemoryTags;
14
15
  exports.getMemoryTags = getMemoryTags;
@@ -130,6 +131,24 @@ function strengthenMemory(db, memoryId, nowIsoStr) {
130
131
  SET access_count = access_count + 1, last_accessed = ?
131
132
  WHERE id = ?`).run(nowIsoStr, memoryId);
132
133
  }
134
+ /**
135
+ * Record that memories appeared in a pushed recall index (#192): bump
136
+ * shown_count and refresh last_accessed (a mild strengthen — the decay clock
137
+ * resets so topically-live memories stop sinking) WITHOUT touching
138
+ * access_count, which stays reserved for real use (hardening + prune shield).
139
+ */
140
+ function touchMemoriesShown(db, memoryIds, nowIsoStr) {
141
+ if (memoryIds.length === 0)
142
+ return;
143
+ const stmt = db.prepare(`UPDATE memories
144
+ SET shown_count = COALESCE(shown_count, 0) + 1, last_accessed = ?
145
+ WHERE id = ?`);
146
+ const run = db.transaction((ids) => {
147
+ for (const id of ids)
148
+ stmt.run(nowIsoStr, id);
149
+ });
150
+ run(memoryIds);
151
+ }
133
152
  /**
134
153
  * Delete a memory, its vector, its tags, and all its links.
135
154
  */
@@ -234,7 +253,7 @@ function vectorSearch(db, queryEmbedding, limit = 10, excludeIds = []) {
234
253
  * Full-text search using FTS5 BM25 ranking.
235
254
  * Returns memories with a rank field (lower is better).
236
255
  */
237
- function searchFts(db, query, limit = 10, privacy, sourceAgent) {
256
+ function searchFts(db, query, limit = 10, privacy, sourceAgent, project) {
238
257
  const conditions = ["memories_fts MATCH ?"];
239
258
  const params = [query];
240
259
  if (privacy && privacy.length > 0) {
@@ -246,6 +265,13 @@ function searchFts(db, query, limit = 10, privacy, sourceAgent) {
246
265
  conditions.push("m.source_agent = ?");
247
266
  params.push(sourceAgent);
248
267
  }
268
+ // #192: project is pushed into SQL (like privacy/sourceAgent) instead of
269
+ // being post-filtered by the caller — post-filtering a global top-N against
270
+ // a small project starves the result set regardless of corpus content.
271
+ if (project) {
272
+ conditions.push("m.project = ?");
273
+ params.push(project);
274
+ }
249
275
  const where = conditions.join(" AND ");
250
276
  params.push(limit);
251
277
  const rows = db
package/dist/types.d.ts CHANGED
@@ -42,6 +42,12 @@ export interface MemorySearchResult {
42
42
  project: string | null;
43
43
  created_at: string;
44
44
  connections: number;
45
+ /** True cosine similarity to the query for vector-matched candidates; null
46
+ * for FTS-only and graph-discovered hits (no measured distance). */
47
+ similarity?: number | null;
48
+ /** Which retrieval channel produced the candidate (vector KNN, BM25 FTS,
49
+ * both, or graph traversal). Used by the /recall-index relevance gate. */
50
+ source?: "vector" | "fts" | "both" | "graph";
45
51
  }
46
52
  /** Report returned by the consolidation pipeline. */
47
53
  export interface ConsolidationReport {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamaze/hicortex",
3
- "version": "0.13.3",
3
+ "version": "0.14.0",
4
4
  "description": "Self-learning memory for AI agents \u2014 experience captured automatically, distilled into lessons overnight, shared across your whole fleet. Works with Hermes, OpenClaw, Claude Code, and Pi.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {