diff --git a/mem0-ts/src/oss/src/vector_stores/baidu.ts b/mem0-ts/src/oss/src/vector_stores/baidu.ts index 645910daa..34e54c5fe 100644 --- a/mem0-ts/src/oss/src/vector_stores/baidu.ts +++ b/mem0-ts/src/oss/src/vector_stores/baidu.ts @@ -453,7 +453,13 @@ export class BaiduDB implements VectorStore { return (response.rows ?? []).map((result) => ({ id: String(result.row.id), payload: resultPayload(result.row), - score: result.score, + // L2 is a distance (lower = closer); the VectorStore contract wants higher = better. + score: + this.metricType === "L2" + ? result.score != null + ? 1 / (1 + result.score) + : undefined + : result.score, })); } diff --git a/mem0-ts/src/oss/tests/baidu.test.ts b/mem0-ts/src/oss/tests/baidu.test.ts index 912758ef9..a2a50013d 100644 --- a/mem0-ts/src/oss/tests/baidu.test.ts +++ b/mem0-ts/src/oss/tests/baidu.test.ts @@ -431,9 +431,12 @@ describe("BaiduDB reads", () => { ], }); - const results = await makeStore(client).search([1, 2, 3], 5, { - userId: "alice", - }); + // Non-L2 metrics already return a higher-is-better score and pass through untouched. + const results = await makeStore(client, { metricType: "COSINE" }).search( + [1, 2, 3], + 5, + { userId: "alice" }, + ); expect(results).toEqual([{ id: "m1", payload: { data: "x" }, score: 0.8 }]); const { request } = client.vectorSearch.mock.calls[0][0]; @@ -445,6 +448,35 @@ describe("BaiduDB reads", () => { expect(request.config.params).toEqual({ ef: 200 }); }); + it("converts an L2 distance into a similarity score (higher = better)", async () => { + // Mirrors the Python provider (#6435): 1 / (1 + distance), so closer scores higher. + const client = fakeClient(); + client.vectorSearch.mockResolvedValue({ + ...OK, + rows: [ + { row: { id: "near", metadata: {} }, score: 0.5 }, + { row: { id: "far", metadata: {} }, score: 2.0 }, + ], + }); + + const results = await makeStore(client).search([1, 2, 3], 2); + + expect(results[0].score).toBeCloseTo(1 / 1.5, 10); + expect(results[1].score).toBeCloseTo(1 / 3.0, 10); + }); + + it("leaves an unscored L2 row's score undefined instead of treating it as the closest match", async () => { + const client = fakeClient(); + client.vectorSearch.mockResolvedValue({ + ...OK, + rows: [{ row: { id: "unscored", metadata: {} } }], + }); + + const results = await makeStore(client).search([1, 2, 3], 1); + + expect(results[0].score).toBeUndefined(); + }); + it("omits the filter when no filters are supplied", async () => { const client = fakeClient(); client.vectorSearch.mockResolvedValue({ ...OK, rows: [] });