diff --git a/pyproject.toml b/pyproject.toml index fe40db39..aec99582 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "zep-cloud" [tool.poetry] name = "zep-cloud" -version = "3.16.0" +version = "3.17.0" description = "" readme = "README.md" authors = [] diff --git a/reference.md b/reference.md index 3fcbf5df..23952967 100644 --- a/reference.md +++ b/reference.md @@ -907,7 +907,7 @@ client.graph.add(
-Add data to the graph in batch mode, processing episodes concurrently. Use only for data that is insensitive to processing order. +Add data to the graph in batch mode. Episodes are processed sequentially in the order provided.
@@ -1115,6 +1115,14 @@ Nested objects and arrays are not allowed.
+**source_node_labels:** `typing.Optional[typing.Sequence[str]]` — The labels for the source node + +
+
+ +
+
+ **source_node_name:** `typing.Optional[str]` — The name of the source node to add
@@ -1150,6 +1158,14 @@ Nested objects and arrays are not allowed.
+**target_node_labels:** `typing.Optional[typing.Sequence[str]]` — The labels for the target node + +
+
+ +
+
+ **target_node_name:** `typing.Optional[str]` — The name of the target node to add
@@ -1360,14 +1376,6 @@ client.graph.create(
-**fact_rating_instruction:** `typing.Optional[FactRatingInstruction]` - -
-
- -
-
- **name:** `typing.Optional[str]`
@@ -1423,6 +1431,8 @@ client = Zep( client.graph.list_all( page_number=1, page_size=1, + order_by="order_by", + asc=True, ) ``` @@ -1455,6 +1465,22 @@ client.graph.list_all(
+**order_by:** `typing.Optional[str]` — Column to sort by (created_at, group_id, name). + +
+
+ +
+
+ +**asc:** `typing.Optional[bool]` — Sort in ascending order. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -1467,7 +1493,7 @@ client.graph.list_all(
-
client.graph.search(...) +
client.graph.detect_patterns(...)
@@ -1479,7 +1505,8 @@ client.graph.list_all(
-Perform a graph search query. +Detects structural patterns in a knowledge graph including relationship frequencies, +multi-hop paths, co-occurrences, hubs, and clusters.
@@ -1499,9 +1526,7 @@ from zep_cloud import Zep client = Zep( api_key="YOUR_API_KEY", ) -client.graph.search( - query="query", -) +client.graph.detect_patterns() ``` @@ -1517,7 +1542,10 @@ client.graph.search(
-**query:** `str` — The string to search for (required) +**detect:** `typing.Optional[DetectConfig]` + +Which pattern types to detect with type-specific configuration. +Omit to detect all types with defaults.
@@ -1525,7 +1553,7 @@ client.graph.search(
-**bfs_origin_node_uuids:** `typing.Optional[typing.Sequence[str]]` — Nodes that are the origins of the BFS searches +**graph_id:** `typing.Optional[str]` — Graph ID when detecting patterns on a named graph
@@ -1533,7 +1561,7 @@ client.graph.search(
-**center_node_uuid:** `typing.Optional[str]` — Node to rerank around for node distance reranking +**include_examples:** `typing.Optional[bool]` — Include example node/edge UUIDs per pattern. Default: false
@@ -1541,7 +1569,7 @@ client.graph.search(
-**graph_id:** `typing.Optional[str]` — The graph_id to search in. When searching user graph, please use user_id instead. +**limit:** `typing.Optional[int]` — Max patterns to return. Default: 50, Max: 200
@@ -1549,7 +1577,115 @@ client.graph.search(
-**limit:** `typing.Optional[int]` — The maximum number of facts to retrieve. Defaults to 10. Limited to 50. +**min_occurrences:** `typing.Optional[int]` — Minimum occurrence count to report a pattern. Default: 2 + +
+
+ +
+
+ +**recency_weight:** `typing.Optional[RecencyWeight]` + +Exponential half-life decay applied to edge created_at timestamps. +Valid values: none, 7_days, 30_days, 90_days. Default: none + +
+
+ +
+
+ +**search_filters:** `typing.Optional[SearchFilters]` + +Filters which edges/nodes participate in pattern detection. +Reuses the same filter format as /graph/search. + +
+
+ +
+
+ +**seeds:** `typing.Optional[PatternSeeds]` — Seed selection. If omitted, analyzes the entire graph. + +
+
+ +
+
+ +**user_id:** `typing.Optional[str]` — User ID when detecting patterns on a user graph + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ +
+ + + +
+ + +
client.graph.search(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Perform a graph search query. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep + +client = Zep( + api_key="YOUR_API_KEY", +) +client.graph.search( + query="query", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**query:** `str` — The string to search for (required)
@@ -1557,7 +1693,7 @@ client.graph.search(
-**min_fact_rating:** `typing.Optional[float]` — The minimum rating by which to filter relevant facts +**bfs_origin_node_uuids:** `typing.Optional[typing.Sequence[str]]` — Nodes that are the origins of the BFS searches
@@ -1565,7 +1701,23 @@ client.graph.search(
-**min_score:** `typing.Optional[float]` — Deprecated +**center_node_uuid:** `typing.Optional[str]` — Node to rerank around for node distance reranking + +
+
+ +
+
+ +**graph_id:** `typing.Optional[str]` — The graph_id to search in. When searching user graph, please use user_id instead. + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — The maximum number of facts to retrieve. Defaults to 10. Limited to 50.
@@ -1831,14 +1983,6 @@ client.graph.update(
-**fact_rating_instruction:** `typing.Optional[FactRatingInstruction]` - -
-
- -
-
- **name:** `typing.Optional[str]`
@@ -2272,9 +2416,7 @@ client = Zep( ) client.thread.get_user_context( thread_id="threadId", - min_rating=1.1, template_id="template_id", - mode="basic", ) ``` @@ -2299,14 +2441,6 @@ client.thread.get_user_context(
-**min_rating:** `typing.Optional[float]` — Deprecated, this field will be removed in a future release. The minimum rating by which to filter relevant facts. - -
-
- -
-
- **template_id:** `typing.Optional[str]` — Optional template ID to use for custom context rendering.
@@ -2315,14 +2449,6 @@ client.thread.get_user_context(
-**mode:** `typing.Optional[ThreadGetUserContextRequestMode]` — Deprecated, this field will be removed in a future release. Defaults to summary mode. Use basic for lower latency - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -2944,14 +3070,6 @@ client.user.add(
-**fact_rating_instruction:** `typing.Optional[FactRatingInstruction]` — Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - -
-
- -
-
- **first_name:** `typing.Optional[str]` — The first name of the user.
@@ -3023,6 +3141,9 @@ client = Zep( client.user.list_ordered( page_number=1, page_size=1, + search="search", + order_by="order_by", + asc=True, ) ``` @@ -3055,6 +3176,30 @@ client.user.list_ordered(
+**search:** `typing.Optional[str]` — Search term for filtering users by user_id, name, or email + +
+
+ +
+
+ +**order_by:** `typing.Optional[str]` — Column to sort by (created_at, user_id, email) + +
+
+ +
+
+ +**asc:** `typing.Optional[bool]` — Sort in ascending order + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -3281,14 +3426,6 @@ client.user.update(
-**fact_rating_instruction:** `typing.Optional[FactRatingInstruction]` — Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - -
-
- -
-
- **first_name:** `typing.Optional[str]` — The first name of the user.
@@ -3844,6 +3981,124 @@ client.graph.edge.delete(
+
+
+
+ +
client.graph.edge.update(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Updates an entity edge by UUID. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep + +client = Zep( + api_key="YOUR_API_KEY", +) +client.graph.edge.update( + uuid_="uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**uuid_:** `str` — Edge UUID + +
+
+ +
+
+ +**attributes:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — Updated attributes. Merged with existing attributes. Set a key to null to delete it. + +
+
+ +
+
+ +**expired_at:** `typing.Optional[str]` — Updated time at which the edge expires + +
+
+ +
+
+ +**fact:** `typing.Optional[str]` — Updated fact for the edge + +
+
+ +
+
+ +**invalid_at:** `typing.Optional[str]` — Updated time at which the fact stopped being true + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Updated name (relationship type) for the edge + +
+
+ +
+
+ +**valid_at:** `typing.Optional[str]` — Updated time at which the fact becomes true + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -4666,6 +4921,108 @@ client.graph.node.delete(
+ +
+ + +
client.graph.node.update(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Updates an entity node by UUID. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep + +client = Zep( + api_key="YOUR_API_KEY", +) +client.graph.node.update( + uuid_="uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**uuid_:** `str` — Node UUID + +
+
+ +
+
+ +**attributes:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — Updated attributes. Merged with existing attributes. Set a key to null to delete it. + +
+
+ +
+
+ +**labels:** `typing.Optional[typing.Sequence[str]]` — Updated labels for the node + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Updated name for the node + +
+
+ +
+
+ +**summary:** `typing.Optional[str]` — Updated summary for the node + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
diff --git a/src/zep_cloud/__init__.py b/src/zep_cloud/__init__.py index ae9a38ff..8492efa3 100644 --- a/src/zep_cloud/__init__.py +++ b/src/zep_cloud/__init__.py @@ -8,10 +8,14 @@ AddTripleResponse, ApiError, CloneGraphResponse, + ClusterDetectConfig, + CoOccurrenceDetectConfig, ComparisonOperator, ContextTemplateResponse, CustomInstruction, DateFilter, + DetectConfig, + DetectPatternsResponse, EdgeType, EntityEdge, EntityEdgeSourceTarget, @@ -24,8 +28,6 @@ EpisodeData, EpisodeMentions, EpisodeResponse, - FactRatingExamples, - FactRatingInstruction, GetTaskResponse, Graph, GraphDataType, @@ -34,16 +36,22 @@ GraphNodesRequest, GraphSearchResults, GraphSearchScope, + HubDetectConfig, ListContextTemplatesResponse, ListCustomInstructionsResponse, ListUserInstructionsResponse, Message, MessageListResponse, - ModelsFactRatingExamples, - ModelsFactRatingInstruction, + PathDetectConfig, + PatternExample, + PatternMetadata, + PatternResult, + PatternSeeds, ProjectInfo, ProjectInfoResponse, PropertyFilter, + RecencyWeight, + RelationshipDetectConfig, Reranker, RoleType, SearchFilters, @@ -58,11 +66,10 @@ UserListResponse, UserNodeResponse, ) -from .errors import BadRequestError, InternalServerError, NotFoundError +from .errors import BadRequestError, ForbiddenError, InternalServerError, NotFoundError from . import context, graph, project, task, thread, user from .client import AsyncZep, Zep from .environment import ZepEnvironment -from .thread import ThreadGetUserContextRequestMode from .version import __version__ __all__ = [ @@ -73,10 +80,14 @@ "AsyncZep", "BadRequestError", "CloneGraphResponse", + "ClusterDetectConfig", + "CoOccurrenceDetectConfig", "ComparisonOperator", "ContextTemplateResponse", "CustomInstruction", "DateFilter", + "DetectConfig", + "DetectPatternsResponse", "EdgeType", "EntityEdge", "EntityEdgeSourceTarget", @@ -89,8 +100,7 @@ "EpisodeData", "EpisodeMentions", "EpisodeResponse", - "FactRatingExamples", - "FactRatingInstruction", + "ForbiddenError", "GetTaskResponse", "Graph", "GraphDataType", @@ -99,18 +109,24 @@ "GraphNodesRequest", "GraphSearchResults", "GraphSearchScope", + "HubDetectConfig", "InternalServerError", "ListContextTemplatesResponse", "ListCustomInstructionsResponse", "ListUserInstructionsResponse", "Message", "MessageListResponse", - "ModelsFactRatingExamples", - "ModelsFactRatingInstruction", "NotFoundError", + "PathDetectConfig", + "PatternExample", + "PatternMetadata", + "PatternResult", + "PatternSeeds", "ProjectInfo", "ProjectInfoResponse", "PropertyFilter", + "RecencyWeight", + "RelationshipDetectConfig", "Reranker", "RoleType", "SearchFilters", @@ -119,7 +135,6 @@ "TaskProgress", "Thread", "ThreadContextResponse", - "ThreadGetUserContextRequestMode", "ThreadListResponse", "User", "UserInstruction", diff --git a/src/zep_cloud/core/client_wrapper.py b/src/zep_cloud/core/client_wrapper.py index 67605577..ecd1bf66 100644 --- a/src/zep_cloud/core/client_wrapper.py +++ b/src/zep_cloud/core/client_wrapper.py @@ -22,10 +22,10 @@ def __init__( def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { - "User-Agent": "zep-cloud/3.16.0", + "User-Agent": "zep-cloud/3.17.0", "X-Fern-Language": "Python", "X-Fern-SDK-Name": "zep-cloud", - "X-Fern-SDK-Version": "3.16.0", + "X-Fern-SDK-Version": "3.17.0", **(self.get_custom_headers() or {}), } headers["Authorization"] = f"Api-Key {self.api_key}" diff --git a/src/zep_cloud/errors/__init__.py b/src/zep_cloud/errors/__init__.py index 2415f2ef..3455a818 100644 --- a/src/zep_cloud/errors/__init__.py +++ b/src/zep_cloud/errors/__init__.py @@ -3,7 +3,8 @@ # isort: skip_file from .bad_request_error import BadRequestError +from .forbidden_error import ForbiddenError from .internal_server_error import InternalServerError from .not_found_error import NotFoundError -__all__ = ["BadRequestError", "InternalServerError", "NotFoundError"] +__all__ = ["BadRequestError", "ForbiddenError", "InternalServerError", "NotFoundError"] diff --git a/src/zep_cloud/errors/forbidden_error.py b/src/zep_cloud/errors/forbidden_error.py new file mode 100644 index 00000000..80e15e0f --- /dev/null +++ b/src/zep_cloud/errors/forbidden_error.py @@ -0,0 +1,11 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.api_error import ApiError as core_api_error_ApiError +from ..types.api_error import ApiError as types_api_error_ApiError + + +class ForbiddenError(core_api_error_ApiError): + def __init__(self, body: types_api_error_ApiError, headers: typing.Optional[typing.Dict[str, str]] = None): + super().__init__(status_code=403, headers=headers, body=body) diff --git a/src/zep_cloud/graph/client.py b/src/zep_cloud/graph/client.py index 2e520964..0236f63e 100644 --- a/src/zep_cloud/graph/client.py +++ b/src/zep_cloud/graph/client.py @@ -7,18 +7,21 @@ from ..types.add_triple_response import AddTripleResponse from ..types.clone_graph_response import CloneGraphResponse from ..types.custom_instruction import CustomInstruction +from ..types.detect_config import DetectConfig +from ..types.detect_patterns_response import DetectPatternsResponse from ..types.edge_type import EdgeType from ..types.entity_type import EntityType from ..types.entity_type_response import EntityTypeResponse from ..types.episode import Episode from ..types.episode_data import EpisodeData -from ..types.fact_rating_instruction import FactRatingInstruction from ..types.graph import Graph from ..types.graph_data_type import GraphDataType from ..types.graph_list_response import GraphListResponse from ..types.graph_search_results import GraphSearchResults from ..types.graph_search_scope import GraphSearchScope from ..types.list_custom_instructions_response import ListCustomInstructionsResponse +from ..types.pattern_seeds import PatternSeeds +from ..types.recency_weight import RecencyWeight from ..types.reranker import Reranker from ..types.search_filters import SearchFilters from ..types.success_response import SuccessResponse @@ -350,7 +353,7 @@ def add_batch( request_options: typing.Optional[RequestOptions] = None, ) -> typing.List[Episode]: """ - Add data to the graph in batch mode, processing episodes concurrently. Use only for data that is insensitive to processing order. + Add data to the graph in batch mode. Episodes are processed sequentially in the order provided. Parameters ---------- @@ -403,10 +406,12 @@ def add_fact_triple( graph_id: typing.Optional[str] = OMIT, invalid_at: typing.Optional[str] = OMIT, source_node_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + source_node_labels: typing.Optional[typing.Sequence[str]] = OMIT, source_node_name: typing.Optional[str] = OMIT, source_node_summary: typing.Optional[str] = OMIT, source_node_uuid: typing.Optional[str] = OMIT, target_node_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + target_node_labels: typing.Optional[typing.Sequence[str]] = OMIT, target_node_name: typing.Optional[str] = OMIT, target_node_summary: typing.Optional[str] = OMIT, target_node_uuid: typing.Optional[str] = OMIT, @@ -447,6 +452,9 @@ def add_fact_triple( Additional attributes of the source node. Values must be scalar types (string, number, boolean, or null). Nested objects and arrays are not allowed. + source_node_labels : typing.Optional[typing.Sequence[str]] + The labels for the source node + source_node_name : typing.Optional[str] The name of the source node to add @@ -460,6 +468,9 @@ def add_fact_triple( Additional attributes of the target node. Values must be scalar types (string, number, boolean, or null). Nested objects and arrays are not allowed. + target_node_labels : typing.Optional[typing.Sequence[str]] + The labels for the target node + target_node_name : typing.Optional[str] The name of the target node to add @@ -504,10 +515,12 @@ def add_fact_triple( graph_id=graph_id, invalid_at=invalid_at, source_node_attributes=source_node_attributes, + source_node_labels=source_node_labels, source_node_name=source_node_name, source_node_summary=source_node_summary, source_node_uuid=source_node_uuid, target_node_attributes=target_node_attributes, + target_node_labels=target_node_labels, target_node_name=target_node_name, target_node_summary=target_node_summary, target_node_uuid=target_node_uuid, @@ -574,7 +587,6 @@ def create( *, graph_id: str, description: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Graph: @@ -587,8 +599,6 @@ def create( description : typing.Optional[str] - fact_rating_instruction : typing.Optional[FactRatingInstruction] - name : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -611,11 +621,7 @@ def create( ) """ _response = self._raw_client.create( - graph_id=graph_id, - description=description, - fact_rating_instruction=fact_rating_instruction, - name=name, - request_options=request_options, + graph_id=graph_id, description=description, name=name, request_options=request_options ) return _response.data @@ -624,6 +630,8 @@ def list_all( *, page_number: typing.Optional[int] = None, page_size: typing.Optional[int] = None, + order_by: typing.Optional[str] = None, + asc: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> GraphListResponse: """ @@ -637,6 +645,12 @@ def list_all( page_size : typing.Optional[int] Number of graphs to retrieve per page. + order_by : typing.Optional[str] + Column to sort by (created_at, group_id, name). + + asc : typing.Optional[bool] + Sort in ascending order. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -655,10 +669,93 @@ def list_all( client.graph.list_all( page_number=1, page_size=1, + order_by="order_by", + asc=True, ) """ _response = self._raw_client.list_all( - page_number=page_number, page_size=page_size, request_options=request_options + page_number=page_number, page_size=page_size, order_by=order_by, asc=asc, request_options=request_options + ) + return _response.data + + def detect_patterns( + self, + *, + detect: typing.Optional[DetectConfig] = OMIT, + graph_id: typing.Optional[str] = OMIT, + include_examples: typing.Optional[bool] = OMIT, + limit: typing.Optional[int] = OMIT, + min_occurrences: typing.Optional[int] = OMIT, + recency_weight: typing.Optional[RecencyWeight] = OMIT, + search_filters: typing.Optional[SearchFilters] = OMIT, + seeds: typing.Optional[PatternSeeds] = OMIT, + user_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DetectPatternsResponse: + """ + Detects structural patterns in a knowledge graph including relationship frequencies, + multi-hop paths, co-occurrences, hubs, and clusters. + + Parameters + ---------- + detect : typing.Optional[DetectConfig] + Which pattern types to detect with type-specific configuration. + Omit to detect all types with defaults. + + graph_id : typing.Optional[str] + Graph ID when detecting patterns on a named graph + + include_examples : typing.Optional[bool] + Include example node/edge UUIDs per pattern. Default: false + + limit : typing.Optional[int] + Max patterns to return. Default: 50, Max: 200 + + min_occurrences : typing.Optional[int] + Minimum occurrence count to report a pattern. Default: 2 + + recency_weight : typing.Optional[RecencyWeight] + Exponential half-life decay applied to edge created_at timestamps. + Valid values: none, 7_days, 30_days, 90_days. Default: none + + search_filters : typing.Optional[SearchFilters] + Filters which edges/nodes participate in pattern detection. + Reuses the same filter format as /graph/search. + + seeds : typing.Optional[PatternSeeds] + Seed selection. If omitted, analyzes the entire graph. + + user_id : typing.Optional[str] + User ID when detecting patterns on a user graph + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DetectPatternsResponse + Detected patterns + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.detect_patterns() + """ + _response = self._raw_client.detect_patterns( + detect=detect, + graph_id=graph_id, + include_examples=include_examples, + limit=limit, + min_occurrences=min_occurrences, + recency_weight=recency_weight, + search_filters=search_filters, + seeds=seeds, + user_id=user_id, + request_options=request_options, ) return _response.data @@ -670,8 +767,6 @@ def search( center_node_uuid: typing.Optional[str] = OMIT, graph_id: typing.Optional[str] = OMIT, limit: typing.Optional[int] = OMIT, - min_fact_rating: typing.Optional[float] = OMIT, - min_score: typing.Optional[float] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, reranker: typing.Optional[Reranker] = OMIT, scope: typing.Optional[GraphSearchScope] = OMIT, @@ -699,12 +794,6 @@ def search( limit : typing.Optional[int] The maximum number of facts to retrieve. Defaults to 10. Limited to 50. - min_fact_rating : typing.Optional[float] - The minimum rating by which to filter relevant facts - - min_score : typing.Optional[float] - Deprecated - mmr_lambda : typing.Optional[float] weighting for maximal marginal relevance @@ -745,8 +834,6 @@ def search( center_node_uuid=center_node_uuid, graph_id=graph_id, limit=limit, - min_fact_rating=min_fact_rating, - min_score=min_score, mmr_lambda=mmr_lambda, reranker=reranker, scope=scope, @@ -823,7 +910,6 @@ def update( graph_id: str, *, description: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Graph: @@ -837,8 +923,6 @@ def update( description : typing.Optional[str] - fact_rating_instruction : typing.Optional[FactRatingInstruction] - name : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -861,11 +945,7 @@ def update( ) """ _response = self._raw_client.update( - graph_id, - description=description, - fact_rating_instruction=fact_rating_instruction, - name=name, - request_options=request_options, + graph_id, description=description, name=name, request_options=request_options ) return _response.data @@ -1237,7 +1317,7 @@ async def add_batch( request_options: typing.Optional[RequestOptions] = None, ) -> typing.List[Episode]: """ - Add data to the graph in batch mode, processing episodes concurrently. Use only for data that is insensitive to processing order. + Add data to the graph in batch mode. Episodes are processed sequentially in the order provided. Parameters ---------- @@ -1298,10 +1378,12 @@ async def add_fact_triple( graph_id: typing.Optional[str] = OMIT, invalid_at: typing.Optional[str] = OMIT, source_node_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + source_node_labels: typing.Optional[typing.Sequence[str]] = OMIT, source_node_name: typing.Optional[str] = OMIT, source_node_summary: typing.Optional[str] = OMIT, source_node_uuid: typing.Optional[str] = OMIT, target_node_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + target_node_labels: typing.Optional[typing.Sequence[str]] = OMIT, target_node_name: typing.Optional[str] = OMIT, target_node_summary: typing.Optional[str] = OMIT, target_node_uuid: typing.Optional[str] = OMIT, @@ -1342,6 +1424,9 @@ async def add_fact_triple( Additional attributes of the source node. Values must be scalar types (string, number, boolean, or null). Nested objects and arrays are not allowed. + source_node_labels : typing.Optional[typing.Sequence[str]] + The labels for the source node + source_node_name : typing.Optional[str] The name of the source node to add @@ -1355,6 +1440,9 @@ async def add_fact_triple( Additional attributes of the target node. Values must be scalar types (string, number, boolean, or null). Nested objects and arrays are not allowed. + target_node_labels : typing.Optional[typing.Sequence[str]] + The labels for the target node + target_node_name : typing.Optional[str] The name of the target node to add @@ -1407,10 +1495,12 @@ async def main() -> None: graph_id=graph_id, invalid_at=invalid_at, source_node_attributes=source_node_attributes, + source_node_labels=source_node_labels, source_node_name=source_node_name, source_node_summary=source_node_summary, source_node_uuid=source_node_uuid, target_node_attributes=target_node_attributes, + target_node_labels=target_node_labels, target_node_name=target_node_name, target_node_summary=target_node_summary, target_node_uuid=target_node_uuid, @@ -1485,7 +1575,6 @@ async def create( *, graph_id: str, description: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Graph: @@ -1498,8 +1587,6 @@ async def create( description : typing.Optional[str] - fact_rating_instruction : typing.Optional[FactRatingInstruction] - name : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -1530,11 +1617,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.create( - graph_id=graph_id, - description=description, - fact_rating_instruction=fact_rating_instruction, - name=name, - request_options=request_options, + graph_id=graph_id, description=description, name=name, request_options=request_options ) return _response.data @@ -1543,6 +1626,8 @@ async def list_all( *, page_number: typing.Optional[int] = None, page_size: typing.Optional[int] = None, + order_by: typing.Optional[str] = None, + asc: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> GraphListResponse: """ @@ -1556,6 +1641,12 @@ async def list_all( page_size : typing.Optional[int] Number of graphs to retrieve per page. + order_by : typing.Optional[str] + Column to sort by (created_at, group_id, name). + + asc : typing.Optional[bool] + Sort in ascending order. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1579,13 +1670,104 @@ async def main() -> None: await client.graph.list_all( page_number=1, page_size=1, + order_by="order_by", + asc=True, ) asyncio.run(main()) """ _response = await self._raw_client.list_all( - page_number=page_number, page_size=page_size, request_options=request_options + page_number=page_number, page_size=page_size, order_by=order_by, asc=asc, request_options=request_options + ) + return _response.data + + async def detect_patterns( + self, + *, + detect: typing.Optional[DetectConfig] = OMIT, + graph_id: typing.Optional[str] = OMIT, + include_examples: typing.Optional[bool] = OMIT, + limit: typing.Optional[int] = OMIT, + min_occurrences: typing.Optional[int] = OMIT, + recency_weight: typing.Optional[RecencyWeight] = OMIT, + search_filters: typing.Optional[SearchFilters] = OMIT, + seeds: typing.Optional[PatternSeeds] = OMIT, + user_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> DetectPatternsResponse: + """ + Detects structural patterns in a knowledge graph including relationship frequencies, + multi-hop paths, co-occurrences, hubs, and clusters. + + Parameters + ---------- + detect : typing.Optional[DetectConfig] + Which pattern types to detect with type-specific configuration. + Omit to detect all types with defaults. + + graph_id : typing.Optional[str] + Graph ID when detecting patterns on a named graph + + include_examples : typing.Optional[bool] + Include example node/edge UUIDs per pattern. Default: false + + limit : typing.Optional[int] + Max patterns to return. Default: 50, Max: 200 + + min_occurrences : typing.Optional[int] + Minimum occurrence count to report a pattern. Default: 2 + + recency_weight : typing.Optional[RecencyWeight] + Exponential half-life decay applied to edge created_at timestamps. + Valid values: none, 7_days, 30_days, 90_days. Default: none + + search_filters : typing.Optional[SearchFilters] + Filters which edges/nodes participate in pattern detection. + Reuses the same filter format as /graph/search. + + seeds : typing.Optional[PatternSeeds] + Seed selection. If omitted, analyzes the entire graph. + + user_id : typing.Optional[str] + User ID when detecting patterns on a user graph + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DetectPatternsResponse + Detected patterns + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.detect_patterns() + + + asyncio.run(main()) + """ + _response = await self._raw_client.detect_patterns( + detect=detect, + graph_id=graph_id, + include_examples=include_examples, + limit=limit, + min_occurrences=min_occurrences, + recency_weight=recency_weight, + search_filters=search_filters, + seeds=seeds, + user_id=user_id, + request_options=request_options, ) return _response.data @@ -1597,8 +1779,6 @@ async def search( center_node_uuid: typing.Optional[str] = OMIT, graph_id: typing.Optional[str] = OMIT, limit: typing.Optional[int] = OMIT, - min_fact_rating: typing.Optional[float] = OMIT, - min_score: typing.Optional[float] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, reranker: typing.Optional[Reranker] = OMIT, scope: typing.Optional[GraphSearchScope] = OMIT, @@ -1626,12 +1806,6 @@ async def search( limit : typing.Optional[int] The maximum number of facts to retrieve. Defaults to 10. Limited to 50. - min_fact_rating : typing.Optional[float] - The minimum rating by which to filter relevant facts - - min_score : typing.Optional[float] - Deprecated - mmr_lambda : typing.Optional[float] weighting for maximal marginal relevance @@ -1680,8 +1854,6 @@ async def main() -> None: center_node_uuid=center_node_uuid, graph_id=graph_id, limit=limit, - min_fact_rating=min_fact_rating, - min_score=min_score, mmr_lambda=mmr_lambda, reranker=reranker, scope=scope, @@ -1776,7 +1948,6 @@ async def update( graph_id: str, *, description: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Graph: @@ -1790,8 +1961,6 @@ async def update( description : typing.Optional[str] - fact_rating_instruction : typing.Optional[FactRatingInstruction] - name : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -1822,10 +1991,6 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.update( - graph_id, - description=description, - fact_rating_instruction=fact_rating_instruction, - name=name, - request_options=request_options, + graph_id, description=description, name=name, request_options=request_options ) return _response.data diff --git a/src/zep_cloud/graph/edge/client.py b/src/zep_cloud/graph/edge/client.py index 944c2628..6f767593 100644 --- a/src/zep_cloud/graph/edge/client.py +++ b/src/zep_cloud/graph/edge/client.py @@ -181,6 +181,75 @@ def delete(self, uuid_: str, *, request_options: typing.Optional[RequestOptions] _response = self._raw_client.delete(uuid_, request_options=request_options) return _response.data + def update( + self, + uuid_: str, + *, + attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + expired_at: typing.Optional[str] = OMIT, + fact: typing.Optional[str] = OMIT, + invalid_at: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + valid_at: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> EntityEdge: + """ + Updates an entity edge by UUID. + + Parameters + ---------- + uuid_ : str + Edge UUID + + attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + Updated attributes. Merged with existing attributes. Set a key to null to delete it. + + expired_at : typing.Optional[str] + Updated time at which the edge expires + + fact : typing.Optional[str] + Updated fact for the edge + + invalid_at : typing.Optional[str] + Updated time at which the fact stopped being true + + name : typing.Optional[str] + Updated name (relationship type) for the edge + + valid_at : typing.Optional[str] + Updated time at which the fact becomes true + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EntityEdge + Updated edge + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.edge.update( + uuid_="uuid", + ) + """ + _response = self._raw_client.update( + uuid_, + attributes=attributes, + expired_at=expired_at, + fact=fact, + invalid_at=invalid_at, + name=name, + valid_at=valid_at, + request_options=request_options, + ) + return _response.data + class AsyncEdgeClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -382,3 +451,80 @@ async def main() -> None: """ _response = await self._raw_client.delete(uuid_, request_options=request_options) return _response.data + + async def update( + self, + uuid_: str, + *, + attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + expired_at: typing.Optional[str] = OMIT, + fact: typing.Optional[str] = OMIT, + invalid_at: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + valid_at: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> EntityEdge: + """ + Updates an entity edge by UUID. + + Parameters + ---------- + uuid_ : str + Edge UUID + + attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + Updated attributes. Merged with existing attributes. Set a key to null to delete it. + + expired_at : typing.Optional[str] + Updated time at which the edge expires + + fact : typing.Optional[str] + Updated fact for the edge + + invalid_at : typing.Optional[str] + Updated time at which the fact stopped being true + + name : typing.Optional[str] + Updated name (relationship type) for the edge + + valid_at : typing.Optional[str] + Updated time at which the fact becomes true + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EntityEdge + Updated edge + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.edge.update( + uuid_="uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + uuid_, + attributes=attributes, + expired_at=expired_at, + fact=fact, + invalid_at=invalid_at, + name=name, + valid_at=valid_at, + request_options=request_options, + ) + return _response.data diff --git a/src/zep_cloud/graph/edge/raw_client.py b/src/zep_cloud/graph/edge/raw_client.py index 1c91b11d..2fc8e42a 100644 --- a/src/zep_cloud/graph/edge/raw_client.py +++ b/src/zep_cloud/graph/edge/raw_client.py @@ -311,6 +311,132 @@ def delete( ), ), ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + uuid_: str, + *, + attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + expired_at: typing.Optional[str] = OMIT, + fact: typing.Optional[str] = OMIT, + invalid_at: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + valid_at: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[EntityEdge]: + """ + Updates an entity edge by UUID. + + Parameters + ---------- + uuid_ : str + Edge UUID + + attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + Updated attributes. Merged with existing attributes. Set a key to null to delete it. + + expired_at : typing.Optional[str] + Updated time at which the edge expires + + fact : typing.Optional[str] + Updated fact for the edge + + invalid_at : typing.Optional[str] + Updated time at which the fact stopped being true + + name : typing.Optional[str] + Updated name (relationship type) for the edge + + valid_at : typing.Optional[str] + Updated time at which the fact becomes true + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[EntityEdge] + Updated edge + """ + _response = self._client_wrapper.httpx_client.request( + f"graph/edge/{jsonable_encoder(uuid_)}", + method="PATCH", + json={ + "attributes": attributes, + "expired_at": expired_at, + "fact": fact, + "invalid_at": invalid_at, + "name": name, + "valid_at": valid_at, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EntityEdge, + parse_obj_as( + type_=EntityEdge, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) if _response.status_code == 500: raise InternalServerError( headers=dict(_response.headers), @@ -625,6 +751,132 @@ async def delete( ), ), ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + uuid_: str, + *, + attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + expired_at: typing.Optional[str] = OMIT, + fact: typing.Optional[str] = OMIT, + invalid_at: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + valid_at: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[EntityEdge]: + """ + Updates an entity edge by UUID. + + Parameters + ---------- + uuid_ : str + Edge UUID + + attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + Updated attributes. Merged with existing attributes. Set a key to null to delete it. + + expired_at : typing.Optional[str] + Updated time at which the edge expires + + fact : typing.Optional[str] + Updated fact for the edge + + invalid_at : typing.Optional[str] + Updated time at which the fact stopped being true + + name : typing.Optional[str] + Updated name (relationship type) for the edge + + valid_at : typing.Optional[str] + Updated time at which the fact becomes true + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[EntityEdge] + Updated edge + """ + _response = await self._client_wrapper.httpx_client.request( + f"graph/edge/{jsonable_encoder(uuid_)}", + method="PATCH", + json={ + "attributes": attributes, + "expired_at": expired_at, + "fact": fact, + "invalid_at": invalid_at, + "name": name, + "valid_at": valid_at, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EntityEdge, + parse_obj_as( + type_=EntityEdge, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) if _response.status_code == 500: raise InternalServerError( headers=dict(_response.headers), diff --git a/src/zep_cloud/graph/node/client.py b/src/zep_cloud/graph/node/client.py index f49aee2a..11df633d 100644 --- a/src/zep_cloud/graph/node/client.py +++ b/src/zep_cloud/graph/node/client.py @@ -249,6 +249,60 @@ def delete(self, uuid_: str, *, request_options: typing.Optional[RequestOptions] _response = self._raw_client.delete(uuid_, request_options=request_options) return _response.data + def update( + self, + uuid_: str, + *, + attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + labels: typing.Optional[typing.Sequence[str]] = OMIT, + name: typing.Optional[str] = OMIT, + summary: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> EntityNode: + """ + Updates an entity node by UUID. + + Parameters + ---------- + uuid_ : str + Node UUID + + attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + Updated attributes. Merged with existing attributes. Set a key to null to delete it. + + labels : typing.Optional[typing.Sequence[str]] + Updated labels for the node + + name : typing.Optional[str] + Updated name for the node + + summary : typing.Optional[str] + Updated summary for the node + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EntityNode + Updated node + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.node.update( + uuid_="uuid", + ) + """ + _response = self._raw_client.update( + uuid_, attributes=attributes, labels=labels, name=name, summary=summary, request_options=request_options + ) + return _response.data + class AsyncNodeClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -532,3 +586,65 @@ async def main() -> None: """ _response = await self._raw_client.delete(uuid_, request_options=request_options) return _response.data + + async def update( + self, + uuid_: str, + *, + attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + labels: typing.Optional[typing.Sequence[str]] = OMIT, + name: typing.Optional[str] = OMIT, + summary: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> EntityNode: + """ + Updates an entity node by UUID. + + Parameters + ---------- + uuid_ : str + Node UUID + + attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + Updated attributes. Merged with existing attributes. Set a key to null to delete it. + + labels : typing.Optional[typing.Sequence[str]] + Updated labels for the node + + name : typing.Optional[str] + Updated name for the node + + summary : typing.Optional[str] + Updated summary for the node + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EntityNode + Updated node + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.node.update( + uuid_="uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + uuid_, attributes=attributes, labels=labels, name=name, summary=summary, request_options=request_options + ) + return _response.data diff --git a/src/zep_cloud/graph/node/raw_client.py b/src/zep_cloud/graph/node/raw_client.py index 71235497..5467a088 100644 --- a/src/zep_cloud/graph/node/raw_client.py +++ b/src/zep_cloud/graph/node/raw_client.py @@ -443,6 +443,122 @@ def delete( ), ), ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + uuid_: str, + *, + attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + labels: typing.Optional[typing.Sequence[str]] = OMIT, + name: typing.Optional[str] = OMIT, + summary: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[EntityNode]: + """ + Updates an entity node by UUID. + + Parameters + ---------- + uuid_ : str + Node UUID + + attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + Updated attributes. Merged with existing attributes. Set a key to null to delete it. + + labels : typing.Optional[typing.Sequence[str]] + Updated labels for the node + + name : typing.Optional[str] + Updated name for the node + + summary : typing.Optional[str] + Updated summary for the node + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[EntityNode] + Updated node + """ + _response = self._client_wrapper.httpx_client.request( + f"graph/node/{jsonable_encoder(uuid_)}", + method="PATCH", + json={ + "attributes": attributes, + "labels": labels, + "name": name, + "summary": summary, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EntityNode, + parse_obj_as( + type_=EntityNode, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) if _response.status_code == 500: raise InternalServerError( headers=dict(_response.headers), @@ -887,6 +1003,122 @@ async def delete( ), ), ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + uuid_: str, + *, + attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + labels: typing.Optional[typing.Sequence[str]] = OMIT, + name: typing.Optional[str] = OMIT, + summary: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[EntityNode]: + """ + Updates an entity node by UUID. + + Parameters + ---------- + uuid_ : str + Node UUID + + attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + Updated attributes. Merged with existing attributes. Set a key to null to delete it. + + labels : typing.Optional[typing.Sequence[str]] + Updated labels for the node + + name : typing.Optional[str] + Updated name for the node + + summary : typing.Optional[str] + Updated summary for the node + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[EntityNode] + Updated node + """ + _response = await self._client_wrapper.httpx_client.request( + f"graph/node/{jsonable_encoder(uuid_)}", + method="PATCH", + json={ + "attributes": attributes, + "labels": labels, + "name": name, + "summary": summary, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EntityNode, + parse_obj_as( + type_=EntityNode, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) if _response.status_code == 500: raise InternalServerError( headers=dict(_response.headers), diff --git a/src/zep_cloud/graph/raw_client.py b/src/zep_cloud/graph/raw_client.py index 934d1a66..8999828f 100644 --- a/src/zep_cloud/graph/raw_client.py +++ b/src/zep_cloud/graph/raw_client.py @@ -11,24 +11,28 @@ from ..core.request_options import RequestOptions from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.bad_request_error import BadRequestError +from ..errors.forbidden_error import ForbiddenError from ..errors.internal_server_error import InternalServerError from ..errors.not_found_error import NotFoundError from ..types.add_triple_response import AddTripleResponse from ..types.api_error import ApiError as types_api_error_ApiError from ..types.clone_graph_response import CloneGraphResponse from ..types.custom_instruction import CustomInstruction +from ..types.detect_config import DetectConfig +from ..types.detect_patterns_response import DetectPatternsResponse from ..types.edge_type import EdgeType from ..types.entity_type import EntityType from ..types.entity_type_response import EntityTypeResponse from ..types.episode import Episode from ..types.episode_data import EpisodeData -from ..types.fact_rating_instruction import FactRatingInstruction from ..types.graph import Graph from ..types.graph_data_type import GraphDataType from ..types.graph_list_response import GraphListResponse from ..types.graph_search_results import GraphSearchResults from ..types.graph_search_scope import GraphSearchScope from ..types.list_custom_instructions_response import ListCustomInstructionsResponse +from ..types.pattern_seeds import PatternSeeds +from ..types.recency_weight import RecencyWeight from ..types.reranker import Reranker from ..types.search_filters import SearchFilters from ..types.success_response import SuccessResponse @@ -571,7 +575,7 @@ def add_batch( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[typing.List[Episode]]: """ - Add data to the graph in batch mode, processing episodes concurrently. Use only for data that is insensitive to processing order. + Add data to the graph in batch mode. Episodes are processed sequentially in the order provided. Parameters ---------- @@ -660,10 +664,12 @@ def add_fact_triple( graph_id: typing.Optional[str] = OMIT, invalid_at: typing.Optional[str] = OMIT, source_node_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + source_node_labels: typing.Optional[typing.Sequence[str]] = OMIT, source_node_name: typing.Optional[str] = OMIT, source_node_summary: typing.Optional[str] = OMIT, source_node_uuid: typing.Optional[str] = OMIT, target_node_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + target_node_labels: typing.Optional[typing.Sequence[str]] = OMIT, target_node_name: typing.Optional[str] = OMIT, target_node_summary: typing.Optional[str] = OMIT, target_node_uuid: typing.Optional[str] = OMIT, @@ -704,6 +710,9 @@ def add_fact_triple( Additional attributes of the source node. Values must be scalar types (string, number, boolean, or null). Nested objects and arrays are not allowed. + source_node_labels : typing.Optional[typing.Sequence[str]] + The labels for the source node + source_node_name : typing.Optional[str] The name of the source node to add @@ -717,6 +726,9 @@ def add_fact_triple( Additional attributes of the target node. Values must be scalar types (string, number, boolean, or null). Nested objects and arrays are not allowed. + target_node_labels : typing.Optional[typing.Sequence[str]] + The labels for the target node + target_node_name : typing.Optional[str] The name of the target node to add @@ -752,10 +764,12 @@ def add_fact_triple( "graph_id": graph_id, "invalid_at": invalid_at, "source_node_attributes": source_node_attributes, + "source_node_labels": source_node_labels, "source_node_name": source_node_name, "source_node_summary": source_node_summary, "source_node_uuid": source_node_uuid, "target_node_attributes": target_node_attributes, + "target_node_labels": target_node_labels, "target_node_name": target_node_name, "target_node_summary": target_node_summary, "target_node_uuid": target_node_uuid, @@ -904,7 +918,6 @@ def create( *, graph_id: str, description: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Graph]: @@ -917,8 +930,6 @@ def create( description : typing.Optional[str] - fact_rating_instruction : typing.Optional[FactRatingInstruction] - name : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -934,9 +945,6 @@ def create( method="POST", json={ "description": description, - "fact_rating_instruction": convert_and_respect_annotation_metadata( - object_=fact_rating_instruction, annotation=FactRatingInstruction, direction="write" - ), "graph_id": graph_id, "name": name, }, @@ -992,6 +1000,8 @@ def list_all( *, page_number: typing.Optional[int] = None, page_size: typing.Optional[int] = None, + order_by: typing.Optional[str] = None, + asc: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GraphListResponse]: """ @@ -1005,6 +1015,12 @@ def list_all( page_size : typing.Optional[int] Number of graphs to retrieve per page. + order_by : typing.Optional[str] + Column to sort by (created_at, group_id, name). + + asc : typing.Optional[bool] + Sort in ascending order. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1019,6 +1035,8 @@ def list_all( params={ "pageNumber": page_number, "pageSize": page_size, + "order_by": order_by, + "asc": asc, }, request_options=request_options, ) @@ -1063,6 +1081,153 @@ def list_all( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) + def detect_patterns( + self, + *, + detect: typing.Optional[DetectConfig] = OMIT, + graph_id: typing.Optional[str] = OMIT, + include_examples: typing.Optional[bool] = OMIT, + limit: typing.Optional[int] = OMIT, + min_occurrences: typing.Optional[int] = OMIT, + recency_weight: typing.Optional[RecencyWeight] = OMIT, + search_filters: typing.Optional[SearchFilters] = OMIT, + seeds: typing.Optional[PatternSeeds] = OMIT, + user_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DetectPatternsResponse]: + """ + Detects structural patterns in a knowledge graph including relationship frequencies, + multi-hop paths, co-occurrences, hubs, and clusters. + + Parameters + ---------- + detect : typing.Optional[DetectConfig] + Which pattern types to detect with type-specific configuration. + Omit to detect all types with defaults. + + graph_id : typing.Optional[str] + Graph ID when detecting patterns on a named graph + + include_examples : typing.Optional[bool] + Include example node/edge UUIDs per pattern. Default: false + + limit : typing.Optional[int] + Max patterns to return. Default: 50, Max: 200 + + min_occurrences : typing.Optional[int] + Minimum occurrence count to report a pattern. Default: 2 + + recency_weight : typing.Optional[RecencyWeight] + Exponential half-life decay applied to edge created_at timestamps. + Valid values: none, 7_days, 30_days, 90_days. Default: none + + search_filters : typing.Optional[SearchFilters] + Filters which edges/nodes participate in pattern detection. + Reuses the same filter format as /graph/search. + + seeds : typing.Optional[PatternSeeds] + Seed selection. If omitted, analyzes the entire graph. + + user_id : typing.Optional[str] + User ID when detecting patterns on a user graph + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DetectPatternsResponse] + Detected patterns + """ + _response = self._client_wrapper.httpx_client.request( + "graph/patterns", + method="POST", + json={ + "detect": convert_and_respect_annotation_metadata( + object_=detect, annotation=DetectConfig, direction="write" + ), + "graph_id": graph_id, + "include_examples": include_examples, + "limit": limit, + "min_occurrences": min_occurrences, + "recency_weight": recency_weight, + "search_filters": convert_and_respect_annotation_metadata( + object_=search_filters, annotation=SearchFilters, direction="write" + ), + "seeds": convert_and_respect_annotation_metadata( + object_=seeds, annotation=PatternSeeds, direction="write" + ), + "user_id": user_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DetectPatternsResponse, + parse_obj_as( + type_=DetectPatternsResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + def search( self, *, @@ -1071,8 +1236,6 @@ def search( center_node_uuid: typing.Optional[str] = OMIT, graph_id: typing.Optional[str] = OMIT, limit: typing.Optional[int] = OMIT, - min_fact_rating: typing.Optional[float] = OMIT, - min_score: typing.Optional[float] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, reranker: typing.Optional[Reranker] = OMIT, scope: typing.Optional[GraphSearchScope] = OMIT, @@ -1100,12 +1263,6 @@ def search( limit : typing.Optional[int] The maximum number of facts to retrieve. Defaults to 10. Limited to 50. - min_fact_rating : typing.Optional[float] - The minimum rating by which to filter relevant facts - - min_score : typing.Optional[float] - Deprecated - mmr_lambda : typing.Optional[float] weighting for maximal marginal relevance @@ -1137,8 +1294,6 @@ def search( "center_node_uuid": center_node_uuid, "graph_id": graph_id, "limit": limit, - "min_fact_rating": min_fact_rating, - "min_score": min_score, "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -1339,7 +1494,6 @@ def update( graph_id: str, *, description: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Graph]: @@ -1353,8 +1507,6 @@ def update( description : typing.Optional[str] - fact_rating_instruction : typing.Optional[FactRatingInstruction] - name : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -1370,9 +1522,6 @@ def update( method="PATCH", json={ "description": description, - "fact_rating_instruction": convert_and_respect_annotation_metadata( - object_=fact_rating_instruction, annotation=FactRatingInstruction, direction="write" - ), "name": name, }, headers={ @@ -1968,7 +2117,7 @@ async def add_batch( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[typing.List[Episode]]: """ - Add data to the graph in batch mode, processing episodes concurrently. Use only for data that is insensitive to processing order. + Add data to the graph in batch mode. Episodes are processed sequentially in the order provided. Parameters ---------- @@ -2057,10 +2206,12 @@ async def add_fact_triple( graph_id: typing.Optional[str] = OMIT, invalid_at: typing.Optional[str] = OMIT, source_node_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + source_node_labels: typing.Optional[typing.Sequence[str]] = OMIT, source_node_name: typing.Optional[str] = OMIT, source_node_summary: typing.Optional[str] = OMIT, source_node_uuid: typing.Optional[str] = OMIT, target_node_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, + target_node_labels: typing.Optional[typing.Sequence[str]] = OMIT, target_node_name: typing.Optional[str] = OMIT, target_node_summary: typing.Optional[str] = OMIT, target_node_uuid: typing.Optional[str] = OMIT, @@ -2101,6 +2252,9 @@ async def add_fact_triple( Additional attributes of the source node. Values must be scalar types (string, number, boolean, or null). Nested objects and arrays are not allowed. + source_node_labels : typing.Optional[typing.Sequence[str]] + The labels for the source node + source_node_name : typing.Optional[str] The name of the source node to add @@ -2114,6 +2268,9 @@ async def add_fact_triple( Additional attributes of the target node. Values must be scalar types (string, number, boolean, or null). Nested objects and arrays are not allowed. + target_node_labels : typing.Optional[typing.Sequence[str]] + The labels for the target node + target_node_name : typing.Optional[str] The name of the target node to add @@ -2149,10 +2306,12 @@ async def add_fact_triple( "graph_id": graph_id, "invalid_at": invalid_at, "source_node_attributes": source_node_attributes, + "source_node_labels": source_node_labels, "source_node_name": source_node_name, "source_node_summary": source_node_summary, "source_node_uuid": source_node_uuid, "target_node_attributes": target_node_attributes, + "target_node_labels": target_node_labels, "target_node_name": target_node_name, "target_node_summary": target_node_summary, "target_node_uuid": target_node_uuid, @@ -2301,7 +2460,6 @@ async def create( *, graph_id: str, description: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Graph]: @@ -2314,8 +2472,6 @@ async def create( description : typing.Optional[str] - fact_rating_instruction : typing.Optional[FactRatingInstruction] - name : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -2331,9 +2487,6 @@ async def create( method="POST", json={ "description": description, - "fact_rating_instruction": convert_and_respect_annotation_metadata( - object_=fact_rating_instruction, annotation=FactRatingInstruction, direction="write" - ), "graph_id": graph_id, "name": name, }, @@ -2389,6 +2542,8 @@ async def list_all( *, page_number: typing.Optional[int] = None, page_size: typing.Optional[int] = None, + order_by: typing.Optional[str] = None, + asc: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GraphListResponse]: """ @@ -2402,6 +2557,12 @@ async def list_all( page_size : typing.Optional[int] Number of graphs to retrieve per page. + order_by : typing.Optional[str] + Column to sort by (created_at, group_id, name). + + asc : typing.Optional[bool] + Sort in ascending order. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2416,6 +2577,8 @@ async def list_all( params={ "pageNumber": page_number, "pageSize": page_size, + "order_by": order_by, + "asc": asc, }, request_options=request_options, ) @@ -2460,6 +2623,153 @@ async def list_all( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) + async def detect_patterns( + self, + *, + detect: typing.Optional[DetectConfig] = OMIT, + graph_id: typing.Optional[str] = OMIT, + include_examples: typing.Optional[bool] = OMIT, + limit: typing.Optional[int] = OMIT, + min_occurrences: typing.Optional[int] = OMIT, + recency_weight: typing.Optional[RecencyWeight] = OMIT, + search_filters: typing.Optional[SearchFilters] = OMIT, + seeds: typing.Optional[PatternSeeds] = OMIT, + user_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DetectPatternsResponse]: + """ + Detects structural patterns in a knowledge graph including relationship frequencies, + multi-hop paths, co-occurrences, hubs, and clusters. + + Parameters + ---------- + detect : typing.Optional[DetectConfig] + Which pattern types to detect with type-specific configuration. + Omit to detect all types with defaults. + + graph_id : typing.Optional[str] + Graph ID when detecting patterns on a named graph + + include_examples : typing.Optional[bool] + Include example node/edge UUIDs per pattern. Default: false + + limit : typing.Optional[int] + Max patterns to return. Default: 50, Max: 200 + + min_occurrences : typing.Optional[int] + Minimum occurrence count to report a pattern. Default: 2 + + recency_weight : typing.Optional[RecencyWeight] + Exponential half-life decay applied to edge created_at timestamps. + Valid values: none, 7_days, 30_days, 90_days. Default: none + + search_filters : typing.Optional[SearchFilters] + Filters which edges/nodes participate in pattern detection. + Reuses the same filter format as /graph/search. + + seeds : typing.Optional[PatternSeeds] + Seed selection. If omitted, analyzes the entire graph. + + user_id : typing.Optional[str] + User ID when detecting patterns on a user graph + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DetectPatternsResponse] + Detected patterns + """ + _response = await self._client_wrapper.httpx_client.request( + "graph/patterns", + method="POST", + json={ + "detect": convert_and_respect_annotation_metadata( + object_=detect, annotation=DetectConfig, direction="write" + ), + "graph_id": graph_id, + "include_examples": include_examples, + "limit": limit, + "min_occurrences": min_occurrences, + "recency_weight": recency_weight, + "search_filters": convert_and_respect_annotation_metadata( + object_=search_filters, annotation=SearchFilters, direction="write" + ), + "seeds": convert_and_respect_annotation_metadata( + object_=seeds, annotation=PatternSeeds, direction="write" + ), + "user_id": user_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DetectPatternsResponse, + parse_obj_as( + type_=DetectPatternsResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + async def search( self, *, @@ -2468,8 +2778,6 @@ async def search( center_node_uuid: typing.Optional[str] = OMIT, graph_id: typing.Optional[str] = OMIT, limit: typing.Optional[int] = OMIT, - min_fact_rating: typing.Optional[float] = OMIT, - min_score: typing.Optional[float] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, reranker: typing.Optional[Reranker] = OMIT, scope: typing.Optional[GraphSearchScope] = OMIT, @@ -2497,12 +2805,6 @@ async def search( limit : typing.Optional[int] The maximum number of facts to retrieve. Defaults to 10. Limited to 50. - min_fact_rating : typing.Optional[float] - The minimum rating by which to filter relevant facts - - min_score : typing.Optional[float] - Deprecated - mmr_lambda : typing.Optional[float] weighting for maximal marginal relevance @@ -2534,8 +2836,6 @@ async def search( "center_node_uuid": center_node_uuid, "graph_id": graph_id, "limit": limit, - "min_fact_rating": min_fact_rating, - "min_score": min_score, "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -2738,7 +3038,6 @@ async def update( graph_id: str, *, description: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Graph]: @@ -2752,8 +3051,6 @@ async def update( description : typing.Optional[str] - fact_rating_instruction : typing.Optional[FactRatingInstruction] - name : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -2769,9 +3066,6 @@ async def update( method="PATCH", json={ "description": description, - "fact_rating_instruction": convert_and_respect_annotation_metadata( - object_=fact_rating_instruction, annotation=FactRatingInstruction, direction="write" - ), "name": name, }, headers={ diff --git a/src/zep_cloud/thread/__init__.py b/src/zep_cloud/thread/__init__.py index 047bbca6..4144d499 100644 --- a/src/zep_cloud/thread/__init__.py +++ b/src/zep_cloud/thread/__init__.py @@ -2,7 +2,6 @@ # isort: skip_file -from .types import ThreadGetUserContextRequestMode from . import message -__all__ = ["ThreadGetUserContextRequestMode", "message"] +__all__ = ["message"] diff --git a/src/zep_cloud/thread/client.py b/src/zep_cloud/thread/client.py index 38041731..32d083fa 100644 --- a/src/zep_cloud/thread/client.py +++ b/src/zep_cloud/thread/client.py @@ -14,7 +14,6 @@ from ..types.thread_list_response import ThreadListResponse from .message.client import AsyncMessageClient, MessageClient from .raw_client import AsyncRawThreadClient, RawThreadClient -from .types.thread_get_user_context_request_mode import ThreadGetUserContextRequestMode # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -161,9 +160,7 @@ def get_user_context( self, thread_id: str, *, - min_rating: typing.Optional[float] = None, template_id: typing.Optional[str] = None, - mode: typing.Optional[ThreadGetUserContextRequestMode] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ThreadContextResponse: """ @@ -174,15 +171,9 @@ def get_user_context( thread_id : str The ID of the current thread (for which context is being retrieved). - min_rating : typing.Optional[float] - Deprecated, this field will be removed in a future release. The minimum rating by which to filter relevant facts. - template_id : typing.Optional[str] Optional template ID to use for custom context rendering. - mode : typing.Optional[ThreadGetUserContextRequestMode] - Deprecated, this field will be removed in a future release. Defaults to summary mode. Use basic for lower latency - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -200,13 +191,11 @@ def get_user_context( ) client.thread.get_user_context( thread_id="threadId", - min_rating=1.1, template_id="template_id", - mode="basic", ) """ _response = self._raw_client.get_user_context( - thread_id, min_rating=min_rating, template_id=template_id, mode=mode, request_options=request_options + thread_id, template_id=template_id, request_options=request_options ) return _response.data @@ -555,9 +544,7 @@ async def get_user_context( self, thread_id: str, *, - min_rating: typing.Optional[float] = None, template_id: typing.Optional[str] = None, - mode: typing.Optional[ThreadGetUserContextRequestMode] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ThreadContextResponse: """ @@ -568,15 +555,9 @@ async def get_user_context( thread_id : str The ID of the current thread (for which context is being retrieved). - min_rating : typing.Optional[float] - Deprecated, this field will be removed in a future release. The minimum rating by which to filter relevant facts. - template_id : typing.Optional[str] Optional template ID to use for custom context rendering. - mode : typing.Optional[ThreadGetUserContextRequestMode] - Deprecated, this field will be removed in a future release. Defaults to summary mode. Use basic for lower latency - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -599,16 +580,14 @@ async def get_user_context( async def main() -> None: await client.thread.get_user_context( thread_id="threadId", - min_rating=1.1, template_id="template_id", - mode="basic", ) asyncio.run(main()) """ _response = await self._raw_client.get_user_context( - thread_id, min_rating=min_rating, template_id=template_id, mode=mode, request_options=request_options + thread_id, template_id=template_id, request_options=request_options ) return _response.data diff --git a/src/zep_cloud/thread/raw_client.py b/src/zep_cloud/thread/raw_client.py index 2512090d..8227888c 100644 --- a/src/zep_cloud/thread/raw_client.py +++ b/src/zep_cloud/thread/raw_client.py @@ -22,7 +22,6 @@ from ..types.thread import Thread from ..types.thread_context_response import ThreadContextResponse from ..types.thread_list_response import ThreadListResponse -from .types.thread_get_user_context_request_mode import ThreadGetUserContextRequestMode # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -263,9 +262,7 @@ def get_user_context( self, thread_id: str, *, - min_rating: typing.Optional[float] = None, template_id: typing.Optional[str] = None, - mode: typing.Optional[ThreadGetUserContextRequestMode] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[ThreadContextResponse]: """ @@ -276,15 +273,9 @@ def get_user_context( thread_id : str The ID of the current thread (for which context is being retrieved). - min_rating : typing.Optional[float] - Deprecated, this field will be removed in a future release. The minimum rating by which to filter relevant facts. - template_id : typing.Optional[str] Optional template ID to use for custom context rendering. - mode : typing.Optional[ThreadGetUserContextRequestMode] - Deprecated, this field will be removed in a future release. Defaults to summary mode. Use basic for lower latency - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -297,9 +288,7 @@ def get_user_context( f"threads/{jsonable_encoder(thread_id)}/context", method="GET", params={ - "minRating": min_rating, "template_id": template_id, - "mode": mode, }, request_options=request_options, ) @@ -829,9 +818,7 @@ async def get_user_context( self, thread_id: str, *, - min_rating: typing.Optional[float] = None, template_id: typing.Optional[str] = None, - mode: typing.Optional[ThreadGetUserContextRequestMode] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[ThreadContextResponse]: """ @@ -842,15 +829,9 @@ async def get_user_context( thread_id : str The ID of the current thread (for which context is being retrieved). - min_rating : typing.Optional[float] - Deprecated, this field will be removed in a future release. The minimum rating by which to filter relevant facts. - template_id : typing.Optional[str] Optional template ID to use for custom context rendering. - mode : typing.Optional[ThreadGetUserContextRequestMode] - Deprecated, this field will be removed in a future release. Defaults to summary mode. Use basic for lower latency - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -863,9 +844,7 @@ async def get_user_context( f"threads/{jsonable_encoder(thread_id)}/context", method="GET", params={ - "minRating": min_rating, "template_id": template_id, - "mode": mode, }, request_options=request_options, ) diff --git a/src/zep_cloud/thread/types/__init__.py b/src/zep_cloud/thread/types/__init__.py deleted file mode 100644 index 95d1e565..00000000 --- a/src/zep_cloud/thread/types/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -# isort: skip_file - -from .thread_get_user_context_request_mode import ThreadGetUserContextRequestMode - -__all__ = ["ThreadGetUserContextRequestMode"] diff --git a/src/zep_cloud/thread/types/thread_get_user_context_request_mode.py b/src/zep_cloud/thread/types/thread_get_user_context_request_mode.py deleted file mode 100644 index e0e796bd..00000000 --- a/src/zep_cloud/thread/types/thread_get_user_context_request_mode.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -ThreadGetUserContextRequestMode = typing.Union[typing.Literal["basic", "summary"], typing.Any] diff --git a/src/zep_cloud/types/__init__.py b/src/zep_cloud/types/__init__.py index 5cbf96a7..cf17d528 100644 --- a/src/zep_cloud/types/__init__.py +++ b/src/zep_cloud/types/__init__.py @@ -7,10 +7,14 @@ from .add_triple_response import AddTripleResponse from .api_error import ApiError from .clone_graph_response import CloneGraphResponse +from .cluster_detect_config import ClusterDetectConfig +from .co_occurrence_detect_config import CoOccurrenceDetectConfig from .comparison_operator import ComparisonOperator from .context_template_response import ContextTemplateResponse from .custom_instruction import CustomInstruction from .date_filter import DateFilter +from .detect_config import DetectConfig +from .detect_patterns_response import DetectPatternsResponse from .edge_type import EdgeType from .entity_edge import EntityEdge from .entity_edge_source_target import EntityEdgeSourceTarget @@ -23,8 +27,6 @@ from .episode_data import EpisodeData from .episode_mentions import EpisodeMentions from .episode_response import EpisodeResponse -from .fact_rating_examples import FactRatingExamples -from .fact_rating_instruction import FactRatingInstruction from .get_task_response import GetTaskResponse from .graph import Graph from .graph_data_type import GraphDataType @@ -33,16 +35,22 @@ from .graph_nodes_request import GraphNodesRequest from .graph_search_results import GraphSearchResults from .graph_search_scope import GraphSearchScope +from .hub_detect_config import HubDetectConfig from .list_context_templates_response import ListContextTemplatesResponse from .list_custom_instructions_response import ListCustomInstructionsResponse from .list_user_instructions_response import ListUserInstructionsResponse from .message import Message from .message_list_response import MessageListResponse -from .models_fact_rating_examples import ModelsFactRatingExamples -from .models_fact_rating_instruction import ModelsFactRatingInstruction +from .path_detect_config import PathDetectConfig +from .pattern_example import PatternExample +from .pattern_metadata import PatternMetadata +from .pattern_result import PatternResult +from .pattern_seeds import PatternSeeds from .project_info import ProjectInfo from .project_info_response import ProjectInfoResponse from .property_filter import PropertyFilter +from .recency_weight import RecencyWeight +from .relationship_detect_config import RelationshipDetectConfig from .reranker import Reranker from .role_type import RoleType from .search_filters import SearchFilters @@ -63,10 +71,14 @@ "AddTripleResponse", "ApiError", "CloneGraphResponse", + "ClusterDetectConfig", + "CoOccurrenceDetectConfig", "ComparisonOperator", "ContextTemplateResponse", "CustomInstruction", "DateFilter", + "DetectConfig", + "DetectPatternsResponse", "EdgeType", "EntityEdge", "EntityEdgeSourceTarget", @@ -79,8 +91,6 @@ "EpisodeData", "EpisodeMentions", "EpisodeResponse", - "FactRatingExamples", - "FactRatingInstruction", "GetTaskResponse", "Graph", "GraphDataType", @@ -89,16 +99,22 @@ "GraphNodesRequest", "GraphSearchResults", "GraphSearchScope", + "HubDetectConfig", "ListContextTemplatesResponse", "ListCustomInstructionsResponse", "ListUserInstructionsResponse", "Message", "MessageListResponse", - "ModelsFactRatingExamples", - "ModelsFactRatingInstruction", + "PathDetectConfig", + "PatternExample", + "PatternMetadata", + "PatternResult", + "PatternSeeds", "ProjectInfo", "ProjectInfoResponse", "PropertyFilter", + "RecencyWeight", + "RelationshipDetectConfig", "Reranker", "RoleType", "SearchFilters", diff --git a/src/zep_cloud/types/cluster_detect_config.py b/src/zep_cloud/types/cluster_detect_config.py new file mode 100644 index 00000000..fa051315 --- /dev/null +++ b/src/zep_cloud/types/cluster_detect_config.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ClusterDetectConfig = typing.Dict[str, typing.Optional[typing.Any]] diff --git a/src/zep_cloud/types/fact_rating_examples.py b/src/zep_cloud/types/co_occurrence_detect_config.py similarity index 68% rename from src/zep_cloud/types/fact_rating_examples.py rename to src/zep_cloud/types/co_occurrence_detect_config.py index 0860b284..4bddda33 100644 --- a/src/zep_cloud/types/fact_rating_examples.py +++ b/src/zep_cloud/types/co_occurrence_detect_config.py @@ -6,10 +6,11 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class FactRatingExamples(UniversalBaseModel): - high: typing.Optional[str] = None - low: typing.Optional[str] = None - medium: typing.Optional[str] = None +class CoOccurrenceDetectConfig(UniversalBaseModel): + max_hops: typing.Optional[int] = pydantic.Field(default=None) + """ + Max hops within which to detect co-occurring node types. Default: 3, Max: 5 + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/detect_config.py b/src/zep_cloud/types/detect_config.py new file mode 100644 index 00000000..e9a40b4d --- /dev/null +++ b/src/zep_cloud/types/detect_config.py @@ -0,0 +1,47 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .cluster_detect_config import ClusterDetectConfig +from .co_occurrence_detect_config import CoOccurrenceDetectConfig +from .hub_detect_config import HubDetectConfig +from .path_detect_config import PathDetectConfig +from .relationship_detect_config import RelationshipDetectConfig + + +class DetectConfig(UniversalBaseModel): + clusters: typing.Optional[ClusterDetectConfig] = pydantic.Field(default=None) + """ + Detect tightly interconnected groups (triangle topology) + """ + + co_occurrences: typing.Optional[CoOccurrenceDetectConfig] = pydantic.Field(default=None) + """ + Detect node types that co-occur within k hops + """ + + hubs: typing.Optional[HubDetectConfig] = pydantic.Field(default=None) + """ + Detect highly connected hub nodes (star topology) + """ + + paths: typing.Optional[PathDetectConfig] = pydantic.Field(default=None) + """ + Detect frequent multi-hop connection paths + """ + + relationships: typing.Optional[RelationshipDetectConfig] = pydantic.Field(default=None) + """ + Detect common (source_label, edge_type, target_label) relationship triples + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/detect_patterns_response.py b/src/zep_cloud/types/detect_patterns_response.py new file mode 100644 index 00000000..d952b2f6 --- /dev/null +++ b/src/zep_cloud/types/detect_patterns_response.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .pattern_metadata import PatternMetadata +from .pattern_result import PatternResult + + +class DetectPatternsResponse(UniversalBaseModel): + metadata: typing.Optional[PatternMetadata] = pydantic.Field(default=None) + """ + Statistics about the detection run + """ + + patterns: typing.Optional[typing.List[PatternResult]] = pydantic.Field(default=None) + """ + Detected patterns, sorted by weighted_score descending + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/fact_rating_instruction.py b/src/zep_cloud/types/fact_rating_instruction.py deleted file mode 100644 index 220d1007..00000000 --- a/src/zep_cloud/types/fact_rating_instruction.py +++ /dev/null @@ -1,35 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .fact_rating_examples import FactRatingExamples - - -class FactRatingInstruction(UniversalBaseModel): - examples: typing.Optional[FactRatingExamples] = pydantic.Field(default=None) - """ - Examples is a list of examples that demonstrate how facts might be rated based on your instruction. You should provide - an example of a highly rated example, a low rated example, and a medium (or in between example). For example, if you are rating - based on relevance to a trip planning application, your examples might be: - High: "Joe's dream vacation is Bali" - Medium: "Joe has a fear of flying", - Low: "Joe's favorite food is Japanese", - """ - - instruction: typing.Optional[str] = pydantic.Field(default=None) - """ - A string describing how to rate facts as they apply to your application. A trip planning application may - use something like "relevancy to planning a trip, the user's preferences when traveling, - or the user's travel history." - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/graph.py b/src/zep_cloud/types/graph.py index 776c757f..62defa62 100644 --- a/src/zep_cloud/types/graph.py +++ b/src/zep_cloud/types/graph.py @@ -6,13 +6,11 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata -from .fact_rating_instruction import FactRatingInstruction class Graph(UniversalBaseModel): created_at: typing.Optional[str] = None description: typing.Optional[str] = None - fact_rating_instruction: typing.Optional[FactRatingInstruction] = None graph_id: typing.Optional[str] = None id: typing.Optional[int] = None name: typing.Optional[str] = None diff --git a/src/zep_cloud/types/hub_detect_config.py b/src/zep_cloud/types/hub_detect_config.py new file mode 100644 index 00000000..ca45f15d --- /dev/null +++ b/src/zep_cloud/types/hub_detect_config.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class HubDetectConfig(UniversalBaseModel): + min_degree: typing.Optional[int] = pydantic.Field(default=None) + """ + Minimum number of connections for a node to be considered a hub. Default: 3, Min: 2 + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/message_list_response.py b/src/zep_cloud/types/message_list_response.py index fe285240..9a7b8811 100644 --- a/src/zep_cloud/types/message_list_response.py +++ b/src/zep_cloud/types/message_list_response.py @@ -18,6 +18,11 @@ class MessageListResponse(UniversalBaseModel): The number of messages returned. """ + thread_created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The thread creation timestamp. + """ + total_count: typing.Optional[int] = pydantic.Field(default=None) """ The total number of messages. diff --git a/src/zep_cloud/types/models_fact_rating_instruction.py b/src/zep_cloud/types/models_fact_rating_instruction.py deleted file mode 100644 index 92901226..00000000 --- a/src/zep_cloud/types/models_fact_rating_instruction.py +++ /dev/null @@ -1,35 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .models_fact_rating_examples import ModelsFactRatingExamples - - -class ModelsFactRatingInstruction(UniversalBaseModel): - examples: typing.Optional[ModelsFactRatingExamples] = pydantic.Field(default=None) - """ - Examples is a list of examples that demonstrate how facts might be rated based on your instruction. You should provide - an example of a highly rated example, a low rated example, and a medium (or in between example). For example, if you are rating - based on relevance to a trip planning application, your examples might be: - High: "Joe's dream vacation is Bali" - Medium: "Joe has a fear of flying", - Low: "Joe's favorite food is Japanese", - """ - - instruction: typing.Optional[str] = pydantic.Field(default=None) - """ - A string describing how to rate facts as they apply to your application. A trip planning application may - use something like "relevancy to planning a trip, the user's preferences when traveling, - or the user's travel history." - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/models_fact_rating_examples.py b/src/zep_cloud/types/path_detect_config.py similarity index 70% rename from src/zep_cloud/types/models_fact_rating_examples.py rename to src/zep_cloud/types/path_detect_config.py index b639f416..e5921b09 100644 --- a/src/zep_cloud/types/models_fact_rating_examples.py +++ b/src/zep_cloud/types/path_detect_config.py @@ -6,10 +6,11 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class ModelsFactRatingExamples(UniversalBaseModel): - high: typing.Optional[str] = None - low: typing.Optional[str] = None - medium: typing.Optional[str] = None +class PathDetectConfig(UniversalBaseModel): + max_hops: typing.Optional[int] = pydantic.Field(default=None) + """ + Max hops from seed nodes for path detection. Default: 3, Max: 5 + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/pattern_example.py b/src/zep_cloud/types/pattern_example.py new file mode 100644 index 00000000..52360db2 --- /dev/null +++ b/src/zep_cloud/types/pattern_example.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class PatternExample(UniversalBaseModel): + edge_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Edge UUIDs involved in this instance + """ + + node_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Node UUIDs involved in this instance + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/pattern_metadata.py b/src/zep_cloud/types/pattern_metadata.py new file mode 100644 index 00000000..cfc36bdd --- /dev/null +++ b/src/zep_cloud/types/pattern_metadata.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class PatternMetadata(UniversalBaseModel): + edges_analyzed: typing.Optional[int] = pydantic.Field(default=None) + """ + Number of edges analyzed + """ + + elapsed_ms: typing.Optional[int] = pydantic.Field(default=None) + """ + Elapsed time in milliseconds + """ + + nodes_analyzed: typing.Optional[int] = pydantic.Field(default=None) + """ + Number of unique nodes analyzed + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/pattern_result.py b/src/zep_cloud/types/pattern_result.py new file mode 100644 index 00000000..072df1b2 --- /dev/null +++ b/src/zep_cloud/types/pattern_result.py @@ -0,0 +1,53 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .pattern_example import PatternExample + + +class PatternResult(UniversalBaseModel): + description: typing.Optional[str] = pydantic.Field(default=None) + """ + Human-readable description of the pattern + """ + + edge_types: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Edge types in the pattern structure + """ + + examples: typing.Optional[typing.List[PatternExample]] = pydantic.Field(default=None) + """ + Example instances (only populated when include_examples is true) + """ + + node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Node labels in the pattern structure + """ + + occurrences: typing.Optional[int] = pydantic.Field(default=None) + """ + Raw occurrence count (always unweighted) + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + Pattern type: relationship, path, co_occurrence, hub, cluster + """ + + weighted_score: typing.Optional[float] = pydantic.Field(default=None) + """ + Weighted sum — equals occurrences when recency_weight is "none" + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/pattern_seeds.py b/src/zep_cloud/types/pattern_seeds.py new file mode 100644 index 00000000..35d843fb --- /dev/null +++ b/src/zep_cloud/types/pattern_seeds.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class PatternSeeds(UniversalBaseModel): + edge_types: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + All endpoints of these edge types become seeds + """ + + node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + All nodes with these labels become seeds + """ + + node_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Specific node UUIDs to analyze around + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/recency_weight.py b/src/zep_cloud/types/recency_weight.py new file mode 100644 index 00000000..18d33ada --- /dev/null +++ b/src/zep_cloud/types/recency_weight.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +RecencyWeight = typing.Union[typing.Literal["none", "7_days", "30_days", "90_days"], typing.Any] diff --git a/src/zep_cloud/types/relationship_detect_config.py b/src/zep_cloud/types/relationship_detect_config.py new file mode 100644 index 00000000..6339bd36 --- /dev/null +++ b/src/zep_cloud/types/relationship_detect_config.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +RelationshipDetectConfig = typing.Dict[str, typing.Optional[typing.Any]] diff --git a/src/zep_cloud/types/user.py b/src/zep_cloud/types/user.py index 6d47f412..5a41a698 100644 --- a/src/zep_cloud/types/user.py +++ b/src/zep_cloud/types/user.py @@ -6,7 +6,6 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata -from .models_fact_rating_instruction import ModelsFactRatingInstruction class User(UniversalBaseModel): @@ -14,7 +13,6 @@ class User(UniversalBaseModel): deleted_at: typing.Optional[str] = None disable_default_ontology: typing.Optional[bool] = None email: typing.Optional[str] = None - fact_rating_instruction: typing.Optional[ModelsFactRatingInstruction] = None first_name: typing.Optional[str] = None id: typing.Optional[int] = None last_name: typing.Optional[str] = None diff --git a/src/zep_cloud/user/client.py b/src/zep_cloud/user/client.py index ac2be954..79e1ec4e 100644 --- a/src/zep_cloud/user/client.py +++ b/src/zep_cloud/user/client.py @@ -4,7 +4,6 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.request_options import RequestOptions -from ..types.fact_rating_instruction import FactRatingInstruction from ..types.list_user_instructions_response import ListUserInstructionsResponse from ..types.success_response import SuccessResponse from ..types.thread import Thread @@ -159,7 +158,6 @@ def add( user_id: str, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, @@ -179,9 +177,6 @@ def add( email : typing.Optional[str] The email address of the user. - fact_rating_instruction : typing.Optional[FactRatingInstruction] - Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - first_name : typing.Optional[str] The first name of the user. @@ -214,7 +209,6 @@ def add( user_id=user_id, disable_default_ontology=disable_default_ontology, email=email, - fact_rating_instruction=fact_rating_instruction, first_name=first_name, last_name=last_name, metadata=metadata, @@ -227,6 +221,9 @@ def list_ordered( *, page_number: typing.Optional[int] = None, page_size: typing.Optional[int] = None, + search: typing.Optional[str] = None, + order_by: typing.Optional[str] = None, + asc: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> UserListResponse: """ @@ -240,6 +237,15 @@ def list_ordered( page_size : typing.Optional[int] Number of users to retrieve per page + search : typing.Optional[str] + Search term for filtering users by user_id, name, or email + + order_by : typing.Optional[str] + Column to sort by (created_at, user_id, email) + + asc : typing.Optional[bool] + Sort in ascending order + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -258,10 +264,18 @@ def list_ordered( client.user.list_ordered( page_number=1, page_size=1, + search="search", + order_by="order_by", + asc=True, ) """ _response = self._raw_client.list_ordered( - page_number=page_number, page_size=page_size, request_options=request_options + page_number=page_number, + page_size=page_size, + search=search, + order_by=order_by, + asc=asc, + request_options=request_options, ) return _response.data @@ -333,7 +347,6 @@ def update( *, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, @@ -353,9 +366,6 @@ def update( email : typing.Optional[str] The email address of the user. - fact_rating_instruction : typing.Optional[FactRatingInstruction] - Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - first_name : typing.Optional[str] The first name of the user. @@ -388,7 +398,6 @@ def update( user_id, disable_default_ontology=disable_default_ontology, email=email, - fact_rating_instruction=fact_rating_instruction, first_name=first_name, last_name=last_name, metadata=metadata, @@ -659,7 +668,6 @@ async def add( user_id: str, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, @@ -679,9 +687,6 @@ async def add( email : typing.Optional[str] The email address of the user. - fact_rating_instruction : typing.Optional[FactRatingInstruction] - Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - first_name : typing.Optional[str] The first name of the user. @@ -722,7 +727,6 @@ async def main() -> None: user_id=user_id, disable_default_ontology=disable_default_ontology, email=email, - fact_rating_instruction=fact_rating_instruction, first_name=first_name, last_name=last_name, metadata=metadata, @@ -735,6 +739,9 @@ async def list_ordered( *, page_number: typing.Optional[int] = None, page_size: typing.Optional[int] = None, + search: typing.Optional[str] = None, + order_by: typing.Optional[str] = None, + asc: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> UserListResponse: """ @@ -748,6 +755,15 @@ async def list_ordered( page_size : typing.Optional[int] Number of users to retrieve per page + search : typing.Optional[str] + Search term for filtering users by user_id, name, or email + + order_by : typing.Optional[str] + Column to sort by (created_at, user_id, email) + + asc : typing.Optional[bool] + Sort in ascending order + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -771,13 +787,21 @@ async def main() -> None: await client.user.list_ordered( page_number=1, page_size=1, + search="search", + order_by="order_by", + asc=True, ) asyncio.run(main()) """ _response = await self._raw_client.list_ordered( - page_number=page_number, page_size=page_size, request_options=request_options + page_number=page_number, + page_size=page_size, + search=search, + order_by=order_by, + asc=asc, + request_options=request_options, ) return _response.data @@ -865,7 +889,6 @@ async def update( *, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, @@ -885,9 +908,6 @@ async def update( email : typing.Optional[str] The email address of the user. - fact_rating_instruction : typing.Optional[FactRatingInstruction] - Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - first_name : typing.Optional[str] The first name of the user. @@ -928,7 +948,6 @@ async def main() -> None: user_id, disable_default_ontology=disable_default_ontology, email=email, - fact_rating_instruction=fact_rating_instruction, first_name=first_name, last_name=last_name, metadata=metadata, diff --git a/src/zep_cloud/user/raw_client.py b/src/zep_cloud/user/raw_client.py index 417fd400..e6bed02c 100644 --- a/src/zep_cloud/user/raw_client.py +++ b/src/zep_cloud/user/raw_client.py @@ -14,7 +14,6 @@ from ..errors.internal_server_error import InternalServerError from ..errors.not_found_error import NotFoundError from ..types.api_error import ApiError as types_api_error_ApiError -from ..types.fact_rating_instruction import FactRatingInstruction from ..types.list_user_instructions_response import ListUserInstructionsResponse from ..types.success_response import SuccessResponse from ..types.thread import Thread @@ -267,7 +266,6 @@ def add( user_id: str, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, @@ -287,9 +285,6 @@ def add( email : typing.Optional[str] The email address of the user. - fact_rating_instruction : typing.Optional[FactRatingInstruction] - Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - first_name : typing.Optional[str] The first name of the user. @@ -313,9 +308,6 @@ def add( json={ "disable_default_ontology": disable_default_ontology, "email": email, - "fact_rating_instruction": convert_and_respect_annotation_metadata( - object_=fact_rating_instruction, annotation=FactRatingInstruction, direction="write" - ), "first_name": first_name, "last_name": last_name, "metadata": metadata, @@ -373,6 +365,9 @@ def list_ordered( *, page_number: typing.Optional[int] = None, page_size: typing.Optional[int] = None, + search: typing.Optional[str] = None, + order_by: typing.Optional[str] = None, + asc: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[UserListResponse]: """ @@ -386,6 +381,15 @@ def list_ordered( page_size : typing.Optional[int] Number of users to retrieve per page + search : typing.Optional[str] + Search term for filtering users by user_id, name, or email + + order_by : typing.Optional[str] + Column to sort by (created_at, user_id, email) + + asc : typing.Optional[bool] + Sort in ascending order + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -400,6 +404,9 @@ def list_ordered( params={ "pageNumber": page_number, "pageSize": page_size, + "search": search, + "order_by": order_by, + "asc": asc, }, request_options=request_options, ) @@ -578,7 +585,6 @@ def update( *, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, @@ -598,9 +604,6 @@ def update( email : typing.Optional[str] The email address of the user. - fact_rating_instruction : typing.Optional[FactRatingInstruction] - Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - first_name : typing.Optional[str] The first name of the user. @@ -624,9 +627,6 @@ def update( json={ "disable_default_ontology": disable_default_ontology, "email": email, - "fact_rating_instruction": convert_and_respect_annotation_metadata( - object_=fact_rating_instruction, annotation=FactRatingInstruction, direction="write" - ), "first_name": first_name, "last_name": last_name, "metadata": metadata, @@ -1114,7 +1114,6 @@ async def add( user_id: str, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, @@ -1134,9 +1133,6 @@ async def add( email : typing.Optional[str] The email address of the user. - fact_rating_instruction : typing.Optional[FactRatingInstruction] - Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - first_name : typing.Optional[str] The first name of the user. @@ -1160,9 +1156,6 @@ async def add( json={ "disable_default_ontology": disable_default_ontology, "email": email, - "fact_rating_instruction": convert_and_respect_annotation_metadata( - object_=fact_rating_instruction, annotation=FactRatingInstruction, direction="write" - ), "first_name": first_name, "last_name": last_name, "metadata": metadata, @@ -1220,6 +1213,9 @@ async def list_ordered( *, page_number: typing.Optional[int] = None, page_size: typing.Optional[int] = None, + search: typing.Optional[str] = None, + order_by: typing.Optional[str] = None, + asc: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[UserListResponse]: """ @@ -1233,6 +1229,15 @@ async def list_ordered( page_size : typing.Optional[int] Number of users to retrieve per page + search : typing.Optional[str] + Search term for filtering users by user_id, name, or email + + order_by : typing.Optional[str] + Column to sort by (created_at, user_id, email) + + asc : typing.Optional[bool] + Sort in ascending order + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1247,6 +1252,9 @@ async def list_ordered( params={ "pageNumber": page_number, "pageSize": page_size, + "search": search, + "order_by": order_by, + "asc": asc, }, request_options=request_options, ) @@ -1427,7 +1435,6 @@ async def update( *, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, - fact_rating_instruction: typing.Optional[FactRatingInstruction] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, @@ -1447,9 +1454,6 @@ async def update( email : typing.Optional[str] The email address of the user. - fact_rating_instruction : typing.Optional[FactRatingInstruction] - Deprecated: this field will be removed in a future release. Optional instruction to use for fact rating. - first_name : typing.Optional[str] The first name of the user. @@ -1473,9 +1477,6 @@ async def update( json={ "disable_default_ontology": disable_default_ontology, "email": email, - "fact_rating_instruction": convert_and_respect_annotation_metadata( - object_=fact_rating_instruction, annotation=FactRatingInstruction, direction="write" - ), "first_name": first_name, "last_name": last_name, "metadata": metadata,