cognee 0.5.1__py3-none-any.whl → 0.5.2__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.
Files changed (265) hide show
  1. cognee/__init__.py +2 -0
  2. cognee/alembic/README +1 -0
  3. cognee/alembic/env.py +107 -0
  4. cognee/alembic/script.py.mako +26 -0
  5. cognee/alembic/versions/1a58b986e6e1_enable_delete_for_old_tutorial_notebooks.py +52 -0
  6. cognee/alembic/versions/1d0bb7fede17_add_pipeline_run_status.py +33 -0
  7. cognee/alembic/versions/1daae0df1866_incremental_loading.py +48 -0
  8. cognee/alembic/versions/211ab850ef3d_add_sync_operations_table.py +118 -0
  9. cognee/alembic/versions/45957f0a9849_add_notebook_table.py +46 -0
  10. cognee/alembic/versions/46a6ce2bd2b2_expand_dataset_database_with_json_.py +333 -0
  11. cognee/alembic/versions/482cd6517ce4_add_default_user.py +30 -0
  12. cognee/alembic/versions/76625596c5c3_expand_dataset_database_for_multi_user.py +98 -0
  13. cognee/alembic/versions/8057ae7329c2_initial_migration.py +25 -0
  14. cognee/alembic/versions/9e7a3cb85175_loader_separation.py +104 -0
  15. cognee/alembic/versions/a1b2c3d4e5f6_add_label_column_to_data.py +38 -0
  16. cognee/alembic/versions/ab7e313804ae_permission_system_rework.py +236 -0
  17. cognee/alembic/versions/b9274c27a25a_kuzu_11_migration.py +75 -0
  18. cognee/alembic/versions/c946955da633_multi_tenant_support.py +137 -0
  19. cognee/alembic/versions/e1ec1dcb50b6_add_last_accessed_to_data.py +51 -0
  20. cognee/alembic/versions/e4ebee1091e7_expand_data_model_info.py +140 -0
  21. cognee/alembic.ini +117 -0
  22. cognee/api/v1/add/add.py +2 -1
  23. cognee/api/v1/add/routers/get_add_router.py +2 -0
  24. cognee/api/v1/cognify/cognify.py +11 -6
  25. cognee/api/v1/cognify/routers/get_cognify_router.py +8 -0
  26. cognee/api/v1/config/config.py +60 -0
  27. cognee/api/v1/datasets/routers/get_datasets_router.py +46 -3
  28. cognee/api/v1/memify/routers/get_memify_router.py +3 -0
  29. cognee/api/v1/search/routers/get_search_router.py +21 -6
  30. cognee/api/v1/search/search.py +21 -5
  31. cognee/api/v1/sync/routers/get_sync_router.py +3 -3
  32. cognee/cli/commands/add_command.py +1 -1
  33. cognee/cli/commands/cognify_command.py +6 -0
  34. cognee/cli/commands/config_command.py +1 -1
  35. cognee/context_global_variables.py +5 -1
  36. cognee/eval_framework/answer_generation/answer_generation_executor.py +7 -8
  37. cognee/infrastructure/databases/cache/cache_db_interface.py +38 -1
  38. cognee/infrastructure/databases/cache/config.py +6 -0
  39. cognee/infrastructure/databases/cache/fscache/FsCacheAdapter.py +21 -0
  40. cognee/infrastructure/databases/cache/get_cache_engine.py +9 -3
  41. cognee/infrastructure/databases/cache/redis/RedisAdapter.py +60 -1
  42. cognee/infrastructure/databases/dataset_database_handler/supported_dataset_database_handlers.py +7 -0
  43. cognee/infrastructure/databases/graph/get_graph_engine.py +29 -1
  44. cognee/infrastructure/databases/graph/neo4j_driver/Neo4jAuraDevDatasetDatabaseHandler.py +62 -27
  45. cognee/infrastructure/databases/hybrid/neptune_analytics/NeptuneAnalyticsAdapter.py +17 -4
  46. cognee/infrastructure/databases/relational/config.py +16 -1
  47. cognee/infrastructure/databases/relational/create_relational_engine.py +13 -3
  48. cognee/infrastructure/databases/relational/sqlalchemy/SqlAlchemyAdapter.py +26 -3
  49. cognee/infrastructure/databases/vector/chromadb/ChromaDBAdapter.py +2 -0
  50. cognee/infrastructure/databases/vector/config.py +6 -0
  51. cognee/infrastructure/databases/vector/create_vector_engine.py +70 -16
  52. cognee/infrastructure/databases/vector/embeddings/LiteLLMEmbeddingEngine.py +64 -9
  53. cognee/infrastructure/databases/vector/embeddings/OllamaEmbeddingEngine.py +13 -2
  54. cognee/infrastructure/databases/vector/lancedb/LanceDBAdapter.py +16 -3
  55. cognee/infrastructure/databases/vector/models/ScoredResult.py +3 -3
  56. cognee/infrastructure/databases/vector/pgvector/PGVectorAdapter.py +16 -3
  57. cognee/infrastructure/databases/vector/pgvector/PGVectorDatasetDatabaseHandler.py +86 -0
  58. cognee/infrastructure/databases/vector/pgvector/create_db_and_tables.py +81 -2
  59. cognee/infrastructure/databases/vector/vector_db_interface.py +8 -0
  60. cognee/infrastructure/files/utils/get_data_file_path.py +33 -27
  61. cognee/infrastructure/llm/LLMGateway.py +0 -13
  62. cognee/infrastructure/llm/prompts/extract_query_time.txt +1 -1
  63. cognee/infrastructure/llm/prompts/generate_event_entity_prompt.txt +1 -1
  64. cognee/infrastructure/llm/prompts/generate_event_graph_prompt.txt +1 -1
  65. cognee/infrastructure/llm/prompts/generate_graph_prompt.txt +2 -2
  66. cognee/infrastructure/llm/prompts/generate_graph_prompt_guided.txt +1 -1
  67. cognee/infrastructure/llm/prompts/generate_graph_prompt_oneshot.txt +2 -2
  68. cognee/infrastructure/llm/prompts/generate_graph_prompt_simple.txt +1 -1
  69. cognee/infrastructure/llm/prompts/generate_graph_prompt_strict.txt +1 -1
  70. cognee/infrastructure/llm/prompts/search_type_selector_prompt.txt +6 -6
  71. cognee/infrastructure/llm/prompts/test.txt +1 -1
  72. cognee/infrastructure/llm/prompts/translate_content.txt +19 -0
  73. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/anthropic/adapter.py +17 -12
  74. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/gemini/adapter.py +31 -25
  75. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/generic_llm_api/adapter.py +132 -7
  76. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/get_llm_client.py +29 -5
  77. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/llama_cpp/adapter.py +191 -0
  78. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/llm_interface.py +2 -6
  79. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/mistral/adapter.py +58 -13
  80. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/ollama/adapter.py +0 -1
  81. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/openai/adapter.py +25 -131
  82. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/types.py +10 -0
  83. cognee/modules/chunking/models/DocumentChunk.py +0 -1
  84. cognee/modules/cognify/config.py +2 -0
  85. cognee/modules/data/models/Data.py +3 -1
  86. cognee/modules/engine/models/Entity.py +0 -1
  87. cognee/modules/engine/operations/setup.py +6 -0
  88. cognee/modules/graph/cognee_graph/CogneeGraph.py +150 -37
  89. cognee/modules/graph/cognee_graph/CogneeGraphElements.py +48 -2
  90. cognee/modules/graph/utils/__init__.py +1 -0
  91. cognee/modules/graph/utils/get_entity_nodes_from_triplets.py +12 -0
  92. cognee/modules/notebooks/methods/__init__.py +1 -0
  93. cognee/modules/notebooks/methods/create_notebook.py +0 -34
  94. cognee/modules/notebooks/methods/create_tutorial_notebooks.py +191 -0
  95. cognee/modules/notebooks/methods/get_notebooks.py +12 -8
  96. cognee/modules/notebooks/tutorials/cognee-basics/cell-1.md +3 -0
  97. cognee/modules/notebooks/tutorials/cognee-basics/cell-2.md +10 -0
  98. cognee/modules/notebooks/tutorials/cognee-basics/cell-3.md +7 -0
  99. cognee/modules/notebooks/tutorials/cognee-basics/cell-4.py +28 -0
  100. cognee/modules/notebooks/tutorials/cognee-basics/cell-5.py +3 -0
  101. cognee/modules/notebooks/tutorials/cognee-basics/cell-6.py +9 -0
  102. cognee/modules/notebooks/tutorials/cognee-basics/cell-7.py +17 -0
  103. cognee/modules/notebooks/tutorials/cognee-basics/config.json +4 -0
  104. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-1.md +3 -0
  105. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-10.md +3 -0
  106. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-11.md +3 -0
  107. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-12.py +3 -0
  108. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-13.md +7 -0
  109. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-14.py +6 -0
  110. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-15.md +3 -0
  111. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-16.py +7 -0
  112. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-2.md +9 -0
  113. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-3.md +7 -0
  114. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-4.md +9 -0
  115. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-5.md +5 -0
  116. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-6.py +13 -0
  117. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-7.md +3 -0
  118. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-8.md +3 -0
  119. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-9.py +31 -0
  120. cognee/modules/notebooks/tutorials/python-development-with-cognee/config.json +4 -0
  121. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/copilot_conversations.json +107 -0
  122. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/guido_contributions.json +976 -0
  123. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/my_developer_rules.md +79 -0
  124. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/pep_style_guide.md +74 -0
  125. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/zen_principles.md +74 -0
  126. cognee/modules/retrieval/EntityCompletionRetriever.py +51 -38
  127. cognee/modules/retrieval/__init__.py +0 -1
  128. cognee/modules/retrieval/base_retriever.py +66 -10
  129. cognee/modules/retrieval/chunks_retriever.py +57 -49
  130. cognee/modules/retrieval/coding_rules_retriever.py +12 -5
  131. cognee/modules/retrieval/completion_retriever.py +29 -28
  132. cognee/modules/retrieval/cypher_search_retriever.py +25 -20
  133. cognee/modules/retrieval/graph_completion_context_extension_retriever.py +42 -46
  134. cognee/modules/retrieval/graph_completion_cot_retriever.py +68 -51
  135. cognee/modules/retrieval/graph_completion_retriever.py +78 -63
  136. cognee/modules/retrieval/graph_summary_completion_retriever.py +2 -0
  137. cognee/modules/retrieval/lexical_retriever.py +34 -12
  138. cognee/modules/retrieval/natural_language_retriever.py +18 -15
  139. cognee/modules/retrieval/summaries_retriever.py +51 -34
  140. cognee/modules/retrieval/temporal_retriever.py +59 -49
  141. cognee/modules/retrieval/triplet_retriever.py +32 -33
  142. cognee/modules/retrieval/utils/access_tracking.py +88 -0
  143. cognee/modules/retrieval/utils/brute_force_triplet_search.py +99 -103
  144. cognee/modules/retrieval/utils/node_edge_vector_search.py +174 -0
  145. cognee/modules/search/methods/__init__.py +1 -0
  146. cognee/modules/search/methods/get_retriever_output.py +53 -0
  147. cognee/modules/search/methods/get_search_type_retriever_instance.py +252 -0
  148. cognee/modules/search/methods/search.py +90 -222
  149. cognee/modules/search/models/SearchResultPayload.py +67 -0
  150. cognee/modules/search/types/SearchResult.py +1 -8
  151. cognee/modules/search/types/SearchType.py +1 -2
  152. cognee/modules/search/types/__init__.py +1 -1
  153. cognee/modules/search/utils/__init__.py +1 -2
  154. cognee/modules/search/utils/transform_insights_to_graph.py +2 -2
  155. cognee/modules/search/utils/{transform_context_to_graph.py → transform_triplets_to_graph.py} +2 -2
  156. cognee/modules/users/authentication/default/default_transport.py +11 -1
  157. cognee/modules/users/authentication/get_api_auth_backend.py +2 -1
  158. cognee/modules/users/authentication/get_client_auth_backend.py +2 -1
  159. cognee/modules/users/methods/create_user.py +0 -9
  160. cognee/modules/users/permissions/methods/has_user_management_permission.py +29 -0
  161. cognee/modules/visualization/cognee_network_visualization.py +1 -1
  162. cognee/run_migrations.py +48 -0
  163. cognee/shared/exceptions/__init__.py +1 -3
  164. cognee/shared/exceptions/exceptions.py +11 -1
  165. cognee/shared/usage_logger.py +332 -0
  166. cognee/shared/utils.py +12 -5
  167. cognee/tasks/chunks/__init__.py +9 -0
  168. cognee/tasks/cleanup/cleanup_unused_data.py +172 -0
  169. cognee/tasks/graph/__init__.py +7 -0
  170. cognee/tasks/ingestion/data_item.py +8 -0
  171. cognee/tasks/ingestion/ingest_data.py +12 -1
  172. cognee/tasks/ingestion/save_data_item_to_storage.py +5 -0
  173. cognee/tasks/memify/__init__.py +8 -0
  174. cognee/tasks/memify/extract_usage_frequency.py +613 -0
  175. cognee/tasks/summarization/models.py +0 -2
  176. cognee/tasks/temporal_graph/__init__.py +0 -1
  177. cognee/tasks/translation/__init__.py +96 -0
  178. cognee/tasks/translation/config.py +110 -0
  179. cognee/tasks/translation/detect_language.py +190 -0
  180. cognee/tasks/translation/exceptions.py +62 -0
  181. cognee/tasks/translation/models.py +72 -0
  182. cognee/tasks/translation/providers/__init__.py +44 -0
  183. cognee/tasks/translation/providers/azure_provider.py +192 -0
  184. cognee/tasks/translation/providers/base.py +85 -0
  185. cognee/tasks/translation/providers/google_provider.py +158 -0
  186. cognee/tasks/translation/providers/llm_provider.py +143 -0
  187. cognee/tasks/translation/translate_content.py +282 -0
  188. cognee/tasks/web_scraper/default_url_crawler.py +6 -2
  189. cognee/tests/cli_tests/cli_unit_tests/test_cli_commands.py +1 -0
  190. cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py +3 -0
  191. cognee/tests/integration/retrieval/test_brute_force_triplet_search_with_cognify.py +62 -0
  192. cognee/tests/integration/retrieval/test_chunks_retriever.py +351 -0
  193. cognee/tests/integration/retrieval/test_graph_completion_retriever.py +276 -0
  194. cognee/tests/integration/retrieval/test_graph_completion_retriever_context_extension.py +228 -0
  195. cognee/tests/integration/retrieval/test_graph_completion_retriever_cot.py +217 -0
  196. cognee/tests/integration/retrieval/test_rag_completion_retriever.py +319 -0
  197. cognee/tests/integration/retrieval/test_structured_output.py +258 -0
  198. cognee/tests/integration/retrieval/test_summaries_retriever.py +195 -0
  199. cognee/tests/integration/retrieval/test_temporal_retriever.py +336 -0
  200. cognee/tests/integration/retrieval/test_triplet_retriever.py +45 -1
  201. cognee/tests/integration/shared/test_usage_logger_integration.py +255 -0
  202. cognee/tests/tasks/translation/README.md +147 -0
  203. cognee/tests/tasks/translation/__init__.py +1 -0
  204. cognee/tests/tasks/translation/config_test.py +93 -0
  205. cognee/tests/tasks/translation/detect_language_test.py +118 -0
  206. cognee/tests/tasks/translation/providers_test.py +151 -0
  207. cognee/tests/tasks/translation/translate_content_test.py +213 -0
  208. cognee/tests/test_chromadb.py +1 -1
  209. cognee/tests/test_cleanup_unused_data.py +165 -0
  210. cognee/tests/test_custom_data_label.py +68 -0
  211. cognee/tests/test_delete_by_id.py +6 -6
  212. cognee/tests/test_extract_usage_frequency.py +308 -0
  213. cognee/tests/test_kuzu.py +17 -7
  214. cognee/tests/test_lancedb.py +3 -1
  215. cognee/tests/test_library.py +1 -1
  216. cognee/tests/test_neo4j.py +17 -7
  217. cognee/tests/test_neptune_analytics_vector.py +3 -1
  218. cognee/tests/test_permissions.py +172 -187
  219. cognee/tests/test_pgvector.py +3 -1
  220. cognee/tests/test_relational_db_migration.py +15 -1
  221. cognee/tests/test_remote_kuzu.py +3 -1
  222. cognee/tests/test_s3_file_storage.py +1 -1
  223. cognee/tests/test_search_db.py +345 -205
  224. cognee/tests/test_usage_logger_e2e.py +268 -0
  225. cognee/tests/unit/api/test_get_raw_data_endpoint.py +206 -0
  226. cognee/tests/unit/eval_framework/answer_generation_test.py +4 -3
  227. cognee/tests/unit/eval_framework/benchmark_adapters_test.py +25 -0
  228. cognee/tests/unit/eval_framework/corpus_builder_test.py +33 -4
  229. cognee/tests/unit/infrastructure/databases/cache/test_cache_config.py +2 -0
  230. cognee/tests/unit/infrastructure/databases/relational/test_RelationalConfig.py +69 -0
  231. cognee/tests/unit/modules/graph/cognee_graph_elements_test.py +42 -2
  232. cognee/tests/unit/modules/graph/cognee_graph_test.py +329 -31
  233. cognee/tests/unit/modules/retrieval/chunks_retriever_test.py +122 -168
  234. cognee/tests/unit/modules/retrieval/conversation_history_test.py +338 -0
  235. cognee/tests/unit/modules/retrieval/graph_completion_retriever_context_extension_test.py +486 -157
  236. cognee/tests/unit/modules/retrieval/graph_completion_retriever_cot_test.py +693 -155
  237. cognee/tests/unit/modules/retrieval/graph_completion_retriever_test.py +619 -200
  238. cognee/tests/unit/modules/retrieval/rag_completion_retriever_test.py +300 -171
  239. cognee/tests/unit/modules/retrieval/summaries_retriever_test.py +184 -155
  240. cognee/tests/unit/modules/retrieval/temporal_retriever_test.py +544 -79
  241. cognee/tests/unit/modules/retrieval/test_brute_force_triplet_search.py +476 -28
  242. cognee/tests/unit/modules/retrieval/test_completion.py +343 -0
  243. cognee/tests/unit/modules/retrieval/test_graph_summary_completion_retriever.py +157 -0
  244. cognee/tests/unit/modules/retrieval/test_node_edge_vector_search.py +273 -0
  245. cognee/tests/unit/modules/retrieval/test_user_qa_feedback.py +312 -0
  246. cognee/tests/unit/modules/retrieval/triplet_retriever_test.py +267 -7
  247. cognee/tests/unit/modules/search/test_get_search_type_retriever_instance.py +125 -0
  248. cognee/tests/unit/modules/search/test_search.py +96 -20
  249. cognee/tests/unit/modules/search/test_search_prepare_search_result_contract.py +190 -0
  250. cognee/tests/unit/modules/users/test_tutorial_notebook_creation.py +511 -297
  251. cognee/tests/unit/shared/test_usage_logger.py +241 -0
  252. cognee/tests/unit/users/permissions/test_has_user_management_permission.py +46 -0
  253. {cognee-0.5.1.dist-info → cognee-0.5.2.dist-info}/METADATA +22 -17
  254. {cognee-0.5.1.dist-info → cognee-0.5.2.dist-info}/RECORD +258 -157
  255. cognee/api/.env.example +0 -5
  256. cognee/modules/retrieval/base_graph_retriever.py +0 -24
  257. cognee/modules/search/methods/get_search_type_tools.py +0 -223
  258. cognee/modules/search/methods/no_access_control_search.py +0 -62
  259. cognee/modules/search/utils/prepare_search_result.py +0 -63
  260. cognee/tests/test_feedback_enrichment.py +0 -174
  261. cognee/tests/unit/modules/retrieval/structured_output_test.py +0 -204
  262. {cognee-0.5.1.dist-info → cognee-0.5.2.dist-info}/WHEEL +0 -0
  263. {cognee-0.5.1.dist-info → cognee-0.5.2.dist-info}/entry_points.txt +0 -0
  264. {cognee-0.5.1.dist-info → cognee-0.5.2.dist-info}/licenses/LICENSE +0 -0
  265. {cognee-0.5.1.dist-info → cognee-0.5.2.dist-info}/licenses/NOTICE.md +0 -0
