hippo-memory 0.8.1 → 0.9.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/README.md +71 -2
- package/dist/cli.d.ts +5 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +581 -211
- package/dist/cli.js.map +1 -1
- package/dist/consolidate.d.ts.map +1 -1
- package/dist/consolidate.js +12 -5
- package/dist/consolidate.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +149 -100
- package/dist/db.js.map +1 -1
- package/dist/handoff.d.ts +29 -0
- package/dist/handoff.d.ts.map +1 -0
- package/dist/handoff.js +30 -0
- package/dist/handoff.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/search.d.ts +19 -0
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +35 -1
- package/dist/search.js.map +1 -1
- package/dist/store.d.ts +18 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +209 -99
- package/dist/store.js.map +1 -1
- package/dist/working-memory.d.ts +59 -0
- package/dist/working-memory.d.ts.map +1 -0
- package/dist/working-memory.js +149 -0
- package/dist/working-memory.js.map +1 -0
- package/extensions/openclaw-plugin/index.ts +569 -495
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Working Memory — bounded buffer for current-state notes.
|
|
3
|
+
*
|
|
4
|
+
* Separate from long-term semantic memory. Entries are scoped,
|
|
5
|
+
* importance-ranked, and automatically evicted when the buffer
|
|
6
|
+
* exceeds WM_MAX_ENTRIES per scope.
|
|
7
|
+
*/
|
|
8
|
+
export declare const WM_MAX_ENTRIES = 20;
|
|
9
|
+
export interface WorkingMemoryItem {
|
|
10
|
+
id: number;
|
|
11
|
+
scope: string;
|
|
12
|
+
sessionId: string | null;
|
|
13
|
+
taskId: string | null;
|
|
14
|
+
importance: number;
|
|
15
|
+
content: string;
|
|
16
|
+
metadata: Record<string, unknown>;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Push a new entry into working memory.
|
|
22
|
+
* If the scope exceeds WM_MAX_ENTRIES, the lowest-importance entry
|
|
23
|
+
* is evicted (ties broken by oldest created_at).
|
|
24
|
+
* Returns the new row ID.
|
|
25
|
+
*/
|
|
26
|
+
export declare function wmPush(hippoRoot: string, opts: {
|
|
27
|
+
scope: string;
|
|
28
|
+
content: string;
|
|
29
|
+
importance?: number;
|
|
30
|
+
sessionId?: string;
|
|
31
|
+
taskId?: string;
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
}): number;
|
|
34
|
+
/**
|
|
35
|
+
* Read working memory entries, sorted by importance DESC.
|
|
36
|
+
*/
|
|
37
|
+
export declare function wmRead(hippoRoot: string, opts?: {
|
|
38
|
+
scope?: string;
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
limit?: number;
|
|
41
|
+
}): WorkingMemoryItem[];
|
|
42
|
+
/**
|
|
43
|
+
* Clear (delete) working memory entries. Returns the count deleted.
|
|
44
|
+
*/
|
|
45
|
+
export declare function wmClear(hippoRoot: string, opts?: {
|
|
46
|
+
scope?: string;
|
|
47
|
+
sessionId?: string;
|
|
48
|
+
}): number;
|
|
49
|
+
/**
|
|
50
|
+
* Flush working memory — delete entries after session end.
|
|
51
|
+
* Functionally identical to wmClear but semantically distinct:
|
|
52
|
+
* used at session boundaries to discard ephemeral state.
|
|
53
|
+
* Returns the count flushed.
|
|
54
|
+
*/
|
|
55
|
+
export declare function wmFlush(hippoRoot: string, opts?: {
|
|
56
|
+
scope?: string;
|
|
57
|
+
sessionId?: string;
|
|
58
|
+
}): number;
|
|
59
|
+
//# sourceMappingURL=working-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"working-memory.d.ts","sourceRoot":"","sources":["../src/working-memory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAkCD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GAAG,MAAM,CAqDT;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,iBAAiB,EAAE,CAgCtB;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAsBT;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAET"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Working Memory — bounded buffer for current-state notes.
|
|
3
|
+
*
|
|
4
|
+
* Separate from long-term semantic memory. Entries are scoped,
|
|
5
|
+
* importance-ranked, and automatically evicted when the buffer
|
|
6
|
+
* exceeds WM_MAX_ENTRIES per scope.
|
|
7
|
+
*/
|
|
8
|
+
import { openHippoDb, closeHippoDb } from './db.js';
|
|
9
|
+
import { initStore } from './store.js';
|
|
10
|
+
export const WM_MAX_ENTRIES = 20;
|
|
11
|
+
function rowToItem(row) {
|
|
12
|
+
let metadata = {};
|
|
13
|
+
try {
|
|
14
|
+
metadata = JSON.parse(row.metadata_json);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// malformed JSON — default to empty
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
id: row.id,
|
|
21
|
+
scope: row.scope,
|
|
22
|
+
sessionId: row.session_id,
|
|
23
|
+
taskId: row.task_id,
|
|
24
|
+
importance: Number(row.importance),
|
|
25
|
+
content: row.content,
|
|
26
|
+
metadata,
|
|
27
|
+
createdAt: row.created_at,
|
|
28
|
+
updatedAt: row.updated_at,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Push a new entry into working memory.
|
|
33
|
+
* If the scope exceeds WM_MAX_ENTRIES, the lowest-importance entry
|
|
34
|
+
* is evicted (ties broken by oldest created_at).
|
|
35
|
+
* Returns the new row ID.
|
|
36
|
+
*/
|
|
37
|
+
export function wmPush(hippoRoot, opts) {
|
|
38
|
+
initStore(hippoRoot);
|
|
39
|
+
const db = openHippoDb(hippoRoot);
|
|
40
|
+
try {
|
|
41
|
+
const now = new Date().toISOString();
|
|
42
|
+
const importance = opts.importance ?? 0;
|
|
43
|
+
db.exec('BEGIN');
|
|
44
|
+
try {
|
|
45
|
+
const result = db.prepare(`
|
|
46
|
+
INSERT INTO working_memory(scope, session_id, task_id, importance, content, metadata_json, created_at, updated_at)
|
|
47
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
48
|
+
`).run(opts.scope, opts.sessionId ?? null, opts.taskId ?? null, importance, opts.content, JSON.stringify(opts.metadata ?? {}), now, now);
|
|
49
|
+
const id = Number(result.lastInsertRowid ?? 0);
|
|
50
|
+
// Evict if over capacity for this scope
|
|
51
|
+
const countRow = db.prepare(`
|
|
52
|
+
SELECT COUNT(*) AS cnt FROM working_memory WHERE scope = ?
|
|
53
|
+
`).get(opts.scope);
|
|
54
|
+
const count = Number(countRow?.cnt ?? 0);
|
|
55
|
+
if (count > WM_MAX_ENTRIES) {
|
|
56
|
+
const excess = count - WM_MAX_ENTRIES;
|
|
57
|
+
db.prepare(`
|
|
58
|
+
DELETE FROM working_memory
|
|
59
|
+
WHERE id IN (
|
|
60
|
+
SELECT id FROM working_memory
|
|
61
|
+
WHERE scope = ?
|
|
62
|
+
ORDER BY importance ASC, created_at ASC
|
|
63
|
+
LIMIT ?
|
|
64
|
+
)
|
|
65
|
+
`).run(opts.scope, excess);
|
|
66
|
+
}
|
|
67
|
+
db.exec('COMMIT');
|
|
68
|
+
return id;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
try {
|
|
72
|
+
db.exec('ROLLBACK');
|
|
73
|
+
}
|
|
74
|
+
catch { /* ignore */ }
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
closeHippoDb(db);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Read working memory entries, sorted by importance DESC.
|
|
84
|
+
*/
|
|
85
|
+
export function wmRead(hippoRoot, opts) {
|
|
86
|
+
initStore(hippoRoot);
|
|
87
|
+
const db = openHippoDb(hippoRoot);
|
|
88
|
+
try {
|
|
89
|
+
const clauses = [];
|
|
90
|
+
const params = [];
|
|
91
|
+
if (opts?.scope) {
|
|
92
|
+
clauses.push('scope = ?');
|
|
93
|
+
params.push(opts.scope);
|
|
94
|
+
}
|
|
95
|
+
if (opts?.sessionId) {
|
|
96
|
+
clauses.push('session_id = ?');
|
|
97
|
+
params.push(opts.sessionId);
|
|
98
|
+
}
|
|
99
|
+
const limit = Math.max(1, Math.trunc(opts?.limit ?? WM_MAX_ENTRIES));
|
|
100
|
+
params.push(limit);
|
|
101
|
+
const where = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
|
|
102
|
+
const rows = db.prepare(`
|
|
103
|
+
SELECT id, scope, session_id, task_id, importance, content, metadata_json, created_at, updated_at
|
|
104
|
+
FROM working_memory
|
|
105
|
+
${where}
|
|
106
|
+
ORDER BY importance DESC, created_at DESC
|
|
107
|
+
LIMIT ?
|
|
108
|
+
`).all(...params);
|
|
109
|
+
return rows.map(rowToItem);
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
closeHippoDb(db);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Clear (delete) working memory entries. Returns the count deleted.
|
|
117
|
+
*/
|
|
118
|
+
export function wmClear(hippoRoot, opts) {
|
|
119
|
+
initStore(hippoRoot);
|
|
120
|
+
const db = openHippoDb(hippoRoot);
|
|
121
|
+
try {
|
|
122
|
+
const clauses = [];
|
|
123
|
+
const params = [];
|
|
124
|
+
if (opts?.scope) {
|
|
125
|
+
clauses.push('scope = ?');
|
|
126
|
+
params.push(opts.scope);
|
|
127
|
+
}
|
|
128
|
+
if (opts?.sessionId) {
|
|
129
|
+
clauses.push('session_id = ?');
|
|
130
|
+
params.push(opts.sessionId);
|
|
131
|
+
}
|
|
132
|
+
const where = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
|
|
133
|
+
const result = db.prepare(`DELETE FROM working_memory ${where}`).run(...params);
|
|
134
|
+
return Number(result.changes ?? 0);
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
closeHippoDb(db);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Flush working memory — delete entries after session end.
|
|
142
|
+
* Functionally identical to wmClear but semantically distinct:
|
|
143
|
+
* used at session boundaries to discard ephemeral state.
|
|
144
|
+
* Returns the count flushed.
|
|
145
|
+
*/
|
|
146
|
+
export function wmFlush(hippoRoot, opts) {
|
|
147
|
+
return wmClear(hippoRoot, opts);
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=working-memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"working-memory.js","sourceRoot":"","sources":["../src/working-memory.ts"],"names":[],"mappings":"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"}
|