graphiti-core 0.11.6rc6__tar.gz → 0.11.6rc9__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.
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/PKG-INFO +1 -1
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/helpers.py +8 -26
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/search/search.py +22 -52
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/search/search_utils.py +117 -13
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/maintenance/node_operations.py +3 -3
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/pyproject.toml +1 -1
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/LICENSE +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/README.md +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/cross_encoder/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/cross_encoder/bge_reranker_client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/cross_encoder/client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/cross_encoder/openai_reranker_client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/edges.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/embedder/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/embedder/client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/embedder/gemini.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/embedder/openai.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/embedder/voyage.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/errors.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/graphiti.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/graphiti_types.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/anthropic_client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/config.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/errors.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/gemini_client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/groq_client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/openai_client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/openai_generic_client.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/utils.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/models/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/models/edges/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/models/edges/edge_db_queries.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/models/nodes/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/models/nodes/node_db_queries.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/nodes.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/dedupe_edges.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/dedupe_nodes.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/eval.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/extract_edge_dates.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/extract_edges.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/extract_nodes.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/invalidate_edges.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/lib.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/models.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/prompt_helpers.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/summarize_nodes.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/py.typed +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/search/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/search/search_config.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/search/search_config_recipes.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/search/search_filters.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/search/search_helpers.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/bulk_utils.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/datetime_utils.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/maintenance/__init__.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/maintenance/community_operations.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/maintenance/edge_operations.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/maintenance/graph_data_operations.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/maintenance/temporal_operations.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/maintenance/utils.py +0 -0
- {graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/ontology_utils/entity_types_utils.py +0 -0
|
@@ -23,6 +23,7 @@ from typing import Any
|
|
|
23
23
|
import numpy as np
|
|
24
24
|
from dotenv import load_dotenv
|
|
25
25
|
from neo4j import time as neo4j_time
|
|
26
|
+
from numpy._typing import NDArray
|
|
26
27
|
from typing_extensions import LiteralString
|
|
27
28
|
|
|
28
29
|
load_dotenv()
|
|
@@ -79,16 +80,10 @@ def lucene_sanitize(query: str) -> str:
|
|
|
79
80
|
return sanitized
|
|
80
81
|
|
|
81
82
|
|
|
82
|
-
def normalize_l2(embedding: list[float]):
|
|
83
|
+
def normalize_l2(embedding: list[float]) -> NDArray:
|
|
83
84
|
embedding_array = np.array(embedding)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if norm == 0:
|
|
87
|
-
return [0.0] * len(embedding)
|
|
88
|
-
return (embedding_array / norm).tolist()
|
|
89
|
-
else:
|
|
90
|
-
norm = np.linalg.norm(embedding_array, 2, axis=1, keepdims=True)
|
|
91
|
-
return (np.where(norm == 0, embedding_array, embedding_array / norm)).tolist()
|
|
85
|
+
norm = np.linalg.norm(embedding_array, 2, axis=0, keepdims=True)
|
|
86
|
+
return np.where(norm == 0, embedding_array, embedding_array / norm)
|
|
92
87
|
|
|
93
88
|
|
|
94
89
|
# Use this instead of asyncio.gather() to bound coroutines
|
|
@@ -98,21 +93,8 @@ async def semaphore_gather(
|
|
|
98
93
|
):
|
|
99
94
|
semaphore = asyncio.Semaphore(max_coroutines)
|
|
100
95
|
|
|
101
|
-
async def
|
|
96
|
+
async def _wrap_coroutine(coroutine):
|
|
102
97
|
async with semaphore:
|
|
103
|
-
return await
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
batch = []
|
|
107
|
-
for coroutine in coroutines:
|
|
108
|
-
batch.append(_wrap(coroutine))
|
|
109
|
-
# once we hit max_coroutines, gather and clear the batch
|
|
110
|
-
if len(batch) >= max_coroutines:
|
|
111
|
-
results.extend(await asyncio.gather(*batch))
|
|
112
|
-
batch.clear()
|
|
113
|
-
|
|
114
|
-
# gather any remaining coroutines in the final batch
|
|
115
|
-
if batch:
|
|
116
|
-
results.extend(await asyncio.gather(*batch))
|
|
117
|
-
|
|
118
|
-
return results
|
|
98
|
+
return await coroutine
|
|
99
|
+
|
|
100
|
+
return await asyncio.gather(*(_wrap_coroutine(coroutine) for coroutine in coroutines))
|
|
@@ -50,6 +50,9 @@ from graphiti_core.search.search_utils import (
|
|
|
50
50
|
edge_similarity_search,
|
|
51
51
|
episode_fulltext_search,
|
|
52
52
|
episode_mentions_reranker,
|
|
53
|
+
get_embeddings_for_communities,
|
|
54
|
+
get_embeddings_for_edges,
|
|
55
|
+
get_embeddings_for_nodes,
|
|
53
56
|
maximal_marginal_relevance,
|
|
54
57
|
node_bfs_search,
|
|
55
58
|
node_distance_reranker,
|
|
@@ -209,26 +212,17 @@ async def edge_search(
|
|
|
209
212
|
|
|
210
213
|
reranked_uuids = rrf(search_result_uuids, min_score=reranker_min_score)
|
|
211
214
|
elif config.reranker == EdgeReranker.mmr:
|
|
212
|
-
await
|
|
213
|
-
|
|
215
|
+
search_result_uuids_and_vectors = await get_embeddings_for_edges(
|
|
216
|
+
driver, list(edge_uuid_map.values())
|
|
214
217
|
)
|
|
215
|
-
search_result_uuids_and_vectors = [
|
|
216
|
-
(edge.uuid, edge.fact_embedding if edge.fact_embedding is not None else [0.0] * 1024)
|
|
217
|
-
for result in search_results
|
|
218
|
-
for edge in result
|
|
219
|
-
]
|
|
220
218
|
reranked_uuids = maximal_marginal_relevance(
|
|
221
219
|
query_vector,
|
|
222
220
|
search_result_uuids_and_vectors,
|
|
223
221
|
config.mmr_lambda,
|
|
222
|
+
reranker_min_score,
|
|
224
223
|
)
|
|
225
224
|
elif config.reranker == EdgeReranker.cross_encoder:
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
rrf_result_uuids = rrf(search_result_uuids, min_score=reranker_min_score)
|
|
229
|
-
rrf_edges = [edge_uuid_map[uuid] for uuid in rrf_result_uuids][:limit]
|
|
230
|
-
|
|
231
|
-
fact_to_uuid_map = {edge.fact: edge.uuid for edge in rrf_edges}
|
|
225
|
+
fact_to_uuid_map = {edge.fact: edge.uuid for edge in list(edge_uuid_map.values())[:limit]}
|
|
232
226
|
reranked_facts = await cross_encoder.rank(query, list(fact_to_uuid_map.keys()))
|
|
233
227
|
reranked_uuids = [
|
|
234
228
|
fact_to_uuid_map[fact] for fact, score in reranked_facts if score >= reranker_min_score
|
|
@@ -311,30 +305,23 @@ async def node_search(
|
|
|
311
305
|
if config.reranker == NodeReranker.rrf:
|
|
312
306
|
reranked_uuids = rrf(search_result_uuids, min_score=reranker_min_score)
|
|
313
307
|
elif config.reranker == NodeReranker.mmr:
|
|
314
|
-
await
|
|
315
|
-
|
|
308
|
+
search_result_uuids_and_vectors = await get_embeddings_for_nodes(
|
|
309
|
+
driver, list(node_uuid_map.values())
|
|
316
310
|
)
|
|
317
|
-
|
|
318
|
-
(node.uuid, node.name_embedding if node.name_embedding is not None else [0.0] * 1024)
|
|
319
|
-
for result in search_results
|
|
320
|
-
for node in result
|
|
321
|
-
]
|
|
311
|
+
|
|
322
312
|
reranked_uuids = maximal_marginal_relevance(
|
|
323
313
|
query_vector,
|
|
324
314
|
search_result_uuids_and_vectors,
|
|
325
315
|
config.mmr_lambda,
|
|
316
|
+
reranker_min_score,
|
|
326
317
|
)
|
|
327
318
|
elif config.reranker == NodeReranker.cross_encoder:
|
|
328
|
-
|
|
329
|
-
rrf_result_uuids = rrf(search_result_uuids, min_score=reranker_min_score)
|
|
330
|
-
rrf_results = [node_uuid_map[uuid] for uuid in rrf_result_uuids][:limit]
|
|
319
|
+
name_to_uuid_map = {node.name: node.uuid for node in list(node_uuid_map.values())}
|
|
331
320
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
reranked_summaries = await cross_encoder.rank(query, list(summary_to_uuid_map.keys()))
|
|
321
|
+
reranked_node_names = await cross_encoder.rank(query, list(name_to_uuid_map.keys()))
|
|
335
322
|
reranked_uuids = [
|
|
336
|
-
|
|
337
|
-
for
|
|
323
|
+
name_to_uuid_map[name]
|
|
324
|
+
for name, score in reranked_node_names
|
|
338
325
|
if score >= reranker_min_score
|
|
339
326
|
]
|
|
340
327
|
elif config.reranker == NodeReranker.episode_mentions:
|
|
@@ -437,35 +424,18 @@ async def community_search(
|
|
|
437
424
|
if config.reranker == CommunityReranker.rrf:
|
|
438
425
|
reranked_uuids = rrf(search_result_uuids, min_score=reranker_min_score)
|
|
439
426
|
elif config.reranker == CommunityReranker.mmr:
|
|
440
|
-
await
|
|
441
|
-
|
|
442
|
-
community.load_name_embedding(driver)
|
|
443
|
-
for result in search_results
|
|
444
|
-
for community in result
|
|
445
|
-
]
|
|
427
|
+
search_result_uuids_and_vectors = await get_embeddings_for_communities(
|
|
428
|
+
driver, list(community_uuid_map.values())
|
|
446
429
|
)
|
|
447
|
-
|
|
448
|
-
(
|
|
449
|
-
community.uuid,
|
|
450
|
-
community.name_embedding if community.name_embedding is not None else [0.0] * 1024,
|
|
451
|
-
)
|
|
452
|
-
for result in search_results
|
|
453
|
-
for community in result
|
|
454
|
-
]
|
|
430
|
+
|
|
455
431
|
reranked_uuids = maximal_marginal_relevance(
|
|
456
|
-
query_vector,
|
|
457
|
-
search_result_uuids_and_vectors,
|
|
458
|
-
config.mmr_lambda,
|
|
432
|
+
query_vector, search_result_uuids_and_vectors, config.mmr_lambda, reranker_min_score
|
|
459
433
|
)
|
|
460
434
|
elif config.reranker == CommunityReranker.cross_encoder:
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
464
|
-
reranked_summaries = await cross_encoder.rank(query, list(summary_to_uuid_map.keys()))
|
|
435
|
+
name_to_uuid_map = {node.name: node.uuid for result in search_results for node in result}
|
|
436
|
+
reranked_nodes = await cross_encoder.rank(query, list(name_to_uuid_map.keys()))
|
|
465
437
|
reranked_uuids = [
|
|
466
|
-
|
|
467
|
-
for fact, score in reranked_summaries
|
|
468
|
-
if score >= reranker_min_score
|
|
438
|
+
name_to_uuid_map[name] for name, score in reranked_nodes if score >= reranker_min_score
|
|
469
439
|
]
|
|
470
440
|
|
|
471
441
|
reranked_communities = [community_uuid_map[uuid] for uuid in reranked_uuids]
|
|
@@ -21,6 +21,7 @@ from typing import Any
|
|
|
21
21
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
from neo4j import AsyncDriver, Query
|
|
24
|
+
from numpy._typing import NDArray
|
|
24
25
|
from typing_extensions import LiteralString
|
|
25
26
|
|
|
26
27
|
from graphiti_core.edges import EntityEdge, get_entity_edge_from_record
|
|
@@ -336,10 +337,10 @@ async def node_fulltext_search(
|
|
|
336
337
|
|
|
337
338
|
query = (
|
|
338
339
|
"""
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
340
|
+
CALL db.index.fulltext.queryNodes("node_name_and_summary", $query, {limit: $limit})
|
|
341
|
+
YIELD node AS n, score
|
|
342
|
+
WHERE n:Entity
|
|
343
|
+
"""
|
|
343
344
|
+ filter_query
|
|
344
345
|
+ ENTITY_NODE_RETURN
|
|
345
346
|
+ """
|
|
@@ -899,6 +900,7 @@ async def node_distance_reranker(
|
|
|
899
900
|
node_uuids=filtered_uuids,
|
|
900
901
|
center_uuid=center_node_uuid,
|
|
901
902
|
database_=DEFAULT_DATABASE,
|
|
903
|
+
routing_='r',
|
|
902
904
|
)
|
|
903
905
|
|
|
904
906
|
for result in path_results:
|
|
@@ -939,6 +941,7 @@ async def episode_mentions_reranker(
|
|
|
939
941
|
query,
|
|
940
942
|
node_uuids=sorted_uuids,
|
|
941
943
|
database_=DEFAULT_DATABASE,
|
|
944
|
+
routing_='r',
|
|
942
945
|
)
|
|
943
946
|
|
|
944
947
|
for result in results:
|
|
@@ -952,15 +955,116 @@ async def episode_mentions_reranker(
|
|
|
952
955
|
|
|
953
956
|
def maximal_marginal_relevance(
|
|
954
957
|
query_vector: list[float],
|
|
955
|
-
candidates:
|
|
958
|
+
candidates: dict[str, list[float]],
|
|
956
959
|
mmr_lambda: float = DEFAULT_MMR_LAMBDA,
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
960
|
+
min_score: float = -2.0,
|
|
961
|
+
) -> list[str]:
|
|
962
|
+
start = time()
|
|
963
|
+
query_array = np.array(query_vector)
|
|
964
|
+
candidate_arrays: dict[str, NDArray] = {}
|
|
965
|
+
for uuid, embedding in candidates.items():
|
|
966
|
+
candidate_arrays[uuid] = normalize_l2(embedding)
|
|
967
|
+
|
|
968
|
+
uuids: list[str] = list(candidate_arrays.keys())
|
|
969
|
+
|
|
970
|
+
similarity_matrix = np.zeros((len(uuids), len(uuids)))
|
|
971
|
+
|
|
972
|
+
for i, uuid_1 in enumerate(uuids):
|
|
973
|
+
for j, uuid_2 in enumerate(uuids[:i]):
|
|
974
|
+
u = candidate_arrays[uuid_1]
|
|
975
|
+
v = candidate_arrays[uuid_2]
|
|
976
|
+
similarity = np.dot(u, v)
|
|
977
|
+
|
|
978
|
+
similarity_matrix[i, j] = similarity
|
|
979
|
+
similarity_matrix[j, i] = similarity
|
|
980
|
+
|
|
981
|
+
mmr_scores: dict[str, float] = {}
|
|
982
|
+
for i, uuid in enumerate(uuids):
|
|
983
|
+
max_sim = np.max(similarity_matrix[i, :])
|
|
984
|
+
mmr = mmr_lambda * np.dot(query_array, candidate_arrays[uuid]) + (mmr_lambda - 1) * max_sim
|
|
985
|
+
mmr_scores[uuid] = mmr
|
|
986
|
+
|
|
987
|
+
uuids.sort(reverse=True, key=lambda c: mmr_scores[c])
|
|
988
|
+
|
|
989
|
+
end = time()
|
|
990
|
+
logger.debug(f'Completed MMR reranking in {(end - start) * 1000} ms')
|
|
991
|
+
|
|
992
|
+
return [uuid for uuid in uuids if mmr_scores[uuid] >= min_score]
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
async def get_embeddings_for_nodes(
|
|
996
|
+
driver: AsyncDriver, nodes: list[EntityNode]
|
|
997
|
+
) -> dict[str, list[float]]:
|
|
998
|
+
query: LiteralString = """MATCH (n:Entity)
|
|
999
|
+
WHERE n.uuid IN $node_uuids
|
|
1000
|
+
RETURN DISTINCT
|
|
1001
|
+
n.uuid AS uuid,
|
|
1002
|
+
n.name_embedding AS name_embedding
|
|
1003
|
+
"""
|
|
1004
|
+
|
|
1005
|
+
results, _, _ = await driver.execute_query(
|
|
1006
|
+
query, node_uuids=[node.uuid for node in nodes], database_=DEFAULT_DATABASE, routing_='r'
|
|
1007
|
+
)
|
|
1008
|
+
|
|
1009
|
+
embeddings_dict: dict[str, list[float]] = {}
|
|
1010
|
+
for result in results:
|
|
1011
|
+
uuid: str = result.get('uuid')
|
|
1012
|
+
embedding: list[float] = result.get('name_embedding')
|
|
1013
|
+
if uuid is not None and embedding is not None:
|
|
1014
|
+
embeddings_dict[uuid] = embedding
|
|
963
1015
|
|
|
964
|
-
|
|
1016
|
+
return embeddings_dict
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
async def get_embeddings_for_communities(
|
|
1020
|
+
driver: AsyncDriver, communities: list[CommunityNode]
|
|
1021
|
+
) -> dict[str, list[float]]:
|
|
1022
|
+
query: LiteralString = """MATCH (c:Community)
|
|
1023
|
+
WHERE c.uuid IN $community_uuids
|
|
1024
|
+
RETURN DISTINCT
|
|
1025
|
+
c.uuid AS uuid,
|
|
1026
|
+
c.name_embedding AS name_embedding
|
|
1027
|
+
"""
|
|
1028
|
+
|
|
1029
|
+
results, _, _ = await driver.execute_query(
|
|
1030
|
+
query,
|
|
1031
|
+
community_uuids=[community.uuid for community in communities],
|
|
1032
|
+
database_=DEFAULT_DATABASE,
|
|
1033
|
+
routing_='r',
|
|
1034
|
+
)
|
|
1035
|
+
|
|
1036
|
+
embeddings_dict: dict[str, list[float]] = {}
|
|
1037
|
+
for result in results:
|
|
1038
|
+
uuid: str = result.get('uuid')
|
|
1039
|
+
embedding: list[float] = result.get('name_embedding')
|
|
1040
|
+
if uuid is not None and embedding is not None:
|
|
1041
|
+
embeddings_dict[uuid] = embedding
|
|
1042
|
+
|
|
1043
|
+
return embeddings_dict
|
|
1044
|
+
|
|
1045
|
+
|
|
1046
|
+
async def get_embeddings_for_edges(
|
|
1047
|
+
driver: AsyncDriver, edges: list[EntityEdge]
|
|
1048
|
+
) -> dict[str, list[float]]:
|
|
1049
|
+
query: LiteralString = """MATCH (n:Entity)-[e:RELATES_TO]-(m:Entity)
|
|
1050
|
+
WHERE e.uuid IN $edge_uuids
|
|
1051
|
+
RETURN DISTINCT
|
|
1052
|
+
e.uuid AS uuid,
|
|
1053
|
+
e.fact_embedding AS fact_embedding
|
|
1054
|
+
"""
|
|
1055
|
+
|
|
1056
|
+
results, _, _ = await driver.execute_query(
|
|
1057
|
+
query,
|
|
1058
|
+
edge_uuids=[edge.uuid for edge in edges],
|
|
1059
|
+
database_=DEFAULT_DATABASE,
|
|
1060
|
+
routing_='r',
|
|
1061
|
+
)
|
|
1062
|
+
|
|
1063
|
+
embeddings_dict: dict[str, list[float]] = {}
|
|
1064
|
+
for result in results:
|
|
1065
|
+
uuid: str = result.get('uuid')
|
|
1066
|
+
embedding: list[float] = result.get('fact_embedding')
|
|
1067
|
+
if uuid is not None and embedding is not None:
|
|
1068
|
+
embeddings_dict[uuid] = embedding
|
|
965
1069
|
|
|
966
|
-
return
|
|
1070
|
+
return embeddings_dict
|
|
@@ -18,6 +18,7 @@ import logging
|
|
|
18
18
|
from contextlib import suppress
|
|
19
19
|
from time import time
|
|
20
20
|
from typing import Any
|
|
21
|
+
from uuid import uuid4
|
|
21
22
|
|
|
22
23
|
import pydantic
|
|
23
24
|
from pydantic import BaseModel, Field
|
|
@@ -395,7 +396,8 @@ async def extract_attributes_from_node(
|
|
|
395
396
|
Field(description=field_info.description),
|
|
396
397
|
)
|
|
397
398
|
|
|
398
|
-
|
|
399
|
+
unique_model_name = f'EntityAttributes_{uuid4().hex}'
|
|
400
|
+
entity_attributes_model = pydantic.create_model(unique_model_name, **attributes_definitions)
|
|
399
401
|
|
|
400
402
|
summary_context: dict[str, Any] = {
|
|
401
403
|
'node': node_context,
|
|
@@ -411,12 +413,10 @@ async def extract_attributes_from_node(
|
|
|
411
413
|
)
|
|
412
414
|
|
|
413
415
|
node.summary = llm_response.get('summary', node.summary)
|
|
414
|
-
node.name = llm_response.get('name', node.name)
|
|
415
416
|
node_attributes = {key: value for key, value in llm_response.items()}
|
|
416
417
|
|
|
417
418
|
with suppress(KeyError):
|
|
418
419
|
del node_attributes['summary']
|
|
419
|
-
del node_attributes['name']
|
|
420
420
|
|
|
421
421
|
node.attributes.update(node_attributes)
|
|
422
422
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "graphiti-core"
|
|
3
3
|
description = "A temporal graph building library"
|
|
4
|
-
version = "0.11.
|
|
4
|
+
version = "0.11.6pre9"
|
|
5
5
|
authors = [
|
|
6
6
|
{ "name" = "Paul Paliychuk", "email" = "paul@getzep.com" },
|
|
7
7
|
{ "name" = "Preston Rasmussen", "email" = "preston@getzep.com" },
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/anthropic_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/gemini_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/llm_client/openai_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/models/edges/edge_db_queries.py
RENAMED
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/models/nodes/node_db_queries.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/extract_edge_dates.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/invalidate_edges.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/prompts/summarize_nodes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/search/search_config_recipes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/maintenance/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.11.6rc6 → graphiti_core-0.11.6rc9}/graphiti_core/utils/maintenance/utils.py
RENAMED
|
File without changes
|
|
File without changes
|