feat(oss): port v3 pipeline with hybrid search, entity extraction, and additive scoring (#4805)

Co-authored-by: Soumil Rathi <soumilrathi@gmail.com>
Co-authored-by: Saket Aryan <saketaryan2002@gmail.com>
Co-authored-by: chaithanyak42 <chaithanya.kumar42a@gmail.com>
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
This commit is contained in:
soumil-rathi
2026-04-14 18:00:58 +05:30
committed by GitHub
co-authored by Soumil Rathi Saket Aryan chaithanyak42 kartik-mem0
parent 57f944e18a
commit a488e19044
120 changed files with 10107 additions and 17135 deletions
+4 -76
View File
@@ -363,78 +363,6 @@ describe("ConfigManager", () => {
});
});
// ─────────────────────────────────────────────────────────────────────────
// Graph store LLM config propagation (issue #3425)
// ─────────────────────────────────────────────────────────────────────────
describe("mergeConfig - graph store LLM config (issue #3425)", () => {
const baseEmbedder = {
provider: "openai",
config: { apiKey: "test-key" },
};
const baseVectorStore = {
provider: "memory",
config: { collectionName: "test" },
};
const graphStoreNeo4j = {
provider: "neo4j",
config: {
url: "neo4j://localhost:7687",
username: "neo4j",
password: "password",
},
};
it("should NOT have a default graphStore.llm — root llm should be the fallback", () => {
const config = ConfigManager.mergeConfig({
embedder: baseEmbedder,
vectorStore: baseVectorStore,
llm: {
provider: "anthropic",
config: { model: "claude-sonnet-4-20250514" },
},
graphStore: graphStoreNeo4j,
});
// graphStore should NOT have its own llm after merge
expect(config.graphStore?.llm).toBeUndefined();
// root llm should be anthropic
expect(config.llm.provider).toBe("anthropic");
expect(config.llm.config.model).toBe("claude-sonnet-4-20250514");
});
it("should preserve explicit graphStore.llm when user provides it", () => {
const config = ConfigManager.mergeConfig({
embedder: baseEmbedder,
vectorStore: baseVectorStore,
llm: {
provider: "anthropic",
config: { model: "claude-sonnet-4-20250514" },
},
graphStore: {
...graphStoreNeo4j,
llm: { provider: "openai", config: { model: "gpt-4o" } },
},
});
// graphStore should have its own llm
expect(config.graphStore?.llm?.provider).toBe("openai");
expect(config.graphStore?.llm?.config).toEqual({ model: "gpt-4o" });
// root llm should still be anthropic
expect(config.llm.provider).toBe("anthropic");
});
it("should not have graphStore.llm when user does not provide one", () => {
const config = ConfigManager.mergeConfig({
embedder: baseEmbedder,
vectorStore: baseVectorStore,
llm: { provider: "openai", config: { model: "gpt-4o" } },
});
// Default graphStore should not have llm
expect(config.graphStore?.llm).toBeUndefined();
});
});
// ─────────────────────────────────────────────────────────────────────────
// Memory class – LM Studio end-to-end flow (mocked factories)
// ─────────────────────────────────────────────────────────────────────────
@@ -520,7 +448,7 @@ describe("Memory – LM Studio end-to-end flow", () => {
disableHistory: true,
});
await mem.getAll({ userId: "u1" });
await mem.getAll({ filters: { user_id: "u1" } });
expect(mockEmbedderFactory.create).toHaveBeenCalledWith(
"lmstudio",
@@ -555,7 +483,7 @@ describe("Memory – LM Studio end-to-end flow", () => {
disableHistory: true,
});
await mem.getAll({ userId: "u1" });
await mem.getAll({ filters: { user_id: "u1" } });
expect(mockEmbedder.embed).toHaveBeenCalledWith("dimension probe");
const vsCall = mockVectorStoreFactory.create.mock.calls[0];
@@ -583,7 +511,7 @@ describe("Memory – LM Studio end-to-end flow", () => {
disableHistory: true,
});
await mem.getAll({ userId: "u1" });
await mem.getAll({ filters: { user_id: "u1" } });
expect(mockEmbedderFactory.create).toHaveBeenCalledWith(
"lmstudio",
@@ -636,7 +564,7 @@ describe("Memory – LM Studio end-to-end flow", () => {
});
const result = await mem.search("What does the user like?", {
userId: "u1",
filters: { user_id: "u1" },
});
expect(mockEmbedder.embed).toHaveBeenCalledWith("What does the user like?");