graphiti-core 0.10.4__tar.gz → 0.10.5__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 (65) hide show
  1. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/PKG-INFO +13 -5
  2. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/README.md +12 -4
  3. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/anthropic_client.py +4 -1
  4. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/client.py +4 -1
  5. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/gemini_client.py +4 -1
  6. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/openai_client.py +4 -1
  7. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/openai_generic_client.py +4 -1
  8. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/nodes.py +4 -10
  9. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/search/search_utils.py +8 -22
  10. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/maintenance/graph_data_operations.py +14 -6
  11. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/pyproject.toml +1 -1
  12. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/LICENSE +0 -0
  13. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/__init__.py +0 -0
  14. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/cross_encoder/__init__.py +0 -0
  15. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/cross_encoder/bge_reranker_client.py +0 -0
  16. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/cross_encoder/client.py +0 -0
  17. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/cross_encoder/openai_reranker_client.py +0 -0
  18. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/edges.py +0 -0
  19. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/embedder/__init__.py +0 -0
  20. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/embedder/client.py +0 -0
  21. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/embedder/gemini.py +0 -0
  22. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/embedder/openai.py +0 -0
  23. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/embedder/voyage.py +0 -0
  24. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/errors.py +0 -0
  25. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/graphiti.py +0 -0
  26. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/helpers.py +0 -0
  27. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/__init__.py +0 -0
  28. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/config.py +0 -0
  29. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/errors.py +0 -0
  30. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/groq_client.py +0 -0
  31. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/llm_client/utils.py +0 -0
  32. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/models/__init__.py +0 -0
  33. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/models/edges/__init__.py +0 -0
  34. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/models/edges/edge_db_queries.py +0 -0
  35. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/models/nodes/__init__.py +0 -0
  36. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/models/nodes/node_db_queries.py +0 -0
  37. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/__init__.py +0 -0
  38. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/dedupe_edges.py +0 -0
  39. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/dedupe_nodes.py +0 -0
  40. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/eval.py +0 -0
  41. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/extract_edge_dates.py +0 -0
  42. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/extract_edges.py +0 -0
  43. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/extract_nodes.py +0 -0
  44. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/invalidate_edges.py +0 -0
  45. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/lib.py +0 -0
  46. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/models.py +0 -0
  47. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/prompt_helpers.py +0 -0
  48. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/prompts/summarize_nodes.py +0 -0
  49. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/py.typed +0 -0
  50. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/search/__init__.py +0 -0
  51. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/search/search.py +0 -0
  52. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/search/search_config.py +0 -0
  53. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/search/search_config_recipes.py +0 -0
  54. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/search/search_filters.py +0 -0
  55. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/search/search_helpers.py +0 -0
  56. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/__init__.py +0 -0
  57. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/bulk_utils.py +0 -0
  58. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/datetime_utils.py +0 -0
  59. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/maintenance/__init__.py +0 -0
  60. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/maintenance/community_operations.py +0 -0
  61. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/maintenance/edge_operations.py +0 -0
  62. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/maintenance/node_operations.py +0 -0
  63. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/maintenance/temporal_operations.py +0 -0
  64. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/maintenance/utils.py +0 -0
  65. {graphiti_core-0.10.4 → graphiti_core-0.10.5}/graphiti_core/utils/ontology_utils/entity_types_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: graphiti-core
3
- Version: 0.10.4
3
+ Version: 0.10.5
4
4
  Summary: A temporal graph building library
5
5
  License: Apache-2.0
6
6
  Author: Paul Paliychuk
@@ -40,14 +40,22 @@ Description-Content-Type: text/markdown
40
40
  Graphiti
41
41
  </h1>
42
42
  <h2 align="center"> Build Real-Time Knowledge Graphs for AI Agents</h2>
43
- <br />
43
+ <div align="center">
44
44
 
