feat: implement local indexer for project-knowledge and add memory hybrid search functionality

This commit is contained in:
2026-05-21 09:13:07 -06:00
parent fc2abda588
commit e0069fd8c6
8 changed files with 575 additions and 0 deletions

View File

@@ -32,6 +32,7 @@ class ContextMCPTests(unittest.TestCase):
names = {tool["name"] for tool in response["result"]["tools"]}
self.assertIn("project_search_memory", names)
self.assertIn("memory_hybrid_search", names)
self.assertIn("communication_latest", names)
def test_initialize_response_declares_resources(self) -> None:
@@ -158,6 +159,43 @@ class ContextMCPTests(unittest.TestCase):
self.assertEqual(len(result["matches"]), 1)
self.assertIn("03-context/project.md", result["matches"][0]["path"])
def test_memory_hybrid_search_uses_index_when_available(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
index = root / ".aiw" / "indexes" / "fidelity" / "project-knowledge.jsonl"
manifest = root / ".aiw" / "indexes" / "fidelity" / "manifest.json"
index.parent.mkdir(parents=True)
index.write_text(json.dumps({
"chunk_id": "abc",
"path": "project-knowledge/03-context/project.md",
"heading": "XFlow",
"text": "Dismissal lifecycle sequencing for XFlow",
"mtime": 1.0,
"sha256": "hash",
}) + "\n", encoding="utf-8")
manifest.write_text(json.dumps({"chunk_count": 1}), encoding="utf-8")
with patch.object(server, "ROOT", root), patch.object(server, "INDEX_ROOT", root / ".aiw" / "indexes"):
result = server.memory_hybrid_search({"profile": "fidelity", "query": "dismissal lifecycle"})["structuredContent"]
self.assertTrue(result["index_available"])
self.assertEqual(result["source"], "derived-project-knowledge-index")
self.assertEqual(result["matches"][0]["chunk_id"], "abc")
def test_memory_hybrid_search_falls_back_without_index(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
real = root / "project-knowledge" / "03-context" / "project.md"
real.parent.mkdir(parents=True)
real.write_text("Important XFlow context", encoding="utf-8")
with patch.object(server, "ROOT", root), patch.object(server, "INDEX_ROOT", root / ".aiw" / "indexes"):
result = server.memory_hybrid_search({"profile": "fidelity", "query": "XFlow"})["structuredContent"]
self.assertFalse(result["index_available"])
self.assertEqual(result["source"], "live-project-knowledge-fallback")
self.assertEqual(len(result["matches"]), 1)
def test_previous_workday_skips_weekend(self) -> None:
monday = date(2026, 5, 18)