40e4a527fe
Introduce RRF-based recall fusion for personal/episodic/temporal paths, zvec-grep workspace shadow probing for code executors, and a local headroom proxy starter aligned with the fusion plan defaults. Co-authored-by: Cursor <cursoragent@cursor.com>
75 lines
2.7 KiB
JavaScript
75 lines
2.7 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
applyRecallFusionToMemoryMerge,
|
|
fuseRecallCandidates,
|
|
normalizeRecallCandidate,
|
|
reciprocalRankFusion,
|
|
resolveRecallFusionMode,
|
|
} from './recall-fusion.mjs';
|
|
|
|
test('resolveRecallFusionMode defaults to off', () => {
|
|
assert.equal(resolveRecallFusionMode({}), 'off');
|
|
assert.equal(resolveRecallFusionMode({ MEMIND_RECALL_FUSION_MODE: 'shadow' }), 'shadow');
|
|
});
|
|
|
|
test('reciprocalRankFusion boosts items appearing in multiple lists', () => {
|
|
const shared = normalizeRecallCandidate(
|
|
{ id: 'm1', text: '用户偏好简洁回答' },
|
|
{ source: 'personal', rank: 0, query: '偏好' },
|
|
);
|
|
const episodicOnly = normalizeRecallCandidate(
|
|
{ id: 'm2', text: '上次讨论了苏州旅行' },
|
|
{ source: 'episodic', rank: 0, query: '苏州' },
|
|
);
|
|
const fused = reciprocalRankFusion([
|
|
{ source: 'personal', candidates: [shared] },
|
|
{ source: 'episodic', candidates: [shared, episodicOnly] },
|
|
], { k: 60 });
|
|
assert.equal(fused[0].id, 'm1');
|
|
assert.ok(fused[0].sources.includes('personal'));
|
|
assert.ok(fused[0].sources.includes('episodic'));
|
|
});
|
|
|
|
test('fuseRecallCandidates dedupes duplicate fingerprints across sources', () => {
|
|
const duplicate = '用户喜欢咖啡';
|
|
const fusion = fuseRecallCandidates({
|
|
query: '咖啡偏好',
|
|
personalMemories: [{ id: 'p1', text: duplicate }],
|
|
episodicMemories: [{ id: 'e1', text: duplicate }],
|
|
limit: 3,
|
|
env: { MEMIND_RECALL_FUSION_MODE: 'active' },
|
|
});
|
|
assert.equal(fusion.keptCount, 1);
|
|
assert.equal(fusion.duplicateCount, 1);
|
|
});
|
|
|
|
test('applyRecallFusionToMemoryMerge keeps legacy merge in shadow mode', () => {
|
|
const applied = applyRecallFusionToMemoryMerge({
|
|
personalMemories: [{ id: 'p1', text: 'alpha' }],
|
|
episodicMemories: [{ id: 'e1', text: 'beta' }],
|
|
query: 'alpha',
|
|
limit: 1,
|
|
legacyMerge: () => [{ id: 'legacy', text: 'legacy-only' }],
|
|
env: { MEMIND_RECALL_FUSION_MODE: 'shadow' },
|
|
});
|
|
assert.equal(applied.applied, false);
|
|
assert.equal(applied.memories[0].id, 'legacy');
|
|
assert.ok(applied.fusion);
|
|
});
|
|
|
|
test('applyRecallFusionToMemoryMerge uses fused ranking in active mode', () => {
|
|
const duplicate = '共享记忆';
|
|
const applied = applyRecallFusionToMemoryMerge({
|
|
personalMemories: [{ id: 'p1', text: duplicate }],
|
|
episodicMemories: [{ id: 'e1', text: duplicate }, { id: 'e2', text: 'unique episodic' }],
|
|
query: '共享',
|
|
limit: 2,
|
|
legacyMerge: () => [{ id: 'legacy', text: 'legacy-only' }],
|
|
env: { MEMIND_RECALL_FUSION_MODE: 'active' },
|
|
});
|
|
assert.equal(applied.applied, true);
|
|
assert.equal(applied.memories.length, 2);
|
|
assert.notEqual(applied.memories[0].id, 'legacy');
|
|
});
|