graphiti-core 0.5.3__py3-none-any.whl → 0.6.1__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.

Potentially problematic release.


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

graphiti_core/graphiti.py CHANGED
@@ -21,6 +21,7 @@ from time import time
21
21
  from dotenv import load_dotenv
22
22
  from neo4j import AsyncGraphDatabase
23
23
  from pydantic import BaseModel
24
+ from typing_extensions import LiteralString
24
25
 
25
26
  from graphiti_core.cross_encoder.client import CrossEncoderClient
26
27
  from graphiti_core.cross_encoder.openai_reranker_client import OpenAIRerankerClient
@@ -723,7 +724,7 @@ class Graphiti:
723
724
  if edge.fact_embedding is None:
724
725
  await edge.generate_embedding(self.embedder)
725
726
 
726
- resolved_nodes, _ = await resolve_extracted_nodes(
727
+ resolved_nodes, uuid_map = await resolve_extracted_nodes(
727
728
  self.llm_client,
728
729
  [source_node, target_node],
729
730
  [
@@ -732,14 +733,16 @@ class Graphiti:
732
733
  ],
733
734
  )
734
735
 
736
+ updated_edge = resolve_edge_pointers([edge], uuid_map)[0]
737
+
735
738
  related_edges = await get_relevant_edges(
736
739
  self.driver,
737
- [edge],
740
+ [updated_edge],
738
741
  source_node_uuid=resolved_nodes[0].uuid,
739
742
  target_node_uuid=resolved_nodes[1].uuid,
740
743
  )
741
744
 
742
- resolved_edge = await dedupe_extracted_edge(self.llm_client, edge, related_edges)
745
+ resolved_edge = await dedupe_extracted_edge(self.llm_client, updated_edge, related_edges)
743
746
 
744
747
  contradicting_edges = await get_edge_contradictions(self.llm_client, edge, related_edges)
745
748
  invalidated_edges = resolve_edge_contradictions(resolved_edge, contradicting_edges)
@@ -747,3 +750,34 @@ class Graphiti:
747
750
  await add_nodes_and_edges_bulk(
748
751
  self.driver, [], [], resolved_nodes, [resolved_edge] + invalidated_edges
749
752
  )
753
+
754
+ async def remove_episode(self, episode_uuid: str):
755
+ # Find the episode to be deleted
756
+ episode = await EpisodicNode.get_by_uuid(self.driver, episode_uuid)
757
+
758
+ # Find edges mentioned by the episode
759
+ edges = await EntityEdge.get_by_uuids(self.driver, episode.entity_edges)
760
+
761
+ # We should only delete edges created by the episode
762
+ edges_to_delete: list[EntityEdge] = []
763
+ for edge in edges:
764
+ if edge.episodes[0] == episode.uuid:
765
+ edges_to_delete.append(edge)
766
+
767
+ # Find nodes mentioned by the episode
768
+ nodes = await get_mentioned_nodes(self.driver, [episode])
769
+ # We should delete all nodes that are only mentioned in the deleted episode
770
+ nodes_to_delete: list[EntityNode] = []
771
+ for node in nodes:
772
+ query: LiteralString = 'MATCH (e:Episodic)-[:MENTIONS]->(n:Entity {uuid: $uuid}) RETURN count(*) AS episode_count'
773
+ records, _, _ = await self.driver.execute_query(
774
+ query, uuid=node.uuid, database_=DEFAULT_DATABASE, routing_='r'
775
+ )
776
+
777
+ for record in records:
778
+ if record['episode_count'] == 1:
779
+ nodes_to_delete.append(node)
780
+
781
+ await semaphore_gather(*[node.delete(self.driver) for node in nodes_to_delete])
782
+ await semaphore_gather(*[edge.delete(self.driver) for edge in edges_to_delete])
783
+ await episode.delete(self.driver)
graphiti_core/nodes.py CHANGED
@@ -170,7 +170,8 @@ class EpisodicNode(Node):
170
170
  e.name AS name,
171
171
  e.group_id AS group_id,
172
172
  e.source_description AS source_description,
173
- e.source AS source
173
+ e.source AS source,
174
+ e.entity_edges AS entity_edges
174
175
  """,
175
176
  uuid=uuid,
176
177
  database_=DEFAULT_DATABASE,
@@ -197,7 +198,8 @@ class EpisodicNode(Node):
197
198
  e.name AS name,
198
199
  e.group_id AS group_id,
199
200
  e.source_description AS source_description,
200
- e.source AS source
201
+ e.source AS source,
202
+ e.entity_edges AS entity_edges
201
203
  """,
202
204
  uuids=uuids,
203
205
  database_=DEFAULT_DATABASE,
@@ -233,7 +235,8 @@ class EpisodicNode(Node):
233
235
  e.name AS name,
234
236
  e.group_id AS group_id,
235
237
  e.source_description AS source_description,
236
- e.source AS source
238
+ e.source AS source,
239
+ e.entity_edges AS entity_edges
237
240
  ORDER BY e.uuid DESC
238
241
  """
239
242
  + limit_query,
@@ -490,6 +493,7 @@ def get_episodic_node_from_record(record: Any) -> EpisodicNode:
490
493
  source=EpisodeType.from_str(record['source']),
491
494
  name=record['name'],
492
495
  source_description=record['source_description'],
496
+ entity_edges=record['entity_edges'],
493
497
  )
494
498
 
495
499
 
@@ -79,8 +79,8 @@ def summarize_context(context: dict[str, Any]) -> list[Message]:
79
79
  {json.dumps(context['episode_content'], indent=2)}
80
80
  </MESSAGES>
81
81
 
82
- Given the above MESSAGES and the following ENTITY name, create a summary for the ENTITY. Your summary must only use
83
- information from the provided MESSAGES. Your summary should also only contain information relevant to the
82
+ Given the above MESSAGES and the following ENTITY name and ENTITY CONTEXT, create a summary for the ENTITY. Your summary must only use
83
+ information from the provided MESSAGES and from the ENTITY CONTEXT. Your summary should also only contain information relevant to the
84
84
  provided ENTITY.
85
85
 
86
86
  Summaries must be under 500 words.
@@ -88,6 +88,9 @@ def summarize_context(context: dict[str, Any]) -> list[Message]:
88
88
  <ENTITY>
89
89
  {context['node_name']}
90
90
  </ENTITY>
91
+ <ENTITY CONTEXT>
92
+ {context['node_summary']}
93
+ </ENTITY CONTEXT>
91
94
  """,
92
95
  ),
