cognee 0.3.6__py3-none-any.whl → 0.3.7.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cognee/__init__.py +1 -0
- cognee/api/health.py +2 -12
- cognee/api/v1/add/add.py +46 -6
- cognee/api/v1/add/routers/get_add_router.py +11 -2
- cognee/api/v1/cognify/cognify.py +29 -9
- cognee/api/v1/cognify/routers/get_cognify_router.py +2 -1
- cognee/api/v1/datasets/datasets.py +11 -0
- cognee/api/v1/datasets/routers/get_datasets_router.py +8 -0
- cognee/api/v1/delete/routers/get_delete_router.py +2 -0
- cognee/api/v1/memify/routers/get_memify_router.py +2 -1
- cognee/api/v1/permissions/routers/get_permissions_router.py +6 -0
- cognee/api/v1/responses/default_tools.py +0 -1
- cognee/api/v1/responses/dispatch_function.py +1 -1
- cognee/api/v1/responses/routers/default_tools.py +0 -1
- cognee/api/v1/search/routers/get_search_router.py +3 -3
- cognee/api/v1/search/search.py +11 -9
- cognee/api/v1/settings/routers/get_settings_router.py +7 -1
- cognee/api/v1/sync/routers/get_sync_router.py +3 -0
- cognee/api/v1/ui/ui.py +45 -16
- cognee/api/v1/update/routers/get_update_router.py +3 -1
- cognee/api/v1/update/update.py +3 -3
- cognee/api/v1/users/routers/get_visualize_router.py +2 -0
- cognee/cli/_cognee.py +61 -10
- cognee/cli/commands/add_command.py +3 -3
- cognee/cli/commands/cognify_command.py +3 -3
- cognee/cli/commands/config_command.py +9 -7
- cognee/cli/commands/delete_command.py +3 -3
- cognee/cli/commands/search_command.py +3 -7
- cognee/cli/config.py +0 -1
- cognee/context_global_variables.py +5 -0
- cognee/exceptions/exceptions.py +1 -1
- cognee/infrastructure/databases/cache/__init__.py +2 -0
- cognee/infrastructure/databases/cache/cache_db_interface.py +79 -0
- cognee/infrastructure/databases/cache/config.py +44 -0
- cognee/infrastructure/databases/cache/get_cache_engine.py +67 -0
- cognee/infrastructure/databases/cache/redis/RedisAdapter.py +243 -0
- cognee/infrastructure/databases/exceptions/__init__.py +1 -0
- cognee/infrastructure/databases/exceptions/exceptions.py +18 -2
- cognee/infrastructure/databases/graph/get_graph_engine.py +1 -1
- cognee/infrastructure/databases/graph/graph_db_interface.py +5 -0
- cognee/infrastructure/databases/graph/kuzu/adapter.py +76 -47
- cognee/infrastructure/databases/graph/neo4j_driver/adapter.py +13 -3
- cognee/infrastructure/databases/graph/neo4j_driver/deadlock_retry.py +1 -1
- cognee/infrastructure/databases/graph/neptune_driver/neptune_utils.py +1 -1
- cognee/infrastructure/databases/relational/sqlalchemy/SqlAlchemyAdapter.py +1 -1
- cognee/infrastructure/databases/vector/embeddings/FastembedEmbeddingEngine.py +21 -3
- cognee/infrastructure/databases/vector/embeddings/LiteLLMEmbeddingEngine.py +17 -10
- cognee/infrastructure/databases/vector/embeddings/OllamaEmbeddingEngine.py +17 -4
- cognee/infrastructure/databases/vector/embeddings/config.py +2 -3
- cognee/infrastructure/databases/vector/exceptions/exceptions.py +1 -1
- cognee/infrastructure/databases/vector/lancedb/LanceDBAdapter.py +0 -1
- cognee/infrastructure/files/exceptions.py +1 -1
- cognee/infrastructure/files/storage/LocalFileStorage.py +9 -9
- cognee/infrastructure/files/storage/S3FileStorage.py +11 -11
- cognee/infrastructure/files/utils/guess_file_type.py +6 -0
- cognee/infrastructure/llm/prompts/feedback_reaction_prompt.txt +14 -0
- cognee/infrastructure/llm/prompts/feedback_report_prompt.txt +13 -0
- cognee/infrastructure/llm/prompts/feedback_user_context_prompt.txt +5 -0
- cognee/infrastructure/llm/prompts/search_type_selector_prompt.txt +0 -5
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/anthropic/adapter.py +19 -9
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/gemini/adapter.py +17 -5
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/generic_llm_api/adapter.py +17 -5
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/get_llm_client.py +32 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/mistral/__init__.py +0 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/mistral/adapter.py +109 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/ollama/adapter.py +33 -8
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/openai/adapter.py +40 -18
- cognee/infrastructure/loaders/LoaderEngine.py +27 -7
- cognee/infrastructure/loaders/external/__init__.py +7 -0
- cognee/infrastructure/loaders/external/advanced_pdf_loader.py +2 -8
- cognee/infrastructure/loaders/external/beautiful_soup_loader.py +310 -0
- cognee/infrastructure/loaders/supported_loaders.py +7 -0
- cognee/modules/data/exceptions/exceptions.py +1 -1
- cognee/modules/data/methods/__init__.py +3 -0
- cognee/modules/data/methods/get_dataset_data.py +4 -1
- cognee/modules/data/methods/has_dataset_data.py +21 -0
- cognee/modules/engine/models/TableRow.py +0 -1
- cognee/modules/ingestion/save_data_to_file.py +9 -2
- cognee/modules/pipelines/exceptions/exceptions.py +1 -1
- cognee/modules/pipelines/operations/pipeline.py +12 -1
- cognee/modules/pipelines/operations/run_tasks.py +25 -197
- cognee/modules/pipelines/operations/run_tasks_base.py +7 -0
- cognee/modules/pipelines/operations/run_tasks_data_item.py +260 -0
- cognee/modules/pipelines/operations/run_tasks_distributed.py +121 -38
- cognee/modules/pipelines/operations/run_tasks_with_telemetry.py +9 -1
- cognee/modules/retrieval/EntityCompletionRetriever.py +48 -8
- cognee/modules/retrieval/base_graph_retriever.py +3 -1
- cognee/modules/retrieval/base_retriever.py +3 -1
- cognee/modules/retrieval/chunks_retriever.py +5 -1
- cognee/modules/retrieval/code_retriever.py +20 -2
- cognee/modules/retrieval/completion_retriever.py +50 -9
- cognee/modules/retrieval/cypher_search_retriever.py +11 -1
- cognee/modules/retrieval/graph_completion_context_extension_retriever.py +47 -8
- cognee/modules/retrieval/graph_completion_cot_retriever.py +152 -22
- cognee/modules/retrieval/graph_completion_retriever.py +54 -10
- cognee/modules/retrieval/lexical_retriever.py +20 -2
- cognee/modules/retrieval/natural_language_retriever.py +10 -1
- cognee/modules/retrieval/summaries_retriever.py +5 -1
- cognee/modules/retrieval/temporal_retriever.py +62 -10
- cognee/modules/retrieval/user_qa_feedback.py +3 -2
- cognee/modules/retrieval/utils/completion.py +30 -4
- cognee/modules/retrieval/utils/description_to_codepart_search.py +1 -1
- cognee/modules/retrieval/utils/session_cache.py +156 -0
- cognee/modules/search/methods/get_search_type_tools.py +0 -5
- cognee/modules/search/methods/no_access_control_search.py +12 -1
- cognee/modules/search/methods/search.py +51 -5
- cognee/modules/search/types/SearchType.py +0 -1
- cognee/modules/settings/get_settings.py +23 -0
- cognee/modules/users/methods/get_authenticated_user.py +3 -1
- cognee/modules/users/methods/get_default_user.py +1 -6
- cognee/modules/users/roles/methods/create_role.py +2 -2
- cognee/modules/users/tenants/methods/create_tenant.py +2 -2
- cognee/shared/exceptions/exceptions.py +1 -1
- cognee/shared/logging_utils.py +18 -11
- cognee/shared/utils.py +24 -2
- cognee/tasks/codingagents/coding_rule_associations.py +1 -2
- cognee/tasks/documents/exceptions/exceptions.py +1 -1
- cognee/tasks/feedback/__init__.py +13 -0
- cognee/tasks/feedback/create_enrichments.py +84 -0
- cognee/tasks/feedback/extract_feedback_interactions.py +230 -0
- cognee/tasks/feedback/generate_improved_answers.py +130 -0
- cognee/tasks/feedback/link_enrichments_to_feedback.py +67 -0
- cognee/tasks/feedback/models.py +26 -0
- cognee/tasks/graph/extract_graph_from_data.py +2 -0
- cognee/tasks/ingestion/data_item_to_text_file.py +3 -3
- cognee/tasks/ingestion/ingest_data.py +11 -5
- cognee/tasks/ingestion/save_data_item_to_storage.py +12 -1
- cognee/tasks/storage/add_data_points.py +3 -10
- cognee/tasks/storage/index_data_points.py +19 -14
- cognee/tasks/storage/index_graph_edges.py +25 -11
- cognee/tasks/web_scraper/__init__.py +34 -0
- cognee/tasks/web_scraper/config.py +26 -0
- cognee/tasks/web_scraper/default_url_crawler.py +446 -0
- cognee/tasks/web_scraper/models.py +46 -0
- cognee/tasks/web_scraper/types.py +4 -0
- cognee/tasks/web_scraper/utils.py +142 -0
- cognee/tasks/web_scraper/web_scraper_task.py +396 -0
- cognee/tests/cli_tests/cli_unit_tests/test_cli_utils.py +0 -1
- cognee/tests/integration/web_url_crawler/test_default_url_crawler.py +13 -0
- cognee/tests/integration/web_url_crawler/test_tavily_crawler.py +19 -0
- cognee/tests/integration/web_url_crawler/test_url_adding_e2e.py +344 -0
- cognee/tests/subprocesses/reader.py +25 -0
- cognee/tests/subprocesses/simple_cognify_1.py +31 -0
- cognee/tests/subprocesses/simple_cognify_2.py +31 -0
- cognee/tests/subprocesses/writer.py +32 -0
- cognee/tests/tasks/descriptive_metrics/metrics_test_utils.py +0 -2
- cognee/tests/tasks/descriptive_metrics/neo4j_metrics_test.py +8 -3
- cognee/tests/tasks/entity_extraction/entity_extraction_test.py +89 -0
- cognee/tests/tasks/web_scraping/web_scraping_test.py +172 -0
- cognee/tests/test_add_docling_document.py +56 -0
- cognee/tests/test_chromadb.py +7 -11
- cognee/tests/test_concurrent_subprocess_access.py +76 -0
- cognee/tests/test_conversation_history.py +240 -0
- cognee/tests/test_feedback_enrichment.py +174 -0
- cognee/tests/test_kuzu.py +27 -15
- cognee/tests/test_lancedb.py +7 -11
- cognee/tests/test_library.py +32 -2
- cognee/tests/test_neo4j.py +24 -16
- cognee/tests/test_neptune_analytics_vector.py +7 -11
- cognee/tests/test_permissions.py +9 -13
- cognee/tests/test_pgvector.py +4 -4
- cognee/tests/test_remote_kuzu.py +8 -11
- cognee/tests/test_s3_file_storage.py +1 -1
- cognee/tests/test_search_db.py +6 -8
- cognee/tests/unit/infrastructure/databases/cache/test_cache_config.py +89 -0
- cognee/tests/unit/modules/retrieval/conversation_history_test.py +154 -0
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_cot_test.py +51 -0
- {cognee-0.3.6.dist-info → cognee-0.3.7.dev1.dist-info}/METADATA +21 -6
- {cognee-0.3.6.dist-info → cognee-0.3.7.dev1.dist-info}/RECORD +178 -139
- {cognee-0.3.6.dist-info → cognee-0.3.7.dev1.dist-info}/entry_points.txt +1 -0
- distributed/Dockerfile +0 -3
- distributed/entrypoint.py +21 -9
- distributed/signal.py +5 -0
- distributed/workers/data_point_saving_worker.py +64 -34
- distributed/workers/graph_saving_worker.py +71 -47
- cognee/infrastructure/databases/graph/memgraph/memgraph_adapter.py +0 -1116
- cognee/modules/retrieval/insights_retriever.py +0 -133
- cognee/tests/test_memgraph.py +0 -109
- cognee/tests/unit/modules/retrieval/insights_retriever_test.py +0 -251
- {cognee-0.3.6.dist-info → cognee-0.3.7.dev1.dist-info}/WHEEL +0 -0
- {cognee-0.3.6.dist-info → cognee-0.3.7.dev1.dist-info}/licenses/LICENSE +0 -0
- {cognee-0.3.6.dist-info → cognee-0.3.7.dev1.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Tests for cache configuration."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from cognee.infrastructure.databases.cache.config import CacheConfig, get_cache_config
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_cache_config_defaults():
|
|
8
|
+
"""Test that CacheConfig has the correct default values."""
|
|
9
|
+
config = CacheConfig()
|
|
10
|
+
|
|
11
|
+
assert config.caching is False
|
|
12
|
+
assert config.shared_kuzu_lock is False
|
|
13
|
+
assert config.cache_host == "localhost"
|
|
14
|
+
assert config.cache_port == 6379
|
|
15
|
+
assert config.agentic_lock_expire == 240
|
|
16
|
+
assert config.agentic_lock_timeout == 300
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_cache_config_custom_values():
|
|
20
|
+
"""Test that CacheConfig accepts custom values."""
|
|
21
|
+
config = CacheConfig(
|
|
22
|
+
caching=True,
|
|
23
|
+
shared_kuzu_lock=True,
|
|
24
|
+
cache_host="redis.example.com",
|
|
25
|
+
cache_port=6380,
|
|
26
|
+
agentic_lock_expire=120,
|
|
27
|
+
agentic_lock_timeout=180,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
assert config.caching is True
|
|
31
|
+
assert config.shared_kuzu_lock is True
|
|
32
|
+
assert config.cache_host == "redis.example.com"
|
|
33
|
+
assert config.cache_port == 6380
|
|
34
|
+
assert config.agentic_lock_expire == 120
|
|
35
|
+
assert config.agentic_lock_timeout == 180
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_cache_config_to_dict():
|
|
39
|
+
"""Test the to_dict method returns all configuration values."""
|
|
40
|
+
config = CacheConfig(
|
|
41
|
+
caching=True,
|
|
42
|
+
shared_kuzu_lock=True,
|
|
43
|
+
cache_host="test-host",
|
|
44
|
+
cache_port=7000,
|
|
45
|
+
agentic_lock_expire=100,
|
|
46
|
+
agentic_lock_timeout=200,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
config_dict = config.to_dict()
|
|
50
|
+
|
|
51
|
+
assert config_dict == {
|
|
52
|
+
"caching": True,
|
|
53
|
+
"shared_kuzu_lock": True,
|
|
54
|
+
"cache_host": "test-host",
|
|
55
|
+
"cache_port": 7000,
|
|
56
|
+
"cache_username": None,
|
|
57
|
+
"cache_password": None,
|
|
58
|
+
"agentic_lock_expire": 100,
|
|
59
|
+
"agentic_lock_timeout": 200,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_get_cache_config_singleton():
|
|
64
|
+
"""Test that get_cache_config returns the same instance."""
|
|
65
|
+
config1 = get_cache_config()
|
|
66
|
+
config2 = get_cache_config()
|
|
67
|
+
|
|
68
|
+
assert config1 is config2
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_cache_config_extra_fields_allowed():
|
|
72
|
+
"""Test that CacheConfig allows extra fields due to extra='allow'."""
|
|
73
|
+
config = CacheConfig(extra_field="extra_value", another_field=123)
|
|
74
|
+
|
|
75
|
+
assert hasattr(config, "extra_field")
|
|
76
|
+
assert config.extra_field == "extra_value"
|
|
77
|
+
assert hasattr(config, "another_field")
|
|
78
|
+
assert config.another_field == 123
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_cache_config_boolean_type_validation():
|
|
82
|
+
"""Test that boolean fields accept various truthy/falsy values."""
|
|
83
|
+
config1 = CacheConfig(caching="true", shared_kuzu_lock="yes")
|
|
84
|
+
assert config1.caching is True
|
|
85
|
+
assert config1.shared_kuzu_lock is True
|
|
86
|
+
|
|
87
|
+
config2 = CacheConfig(caching="false", shared_kuzu_lock="no")
|
|
88
|
+
assert config2.caching is False
|
|
89
|
+
assert config2.shared_kuzu_lock is False
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from unittest.mock import AsyncMock, patch, MagicMock
|
|
3
|
+
from cognee.context_global_variables import session_user
|
|
4
|
+
import importlib
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def create_mock_cache_engine(qa_history=None):
|
|
8
|
+
mock_cache = AsyncMock()
|
|
9
|
+
if qa_history is None:
|
|
10
|
+
qa_history = []
|
|
11
|
+
mock_cache.get_latest_qa = AsyncMock(return_value=qa_history)
|
|
12
|
+
mock_cache.add_qa = AsyncMock(return_value=None)
|
|
13
|
+
return mock_cache
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def create_mock_user():
|
|
17
|
+
mock_user = MagicMock()
|
|
18
|
+
mock_user.id = "test-user-id-123"
|
|
19
|
+
return mock_user
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TestConversationHistoryUtils:
|
|
23
|
+
@pytest.mark.asyncio
|
|
24
|
+
async def test_get_conversation_history_returns_empty_when_no_history(self):
|
|
25
|
+
user = create_mock_user()
|
|
26
|
+
session_user.set(user)
|
|
27
|
+
mock_cache = create_mock_cache_engine([])
|
|
28
|
+
|
|
29
|
+
cache_module = importlib.import_module(
|
|
30
|
+
"cognee.infrastructure.databases.cache.get_cache_engine"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
with patch.object(cache_module, "get_cache_engine", return_value=mock_cache):
|
|
34
|
+
from cognee.modules.retrieval.utils.session_cache import get_conversation_history
|
|
35
|
+
|
|
36
|
+
result = await get_conversation_history(session_id="test_session")
|
|
37
|
+
|
|
38
|
+
assert result == ""
|
|
39
|
+
|
|
40
|
+
@pytest.mark.asyncio
|
|
41
|
+
async def test_get_conversation_history_formats_history_correctly(self):
|
|
42
|
+
"""Test get_conversation_history formats Q&A history with correct structure."""
|
|
43
|
+
user = create_mock_user()
|
|
44
|
+
session_user.set(user)
|
|
45
|
+
|
|
46
|
+
mock_history = [
|
|
47
|
+
{
|
|
48
|
+
"time": "2024-01-15 10:30:45",
|
|
49
|
+
"question": "What is AI?",
|
|
50
|
+
"context": "AI is artificial intelligence",
|
|
51
|
+
"answer": "AI stands for Artificial Intelligence",
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
mock_cache = create_mock_cache_engine(mock_history)
|
|
55
|
+
|
|
56
|
+
# Import the real module to patch safely
|
|
57
|
+
cache_module = importlib.import_module(
|
|
58
|
+
"cognee.infrastructure.databases.cache.get_cache_engine"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
with patch.object(cache_module, "get_cache_engine", return_value=mock_cache):
|
|
62
|
+
with patch(
|
|
63
|
+
"cognee.modules.retrieval.utils.session_cache.CacheConfig"
|
|
64
|
+
) as MockCacheConfig:
|
|
65
|
+
mock_config = MagicMock()
|
|
66
|
+
mock_config.caching = True
|
|
67
|
+
MockCacheConfig.return_value = mock_config
|
|
68
|
+
|
|
69
|
+
from cognee.modules.retrieval.utils.session_cache import (
|
|
70
|
+
get_conversation_history,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
result = await get_conversation_history(session_id="test_session")
|
|
74
|
+
|
|
75
|
+
assert "Previous conversation:" in result
|
|
76
|
+
assert "[2024-01-15 10:30:45]" in result
|
|
77
|
+
assert "QUESTION: What is AI?" in result
|
|
78
|
+
assert "CONTEXT: AI is artificial intelligence" in result
|
|
79
|
+
assert "ANSWER: AI stands for Artificial Intelligence" in result
|
|
80
|
+
|
|
81
|
+
@pytest.mark.asyncio
|
|
82
|
+
async def test_save_to_session_cache_saves_correctly(self):
|
|
83
|
+
"""Test save_conversation_history calls add_qa with correct parameters."""
|
|
84
|
+
user = create_mock_user()
|
|
85
|
+
session_user.set(user)
|
|
86
|
+
|
|
87
|
+
mock_cache = create_mock_cache_engine([])
|
|
88
|
+
|
|
89
|
+
cache_module = importlib.import_module(
|
|
90
|
+
"cognee.infrastructure.databases.cache.get_cache_engine"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
with patch.object(cache_module, "get_cache_engine", return_value=mock_cache):
|
|
94
|
+
with patch(
|
|
95
|
+
"cognee.modules.retrieval.utils.session_cache.CacheConfig"
|
|
96
|
+
) as MockCacheConfig:
|
|
97
|
+
mock_config = MagicMock()
|
|
98
|
+
mock_config.caching = True
|
|
99
|
+
MockCacheConfig.return_value = mock_config
|
|
100
|
+
|
|
101
|
+
from cognee.modules.retrieval.utils.session_cache import (
|
|
102
|
+
save_conversation_history,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
result = await save_conversation_history(
|
|
106
|
+
query="What is Python?",
|
|
107
|
+
context_summary="Python is a programming language",
|
|
108
|
+
answer="Python is a high-level programming language",
|
|
109
|
+
session_id="my_session",
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
assert result is True
|
|
113
|
+
mock_cache.add_qa.assert_called_once()
|
|
114
|
+
|
|
115
|
+
call_kwargs = mock_cache.add_qa.call_args.kwargs
|
|
116
|
+
assert call_kwargs["question"] == "What is Python?"
|
|
117
|
+
assert call_kwargs["context"] == "Python is a programming language"
|
|
118
|
+
assert call_kwargs["answer"] == "Python is a high-level programming language"
|
|
119
|
+
assert call_kwargs["session_id"] == "my_session"
|
|
120
|
+
|
|
121
|
+
@pytest.mark.asyncio
|
|
122
|
+
async def test_save_to_session_cache_uses_default_session_when_none(self):
|
|
123
|
+
"""Test save_conversation_history uses 'default_session' when session_id is None."""
|
|
124
|
+
user = create_mock_user()
|
|
125
|
+
session_user.set(user)
|
|
126
|
+
|
|
127
|
+
mock_cache = create_mock_cache_engine([])
|
|
128
|
+
|
|
129
|
+
cache_module = importlib.import_module(
|
|
130
|
+
"cognee.infrastructure.databases.cache.get_cache_engine"
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
with patch.object(cache_module, "get_cache_engine", return_value=mock_cache):
|
|
134
|
+
with patch(
|
|
135
|
+
"cognee.modules.retrieval.utils.session_cache.CacheConfig"
|
|
136
|
+
) as MockCacheConfig:
|
|
137
|
+
mock_config = MagicMock()
|
|
138
|
+
mock_config.caching = True
|
|
139
|
+
MockCacheConfig.return_value = mock_config
|
|
140
|
+
|
|
141
|
+
from cognee.modules.retrieval.utils.session_cache import (
|
|
142
|
+
save_conversation_history,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
result = await save_conversation_history(
|
|
146
|
+
query="Test question",
|
|
147
|
+
context_summary="Test context",
|
|
148
|
+
answer="Test answer",
|
|
149
|
+
session_id=None,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
assert result is True
|
|
153
|
+
call_kwargs = mock_cache.add_qa.call_args.kwargs
|
|
154
|
+
assert call_kwargs["session_id"] == "default_session"
|
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
import pytest
|
|
3
3
|
import pathlib
|
|
4
4
|
from typing import Optional, Union
|
|
5
|
+
from pydantic import BaseModel
|
|
5
6
|
|
|
6
7
|
import cognee
|
|
7
8
|
from cognee.low_level import setup, DataPoint
|
|
@@ -10,6 +11,11 @@ from cognee.tasks.storage import add_data_points
|
|
|
10
11
|
from cognee.modules.retrieval.graph_completion_cot_retriever import GraphCompletionCotRetriever
|
|
11
12
|
|
|
12
13
|
|
|
14
|
+
class TestAnswer(BaseModel):
|
|
15
|
+
answer: str
|
|
16
|
+
explanation: str
|
|
17
|
+
|
|
18
|
+
|
|
13
19
|
class TestGraphCompletionCoTRetriever:
|
|
14
20
|
@pytest.mark.asyncio
|
|
15
21
|
async def test_graph_completion_cot_context_simple(self):
|
|
@@ -168,3 +174,48 @@ class TestGraphCompletionCoTRetriever:
|
|
|
168
174
|
assert all(isinstance(item, str) and item.strip() for item in answer), (
|
|
169
175
|
"Answer must contain only non-empty strings"
|
|
170
176
|
)
|
|
177
|
+
|
|
178
|
+
@pytest.mark.asyncio
|
|
179
|
+
async def test_get_structured_completion(self):
|
|
180
|
+
system_directory_path = os.path.join(
|
|
181
|
+
pathlib.Path(__file__).parent, ".cognee_system/test_get_structured_completion"
|
|
182
|
+
)
|
|
183
|
+
cognee.config.system_root_directory(system_directory_path)
|
|
184
|
+
data_directory_path = os.path.join(
|
|
185
|
+
pathlib.Path(__file__).parent, ".data_storage/test_get_structured_completion"
|
|
186
|
+
)
|
|
187
|
+
cognee.config.data_root_directory(data_directory_path)
|
|
188
|
+
|
|
189
|
+
await cognee.prune.prune_data()
|
|
190
|
+
await cognee.prune.prune_system(metadata=True)
|
|
191
|
+
await setup()
|
|
192
|
+
|
|
193
|
+
class Company(DataPoint):
|
|
194
|
+
name: str
|
|
195
|
+
|
|
196
|
+
class Person(DataPoint):
|
|
197
|
+
name: str
|
|
198
|
+
works_for: Company
|
|
199
|
+
|
|
200
|
+
company1 = Company(name="Figma")
|
|
201
|
+
person1 = Person(name="Steve Rodger", works_for=company1)
|
|
202
|
+
|
|
203
|
+
entities = [company1, person1]
|
|
204
|
+
await add_data_points(entities)
|
|
205
|
+
|
|
206
|
+
retriever = GraphCompletionCotRetriever()
|
|
207
|
+
|
|
208
|
+
# Test with string response model (default)
|
|
209
|
+
string_answer = await retriever.get_structured_completion("Who works at Figma?")
|
|
210
|
+
assert isinstance(string_answer, str), f"Expected str, got {type(string_answer).__name__}"
|
|
211
|
+
assert string_answer.strip(), "Answer should not be empty"
|
|
212
|
+
|
|
213
|
+
# Test with structured response model
|
|
214
|
+
structured_answer = await retriever.get_structured_completion(
|
|
215
|
+
"Who works at Figma?", response_model=TestAnswer
|
|
216
|
+
)
|
|
217
|
+
assert isinstance(structured_answer, TestAnswer), (
|
|
218
|
+
f"Expected TestAnswer, got {type(structured_answer).__name__}"
|
|
219
|
+
)
|
|
220
|
+
assert structured_answer.answer.strip(), "Answer field should not be empty"
|
|
221
|
+
assert structured_answer.explanation.strip(), "Explanation field should not be empty"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cognee
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.7.dev1
|
|
4
4
|
Summary: Cognee - is a library for enriching LLM context with a semantic layer for better understanding and reasoning.
|
|
5
5
|
Project-URL: Homepage, https://www.cognee.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/topoteretes/cognee
|
|
@@ -15,13 +15,13 @@ Classifier: Operating System :: MacOS :: MacOS X
|
|
|
15
15
|
Classifier: Operating System :: Microsoft :: Windows
|
|
16
16
|
Classifier: Operating System :: POSIX :: Linux
|
|
17
17
|
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
-
Requires-Python:
|
|
18
|
+
Requires-Python: <3.14,>=3.10
|
|
19
19
|
Requires-Dist: aiofiles<24.0.0,>=23.2.1
|
|
20
20
|
Requires-Dist: aiohttp<4.0.0,>=3.11.14
|
|
21
21
|
Requires-Dist: aiosqlite<1.0.0,>=0.20.0
|
|
22
22
|
Requires-Dist: alembic<2,>=1.13.3
|
|
23
23
|
Requires-Dist: fastapi-users[sqlalchemy]<15.0.0,>=14.0.1
|
|
24
|
-
Requires-Dist: fastapi<1.0.0,>=0.
|
|
24
|
+
Requires-Dist: fastapi<1.0.0,>=0.116.2
|
|
25
25
|
Requires-Dist: fastembed<=0.6.0
|
|
26
26
|
Requires-Dist: filetype<2.0.0,>=1.2.0
|
|
27
27
|
Requires-Dist: gunicorn<24,>=20.1.0
|
|
@@ -31,6 +31,7 @@ Requires-Dist: kuzu==0.11.3
|
|
|
31
31
|
Requires-Dist: lancedb<1.0.0,>=0.24.0
|
|
32
32
|
Requires-Dist: limits<5,>=4.4.1
|
|
33
33
|
Requires-Dist: litellm>=1.76.0
|
|
34
|
+
Requires-Dist: mistralai>=1.9.10
|
|
34
35
|
Requires-Dist: nbformat<6.0.0,>=5.7.0
|
|
35
36
|
Requires-Dist: networkx<4,>=3.4.2
|
|
36
37
|
Requires-Dist: numpy<=4.0.0,>=1.26.4
|
|
@@ -47,6 +48,7 @@ Requires-Dist: python-multipart<1.0.0,>=0.0.20
|
|
|
47
48
|
Requires-Dist: rdflib<7.2.0,>=7.1.4
|
|
48
49
|
Requires-Dist: sqlalchemy<3.0.0,>=2.0.39
|
|
49
50
|
Requires-Dist: structlog<26,>=25.2.0
|
|
51
|
+
Requires-Dist: tenacity>=9.0.0
|
|
50
52
|
Requires-Dist: tiktoken<1.0.0,>=0.8.0
|
|
51
53
|
Requires-Dist: typing-extensions<5.0.0,>=4.12.2
|
|
52
54
|
Requires-Dist: uvicorn<1.0.0,>=0.34.0
|
|
@@ -90,7 +92,11 @@ Provides-Extra: distributed
|
|
|
90
92
|
Requires-Dist: modal<2.0.0,>=1.0.5; extra == 'distributed'
|
|
91
93
|
Provides-Extra: dlt
|
|
92
94
|
Requires-Dist: dlt[sqlalchemy]<2,>=1.9.0; extra == 'dlt'
|
|
95
|
+
Provides-Extra: docling
|
|
96
|
+
Requires-Dist: docling>=2.54; extra == 'docling'
|
|
97
|
+
Requires-Dist: transformers>=4.55; extra == 'docling'
|
|
93
98
|
Provides-Extra: docs
|
|
99
|
+
Requires-Dist: lxml<6.0.0; extra == 'docs'
|
|
94
100
|
Requires-Dist: unstructured[csv,doc,docx,epub,md,odt,org,pdf,ppt,pptx,rst,rtf,tsv,xlsx]<19,>=0.18.1; extra == 'docs'
|
|
95
101
|
Provides-Extra: evals
|
|
96
102
|
Requires-Dist: gdown<6,>=5.2.0; extra == 'evals'
|
|
@@ -132,6 +138,15 @@ Requires-Dist: pgvector<0.4,>=0.3.5; extra == 'postgres-binary'
|
|
|
132
138
|
Requires-Dist: psycopg2-binary<3.0.0,>=2.9.10; extra == 'postgres-binary'
|
|
133
139
|
Provides-Extra: posthog
|
|
134
140
|
Requires-Dist: posthog<4,>=3.5.0; extra == 'posthog'
|
|
141
|
+
Provides-Extra: redis
|
|
142
|
+
Requires-Dist: redis<6.0.0,>=5.0.3; extra == 'redis'
|
|
143
|
+
Provides-Extra: scraping
|
|
144
|
+
Requires-Dist: apscheduler<=3.11.0,>=3.10.0; extra == 'scraping'
|
|
145
|
+
Requires-Dist: beautifulsoup4>=4.13.1; extra == 'scraping'
|
|
146
|
+
Requires-Dist: lxml>=4.9.3; extra == 'scraping'
|
|
147
|
+
Requires-Dist: playwright>=1.9.0; extra == 'scraping'
|
|
148
|
+
Requires-Dist: protego>=0.1; extra == 'scraping'
|
|
149
|
+
Requires-Dist: tavily-python>=0.7.12; extra == 'scraping'
|
|
135
150
|
Description-Content-Type: text/markdown
|
|
136
151
|
|
|
137
152
|
<div align="center">
|
|
@@ -207,7 +222,7 @@ Build dynamic memory for Agents and replace RAG using scalable, modular ECL (Ext
|
|
|
207
222
|
|
|
208
223
|
## Get Started
|
|
209
224
|
|
|
210
|
-
Get started quickly with a Google Colab <a href="https://colab.research.google.com/drive/
|
|
225
|
+
Get started quickly with a Google Colab <a href="https://colab.research.google.com/drive/12Vi9zID-M3fpKpKiaqDBvkk98ElkRPWy?usp=sharing">notebook</a> , <a href="https://deepnote.com/workspace/cognee-382213d0-0444-4c89-8265-13770e333c02/project/cognee-demo-78ffacb9-5832-4611-bb1a-560386068b30/notebook/Notebook-1-75b24cda566d4c24ab348f7150792601?utm_source=share-modal&utm_medium=product-shared-content&utm_campaign=notebook&utm_content=78ffacb9-5832-4611-bb1a-560386068b30">Deepnote notebook</a> or <a href="https://github.com/topoteretes/cognee/tree/main/cognee-starter-kit">starter repo</a>
|
|
211
226
|
|
|
212
227
|
|
|
213
228
|
## About cognee
|
|
@@ -360,12 +375,12 @@ We now have a paper you can cite:
|
|
|
360
375
|
|
|
361
376
|
```bibtex
|
|
362
377
|
@misc{markovic2025optimizinginterfaceknowledgegraphs,
|
|
363
|
-
title={Optimizing the Interface Between Knowledge Graphs and LLMs for Complex Reasoning},
|
|
378
|
+
title={Optimizing the Interface Between Knowledge Graphs and LLMs for Complex Reasoning},
|
|
364
379
|
author={Vasilije Markovic and Lazar Obradovic and Laszlo Hajdu and Jovan Pavlovic},
|
|
365
380
|
year={2025},
|
|
366
381
|
eprint={2505.24478},
|
|
367
382
|
archivePrefix={arXiv},
|
|
368
383
|
primaryClass={cs.AI},
|
|
369
|
-
url={https://arxiv.org/abs/2505.24478},
|
|
384
|
+
url={https://arxiv.org/abs/2505.24478},
|
|
370
385
|
}
|
|
371
386
|
```
|