graphiti-core 0.20.4__tar.gz → 0.21.0rc1__tar.gz

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.

Potentially problematic release.


This version of graphiti-core might be problematic. Click here for more details.

Files changed (189) hide show
  1. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/PKG-INFO +4 -1
  2. graphiti_core-0.21.0rc1/graphiti_core/driver/driver.py +259 -0
  3. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/driver/falkordb_driver.py +1 -0
  4. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/driver/kuzu_driver.py +1 -0
  5. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/driver/neo4j_driver.py +48 -2
  6. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/driver/neptune_driver.py +25 -44
  7. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/edges.py +18 -3
  8. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/embedder/client.py +2 -1
  9. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/models/edges/edge_db_queries.py +36 -16
  10. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/models/nodes/node_db_queries.py +30 -10
  11. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/nodes.py +26 -18
  12. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/search/search_filters.py +45 -0
  13. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/search/search_utils.py +200 -56
  14. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/bulk_utils.py +15 -2
  15. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/maintenance/graph_data_operations.py +7 -5
  16. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/pyproject.toml +2 -1
  17. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/signatures/version1/cla.json +16 -0
  18. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/uv.lock +8 -2
  19. graphiti_core-0.20.4/graphiti_core/driver/driver.py +0 -89
  20. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.env.example +0 -0
  21. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  22. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/dependabot.yml +0 -0
  23. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/pull_request_template.md +0 -0
  24. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/secret_scanning.yml +0 -0
  25. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/ai-moderator.yml +0 -0
  26. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/cla.yml +0 -0
  27. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/claude-code-review.yml +0 -0
  28. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/claude.yml +0 -0
  29. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/codeql.yml +0 -0
  30. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/lint.yml +0 -0
  31. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/mcp-server-docker.yml +0 -0
  32. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/release-graphiti-core.yml +0 -0
  33. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/typecheck.yml +0 -0
  34. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.github/workflows/unit_tests.yml +0 -0
  35. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/.gitignore +0 -0
  36. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/CLAUDE.md +0 -0
  37. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/CODE_OF_CONDUCT.md +0 -0
  38. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/CONTRIBUTING.md +0 -0
  39. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/Dockerfile +0 -0
  40. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/LICENSE +0 -0
  41. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/Makefile +0 -0
  42. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/README.md +0 -0
  43. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/SECURITY.md +0 -0
  44. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/Zep-CLA.md +0 -0
  45. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/conftest.py +0 -0
  46. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/depot.json +0 -0
  47. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/docker-compose.test.yml +0 -0
  48. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/docker-compose.yml +0 -0
  49. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/ellipsis.yaml +0 -0
  50. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/data/manybirds_products.json +0 -0
  51. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/ecommerce/runner.ipynb +0 -0
  52. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/ecommerce/runner.py +0 -0
  53. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/langgraph-agent/agent.ipynb +0 -0
  54. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/langgraph-agent/tinybirds-jess.png +0 -0
  55. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/podcast/podcast_runner.py +0 -0
  56. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/podcast/podcast_transcript.txt +0 -0
  57. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/podcast/transcript_parser.py +0 -0
  58. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/quickstart/README.md +0 -0
  59. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/quickstart/quickstart_falkordb.py +0 -0
  60. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/quickstart/quickstart_neo4j.py +0 -0
  61. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/quickstart/quickstart_neptune.py +0 -0
  62. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/quickstart/requirements.txt +0 -0
  63. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/wizard_of_oz/parser.py +0 -0
  64. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/wizard_of_oz/runner.py +0 -0
  65. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/examples/wizard_of_oz/woo.txt +0 -0
  66. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/__init__.py +0 -0
  67. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/cross_encoder/__init__.py +0 -0
  68. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/cross_encoder/bge_reranker_client.py +0 -0
  69. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/cross_encoder/client.py +0 -0
  70. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/cross_encoder/gemini_reranker_client.py +0 -0
  71. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/cross_encoder/openai_reranker_client.py +0 -0
  72. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/driver/__init__.py +0 -0
  73. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/embedder/__init__.py +0 -0
  74. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/embedder/azure_openai.py +0 -0
  75. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/embedder/gemini.py +0 -0
  76. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/embedder/openai.py +0 -0
  77. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/embedder/voyage.py +0 -0
  78. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/errors.py +0 -0
  79. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/graph_queries.py +0 -0
  80. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/graphiti.py +0 -0
  81. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/graphiti_types.py +0 -0
  82. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/helpers.py +0 -0
  83. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/__init__.py +0 -0
  84. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/anthropic_client.py +0 -0
  85. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/azure_openai_client.py +0 -0
  86. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/client.py +0 -0
  87. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/config.py +0 -0
  88. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/errors.py +0 -0
  89. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/gemini_client.py +0 -0
  90. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/groq_client.py +0 -0
  91. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/openai_base_client.py +0 -0
  92. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/openai_client.py +0 -0
  93. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/openai_generic_client.py +0 -0
  94. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/llm_client/utils.py +0 -0
  95. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/migrations/__init__.py +0 -0
  96. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/models/__init__.py +0 -0
  97. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/models/edges/__init__.py +0 -0
  98. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/models/nodes/__init__.py +0 -0
  99. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/__init__.py +0 -0
  100. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/dedupe_edges.py +0 -0
  101. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/dedupe_nodes.py +0 -0
  102. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/eval.py +0 -0
  103. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/extract_edge_dates.py +0 -0
  104. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/extract_edges.py +0 -0
  105. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/extract_nodes.py +0 -0
  106. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/invalidate_edges.py +0 -0
  107. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/lib.py +0 -0
  108. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/models.py +0 -0
  109. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/prompt_helpers.py +0 -0
  110. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/prompts/summarize_nodes.py +0 -0
  111. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/py.typed +0 -0
  112. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/search/__init__.py +0 -0
  113. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/search/search.py +0 -0
  114. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/search/search_config.py +0 -0
  115. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/search/search_config_recipes.py +0 -0
  116. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/search/search_helpers.py +0 -0
  117. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/telemetry/__init__.py +0 -0
  118. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/telemetry/telemetry.py +0 -0
  119. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/__init__.py +0 -0
  120. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/datetime_utils.py +0 -0
  121. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/maintenance/__init__.py +0 -0
  122. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/maintenance/community_operations.py +0 -0
  123. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/maintenance/edge_operations.py +0 -0
  124. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/maintenance/node_operations.py +0 -0
  125. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/maintenance/temporal_operations.py +0 -0
  126. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/maintenance/utils.py +0 -0
  127. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/graphiti_core/utils/ontology_utils/entity_types_utils.py +0 -0
  128. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/images/arxiv-screenshot.png +0 -0
  129. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/images/graphiti-graph-intro.gif +0 -0
  130. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/images/graphiti-intro-slides-stock-2.gif +0 -0
  131. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/images/simple_graph.svg +0 -0
  132. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/.env.example +0 -0
  133. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/.python-version +0 -0
  134. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/Dockerfile +0 -0
  135. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/README.md +0 -0
  136. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/cursor_rules.md +0 -0
  137. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/docker-compose.yml +0 -0
  138. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/graphiti_mcp_server.py +0 -0
  139. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/mcp_config_sse_example.json +0 -0
  140. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/mcp_config_stdio_example.json +0 -0
  141. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/pyproject.toml +0 -0
  142. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/mcp_server/uv.lock +0 -0
  143. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/poetry.lock +0 -0
  144. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/py.typed +0 -0
  145. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/pytest.ini +0 -0
  146. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/.env.example +0 -0
  147. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/Makefile +0 -0
  148. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/README.md +0 -0
  149. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/__init__.py +0 -0
  150. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/config.py +0 -0
  151. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/dto/__init__.py +0 -0
  152. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/dto/common.py +0 -0
  153. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/dto/ingest.py +0 -0
  154. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/dto/retrieve.py +0 -0
  155. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/main.py +0 -0
  156. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/routers/__init__.py +0 -0
  157. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/routers/ingest.py +0 -0
  158. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/routers/retrieve.py +0 -0
  159. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/graph_service/zep_graphiti.py +0 -0
  160. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/pyproject.toml +0 -0
  161. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/server/uv.lock +0 -0
  162. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/cross_encoder/test_bge_reranker_client.py +0 -0
  163. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/cross_encoder/test_gemini_reranker_client.py +0 -0
  164. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/driver/__init__.py +0 -0
  165. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/driver/test_falkordb_driver.py +0 -0
  166. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/embedder/embedder_fixtures.py +0 -0
  167. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/embedder/test_gemini.py +0 -0
  168. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/embedder/test_openai.py +0 -0
  169. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/embedder/test_voyage.py +0 -0
  170. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/evals/data/longmemeval_data/README.md +0 -0
  171. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/evals/data/longmemeval_data/longmemeval_oracle.json +0 -0
  172. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/evals/eval_cli.py +0 -0
  173. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/evals/eval_e2e_graph_building.py +0 -0
  174. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/evals/pytest.ini +0 -0
  175. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/evals/utils.py +0 -0
  176. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/helpers_test.py +0 -0
  177. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/llm_client/test_anthropic_client.py +0 -0
  178. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/llm_client/test_anthropic_client_int.py +0 -0
  179. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/llm_client/test_client.py +0 -0
  180. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/llm_client/test_errors.py +0 -0
  181. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/llm_client/test_gemini_client.py +0 -0
  182. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/test_edge_int.py +0 -0
  183. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/test_entity_exclusion_int.py +0 -0
  184. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/test_graphiti_int.py +0 -0
  185. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/test_graphiti_mock.py +0 -0
  186. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/test_node_int.py +0 -0
  187. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/utils/maintenance/test_edge_operations.py +0 -0
  188. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/utils/maintenance/test_temporal_operations_int.py +0 -0
  189. {graphiti_core-0.20.4 → graphiti_core-0.21.0rc1}/tests/utils/search/search_utils_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphiti-core