93
96
  ]
@@ -268,6 +268,7 @@ async def resolve_extracted_node(
268
268
 
269
269
  summary_context = {
270
270
  'node_name': extracted_node.name,
271
+ 'node_summary': extracted_node.summary,
271
272
  'episode_content': episode.content if episode is not None else '',
272
273
  'previous_episodes': [ep.content for ep in previous_episodes]
273
274
  if previous_episodes is not None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: graphiti-core
3
- Version: 0.5.3
3
+ Version: 0.6.1
4
4
  Summary: A temporal graph building library
5
5
  License: Apache-2.0
6
6
  Author: Paul Paliychuk
@@ -22,7 +22,7 @@ Description-Content-Type: text/markdown
22
22
 
23
23
  <div align="center">
24
24
 
25
- <img width="350" alt="Graphiti-ts-small" src="https://github.com/user-attachments/assets/bbd02947-e435-4a05-b25a-bbbac36d52c8">
25
+ # Graphiti
26
26
 
27
27
  ## Temporal Knowledge Graphs for Agentic Applications
28
28
 
@@ -45,7 +45,7 @@ a fusion of time, full-text, semantic, and graph algorithm approaches.
45
45
  <br />
46
46
 
47
47
  <p align="center">
48
- <img src="/images/graphiti-graph-intro.gif" alt="Graphiti temporal walkthrough" width="700px">
48
+ <img src="images/graphiti-graph-intro.gif" alt="Graphiti temporal walkthrough" width="700px">
49
49
  </p>
50
50
 
51
51
  <br />
@@ -65,6 +65,20 @@ With Graphiti, you can build LLM applications such as:
65
65
  Graphiti supports a wide range of applications in sales, customer service, health, finance, and more, enabling long-term
66
66
  recall and state-based reasoning for both assistants and agents.
67
67
 
68
+ ## Graphiti and Zep Memory
69
+
70
+ Graphiti powers the core of [Zep's memory layer](https://www.getzep.com) for LLM-powered Assistants and Agents.
71
+
72
+ Using Graphiti, we've demonstrated Zep is the [State of the Art in Agent Memory](https://blog.getzep.com/state-of-the-art-agent-memory/).
73
+
74
+ Read our paper: [Zep: A Temporal Knowledge Graph Architecture for Agent Memory](https://arxiv.org/abs/2501.13956).
75
+
76
+ We're excited to open-source Graphiti, believing its potential reaches far beyond memory applications.
77
+
78
+ <p align="center">
79
+ <a href="https://arxiv.org/abs/2501.13956"><img src="images/arxiv-screenshot.png" alt="Zep: A Temporal Knowledge Graph Architecture for Agent Memory" width="700px"></a>
80
+ </p>
81
+
68
82
  ## Why Graphiti?
69
83
 
70
84
  We were intrigued by Microsoft’s GraphRAG, which expanded on RAG text chunking by using a graph to better model a
@@ -89,12 +103,6 @@ scale:
89
103
  <img src="/images/graphiti-intro-slides-stock-2.gif" alt="Graphiti structured + unstructured demo" width="700px">
90
104
  </p>
91
105
 
92
- ## Graphiti and Zep Memory
93
-
94
- Graphiti powers the core of [Zep's memory layer](https://www.getzep.com) for LLM-powered Assistants and Agents.
95
-
96
- We're excited to open-source Graphiti, believing its potential reaches far beyond memory applications.
97
-
98
106
  ## Installation
99
107
 
100
108
  Requirements:
@@ -125,7 +133,7 @@ poetry add graphiti-core
125
133
 
126
134
  > [!IMPORTANT]
127
135
  > Graphiti uses OpenAI for LLM inference and embedding. Ensure that an `OPENAI_API_KEY` is set in your environment.
128
- > Support for Anthropic and Groq LLM inferences is available, too.
136
+ > Support for Anthropic and Groq LLM inferences is available, too. Other LLM providers may be supported via OpenAI compatible APIs.
129
137
 
130
138
  ```python
131
139
  from graphiti_core import Graphiti
@@ -216,13 +224,9 @@ as such this feature is off by default.
216
224
 
217
225
  Graphiti is under active development. We aim to maintain API stability while working on:
218
226
 
219
- - [x] Implementing node and edge CRUD operations
220
- - [ ] Improving performance and scalability
221
- - [ ] Achieving good performance with different LLM and embedding models
222
- - [x] Creating a dedicated embedder interface
223
227
  - [ ] Supporting custom graph schemas:
224
- - Allow developers to provide their own defined node and edge classes when ingesting episodes
225
- - Enable more flexible knowledge representation tailored to specific use cases
228
+ - Allow developers to provide their own defined node and edge classes when ingesting episodes
229
+ - Enable more flexible knowledge representation tailored to specific use cases
226
230
  - [x] Enhancing retrieval capabilities with more robust and configurable options
227
231
  - [ ] Expanding test coverage to ensure reliability and catch edge cases
228
232
 
@@ -9,7 +9,7 @@ graphiti_core/embedder/client.py,sha256=HKIlpPLnzFT81jurPkry6z8F8nxfZVfejdcfxHVU
9
9
  graphiti_core/embedder/openai.py,sha256=FzEM9rtSDK1wTb4iYKjNjjdFf8BEBTDxG2vM_E-5W-8,1621
10
10
  graphiti_core/embedder/voyage.py,sha256=7kqrLG75J3Q6cdA2Nlx1JSYtpk2141ckdl3OtDDw0vU,1882
11
11
  graphiti_core/errors.py,sha256=ddHrHGQxhwkVAtSph4AV84UoOlgwZufMczXPwB7uqPo,1795
12
- graphiti_core/graphiti.py,sha256=3W_Ade1e8SLKfb94D5zQ0kpvILfPOc9YzAr8wG0WRwE,27403
12
+ graphiti_core/graphiti.py,sha256=IaQ2xUM3Z1BG7ByJpznRAdg3FWtcOuIOq9YkY_JfiLE,28974
13
13
  graphiti_core/helpers.py,sha256=z7ApOgrm_J7hk5FN_XPAwkKyopEY943BgHjDJbSXr2s,2869
14
14
  graphiti_core/llm_client/__init__.py,sha256=PA80TSMeX-sUXITXEAxMDEt3gtfZgcJrGJUcyds1mSo,207
15
15
  graphiti_core/llm_client/anthropic_client.py,sha256=RlD6e49XvMJsTKU0krpq46gPSFm6-hfLkkq4Sfx27BE,2574
@@ -25,7 +25,7 @@ graphiti_core/models/edges/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
25
25
  graphiti_core/models/edges/edge_db_queries.py,sha256=2UoLkmazO-FJYqjc3g0LuL-pyjekzQxxed_XHVv_HZE,2671
26
26
  graphiti_core/models/nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  graphiti_core/models/nodes/node_db_queries.py,sha256=I0top_N23FN0U5ZbypaS5IXvtfx2zgJmKUCT_7mpUdo,2257
28
- graphiti_core/nodes.py,sha256=W5E7Tce02yF8fgo_rimVmPTrwYJ7qoqlfAtlcBs9jjk,15921
28
+ graphiti_core/nodes.py,sha256=_ExaTj2HU-xDczbls4aFcLdpc8zwPZUZ8JgVOrBiEdw,16098
29
29
  graphiti_core/prompts/__init__.py,sha256=EA-x9xUki9l8wnu2l8ek_oNf75-do5tq5hVq7Zbv8Kw,101
30
30
  graphiti_core/prompts/dedupe_edges.py,sha256=EuX8ngeItBzrlMBOgeHrpExzxIFHD2aoDyaX1ZniF6I,3556
31
31
  graphiti_core/prompts/dedupe_nodes.py,sha256=mqvNATL-4Vo33vaxUEZfOq6hXXOiL-ftY0zcx2G-82I,4624
@@ -37,7 +37,7 @@ graphiti_core/prompts/invalidate_edges.py,sha256=DV2mEyIhhjc0hdKEMFLQMeG0FiUCkv_
37
37
  graphiti_core/prompts/lib.py,sha256=oxhlpGEgV15VOLEZiwirxmIJBIdfzfiyL58iyzFDskE,4254
38
38
  graphiti_core/prompts/models.py,sha256=cvx_Bv5RMFUD_5IUawYrbpOKLPHogai7_bm7YXrSz84,867
39
39
  graphiti_core/prompts/prompt_helpers.py,sha256=-9TABwIcIQUVHcNANx6wIZd-FT2DgYKyGTfx4IGYq2I,64
40
- graphiti_core/prompts/summarize_nodes.py,sha256=5J_IONG7fHYiQZWnCaUyw7w2zunEaN7V89nEluRP-qY,3461
40
+ graphiti_core/prompts/summarize_nodes.py,sha256=XOJykwT7LtzWk2bRquFgv4tRAU3JOkkNkWBg-mkYOKc,3593
41
41
  graphiti_core/py.typed,sha256=vlmmzQOt7bmeQl9L3XJP4W6Ry0iiELepnOrinKz5KQg,79
42
42
  graphiti_core/search/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  graphiti_core/search/search.py,sha256=4DaeP5aRT7ZOByDO3H5UK0edxfwQ4mzAOdFjnjwaDJs,12454
@@ -52,10 +52,10 @@ graphiti_core/utils/maintenance/__init__.py,sha256=TRY3wWWu5kn3Oahk_KKhltrWnh0NA
52
52
  graphiti_core/utils/maintenance/community_operations.py,sha256=gIw1M5HGgc2c3TXag5ygPPpAv5WsG-yoC8Lhmfr6FMs,10011
53
53
  graphiti_core/utils/maintenance/edge_operations.py,sha256=tNw56vN586JYZMgie6RLRTiHZ680-kWzDIxW8ucL6SU,12780
54
54
  graphiti_core/utils/maintenance/graph_data_operations.py,sha256=qds9ALk9PhpQs1CNZTZGpi70mqJ93Y2KhIh9X2r8MUI,6533
55
- graphiti_core/utils/maintenance/node_operations.py,sha256=A-6H2ohqcGJRA_sg_-0m_AA7syiP_gVBsyY7VTTbfuA,12036
55
+ graphiti_core/utils/maintenance/node_operations.py,sha256=lrlp27clVhWrxy2BxofTjIISZpwqNG12evHO5wNwOY8,12084
56
56
  graphiti_core/utils/maintenance/temporal_operations.py,sha256=RdNtubCyYhOVrvcOIq2WppHls1Q-BEjtsN8r38l-Rtc,3691
57
57
  graphiti_core/utils/maintenance/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
- graphiti_core-0.5.3.dist-info/LICENSE,sha256=KCUwCyDXuVEgmDWkozHyniRyWjnWUWjkuDHfU6o3JlA,11325
59
- graphiti_core-0.5.3.dist-info/METADATA,sha256=SCPV6WVIYr-3nkv3aIpIt02jgXC_tgpNVlw8qZdY5Fc,10058
60
- graphiti_core-0.5.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
61
- graphiti_core-0.5.3.dist-info/RECORD,,
58
+ graphiti_core-0.6.1.dist-info/LICENSE,sha256=KCUwCyDXuVEgmDWkozHyniRyWjnWUWjkuDHfU6o3JlA,11325
59
+ graphiti_core-0.6.1.dist-info/METADATA,sha256=T7rqCclsf8c92WTRWiYXFzWpQR36gy3whh_w-uXWjvA,10242
60
+ graphiti_core-0.6.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
61
+ graphiti_core-0.6.1.dist-info/RECORD,,