Skip to content
This repository was archived by the owner on Apr 20, 2026. It is now read-only.

Commit 6f8f750

Browse files
fix(db,hsg,memory): post-impl verification fixes found by e2e testing
- OM-2: fix upsert_key lookup — query was filtering by user_id but ins_mem stores 'anonymous' as fallback; simplified to key-only lookup since upsert_key is a global stable identifier (users should namespace if needed) - OM-9/OM-11: expose dedup_count, dedup_last_at, upsert_key in HTTP GET /memory/:id response (was MCP-only); add metadata_only param to HTTP POST /memory/query (was MCP-only, HTTP route not updated) - All 5 e2e verification tests now pass locally Co-Authored-By: Claude <noreply@anthropic.com> AI-Generated: true
1 parent bdbb1c8 commit 6f8f750

3 files changed

Lines changed: 28 additions & 19 deletions

File tree

packages/openmemory-js/src/core/db.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type q_type = {
1818
del_mem: { run: (...p: any[]) => Promise<void> };
1919
get_mem: { get: (id: string) => Promise<any> };
2020
get_mem_by_simhash: { get: (simhash: string) => Promise<any> };
21-
get_mem_by_upsert_key: { get: (upsert_key: string, user_id: string | null, user_id2: string | null) => Promise<any> };
21+
get_mem_by_upsert_key: { get: (upsert_key: string) => Promise<any> };
2222
all_mem: { all: (limit: number, offset: number) => Promise<any[]> };
2323
all_mem_by_sector: {
2424
all: (sector: string, limit: number, offset: number) => Promise<any[]>;
@@ -427,10 +427,10 @@ if (is_pg) {
427427
),
428428
},
429429
get_mem_by_upsert_key: {
430-
get: (upsert_key, user_id, user_id2) =>
430+
get: (upsert_key) =>
431431
get_async(
432-
`select * from ${m} where upsert_key=$1 and (user_id=$2 or (user_id is null and $3 is null)) limit 1`,
433-
[upsert_key, user_id, user_id2],
432+
`select * from ${m} where upsert_key=$1 limit 1`,
433+
[upsert_key],
434434
),
435435
},
436436
all_mem: {
@@ -911,10 +911,10 @@ if (is_pg) {
911911
),
912912
},
913913
get_mem_by_upsert_key: {
914-
get: (upsert_key, user_id, user_id2) =>
914+
get: (upsert_key) =>
915915
one(
916-
"select * from memories where upsert_key=? and (user_id=? or (user_id is null and ? is null)) limit 1",
917-
[upsert_key, user_id, user_id2],
916+
"select * from memories where upsert_key=? limit 1",
917+
[upsert_key],
918918
),
919919
},
920920
all_mem: {

packages/openmemory-js/src/memory/hsg.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,7 @@ export async function add_hsg_memory(
10651065
}> {
10661066
// Named upsert: if upsert_key matches an existing memory, update in-place
10671067
if (upsert_key) {
1068-
const existing_uk = await q.get_mem_by_upsert_key.get(upsert_key, user_id ?? null, user_id ?? null);
1068+
const existing_uk = await q.get_mem_by_upsert_key.get(upsert_key);
10691069
if (existing_uk) {
10701070
const now = Date.now();
10711071
await q.upd_mem.run(content, tags ?? null, JSON.stringify(metadata ?? {}), now, existing_uk.id);

packages/openmemory-js/src/server/routes/memory.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ export function mem(app: any) {
101101
});
102102

103103
app.post("/memory/query", async (req: any, res: any) => {
104-
const b = req.body as q_req;
104+
const b = req.body as q_req & { metadata_only?: boolean };
105105
const k = b.k || 8;
106+
const metadata_only = b.metadata_only === true;
106107
try {
107108
const f = {
108109
sectors: b.filters?.sector ? [b.filters.sector] : undefined,
@@ -114,16 +115,21 @@ export function mem(app: any) {
114115
const m = await hsg_query(b.query, k, f);
115116
res.json({
116117
query: b.query,
117-
matches: m.map((x: any) => ({
118-
id: x.id,
119-
content: x.content,
120-
score: x.score,
121-
sectors: x.sectors,
122-
primary_sector: x.primary_sector,
123-
path: x.path,
124-
salience: x.salience,
125-
last_seen_at: x.last_seen_at,
126-
})),
118+
matches: m.map((x: any) => {
119+
const base = {
120+
id: x.id,
121+
score: x.score,
122+
sectors: x.sectors,
123+
primary_sector: x.primary_sector,
124+
path: x.path,
125+
salience: x.salience,
126+
last_seen_at: x.last_seen_at,
127+
};
128+
if (metadata_only) {
129+
return { ...base, content_length: x.content?.length ?? 0 };
130+
}
131+
return { ...base, content: x.content };
132+
}),
127133
});
128134
} catch (e: any) {
129135
res.json({ query: b.query, matches: [] });
@@ -255,6 +261,9 @@ export function mem(app: any) {
255261
decay_lambda: m.decay_lambda,
256262
version: m.version,
257263
user_id: m.user_id,
264+
dedup_count: m.dedup_count ?? 0,
265+
dedup_last_at: m.dedup_last_at ?? null,
266+
upsert_key: m.upsert_key ?? null,
258267
});
259268
} catch (e: any) {
260269
res.status(500).json({ err: "internal" });

0 commit comments

Comments
 (0)