3
- Version: 0.20.4
3
+ Version: 0.21.0rc1
4
4
  Summary: A temporal graph building library
5
5
  Project-URL: Homepage, https://help.getzep.com/graphiti/graphiti/overview
6
6
  Project-URL: Repository, https://github.com/getzep/graphiti
@@ -47,6 +47,9 @@ Provides-Extra: groq
47
47
  Requires-Dist: groq>=0.2.0; extra == 'groq'
48
48
  Provides-Extra: kuzu
49
49
  Requires-Dist: kuzu>=0.11.2; extra == 'kuzu'
50
+ Provides-Extra: neo4j-opensearch
51
+ Requires-Dist: boto3>=1.39.16; extra == 'neo4j-opensearch'
52
+ Requires-Dist: opensearch-py>=3.0.0; extra == 'neo4j-opensearch'
50
53
  Provides-Extra: neptune
51
54
  Requires-Dist: boto3>=1.39.16; extra == 'neptune'
52
55
  Requires-Dist: langchain-aws>=0.2.29; extra == 'neptune'
@@ -0,0 +1,259 @@
1
+ """
2
+ Copyright 2024, Zep Software, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ """
16
+
17
+ import asyncio
18
+ import copy
19
+ import logging
20
+ from abc import ABC, abstractmethod
21
+ from collections.abc import Coroutine
22
+ from datetime import datetime
23
+ from enum import Enum
24
+ from typing import Any
25
+
26
+ from graphiti_core.embedder.client import EMBEDDING_DIM
27
+
28
+ try:
29
+ from opensearchpy import OpenSearch, helpers
30
+
31
+ _HAS_OPENSEARCH = True
32
+ except ImportError:
33
+ OpenSearch = None
34
+ helpers = None
35
+ _HAS_OPENSEARCH = False
36
+
37
+ logger = logging.getLogger(__name__)
38
+
39
+ DEFAULT_SIZE = 10
40
+
41
+
42
+ class GraphProvider(Enum):
43
+ NEO4J = 'neo4j'
44
+ FALKORDB = 'falkordb'
45
+ KUZU = 'kuzu'
46
+ NEPTUNE = 'neptune'
47
+
48
+
49
+ aoss_indices = [
50
+ {
51
+ 'index_name': 'entities',
52
+ 'body': {
53
+ 'mappings': {
54
+ 'properties': {
55
+ 'uuid': {'type': 'keyword'},
56
+ 'name': {'type': 'text'},
57
+ 'summary': {'type': 'text'},
58
+ 'group_id': {'type': 'text'},
59
+ 'created_at': {'type': 'date', 'format': "yyyy-MM-dd'T'HH:mm:ss.SSSZ"},
60
+ 'name_embedding': {
61
+ 'type': 'knn_vector',
62
+ 'dims': EMBEDDING_DIM,
63
+ 'index': True,
64
+ 'similarity': 'cosine',
65
+ 'method': {
66
+ 'engine': 'faiss',
67
+ 'space_type': 'cosinesimil',
68
+ 'name': 'hnsw',
69
+ 'parameters': {'ef_construction': 128, 'm': 16},
70
+ },
71
+ },
72
+ }
73
+ }
74
+ },
75
+ },
76
+ {
77
+ 'index_name': 'communities',
78
+ 'body': {
79
+ 'mappings': {
80
+ 'properties': {
81
+ 'uuid': {'type': 'keyword'},
82
+ 'name': {'type': 'text'},
83
+ 'group_id': {'type': 'text'},
84
+ }
85
+ }
86
+ },
87
+ },
88
+ {
89
+ 'index_name': 'episodes',
90
+ 'body': {
91
+ 'mappings': {
92
+ 'properties': {
93
+ 'uuid': {'type': 'keyword'},
94
+ 'content': {'type': 'text'},
95
+ 'source': {'type': 'text'},
96
+ 'source_description': {'type': 'text'},
97
+ 'group_id': {'type': 'text'},
98
+ 'created_at': {'type': 'date', 'format': "yyyy-MM-dd'T'HH:mm:ss.SSSZ"},
99
+ 'valid_at': {'type': 'date', 'format': "yyyy-MM-dd'T'HH:mm:ss.SSSZ"},
100
+ }
101
+ }
102
+ },
103
+ },
104
+ {
105
+ 'index_name': 'entity_edges',
106
+ 'body': {
107
+ 'mappings': {
108
+ 'properties': {
109
+ 'uuid': {'type': 'keyword'},
110
+ 'name': {'type': 'text'},
111
+ 'fact': {'type': 'text'},
112
+ 'group_id': {'type': 'text'},
113
+ 'created_at': {'type': 'date', 'format': "yyyy-MM-dd'T'HH:mm:ss.SSSZ"},
114
+ 'valid_at': {'type': 'date', 'format': "yyyy-MM-dd'T'HH:mm:ss.SSSZ"},
115
+ 'expired_at': {'type': 'date', 'format': "yyyy-MM-dd'T'HH:mm:ss.SSSZ"},
116
+ 'invalid_at': {'type': 'date', 'format': "yyyy-MM-dd'T'HH:mm:ss.SSSZ"},
117
+ 'fact_embedding': {
118
+ 'type': 'knn_vector',
119
+ 'dims': EMBEDDING_DIM,
120
+ 'index': True,
121
+ 'similarity': 'cosine',
122
+ 'method': {
123
+ 'engine': 'faiss',
124
+ 'space_type': 'cosinesimil',
125
+ 'name': 'hnsw',
126
+ 'parameters': {'ef_construction': 128, 'm': 16},
127
+ },
128
+ },
129
+ }
130
+ }
131
+ },
132
+ },
133
+ ]
134
+
135
+
136
+ class GraphDriverSession(ABC):
137
+ provider: GraphProvider
138
+
139
+ async def __aenter__(self):
140
+ return self
141
+
142
+ @abstractmethod
143
+ async def __aexit__(self, exc_type, exc, tb):
144
+ # No cleanup needed for Falkor, but method must exist
145
+ pass
146
+
147
+ @abstractmethod
148
+ async def run(self, query: str, **kwargs: Any) -> Any:
149
+ raise NotImplementedError()
150
+
151
+ @abstractmethod
152
+ async def close(self):
153
+ raise NotImplementedError()
154
+
155
+ @abstractmethod
156
+ async def execute_write(self, func, *args, **kwargs):
157
+ raise NotImplementedError()
158
+
159
+
160
+ class GraphDriver(ABC):
161
+ provider: GraphProvider
162
+ fulltext_syntax: str = (
163
+ '' # Neo4j (default) syntax does not require a prefix for fulltext queries
164
+ )
165
+ _database: str
166
+ aoss_client: OpenSearch | None # type: ignore
167
+
168
+ @abstractmethod
169
+ def execute_query(self, cypher_query_: str, **kwargs: Any) -> Coroutine:
170
+ raise NotImplementedError()
171
+
172
+ @abstractmethod
173
+ def session(self, database: str | None = None) -> GraphDriverSession:
174
+ raise NotImplementedError()
175
+
176
+ @abstractmethod
177
+ def close(self):
178
+ raise NotImplementedError()
179
+
180
+ @abstractmethod
181
+ def delete_all_indexes(self) -> Coroutine:
182
+ raise NotImplementedError()
183
+
184
+ def with_database(self, database: str) -> 'GraphDriver':
185
+ """
186
+ Returns a shallow copy of this driver with a different default database.
187
+ Reuses the same connection (e.g. FalkorDB, Neo4j).
188
+ """
189
+ cloned = copy.copy(self)
190
+ cloned._database = database
191
+
192
+ return cloned
193
+
194
+ async def delete_all_indexes_impl(self) -> Coroutine[Any, Any, Any]:
195
+ # No matter what happens above, always return True
196
+ return self.delete_aoss_indices()
197
+
198
+ async def create_aoss_indices(self):
199
+ client = self.aoss_client
200
+ if not client:
201
+ logger.warning('No OpenSearch client found')
202
+ return
203
+
204
+ for index in aoss_indices:
205
+ alias_name = index['index_name']
206
+
207
+ # If alias already exists, skip (idempotent behavior)
208
+ if client.indices.exists_alias(name=alias_name):
209
+ continue
210
+
211
+ # Build a physical index name with timestamp
212
+ ts_suffix = datetime.utcnow().strftime('%Y%m%d%H%M%S')
213
+ physical_index_name = f'{alias_name}_{ts_suffix}'
214
+
215
+ # Create the index
216
+ client.indices.create(index=physical_index_name, body=index['body'])
217
+
218
+ # Point alias to it
219
+ client.indices.put_alias(index=physical_index_name, name=alias_name)
220
+
221
+ # Allow some time for index creation
222
+ await asyncio.sleep(60)
223
+
224
+ async def delete_aoss_indices(self):
225
+ for index in aoss_indices:
226
+ index_name = index['index_name']
227
+ client = self.aoss_client
228
+
229
+ if not client:
230
+ logger.warning('No OpenSearch client found')
231
+ return
232
+
233
+ if client.indices.exists(index=index_name):
234
+ client.indices.delete(index=index_name)
235
+
236
+ def save_to_aoss(self, name: str, data: list[dict]) -> int:
237
+ client = self.aoss_client
238
+ if not client or not helpers:
239
+ logger.warning('No OpenSearch client found')
240
+ return 0
241
+
242
+ for index in aoss_indices:
243
+ if name.lower() == index['index_name']:
244
+ to_index = []
245
+ for d in data:
246
+ item = {
247
+ '_index': name,
248
+ '_routing': d.get('group_id'), # shard routing
249
+ }
250
+ for p in index['body']['mappings']['properties']:
251
+ if p in d: # protect against missing fields
252
+ item[p] = d[p]
253
+ to_index.append(item)
254
+
255
+ success, failed = helpers.bulk(client, to_index, stats_only=True)
256
+
257
+ return success if failed == 0 else success
258
+
259
+ return 0
@@ -74,6 +74,7 @@ class FalkorDriverSession(GraphDriverSession):
74
74
 
