claude-memory-layer 1.0.24 → 1.0.26
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/.claude/settings.local.json +15 -1
- package/dist/cli/index.js +156 -972
- package/dist/cli/index.js.map +4 -4
- package/dist/core/index.js +33 -67
- package/dist/core/index.js.map +3 -3
- package/dist/hooks/post-tool-use.js +183 -968
- package/dist/hooks/post-tool-use.js.map +4 -4
- package/dist/hooks/semantic-daemon.js +150 -966
- package/dist/hooks/semantic-daemon.js.map +4 -4
- package/dist/hooks/session-end.js +150 -966
- package/dist/hooks/session-end.js.map +4 -4
- package/dist/hooks/session-start.js +152 -966
- package/dist/hooks/session-start.js.map +4 -4
- package/dist/hooks/stop.js +158 -966
- package/dist/hooks/stop.js.map +4 -4
- package/dist/hooks/user-prompt-submit.js +152 -968
- package/dist/hooks/user-prompt-submit.js.map +4 -4
- package/dist/server/api/index.js +151 -967
- package/dist/server/api/index.js.map +4 -4
- package/dist/server/index.js +151 -967
- package/dist/server/index.js.map +4 -4
- package/dist/services/memory-service.js +150 -966
- package/dist/services/memory-service.js.map +4 -4
- package/memory/_index.md +2 -0
- package/memory/agent_response/uncategorized/2026-03-04.md +276 -1
- package/memory/agent_response/uncategorized/2026-03-05.md +48 -0
- package/memory/session_summary/uncategorized/2026-03-04.md +20 -1
- package/memory/tool_observation/uncategorized/2026-03-04.md +245 -1
- package/memory/tool_observation/uncategorized/2026-03-05.md +29 -0
- package/memory/user_prompt/uncategorized/2026-03-04.md +193 -1
- package/package.json +1 -2
- package/specs/memory-utilization-improvements/context.md +145 -0
- package/specs/memory-utilization-improvements/plan.md +361 -0
- package/specs/memory-utilization-improvements/spec.md +361 -0
- package/specs/optional-duckdb/context.md +77 -0
- package/specs/optional-duckdb/plan.md +142 -0
- package/specs/optional-duckdb/spec.md +35 -0
- package/src/core/db-wrapper.ts +18 -73
- package/src/core/sqlite-event-store.ts +32 -4
- package/src/hooks/post-tool-use.ts +25 -0
- package/src/hooks/session-start.ts +4 -0
- package/src/hooks/stop.ts +14 -0
- package/src/server/api/utils.ts +1 -1
- package/src/services/memory-service.ts +62 -58
package/dist/core/index.js
CHANGED
|
@@ -621,25 +621,7 @@ function parseEntityCanonicalKey(canonicalKey) {
|
|
|
621
621
|
import { randomUUID } from "crypto";
|
|
622
622
|
|
|
623
623
|
// src/core/db-wrapper.ts
|
|
624
|
-
import
|
|
625
|
-
function convertBigInts(obj) {
|
|
626
|
-
if (obj === null || obj === void 0)
|
|
627
|
-
return obj;
|
|
628
|
-
if (typeof obj === "bigint")
|
|
629
|
-
return Number(obj);
|
|
630
|
-
if (obj instanceof Date)
|
|
631
|
-
return obj;
|
|
632
|
-
if (Array.isArray(obj))
|
|
633
|
-
return obj.map(convertBigInts);
|
|
634
|
-
if (typeof obj === "object") {
|
|
635
|
-
const result = {};
|
|
636
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
637
|
-
result[key] = convertBigInts(value);
|
|
638
|
-
}
|
|
639
|
-
return result;
|
|
640
|
-
}
|
|
641
|
-
return obj;
|
|
642
|
-
}
|
|
624
|
+
import BetterSqlite3 from "better-sqlite3";
|
|
643
625
|
function toDate(value) {
|
|
644
626
|
if (value instanceof Date)
|
|
645
627
|
return value;
|
|
@@ -649,59 +631,19 @@ function toDate(value) {
|
|
|
649
631
|
return new Date(value);
|
|
650
632
|
return new Date(String(value));
|
|
651
633
|
}
|
|
652
|
-
function createDatabase(
|
|
653
|
-
|
|
654
|
-
return new duckdb.Database(path2, { access_mode: "READ_ONLY" });
|
|
655
|
-
}
|
|
656
|
-
return new duckdb.Database(path2);
|
|
634
|
+
function createDatabase(dbPath, options) {
|
|
635
|
+
return new BetterSqlite3(dbPath, { readonly: options?.readOnly });
|
|
657
636
|
}
|
|
658
637
|
function dbRun(db, sql, params = []) {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
db.run(sql, (err) => {
|
|
662
|
-
if (err)
|
|
663
|
-
reject(err);
|
|
664
|
-
else
|
|
665
|
-
resolve();
|
|
666
|
-
});
|
|
667
|
-
} else {
|
|
668
|
-
db.run(sql, ...params, (err) => {
|
|
669
|
-
if (err)
|
|
670
|
-
reject(err);
|
|
671
|
-
else
|
|
672
|
-
resolve();
|
|
673
|
-
});
|
|
674
|
-
}
|
|
675
|
-
});
|
|
638
|
+
db.prepare(sql).run(...params);
|
|
639
|
+
return Promise.resolve();
|
|
676
640
|
}
|
|
677
641
|
function dbAll(db, sql, params = []) {
|
|
678
|
-
return
|
|
679
|
-
if (params.length === 0) {
|
|
680
|
-
db.all(sql, (err, rows) => {
|
|
681
|
-
if (err)
|
|
682
|
-
reject(err);
|
|
683
|
-
else
|
|
684
|
-
resolve(convertBigInts(rows || []));
|
|
685
|
-
});
|
|
686
|
-
} else {
|
|
687
|
-
db.all(sql, ...params, (err, rows) => {
|
|
688
|
-
if (err)
|
|
689
|
-
reject(err);
|
|
690
|
-
else
|
|
691
|
-
resolve(convertBigInts(rows || []));
|
|
692
|
-
});
|
|
693
|
-
}
|
|
694
|
-
});
|
|
642
|
+
return Promise.resolve(db.prepare(sql).all(...params));
|
|
695
643
|
}
|
|
696
644
|
function dbClose(db) {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
if (err)
|
|
700
|
-
reject(err);
|
|
701
|
-
else
|
|
702
|
-
resolve();
|
|
703
|
-
});
|
|
704
|
-
});
|
|
645
|
+
db.close();
|
|
646
|
+
return Promise.resolve();
|
|
705
647
|
}
|
|
706
648
|
|
|
707
649
|
// src/core/event-store.ts
|
|
@@ -1903,6 +1845,29 @@ var SQLiteEventStore = class {
|
|
|
1903
1845
|
};
|
|
1904
1846
|
}
|
|
1905
1847
|
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Get session IDs that have events but no session_summary event.
|
|
1850
|
+
* Used to backfill summaries for sessions that ended without Stop hook.
|
|
1851
|
+
*/
|
|
1852
|
+
async getSessionsWithoutSummary(currentSessionId, limit = 5) {
|
|
1853
|
+
await this.initialize();
|
|
1854
|
+
const rows = sqliteAll(
|
|
1855
|
+
this.db,
|
|
1856
|
+
`SELECT DISTINCT e.session_id
|
|
1857
|
+
FROM events e
|
|
1858
|
+
WHERE e.session_id != ?
|
|
1859
|
+
AND e.event_type != 'session_summary'
|
|
1860
|
+
AND e.session_id NOT IN (
|
|
1861
|
+
SELECT DISTINCT session_id FROM events WHERE event_type = 'session_summary'
|
|
1862
|
+
)
|
|
1863
|
+
GROUP BY e.session_id
|
|
1864
|
+
HAVING COUNT(*) >= 3
|
|
1865
|
+
ORDER BY MAX(e.timestamp) DESC
|
|
1866
|
+
LIMIT ?`,
|
|
1867
|
+
[currentSessionId, limit]
|
|
1868
|
+
);
|
|
1869
|
+
return rows.map((r) => r.session_id);
|
|
1870
|
+
}
|
|
1906
1871
|
/**
|
|
1907
1872
|
* Get events by session ID
|
|
1908
1873
|
*/
|
|
@@ -2489,7 +2454,8 @@ var SQLiteEventStore = class {
|
|
|
2489
2454
|
}
|
|
2490
2455
|
}
|
|
2491
2456
|
const retrievalScore = retrieval.retrieval_score || 0;
|
|
2492
|
-
const
|
|
2457
|
+
const promptNorm = Math.min(promptCountAfter / 2, 1);
|
|
2458
|
+
const helpfulnessScore = 0.4 * Math.min(retrievalScore, 1) + 0.3 * promptNorm + 0.2 * toolSuccessRatio + 0.1 * (sessionContinued ? 1 : 0);
|
|
2493
2459
|
sqliteRun(
|
|
2494
2460
|
this.db,
|
|
2495
2461
|
`UPDATE memory_helpfulness
|