@@ -0,0 +1,343 @@
1
+ import pytest
2
+ from unittest.mock import AsyncMock, patch, MagicMock
3
+ from typing import Type
4
+
5
+
6
+ class TestGenerateCompletion:
7
+ @pytest.mark.asyncio
8
+ async def test_generate_completion_with_system_prompt(self):
9
+ """Test generate_completion with provided system_prompt."""
10
+ mock_llm_response = "Generated answer"
11
+
12
+ with (
13
+ patch(
14
+ "cognee.modules.retrieval.utils.completion.render_prompt",
15
+ return_value="User prompt text",
16
+ ),
17
+ patch(
18
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
19
+ new_callable=AsyncMock,
20
+ return_value=mock_llm_response,
21
+ ) as mock_llm,
22
+ ):
23
+ from cognee.modules.retrieval.utils.completion import generate_completion
24
+
25
+ result = await generate_completion(
26
+ query="What is AI?",
27
+ context="AI is artificial intelligence",
28
+ user_prompt_path="user_prompt.txt",
29
+ system_prompt_path="system_prompt.txt",
30
+ system_prompt="Custom system prompt",
31
+ )
32
+
33
+ assert result == mock_llm_response
34
+ mock_llm.assert_awaited_once_with(
35
+ text_input="User prompt text",
36
+ system_prompt="Custom system prompt",
37
+ response_model=str,
38
+ )
39
+
40
+ @pytest.mark.asyncio
41
+ async def test_generate_completion_without_system_prompt(self):
42
+ """Test generate_completion reads system_prompt from file when not provided."""
43
+ mock_llm_response = "Generated answer"
44
+
45
+ with (
46
+ patch(
47
+ "cognee.modules.retrieval.utils.completion.render_prompt",
48
+ return_value="User prompt text",
49
+ ),
50
+ patch(
51
+ "cognee.modules.retrieval.utils.completion.read_query_prompt",
52
+ return_value="System prompt from file",
53
+ ),
54
+ patch(
55
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
56
+ new_callable=AsyncMock,
57
+ return_value=mock_llm_response,
58
+ ) as mock_llm,
59
+ ):
60
+ from cognee.modules.retrieval.utils.completion import generate_completion
61
+
62
+ result = await generate_completion(
63
+ query="What is AI?",
64
+ context="AI is artificial intelligence",
65
+ user_prompt_path="user_prompt.txt",
66
+ system_prompt_path="system_prompt.txt",
67
+ )
68
+
69
+ assert result == mock_llm_response
70
+ mock_llm.assert_awaited_once_with(
71
+ text_input="User prompt text",
72
+ system_prompt="System prompt from file",
73
+ response_model=str,
74
+ )
75
+
76
+ @pytest.mark.asyncio
77
+ async def test_generate_completion_with_conversation_history(self):
78
+ """Test generate_completion includes conversation_history in system_prompt."""
79
+ mock_llm_response = "Generated answer"
80
+
81
+ with (
82
+ patch(
83
+ "cognee.modules.retrieval.utils.completion.render_prompt",
84
+ return_value="User prompt text",
85
+ ),
86
+ patch(
87
+ "cognee.modules.retrieval.utils.completion.read_query_prompt",
88
+ return_value="System prompt from file",
89
+ ),
90
+ patch(
91
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
92
+ new_callable=AsyncMock,
93
+ return_value=mock_llm_response,
94
+ ) as mock_llm,
95
+ ):
96
+ from cognee.modules.retrieval.utils.completion import generate_completion
97
+
98
+ result = await generate_completion(
99
+ query="What is AI?",
100
+ context="AI is artificial intelligence",
101
+ user_prompt_path="user_prompt.txt",
102
+ system_prompt_path="system_prompt.txt",
103
+ conversation_history="Previous conversation:\nQ: What is ML?\nA: ML is machine learning",
104
+ )
105
+
106
+ assert result == mock_llm_response
107
+ expected_system_prompt = (
108
+ "Previous conversation:\nQ: What is ML?\nA: ML is machine learning"
109
+ + "\nTASK:"
110
+ + "System prompt from file"
111
+ )
112
+ mock_llm.assert_awaited_once_with(
113
+ text_input="User prompt text",
114
+ system_prompt=expected_system_prompt,
115
+ response_model=str,
116
+ )
117
+
118
+ @pytest.mark.asyncio
119
+ async def test_generate_completion_with_conversation_history_and_custom_system_prompt(self):
120
+ """Test generate_completion includes conversation_history with custom system_prompt."""
121
+ mock_llm_response = "Generated answer"
122
+
123
+ with (
124
+ patch(
125
+ "cognee.modules.retrieval.utils.completion.render_prompt",
126
+ return_value="User prompt text",
127
+ ),
128
+ patch(
129
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
130
+ new_callable=AsyncMock,
131
+ return_value=mock_llm_response,
132
+ ) as mock_llm,
133
+ ):
134
+ from cognee.modules.retrieval.utils.completion import generate_completion
135
+
136
+ result = await generate_completion(
137
+ query="What is AI?",
138
+ context="AI is artificial intelligence",
139
+ user_prompt_path="user_prompt.txt",
140
+ system_prompt_path="system_prompt.txt",
141
+ system_prompt="Custom system prompt",
142
+ conversation_history="Previous conversation:\nQ: What is ML?\nA: ML is machine learning",
143
+ )
144
+
145
+ assert result == mock_llm_response
146
+ expected_system_prompt = (
147
+ "Previous conversation:\nQ: What is ML?\nA: ML is machine learning"
148
+ + "\nTASK:"
149
+ + "Custom system prompt"
150
+ )
151
+ mock_llm.assert_awaited_once_with(
152
+ text_input="User prompt text",
153
+ system_prompt=expected_system_prompt,
154
+ response_model=str,
155
+ )
156
+
157
+ @pytest.mark.asyncio
158
+ async def test_generate_completion_with_response_model(self):
159
+ """Test generate_completion with custom response_model."""
160
+ mock_response_model = MagicMock()
161
+ mock_llm_response = {"answer": "Generated answer"}
162
+
163
+ with (
164
+ patch(
165
+ "cognee.modules.retrieval.utils.completion.render_prompt",
166
+ return_value="User prompt text",
167
+ ),
168
+ patch(
169
+ "cognee.modules.retrieval.utils.completion.read_query_prompt",
170
+ return_value="System prompt from file",
171
+ ),
172
+ patch(
173
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
174
+ new_callable=AsyncMock,
175
+ return_value=mock_llm_response,
176
+ ) as mock_llm,
177
+ ):
178
+ from cognee.modules.retrieval.utils.completion import generate_completion
179
+
180
+ result = await generate_completion(
181
+ query="What is AI?",
182
+ context="AI is artificial intelligence",
183
+ user_prompt_path="user_prompt.txt",
184
+ system_prompt_path="system_prompt.txt",
185
+ response_model=mock_response_model,
186
+ )
187
+
188
+ assert result == mock_llm_response
189
+ mock_llm.assert_awaited_once_with(
190
+ text_input="User prompt text",
191
+ system_prompt="System prompt from file",
192
+ response_model=mock_response_model,
193
+ )
194
+
195
+ @pytest.mark.asyncio
196
+ async def test_generate_completion_render_prompt_args(self):
197
+ """Test generate_completion passes correct args to render_prompt."""
198
+ mock_llm_response = "Generated answer"
199
+
200
+ with (
201
+ patch(
202
+ "cognee.modules.retrieval.utils.completion.render_prompt",
203
+ return_value="User prompt text",
204
+ ) as mock_render,
205
+ patch(
206
+ "cognee.modules.retrieval.utils.completion.read_query_prompt",
207
+ return_value="System prompt from file",
208
+ ),
209
+ patch(
210
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
211
+ new_callable=AsyncMock,
212
+ return_value=mock_llm_response,
213
+ ),
214
+ ):
215
+ from cognee.modules.retrieval.utils.completion import generate_completion
216
+
217
+ await generate_completion(
218
+ query="What is AI?",
219
+ context="AI is artificial intelligence",
220
+ user_prompt_path="user_prompt.txt",
221
+ system_prompt_path="system_prompt.txt",
222
+ )
223
+
224
+ mock_render.assert_called_once_with(
225
+ "user_prompt.txt",
226
+ {"question": "What is AI?", "context": "AI is artificial intelligence"},
227
+ )
228
+
229
+
230
+ class TestSummarizeText:
231
+ @pytest.mark.asyncio
232
+ async def test_summarize_text_with_system_prompt(self):
233
+ """Test summarize_text with provided system_prompt."""
234
+ mock_llm_response = "Summary text"
235
+
236
+ with patch(
237
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
238
+ new_callable=AsyncMock,
239
+ return_value=mock_llm_response,
240
+ ) as mock_llm:
241
+ from cognee.modules.retrieval.utils.completion import summarize_text
242
+
243
+ result = await summarize_text(
244
+ text="Long text to summarize",
245
+ system_prompt_path="summarize_search_results.txt",
246
+ system_prompt="Custom summary prompt",
247
+ )
248
+
249
+ assert result == mock_llm_response
250
+ mock_llm.assert_awaited_once_with(
251
+ text_input="Long text to summarize",
252
+ system_prompt="Custom summary prompt",
253
+ response_model=str,
254
+ )
255
+
256
+ @pytest.mark.asyncio
257
+ async def test_summarize_text_without_system_prompt(self):
258
+ """Test summarize_text reads system_prompt from file when not provided."""
259
+ mock_llm_response = "Summary text"
260
+
261
+ with (
262
+ patch(
263
+ "cognee.modules.retrieval.utils.completion.read_query_prompt",
264
+ return_value="System prompt from file",
265
+ ),
266
+ patch(
267
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
268
+ new_callable=AsyncMock,
269
+ return_value=mock_llm_response,
270
+ ) as mock_llm,
271
+ ):
272
+ from cognee.modules.retrieval.utils.completion import summarize_text
273
+
274
+ result = await summarize_text(
275
+ text="Long text to summarize",
276
+ system_prompt_path="summarize_search_results.txt",
277
+ )
278
+
279
+ assert result == mock_llm_response
280
+ mock_llm.assert_awaited_once_with(
281
+ text_input="Long text to summarize",
282
+ system_prompt="System prompt from file",
283
+ response_model=str,
284
+ )
285
+
286
+ @pytest.mark.asyncio
287
+ async def test_summarize_text_default_prompt_path(self):
288
+ """Test summarize_text uses default prompt path when not provided."""
289
+ mock_llm_response = "Summary text"
290
+
291
+ with (
292
+ patch(
293
+ "cognee.modules.retrieval.utils.completion.read_query_prompt",
294
+ return_value="Default system prompt",
295
+ ) as mock_read,
296
+ patch(
297
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
298
+ new_callable=AsyncMock,
299
+ return_value=mock_llm_response,
300
+ ) as mock_llm,
301
+ ):
302
+ from cognee.modules.retrieval.utils.completion import summarize_text
303
+
304
+ result = await summarize_text(text="Long text to summarize")
305
+
306
+ assert result == mock_llm_response
307
+ mock_read.assert_called_once_with("summarize_search_results.txt")
308
+ mock_llm.assert_awaited_once_with(
309
+ text_input="Long text to summarize",
310
+ system_prompt="Default system prompt",
311
+ response_model=str,
312
+ )
313
+
314
+ @pytest.mark.asyncio
315
+ async def test_summarize_text_custom_prompt_path(self):
316
+ """Test summarize_text uses custom prompt path when provided."""
317
+ mock_llm_response = "Summary text"
318
+
319
+ with (
320
+ patch(
321
+ "cognee.modules.retrieval.utils.completion.read_query_prompt",
322
+ return_value="Custom system prompt",
323
+ ) as mock_read,
324
+ patch(
325
+ "cognee.modules.retrieval.utils.completion.LLMGateway.acreate_structured_output",
326
+ new_callable=AsyncMock,
327
+ return_value=mock_llm_response,
328
+ ) as mock_llm,
329
+ ):
330
+ from cognee.modules.retrieval.utils.completion import summarize_text
331
+
332
+ result = await summarize_text(
333
+ text="Long text to summarize",
334
+ system_prompt_path="custom_prompt.txt",
335
+ )
336
+
337
+ assert result == mock_llm_response
338
+ mock_read.assert_called_once_with("custom_prompt.txt")
339
+ mock_llm.assert_awaited_once_with(
340
+ text_input="Long text to summarize",
341
+ system_prompt="Custom system prompt",
342
+ response_model=str,
343
+ )
@@ -0,0 +1,157 @@
1
+ import pytest
2
+ from unittest.mock import AsyncMock, patch, MagicMock
3
+
4
+ from cognee.modules.retrieval.graph_summary_completion_retriever import (
5
+ GraphSummaryCompletionRetriever,
6
+ )
7
+ from cognee.modules.graph.cognee_graph.CogneeGraphElements import Edge
8
+
9
+
10
+ @pytest.fixture
11
+ def mock_edge():
12
+ """Create a mock edge."""
13
+ edge = MagicMock(spec=Edge)
14
+ return edge
15
+
16
+
17
+ class TestGraphSummaryCompletionRetriever:
18
+ @pytest.mark.asyncio
19
+ async def test_init_defaults(self):
20
+ """Test GraphSummaryCompletionRetriever initialization with defaults."""
21
+ retriever = GraphSummaryCompletionRetriever()
22
+
23
+ assert retriever.summarize_prompt_path == "summarize_search_results.txt"
24
+ assert retriever.user_prompt_path == "graph_context_for_question.txt"
25
+ assert retriever.system_prompt_path == "answer_simple_question.txt"
26
+ assert retriever.top_k == 5
27
+ assert retriever.save_interaction is False
28
+
29
+ @pytest.mark.asyncio
30
+ async def test_init_custom_params(self):
31
+ """Test GraphSummaryCompletionRetriever initialization with custom parameters."""
32
+ retriever = GraphSummaryCompletionRetriever(
33
+ user_prompt_path="custom_user.txt",
34
+ system_prompt_path="custom_system.txt",
35
+ summarize_prompt_path="custom_summarize.txt",
36
+ system_prompt="Custom system prompt",
37
+ top_k=10,
38
+ save_interaction=True,
39
+ wide_search_top_k=200,
40
+ triplet_distance_penalty=2.5,
41
+ )
42
+
43
+ assert retriever.summarize_prompt_path == "custom_summarize.txt"
44
+ assert retriever.user_prompt_path == "custom_user.txt"
45
+ assert retriever.system_prompt_path == "custom_system.txt"
46
+ assert retriever.top_k == 10
47
+ assert retriever.save_interaction is True
48
+
49
+ @pytest.mark.asyncio
50
+ async def test_resolve_edges_to_text_calls_super_and_summarizes(self, mock_edge):
51
+ """Test resolve_edges_to_text calls super method and then summarizes."""
52
+ retriever = GraphSummaryCompletionRetriever(
53
+ summarize_prompt_path="custom_summarize.txt",
54
+ system_prompt="Custom system prompt",
55
+ )
56
+
57
+ with (
58
+ patch(
59
+ "cognee.modules.retrieval.graph_completion_retriever.GraphCompletionRetriever.resolve_edges_to_text",
60
+ new_callable=AsyncMock,
61
+ return_value="Resolved edges text",
62
+ ) as mock_super_resolve,
63
+ patch(
64
+ "cognee.modules.retrieval.graph_summary_completion_retriever.summarize_text",
65
+ new_callable=AsyncMock,
66
+ return_value="Summarized text",
67
+ ) as mock_summarize,
68
+ ):
69
+ result = await retriever.resolve_edges_to_text([mock_edge])
70
+
71
+ assert result == "Summarized text"
72
+ mock_super_resolve.assert_awaited_once_with([mock_edge])
73
+ mock_summarize.assert_awaited_once_with(
74
+ "Resolved edges text",
75
+ "custom_summarize.txt",
76
+ "Custom system prompt",
77
+ )
78
+
79
+ @pytest.mark.asyncio
80
+ async def test_resolve_edges_to_text_with_default_system_prompt(self, mock_edge):
81
+ """Test resolve_edges_to_text uses None for system_prompt when not provided."""
82
+ retriever = GraphSummaryCompletionRetriever()
83
+
84
+ with (
85
+ patch(
86
+ "cognee.modules.retrieval.graph_completion_retriever.GraphCompletionRetriever.resolve_edges_to_text",
87
+ new_callable=AsyncMock,
88
+ return_value="Resolved edges text",
89
+ ),
90
+ patch(
91
+ "cognee.modules.retrieval.graph_summary_completion_retriever.summarize_text",
92
+ new_callable=AsyncMock,
93
+ return_value="Summarized text",
94
+ ) as mock_summarize,
95
+ ):
96
+ await retriever.resolve_edges_to_text([mock_edge])
97
+
98
+ mock_summarize.assert_awaited_once_with(
99
+ "Resolved edges text",
100
+ "summarize_search_results.txt",
101
+ None,
102
+ )
103
+
104
+ @pytest.mark.asyncio
105
+ async def test_resolve_edges_to_text_with_empty_edges(self):
106
+ """Test resolve_edges_to_text handles empty edges list."""
107
+ retriever = GraphSummaryCompletionRetriever()
108
+
109
+ with (
110
+ patch(
111
+ "cognee.modules.retrieval.graph_completion_retriever.GraphCompletionRetriever.resolve_edges_to_text",
112
+ new_callable=AsyncMock,
113
+ return_value="",
114
+ ),
115
+ patch(
116
+ "cognee.modules.retrieval.graph_summary_completion_retriever.summarize_text",
117
+ new_callable=AsyncMock,
118
+ return_value="Empty summary",
119
+ ) as mock_summarize,
120
+ ):
121
+ result = await retriever.resolve_edges_to_text([])
122
+
123
+ assert result == "Empty summary"
124
+ mock_summarize.assert_awaited_once_with(
125
+ "",
126
+ "summarize_search_results.txt",
127
+ None,
128
+ )
129
+
130
+ @pytest.mark.asyncio
131
+ async def test_resolve_edges_to_text_with_multiple_edges(self, mock_edge):
132
+ """Test resolve_edges_to_text handles multiple edges."""
133
+ retriever = GraphSummaryCompletionRetriever()
134
+
135
+ mock_edge2 = MagicMock(spec=Edge)
136
+ mock_edge3 = MagicMock(spec=Edge)
137
+
138
+ with (
139
+ patch(
140
+ "cognee.modules.retrieval.graph_completion_retriever.GraphCompletionRetriever.resolve_edges_to_text",
141
+ new_callable=AsyncMock,
142
+ return_value="Multiple edges resolved text",
143
+ ),
144
+ patch(
145
+ "cognee.modules.retrieval.graph_summary_completion_retriever.summarize_text",
146
+ new_callable=AsyncMock,
147
+ return_value="Multiple edges summarized",
148
+ ) as mock_summarize,
149
+ ):
150
+ result = await retriever.resolve_edges_to_text([mock_edge, mock_edge2, mock_edge3])
151
+
152
+ assert result == "Multiple edges summarized"
153
+ mock_summarize.assert_awaited_once_with(
154
+ "Multiple edges resolved text",
155
+ "summarize_search_results.txt",
156
+ None,
157
+ )