75
75
  class FalkorDriver(GraphDriver):
76
76
  provider = GraphProvider.FALKORDB
77
+ aoss_client: None = None
77
78
 
78
79
  def __init__(
79
80
  self,
@@ -92,6 +92,7 @@ SCHEMA_QUERIES = """
92
92
 
93
93
  class KuzuDriver(GraphDriver):
94
94
  provider: GraphProvider = GraphProvider.KUZU
95
+ aoss_client: None = None
95
96
 
96
97
  def __init__(
97
98
  self,
@@ -22,14 +22,35 @@ from neo4j import AsyncGraphDatabase, EagerResult
22
22
  from typing_extensions import LiteralString
23
23
 
24
24
  from graphiti_core.driver.driver import GraphDriver, GraphDriverSession, GraphProvider
25
+ from graphiti_core.helpers import semaphore_gather
25
26
 
26
27
  logger = logging.getLogger(__name__)
27
28
 
29
+ try:
30
+ import boto3
31
+ from opensearchpy import OpenSearch, Urllib3AWSV4SignerAuth, Urllib3HttpConnection
32
+
33
+ _HAS_OPENSEARCH = True
34
+ except ImportError:
35
+ boto3 = None
36
+ OpenSearch = None
37
+ Urllib3AWSV4SignerAuth = None
38
+ Urllib3HttpConnection = None
39
+ _HAS_OPENSEARCH = False
40
+
28
41
 
29
42
  class Neo4jDriver(GraphDriver):
30
43
  provider = GraphProvider.NEO4J
31
44
 
32
- def __init__(self, uri: str, user: str | None, password: str | None, database: str = 'neo4j'):
45
+ def __init__(
46
+ self,
47
+ uri: str,
48
+ user: str | None,
49
+ password: str | None,
50
+ database: str = 'neo4j',
51
+ aoss_host: str | None = None,
52
+ aoss_port: int | None = None,
53
+ ):
33
54
  super().__init__()
34
55
  self.client = AsyncGraphDatabase.driver(
35
56
  uri=uri,
@@ -37,6 +58,24 @@ class Neo4jDriver(GraphDriver):
37
58
  )
38
59
  self._database = database
39
60
 
61
+ self.aoss_client = None
62
+ if aoss_host and aoss_port and boto3 is not None:
63
+ try:
64
+ session = boto3.Session()
65
+ self.aoss_client = OpenSearch( # type: ignore
66
+ hosts=[{'host': aoss_host, 'port': aoss_port}],
67
+ http_auth=Urllib3AWSV4SignerAuth( # type: ignore
68
+ session.get_credentials(), session.region_name, 'aoss'
69
+ ),
70
+ use_ssl=True,
71
+ verify_certs=True,
72
+ connection_class=Urllib3HttpConnection,
73
+ pool_maxsize=20,
74
+ ) # type: ignore
75
+ except Exception as e:
76
+ logger.warning(f'Failed to initialize OpenSearch client: {e}')
77
+ self.aoss_client = None
78
+
40
79
  async def execute_query(self, cypher_query_: LiteralString, **kwargs: Any) -> EagerResult:
41
80
  # Check if database_ is provided in kwargs.
42
81
  # If not populated, set the value to retain backwards compatibility
@@ -60,7 +99,14 @@ class Neo4jDriver(GraphDriver):
60
99
  async def close(self) -> None:
61
100
  return await self.client.close()
62
101
 
63
- def delete_all_indexes(self) -> Coroutine[Any, Any, EagerResult]:
102
+ def delete_all_indexes(self) -> Coroutine:
103
+ if self.aoss_client:
104
+ return semaphore_gather(
105
+ self.client.execute_query(
106
+ 'CALL db.indexes() YIELD name DROP INDEX name',
107
+ ),
108
+ self.delete_aoss_indices(),
109
+ )
64
110
  return self.client.execute_query(
65
111
  'CALL db.indexes() YIELD name DROP INDEX name',
66
112
  )
@@ -22,16 +22,21 @@ from typing import Any
22
22
 
23
23
  import boto3
24
24
  from langchain_aws.graphs import NeptuneAnalyticsGraph, NeptuneGraph
25
- from opensearchpy import OpenSearch, Urllib3AWSV4SignerAuth, Urllib3HttpConnection, helpers
25
+ from opensearchpy import OpenSearch, Urllib3AWSV4SignerAuth, Urllib3HttpConnection
26
26
 
27
- from graphiti_core.driver.driver import GraphDriver, GraphDriverSession, GraphProvider
27
+ from graphiti_core.driver.driver import (
28
+ DEFAULT_SIZE,
29
+ GraphDriver,
30
+ GraphDriverSession,
31
+ GraphProvider,
32
+ )
28
33
 
29
34
  logger = logging.getLogger(__name__)
30
- DEFAULT_SIZE = 10
31
35
 
32
- aoss_indices = [
36
+ neptune_aoss_indices = [
33
37
  {
34
38
  'index_name': 'node_name_and_summary',
39
+ 'alias_name': 'entities',
35
40
  'body': {
36
41
  'mappings': {
37
42
  'properties': {
@@ -49,6 +54,7 @@ aoss_indices = [
49
54
  },
50
55
  {
51
56
  'index_name': 'community_name',
57
+ 'alias_name': 'communities',
52
58
  'body': {
53
59
  'mappings': {
54
60
  'properties': {
@@ -65,6 +71,7 @@ aoss_indices = [
65
71
  },
66
72
  {
67
73
  'index_name': 'episode_content',
74
+ 'alias_name': 'episodes',
68
75
  'body': {
69
76
  'mappings': {
70
77
  'properties': {
@@ -88,6 +95,7 @@ aoss_indices = [
88
95
  },
89
96
  {
90
97
  'index_name': 'edge_name_and_fact',
98
+ 'alias_name': 'facts',
91
99
  'body': {
92
100
  'mappings': {
93
101
  'properties': {
@@ -220,54 +228,27 @@ class NeptuneDriver(GraphDriver):
220
228
  async def _delete_all_data(self) -> Any:
221
229
  return await self.execute_query('MATCH (n) DETACH DELETE n')
222
230
 
223
- def delete_all_indexes(self) -> Coroutine[Any, Any, Any]:
224
- return self.delete_all_indexes_impl()
225
-
226
- async def delete_all_indexes_impl(self) -> Coroutine[Any, Any, Any]:
227
- # No matter what happens above, always return True
228
- return self.delete_aoss_indices()
229
-
230
231
  async def create_aoss_indices(self):
231
- for index in aoss_indices:
232
+ for index in neptune_aoss_indices:
232
233
  index_name = index['index_name']
233
234
  client = self.aoss_client
235
+ if not client:
236
+ raise ValueError(
237
+ 'You must provide an AOSS endpoint to create an OpenSearch driver.'
238
+ )
234
239
  if not client.indices.exists(index=index_name):
235
240
  client.indices.create(index=index_name, body=index['body'])
241
+
242
+ alias_name = index.get('alias_name', index_name)
243
+
244
+ if not client.indices.exists_alias(name=alias_name, index=index_name):
245
+ client.indices.put_alias(index=index_name, name=alias_name)
246
+
236
247
  # Sleep for 1 minute to let the index creation complete
237
248
  await asyncio.sleep(60)
238
249
 
239
- async def delete_aoss_indices(self):
240
- for index in aoss_indices:
241
- index_name = index['index_name']
242
- client = self.aoss_client
243
- if client.indices.exists(index=index_name):
244
- client.indices.delete(index=index_name)
245
-
246
- def run_aoss_query(self, name: str, query_text: str, limit: int = 10) -> dict[str, Any]:
247
- for index in aoss_indices:
248
- if name.lower() == index['index_name']:
249
- index['query']['query']['multi_match']['query'] = query_text
250
- query = {'size': limit, 'query': index['query']}
251
- resp = self.aoss_client.search(body=query['query'], index=index['index_name'])
252
- return resp
253
- return {}
254
-
255
- def save_to_aoss(self, name: str, data: list[dict]) -> int:
256
- for index in aoss_indices:
257
- if name.lower() == index['index_name']:
258
- to_index = []
259
- for d in data:
260
- item = {'_index': name}
261
- for p in index['body']['mappings']['properties']:
262
- item[p] = d[p]
263
- to_index.append(item)
264
- success, failed = helpers.bulk(self.aoss_client, to_index, stats_only=True)
265
- if failed > 0:
266
- return success
267
- else:
268
- return 0
269
-
270
- return 0
250
+ def delete_all_indexes(self) -> Coroutine[Any, Any, Any]:
251
+ return self.delete_all_indexes_impl()
271
252
 
272
253
 
273
254
  class NeptuneDriverSession(GraphDriverSession):
@@ -255,6 +255,21 @@ class EntityEdge(Edge):
255
255
  MATCH (n:Entity)-[e:RELATES_TO {uuid: $uuid}]->(m:Entity)
256
256
  RETURN [x IN split(e.fact_embedding, ",") | toFloat(x)] as fact_embedding
257
257
  """
258
+ elif driver.aoss_client:
259
+ resp = driver.aoss_client.search(
260
+ body={
261
+ 'query': {'multi_match': {'query': self.uuid, 'fields': ['uuid']}},
262
+ 'size': 1,
263
+ },
264
+ index='entity_edges',
265
+ routing=self.group_id,
266
+ )
267
+
268
+ if resp['hits']['hits']:
269
+ self.fact_embedding = resp['hits']['hits'][0]['_source']['fact_embedding']
270
+ return
271
+ else:
272
+ raise EdgeNotFoundError(self.uuid)
258
273
 
259
274
  if driver.provider == GraphProvider.KUZU:
260
275
  query = """
@@ -292,14 +307,14 @@ class EntityEdge(Edge):
292
307
  if driver.provider == GraphProvider.KUZU:
293
308
  edge_data['attributes'] = json.dumps(self.attributes)
294
309
  result = await driver.execute_query(
295
- get_entity_edge_save_query(driver.provider),
310
+ get_entity_edge_save_query(driver.provider, has_aoss=bool(driver.aoss_client)),
296
311
  **edge_data,
297
312
  )
298
313
  else:
299
314
  edge_data.update(self.attributes or {})
300
315
 
301
- if driver.provider == GraphProvider.NEPTUNE:
302
- driver.save_to_aoss('edge_name_and_fact', [edge_data]) # pyright: ignore reportAttributeAccessIssue
316
+ if driver.aoss_client:
317
+ driver.save_to_aoss('entity_edges', [edge_data]) # pyright: ignore reportAttributeAccessIssue
303
318
 
304
319
  result = await driver.execute_query(
305
320
  get_entity_edge_save_query(driver.provider),
@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  """
16
16
 
17
+ import os
17
18
  from abc import ABC, abstractmethod
18
19
  from collections.abc import Iterable
19
20
 
20
21
  from pydantic import BaseModel, Field
21
22
 
22
- EMBEDDING_DIM = 1024
23
+ EMBEDDING_DIM = int(os.getenv('EMBEDDING_DIM', 1024))
23
24
 
24
25
 
25
26
  class EmbedderConfig(BaseModel):
@@ -60,7 +60,7 @@ EPISODIC_EDGE_RETURN = """
60
60
  """
61
61
 
62
62
 
63
- def get_entity_edge_save_query(provider: GraphProvider) -> str:
63
+ def get_entity_edge_save_query(provider: GraphProvider, has_aoss: bool = False) -> str:
64
64
  match provider:
65
65
  case GraphProvider.FALKORDB:
66
66
  return """
@@ -99,17 +99,28 @@ def get_entity_edge_save_query(provider: GraphProvider) -> str:
99
99
  RETURN e.uuid AS uuid
100
100
  """
101
101
  case _: # Neo4j
102
- return """
103
- MATCH (source:Entity {uuid: $edge_data.source_uuid})
104
- MATCH (target:Entity {uuid: $edge_data.target_uuid})
105
- MERGE (source)-[e:RELATES_TO {uuid: $edge_data.uuid}]->(target)
106
- SET e = $edge_data
107
- WITH e CALL db.create.setRelationshipVectorProperty(e, "fact_embedding", $edge_data.fact_embedding)
102
+ save_embedding_query = (
103
+ """WITH e CALL db.create.setRelationshipVectorProperty(e, "fact_embedding", $edge_data.fact_embedding)"""
104
+ if not has_aoss
105
+ else ''
106
+ )
107
+ return (
108
+ (
109
+ """
110
+ MATCH (source:Entity {uuid: $edge_data.source_uuid})
111
+ MATCH (target:Entity {uuid: $edge_data.target_uuid})
112
+ MERGE (source)-[e:RELATES_TO {uuid: $edge_data.uuid}]->(target)
113
+ SET e = $edge_data
114
+ """
115
+ + save_embedding_query
116
+ )
117
+ + """
108
118
  RETURN e.uuid AS uuid
109
- """
119
+ """
120
+ )
110
121
 
