Merge pull request #1834 from AndyMik90/fix/memory-falkordb-to-ladybug
fix(memory): complete FalkorDB to LadybugDB migration in memory system
This commit is contained in:
@@ -635,10 +635,20 @@ def get_graphiti_status() -> dict:
|
||||
try:
|
||||
# Attempt to import the main graphiti_memory module
|
||||
import graphiti_core # noqa: F401
|
||||
from graphiti_core.driver.falkordb_driver import FalkorDriver # noqa: F401
|
||||
|
||||
# If we got here, packages are importable
|
||||
status["available"] = True # pragma: no cover
|
||||
# Try LadybugDB first (preferred for Python 3.12+), fall back to kuzu
|
||||
try:
|
||||
import real_ladybug # noqa: F401
|
||||
except ImportError:
|
||||
try:
|
||||
import kuzu # noqa: F401
|
||||
except ImportError:
|
||||
status["available"] = False
|
||||
status["reason"] = (
|
||||
"Graph database backend not installed (need real_ladybug or kuzu)"
|
||||
)
|
||||
return status
|
||||
status["available"] = True
|
||||
except ImportError as e:
|
||||
status["available"] = False
|
||||
status["reason"] = f"Graphiti packages not installed: {e}"
|
||||
|
||||
@@ -81,16 +81,16 @@ def mock_graphiti_core():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_falkor_driver():
|
||||
"""Mock graphiti_core.driver.falkordb_driver.FalkorDriver.
|
||||
def mock_kuzu_driver():
|
||||
"""Mock graphiti_core.driver.kuzu_driver.KuzuDriver.
|
||||
|
||||
Prevents actual FalkorDB connections during tests.
|
||||
Prevents actual LadybugDB/kuzu connections during tests.
|
||||
|
||||
Yields:
|
||||
tuple: (mock_driver_class, mock_driver_instance)
|
||||
"""
|
||||
with patch(
|
||||
"integrations.graphiti.queries_pkg.graphiti.graphiti_core.driver.falkordb_driver.FalkorDriver"
|
||||
"integrations.graphiti.queries_pkg.graphiti.graphiti_core.driver.kuzu_driver.KuzuDriver"
|
||||
) as mock_driver:
|
||||
mock_instance = MagicMock()
|
||||
mock_driver.return_value = mock_instance
|
||||
|
||||
@@ -15,7 +15,7 @@ Tests cover:
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from integrations.graphiti.config import (
|
||||
@@ -1054,20 +1054,48 @@ class TestModuleLevelFunctions:
|
||||
assert "OPENAI_API_KEY" in status["errors"][0]
|
||||
|
||||
def test_get_graphiti_status_invalid_config_sets_reason(self, clean_env):
|
||||
"""Test get_graphiti_status sets reason when config is invalid.
|
||||
"""Test get_graphiti_status with validation errors (embedder misconfigured).
|
||||
|
||||
This tests lines 628-629 where the reason is set from validation errors.
|
||||
When packages are installed but embedder config has errors, available should
|
||||
still be True (embedder is optional - keyword search fallback exists).
|
||||
Validation errors are reported in the errors list for informational purposes.
|
||||
"""
|
||||
os.environ["GRAPHITI_ENABLED"] = "true"
|
||||
os.environ["GRAPHITI_EMBEDDER_PROVIDER"] = "voyage"
|
||||
|
||||
status = get_graphiti_status()
|
||||
# Mock imports to ensure test is independent of environment
|
||||
with patch.dict(
|
||||
"sys.modules",
|
||||
{"graphiti_core": MagicMock(), "real_ladybug": MagicMock()},
|
||||
):
|
||||
status = get_graphiti_status()
|
||||
|
||||
assert status["enabled"] is True
|
||||
# available depends on whether mocked packages are resolved correctly;
|
||||
# sys.modules patching should make imports succeed, but guard against
|
||||
# environment quirks (consistent with test_get_graphiti_status_enabled)
|
||||
assert status["available"] is True
|
||||
assert len(status["errors"]) > 0
|
||||
assert "VOYAGE_API_KEY" in status["errors"][0]
|
||||
|
||||
def test_get_graphiti_status_no_graph_backend(self, clean_env):
|
||||
"""Test get_graphiti_status when graphiti_core exists but no graph DB backend.
|
||||
|
||||
This tests the error path in config.py lines 645-650 where graphiti_core
|
||||
imports successfully but neither real_ladybug nor kuzu is available.
|
||||
"""
|
||||
os.environ["GRAPHITI_ENABLED"] = "true"
|
||||
|
||||
# Mock graphiti_core as present, but ensure real_ladybug and kuzu are absent
|
||||
with patch.dict(
|
||||
"sys.modules",
|
||||
{"graphiti_core": MagicMock(), "real_ladybug": None, "kuzu": None},
|
||||
):
|
||||
status = get_graphiti_status()
|
||||
|
||||
assert status["enabled"] is True
|
||||
assert status["available"] is False
|
||||
# When config is invalid, reason should be set from errors
|
||||
assert status["reason"] != ""
|
||||
assert len(status["errors"]) > 0
|
||||
assert "real_ladybug or kuzu" in status["reason"]
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_get_graphiti_status_with_graphiti_installed(self, clean_env):
|
||||
@@ -1089,9 +1117,9 @@ class TestModuleLevelFunctions:
|
||||
assert "reason" in status
|
||||
assert "errors" in status
|
||||
|
||||
# Note: Line 641 (status["available"] = True) requires falkordb to be installed.
|
||||
# Since falkordb is not installed in the test environment, that line is marked
|
||||
# with pragma: no cover. The except clause (lines 642-644) is tested here.
|
||||
# Note: Line 644 (status["available"] = True) requires LadybugDB/kuzu to be installed.
|
||||
# Since LadybugDB/kuzu may not be installed in all test environments, that line
|
||||
# may be marked with pragma: no cover. The except clause is tested here.
|
||||
|
||||
def test_get_available_providers_empty(self, clean_env):
|
||||
"""Test get_available_providers with no credentials."""
|
||||
|
||||
@@ -264,7 +264,7 @@ class TestTestGraphitiConnection:
|
||||
|
||||
# Mock graphiti_core imports to succeed
|
||||
mock_graphiti = MagicMock()
|
||||
mock_falkordb_driver = MagicMock()
|
||||
mock_kuzu_driver = MagicMock()
|
||||
|
||||
# Mock provider creation to raise ProviderError
|
||||
with patch("graphiti_providers.create_llm_client") as mock_create_llm:
|
||||
@@ -275,7 +275,7 @@ class TestTestGraphitiConnection:
|
||||
{
|
||||
"graphiti_core": MagicMock(Graphiti=mock_graphiti),
|
||||
"graphiti_core.driver": MagicMock(),
|
||||
"graphiti_core.driver.falkordb_driver": mock_falkordb_driver,
|
||||
"graphiti_core.driver.kuzu_driver": mock_kuzu_driver,
|
||||
"graphiti_providers": MagicMock(
|
||||
ProviderError=ProviderError,
|
||||
create_embedder=MagicMock(),
|
||||
|
||||
@@ -160,7 +160,7 @@ class TestTestGraphitiConnection:
|
||||
"""Tests for the test_graphiti_connection async function.
|
||||
|
||||
Note: The function now uses embedded LadybugDB via patched KuzuDriver
|
||||
instead of remote FalkorDB with host/port credentials.
|
||||
instead of remote database with host/port credentials.
|
||||
"""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
"project_root": "/Users/andremikalsen/Documents/Coding/autonomous-coding",
|
||||
"project_type": "single",
|
||||
"services": {},
|
||||
"infrastructure": {
|
||||
"docker_compose": "docker-compose.yml",
|
||||
"docker_services": [
|
||||
"falkordb"
|
||||
]
|
||||
},
|
||||
"infrastructure": {},
|
||||
"conventions": {}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ Examples:
|
||||
python spec_runner.py --task "Update text" --complexity simple
|
||||
|
||||
# Complex integration (auto-detected)
|
||||
python spec_runner.py --task "Add Graphiti memory integration with FalkorDB"
|
||||
python spec_runner.py --task "Add Graphiti memory integration with LadybugDB"
|
||||
|
||||
# Interactive mode
|
||||
python spec_runner.py --interactive
|
||||
|
||||
Reference in New Issue
Block a user