45
- [![Discord](https://dcbadge.vercel.app/api/server/W8Kw6bsgXQ?style=flat)](https://discord.com/invite/W8Kw6bsgXQ)
46
- [![Lint](https://github.com/getzep/Graphiti/actions/workflows/lint.yml/badge.svg)](https://github.com/getzep/Graphiti/actions/workflows/lint.yml)
45
+
46
+ [![Lint](https://github.com/getzep/Graphiti/actions/workflows/lint.yml/badge.svg?style=flat)](https://github.com/getzep/Graphiti/actions/workflows/lint.yml)
47
47
  [![Unit Tests](https://github.com/getzep/Graphiti/actions/workflows/unit_tests.yml/badge.svg)](https://github.com/getzep/Graphiti/actions/workflows/unit_tests.yml)
48
48
  [![MyPy Check](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml/badge.svg)](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml)
49
- [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/getzep/Graphiti)
50
49
 
50
+ [![Discord](https://dcbadge.vercel.app/api/server/W8Kw6bsgXQ?style=flat)](https://discord.com/invite/W8Kw6bsgXQ)
51
+ [![arXiv](https://img.shields.io/badge/arXiv-2501.13956-b31b1b.svg?style=flat)](https://arxiv.org/abs/2501.13956)
52
+ [![Release](https://img.shields.io/github/v/release/getzep/graphiti?style=flat&label=Release&color=limegreen)](https://github.com/getzep/graphiti/releases)
53
+
54
+ </div>
55
+ <div align="center">
56
+
57
+ <a href="https://trendshift.io/repositories/12986" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12986" alt="getzep%2Fgraphiti | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
58
+ </div>
51
59
  :star: _Help us reach more developers and grow the Graphiti community. Star this repo!_
52
60
  <br />
53
61
 
@@ -8,14 +8,22 @@
8
8
  Graphiti
9
9
  </h1>
10
10
  <h2 align="center"> Build Real-Time Knowledge Graphs for AI Agents</h2>
11
- <br />
11
+ <div align="center">
12
12
 
13
- [![Discord](https://dcbadge.vercel.app/api/server/W8Kw6bsgXQ?style=flat)](https://discord.com/invite/W8Kw6bsgXQ)
14
- [![Lint](https://github.com/getzep/Graphiti/actions/workflows/lint.yml/badge.svg)](https://github.com/getzep/Graphiti/actions/workflows/lint.yml)
13
+
14
+ [![Lint](https://github.com/getzep/Graphiti/actions/workflows/lint.yml/badge.svg?style=flat)](https://github.com/getzep/Graphiti/actions/workflows/lint.yml)
15
15
  [![Unit Tests](https://github.com/getzep/Graphiti/actions/workflows/unit_tests.yml/badge.svg)](https://github.com/getzep/Graphiti/actions/workflows/unit_tests.yml)
16
16
  [![MyPy Check](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml/badge.svg)](https://github.com/getzep/Graphiti/actions/workflows/typecheck.yml)
17
- [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/getzep/Graphiti)
18
17
 
18
+ [![Discord](https://dcbadge.vercel.app/api/server/W8Kw6bsgXQ?style=flat)](https://discord.com/invite/W8Kw6bsgXQ)
19
+ [![arXiv](https://img.shields.io/badge/arXiv-2501.13956-b31b1b.svg?style=flat)](https://arxiv.org/abs/2501.13956)
20
+ [![Release](https://img.shields.io/github/v/release/getzep/graphiti?style=flat&label=Release&color=limegreen)](https://github.com/getzep/graphiti/releases)
21
+
22
+ </div>
23
+ <div align="center">
24
+
25
+ <a href="https://trendshift.io/repositories/12986" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12986" alt="getzep%2Fgraphiti | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
26
+ </div>
19
27
  :star: _Help us reach more developers and grow the Graphiti community. Star this repo!_
20
28
  <br />
21
29
 
@@ -262,7 +262,7 @@ class AnthropicClient(LLMClient):
262
262
  self,
263
263
  messages: list[Message],
264
264
  response_model: type[BaseModel] | None = None,
265
- max_tokens: int = DEFAULT_MAX_TOKENS,
265
+ max_tokens: int | None = None,
266
266
  ) -> dict[str, typing.Any]:
267
267
  """
268
268
  Generate a response from the LLM.
@@ -280,6 +280,9 @@ class AnthropicClient(LLMClient):
280
280
  RefusalError: If the LLM refuses to respond.
281
281
  Exception: If an error occurs during the generation process.
282
282
  """
283
+ if max_tokens is None:
284
+ max_tokens = self.max_tokens
285
+
283
286
  retry_count = 0
284
287
  max_retries = 2
285
288
  last_error: Exception | None = None
@@ -127,8 +127,11 @@ class LLMClient(ABC):
127
127
  self,
128
128
  messages: list[Message],
129
129
  response_model: type[BaseModel] | None = None,
130
- max_tokens: int = DEFAULT_MAX_TOKENS,
130
+ max_tokens: int | None = None,
131
131
  ) -> dict[str, typing.Any]:
132
+ if max_tokens is None:
133
+ max_tokens = self.max_tokens
134
+
132
135
  if response_model is not None:
133
136
  serialized_model = json.dumps(response_model.model_json_schema())
134
137
  messages[
@@ -166,7 +166,7 @@ class GeminiClient(LLMClient):
166
166
  self,
167
167
  messages: list[Message],
168
168
  response_model: type[BaseModel] | None = None,
169
- max_tokens: int = DEFAULT_MAX_TOKENS,
169
+ max_tokens: int | None = None,
170
170
  ) -> dict[str, typing.Any]:
171
171
  """
172
172
  Generate a response from the Gemini language model.
@@ -180,6 +180,9 @@ class GeminiClient(LLMClient):
180
180
  Returns:
181
181
  dict[str, typing.Any]: The response from the language model.
182
182
  """
183
+ if max_tokens is None:
184
+ max_tokens = self.max_tokens
185
+
183
186
  # Call the internal _generate_response method
184
187
  return await self._generate_response(
185
188
  messages=messages, response_model=response_model, max_tokens=max_tokens
@@ -131,8 +131,11 @@ class OpenAIClient(LLMClient):
131
131
  self,
132
132
  messages: list[Message],
133
133
  response_model: type[BaseModel] | None = None,
134
- max_tokens: int = DEFAULT_MAX_TOKENS,
134
+ max_tokens: int | None = None,
135
135
  ) -> dict[str, typing.Any]:
136
+ if max_tokens is None:
137
+ max_tokens = self.max_tokens
138
+
136
139
  retry_count = 0
137
140
  last_error = None
138
141
 
@@ -117,8 +117,11 @@ class OpenAIGenericClient(LLMClient):
117
117
  self,
118
118
  messages: list[Message],
119
119
  response_model: type[BaseModel] | None = None,
120
- max_tokens: int = DEFAULT_MAX_TOKENS,
120
+ max_tokens: int | None = None,
121
121
  ) -> dict[str, typing.Any]:
122
+ if max_tokens is None:
123
+ max_tokens = self.max_tokens
124
+
122
125
  retry_count = 0
123
126
  last_error = None
124
127
 
@@ -39,8 +39,6 @@ from graphiti_core.utils.datetime_utils import utc_now
39
39
  logger = logging.getLogger(__name__)
40
40
 
41
41
  ENTITY_NODE_RETURN: LiteralString = """
42
- OPTIONAL MATCH (e:Episodic)-[r:MENTIONS]->(n)
43
- WITH n, collect(e.uuid) AS episodes
44
42
  RETURN
45
43
  n.uuid As uuid,
46
44
  n.name AS name,
@@ -49,8 +47,8 @@ ENTITY_NODE_RETURN: LiteralString = """
49
47
  n.created_at AS created_at,
50
48
  n.summary AS summary,
51
49
  labels(n) AS labels,
52
- properties(n) AS attributes,
53
- episodes"""
50
+ properties(n) AS attributes
51
+ """
54
52
 
55
53
 
56
54
  class EpisodeType(Enum):
@@ -294,9 +292,6 @@ class EpisodicNode(Node):
294
292
  class EntityNode(Node):
295
293
  name_embedding: list[float] | None = Field(default=None, description='embedding of the name')
296
294
  summary: str = Field(description='regional summary of surrounding edges', default_factory=str)
297
- episodes: list[str] | None = Field(
298
- default=None, description='List of episode uuids that mention this node.'
299
- )
300
295
  attributes: dict[str, Any] = Field(
301
296
  default={}, description='Additional attributes of the node. Dependent on node labels'
302
297
  )
@@ -337,8 +332,8 @@ class EntityNode(Node):
337
332
  async def get_by_uuid(cls, driver: AsyncDriver, uuid: str):
338
333
  query = (
339
334
  """
340
- MATCH (n:Entity {uuid: $uuid})
341
- """
335
+ MATCH (n:Entity {uuid: $uuid})
336
+ """
342
337
  + ENTITY_NODE_RETURN
343
338
  )
344
339
  records, _, _ = await driver.execute_query(
@@ -544,7 +539,6 @@ def get_entity_node_from_record(record: Any) -> EntityNode:
544
539
  created_at=record['created_at'].to_native(),
545
540
  summary=record['summary'],
546
541
  attributes=record['attributes'],
547
- episodes=record['episodes'],
548
542
  )
549
543
 
550
544
  entity_node.attributes.pop('uuid', None)
@@ -54,20 +54,6 @@ DEFAULT_MMR_LAMBDA = 0.5
54
54
  MAX_SEARCH_DEPTH = 3
55
55
  MAX_QUERY_LENGTH = 32
56
56
 
57
- SEARCH_ENTITY_NODE_RETURN: LiteralString = """
58
- OPTIONAL MATCH (e:Episodic)-[r:MENTIONS]->(n)
59
- WITH n, score, collect(e.uuid) AS episodes
60
- RETURN
61
- n.uuid As uuid,
62
- n.name AS name,
63
- n.name_embedding AS name_embedding,
64
- n.group_id AS group_id,
65
- n.created_at AS created_at,
66
- n.summary AS summary,
67
- labels(n) AS labels,
68
- properties(n) AS attributes,
69
- episodes"""
70
-
71
57
 
72
58
  def fulltext_query(query: str, group_ids: list[str] | None = None):
73
59
  group_ids_filter_list = (
@@ -245,8 +231,8 @@ async def edge_similarity_search(
245
231
 
246
232
  query: LiteralString = (
247
233
  """
248
- MATCH (n:Entity)-[r:RELATES_TO]->(m:Entity)
249
- """
234
+ MATCH (n:Entity)-[r:RELATES_TO]->(m:Entity)
235
+ """
250
236
  + group_filter_query
251
237
  + filter_query
252
238
  + """\nWITH DISTINCT r, vector.similarity.cosine(r.fact_embedding, $search_vector) AS score
@@ -358,12 +344,12 @@ async def node_fulltext_search(
358
344
 
359
345
  query = (
360
346
  """
361
- CALL db.index.fulltext.queryNodes("node_name_and_summary", $query, {limit: $limit})
362
- YIELD node AS n, score
363
- WHERE n:Entity
364
- """
347
+ CALL db.index.fulltext.queryNodes("node_name_and_summary", $query, {limit: $limit})
348
+ YIELD node AS n, score
349
+ WHERE n:Entity
350
+ """
365
351
  + filter_query
366
- + SEARCH_ENTITY_NODE_RETURN
352
+ + ENTITY_NODE_RETURN
367
353
  + """
368
354
  ORDER BY score DESC
369
355
  """
@@ -416,7 +402,7 @@ async def node_similarity_search(
416
402
  + """
417
403
  WITH n, vector.similarity.cosine(n.name_embedding, $search_vector) AS score
418
404
  WHERE score > $min_score"""
419
- + SEARCH_ENTITY_NODE_RETURN
405
+ + ENTITY_NODE_RETURN
420
406
  + """
421
407
  ORDER BY score DESC
422
408
  LIMIT $limit
@@ -72,7 +72,7 @@ async def build_indices_and_constraints(driver: AsyncDriver, delete_existing: bo
72
72
 
73
73
  fulltext_indices: list[LiteralString] = [
74
74
  """CREATE FULLTEXT INDEX episode_content IF NOT EXISTS
75
- FOR (e:Episodic) ON EACH [e.content, e.source, e.group_id]""",
75
+ FOR (e:Episodic) ON EACH [e.content, e.source, e.source_description, e.group_id]""",
76
76
  """CREATE FULLTEXT INDEX node_name_and_summary IF NOT EXISTS
77
77
  FOR (n:Entity) ON EACH [n.name, n.summary, n.group_id]""",
78
78
  """CREATE FULLTEXT INDEX community_name IF NOT EXISTS
@@ -132,10 +132,14 @@ async def retrieve_episodes(
132
132
  Returns:
133
133
  list[EpisodicNode]: A list of EpisodicNode objects representing the retrieved episodes.
134
134
  """
135
- result = await driver.execute_query(
135
+ group_id_filter: LiteralString = 'AND e.group_id IN $group_ids' if group_ids and len(group_ids) > 0 else ''
136
+
137
+ query: LiteralString = (
136
138
  """
137
- MATCH (e:Episodic) WHERE e.valid_at <= $reference_time
138
- AND ($group_ids IS NULL) OR e.group_id in $group_ids
139
+ MATCH (e:Episodic) WHERE e.valid_at <= $reference_time
140
+ """
141
+ + group_id_filter
142
+ + """
139
143
  RETURN e.content AS content,
140
144
  e.created_at AS created_at,
141
145
  e.valid_at AS valid_at,
@@ -144,9 +148,13 @@ async def retrieve_episodes(
144
148
  e.name AS name,
145
149
  e.source_description AS source_description,
146
150
  e.source AS source
147
- ORDER BY e.created_at DESC
151
+ ORDER BY e.valid_at DESC
148
152
  LIMIT $num_episodes
149
- """,
153
+ """
154
+ )
155
+
156
+ result = await driver.execute_query(
157
+ query,
150
158
  reference_time=reference_time,
151
159
  num_episodes=last_n,
152
160
  group_ids=group_ids,
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "graphiti-core"
3
3
  description = "A temporal graph building library"
4
- version = "0.10.4"
4
+ version = "0.10.5"
5
5
  authors = [
6
6
  { "name" = "Paul Paliychuk", "email" = "paul@getzep.com" },
7
7
  { "name" = "Preston Rasmussen", "email" = "preston@getzep.com" },
File without changes