111
122
 
112
- def get_entity_edge_save_bulk_query(provider: GraphProvider) -> str:
123
+ def get_entity_edge_save_bulk_query(provider: GraphProvider, has_aoss: bool = False) -> str:
113
124
  match provider:
114
125
  case GraphProvider.FALKORDB:
115
126
  return """
@@ -152,15 +163,24 @@ def get_entity_edge_save_bulk_query(provider: GraphProvider) -> str:
152
163
  RETURN e.uuid AS uuid
153
164
  """
154
165
  case _:
155
- return """
156
- UNWIND $entity_edges AS edge
157
- MATCH (source:Entity {uuid: edge.source_node_uuid})
158
- MATCH (target:Entity {uuid: edge.target_node_uuid})
159
- MERGE (source)-[e:RELATES_TO {uuid: edge.uuid}]->(target)
160
- SET e = edge
161
- WITH e, edge CALL db.create.setRelationshipVectorProperty(e, "fact_embedding", edge.fact_embedding)
166
+ save_embedding_query = (
167
+ 'WITH e, edge CALL db.create.setRelationshipVectorProperty(e, "fact_embedding", edge.fact_embedding)'
168
+ if not has_aoss
169
+ else ''
170
+ )
171
+ return (
172
+ """
173
+ UNWIND $entity_edges AS edge
174
+ MATCH (source:Entity {uuid: edge.source_node_uuid})
175
+ MATCH (target:Entity {uuid: edge.target_node_uuid})
176
+ MERGE (source)-[e:RELATES_TO {uuid: edge.uuid}]->(target)
177
+ SET e = edge
178
+ """
179
+ + save_embedding_query
180
+ + """
162
181
  RETURN edge.uuid AS uuid
163
182
  """
183
+ )
164
184
 
165
185
 
166
186
  def get_entity_edge_return_query(provider: GraphProvider) -> str: