From 6384c5b44cb56ce2705f015ddd6bf43db2513c80 Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Sun, 3 May 2026 00:25:07 +0200 Subject: [PATCH] =?UTF-8?q?test(sf):=20integration=20test=20=E2=80=94=20gr?= =?UTF-8?q?aph-boost=20lifts=20neighbor=20through=20full=20pipeline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pure-function tests for applyRelationBoost (55b14c3f7) cover the math, but the wired-through path (createMemoryRelation → boost picked up by getRelevantMemoriesRanked → reordered output) had no end-to-end test. New test: 1. Creates memories a, b, c with orthogonal embeddings 2. Mocks gateway to return a query vector aligned only with a 3. Wires a→b with related_to (confidence 1.0) 4. Asserts ranking: a (cosine top) > b (boost from a) > c (unrelated) Locks the contract that the boost actually fires through the full pipeline, not just the pure helper. 16 → 17 tests in the file. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../sf/tests/memory-query-ranking.test.ts | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/resources/extensions/sf/tests/memory-query-ranking.test.ts b/src/resources/extensions/sf/tests/memory-query-ranking.test.ts index 48692fc03..cb7be2a25 100644 --- a/src/resources/extensions/sf/tests/memory-query-ranking.test.ts +++ b/src/resources/extensions/sf/tests/memory-query-ranking.test.ts @@ -274,6 +274,57 @@ describe("getRelevantMemoriesRanked (async, mocked gateway)", () => { assert.equal(out.length, 1); }); + test("relation boost promotes a connected memory through the full pipeline", async () => { + process.env.SF_LLM_GATEWAY_KEY = "x"; + process.env.SF_LLM_GATEWAY_URL = "https://gateway.test/v1"; + const a = createMemory({ + category: "architecture", + content: "primary topic content", + }); + const b = createMemory({ + category: "convention", + content: "secondary topic that's related", + }); + const c = createMemory({ + category: "gotcha", + content: "completely unrelated", + }); + assert.ok(a && b && c); + + // a is the cosine match; b and c are unrelated to query semantically. + saveEmbedding(a, Float32Array.from([1, 0, 0]), "test-model"); + saveEmbedding(b, Float32Array.from([0, 1, 0]), "test-model"); + saveEmbedding(c, Float32Array.from([0, 0, 1]), "test-model"); + + // Wire b as a related-to neighbor of a; c stays disconnected. + const { createMemoryRelation } = await import("../memory-relations.ts"); + createMemoryRelation(a, b, "related_to", 1.0); + + // Mock gateway → query vector aligned with a only. + vi.stubGlobal( + "fetch", + vi.fn(async () => + new Response( + JSON.stringify({ + object: "list", + data: [ + { object: "embedding", index: 0, embedding: [1, 0, 0] }, + ], + }), + { status: 200 }, + ), + ), + ); + + const out = await getRelevantMemoriesRanked("topic query", 10); + assert.equal(out.length, 3); + // a is the cosine top hit (perfect alignment). + assert.equal(out[0].id, a); + // b is connected to a via related_to → graph-boost lifts it above c. + assert.equal(out[1].id, b, "graph-boosted neighbor should rank above unrelated"); + assert.equal(out[2].id, c); + }); + test("static ranking still works with no embeddings table populated", async () => { const fallbackOrder = getActiveMemoriesRanked(10).length; assert.equal(fallbackOrder, 0); // pre-condition: empty