cognee 0.5.1.dev0__py3-none-any.whl → 0.5.2.dev0__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 (238) 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/routers/get_add_router.py +2 -0
  23. cognee/api/v1/cognify/cognify.py +11 -6
  24. cognee/api/v1/cognify/routers/get_cognify_router.py +8 -0
  25. cognee/api/v1/config/config.py +60 -0
  26. cognee/api/v1/datasets/routers/get_datasets_router.py +45 -3
  27. cognee/api/v1/memify/routers/get_memify_router.py +2 -0
  28. cognee/api/v1/search/routers/get_search_router.py +21 -6
  29. cognee/api/v1/search/search.py +25 -5
  30. cognee/api/v1/sync/routers/get_sync_router.py +3 -3
  31. cognee/cli/commands/add_command.py +1 -1
  32. cognee/cli/commands/cognify_command.py +6 -0
  33. cognee/cli/commands/config_command.py +1 -1
  34. cognee/context_global_variables.py +5 -1
  35. cognee/eval_framework/answer_generation/answer_generation_executor.py +7 -8
  36. cognee/infrastructure/databases/cache/cache_db_interface.py +38 -1
  37. cognee/infrastructure/databases/cache/config.py +6 -0
  38. cognee/infrastructure/databases/cache/fscache/FsCacheAdapter.py +21 -0
  39. cognee/infrastructure/databases/cache/get_cache_engine.py +9 -3
  40. cognee/infrastructure/databases/cache/redis/RedisAdapter.py +60 -1
  41. cognee/infrastructure/databases/dataset_database_handler/supported_dataset_database_handlers.py +7 -0
  42. cognee/infrastructure/databases/graph/get_graph_engine.py +29 -1
  43. cognee/infrastructure/databases/graph/neo4j_driver/Neo4jAuraDevDatasetDatabaseHandler.py +62 -27
  44. cognee/infrastructure/databases/hybrid/neptune_analytics/NeptuneAnalyticsAdapter.py +17 -4
  45. cognee/infrastructure/databases/relational/sqlalchemy/SqlAlchemyAdapter.py +2 -1
  46. cognee/infrastructure/databases/vector/chromadb/ChromaDBAdapter.py +2 -0
  47. cognee/infrastructure/databases/vector/config.py +6 -0
  48. cognee/infrastructure/databases/vector/create_vector_engine.py +69 -22
  49. cognee/infrastructure/databases/vector/embeddings/LiteLLMEmbeddingEngine.py +64 -9
  50. cognee/infrastructure/databases/vector/embeddings/OllamaEmbeddingEngine.py +13 -2
  51. cognee/infrastructure/databases/vector/lancedb/LanceDBAdapter.py +16 -3
  52. cognee/infrastructure/databases/vector/models/ScoredResult.py +3 -3
  53. cognee/infrastructure/databases/vector/pgvector/PGVectorAdapter.py +16 -3
  54. cognee/infrastructure/databases/vector/pgvector/PGVectorDatasetDatabaseHandler.py +86 -0
  55. cognee/infrastructure/databases/vector/pgvector/create_db_and_tables.py +81 -2
  56. cognee/infrastructure/databases/vector/vector_db_interface.py +8 -0
  57. cognee/infrastructure/files/utils/get_data_file_path.py +33 -27
  58. cognee/infrastructure/llm/prompts/extract_query_time.txt +1 -1
  59. cognee/infrastructure/llm/prompts/generate_event_entity_prompt.txt +1 -1
  60. cognee/infrastructure/llm/prompts/generate_event_graph_prompt.txt +1 -1
  61. cognee/infrastructure/llm/prompts/generate_graph_prompt.txt +2 -2
  62. cognee/infrastructure/llm/prompts/generate_graph_prompt_guided.txt +1 -1
  63. cognee/infrastructure/llm/prompts/generate_graph_prompt_oneshot.txt +2 -2
  64. cognee/infrastructure/llm/prompts/generate_graph_prompt_simple.txt +1 -1
  65. cognee/infrastructure/llm/prompts/generate_graph_prompt_strict.txt +1 -1
  66. cognee/infrastructure/llm/prompts/search_type_selector_prompt.txt +6 -6
  67. cognee/infrastructure/llm/prompts/test.txt +1 -1
  68. cognee/infrastructure/llm/prompts/translate_content.txt +19 -0
  69. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/get_llm_client.py +24 -0
  70. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/llama_cpp/adapter.py +191 -0
  71. cognee/modules/chunking/models/DocumentChunk.py +0 -1
  72. cognee/modules/cognify/config.py +2 -0
  73. cognee/modules/data/models/Data.py +1 -0
  74. cognee/modules/engine/models/Entity.py +0 -1
  75. cognee/modules/engine/operations/setup.py +6 -0
  76. cognee/modules/graph/cognee_graph/CogneeGraph.py +150 -37
  77. cognee/modules/graph/cognee_graph/CogneeGraphElements.py +48 -2
  78. cognee/modules/graph/utils/__init__.py +1 -0
  79. cognee/modules/graph/utils/get_entity_nodes_from_triplets.py +12 -0
  80. cognee/modules/notebooks/methods/__init__.py +1 -0
  81. cognee/modules/notebooks/methods/create_notebook.py +0 -34
  82. cognee/modules/notebooks/methods/create_tutorial_notebooks.py +191 -0
  83. cognee/modules/notebooks/methods/get_notebooks.py +12 -8
  84. cognee/modules/notebooks/tutorials/cognee-basics/cell-1.md +3 -0
  85. cognee/modules/notebooks/tutorials/cognee-basics/cell-2.md +10 -0
  86. cognee/modules/notebooks/tutorials/cognee-basics/cell-3.md +7 -0
  87. cognee/modules/notebooks/tutorials/cognee-basics/cell-4.py +28 -0
  88. cognee/modules/notebooks/tutorials/cognee-basics/cell-5.py +3 -0
  89. cognee/modules/notebooks/tutorials/cognee-basics/cell-6.py +9 -0
  90. cognee/modules/notebooks/tutorials/cognee-basics/cell-7.py +17 -0
  91. cognee/modules/notebooks/tutorials/cognee-basics/config.json +4 -0
  92. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-1.md +3 -0
  93. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-10.md +3 -0
  94. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-11.md +3 -0
  95. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-12.py +3 -0
  96. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-13.md +7 -0
  97. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-14.py +6 -0
  98. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-15.md +3 -0
  99. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-16.py +7 -0
  100. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-2.md +9 -0
  101. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-3.md +7 -0
  102. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-4.md +9 -0
  103. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-5.md +5 -0
  104. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-6.py +13 -0
  105. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-7.md +3 -0
  106. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-8.md +3 -0
  107. cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-9.py +31 -0
  108. cognee/modules/notebooks/tutorials/python-development-with-cognee/config.json +4 -0
  109. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/copilot_conversations.json +107 -0
  110. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/guido_contributions.json +976 -0
  111. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/my_developer_rules.md +79 -0
  112. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/pep_style_guide.md +74 -0
  113. cognee/modules/notebooks/tutorials/python-development-with-cognee/data/zen_principles.md +74 -0
  114. cognee/modules/retrieval/EntityCompletionRetriever.py +51 -38
  115. cognee/modules/retrieval/__init__.py +0 -1
  116. cognee/modules/retrieval/base_retriever.py +66 -10
  117. cognee/modules/retrieval/chunks_retriever.py +57 -49
  118. cognee/modules/retrieval/coding_rules_retriever.py +12 -5
  119. cognee/modules/retrieval/completion_retriever.py +29 -28
  120. cognee/modules/retrieval/cypher_search_retriever.py +25 -20
  121. cognee/modules/retrieval/graph_completion_context_extension_retriever.py +42 -46
  122. cognee/modules/retrieval/graph_completion_cot_retriever.py +68 -51
  123. cognee/modules/retrieval/graph_completion_retriever.py +78 -63
  124. cognee/modules/retrieval/graph_summary_completion_retriever.py +2 -0
  125. cognee/modules/retrieval/lexical_retriever.py +34 -12
  126. cognee/modules/retrieval/natural_language_retriever.py +18 -15
  127. cognee/modules/retrieval/summaries_retriever.py +51 -34
  128. cognee/modules/retrieval/temporal_retriever.py +59 -49
  129. cognee/modules/retrieval/triplet_retriever.py +31 -32
  130. cognee/modules/retrieval/utils/access_tracking.py +88 -0
  131. cognee/modules/retrieval/utils/brute_force_triplet_search.py +99 -85
  132. cognee/modules/retrieval/utils/node_edge_vector_search.py +174 -0
  133. cognee/modules/search/methods/__init__.py +1 -0
  134. cognee/modules/search/methods/get_retriever_output.py +53 -0
  135. cognee/modules/search/methods/get_search_type_retriever_instance.py +252 -0
  136. cognee/modules/search/methods/search.py +90 -215
  137. cognee/modules/search/models/SearchResultPayload.py +67 -0
  138. cognee/modules/search/types/SearchResult.py +1 -8
  139. cognee/modules/search/types/SearchType.py +1 -2
  140. cognee/modules/search/types/__init__.py +1 -1
  141. cognee/modules/search/utils/__init__.py +1 -2
  142. cognee/modules/search/utils/transform_insights_to_graph.py +2 -2
  143. cognee/modules/search/utils/{transform_context_to_graph.py → transform_triplets_to_graph.py} +2 -2
  144. cognee/modules/users/authentication/default/default_transport.py +11 -1
  145. cognee/modules/users/authentication/get_api_auth_backend.py +2 -1
  146. cognee/modules/users/authentication/get_client_auth_backend.py +2 -1
  147. cognee/modules/users/methods/create_user.py +0 -9
  148. cognee/modules/users/permissions/methods/has_user_management_permission.py +29 -0
  149. cognee/modules/visualization/cognee_network_visualization.py +1 -1
  150. cognee/run_migrations.py +48 -0
  151. cognee/shared/exceptions/__init__.py +1 -3
  152. cognee/shared/exceptions/exceptions.py +11 -1
  153. cognee/shared/usage_logger.py +332 -0
  154. cognee/shared/utils.py +12 -5
  155. cognee/tasks/cleanup/cleanup_unused_data.py +172 -0
  156. cognee/tasks/memify/extract_usage_frequency.py +613 -0
  157. cognee/tasks/summarization/models.py +0 -2
  158. cognee/tasks/temporal_graph/__init__.py +0 -1
  159. cognee/tasks/translation/__init__.py +96 -0
  160. cognee/tasks/translation/config.py +110 -0
  161. cognee/tasks/translation/detect_language.py +190 -0
  162. cognee/tasks/translation/exceptions.py +62 -0
  163. cognee/tasks/translation/models.py +72 -0
  164. cognee/tasks/translation/providers/__init__.py +44 -0
  165. cognee/tasks/translation/providers/azure_provider.py +192 -0
  166. cognee/tasks/translation/providers/base.py +85 -0
  167. cognee/tasks/translation/providers/google_provider.py +158 -0
  168. cognee/tasks/translation/providers/llm_provider.py +143 -0
  169. cognee/tasks/translation/translate_content.py +282 -0
  170. cognee/tasks/web_scraper/default_url_crawler.py +6 -2
  171. cognee/tests/cli_tests/cli_unit_tests/test_cli_commands.py +1 -0
  172. cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py +3 -0
  173. cognee/tests/integration/retrieval/test_brute_force_triplet_search_with_cognify.py +62 -0
  174. cognee/tests/integration/retrieval/test_chunks_retriever.py +115 -16
  175. cognee/tests/integration/retrieval/test_graph_completion_retriever.py +13 -5
  176. cognee/tests/integration/retrieval/test_graph_completion_retriever_context_extension.py +22 -20
  177. cognee/tests/integration/retrieval/test_graph_completion_retriever_cot.py +23 -24
  178. cognee/tests/integration/retrieval/test_rag_completion_retriever.py +70 -5
  179. cognee/tests/integration/retrieval/test_structured_output.py +62 -18
  180. cognee/tests/integration/retrieval/test_summaries_retriever.py +20 -9
  181. cognee/tests/integration/retrieval/test_temporal_retriever.py +38 -8
  182. cognee/tests/integration/retrieval/test_triplet_retriever.py +13 -4
  183. cognee/tests/integration/shared/test_usage_logger_integration.py +255 -0
  184. cognee/tests/tasks/translation/README.md +147 -0
  185. cognee/tests/tasks/translation/__init__.py +1 -0
  186. cognee/tests/tasks/translation/config_test.py +93 -0
  187. cognee/tests/tasks/translation/detect_language_test.py +118 -0
  188. cognee/tests/tasks/translation/providers_test.py +151 -0
  189. cognee/tests/tasks/translation/translate_content_test.py +213 -0
  190. cognee/tests/test_chromadb.py +1 -1
  191. cognee/tests/test_cleanup_unused_data.py +165 -0
  192. cognee/tests/test_delete_by_id.py +6 -6
  193. cognee/tests/test_extract_usage_frequency.py +308 -0
  194. cognee/tests/test_kuzu.py +17 -7
  195. cognee/tests/test_lancedb.py +3 -1
  196. cognee/tests/test_library.py +1 -1
  197. cognee/tests/test_neo4j.py +17 -7
  198. cognee/tests/test_neptune_analytics_vector.py +3 -1
  199. cognee/tests/test_permissions.py +172 -187
  200. cognee/tests/test_pgvector.py +3 -1
  201. cognee/tests/test_relational_db_migration.py +15 -1
  202. cognee/tests/test_remote_kuzu.py +3 -1
  203. cognee/tests/test_s3_file_storage.py +1 -1
  204. cognee/tests/test_search_db.py +97 -110
  205. cognee/tests/test_usage_logger_e2e.py +268 -0
  206. cognee/tests/unit/api/test_get_raw_data_endpoint.py +206 -0
  207. cognee/tests/unit/eval_framework/answer_generation_test.py +4 -3
  208. cognee/tests/unit/infrastructure/databases/cache/test_cache_config.py +2 -0
  209. cognee/tests/unit/modules/graph/cognee_graph_elements_test.py +42 -2
  210. cognee/tests/unit/modules/graph/cognee_graph_test.py +329 -31
  211. cognee/tests/unit/modules/retrieval/chunks_retriever_test.py +31 -59
  212. cognee/tests/unit/modules/retrieval/graph_completion_retriever_context_extension_test.py +70 -33
  213. cognee/tests/unit/modules/retrieval/graph_completion_retriever_cot_test.py +72 -52
  214. cognee/tests/unit/modules/retrieval/graph_completion_retriever_test.py +27 -33
  215. cognee/tests/unit/modules/retrieval/rag_completion_retriever_test.py +28 -15
  216. cognee/tests/unit/modules/retrieval/summaries_retriever_test.py +37 -42
  217. cognee/tests/unit/modules/retrieval/temporal_retriever_test.py +48 -64
  218. cognee/tests/unit/modules/retrieval/test_brute_force_triplet_search.py +263 -24
  219. cognee/tests/unit/modules/retrieval/test_node_edge_vector_search.py +273 -0
  220. cognee/tests/unit/modules/retrieval/triplet_retriever_test.py +30 -16
  221. cognee/tests/unit/modules/search/test_get_search_type_retriever_instance.py +125 -0
  222. cognee/tests/unit/modules/search/test_search.py +176 -0
  223. cognee/tests/unit/modules/search/test_search_prepare_search_result_contract.py +190 -0
  224. cognee/tests/unit/modules/users/test_tutorial_notebook_creation.py +511 -297
  225. cognee/tests/unit/shared/test_usage_logger.py +241 -0
  226. cognee/tests/unit/users/permissions/test_has_user_management_permission.py +46 -0
  227. {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/METADATA +17 -10
  228. {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/RECORD +232 -144
  229. cognee/api/.env.example +0 -5
  230. cognee/modules/retrieval/base_graph_retriever.py +0 -24
  231. cognee/modules/search/methods/get_search_type_tools.py +0 -223
  232. cognee/modules/search/methods/no_access_control_search.py +0 -62
  233. cognee/modules/search/utils/prepare_search_result.py +0 -63
  234. cognee/tests/test_feedback_enrichment.py +0 -174
  235. {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/WHEEL +0 -0
  236. {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/entry_points.txt +0 -0
  237. {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/licenses/LICENSE +0 -0
  238. {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dev0.dist-info}/licenses/NOTICE.md +0 -0
@@ -6,6 +6,7 @@ from cognee.modules.retrieval.utils.brute_force_triplet_search import (
6
6
  get_memory_fragment,
7
7
  format_triplets,
8
8
  )
9
+ from cognee.modules.engine.utils.generate_edge_id import generate_edge_id
9
10
  from cognee.modules.graph.cognee_graph.CogneeGraph import CogneeGraph
10
11
  from cognee.modules.graph.exceptions.exceptions import EntityNotFoundError
11
12
  from cognee.infrastructure.databases.vector.exceptions.exceptions import CollectionNotFoundError
@@ -30,7 +31,7 @@ async def test_brute_force_triplet_search_empty_query():
30
31
  @pytest.mark.asyncio
31
32
  async def test_brute_force_triplet_search_none_query():
32
33
  """Test that None query raises ValueError."""
33
- with pytest.raises(ValueError, match="The query must be a non-empty string."):
34
+ with pytest.raises(ValueError, match="Must provide either 'query' or 'query_batch'."):
34
35
  await brute_force_triplet_search(query=None)
35
36
 
36
37
 
@@ -57,7 +58,7 @@ async def test_brute_force_triplet_search_wide_search_limit_global_search():
57
58
  mock_vector_engine.search = AsyncMock(return_value=[])
58
59
 
59
60
  with patch(
60
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
61
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
61
62
  return_value=mock_vector_engine,
62
63
  ):
63
64
  await brute_force_triplet_search(
@@ -79,7 +80,7 @@ async def test_brute_force_triplet_search_wide_search_limit_filtered_search():
79
80
  mock_vector_engine.search = AsyncMock(return_value=[])
80
81
 
81
82
  with patch(
82
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
83
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
83
84
  return_value=mock_vector_engine,
84
85
  ):
85
86
  await brute_force_triplet_search(
@@ -101,7 +102,7 @@ async def test_brute_force_triplet_search_wide_search_default():
101
102
  mock_vector_engine.search = AsyncMock(return_value=[])
102
103
 
103
104
  with patch(
104
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
105
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
105
106
  return_value=mock_vector_engine,
106
107
  ):
107
108
  await brute_force_triplet_search(query="test", node_name=None)
@@ -119,7 +120,7 @@ async def test_brute_force_triplet_search_default_collections():
119
120
  mock_vector_engine.search = AsyncMock(return_value=[])
120
121
 
121
122
  with patch(
122
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
123
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
123
124
  return_value=mock_vector_engine,
124
125
  ):
125
126
  await brute_force_triplet_search(query="test")
@@ -149,7 +150,7 @@ async def test_brute_force_triplet_search_custom_collections():
149
150
  custom_collections = ["CustomCol1", "CustomCol2"]
150
151
 
151
152
  with patch(
152
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
153
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
153
154
  return_value=mock_vector_engine,
154
155
  ):
155
156
  await brute_force_triplet_search(query="test", collections=custom_collections)
@@ -171,7 +172,7 @@ async def test_brute_force_triplet_search_always_includes_edge_collection():
171
172
  collections_without_edge = ["Entity_name", "TextSummary_text"]
172
173
 
173
174
  with patch(
174
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
175
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
175
176
  return_value=mock_vector_engine,
176
177
  ):
177
178
  await brute_force_triplet_search(query="test", collections=collections_without_edge)
@@ -194,7 +195,7 @@ async def test_brute_force_triplet_search_all_collections_empty():
194
195
  mock_vector_engine.search = AsyncMock(return_value=[])
195
196
 
196
197
  with patch(
197
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
198
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
198
199
  return_value=mock_vector_engine,
199
200
  ):
200
201
  results = await brute_force_triplet_search(query="test")
@@ -216,7 +217,7 @@ async def test_brute_force_triplet_search_embeds_query():
216
217
  mock_vector_engine.search = AsyncMock(return_value=[])
217
218
 
218
219
  with patch(
219
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
220
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
220
221
  return_value=mock_vector_engine,
221
222
  ):
222
223
  await brute_force_triplet_search(query=query_text)
@@ -249,7 +250,7 @@ async def test_brute_force_triplet_search_extracts_node_ids_global_search():
249
250
 
250
251
  with (
251
252
  patch(
252
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
253
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
253
254
  return_value=mock_vector_engine,
254
255
  ),
255
256
  patch(
@@ -279,7 +280,7 @@ async def test_brute_force_triplet_search_reuses_provided_fragment():
279
280
 
280
281
  with (
281
282
  patch(
282
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
283
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
283
284
  return_value=mock_vector_engine,
284
285
  ),
285
286
  patch(
@@ -311,7 +312,7 @@ async def test_brute_force_triplet_search_creates_fragment_when_not_provided():
311
312
 
312
313
  with (
313
314
  patch(
314
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
315
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
315
316
  return_value=mock_vector_engine,
316
317
  ),
317
318
  patch(
@@ -340,7 +341,7 @@ async def test_brute_force_triplet_search_passes_top_k_to_importance_calculation
340
341
 
341
342
  with (
342
343
  patch(
343
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
344
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
344
345
  return_value=mock_vector_engine,
345
346
  ),
346
347
  patch(
@@ -351,7 +352,9 @@ async def test_brute_force_triplet_search_passes_top_k_to_importance_calculation
351
352
  custom_top_k = 15
352
353
  await brute_force_triplet_search(query="test", top_k=custom_top_k, node_name=["n"])
353
354
 
354
- mock_fragment.calculate_top_triplet_importances.assert_called_once_with(k=custom_top_k)
355
+ mock_fragment.calculate_top_triplet_importances.assert_called_once_with(
356
+ k=custom_top_k, query_list_length=None
357
+ )
355
358
 
356
359
 
357
360
  @pytest.mark.asyncio
@@ -430,7 +433,7 @@ async def test_brute_force_triplet_search_deduplicates_node_ids():
430
433
 
431
434
  with (
432
435
  patch(
433
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
436
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
434
437
  return_value=mock_vector_engine,
435
438
  ),
436
439
  patch(
@@ -471,7 +474,7 @@ async def test_brute_force_triplet_search_excludes_edge_collection():
471
474
 
472
475
  with (
473
476
  patch(
474
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
477
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
475
478
  return_value=mock_vector_engine,
476
479
  ),
477
480
  patch(
@@ -523,7 +526,7 @@ async def test_brute_force_triplet_search_skips_nodes_without_ids():
523
526
 
524
527
  with (
525
528
  patch(
526
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
529
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
527
530
  return_value=mock_vector_engine,
528
531
  ),
529
532
  patch(
@@ -564,7 +567,7 @@ async def test_brute_force_triplet_search_handles_tuple_results():
564
567
 
565
568
  with (
566
569
  patch(
567
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
570
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
568
571
  return_value=mock_vector_engine,
569
572
  ),
570
573
  patch(
@@ -606,7 +609,7 @@ async def test_brute_force_triplet_search_mixed_empty_collections():
606
609
 
607
610
  with (
608
611
  patch(
609
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
612
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
610
613
  return_value=mock_vector_engine,
611
614
  ),
612
615
  patch(
@@ -689,7 +692,7 @@ async def test_brute_force_triplet_search_vector_engine_init_error():
689
692
  """Test brute_force_triplet_search handles vector engine initialization error (lines 145-147)."""
690
693
  with (
691
694
  patch(
692
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine"
695
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine"
693
696
  ) as mock_get_vector_engine,
694
697
  ):
695
698
  mock_get_vector_engine.side_effect = Exception("Initialization error")
@@ -716,7 +719,7 @@ async def test_brute_force_triplet_search_collection_not_found_error():
716
719
 
717
720
  with (
718
721
  patch(
719
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
722
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
720
723
  return_value=mock_vector_engine,
721
724
  ),
722
725
  patch(
@@ -743,7 +746,7 @@ async def test_brute_force_triplet_search_generic_exception():
743
746
 
744
747
  with (
745
748
  patch(
746
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
749
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
747
750
  return_value=mock_vector_engine,
748
751
  ),
749
752
  ):
@@ -769,7 +772,7 @@ async def test_brute_force_triplet_search_with_node_name_sets_relevant_ids_to_no
769
772
 
770
773
  with (
771
774
  patch(
772
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
775
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
773
776
  return_value=mock_vector_engine,
774
777
  ),
775
778
  patch(
@@ -804,7 +807,7 @@ async def test_brute_force_triplet_search_collection_not_found_at_top_level():
804
807
 
805
808
  with (
806
809
  patch(
807
- "cognee.modules.retrieval.utils.brute_force_triplet_search.get_vector_engine",
810
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
808
811
  return_value=mock_vector_engine,
809
812
  ),
810
813
  patch(
@@ -815,3 +818,239 @@ async def test_brute_force_triplet_search_collection_not_found_at_top_level():
815
818
  result = await brute_force_triplet_search(query="test query")
816
819
 
817
820
  assert result == []
821
+
822
+
823
+ @pytest.mark.asyncio
824
+ async def test_brute_force_triplet_search_single_query_regression():
825
+ """Test that single-query mode maintains legacy behavior (flat list, ID filtering)."""
826
+ mock_vector_engine = AsyncMock()
827
+ mock_vector_engine.embedding_engine = AsyncMock()
828
+ mock_vector_engine.embedding_engine.embed_text = AsyncMock(return_value=[[0.1, 0.2, 0.3]])
829
+ mock_vector_engine.search = AsyncMock(return_value=[MockScoredResult("node1", 0.95)])
830
+
831
+ mock_fragment = AsyncMock(
832
+ map_vector_distances_to_graph_nodes=AsyncMock(),
833
+ map_vector_distances_to_graph_edges=AsyncMock(),
834
+ calculate_top_triplet_importances=AsyncMock(return_value=[]),
835
+ )
836
+
837
+ with (
838
+ patch(
839
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
840
+ return_value=mock_vector_engine,
841
+ ),
842
+ patch(
843
+ "cognee.modules.retrieval.utils.brute_force_triplet_search.get_memory_fragment",
844
+ return_value=mock_fragment,
845
+ ) as mock_get_fragment,
846
+ ):
847
+ result = await brute_force_triplet_search(
848
+ query="q1", query_batch=None, wide_search_top_k=10, node_name=None
849
+ )
850
+
851
+ assert isinstance(result, list)
852
+ assert not (result and isinstance(result[0], list))
853
+ mock_get_fragment.assert_called_once()
854
+ call_kwargs = mock_get_fragment.call_args[1]
855
+ assert call_kwargs["relevant_ids_to_filter"] is not None
856
+
857
+
858
+ @pytest.mark.asyncio
859
+ async def test_brute_force_triplet_search_batch_wiring_happy_path():
860
+ """Test that batch mode returns list-of-lists and skips ID filtering."""
861
+ mock_vector_engine = AsyncMock()
862
+ mock_vector_engine.embedding_engine = AsyncMock()
863
+ mock_vector_engine.batch_search = AsyncMock(
864
+ return_value=[
865
+ [MockScoredResult("node1", 0.95)],
866
+ [MockScoredResult("node2", 0.87)],
867
+ ]
868
+ )
869
+
870
+ mock_fragment = AsyncMock(
871
+ map_vector_distances_to_graph_nodes=AsyncMock(),
872
+ map_vector_distances_to_graph_edges=AsyncMock(),
873
+ calculate_top_triplet_importances=AsyncMock(return_value=[[], []]),
874
+ )
875
+
876
+ with (
877
+ patch(
878
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
879
+ return_value=mock_vector_engine,
880
+ ),
881
+ patch(
882
+ "cognee.modules.retrieval.utils.brute_force_triplet_search.get_memory_fragment",
883
+ return_value=mock_fragment,
884
+ ) as mock_get_fragment,
885
+ ):
886
+ result = await brute_force_triplet_search(query_batch=["q1", "q2"])
887
+
888
+ assert isinstance(result, list)
889
+ assert len(result) == 2
890
+ assert isinstance(result[0], list)
891
+ assert isinstance(result[1], list)
892
+ mock_get_fragment.assert_called_once()
893
+ call_kwargs = mock_get_fragment.call_args[1]
894
+ assert call_kwargs["relevant_ids_to_filter"] is None
895
+
896
+
897
+ @pytest.mark.asyncio
898
+ async def test_brute_force_triplet_search_shape_propagation_to_graph():
899
+ """Test that query_list_length is passed through to graph mapping methods."""
900
+ mock_vector_engine = AsyncMock()
901
+ mock_vector_engine.embedding_engine = AsyncMock()
902
+ mock_vector_engine.batch_search = AsyncMock(
903
+ return_value=[
904
+ [MockScoredResult("node1", 0.95)],
905
+ [MockScoredResult("node2", 0.87)],
906
+ ]
907
+ )
908
+
909
+ mock_fragment = AsyncMock(
910
+ map_vector_distances_to_graph_nodes=AsyncMock(),
911
+ map_vector_distances_to_graph_edges=AsyncMock(),
912
+ calculate_top_triplet_importances=AsyncMock(return_value=[[], []]),
913
+ )
914
+
915
+ with (
916
+ patch(
917
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
918
+ return_value=mock_vector_engine,
919
+ ),
920
+ patch(
921
+ "cognee.modules.retrieval.utils.brute_force_triplet_search.get_memory_fragment",
922
+ return_value=mock_fragment,
923
+ ),
924
+ ):
925
+ await brute_force_triplet_search(query_batch=["q1", "q2"])
926
+
927
+ mock_fragment.map_vector_distances_to_graph_nodes.assert_called_once()
928
+ node_call_kwargs = mock_fragment.map_vector_distances_to_graph_nodes.call_args[1]
929
+ assert "query_list_length" in node_call_kwargs
930
+ assert node_call_kwargs["query_list_length"] == 2
931
+
932
+ mock_fragment.map_vector_distances_to_graph_edges.assert_called_once()
933
+ edge_call_kwargs = mock_fragment.map_vector_distances_to_graph_edges.call_args[1]
934
+ assert "query_list_length" in edge_call_kwargs
935
+ assert edge_call_kwargs["query_list_length"] == 2
936
+
937
+ mock_fragment.calculate_top_triplet_importances.assert_called_once()
938
+ importance_call_kwargs = mock_fragment.calculate_top_triplet_importances.call_args[1]
939
+ assert "query_list_length" in importance_call_kwargs
940
+ assert importance_call_kwargs["query_list_length"] == 2
941
+
942
+
943
+ @pytest.mark.asyncio
944
+ async def test_brute_force_triplet_search_batch_path_comprehensive():
945
+ """Test batch mode: returns list-of-lists, skips ID filtering, passes None for wide_search_limit."""
946
+ mock_vector_engine = AsyncMock()
947
+ mock_vector_engine.embedding_engine = AsyncMock()
948
+
949
+ def batch_search_side_effect(*args, **kwargs):
950
+ collection_name = kwargs.get("collection_name")
951
+ if collection_name == "Entity_name":
952
+ return [
953
+ [MockScoredResult("node1", 0.95)],
954
+ [MockScoredResult("node2", 0.87)],
955
+ ]
956
+ elif collection_name == "EdgeType_relationship_name":
957
+ return [
958
+ [MockScoredResult("edge1", 0.92)],
959
+ [MockScoredResult("edge2", 0.88)],
960
+ ]
961
+ return [[], []]
962
+
963
+ mock_vector_engine.batch_search = AsyncMock(side_effect=batch_search_side_effect)
964
+
965
+ mock_fragment = AsyncMock(
966
+ map_vector_distances_to_graph_nodes=AsyncMock(),
967
+ map_vector_distances_to_graph_edges=AsyncMock(),
968
+ calculate_top_triplet_importances=AsyncMock(return_value=[[], []]),
969
+ )
970
+
971
+ with (
972
+ patch(
973
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
974
+ return_value=mock_vector_engine,
975
+ ),
976
+ patch(
977
+ "cognee.modules.retrieval.utils.brute_force_triplet_search.get_memory_fragment",
978
+ return_value=mock_fragment,
979
+ ) as mock_get_fragment,
980
+ ):
981
+ result = await brute_force_triplet_search(
982
+ query_batch=["q1", "q2"], collections=["Entity_name", "EdgeType_relationship_name"]
983
+ )
984
+
985
+ assert isinstance(result, list)
986
+ assert len(result) == 2
987
+ assert isinstance(result[0], list)
988
+ assert isinstance(result[1], list)
989
+
990
+ mock_get_fragment.assert_called_once()
991
+ fragment_call_kwargs = mock_get_fragment.call_args[1]
992
+ assert fragment_call_kwargs["relevant_ids_to_filter"] is None
993
+
994
+ batch_search_calls = mock_vector_engine.batch_search.call_args_list
995
+ assert len(batch_search_calls) > 0
996
+ for call in batch_search_calls:
997
+ assert call[1]["limit"] is None
998
+
999
+
1000
+ @pytest.mark.asyncio
1001
+ async def test_brute_force_triplet_search_batch_error_fallback():
1002
+ """Test that CollectionNotFoundError in batch mode returns [[], []] matching batch length."""
1003
+ mock_vector_engine = AsyncMock()
1004
+ mock_vector_engine.embedding_engine = AsyncMock()
1005
+ mock_vector_engine.batch_search = AsyncMock(
1006
+ side_effect=CollectionNotFoundError("Collection not found")
1007
+ )
1008
+
1009
+ with patch(
1010
+ "cognee.modules.retrieval.utils.node_edge_vector_search.get_vector_engine",
1011
+ return_value=mock_vector_engine,
1012
+ ):
1013
+ result = await brute_force_triplet_search(query_batch=["q1", "q2"])
1014
+
1015
+ assert result == [[], []]
1016
+ assert len(result) == 2
1017
+
1018
+
1019
+ @pytest.mark.asyncio
1020
+ async def test_cognee_graph_mapping_batch_shapes():
1021
+ """Test that CogneeGraph mapping methods accept list-of-lists with query_list_length set."""
1022
+ from cognee.modules.graph.cognee_graph.CogneeGraphElements import Node, Edge
1023
+
1024
+ graph = CogneeGraph()
1025
+ node1 = Node("node1", {"name": "Node1"})
1026
+ node2 = Node("node2", {"name": "Node2"})
1027
+ graph.add_node(node1)
1028
+ graph.add_node(node2)
1029
+
1030
+ edge = Edge(node1, node2, attributes={"edge_text": "relates_to"})
1031
+ graph.add_edge(edge)
1032
+
1033
+ node_distances_batch = {
1034
+ "Entity_name": [
1035
+ [MockScoredResult("node1", 0.95)],
1036
+ [MockScoredResult("node2", 0.87)],
1037
+ ]
1038
+ }
1039
+
1040
+ edge_1_text = "relates_to"
1041
+ edge_2_text = "relates_to"
1042
+ edge_distances_batch = [
1043
+ [MockScoredResult(generate_edge_id(edge_1_text), 0.92, payload={"text": edge_1_text})],
1044
+ [MockScoredResult(generate_edge_id(edge_2_text), 0.88, payload={"text": edge_2_text})],
1045
+ ]
1046
+
1047
+ await graph.map_vector_distances_to_graph_nodes(
1048
+ node_distances=node_distances_batch, query_list_length=2
1049
+ )
1050
+ await graph.map_vector_distances_to_graph_edges(
1051
+ edge_distances=edge_distances_batch, query_list_length=2
1052
+ )
1053
+
1054
+ assert node1.attributes.get("vector_distance") == [0.95, 3.5]
1055
+ assert node2.attributes.get("vector_distance") == [3.5, 0.87]
1056
+ assert edge.attributes.get("vector_distance") == [0.92, 0.88]