diff --git a/.fern/metadata.json b/.fern/metadata.json index ceeaa835..e17d2693 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -11,6 +11,6 @@ "exported_class_name": "Zep" } }, - "originGitCommit": "6eab49e9f904a487d71c9e469a8b3c63a8e2eb5d", - "sdkVersion": "4.0.0a4" + "originGitCommit": "70d7aaa9c19f07072ca0c09b2e89a8f3c87001d4", + "sdkVersion": "4.0.0a5" } \ No newline at end of file diff --git a/.fern/replay.lock b/.fern/replay.lock index c48f2e31..a25ea8cb 100644 --- a/.fern/replay.lock +++ b/.fern/replay.lock @@ -30,5 +30,317 @@ generations: cli_version: unknown generator_versions: fernapi/fern-python-sdk: 4.64.1 -current_generation: e0584ce4f4a2c870a736d4981e6cc68167b4e13b -patches: [] + - commit_sha: 307ba9f1f528288490ca0530f925b2ee22fe77a5 + tree_hash: e6a6f1e283c7c93456d6e36cb5819404d436f76e + timestamp: 2026-08-26T22:40:25.620Z + cli_version: unknown + generator_versions: + fernapi/fern-python-sdk: 4.64.1 +current_generation: 307ba9f1f528288490ca0530f925b2ee22fe77a5 +patches: + - id: patch-082f322d + content_hash: sha256:224b66a70143bfc3108720a64cc8e3347d9918ced9061c366471f239407f391a + original_commit: 082f322d1bd077cff00e3630500ac6187251a000 + original_message: Let an ontology field opt out, and fix the README (#348) + original_author: Pavlo Paliychuk + base_generation: 307ba9f1f528288490ca0530f925b2ee22fe77a5 + files: + - README.md + patch_content: | + diff --git a/README.md b/README.md + index 08ab94f..7775bfb 100644 + --- a/README.md + +++ b/README.md + @@ -32,78 +32,18 @@ pip install zep-cloud + > [!NOTE] + > Zep Cloud [overview](https://help.getzep.com/concepts) and [cloud sdk guide](https://help.getzep.com/sdks). + + -### Community Installation + -```bash + -pip install zep-python + -``` + -> [!NOTE] + -> Zep Community Edition [quick start](https://help.getzep.com/ce/quickstart) and [sdk guide](https://help.getzep.com/ce/sdks). + - + -### Zep v0.x Compatible SDK + -You can install Zep v0.x compatible sdk by running: + -```bash + -pip install "zep-python>=1.5.0,<2.0.0" + -``` + -> [!NOTE] + -> Zep v0.x [quick start](https://help.getzep.com/ce/legacy/deployment/quickstart) and [sdk guide](https://help.getzep.com/ce/legacy/sdk). + - + ### How Zep works + + Zep persists and recalls chat histories, and automatically generates summaries and other artifacts from these chat histories. It also embeds messages and summaries, enabling you to search Zep for relevant context from past conversations. Zep does all of this asynchronously, ensuring these operations don't impact your user's chat experience. Data is persisted to database, allowing you to scale out when growth demands. + + -Zep also provides a simple, easy to use abstraction for document vector search called Document Collections. This is designed to complement Zep's core context features, but is not designed to be a general purpose vector database. + - + Zep allows you to be more intentional about constructing your prompt: + 1. automatically adding a few recent messages, with the number customized for your app; + 2. a summary of recent conversations prior to the messages above; + 3. and/or contextually relevant summaries or messages surfaced from the entire chat session. + -4. and/or relevant Business data from Zep Document Collections. + - + -Zep Cloud offers: + -- **Fact Extraction:** Automatically build fact tables from conversations, without having to define a data schema upfront. + -- **Dialog Classification:** Instantly and accurately classify chat dialog. Understand user intent and emotion, segment users, and more. Route chains based on semantic context, and trigger events. + -- **Structured Data Extraction:** Quickly extract business data from chat conversations using a schema you define. Understand what your Assistant should ask for next in order to complete its task. + + You will also need to provide a Zep Project API key to your zep client. + You can find out about zep projects in our [cloud docs](https://help.getzep.com/projects.html) + + -### Using LangChain Zep Classes with `zep-python` + - + -(Currently only available on release candidate versions) + - + -In the pre-release version `zep-python` sdk comes with `ZepChatMessageHistory` and `ZepVectorStore` + -classes that are compatible with [LangChain's Python expression language](https://python.langchain.com/docs/expression_language/) + - + -In order to use these classes in your application, you need to make sure that you have + -`langchain_core` package installed, please refer to [Langchain's docs installation section](https://python.langchain.com/docs/get_started/installation#langchain-core). + - + -We support `langchain_core@>=0.1.3<0.2.0` + - + -You can import these classes in the following way: + - + -```python + -from zep_cloud.langchain import ZepChatMessageHistory, ZepVectorStore + -``` + - + -### Running Examples + -You will need to set the following environment variables to run examples in the `examples` directory: + - + -```dotenv + -# Please use examples/.env.example as a template for .env file + - + -# Required + -ZEP_API_KEY=# Your Zep Project API Key + -ZEP_COLLECTION=# used in ingestion script and in vector store examples + -OPENAI_API_KEY=# Your OpenAI API Key + - + -# Optional (If you want to use langsmith with LangServe Sample App) + -LANGCHAIN_TRACING_V2=true + -LANGCHAIN_API_KEY= + -LANGCHAIN_PROJECT=# If not specified, defaults to "default" + -``` + - + - + - + ## Installation + + ```sh + theirs_snapshot: + README.md: | + # Zep Python Library + + [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Fgetzep%2Fzep-python) + [![pypi](https://img.shields.io/pypi/v/zep-cloud)](https://pypi.python.org/pypi/zep-cloud) + + The Zep Python library provides convenient access to the Zep APIs from Python. + + ## Table of Contents + + - [What Is Zep 💬](#what-is-zep-) + - [Installation](#installation) + - [Reference](#reference) + - [Usage](#usage) + - [Async Client](#async-client) + - [Exception Handling](#exception-handling) + - [Pagination](#pagination) + - [Advanced](#advanced) + - [Access Raw Response Data](#access-raw-response-data) + - [Retries](#retries) + - [Timeouts](#timeouts) + - [Custom Client](#custom-client) + - [Contributing](#contributing) + + ## What is Zep? 💬 + Zep is a context engineering platform for AI Assistant apps. With Zep, you can provide AI assistants with the ability to recall past conversations, no matter how distant, while also reducing hallucinations, latency, and cost. + + ### Cloud Installation + You can install the Zep Cloud SDK by running: + ```bash + pip install zep-cloud + ``` + > [!NOTE] + > Zep Cloud [overview](https://help.getzep.com/concepts) and [cloud sdk guide](https://help.getzep.com/sdks). + + ### How Zep works + + Zep persists and recalls chat histories, and automatically generates summaries and other artifacts from these chat histories. It also embeds messages and summaries, enabling you to search Zep for relevant context from past conversations. Zep does all of this asynchronously, ensuring these operations don't impact your user's chat experience. Data is persisted to database, allowing you to scale out when growth demands. + + Zep allows you to be more intentional about constructing your prompt: + 1. automatically adding a few recent messages, with the number customized for your app; + 2. a summary of recent conversations prior to the messages above; + 3. and/or contextually relevant summaries or messages surfaced from the entire chat session. + + You will also need to provide a Zep Project API key to your zep client. + You can find out about zep projects in our [cloud docs](https://help.getzep.com/projects.html) + + ## Installation + + ```sh + pip install zep-cloud + ``` + + ## Reference + + A full reference for this library is available [here](https://github.com/getzep/zep-python/blob/HEAD/./reference.md). + + ## Usage + + Instantiate and use the client with the following: + + ```python + from zep_cloud import Zep + + client = Zep( + api_key="", + ) + + client.batch.create() + ``` + + ## Async Client + + The SDK also exports an `async` client so that you can make non-blocking calls to our API. Note that if you are constructing an Async httpx client class to pass into this client, use `httpx.AsyncClient()` instead of `httpx.Client()` (e.g. for the `httpx_client` parameter of this client). + + ```python + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="", + ) + + + async def main() -> None: + await client.batch.create() + + + asyncio.run(main()) + ``` + + ## Exception Handling + + When the API returns a non-success status code (4xx or 5xx response), a subclass of the following error + will be thrown. + + ```python + from zep_cloud.core.api_error import ApiError + + try: + client.batch.create(...) + except ApiError as e: + print(e.status_code) + print(e.body) + ``` + + ## Pagination + + Paginated requests will return a `SyncPager` or `AsyncPager`, which can be used as generators for the underlying object. + + ```python + from zep_cloud import Zep + + client = Zep( + api_key="", + ) + + client.batch.list( + limit=1, + cursor="cursor", + status="status", + ) + ``` + + ```python + # You can also iterate through pages and access the typed response per page + pager = client.batch.list(...) + for page in pager.iter_pages(): + print(page.response) # access the typed response for each page + for item in page: + print(item) + ``` + + ## Advanced + + ### Access Raw Response Data + + The SDK provides access to raw response data, including headers, through the `.with_raw_response` property. + The `.with_raw_response` property returns a "raw" client that can be used to access the `.headers` and `.data` attributes. + + ```python + from zep_cloud import Zep + + client = Zep(...) + response = client.batch.with_raw_response.create(...) + print(response.headers) # access the response headers + print(response.status_code) # access the response status code + print(response.data) # access the underlying object + ``` + + ### Retries + + The SDK is instrumented with automatic retries with exponential backoff. A request will be retried as long + as the request is deemed retryable and the number of retry attempts has not grown larger than the configured + retry limit (default: 2). + + A request is deemed retryable when any of the following HTTP status codes is returned: + + - [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout) + - [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests) + - [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors) + + Use the `max_retries` request option to configure this behavior. + + ```python + client.batch.create(..., request_options={ + "max_retries": 1 + }) + ``` + + ### Timeouts + + The SDK defaults to a 60 second timeout. You can configure this with a timeout option at the client or request level. + + ```python + from zep_cloud import Zep + + client = Zep(..., timeout=20.0) + + # Override timeout for a specific method + client.batch.create(..., request_options={ + "timeout_in_seconds": 1 + }) + ``` + + ### Custom Client + + You can override the `httpx` client to customize it for your use-case. Some common use-cases include support for proxies + and transports. + + ```python + import httpx + from zep_cloud import Zep + + client = Zep( + ..., + httpx_client=httpx.Client( + proxy="http://my.test.proxy.example.com", + transport=httpx.HTTPTransport(local_address="0.0.0.0"), + ), + ) + ``` + + ## Contributing + + While we value open-source contributions to this SDK, this library is generated programmatically. + Additions made directly to this library would have to be moved over to our generation code, + otherwise they would be overwritten upon the next generated release. Feel free to open a PR as + a proof of concept, but know that we will not be able to merge it as-is. We suggest opening + an issue first to discuss with us! + + On the other hand, contributions to the README are always very welcome! diff --git a/pyproject.toml b/pyproject.toml index 287e4f22..44c0dec5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,11 @@ [project] name = "zep-cloud" dynamic = ["version"] -version = "4.0.0a4" +version = "4.0.0a5" [tool.poetry] name = "zep-cloud" -version = "4.0.0a4" +version = "4.0.0a5" description = "" readme = "README.md" authors = [] diff --git a/reference.md b/reference.md index fa34d1fd..3da22a1d 100644 --- a/reference.md +++ b/reference.md @@ -115,6 +115,9 @@ client.batch.create()
**ignore_roles:** `typing.Optional[typing.List[str]]` + +Message roles to skip during graph extraction for thread message items in +this batch.
@@ -122,7 +125,7 @@ client.batch.create()
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to store on the batch.
@@ -131,6 +134,9 @@ client.batch.create()
**strict_ontology:** `typing.Optional[bool]` + +When true, prevents extraction of generic entity nodes that do not match +the configured ontology for episodes in this batch.
@@ -358,7 +364,7 @@ client.batch.list_items(
```python -from zep_cloud import Zep +from zep_cloud import Zep, BatchItemInput from zep_cloud.environment import ZepEnvironment client = Zep( @@ -368,6 +374,11 @@ client = Zep( client.batch.add_items( batch_uuid="batch_uuid", + items=[ + BatchItemInput( + type="graph_episode", + ) + ], ) ``` @@ -392,7 +403,7 @@ client.batch.add_items(
-**items:** `typing.Optional[typing.List[typing.Dict[str, typing.Any]]]` +**items:** `typing.List[BatchItemInput]` — The batch items to append, each identified by its type field.
@@ -585,7 +596,7 @@ client.context.list_templates(
-**name:** `typing.Optional[str]` +**name:** `typing.Optional[str]` — Filters results to the context template with this exact name.
@@ -828,7 +839,7 @@ client.graph.create()
-**description:** `typing.Optional[str]` +**description:** `typing.Optional[str]` — A description of the graph.
@@ -836,7 +847,7 @@ client.graph.create()
-**graph_id:** `typing.Optional[str]` +**graph_id:** `typing.Optional[str]` — An optional developer-assigned identifier for the graph.
@@ -844,7 +855,7 @@ client.graph.create()
-**name:** `typing.Optional[str]` +**name:** `typing.Optional[str]` — A display name for the graph.
@@ -852,7 +863,7 @@ client.graph.create()
-**time_zone:** `typing.Optional[str]` +**time_zone:** `typing.Optional[str]` — The graph's IANA time zone.
@@ -947,6 +958,9 @@ client.graph.list(
**search:** `typing.Optional[str]` + +Filters results to graphs whose name, description, or graph ID contains +this text.
@@ -1188,7 +1202,7 @@ client.graph.update(
-**description:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**description:** `typing.Optional[str]` — A description of the graph.
@@ -1196,7 +1210,7 @@ client.graph.update(
-**name:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**name:** `typing.Optional[str]` — The graph's display name.
@@ -1204,7 +1218,7 @@ client.graph.update(
-**time_zone:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**time_zone:** `typing.Optional[str]` — The graph's IANA time zone.
@@ -1271,7 +1285,7 @@ client.graph.clone(
-**target_graph_id:** `typing.Optional[str]` +**target_graph_id:** `typing.Optional[str]` — An optional name for the cloned graph.
@@ -1314,6 +1328,7 @@ client = Zep( client.graph.get_context( graph_uuid="graph_uuid", + query="query", ) ``` @@ -1338,7 +1353,7 @@ client.graph.get_context(
-**filters:** `typing.Optional[typing.Dict[str, typing.Any]]` +**query:** `str` — The search query used to assemble the context block.
@@ -1346,7 +1361,10 @@ client.graph.get_context(
-**include_results:** `typing.Optional[bool]` +**filters:** `typing.Optional[SearchFilters]` + +Filters constraining which graph data can be selected for the context +block.
@@ -1354,7 +1372,7 @@ client.graph.get_context(
-**max_characters:** `typing.Optional[int]` +**include_results:** `typing.Optional[bool]` — When true, includes the raw graph results selected for the context block.
@@ -1362,7 +1380,7 @@ client.graph.get_context(
-**query:** `typing.Optional[str]` +**max_characters:** `typing.Optional[int]` — The maximum number of characters in the assembled context block.
@@ -1370,7 +1388,7 @@ client.graph.get_context(
-**recency_bias:** `typing.Optional[str]` +**recency_bias:** `typing.Optional[V4GraphContextRequestRecencyBias]` — Adjusts result selection to favor more recent graph data.
@@ -1378,7 +1396,7 @@ client.graph.get_context(
-**template_uuid:** `typing.Optional[str]` +**template_uuid:** `typing.Optional[str]` — The UUID of a context template used to render the context block.
@@ -1801,6 +1819,7 @@ client.graph.search_edges( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) ``` @@ -1886,6 +1905,7 @@ client.graph.search_episodes( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) ``` @@ -1971,6 +1991,7 @@ client.graph.search_nodes( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) ``` @@ -2056,6 +2077,7 @@ client.graph.search_observations( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) ``` @@ -2141,6 +2163,7 @@ client.graph.search_thread_summaries( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) ``` @@ -2224,6 +2247,9 @@ client = Zep( client.graph.get_subgraph( graph_uuid="graph_uuid", + seed_node_uuids=[ + "seed_node_uuids" + ], ) ``` @@ -2248,7 +2274,7 @@ client.graph.get_subgraph(
-**depth:** `typing.Optional[int]` +**seed_node_uuids:** `typing.List[str]` — The node UUIDs to expand from, in traversal-priority order.
@@ -2256,7 +2282,7 @@ client.graph.get_subgraph(
-**direction:** `typing.Optional[str]` +**depth:** `typing.Optional[int]` — The maximum traversal depth from the seed nodes. Defaults to 1.
@@ -2264,7 +2290,10 @@ client.graph.get_subgraph(
-**filters:** `typing.Optional[typing.Dict[str, typing.Any]]` +**direction:** `typing.Optional[V4SubgraphRequestDirection]` + +The edge orientation to follow during expansion: in, out, or both. +Defaults to both.
@@ -2272,7 +2301,7 @@ client.graph.get_subgraph(
-**max_edges:** `typing.Optional[int]` +**filters:** `typing.Optional[SearchFilters]` — Filters constraining the traversed edges and included nodes.
@@ -2280,7 +2309,7 @@ client.graph.get_subgraph(
-**max_nodes:** `typing.Optional[int]` +**max_edges:** `typing.Optional[int]` — The maximum number of edges in the response. Defaults to 200.
@@ -2288,7 +2317,7 @@ client.graph.get_subgraph(
-**seed_node_uuids:** `typing.Optional[typing.List[str]]` +**max_nodes:** `typing.Optional[int]` — The maximum number of nodes in the response. Defaults to 100.
@@ -2405,7 +2434,7 @@ client.lookup.batch()
-**graphs:** `typing.Optional[typing.List[str]]` +**graphs:** `typing.Optional[typing.List[str]]` — Developer-assigned graph IDs to resolve to UUIDs.
@@ -2413,7 +2442,7 @@ client.lookup.batch()
-**threads:** `typing.Optional[typing.List[str]]` +**threads:** `typing.Optional[typing.List[str]]` — Developer-assigned thread IDs to resolve to UUIDs.
@@ -2421,7 +2450,7 @@ client.lookup.batch()
-**users:** `typing.Optional[typing.List[str]]` +**users:** `typing.Optional[typing.List[str]]` — Developer-assigned user IDs to resolve to UUIDs.
@@ -2528,7 +2557,10 @@ client.project.update()
-**default_time_zone:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**default_time_zone:** `typing.Optional[str]` + +The project's IANA fallback time zone. Set to null to clear the existing +value.
@@ -3217,7 +3249,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.create() +client.thread.create( + user_uuid="user_uuid", +) ``` @@ -3233,7 +3267,7 @@ client.thread.create()
-**thread_id:** `typing.Optional[str]` +**user_uuid:** `str` — The UUID of the user this thread belongs to.
@@ -3241,7 +3275,7 @@ client.thread.create()
-**user_uuid:** `typing.Optional[str]` +**thread_id:** `typing.Optional[str]` — An optional developer-assigned identifier for the thread.
@@ -3671,7 +3705,7 @@ client.thread.list_messages(
```python -from zep_cloud import Zep +from zep_cloud import Zep, AddMessage from zep_cloud.environment import ZepEnvironment client = Zep( @@ -3681,6 +3715,9 @@ client = Zep( client.thread.add_messages( thread_uuid="thread_uuid", + messages=[ + AddMessage() + ], ) ``` @@ -3705,7 +3742,7 @@ client.thread.add_messages(
-**ignore_roles:** `typing.Optional[typing.List[str]]` +**messages:** `typing.List[AddMessage]` — The messages to add to the thread.
@@ -3713,7 +3750,10 @@ client.thread.add_messages(
-**messages:** `typing.Optional[typing.List[AddMessage]]` +**ignore_roles:** `typing.Optional[typing.List[str]]` + +Message roles to skip during graph extraction; the messages are still +stored.
@@ -3722,6 +3762,9 @@ client.thread.add_messages(
**return_context:** `typing.Optional[bool]` + +When true, returns the context block for the thread's most recent +messages.
@@ -3730,6 +3773,9 @@ client.thread.add_messages(
**strict_ontology:** `typing.Optional[bool]` + +When true, prevents extraction of generic entity nodes that do not match +the configured ontology.
@@ -3808,11 +3854,25 @@ client.thread.get_summary( -## User -
client.user.create(...) -> User +## UserGroup +
client.user_group.create(...) -> UserGroup +
+
+ +#### 📝 Description + +
+
+
+Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ #### 🔌 Usage
@@ -3830,7 +3890,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.create() +client.user_group.create( + name="name", +) ```
@@ -3846,7 +3908,7 @@ client.user.create()
-**disable_default_ontology:** `typing.Optional[bool]` +**name:** `str` — The name of the user group.
@@ -3854,7 +3916,7 @@ client.user.create()
-**email:** `typing.Optional[str]` +**description:** `typing.Optional[str]` — A description of the user group.
@@ -3862,61 +3924,35 @@ client.user.create()
-**first_name:** `typing.Optional[str]` +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
- -
-
- -**last_name:** `typing.Optional[str]` -
-
-
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` -
+
+
client.user_group.list(...) -> UserGroupPage
-**time_zone:** `typing.Optional[str]` - -
-
+#### 📝 Description
-**user_id:** `typing.Optional[str]` - -
-
-
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
+Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. - - -
- -
client.user.list(...) -> UserPage -
-
#### 🔌 Usage @@ -3935,11 +3971,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.list( +client.user_group.list( limit=1, cursor="cursor", - order_by="order_by", - order="order", ) ``` @@ -3956,7 +3990,7 @@ client.user.list(
-**limit:** `typing.Optional[int]` — Page size +**request:** `SearchListRequest`
@@ -3964,7 +3998,7 @@ client.user.list(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**limit:** `typing.Optional[int]` — Page size
@@ -3972,7 +4006,7 @@ client.user.list(
-**order_by:** `typing.Optional[str]` — Sort field +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -3980,38 +4014,36 @@ client.user.list(
-**order:** `typing.Optional[str]` — asc or desc +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**search:** `typing.Optional[str]` -
+
+
client.user_group.get(...) -> UserGroup
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
- - - +#### 📝 Description - - -
+
+
-
client.user.lookup(...) -> User
+Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ #### 🔌 Usage
@@ -4029,7 +4061,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.lookup() +client.user_group.get( + group_uuid="group_uuid", +) ``` @@ -4045,7 +4079,7 @@ client.user.lookup()
-**request:** `LookupRequest` +**group_uuid:** `str` — User group UUID
@@ -4065,10 +4099,24 @@ client.user.lookup()
-
client.user.get(...) -> User +
client.user_group.delete(...) +
+
+ +#### 📝 Description + +
+
+
+Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ #### 🔌 Usage
@@ -4086,8 +4134,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.get( - user_uuid="user_uuid", +client.user_group.delete( + group_uuid="group_uuid", ) ``` @@ -4104,7 +4152,7 @@ client.user.get(
-**user_uuid:** `str` — User UUID +**group_uuid:** `str` — User group UUID
@@ -4124,10 +4172,24 @@ client.user.get(
-
client.user.delete(...) -> UserDeleteResult +
client.user_group.update(...) -> UserGroup +
+
+ +#### 📝 Description + +
+
+
+Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ #### 🔌 Usage
@@ -4145,8 +4207,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.delete( - user_uuid="user_uuid", +client.user_group.update( + group_uuid="group_uuid", ) ``` @@ -4163,7 +4225,31 @@ client.user.delete(
-**user_uuid:** `str` — User UUID +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**description:** `typing.Optional[str]` — A description of the user group. + +
+
+ +
+
+ +**expected_version:** `typing.Optional[int]` — The user group's current version, used to detect concurrent updates. + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — The name of the user group.
@@ -4183,10 +4269,24 @@ client.user.delete(
-
client.user.update(...) -> User +
client.user_group.list_member_candidates(...) -> UserPage +
+
+ +#### 📝 Description + +
+
+
+Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ #### 🔌 Usage
@@ -4204,8 +4304,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.update( - user_uuid="user_uuid", +client.user_group.list_member_candidates( + group_uuid="group_uuid", + limit=1, + cursor="cursor", ) ``` @@ -4222,7 +4324,7 @@ client.user.update(
-**user_uuid:** `str` — User UUID +**group_uuid:** `str` — User group UUID
@@ -4230,7 +4332,7 @@ client.user.update(
-**disable_default_ontology:** `typing.Optional[bool]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**request:** `SearchListRequest`
@@ -4238,7 +4340,7 @@ client.user.update(
-**email:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**limit:** `typing.Optional[int]` — Page size
@@ -4246,7 +4348,7 @@ client.user.update(
-**first_name:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -4254,45 +4356,35 @@ client.user.update(
-**last_name:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` -
+
+
client.user_group.add_members(...) -> MembershipMutationResult
-**time_zone:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. - -
-
+#### 📝 Description
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
+
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control.
- - -
- -
client.user.get_node(...) -> Node -
-
#### 🔌 Usage @@ -4311,8 +4403,11 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.get_node( - user_uuid="user_uuid", +client.user_group.add_members( + group_uuid="group_uuid", + user_uuids=[ + "user_uuids" + ], ) ``` @@ -4329,7 +4424,15 @@ client.user.get_node(
-**user_uuid:** `str` — User UUID +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**request:** `MutateMembersRequest`
@@ -4349,10 +4452,24 @@ client.user.get_node(
-
client.user.get_summary_instructions(...) -> UserSummaryInstructions +
client.user_group.list_members(...) -> UserPage +
+
+ +#### 📝 Description + +
+
+
+Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ #### 🔌 Usage
@@ -4370,8 +4487,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.get_summary_instructions( - user_uuid="user_uuid", +client.user_group.list_members( + group_uuid="group_uuid", + limit=1, + cursor="cursor", ) ``` @@ -4388,7 +4507,31 @@ client.user.get_summary_instructions(
-**user_uuid:** `str` — User UUID +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**request:** `SearchListRequest` + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -4408,11 +4551,11 @@ client.user.get_summary_instructions(
-
client.user.set_summary_instructions(...) -> UserSummaryInstructions +
client.user_group.remove_members(...) -> MembershipMutationResult
-#### 🔌 Usage +#### 📝 Description
@@ -4420,12 +4563,869 @@ client.user.get_summary_instructions(
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
-client = Zep( - api_key="", +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.remove_members( + group_uuid="group_uuid", + user_uuids=[ + "user_uuids" + ], +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**request:** `MutateMembersRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.remove_member(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.remove_member( + group_uuid="group_uuid", + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.list_for_user(...) -> UserGroupPage +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.list_for_user( + user_uuid="user_uuid", + limit=1, + cursor="cursor", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## User +
client.user.create(...) -> User +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.create() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**disable_default_ontology:** `typing.Optional[bool]` — When true, disables the default ontology for the user's graph. + +
+
+ +
+
+ +**email:** `typing.Optional[str]` — The email address of the user. + +
+
+ +
+
+ +**first_name:** `typing.Optional[str]` — The user's first name. + +
+
+ +
+
+ +**last_name:** `typing.Optional[str]` — The user's last name. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to store on the user. + +
+
+ +
+
+ +**time_zone:** `typing.Optional[str]` — The user's IANA time zone. + +
+
+ +
+
+ +**user_id:** `typing.Optional[str]` — An optional developer-assigned identifier for the user. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.list(...) -> UserPage +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.list( + limit=1, + cursor="cursor", + order_by="order_by", + order="order", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**order_by:** `typing.Optional[str]` — Sort field + +
+
+ +
+
+ +**order:** `typing.Optional[str]` — asc or desc + +
+
+ +
+
+ +**search:** `typing.Optional[str]` — Filters results to users whose user ID, email, or name contains this text. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.lookup(...) -> User +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.lookup() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `LookupRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.get(...) -> User +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.get( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.delete(...) -> UserDeleteResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.delete( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.update(...) -> User +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.update( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**disable_default_ontology:** `typing.Optional[bool]` — When true, disables the default ontology for the user's graph. + +
+
+ +
+
+ +**email:** `typing.Optional[str]` — The email address of the user. + +
+
+ +
+
+ +**first_name:** `typing.Optional[str]` — The user's first name. + +
+
+ +
+
+ +**last_name:** `typing.Optional[str]` — The user's last name. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to merge onto the user; a key set to null is removed. + +
+
+ +
+
+ +**time_zone:** `typing.Optional[str]` — The user's IANA time zone. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.get_node(...) -> Node +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.get_node( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.get_summary_instructions(...) -> UserSummaryInstructions +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.get_summary_instructions( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.set_summary_instructions(...) -> UserSummaryInstructions +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", environment=ZepEnvironment.DEFAULT, ) @@ -4671,6 +5671,7 @@ client = Zep( client.graph.episode.add( graph_uuid="graph_uuid", + data="data", ) ``` @@ -4695,7 +5696,7 @@ client.graph.episode.add(
-**created_at:** `typing.Optional[str]` +**data:** `str` — The episode content to add to the graph.
@@ -4703,7 +5704,10 @@ client.graph.episode.add(
-**data:** `typing.Optional[str]` +**created_at:** `typing.Optional[str]` + +The episode's reference time, used for temporal reasoning rather than +ingestion time.
@@ -4711,7 +5715,7 @@ client.graph.episode.add(
-**document_id:** `typing.Optional[str]` +**document_id:** `typing.Optional[str]` — Groups this episode as a chunk of a document on the graph.
@@ -4719,7 +5723,7 @@ client.graph.episode.add(
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to store on the episode.
@@ -4727,7 +5731,7 @@ client.graph.episode.add(
-**source_description:** `typing.Optional[str]` +**source_description:** `typing.Optional[str]` — A description of the source of this episode.
@@ -4736,6 +5740,9 @@ client.graph.episode.add(
**strict_ontology:** `typing.Optional[bool]` + +When true, prevents extraction of generic entity nodes that do not match +the configured ontology.
@@ -4743,7 +5750,7 @@ client.graph.episode.add(
-**type:** `typing.Optional[str]` +**type:** `typing.Optional[V4AddEpisodeRequestType]` — The data format of the episode: text, json, or message. Defaults to text.
@@ -5040,7 +6047,7 @@ client.graph.episode.update(
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to merge onto the episode; a key set to null is removed.
@@ -5074,7 +6081,7 @@ client.graph.episode.update(
```python -from zep_cloud import Zep +from zep_cloud import Zep, EdgeNodeRef from zep_cloud.environment import ZepEnvironment client = Zep( @@ -5084,6 +6091,10 @@ client = Zep( client.graph.edge.add( graph_uuid="graph_uuid", + fact="fact", + fact_name="fact_name", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), ) ``` @@ -5108,7 +6119,10 @@ client.graph.edge.add(
-**attributes:** `typing.Optional[typing.Dict[str, typing.Any]]` +**fact:** `str` + +The fact text describing the relationship between the source and target +nodes.
@@ -5116,7 +6130,7 @@ client.graph.edge.add(
-**expired_at:** `typing.Optional[str]` +**fact_name:** `str` — The name of the edge, in upper snake case, for example RELATES_TO.
@@ -5124,7 +6138,10 @@ client.graph.edge.add(
-**fact:** `typing.Optional[str]` +**source_node:** `EdgeNodeRef` + +The source node of the edge, referenced by uuid or created or matched by +name.
@@ -5132,7 +6149,10 @@ client.graph.edge.add(
-**fact_name:** `typing.Optional[str]` +**target_node:** `EdgeNodeRef` + +The target node of the edge, referenced by uuid or created or matched by +name.
@@ -5140,7 +6160,7 @@ client.graph.edge.add(
-**invalid_at:** `typing.Optional[str]` +**attributes:** `typing.Optional[typing.Dict[str, typing.Any]]` — Additional attributes to store on the edge.
@@ -5148,7 +6168,7 @@ client.graph.edge.add(
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` +**expired_at:** `typing.Optional[str]` — The time at which the fact was superseded or invalidated.
@@ -5156,7 +6176,7 @@ client.graph.edge.add(
-**source_node:** `typing.Optional[typing.Dict[str, typing.Any]]` +**invalid_at:** `typing.Optional[str]` — The time at which the fact stopped being true.
@@ -5164,7 +6184,7 @@ client.graph.edge.add(
-**target_node:** `typing.Optional[typing.Dict[str, typing.Any]]` +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata attached to the episode created for this edge.
@@ -5172,7 +6192,7 @@ client.graph.edge.add(
-**valid_at:** `typing.Optional[str]` +**valid_at:** `typing.Optional[str]` — The time at which the fact became true.
@@ -5470,6 +6490,9 @@ client.graph.edge.update(
**attributes:** `typing.Optional[typing.Dict[str, typing.Any]]` + +Additional attributes to merge onto the edge; a key set to null is +removed.
@@ -5477,7 +6500,10 @@ client.graph.edge.update(
-**fact:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**fact:** `typing.Optional[str]` + +The fact text describing the relationship between the source and target +nodes.
@@ -5511,7 +6537,7 @@ client.graph.edge.update(
```python -from zep_cloud import Zep +from zep_cloud import Zep, NodeInput from zep_cloud.environment import ZepEnvironment client = Zep( @@ -5521,6 +6547,11 @@ client = Zep( client.graph.node.add( graph_uuid="graph_uuid", + nodes=[ + NodeInput( + name="name", + ) + ], ) ``` @@ -5545,7 +6576,7 @@ client.graph.node.add(
-**nodes:** `typing.Optional[typing.List[typing.Dict[str, typing.Any]]]` +**nodes:** `typing.List[NodeInput]` — The nodes to add to the graph.
@@ -5843,6 +6874,9 @@ client.graph.node.update(
**attributes:** `typing.Optional[typing.Dict[str, typing.Any]]` + +Additional attributes to merge onto the node; a key set to null is +removed.
@@ -5850,7 +6884,7 @@ client.graph.node.update(
-**name:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**name:** `typing.Optional[str]` — The node's name.
@@ -5858,7 +6892,7 @@ client.graph.node.update(
-**summary:** `typing.Optional[str]` — Omit to leave unchanged, send JSON null to clear, or send a value to set. +**summary:** `typing.Optional[str]` — A summary of the node.
@@ -5952,7 +6986,7 @@ client.graph.node.list_neighbors(
-**direction:** `typing.Optional[str]` +**direction:** `typing.Optional[V4NeighborsRequestDirection]` — The edge orientation to follow from the node: in, out, or both.
@@ -5960,7 +6994,7 @@ client.graph.node.list_neighbors(
-**filters:** `typing.Optional[typing.Dict[str, typing.Any]]` +**filters:** `typing.Optional[SearchFilters]` — Filters constraining the connecting edges and the neighbor nodes.
@@ -6345,7 +7379,7 @@ client.thread.message.update(
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to merge onto the message; a key set to null is removed.
diff --git a/src/zep_cloud/__init__.py b/src/zep_cloud/__init__.py index d485aa83..14601278 100644 --- a/src/zep_cloud/__init__.py +++ b/src/zep_cloud/__init__.py @@ -19,12 +19,14 @@ AsyncResult, Batch, BatchItem, + BatchItemInput, BatchItemKind, BatchItemPage, BatchItemStatus, BatchItemsResponse, BatchPage, CloneGraphResult, + ComparisonOperator, ContextEdge, ContextEpisode, ContextNode, @@ -34,9 +36,12 @@ ContextTemplatePage, ContextThreadSummary, CreateContextTemplateRequest, + CustomInstruction, + DateFilter, DocumentSummary, DocumentSummaryPage, Edge, + EdgeNodeRef, EdgePage, EdgeSourceTarget, EdgeType, @@ -44,6 +49,7 @@ EntityPropertyType, EntityType, Episode, + EpisodeMetadataFilter, EpisodePage, ErrorBody, Graph, @@ -51,23 +57,32 @@ GraphDataType, GraphDeleteResult, GraphPage, + GraphitiMetadataFilterGroupType, Instructions, LookupBatchResponse, LookupItem, LookupRequest, + MembershipMutationResult, Message, MessagePage, + MetadataFilterGroup, + MutateMembersRequest, NeighborEntry, NeighborPage, Node, + NodeInput, NodePage, Observation, ObservationPage, ObservationSteering, + ObservationType, Ontology, ProcessBatchResult, Project, + PropertyFilter, RoleType, + SearchFilters, + SearchListRequest, SearchRequest, SubgraphResponse, Task, @@ -81,13 +96,21 @@ ThreadSummaryPage, User, UserDeleteResult, + UserGroup, + UserGroupPage, + UserInstruction, UserPage, UserSummaryInstructions, + V4BatchItemInputDataType, + V4BatchItemInputRole, + V4BatchItemInputType, + V4SearchRequestReranker, ) - from .errors import BadRequestError, NotFoundError, UnauthorizedError - from . import batch, context, graph, lookup, project, task, thread, user + from .errors import BadRequestError, ConflictError, ForbiddenError, NotFoundError, UnauthorizedError + from . import batch, context, graph, lookup, project, task, thread, user, user_group from .client import AsyncZep, Zep from .environment import ZepEnvironment + from .graph import V4GraphContextRequestRecencyBias, V4SubgraphRequestDirection from .version import __version__ _dynamic_imports: typing.Dict[str, str] = { "AddEdgeResult": ".types", @@ -104,12 +127,15 @@ "BadRequestError": ".errors", "Batch": ".types", "BatchItem": ".types", + "BatchItemInput": ".types", "BatchItemKind": ".types", "BatchItemPage": ".types", "BatchItemStatus": ".types", "BatchItemsResponse": ".types", "BatchPage": ".types", "CloneGraphResult": ".types", + "ComparisonOperator": ".types", + "ConflictError": ".errors", "ContextEdge": ".types", "ContextEpisode": ".types", "ContextNode": ".types", @@ -119,9 +145,12 @@ "ContextTemplatePage": ".types", "ContextThreadSummary": ".types", "CreateContextTemplateRequest": ".types", + "CustomInstruction": ".types", + "DateFilter": ".types", "DocumentSummary": ".types", "DocumentSummaryPage": ".types", "Edge": ".types", + "EdgeNodeRef": ".types", "EdgePage": ".types", "EdgeSourceTarget": ".types", "EdgeType": ".types", @@ -129,31 +158,42 @@ "EntityPropertyType": ".types", "EntityType": ".types", "Episode": ".types", + "EpisodeMetadataFilter": ".types", "EpisodePage": ".types", "ErrorBody": ".types", + "ForbiddenError": ".errors", "Graph": ".types", "GraphContextResponse": ".types", "GraphDataType": ".types", "GraphDeleteResult": ".types", "GraphPage": ".types", + "GraphitiMetadataFilterGroupType": ".types", "Instructions": ".types", "LookupBatchResponse": ".types", "LookupItem": ".types", "LookupRequest": ".types", + "MembershipMutationResult": ".types", "Message": ".types", "MessagePage": ".types", + "MetadataFilterGroup": ".types", + "MutateMembersRequest": ".types", "NeighborEntry": ".types", "NeighborPage": ".types", "Node": ".types", + "NodeInput": ".types", "NodePage": ".types", "NotFoundError": ".errors", "Observation": ".types", "ObservationPage": ".types", "ObservationSteering": ".types", + "ObservationType": ".types", "Ontology": ".types", "ProcessBatchResult": ".types", "Project": ".types", + "PropertyFilter": ".types", "RoleType": ".types", + "SearchFilters": ".types", + "SearchListRequest": ".types", "SearchRequest": ".types", "SubgraphResponse": ".types", "Task": ".types", @@ -168,8 +208,17 @@ "UnauthorizedError": ".errors", "User": ".types", "UserDeleteResult": ".types", + "UserGroup": ".types", + "UserGroupPage": ".types", + "UserInstruction": ".types", "UserPage": ".types", "UserSummaryInstructions": ".types", + "V4BatchItemInputDataType": ".types", + "V4BatchItemInputRole": ".types", + "V4BatchItemInputType": ".types", + "V4GraphContextRequestRecencyBias": ".graph", + "V4SearchRequestReranker": ".types", + "V4SubgraphRequestDirection": ".graph", "Zep": ".client", "ZepEnvironment": ".environment", "__version__": ".version", @@ -181,6 +230,7 @@ "task": ".task", "thread": ".thread", "user": ".user", + "user_group": ".user_group", } @@ -220,12 +270,15 @@ def __dir__(): "BadRequestError", "Batch", "BatchItem", + "BatchItemInput", "BatchItemKind", "BatchItemPage", "BatchItemStatus", "BatchItemsResponse", "BatchPage", "CloneGraphResult", + "ComparisonOperator", + "ConflictError", "ContextEdge", "ContextEpisode", "ContextNode", @@ -235,9 +288,12 @@ def __dir__(): "ContextTemplatePage", "ContextThreadSummary", "CreateContextTemplateRequest", + "CustomInstruction", + "DateFilter", "DocumentSummary", "DocumentSummaryPage", "Edge", + "EdgeNodeRef", "EdgePage", "EdgeSourceTarget", "EdgeType", @@ -245,31 +301,42 @@ def __dir__(): "EntityPropertyType", "EntityType", "Episode", + "EpisodeMetadataFilter", "EpisodePage", "ErrorBody", + "ForbiddenError", "Graph", "GraphContextResponse", "GraphDataType", "GraphDeleteResult", "GraphPage", + "GraphitiMetadataFilterGroupType", "Instructions", "LookupBatchResponse", "LookupItem", "LookupRequest", + "MembershipMutationResult", "Message", "MessagePage", + "MetadataFilterGroup", + "MutateMembersRequest", "NeighborEntry", "NeighborPage", "Node", + "NodeInput", "NodePage", "NotFoundError", "Observation", "ObservationPage", "ObservationSteering", + "ObservationType", "Ontology", "ProcessBatchResult", "Project", + "PropertyFilter", "RoleType", + "SearchFilters", + "SearchListRequest", "SearchRequest", "SubgraphResponse", "Task", @@ -284,8 +351,17 @@ def __dir__(): "UnauthorizedError", "User", "UserDeleteResult", + "UserGroup", + "UserGroupPage", + "UserInstruction", "UserPage", "UserSummaryInstructions", + "V4BatchItemInputDataType", + "V4BatchItemInputRole", + "V4BatchItemInputType", + "V4GraphContextRequestRecencyBias", + "V4SearchRequestReranker", + "V4SubgraphRequestDirection", "Zep", "ZepEnvironment", "__version__", @@ -297,4 +373,5 @@ def __dir__(): "task", "thread", "user", + "user_group", ] diff --git a/src/zep_cloud/base_client.py b/src/zep_cloud/base_client.py index 998188e7..01b419a6 100644 --- a/src/zep_cloud/base_client.py +++ b/src/zep_cloud/base_client.py @@ -20,6 +20,7 @@ from .task.client import AsyncTaskClient, TaskClient from .thread.client import AsyncThreadClient, ThreadClient from .user.client import AsyncUserClient, UserClient + from .user_group.client import AsyncUserGroupClient, UserGroupClient class BaseClient: @@ -101,6 +102,7 @@ def __init__( self._project: typing.Optional[ProjectClient] = None self._task: typing.Optional[TaskClient] = None self._thread: typing.Optional[ThreadClient] = None + self._user_group: typing.Optional[UserGroupClient] = None self._user: typing.Optional[UserClient] = None @property @@ -159,6 +161,14 @@ def thread(self): self._thread = ThreadClient(client_wrapper=self._client_wrapper) return self._thread + @property + def user_group(self): + if self._user_group is None: + from .user_group.client import UserGroupClient # noqa: E402 + + self._user_group = UserGroupClient(client_wrapper=self._client_wrapper) + return self._user_group + @property def user(self): if self._user is None: @@ -247,6 +257,7 @@ def __init__( self._project: typing.Optional[AsyncProjectClient] = None self._task: typing.Optional[AsyncTaskClient] = None self._thread: typing.Optional[AsyncThreadClient] = None + self._user_group: typing.Optional[AsyncUserGroupClient] = None self._user: typing.Optional[AsyncUserClient] = None @property @@ -305,6 +316,14 @@ def thread(self): self._thread = AsyncThreadClient(client_wrapper=self._client_wrapper) return self._thread + @property + def user_group(self): + if self._user_group is None: + from .user_group.client import AsyncUserGroupClient # noqa: E402 + + self._user_group = AsyncUserGroupClient(client_wrapper=self._client_wrapper) + return self._user_group + @property def user(self): if self._user is None: diff --git a/src/zep_cloud/batch/client.py b/src/zep_cloud/batch/client.py index 52781b8d..c9b61dc7 100644 --- a/src/zep_cloud/batch/client.py +++ b/src/zep_cloud/batch/client.py @@ -7,6 +7,7 @@ from ..core.request_options import RequestOptions from ..types.batch import Batch from ..types.batch_item import BatchItem +from ..types.batch_item_input import BatchItemInput from ..types.batch_item_page import BatchItemPage from ..types.batch_items_response import BatchItemsResponse from ..types.batch_page import BatchPage @@ -93,10 +94,15 @@ def create( Parameters ---------- ignore_roles : typing.Optional[typing.Sequence[str]] + Message roles to skip during graph extraction for thread message items in + this batch. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the batch. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology for episodes in this batch. idempotency_key : typing.Optional[str] @@ -245,7 +251,7 @@ def add_items( self, batch_uuid: str, *, - items: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + items: typing.Sequence[BatchItemInput], idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> BatchItemsResponse: @@ -255,7 +261,8 @@ def add_items( batch_uuid : str Batch UUID - items : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + items : typing.Sequence[BatchItemInput] + The batch items to append, each identified by its type field. idempotency_key : typing.Optional[str] @@ -269,13 +276,18 @@ def add_items( Examples -------- - from zep_cloud import Zep + from zep_cloud import BatchItemInput, Zep client = Zep( api_key="YOUR_API_KEY", ) client.batch.add_items( batch_uuid="batch_uuid", + items=[ + BatchItemInput( + type="graph_episode", + ) + ], ) """ _response = self._raw_client.add_items( @@ -408,10 +420,15 @@ async def create( Parameters ---------- ignore_roles : typing.Optional[typing.Sequence[str]] + Message roles to skip during graph extraction for thread message items in + this batch. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the batch. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology for episodes in this batch. idempotency_key : typing.Optional[str] @@ -595,7 +612,7 @@ async def add_items( self, batch_uuid: str, *, - items: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + items: typing.Sequence[BatchItemInput], idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> BatchItemsResponse: @@ -605,7 +622,8 @@ async def add_items( batch_uuid : str Batch UUID - items : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + items : typing.Sequence[BatchItemInput] + The batch items to append, each identified by its type field. idempotency_key : typing.Optional[str] @@ -621,7 +639,7 @@ async def add_items( -------- import asyncio - from zep_cloud import AsyncZep + from zep_cloud import AsyncZep, BatchItemInput client = AsyncZep( api_key="YOUR_API_KEY", @@ -631,6 +649,11 @@ async def add_items( async def main() -> None: await client.batch.add_items( batch_uuid="batch_uuid", + items=[ + BatchItemInput( + type="graph_episode", + ) + ], ) diff --git a/src/zep_cloud/batch/raw_client.py b/src/zep_cloud/batch/raw_client.py index 195c53ae..0fc22bc3 100644 --- a/src/zep_cloud/batch/raw_client.py +++ b/src/zep_cloud/batch/raw_client.py @@ -11,12 +11,15 @@ from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..types.api_error import ApiError as types_api_error_ApiError from ..types.batch import Batch from ..types.batch_item import BatchItem +from ..types.batch_item_input import BatchItemInput from ..types.batch_item_page import BatchItemPage from ..types.batch_items_response import BatchItemsResponse from ..types.batch_page import BatchPage @@ -147,10 +150,15 @@ def create( Parameters ---------- ignore_roles : typing.Optional[typing.Sequence[str]] + Message roles to skip during graph extraction for thread message items in + this batch. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the batch. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology for episodes in this batch. idempotency_key : typing.Optional[str] @@ -220,6 +228,17 @@ def create( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -375,6 +394,17 @@ def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -494,7 +524,7 @@ def add_items( self, batch_uuid: str, *, - items: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + items: typing.Sequence[BatchItemInput], idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[BatchItemsResponse]: @@ -504,7 +534,8 @@ def add_items( batch_uuid : str Batch UUID - items : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + items : typing.Sequence[BatchItemInput] + The batch items to append, each identified by its type field. idempotency_key : typing.Optional[str] @@ -520,7 +551,9 @@ def add_items( f"batches/{jsonable_encoder(batch_uuid)}/items", method="POST", json={ - "items": items, + "items": convert_and_respect_annotation_metadata( + object_=items, annotation=typing.Sequence[BatchItemInput], direction="write" + ), }, headers={ "content-type": "application/json", @@ -572,6 +605,17 @@ def add_items( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -659,6 +703,17 @@ def process( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -796,10 +851,15 @@ async def create( Parameters ---------- ignore_roles : typing.Optional[typing.Sequence[str]] + Message roles to skip during graph extraction for thread message items in + this batch. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the batch. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology for episodes in this batch. idempotency_key : typing.Optional[str] @@ -869,6 +929,17 @@ async def create( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1026,6 +1097,17 @@ async def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1148,7 +1230,7 @@ async def add_items( self, batch_uuid: str, *, - items: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + items: typing.Sequence[BatchItemInput], idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[BatchItemsResponse]: @@ -1158,7 +1240,8 @@ async def add_items( batch_uuid : str Batch UUID - items : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + items : typing.Sequence[BatchItemInput] + The batch items to append, each identified by its type field. idempotency_key : typing.Optional[str] @@ -1174,7 +1257,9 @@ async def add_items( f"batches/{jsonable_encoder(batch_uuid)}/items", method="POST", json={ - "items": items, + "items": convert_and_respect_annotation_metadata( + object_=items, annotation=typing.Sequence[BatchItemInput], direction="write" + ), }, headers={ "content-type": "application/json", @@ -1226,6 +1311,17 @@ async def add_items( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1313,6 +1409,17 @@ async def process( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/context/client.py b/src/zep_cloud/context/client.py index 8ed77ced..1d509fbf 100644 --- a/src/zep_cloud/context/client.py +++ b/src/zep_cloud/context/client.py @@ -40,8 +40,10 @@ def create_template( Parameters ---------- name : typing.Optional[str] + A unique, human-readable name for the template. template : typing.Optional[str] + The template content used to render context blocks. idempotency_key : typing.Optional[str] @@ -86,6 +88,7 @@ def list_templates( Opaque page cursor name : typing.Optional[str] + Filters results to the context template with this exact name. idempotency_key : typing.Optional[str] @@ -165,8 +168,10 @@ def update_template( Template UUID name : typing.Optional[str] + A unique, human-readable name for the template. template : typing.Optional[str] + The template content used to render context blocks. idempotency_key : typing.Optional[str] @@ -264,8 +269,10 @@ async def create_template( Parameters ---------- name : typing.Optional[str] + A unique, human-readable name for the template. template : typing.Optional[str] + The template content used to render context blocks. idempotency_key : typing.Optional[str] @@ -318,6 +325,7 @@ async def list_templates( Opaque page cursor name : typing.Optional[str] + Filters results to the context template with this exact name. idempotency_key : typing.Optional[str] @@ -414,8 +422,10 @@ async def update_template( Template UUID name : typing.Optional[str] + A unique, human-readable name for the template. template : typing.Optional[str] + The template content used to render context blocks. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/context/raw_client.py b/src/zep_cloud/context/raw_client.py index a843e543..4df61098 100644 --- a/src/zep_cloud/context/raw_client.py +++ b/src/zep_cloud/context/raw_client.py @@ -12,6 +12,7 @@ from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..types.api_error import ApiError as types_api_error_ApiError @@ -39,8 +40,10 @@ def create_template( Parameters ---------- name : typing.Optional[str] + A unique, human-readable name for the template. template : typing.Optional[str] + The template content used to render context blocks. idempotency_key : typing.Optional[str] @@ -109,6 +112,17 @@ def create_template( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -141,6 +155,7 @@ def list_templates( Opaque page cursor name : typing.Optional[str] + Filters results to the context template with this exact name. idempotency_key : typing.Optional[str] @@ -222,6 +237,17 @@ def list_templates( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -329,8 +355,10 @@ def update_template( Template UUID name : typing.Optional[str] + A unique, human-readable name for the template. template : typing.Optional[str] + The template content used to render context blocks. idempotency_key : typing.Optional[str] @@ -399,6 +427,17 @@ def update_template( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -478,6 +517,17 @@ def delete_template( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -508,8 +558,10 @@ async def create_template( Parameters ---------- name : typing.Optional[str] + A unique, human-readable name for the template. template : typing.Optional[str] + The template content used to render context blocks. idempotency_key : typing.Optional[str] @@ -578,6 +630,17 @@ async def create_template( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -610,6 +673,7 @@ async def list_templates( Opaque page cursor name : typing.Optional[str] + Filters results to the context template with this exact name. idempotency_key : typing.Optional[str] @@ -694,6 +758,17 @@ async def _get_next(): ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -801,8 +876,10 @@ async def update_template( Template UUID name : typing.Optional[str] + A unique, human-readable name for the template. template : typing.Optional[str] + The template content used to render context blocks. idempotency_key : typing.Optional[str] @@ -871,6 +948,17 @@ async def update_template( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -950,6 +1038,17 @@ async def delete_template( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/core/client_wrapper.py b/src/zep_cloud/core/client_wrapper.py index a5a23988..bd63d096 100644 --- a/src/zep_cloud/core/client_wrapper.py +++ b/src/zep_cloud/core/client_wrapper.py @@ -27,12 +27,12 @@ def get_headers(self) -> typing.Dict[str, str]: import platform headers: typing.Dict[str, str] = { - "User-Agent": "zep-cloud/4.0.0a4", + "User-Agent": "zep-cloud/4.0.0a5", "X-Fern-Language": "Python", "X-Fern-Runtime": f"python/{platform.python_version()}", "X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}", "X-Fern-SDK-Name": "zep-cloud", - "X-Fern-SDK-Version": "4.0.0a4", + "X-Fern-SDK-Version": "4.0.0a5", **(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 370c6048..b6b9eb9e 100644 --- a/src/zep_cloud/errors/__init__.py +++ b/src/zep_cloud/errors/__init__.py @@ -7,10 +7,14 @@ if typing.TYPE_CHECKING: from .bad_request_error import BadRequestError + from .conflict_error import ConflictError + from .forbidden_error import ForbiddenError from .not_found_error import NotFoundError from .unauthorized_error import UnauthorizedError _dynamic_imports: typing.Dict[str, str] = { "BadRequestError": ".bad_request_error", + "ConflictError": ".conflict_error", + "ForbiddenError": ".forbidden_error", "NotFoundError": ".not_found_error", "UnauthorizedError": ".unauthorized_error", } @@ -37,4 +41,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["BadRequestError", "NotFoundError", "UnauthorizedError"] +__all__ = ["BadRequestError", "ConflictError", "ForbiddenError", "NotFoundError", "UnauthorizedError"] diff --git a/src/zep_cloud/errors/conflict_error.py b/src/zep_cloud/errors/conflict_error.py new file mode 100644 index 00000000..a1954586 --- /dev/null +++ b/src/zep_cloud/errors/conflict_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 ConflictError(core_api_error_ApiError): + def __init__(self, body: types_api_error_ApiError, headers: typing.Optional[typing.Dict[str, str]] = None): + super().__init__(status_code=409, headers=headers, body=body) 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/__init__.py b/src/zep_cloud/graph/__init__.py index a82cd113..d586c4f7 100644 --- a/src/zep_cloud/graph/__init__.py +++ b/src/zep_cloud/graph/__init__.py @@ -6,8 +6,15 @@ from importlib import import_module if typing.TYPE_CHECKING: + from .types import V4GraphContextRequestRecencyBias, V4SubgraphRequestDirection from . import document_summary, edge, episode, node, observation, thread_summary + from .episode import V4AddEpisodeRequestType + from .node import V4NeighborsRequestDirection _dynamic_imports: typing.Dict[str, str] = { + "V4AddEpisodeRequestType": ".episode", + "V4GraphContextRequestRecencyBias": ".types", + "V4NeighborsRequestDirection": ".node", + "V4SubgraphRequestDirection": ".types", "document_summary": ".document_summary", "edge": ".edge", "episode": ".episode", @@ -38,4 +45,15 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["document_summary", "edge", "episode", "node", "observation", "thread_summary"] +__all__ = [ + "V4AddEpisodeRequestType", + "V4GraphContextRequestRecencyBias", + "V4NeighborsRequestDirection", + "V4SubgraphRequestDirection", + "document_summary", + "edge", + "episode", + "node", + "observation", + "thread_summary", +] diff --git a/src/zep_cloud/graph/client.py b/src/zep_cloud/graph/client.py index 5bd06b59..51b998f5 100644 --- a/src/zep_cloud/graph/client.py +++ b/src/zep_cloud/graph/client.py @@ -9,6 +9,7 @@ from ..core.request_options import RequestOptions from ..types.async_result import AsyncResult from ..types.clone_graph_result import CloneGraphResult +from ..types.custom_instruction import CustomInstruction from ..types.edge import Edge from ..types.edge_page import EdgePage from ..types.edge_type import EdgeType @@ -25,11 +26,16 @@ from ..types.observation import Observation from ..types.observation_page import ObservationPage from ..types.observation_steering import ObservationSteering +from ..types.observation_type import ObservationType from ..types.ontology import Ontology +from ..types.search_filters import SearchFilters from ..types.subgraph_response import SubgraphResponse from ..types.thread_summary import ThreadSummary from ..types.thread_summary_page import ThreadSummaryPage +from ..types.v4search_request_reranker import V4SearchRequestReranker from .raw_client import AsyncRawGraphClient, RawGraphClient +from .types.v4graph_context_request_recency_bias import V4GraphContextRequestRecencyBias +from .types.v4subgraph_request_direction import V4SubgraphRequestDirection if typing.TYPE_CHECKING: from .document_summary.client import AsyncDocumentSummaryClient, DocumentSummaryClient @@ -78,12 +84,16 @@ def create( Parameters ---------- description : typing.Optional[str] + A description of the graph. graph_id : typing.Optional[str] + An optional developer-assigned identifier for the graph. name : typing.Optional[str] + A display name for the graph. time_zone : typing.Optional[str] + The graph's IANA time zone. idempotency_key : typing.Optional[str] @@ -141,6 +151,8 @@ def list( asc or desc search : typing.Optional[str] + Filters results to graphs whose name, description, or graph ID contains + this text. idempotency_key : typing.Optional[str] @@ -194,10 +206,16 @@ def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -312,13 +330,13 @@ def update( Graph UUID description : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + A description of the graph. name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The graph's display name. time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The graph's IANA time zone. idempotency_key : typing.Optional[str] @@ -366,6 +384,7 @@ def clone( Graph UUID target_graph_id : typing.Optional[str] + An optional name for the cloned graph. idempotency_key : typing.Optional[str] @@ -400,11 +419,11 @@ def get_context( self, graph_uuid: str, *, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + query: str, + filters: typing.Optional[SearchFilters] = OMIT, include_results: typing.Optional[bool] = OMIT, max_characters: typing.Optional[int] = OMIT, - query: typing.Optional[str] = OMIT, - recency_bias: typing.Optional[str] = OMIT, + recency_bias: typing.Optional[V4GraphContextRequestRecencyBias] = OMIT, template_uuid: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -415,17 +434,24 @@ def get_context( graph_uuid : str Graph UUID - filters : typing.Optional[typing.Dict[str, typing.Any]] + query : str + The search query used to assemble the context block. + + filters : typing.Optional[SearchFilters] + Filters constraining which graph data can be selected for the context + block. include_results : typing.Optional[bool] + When true, includes the raw graph results selected for the context block. max_characters : typing.Optional[int] + The maximum number of characters in the assembled context block. - query : typing.Optional[str] - - recency_bias : typing.Optional[str] + recency_bias : typing.Optional[V4GraphContextRequestRecencyBias] + Adjusts result selection to favor more recent graph data. template_uuid : typing.Optional[str] + The UUID of a context template used to render the context block. idempotency_key : typing.Optional[str] @@ -446,14 +472,15 @@ def get_context( ) client.graph.get_context( graph_uuid="graph_uuid", + query="query", ) """ _response = self._raw_client.get_context( graph_uuid, + query=query, filters=filters, include_results=include_results, max_characters=max_characters, - query=query, recency_bias=recency_bias, template_uuid=template_uuid, idempotency_key=idempotency_key, @@ -497,7 +524,7 @@ def set_instructions( graph_uuid: str, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Instructions: @@ -508,8 +535,12 @@ def set_instructions( Graph UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[CustomInstruction]] + The custom extraction instructions in effect at this scope, each with a + name and text. idempotency_key : typing.Optional[str] @@ -578,7 +609,7 @@ def set_observation_steering( *, inherited: typing.Optional[bool] = OMIT, instruction: typing.Optional[str] = OMIT, - types: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ObservationSteering: @@ -589,10 +620,16 @@ def set_observation_steering( Graph UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. instruction : typing.Optional[str] + The natural-language instruction steering how observations are generated + at this scope. - types : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + types : typing.Optional[typing.Sequence[ObservationType]] + The named observation types, each with a description, that generation + should steer toward at this scope. idempotency_key : typing.Optional[str] @@ -671,10 +708,14 @@ def set_ontology( Graph UUID edge_types : typing.Optional[typing.Sequence[EdgeType]] + The edge types defined in the ontology in effect at this scope. entity_types : typing.Optional[typing.Sequence[EntityType]] + The entity types defined in the ontology in effect at this scope. inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. idempotency_key : typing.Optional[str] @@ -711,14 +752,14 @@ def search_edges( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Edge, EdgePage]: @@ -728,6 +769,9 @@ def search_edges( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -735,16 +779,21 @@ def search_edges( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -767,6 +816,7 @@ def search_edges( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) for item in response: yield item @@ -776,13 +826,13 @@ def search_edges( """ return self._raw_client.search_edges( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -792,14 +842,14 @@ def search_episodes( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Episode, EpisodePage]: @@ -809,6 +859,9 @@ def search_episodes( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -816,16 +869,21 @@ def search_episodes( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -848,6 +906,7 @@ def search_episodes( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) for item in response: yield item @@ -857,13 +916,13 @@ def search_episodes( """ return self._raw_client.search_episodes( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -873,14 +932,14 @@ def search_nodes( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Node, NodePage]: @@ -890,6 +949,9 @@ def search_nodes( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -897,16 +959,21 @@ def search_nodes( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -929,6 +996,7 @@ def search_nodes( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) for item in response: yield item @@ -938,13 +1006,13 @@ def search_nodes( """ return self._raw_client.search_nodes( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -954,14 +1022,14 @@ def search_observations( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Observation, ObservationPage]: @@ -971,6 +1039,9 @@ def search_observations( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -978,16 +1049,21 @@ def search_observations( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -1010,6 +1086,7 @@ def search_observations( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) for item in response: yield item @@ -1019,13 +1096,13 @@ def search_observations( """ return self._raw_client.search_observations( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -1035,14 +1112,14 @@ def search_thread_summaries( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ThreadSummary, ThreadSummaryPage]: @@ -1052,6 +1129,9 @@ def search_thread_summaries( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -1059,16 +1139,21 @@ def search_thread_summaries( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -1091,6 +1176,7 @@ def search_thread_summaries( graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) for item in response: yield item @@ -1100,13 +1186,13 @@ def search_thread_summaries( """ return self._raw_client.search_thread_summaries( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -1116,12 +1202,12 @@ def get_subgraph( self, graph_uuid: str, *, + seed_node_uuids: typing.Sequence[str], depth: typing.Optional[int] = OMIT, - direction: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + direction: typing.Optional[V4SubgraphRequestDirection] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, max_edges: typing.Optional[int] = OMIT, max_nodes: typing.Optional[int] = OMIT, - seed_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SubgraphResponse: @@ -1131,17 +1217,24 @@ def get_subgraph( graph_uuid : str Graph UUID + seed_node_uuids : typing.Sequence[str] + The node UUIDs to expand from, in traversal-priority order. + depth : typing.Optional[int] + The maximum traversal depth from the seed nodes. Defaults to 1. - direction : typing.Optional[str] + direction : typing.Optional[V4SubgraphRequestDirection] + The edge orientation to follow during expansion: in, out, or both. + Defaults to both. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining the traversed edges and included nodes. max_edges : typing.Optional[int] + The maximum number of edges in the response. Defaults to 200. max_nodes : typing.Optional[int] - - seed_node_uuids : typing.Optional[typing.Sequence[str]] + The maximum number of nodes in the response. Defaults to 100. idempotency_key : typing.Optional[str] @@ -1162,16 +1255,17 @@ def get_subgraph( ) client.graph.get_subgraph( graph_uuid="graph_uuid", + seed_node_uuids=["seed_node_uuids"], ) """ _response = self._raw_client.get_subgraph( graph_uuid, + seed_node_uuids=seed_node_uuids, depth=depth, direction=direction, filters=filters, max_edges=max_edges, max_nodes=max_nodes, - seed_node_uuids=seed_node_uuids, idempotency_key=idempotency_key, request_options=request_options, ) @@ -1299,12 +1393,16 @@ async def create( Parameters ---------- description : typing.Optional[str] + A description of the graph. graph_id : typing.Optional[str] + An optional developer-assigned identifier for the graph. name : typing.Optional[str] + A display name for the graph. time_zone : typing.Optional[str] + The graph's IANA time zone. idempotency_key : typing.Optional[str] @@ -1370,6 +1468,8 @@ async def list( asc or desc search : typing.Optional[str] + Filters results to graphs whose name, description, or graph ID contains + this text. idempotency_key : typing.Optional[str] @@ -1432,10 +1532,16 @@ async def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -1574,13 +1680,13 @@ async def update( Graph UUID description : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + A description of the graph. name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The graph's display name. time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The graph's IANA time zone. idempotency_key : typing.Optional[str] @@ -1636,6 +1742,7 @@ async def clone( Graph UUID target_graph_id : typing.Optional[str] + An optional name for the cloned graph. idempotency_key : typing.Optional[str] @@ -1678,11 +1785,11 @@ async def get_context( self, graph_uuid: str, *, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + query: str, + filters: typing.Optional[SearchFilters] = OMIT, include_results: typing.Optional[bool] = OMIT, max_characters: typing.Optional[int] = OMIT, - query: typing.Optional[str] = OMIT, - recency_bias: typing.Optional[str] = OMIT, + recency_bias: typing.Optional[V4GraphContextRequestRecencyBias] = OMIT, template_uuid: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -1693,17 +1800,24 @@ async def get_context( graph_uuid : str Graph UUID - filters : typing.Optional[typing.Dict[str, typing.Any]] + query : str + The search query used to assemble the context block. + + filters : typing.Optional[SearchFilters] + Filters constraining which graph data can be selected for the context + block. include_results : typing.Optional[bool] + When true, includes the raw graph results selected for the context block. max_characters : typing.Optional[int] + The maximum number of characters in the assembled context block. - query : typing.Optional[str] - - recency_bias : typing.Optional[str] + recency_bias : typing.Optional[V4GraphContextRequestRecencyBias] + Adjusts result selection to favor more recent graph data. template_uuid : typing.Optional[str] + The UUID of a context template used to render the context block. idempotency_key : typing.Optional[str] @@ -1729,6 +1843,7 @@ async def get_context( async def main() -> None: await client.graph.get_context( graph_uuid="graph_uuid", + query="query", ) @@ -1736,10 +1851,10 @@ async def main() -> None: """ _response = await self._raw_client.get_context( graph_uuid, + query=query, filters=filters, include_results=include_results, max_characters=max_characters, - query=query, recency_bias=recency_bias, template_uuid=template_uuid, idempotency_key=idempotency_key, @@ -1791,7 +1906,7 @@ async def set_instructions( graph_uuid: str, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Instructions: @@ -1802,8 +1917,12 @@ async def set_instructions( Graph UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[CustomInstruction]] + The custom extraction instructions in effect at this scope, each with a + name and text. idempotency_key : typing.Optional[str] @@ -1888,7 +2007,7 @@ async def set_observation_steering( *, inherited: typing.Optional[bool] = OMIT, instruction: typing.Optional[str] = OMIT, - types: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ObservationSteering: @@ -1899,10 +2018,16 @@ async def set_observation_steering( Graph UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. instruction : typing.Optional[str] + The natural-language instruction steering how observations are generated + at this scope. - types : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + types : typing.Optional[typing.Sequence[ObservationType]] + The named observation types, each with a description, that generation + should steer toward at this scope. idempotency_key : typing.Optional[str] @@ -1999,10 +2124,14 @@ async def set_ontology( Graph UUID edge_types : typing.Optional[typing.Sequence[EdgeType]] + The edge types defined in the ontology in effect at this scope. entity_types : typing.Optional[typing.Sequence[EntityType]] + The entity types defined in the ontology in effect at this scope. inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. idempotency_key : typing.Optional[str] @@ -2047,14 +2176,14 @@ async def search_edges( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Edge, EdgePage]: @@ -2064,6 +2193,9 @@ async def search_edges( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -2071,16 +2203,21 @@ async def search_edges( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -2108,6 +2245,7 @@ async def main() -> None: graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) async for item in response: yield item @@ -2121,13 +2259,13 @@ async def main() -> None: """ return await self._raw_client.search_edges( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -2137,14 +2275,14 @@ async def search_episodes( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Episode, EpisodePage]: @@ -2154,6 +2292,9 @@ async def search_episodes( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -2161,16 +2302,21 @@ async def search_episodes( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -2198,6 +2344,7 @@ async def main() -> None: graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) async for item in response: yield item @@ -2211,13 +2358,13 @@ async def main() -> None: """ return await self._raw_client.search_episodes( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -2227,14 +2374,14 @@ async def search_nodes( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Node, NodePage]: @@ -2244,6 +2391,9 @@ async def search_nodes( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -2251,16 +2401,21 @@ async def search_nodes( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -2288,6 +2443,7 @@ async def main() -> None: graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) async for item in response: yield item @@ -2301,13 +2457,13 @@ async def main() -> None: """ return await self._raw_client.search_nodes( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -2317,14 +2473,14 @@ async def search_observations( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Observation, ObservationPage]: @@ -2334,6 +2490,9 @@ async def search_observations( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -2341,16 +2500,21 @@ async def search_observations( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -2378,6 +2542,7 @@ async def main() -> None: graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) async for item in response: yield item @@ -2391,13 +2556,13 @@ async def main() -> None: """ return await self._raw_client.search_observations( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -2407,14 +2572,14 @@ async def search_thread_summaries( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ThreadSummary, ThreadSummaryPage]: @@ -2424,6 +2589,9 @@ async def search_thread_summaries( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -2431,16 +2599,21 @@ async def search_thread_summaries( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -2468,6 +2641,7 @@ async def main() -> None: graph_uuid="graph_uuid", limit=1, cursor="cursor", + query="query", ) async for item in response: yield item @@ -2481,13 +2655,13 @@ async def main() -> None: """ return await self._raw_client.search_thread_summaries( graph_uuid, + query=query, limit=limit, cursor=cursor, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -2497,12 +2671,12 @@ async def get_subgraph( self, graph_uuid: str, *, + seed_node_uuids: typing.Sequence[str], depth: typing.Optional[int] = OMIT, - direction: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + direction: typing.Optional[V4SubgraphRequestDirection] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, max_edges: typing.Optional[int] = OMIT, max_nodes: typing.Optional[int] = OMIT, - seed_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SubgraphResponse: @@ -2512,17 +2686,24 @@ async def get_subgraph( graph_uuid : str Graph UUID + seed_node_uuids : typing.Sequence[str] + The node UUIDs to expand from, in traversal-priority order. + depth : typing.Optional[int] + The maximum traversal depth from the seed nodes. Defaults to 1. - direction : typing.Optional[str] + direction : typing.Optional[V4SubgraphRequestDirection] + The edge orientation to follow during expansion: in, out, or both. + Defaults to both. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining the traversed edges and included nodes. max_edges : typing.Optional[int] + The maximum number of edges in the response. Defaults to 200. max_nodes : typing.Optional[int] - - seed_node_uuids : typing.Optional[typing.Sequence[str]] + The maximum number of nodes in the response. Defaults to 100. idempotency_key : typing.Optional[str] @@ -2548,6 +2729,7 @@ async def get_subgraph( async def main() -> None: await client.graph.get_subgraph( graph_uuid="graph_uuid", + seed_node_uuids=["seed_node_uuids"], ) @@ -2555,12 +2737,12 @@ async def main() -> None: """ _response = await self._raw_client.get_subgraph( graph_uuid, + seed_node_uuids=seed_node_uuids, depth=depth, direction=direction, filters=filters, max_edges=max_edges, max_nodes=max_nodes, - seed_node_uuids=seed_node_uuids, idempotency_key=idempotency_key, request_options=request_options, ) diff --git a/src/zep_cloud/graph/document_summary/client.py b/src/zep_cloud/graph/document_summary/client.py index da3c2d40..1337ac1b 100644 --- a/src/zep_cloud/graph/document_summary/client.py +++ b/src/zep_cloud/graph/document_summary/client.py @@ -51,6 +51,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -128,6 +129,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/graph/document_summary/raw_client.py b/src/zep_cloud/graph/document_summary/raw_client.py index a02ba67f..2f58d5be 100644 --- a/src/zep_cloud/graph/document_summary/raw_client.py +++ b/src/zep_cloud/graph/document_summary/raw_client.py @@ -11,6 +11,8 @@ from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError from ...errors.not_found_error import NotFoundError from ...errors.unauthorized_error import UnauthorizedError from ...types.api_error import ApiError as types_api_error_ApiError @@ -49,6 +51,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -120,6 +123,17 @@ def list( ), ), ) + 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), @@ -131,6 +145,17 @@ def list( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -172,6 +197,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -246,6 +272,17 @@ async def _get_next(): ), ), ) + 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), @@ -257,6 +294,17 @@ async def _get_next(): ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/graph/edge/client.py b/src/zep_cloud/graph/edge/client.py index 3a2bacd6..e8919f75 100644 --- a/src/zep_cloud/graph/edge/client.py +++ b/src/zep_cloud/graph/edge/client.py @@ -8,6 +8,7 @@ from ...types.add_edge_result import AddEdgeResult from ...types.async_result import AsyncResult from ...types.edge import Edge +from ...types.edge_node_ref import EdgeNodeRef from ...types.edge_page import EdgePage from .raw_client import AsyncRawEdgeClient, RawEdgeClient @@ -34,14 +35,14 @@ def add( self, graph_uuid: str, *, + fact: str, + fact_name: str, + source_node: EdgeNodeRef, + target_node: EdgeNodeRef, attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, expired_at: typing.Optional[str] = OMIT, - fact: typing.Optional[str] = OMIT, - fact_name: typing.Optional[str] = OMIT, invalid_at: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - source_node: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - target_node: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, valid_at: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -52,23 +53,35 @@ def add( graph_uuid : str Graph UUID - attributes : typing.Optional[typing.Dict[str, typing.Any]] + fact : str + The fact text describing the relationship between the source and target + nodes. - expired_at : typing.Optional[str] + fact_name : str + The name of the edge, in upper snake case, for example RELATES_TO. - fact : typing.Optional[str] + source_node : EdgeNodeRef + The source node of the edge, referenced by uuid or created or matched by + name. - fact_name : typing.Optional[str] + target_node : EdgeNodeRef + The target node of the edge, referenced by uuid or created or matched by + name. - invalid_at : typing.Optional[str] + attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to store on the edge. - metadata : typing.Optional[typing.Dict[str, typing.Any]] + expired_at : typing.Optional[str] + The time at which the fact was superseded or invalidated. - source_node : typing.Optional[typing.Dict[str, typing.Any]] + invalid_at : typing.Optional[str] + The time at which the fact stopped being true. - target_node : typing.Optional[typing.Dict[str, typing.Any]] + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata attached to the episode created for this edge. valid_at : typing.Optional[str] + The time at which the fact became true. idempotency_key : typing.Optional[str] @@ -82,25 +95,29 @@ def add( Examples -------- - from zep_cloud import Zep + from zep_cloud import EdgeNodeRef, Zep client = Zep( api_key="YOUR_API_KEY", ) client.graph.edge.add( graph_uuid="graph_uuid", + fact="fact", + fact_name="fact_name", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), ) """ _response = self._raw_client.add( graph_uuid, - attributes=attributes, - expired_at=expired_at, fact=fact, fact_name=fact_name, - invalid_at=invalid_at, - metadata=metadata, source_node=source_node, target_node=target_node, + attributes=attributes, + expired_at=expired_at, + invalid_at=invalid_at, + metadata=metadata, valid_at=valid_at, idempotency_key=idempotency_key, request_options=request_options, @@ -130,6 +147,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -265,9 +283,12 @@ def update( Edge UUID attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to merge onto the edge; a key set to null is + removed. fact : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The fact text describing the relationship between the source and target + nodes. idempotency_key : typing.Optional[str] @@ -321,14 +342,14 @@ async def add( self, graph_uuid: str, *, + fact: str, + fact_name: str, + source_node: EdgeNodeRef, + target_node: EdgeNodeRef, attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, expired_at: typing.Optional[str] = OMIT, - fact: typing.Optional[str] = OMIT, - fact_name: typing.Optional[str] = OMIT, invalid_at: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - source_node: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - target_node: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, valid_at: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -339,23 +360,35 @@ async def add( graph_uuid : str Graph UUID - attributes : typing.Optional[typing.Dict[str, typing.Any]] + fact : str + The fact text describing the relationship between the source and target + nodes. - expired_at : typing.Optional[str] + fact_name : str + The name of the edge, in upper snake case, for example RELATES_TO. - fact : typing.Optional[str] + source_node : EdgeNodeRef + The source node of the edge, referenced by uuid or created or matched by + name. - fact_name : typing.Optional[str] + target_node : EdgeNodeRef + The target node of the edge, referenced by uuid or created or matched by + name. - invalid_at : typing.Optional[str] + attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to store on the edge. - metadata : typing.Optional[typing.Dict[str, typing.Any]] + expired_at : typing.Optional[str] + The time at which the fact was superseded or invalidated. - source_node : typing.Optional[typing.Dict[str, typing.Any]] + invalid_at : typing.Optional[str] + The time at which the fact stopped being true. - target_node : typing.Optional[typing.Dict[str, typing.Any]] + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata attached to the episode created for this edge. valid_at : typing.Optional[str] + The time at which the fact became true. idempotency_key : typing.Optional[str] @@ -371,7 +404,7 @@ async def add( -------- import asyncio - from zep_cloud import AsyncZep + from zep_cloud import AsyncZep, EdgeNodeRef client = AsyncZep( api_key="YOUR_API_KEY", @@ -381,6 +414,10 @@ async def add( async def main() -> None: await client.graph.edge.add( graph_uuid="graph_uuid", + fact="fact", + fact_name="fact_name", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), ) @@ -388,14 +425,14 @@ async def main() -> None: """ _response = await self._raw_client.add( graph_uuid, - attributes=attributes, - expired_at=expired_at, fact=fact, fact_name=fact_name, - invalid_at=invalid_at, - metadata=metadata, source_node=source_node, target_node=target_node, + attributes=attributes, + expired_at=expired_at, + invalid_at=invalid_at, + metadata=metadata, valid_at=valid_at, idempotency_key=idempotency_key, request_options=request_options, @@ -425,6 +462,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -587,9 +625,12 @@ async def update( Edge UUID attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to merge onto the edge; a key set to null is + removed. fact : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The fact text describing the relationship between the source and target + nodes. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/graph/edge/raw_client.py b/src/zep_cloud/graph/edge/raw_client.py index f9062a76..712942e3 100644 --- a/src/zep_cloud/graph/edge/raw_client.py +++ b/src/zep_cloud/graph/edge/raw_client.py @@ -11,13 +11,17 @@ from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError from ...errors.not_found_error import NotFoundError from ...errors.unauthorized_error import UnauthorizedError from ...types.add_edge_result import AddEdgeResult from ...types.api_error import ApiError as types_api_error_ApiError from ...types.async_result import AsyncResult from ...types.edge import Edge +from ...types.edge_node_ref import EdgeNodeRef from ...types.edge_page import EdgePage from pydantic import ValidationError @@ -33,14 +37,14 @@ def add( self, graph_uuid: str, *, + fact: str, + fact_name: str, + source_node: EdgeNodeRef, + target_node: EdgeNodeRef, attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, expired_at: typing.Optional[str] = OMIT, - fact: typing.Optional[str] = OMIT, - fact_name: typing.Optional[str] = OMIT, invalid_at: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - source_node: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - target_node: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, valid_at: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -51,23 +55,35 @@ def add( graph_uuid : str Graph UUID - attributes : typing.Optional[typing.Dict[str, typing.Any]] + fact : str + The fact text describing the relationship between the source and target + nodes. - expired_at : typing.Optional[str] + fact_name : str + The name of the edge, in upper snake case, for example RELATES_TO. - fact : typing.Optional[str] + source_node : EdgeNodeRef + The source node of the edge, referenced by uuid or created or matched by + name. - fact_name : typing.Optional[str] + target_node : EdgeNodeRef + The target node of the edge, referenced by uuid or created or matched by + name. - invalid_at : typing.Optional[str] + attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to store on the edge. - metadata : typing.Optional[typing.Dict[str, typing.Any]] + expired_at : typing.Optional[str] + The time at which the fact was superseded or invalidated. - source_node : typing.Optional[typing.Dict[str, typing.Any]] + invalid_at : typing.Optional[str] + The time at which the fact stopped being true. - target_node : typing.Optional[typing.Dict[str, typing.Any]] + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata attached to the episode created for this edge. valid_at : typing.Optional[str] + The time at which the fact became true. idempotency_key : typing.Optional[str] @@ -89,8 +105,12 @@ def add( "fact_name": fact_name, "invalid_at": invalid_at, "metadata": metadata, - "source_node": source_node, - "target_node": target_node, + "source_node": convert_and_respect_annotation_metadata( + object_=source_node, annotation=EdgeNodeRef, direction="write" + ), + "target_node": convert_and_respect_annotation_metadata( + object_=target_node, annotation=EdgeNodeRef, direction="write" + ), "valid_at": valid_at, }, headers={ @@ -132,6 +152,17 @@ def add( ), ), ) + 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), @@ -143,6 +174,17 @@ def add( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -179,6 +221,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -250,6 +293,17 @@ def list( ), ), ) + 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), @@ -261,6 +315,17 @@ def list( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -331,6 +396,17 @@ def get( ), ), ) + 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), @@ -422,6 +498,17 @@ def delete( ), ), ) + 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), @@ -433,6 +520,17 @@ def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -466,9 +564,12 @@ def update( Edge UUID attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to merge onto the edge; a key set to null is + removed. fact : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The fact text describing the relationship between the source and target + nodes. idempotency_key : typing.Optional[str] @@ -526,6 +627,17 @@ def update( ), ), ) + 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), @@ -537,6 +649,17 @@ def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -559,14 +682,14 @@ async def add( self, graph_uuid: str, *, + fact: str, + fact_name: str, + source_node: EdgeNodeRef, + target_node: EdgeNodeRef, attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, expired_at: typing.Optional[str] = OMIT, - fact: typing.Optional[str] = OMIT, - fact_name: typing.Optional[str] = OMIT, invalid_at: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - source_node: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - target_node: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, valid_at: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -577,23 +700,35 @@ async def add( graph_uuid : str Graph UUID - attributes : typing.Optional[typing.Dict[str, typing.Any]] + fact : str + The fact text describing the relationship between the source and target + nodes. - expired_at : typing.Optional[str] + fact_name : str + The name of the edge, in upper snake case, for example RELATES_TO. - fact : typing.Optional[str] + source_node : EdgeNodeRef + The source node of the edge, referenced by uuid or created or matched by + name. - fact_name : typing.Optional[str] + target_node : EdgeNodeRef + The target node of the edge, referenced by uuid or created or matched by + name. - invalid_at : typing.Optional[str] + attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to store on the edge. - metadata : typing.Optional[typing.Dict[str, typing.Any]] + expired_at : typing.Optional[str] + The time at which the fact was superseded or invalidated. - source_node : typing.Optional[typing.Dict[str, typing.Any]] + invalid_at : typing.Optional[str] + The time at which the fact stopped being true. - target_node : typing.Optional[typing.Dict[str, typing.Any]] + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata attached to the episode created for this edge. valid_at : typing.Optional[str] + The time at which the fact became true. idempotency_key : typing.Optional[str] @@ -615,8 +750,12 @@ async def add( "fact_name": fact_name, "invalid_at": invalid_at, "metadata": metadata, - "source_node": source_node, - "target_node": target_node, + "source_node": convert_and_respect_annotation_metadata( + object_=source_node, annotation=EdgeNodeRef, direction="write" + ), + "target_node": convert_and_respect_annotation_metadata( + object_=target_node, annotation=EdgeNodeRef, direction="write" + ), "valid_at": valid_at, }, headers={ @@ -658,6 +797,17 @@ async def add( ), ), ) + 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), @@ -669,6 +819,17 @@ async def add( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -705,6 +866,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -779,6 +941,17 @@ async def _get_next(): ), ), ) + 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), @@ -790,6 +963,17 @@ async def _get_next(): ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -860,6 +1044,17 @@ async def get( ), ), ) + 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), @@ -951,6 +1146,17 @@ async def delete( ), ), ) + 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), @@ -962,6 +1168,17 @@ async def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -995,9 +1212,12 @@ async def update( Edge UUID attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to merge onto the edge; a key set to null is + removed. fact : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The fact text describing the relationship between the source and target + nodes. idempotency_key : typing.Optional[str] @@ -1055,6 +1275,17 @@ async def update( ), ), ) + 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), @@ -1066,6 +1297,17 @@ async def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/graph/episode/__init__.py b/src/zep_cloud/graph/episode/__init__.py index 5cde0202..e0a9a0ef 100644 --- a/src/zep_cloud/graph/episode/__init__.py +++ b/src/zep_cloud/graph/episode/__init__.py @@ -2,3 +2,33 @@ # isort: skip_file +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import V4AddEpisodeRequestType +_dynamic_imports: typing.Dict[str, str] = {"V4AddEpisodeRequestType": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["V4AddEpisodeRequestType"] diff --git a/src/zep_cloud/graph/episode/client.py b/src/zep_cloud/graph/episode/client.py index f27053d3..d4f8b96d 100644 --- a/src/zep_cloud/graph/episode/client.py +++ b/src/zep_cloud/graph/episode/client.py @@ -10,6 +10,7 @@ from ...types.episode import Episode from ...types.episode_page import EpisodePage from .raw_client import AsyncRawEpisodeClient, RawEpisodeClient +from .types.v4add_episode_request_type import V4AddEpisodeRequestType # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -89,13 +90,13 @@ def add( self, graph_uuid: str, *, + data: str, created_at: typing.Optional[str] = OMIT, - data: typing.Optional[str] = OMIT, document_id: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, source_description: typing.Optional[str] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, - type: typing.Optional[str] = OMIT, + type: typing.Optional[V4AddEpisodeRequestType] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AddEpisodeResult: @@ -105,19 +106,28 @@ def add( graph_uuid : str Graph UUID - created_at : typing.Optional[str] + data : str + The episode content to add to the graph. - data : typing.Optional[str] + created_at : typing.Optional[str] + The episode's reference time, used for temporal reasoning rather than + ingestion time. document_id : typing.Optional[str] + Groups this episode as a chunk of a document on the graph. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the episode. source_description : typing.Optional[str] + A description of the source of this episode. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology. - type : typing.Optional[str] + type : typing.Optional[V4AddEpisodeRequestType] + The data format of the episode: text, json, or message. Defaults to text. idempotency_key : typing.Optional[str] @@ -138,12 +148,13 @@ def add( ) client.graph.episode.add( graph_uuid="graph_uuid", + data="data", ) """ _response = self._raw_client.add( graph_uuid, - created_at=created_at, data=data, + created_at=created_at, document_id=document_id, metadata=metadata, source_description=source_description, @@ -177,6 +188,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -313,6 +325,7 @@ def update( Episode UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the episode; a key set to null is removed. idempotency_key : typing.Optional[str] @@ -429,13 +442,13 @@ async def add( self, graph_uuid: str, *, + data: str, created_at: typing.Optional[str] = OMIT, - data: typing.Optional[str] = OMIT, document_id: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, source_description: typing.Optional[str] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, - type: typing.Optional[str] = OMIT, + type: typing.Optional[V4AddEpisodeRequestType] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AddEpisodeResult: @@ -445,19 +458,28 @@ async def add( graph_uuid : str Graph UUID - created_at : typing.Optional[str] + data : str + The episode content to add to the graph. - data : typing.Optional[str] + created_at : typing.Optional[str] + The episode's reference time, used for temporal reasoning rather than + ingestion time. document_id : typing.Optional[str] + Groups this episode as a chunk of a document on the graph. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the episode. source_description : typing.Optional[str] + A description of the source of this episode. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology. - type : typing.Optional[str] + type : typing.Optional[V4AddEpisodeRequestType] + The data format of the episode: text, json, or message. Defaults to text. idempotency_key : typing.Optional[str] @@ -483,6 +505,7 @@ async def add( async def main() -> None: await client.graph.episode.add( graph_uuid="graph_uuid", + data="data", ) @@ -490,8 +513,8 @@ async def main() -> None: """ _response = await self._raw_client.add( graph_uuid, - created_at=created_at, data=data, + created_at=created_at, document_id=document_id, metadata=metadata, source_description=source_description, @@ -525,6 +548,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -686,6 +710,7 @@ async def update( Episode UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the episode; a key set to null is removed. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/graph/episode/raw_client.py b/src/zep_cloud/graph/episode/raw_client.py index fa405b2e..0e5fb735 100644 --- a/src/zep_cloud/graph/episode/raw_client.py +++ b/src/zep_cloud/graph/episode/raw_client.py @@ -12,6 +12,8 @@ from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError from ...errors.not_found_error import NotFoundError from ...errors.unauthorized_error import UnauthorizedError from ...types.add_episode_result import AddEpisodeResult @@ -19,6 +21,7 @@ from ...types.async_result import AsyncResult from ...types.episode import Episode from ...types.episode_page import EpisodePage +from .types.v4add_episode_request_type import V4AddEpisodeRequestType from pydantic import ValidationError # this is used as the default value for optional parameters @@ -112,6 +115,17 @@ def list_for_document( ), ), ) + 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), @@ -123,6 +137,17 @@ def list_for_document( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -140,13 +165,13 @@ def add( self, graph_uuid: str, *, + data: str, created_at: typing.Optional[str] = OMIT, - data: typing.Optional[str] = OMIT, document_id: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, source_description: typing.Optional[str] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, - type: typing.Optional[str] = OMIT, + type: typing.Optional[V4AddEpisodeRequestType] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[AddEpisodeResult]: @@ -156,19 +181,28 @@ def add( graph_uuid : str Graph UUID - created_at : typing.Optional[str] + data : str + The episode content to add to the graph. - data : typing.Optional[str] + created_at : typing.Optional[str] + The episode's reference time, used for temporal reasoning rather than + ingestion time. document_id : typing.Optional[str] + Groups this episode as a chunk of a document on the graph. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the episode. source_description : typing.Optional[str] + A description of the source of this episode. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology. - type : typing.Optional[str] + type : typing.Optional[V4AddEpisodeRequestType] + The data format of the episode: text, json, or message. Defaults to text. idempotency_key : typing.Optional[str] @@ -231,6 +265,17 @@ def add( ), ), ) + 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), @@ -242,6 +287,17 @@ def add( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -278,6 +334,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -349,6 +406,17 @@ def list( ), ), ) + 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), @@ -430,6 +498,17 @@ def get( ), ), ) + 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), @@ -521,6 +600,17 @@ def delete( ), ), ) + 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), @@ -532,6 +622,17 @@ def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -564,6 +665,7 @@ def update( Episode UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the episode; a key set to null is removed. idempotency_key : typing.Optional[str] @@ -620,6 +722,17 @@ def update( ), ), ) + 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), @@ -631,6 +744,17 @@ def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -735,6 +859,17 @@ async def _get_next(): ), ), ) + 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), @@ -746,6 +881,17 @@ async def _get_next(): ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -763,13 +909,13 @@ async def add( self, graph_uuid: str, *, + data: str, created_at: typing.Optional[str] = OMIT, - data: typing.Optional[str] = OMIT, document_id: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, source_description: typing.Optional[str] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, - type: typing.Optional[str] = OMIT, + type: typing.Optional[V4AddEpisodeRequestType] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[AddEpisodeResult]: @@ -779,19 +925,28 @@ async def add( graph_uuid : str Graph UUID - created_at : typing.Optional[str] + data : str + The episode content to add to the graph. - data : typing.Optional[str] + created_at : typing.Optional[str] + The episode's reference time, used for temporal reasoning rather than + ingestion time. document_id : typing.Optional[str] + Groups this episode as a chunk of a document on the graph. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the episode. source_description : typing.Optional[str] + A description of the source of this episode. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology. - type : typing.Optional[str] + type : typing.Optional[V4AddEpisodeRequestType] + The data format of the episode: text, json, or message. Defaults to text. idempotency_key : typing.Optional[str] @@ -854,6 +1009,17 @@ async def add( ), ), ) + 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), @@ -865,6 +1031,17 @@ async def add( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -901,6 +1078,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -975,6 +1153,17 @@ async def _get_next(): ), ), ) + 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), @@ -1056,6 +1245,17 @@ async def get( ), ), ) + 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), @@ -1147,6 +1347,17 @@ async def delete( ), ), ) + 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), @@ -1158,6 +1369,17 @@ async def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1190,6 +1412,7 @@ async def update( Episode UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the episode; a key set to null is removed. idempotency_key : typing.Optional[str] @@ -1246,6 +1469,17 @@ async def update( ), ), ) + 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), @@ -1257,6 +1491,17 @@ async def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/graph/episode/types/__init__.py b/src/zep_cloud/graph/episode/types/__init__.py new file mode 100644 index 00000000..159e4f05 --- /dev/null +++ b/src/zep_cloud/graph/episode/types/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .v4add_episode_request_type import V4AddEpisodeRequestType +_dynamic_imports: typing.Dict[str, str] = {"V4AddEpisodeRequestType": ".v4add_episode_request_type"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["V4AddEpisodeRequestType"] diff --git a/src/zep_cloud/graph/episode/types/v4add_episode_request_type.py b/src/zep_cloud/graph/episode/types/v4add_episode_request_type.py new file mode 100644 index 00000000..7c330ae1 --- /dev/null +++ b/src/zep_cloud/graph/episode/types/v4add_episode_request_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V4AddEpisodeRequestType = typing.Union[typing.Literal["text", "json", "message"], typing.Any] diff --git a/src/zep_cloud/graph/node/__init__.py b/src/zep_cloud/graph/node/__init__.py index 5cde0202..6c63ceb0 100644 --- a/src/zep_cloud/graph/node/__init__.py +++ b/src/zep_cloud/graph/node/__init__.py @@ -2,3 +2,33 @@ # isort: skip_file +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import V4NeighborsRequestDirection +_dynamic_imports: typing.Dict[str, str] = {"V4NeighborsRequestDirection": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["V4NeighborsRequestDirection"] diff --git a/src/zep_cloud/graph/node/client.py b/src/zep_cloud/graph/node/client.py index 25b01601..c46151da 100644 --- a/src/zep_cloud/graph/node/client.py +++ b/src/zep_cloud/graph/node/client.py @@ -10,8 +10,11 @@ from ...types.neighbor_entry import NeighborEntry from ...types.neighbor_page import NeighborPage from ...types.node import Node +from ...types.node_input import NodeInput from ...types.node_page import NodePage +from ...types.search_filters import SearchFilters from .raw_client import AsyncRawNodeClient, RawNodeClient +from .types.v4neighbors_request_direction import V4NeighborsRequestDirection # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -36,7 +39,7 @@ def add( self, graph_uuid: str, *, - nodes: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + nodes: typing.Sequence[NodeInput], idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AddNodesResult: @@ -46,7 +49,8 @@ def add( graph_uuid : str Graph UUID - nodes : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + nodes : typing.Sequence[NodeInput] + The nodes to add to the graph. idempotency_key : typing.Optional[str] @@ -60,13 +64,18 @@ def add( Examples -------- - from zep_cloud import Zep + from zep_cloud import NodeInput, Zep client = Zep( api_key="YOUR_API_KEY", ) client.graph.node.add( graph_uuid="graph_uuid", + nodes=[ + NodeInput( + name="name", + ) + ], ) """ _response = self._raw_client.add( @@ -97,6 +106,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -233,12 +243,14 @@ def update( Node UUID attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to merge onto the node; a key set to null is + removed. name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The node's name. summary : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + A summary of the node. idempotency_key : typing.Optional[str] @@ -280,8 +292,8 @@ def list_neighbors( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - direction: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + direction: typing.Optional[V4NeighborsRequestDirection] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[NeighborEntry, NeighborPage]: @@ -300,9 +312,11 @@ def list_neighbors( cursor : typing.Optional[str] Opaque page cursor - direction : typing.Optional[str] + direction : typing.Optional[V4NeighborsRequestDirection] + The edge orientation to follow from the node: in, out, or both. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining the connecting edges and the neighbor nodes. idempotency_key : typing.Optional[str] @@ -364,7 +378,7 @@ async def add( self, graph_uuid: str, *, - nodes: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + nodes: typing.Sequence[NodeInput], idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AddNodesResult: @@ -374,7 +388,8 @@ async def add( graph_uuid : str Graph UUID - nodes : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + nodes : typing.Sequence[NodeInput] + The nodes to add to the graph. idempotency_key : typing.Optional[str] @@ -390,7 +405,7 @@ async def add( -------- import asyncio - from zep_cloud import AsyncZep + from zep_cloud import AsyncZep, NodeInput client = AsyncZep( api_key="YOUR_API_KEY", @@ -400,6 +415,11 @@ async def add( async def main() -> None: await client.graph.node.add( graph_uuid="graph_uuid", + nodes=[ + NodeInput( + name="name", + ) + ], ) @@ -433,6 +453,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -596,12 +617,14 @@ async def update( Node UUID attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to merge onto the node; a key set to null is + removed. name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The node's name. summary : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + A summary of the node. idempotency_key : typing.Optional[str] @@ -651,8 +674,8 @@ async def list_neighbors( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - direction: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + direction: typing.Optional[V4NeighborsRequestDirection] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[NeighborEntry, NeighborPage]: @@ -671,9 +694,11 @@ async def list_neighbors( cursor : typing.Optional[str] Opaque page cursor - direction : typing.Optional[str] + direction : typing.Optional[V4NeighborsRequestDirection] + The edge orientation to follow from the node: in, out, or both. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining the connecting edges and the neighbor nodes. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/graph/node/raw_client.py b/src/zep_cloud/graph/node/raw_client.py index 7a6ad915..c3bf3708 100644 --- a/src/zep_cloud/graph/node/raw_client.py +++ b/src/zep_cloud/graph/node/raw_client.py @@ -11,7 +11,10 @@ from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError from ...errors.not_found_error import NotFoundError from ...errors.unauthorized_error import UnauthorizedError from ...types.add_nodes_result import AddNodesResult @@ -20,7 +23,10 @@ from ...types.neighbor_entry import NeighborEntry from ...types.neighbor_page import NeighborPage from ...types.node import Node +from ...types.node_input import NodeInput from ...types.node_page import NodePage +from ...types.search_filters import SearchFilters +from .types.v4neighbors_request_direction import V4NeighborsRequestDirection from pydantic import ValidationError # this is used as the default value for optional parameters @@ -35,7 +41,7 @@ def add( self, graph_uuid: str, *, - nodes: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + nodes: typing.Sequence[NodeInput], idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[AddNodesResult]: @@ -45,7 +51,8 @@ def add( graph_uuid : str Graph UUID - nodes : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + nodes : typing.Sequence[NodeInput] + The nodes to add to the graph. idempotency_key : typing.Optional[str] @@ -61,7 +68,9 @@ def add( f"graphs/{jsonable_encoder(graph_uuid)}/nodes", method="POST", json={ - "nodes": nodes, + "nodes": convert_and_respect_annotation_metadata( + object_=nodes, annotation=typing.Sequence[NodeInput], direction="write" + ), }, headers={ "content-type": "application/json", @@ -102,6 +111,17 @@ def add( ), ), ) + 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), @@ -113,6 +133,17 @@ def add( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -149,6 +180,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -220,6 +252,17 @@ def list( ), ), ) + 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), @@ -231,6 +274,17 @@ def list( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -301,6 +355,17 @@ def get( ), ), ) + 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), @@ -312,6 +377,17 @@ def get( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -392,6 +468,17 @@ def delete( ), ), ) + 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), @@ -403,6 +490,17 @@ def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -437,12 +535,14 @@ def update( Node UUID attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to merge onto the node; a key set to null is + removed. name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The node's name. summary : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + A summary of the node. idempotency_key : typing.Optional[str] @@ -501,6 +601,17 @@ def update( ), ), ) + 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), @@ -512,6 +623,17 @@ def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -532,8 +654,8 @@ def list_neighbors( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - direction: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + direction: typing.Optional[V4NeighborsRequestDirection] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[NeighborEntry, NeighborPage]: @@ -552,9 +674,11 @@ def list_neighbors( cursor : typing.Optional[str] Opaque page cursor - direction : typing.Optional[str] + direction : typing.Optional[V4NeighborsRequestDirection] + The edge orientation to follow from the node: in, out, or both. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining the connecting edges and the neighbor nodes. idempotency_key : typing.Optional[str] @@ -575,7 +699,9 @@ def list_neighbors( }, json={ "direction": direction, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), }, headers={ "content-type": "application/json", @@ -629,6 +755,17 @@ def list_neighbors( ), ), ) + 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), @@ -640,6 +777,17 @@ def list_neighbors( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -662,7 +810,7 @@ async def add( self, graph_uuid: str, *, - nodes: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + nodes: typing.Sequence[NodeInput], idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[AddNodesResult]: @@ -672,7 +820,8 @@ async def add( graph_uuid : str Graph UUID - nodes : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + nodes : typing.Sequence[NodeInput] + The nodes to add to the graph. idempotency_key : typing.Optional[str] @@ -688,7 +837,9 @@ async def add( f"graphs/{jsonable_encoder(graph_uuid)}/nodes", method="POST", json={ - "nodes": nodes, + "nodes": convert_and_respect_annotation_metadata( + object_=nodes, annotation=typing.Sequence[NodeInput], direction="write" + ), }, headers={ "content-type": "application/json", @@ -729,6 +880,17 @@ async def add( ), ), ) + 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), @@ -740,6 +902,17 @@ async def add( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -776,6 +949,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -850,6 +1024,17 @@ async def _get_next(): ), ), ) + 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), @@ -861,6 +1046,17 @@ async def _get_next(): ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -931,6 +1127,17 @@ async def get( ), ), ) + 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), @@ -942,6 +1149,17 @@ async def get( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1022,6 +1240,17 @@ async def delete( ), ), ) + 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), @@ -1033,6 +1262,17 @@ async def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1067,12 +1307,14 @@ async def update( Node UUID attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to merge onto the node; a key set to null is + removed. name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The node's name. summary : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + A summary of the node. idempotency_key : typing.Optional[str] @@ -1131,6 +1373,17 @@ async def update( ), ), ) + 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), @@ -1142,6 +1395,17 @@ async def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1162,8 +1426,8 @@ async def list_neighbors( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - direction: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + direction: typing.Optional[V4NeighborsRequestDirection] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[NeighborEntry, NeighborPage]: @@ -1182,9 +1446,11 @@ async def list_neighbors( cursor : typing.Optional[str] Opaque page cursor - direction : typing.Optional[str] + direction : typing.Optional[V4NeighborsRequestDirection] + The edge orientation to follow from the node: in, out, or both. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining the connecting edges and the neighbor nodes. idempotency_key : typing.Optional[str] @@ -1205,7 +1471,9 @@ async def list_neighbors( }, json={ "direction": direction, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), }, headers={ "content-type": "application/json", @@ -1262,6 +1530,17 @@ async def _get_next(): ), ), ) + 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), @@ -1273,6 +1552,17 @@ async def _get_next(): ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/graph/node/types/__init__.py b/src/zep_cloud/graph/node/types/__init__.py new file mode 100644 index 00000000..92034f44 --- /dev/null +++ b/src/zep_cloud/graph/node/types/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .v4neighbors_request_direction import V4NeighborsRequestDirection +_dynamic_imports: typing.Dict[str, str] = {"V4NeighborsRequestDirection": ".v4neighbors_request_direction"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["V4NeighborsRequestDirection"] diff --git a/src/zep_cloud/graph/node/types/v4neighbors_request_direction.py b/src/zep_cloud/graph/node/types/v4neighbors_request_direction.py new file mode 100644 index 00000000..6d43f589 --- /dev/null +++ b/src/zep_cloud/graph/node/types/v4neighbors_request_direction.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V4NeighborsRequestDirection = typing.Union[typing.Literal["in", "out", "both"], typing.Any] diff --git a/src/zep_cloud/graph/observation/client.py b/src/zep_cloud/graph/observation/client.py index 7669ad8c..068737a7 100644 --- a/src/zep_cloud/graph/observation/client.py +++ b/src/zep_cloud/graph/observation/client.py @@ -51,6 +51,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -163,6 +164,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/graph/observation/raw_client.py b/src/zep_cloud/graph/observation/raw_client.py index 85ddd323..0d76c501 100644 --- a/src/zep_cloud/graph/observation/raw_client.py +++ b/src/zep_cloud/graph/observation/raw_client.py @@ -12,6 +12,8 @@ from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError from ...errors.not_found_error import NotFoundError from ...errors.unauthorized_error import UnauthorizedError from ...types.api_error import ApiError as types_api_error_ApiError @@ -50,6 +52,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -121,6 +124,17 @@ def list( ), ), ) + 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), @@ -132,6 +146,17 @@ def list( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -202,6 +227,17 @@ def get( ), ), ) + 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), @@ -213,6 +249,17 @@ def get( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -254,6 +301,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -328,6 +376,17 @@ async def _get_next(): ), ), ) + 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), @@ -339,6 +398,17 @@ async def _get_next(): ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -409,6 +479,17 @@ async def get( ), ), ) + 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), @@ -420,6 +501,17 @@ async def get( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/graph/raw_client.py b/src/zep_cloud/graph/raw_client.py index ff8e012a..22ebf730 100644 --- a/src/zep_cloud/graph/raw_client.py +++ b/src/zep_cloud/graph/raw_client.py @@ -13,11 +13,14 @@ from ..core.request_options import RequestOptions from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..types.api_error import ApiError as types_api_error_ApiError from ..types.async_result import AsyncResult from ..types.clone_graph_result import CloneGraphResult +from ..types.custom_instruction import CustomInstruction from ..types.edge import Edge from ..types.edge_page import EdgePage from ..types.edge_type import EdgeType @@ -34,10 +37,15 @@ from ..types.observation import Observation from ..types.observation_page import ObservationPage from ..types.observation_steering import ObservationSteering +from ..types.observation_type import ObservationType from ..types.ontology import Ontology +from ..types.search_filters import SearchFilters from ..types.subgraph_response import SubgraphResponse from ..types.thread_summary import ThreadSummary from ..types.thread_summary_page import ThreadSummaryPage +from ..types.v4search_request_reranker import V4SearchRequestReranker +from .types.v4graph_context_request_recency_bias import V4GraphContextRequestRecencyBias +from .types.v4subgraph_request_direction import V4SubgraphRequestDirection from pydantic import ValidationError # this is used as the default value for optional parameters @@ -62,12 +70,16 @@ def create( Parameters ---------- description : typing.Optional[str] + A description of the graph. graph_id : typing.Optional[str] + An optional developer-assigned identifier for the graph. name : typing.Optional[str] + A display name for the graph. time_zone : typing.Optional[str] + The graph's IANA time zone. idempotency_key : typing.Optional[str] @@ -127,6 +139,17 @@ def create( ), ), ) + 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), @@ -138,6 +161,17 @@ def create( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -178,6 +212,8 @@ def list( asc or desc search : typing.Optional[str] + Filters results to graphs whose name, description, or graph ID contains + this text. idempotency_key : typing.Optional[str] @@ -252,6 +288,17 @@ def list( ), ), ) + 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), @@ -289,10 +336,16 @@ def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -427,6 +480,17 @@ def get(self, graph_uuid: str, *, request_options: typing.Optional[RequestOption ), ), ) + 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), @@ -514,6 +578,17 @@ def delete( ), ), ) + 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), @@ -525,6 +600,17 @@ def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -555,13 +641,13 @@ def update( Graph UUID description : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + A description of the graph. name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The graph's display name. time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The graph's IANA time zone. idempotency_key : typing.Optional[str] @@ -620,6 +706,17 @@ def update( ), ), ) + 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), @@ -631,6 +728,17 @@ def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -659,6 +767,7 @@ def clone( Graph UUID target_graph_id : typing.Optional[str] + An optional name for the cloned graph. idempotency_key : typing.Optional[str] @@ -715,6 +824,17 @@ def clone( ), ), ) + 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), @@ -726,6 +846,17 @@ def clone( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -743,11 +874,11 @@ def get_context( self, graph_uuid: str, *, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + query: str, + filters: typing.Optional[SearchFilters] = OMIT, include_results: typing.Optional[bool] = OMIT, max_characters: typing.Optional[int] = OMIT, - query: typing.Optional[str] = OMIT, - recency_bias: typing.Optional[str] = OMIT, + recency_bias: typing.Optional[V4GraphContextRequestRecencyBias] = OMIT, template_uuid: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -758,17 +889,24 @@ def get_context( graph_uuid : str Graph UUID - filters : typing.Optional[typing.Dict[str, typing.Any]] + query : str + The search query used to assemble the context block. + + filters : typing.Optional[SearchFilters] + Filters constraining which graph data can be selected for the context + block. include_results : typing.Optional[bool] + When true, includes the raw graph results selected for the context block. max_characters : typing.Optional[int] + The maximum number of characters in the assembled context block. - query : typing.Optional[str] - - recency_bias : typing.Optional[str] + recency_bias : typing.Optional[V4GraphContextRequestRecencyBias] + Adjusts result selection to favor more recent graph data. template_uuid : typing.Optional[str] + The UUID of a context template used to render the context block. idempotency_key : typing.Optional[str] @@ -784,7 +922,9 @@ def get_context( f"graphs/{jsonable_encoder(graph_uuid)}/context", method="POST", json={ - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "include_results": include_results, "max_characters": max_characters, "query": query, @@ -830,6 +970,17 @@ def get_context( ), ), ) + 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), @@ -841,6 +992,17 @@ def get_context( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -937,7 +1099,7 @@ def set_instructions( graph_uuid: str, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Instructions]: @@ -948,8 +1110,12 @@ def set_instructions( Graph UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[CustomInstruction]] + The custom extraction instructions in effect at this scope, each with a + name and text. idempotency_key : typing.Optional[str] @@ -966,7 +1132,9 @@ def set_instructions( method="PUT", json={ "inherited": inherited, - "instructions": instructions, + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[CustomInstruction], direction="write" + ), }, headers={ "content-type": "application/json", @@ -1115,7 +1283,7 @@ def set_observation_steering( *, inherited: typing.Optional[bool] = OMIT, instruction: typing.Optional[str] = OMIT, - types: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[ObservationSteering]: @@ -1126,10 +1294,16 @@ def set_observation_steering( Graph UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. instruction : typing.Optional[str] + The natural-language instruction steering how observations are generated + at this scope. - types : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + types : typing.Optional[typing.Sequence[ObservationType]] + The named observation types, each with a description, that generation + should steer toward at this scope. idempotency_key : typing.Optional[str] @@ -1147,7 +1321,9 @@ def set_observation_steering( json={ "inherited": inherited, "instruction": instruction, - "types": types, + "types": convert_and_respect_annotation_metadata( + object_=types, annotation=typing.Sequence[ObservationType], direction="write" + ), }, headers={ "content-type": "application/json", @@ -1307,10 +1483,14 @@ def set_ontology( Graph UUID edge_types : typing.Optional[typing.Sequence[EdgeType]] + The edge types defined in the ontology in effect at this scope. entity_types : typing.Optional[typing.Sequence[EntityType]] + The entity types defined in the ontology in effect at this scope. inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. idempotency_key : typing.Optional[str] @@ -1401,14 +1581,14 @@ def search_edges( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Edge, EdgePage]: @@ -1418,6 +1598,9 @@ def search_edges( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -1425,16 +1608,21 @@ def search_edges( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -1456,7 +1644,9 @@ def search_edges( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -1482,13 +1672,13 @@ def search_edges( _has_next = _parsed_next is not None and _parsed_next != "" _get_next = lambda: self.search_edges( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -1516,6 +1706,17 @@ def search_edges( ), ), ) + 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), @@ -1544,14 +1745,14 @@ def search_episodes( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Episode, EpisodePage]: @@ -1561,6 +1762,9 @@ def search_episodes( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -1568,16 +1772,21 @@ def search_episodes( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -1599,7 +1808,9 @@ def search_episodes( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -1625,13 +1836,13 @@ def search_episodes( _has_next = _parsed_next is not None and _parsed_next != "" _get_next = lambda: self.search_episodes( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -1659,6 +1870,17 @@ def search_episodes( ), ), ) + 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), @@ -1687,14 +1909,14 @@ def search_nodes( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Node, NodePage]: @@ -1704,6 +1926,9 @@ def search_nodes( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -1711,16 +1936,21 @@ def search_nodes( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -1742,7 +1972,9 @@ def search_nodes( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -1768,13 +2000,13 @@ def search_nodes( _has_next = _parsed_next is not None and _parsed_next != "" _get_next = lambda: self.search_nodes( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -1802,6 +2034,17 @@ def search_nodes( ), ), ) + 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), @@ -1830,14 +2073,14 @@ def search_observations( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Observation, ObservationPage]: @@ -1847,6 +2090,9 @@ def search_observations( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -1854,16 +2100,21 @@ def search_observations( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -1885,7 +2136,9 @@ def search_observations( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -1911,13 +2164,13 @@ def search_observations( _has_next = _parsed_next is not None and _parsed_next != "" _get_next = lambda: self.search_observations( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -1945,6 +2198,17 @@ def search_observations( ), ), ) + 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), @@ -1973,14 +2237,14 @@ def search_thread_summaries( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ThreadSummary, ThreadSummaryPage]: @@ -1990,6 +2254,9 @@ def search_thread_summaries( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -1997,16 +2264,21 @@ def search_thread_summaries( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -2028,7 +2300,9 @@ def search_thread_summaries( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -2054,13 +2328,13 @@ def search_thread_summaries( _has_next = _parsed_next is not None and _parsed_next != "" _get_next = lambda: self.search_thread_summaries( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -2088,6 +2362,17 @@ def search_thread_summaries( ), ), ) + 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), @@ -2116,12 +2401,12 @@ def get_subgraph( self, graph_uuid: str, *, + seed_node_uuids: typing.Sequence[str], depth: typing.Optional[int] = OMIT, - direction: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + direction: typing.Optional[V4SubgraphRequestDirection] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, max_edges: typing.Optional[int] = OMIT, max_nodes: typing.Optional[int] = OMIT, - seed_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[SubgraphResponse]: @@ -2131,17 +2416,24 @@ def get_subgraph( graph_uuid : str Graph UUID + seed_node_uuids : typing.Sequence[str] + The node UUIDs to expand from, in traversal-priority order. + depth : typing.Optional[int] + The maximum traversal depth from the seed nodes. Defaults to 1. - direction : typing.Optional[str] + direction : typing.Optional[V4SubgraphRequestDirection] + The edge orientation to follow during expansion: in, out, or both. + Defaults to both. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining the traversed edges and included nodes. max_edges : typing.Optional[int] + The maximum number of edges in the response. Defaults to 200. max_nodes : typing.Optional[int] - - seed_node_uuids : typing.Optional[typing.Sequence[str]] + The maximum number of nodes in the response. Defaults to 100. idempotency_key : typing.Optional[str] @@ -2159,7 +2451,9 @@ def get_subgraph( json={ "depth": depth, "direction": direction, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "max_edges": max_edges, "max_nodes": max_nodes, "seed_node_uuids": seed_node_uuids, @@ -2203,6 +2497,17 @@ def get_subgraph( ), ), ) + 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), @@ -2290,6 +2595,17 @@ def warm( ), ), ) + 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), @@ -2301,6 +2617,17 @@ def warm( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -2333,12 +2660,16 @@ async def create( Parameters ---------- description : typing.Optional[str] + A description of the graph. graph_id : typing.Optional[str] + An optional developer-assigned identifier for the graph. name : typing.Optional[str] + A display name for the graph. time_zone : typing.Optional[str] + The graph's IANA time zone. idempotency_key : typing.Optional[str] @@ -2398,6 +2729,17 @@ async def create( ), ), ) + 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), @@ -2409,6 +2751,17 @@ async def create( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -2449,6 +2802,8 @@ async def list( asc or desc search : typing.Optional[str] + Filters results to graphs whose name, description, or graph ID contains + this text. idempotency_key : typing.Optional[str] @@ -2526,6 +2881,17 @@ async def _get_next(): ), ), ) + 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), @@ -2563,10 +2929,16 @@ async def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -2703,6 +3075,17 @@ async def get( ), ), ) + 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), @@ -2790,6 +3173,17 @@ async def delete( ), ), ) + 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), @@ -2801,6 +3195,17 @@ async def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -2831,13 +3236,13 @@ async def update( Graph UUID description : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + A description of the graph. name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The graph's display name. time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The graph's IANA time zone. idempotency_key : typing.Optional[str] @@ -2896,6 +3301,17 @@ async def update( ), ), ) + 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), @@ -2907,6 +3323,17 @@ async def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -2935,6 +3362,7 @@ async def clone( Graph UUID target_graph_id : typing.Optional[str] + An optional name for the cloned graph. idempotency_key : typing.Optional[str] @@ -2991,6 +3419,17 @@ async def clone( ), ), ) + 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), @@ -3002,6 +3441,17 @@ async def clone( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -3019,11 +3469,11 @@ async def get_context( self, graph_uuid: str, *, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + query: str, + filters: typing.Optional[SearchFilters] = OMIT, include_results: typing.Optional[bool] = OMIT, max_characters: typing.Optional[int] = OMIT, - query: typing.Optional[str] = OMIT, - recency_bias: typing.Optional[str] = OMIT, + recency_bias: typing.Optional[V4GraphContextRequestRecencyBias] = OMIT, template_uuid: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -3034,17 +3484,24 @@ async def get_context( graph_uuid : str Graph UUID - filters : typing.Optional[typing.Dict[str, typing.Any]] + query : str + The search query used to assemble the context block. + + filters : typing.Optional[SearchFilters] + Filters constraining which graph data can be selected for the context + block. include_results : typing.Optional[bool] + When true, includes the raw graph results selected for the context block. max_characters : typing.Optional[int] + The maximum number of characters in the assembled context block. - query : typing.Optional[str] - - recency_bias : typing.Optional[str] + recency_bias : typing.Optional[V4GraphContextRequestRecencyBias] + Adjusts result selection to favor more recent graph data. template_uuid : typing.Optional[str] + The UUID of a context template used to render the context block. idempotency_key : typing.Optional[str] @@ -3060,7 +3517,9 @@ async def get_context( f"graphs/{jsonable_encoder(graph_uuid)}/context", method="POST", json={ - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "include_results": include_results, "max_characters": max_characters, "query": query, @@ -3106,6 +3565,17 @@ async def get_context( ), ), ) + 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), @@ -3117,6 +3587,17 @@ async def get_context( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -3213,7 +3694,7 @@ async def set_instructions( graph_uuid: str, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Instructions]: @@ -3224,8 +3705,12 @@ async def set_instructions( Graph UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[CustomInstruction]] + The custom extraction instructions in effect at this scope, each with a + name and text. idempotency_key : typing.Optional[str] @@ -3242,7 +3727,9 @@ async def set_instructions( method="PUT", json={ "inherited": inherited, - "instructions": instructions, + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[CustomInstruction], direction="write" + ), }, headers={ "content-type": "application/json", @@ -3391,7 +3878,7 @@ async def set_observation_steering( *, inherited: typing.Optional[bool] = OMIT, instruction: typing.Optional[str] = OMIT, - types: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[ObservationSteering]: @@ -3402,10 +3889,16 @@ async def set_observation_steering( Graph UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. instruction : typing.Optional[str] + The natural-language instruction steering how observations are generated + at this scope. - types : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + types : typing.Optional[typing.Sequence[ObservationType]] + The named observation types, each with a description, that generation + should steer toward at this scope. idempotency_key : typing.Optional[str] @@ -3423,7 +3916,9 @@ async def set_observation_steering( json={ "inherited": inherited, "instruction": instruction, - "types": types, + "types": convert_and_respect_annotation_metadata( + object_=types, annotation=typing.Sequence[ObservationType], direction="write" + ), }, headers={ "content-type": "application/json", @@ -3583,10 +4078,14 @@ async def set_ontology( Graph UUID edge_types : typing.Optional[typing.Sequence[EdgeType]] + The edge types defined in the ontology in effect at this scope. entity_types : typing.Optional[typing.Sequence[EntityType]] + The entity types defined in the ontology in effect at this scope. inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. idempotency_key : typing.Optional[str] @@ -3677,14 +4176,14 @@ async def search_edges( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Edge, EdgePage]: @@ -3694,6 +4193,9 @@ async def search_edges( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -3701,16 +4203,21 @@ async def search_edges( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -3732,7 +4239,9 @@ async def search_edges( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -3760,13 +4269,13 @@ async def search_edges( async def _get_next(): return await self.search_edges( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -3795,6 +4304,17 @@ async def _get_next(): ), ), ) + 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), @@ -3823,14 +4343,14 @@ async def search_episodes( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Episode, EpisodePage]: @@ -3840,6 +4360,9 @@ async def search_episodes( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -3847,16 +4370,21 @@ async def search_episodes( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -3878,7 +4406,9 @@ async def search_episodes( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -3906,13 +4436,13 @@ async def search_episodes( async def _get_next(): return await self.search_episodes( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -3941,6 +4471,17 @@ async def _get_next(): ), ), ) + 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), @@ -3969,14 +4510,14 @@ async def search_nodes( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Node, NodePage]: @@ -3986,6 +4527,9 @@ async def search_nodes( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -3993,16 +4537,21 @@ async def search_nodes( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -4024,7 +4573,9 @@ async def search_nodes( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -4052,13 +4603,13 @@ async def search_nodes( async def _get_next(): return await self.search_nodes( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -4087,6 +4638,17 @@ async def _get_next(): ), ), ) + 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), @@ -4115,14 +4677,14 @@ async def search_observations( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Observation, ObservationPage]: @@ -4132,6 +4694,9 @@ async def search_observations( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -4139,16 +4704,21 @@ async def search_observations( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -4170,7 +4740,9 @@ async def search_observations( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -4198,13 +4770,13 @@ async def search_observations( async def _get_next(): return await self.search_observations( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -4233,6 +4805,17 @@ async def _get_next(): ), ), ) + 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), @@ -4261,14 +4844,14 @@ async def search_thread_summaries( self, graph_uuid: str, *, + query: str, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, bfs_origin_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, center_node_uuid: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - query: typing.Optional[str] = OMIT, - reranker: typing.Optional[str] = OMIT, + reranker: typing.Optional[V4SearchRequestReranker] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ThreadSummary, ThreadSummaryPage]: @@ -4278,6 +4861,9 @@ async def search_thread_summaries( graph_uuid : str Graph UUID + query : str + The search query. + limit : typing.Optional[int] Page size @@ -4285,16 +4871,21 @@ async def search_thread_summaries( Opaque page cursor bfs_origin_node_uuids : typing.Optional[typing.Sequence[str]] + Nodes used as BFS origins for graph-distance-aware retrieval. center_node_uuid : typing.Optional[str] + The node to rank results by distance from. Required when reranker is + node_distance. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining which items are returned. mmr_lambda : typing.Optional[float] + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. - query : typing.Optional[str] - - reranker : typing.Optional[str] + reranker : typing.Optional[V4SearchRequestReranker] + The reranking strategy applied to retrieved results. Defaults to rrf. idempotency_key : typing.Optional[str] @@ -4316,7 +4907,9 @@ async def search_thread_summaries( json={ "bfs_origin_node_uuids": bfs_origin_node_uuids, "center_node_uuid": center_node_uuid, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "mmr_lambda": mmr_lambda, "query": query, "reranker": reranker, @@ -4344,13 +4937,13 @@ async def search_thread_summaries( async def _get_next(): return await self.search_thread_summaries( graph_uuid, + query=query, limit=limit, cursor=_parsed_next, bfs_origin_node_uuids=bfs_origin_node_uuids, center_node_uuid=center_node_uuid, filters=filters, mmr_lambda=mmr_lambda, - query=query, reranker=reranker, idempotency_key=idempotency_key, request_options=request_options, @@ -4379,6 +4972,17 @@ async def _get_next(): ), ), ) + 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), @@ -4407,12 +5011,12 @@ async def get_subgraph( self, graph_uuid: str, *, + seed_node_uuids: typing.Sequence[str], depth: typing.Optional[int] = OMIT, - direction: typing.Optional[str] = OMIT, - filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + direction: typing.Optional[V4SubgraphRequestDirection] = OMIT, + filters: typing.Optional[SearchFilters] = OMIT, max_edges: typing.Optional[int] = OMIT, max_nodes: typing.Optional[int] = OMIT, - seed_node_uuids: typing.Optional[typing.Sequence[str]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[SubgraphResponse]: @@ -4422,17 +5026,24 @@ async def get_subgraph( graph_uuid : str Graph UUID + seed_node_uuids : typing.Sequence[str] + The node UUIDs to expand from, in traversal-priority order. + depth : typing.Optional[int] + The maximum traversal depth from the seed nodes. Defaults to 1. - direction : typing.Optional[str] + direction : typing.Optional[V4SubgraphRequestDirection] + The edge orientation to follow during expansion: in, out, or both. + Defaults to both. - filters : typing.Optional[typing.Dict[str, typing.Any]] + filters : typing.Optional[SearchFilters] + Filters constraining the traversed edges and included nodes. max_edges : typing.Optional[int] + The maximum number of edges in the response. Defaults to 200. max_nodes : typing.Optional[int] - - seed_node_uuids : typing.Optional[typing.Sequence[str]] + The maximum number of nodes in the response. Defaults to 100. idempotency_key : typing.Optional[str] @@ -4450,7 +5061,9 @@ async def get_subgraph( json={ "depth": depth, "direction": direction, - "filters": filters, + "filters": convert_and_respect_annotation_metadata( + object_=filters, annotation=SearchFilters, direction="write" + ), "max_edges": max_edges, "max_nodes": max_nodes, "seed_node_uuids": seed_node_uuids, @@ -4494,6 +5107,17 @@ async def get_subgraph( ), ), ) + 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), @@ -4581,6 +5205,17 @@ async def warm( ), ), ) + 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), @@ -4592,6 +5227,17 @@ async def warm( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/graph/thread_summary/client.py b/src/zep_cloud/graph/thread_summary/client.py index 779cf028..3cca6737 100644 --- a/src/zep_cloud/graph/thread_summary/client.py +++ b/src/zep_cloud/graph/thread_summary/client.py @@ -51,6 +51,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -128,6 +129,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/graph/thread_summary/raw_client.py b/src/zep_cloud/graph/thread_summary/raw_client.py index 274635b9..ef650ac3 100644 --- a/src/zep_cloud/graph/thread_summary/raw_client.py +++ b/src/zep_cloud/graph/thread_summary/raw_client.py @@ -11,6 +11,8 @@ from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError from ...errors.not_found_error import NotFoundError from ...errors.unauthorized_error import UnauthorizedError from ...types.api_error import ApiError as types_api_error_ApiError @@ -49,6 +51,7 @@ def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -120,6 +123,17 @@ def list( ), ), ) + 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), @@ -131,6 +145,17 @@ def list( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -172,6 +197,7 @@ async def list( Opaque page cursor filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. idempotency_key : typing.Optional[str] @@ -246,6 +272,17 @@ async def _get_next(): ), ), ) + 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), @@ -257,6 +294,17 @@ async def _get_next(): ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/graph/types/__init__.py b/src/zep_cloud/graph/types/__init__.py new file mode 100644 index 00000000..9b446df3 --- /dev/null +++ b/src/zep_cloud/graph/types/__init__.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .v4graph_context_request_recency_bias import V4GraphContextRequestRecencyBias + from .v4subgraph_request_direction import V4SubgraphRequestDirection +_dynamic_imports: typing.Dict[str, str] = { + "V4GraphContextRequestRecencyBias": ".v4graph_context_request_recency_bias", + "V4SubgraphRequestDirection": ".v4subgraph_request_direction", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["V4GraphContextRequestRecencyBias", "V4SubgraphRequestDirection"] diff --git a/src/zep_cloud/graph/types/v4graph_context_request_recency_bias.py b/src/zep_cloud/graph/types/v4graph_context_request_recency_bias.py new file mode 100644 index 00000000..ac1a67b5 --- /dev/null +++ b/src/zep_cloud/graph/types/v4graph_context_request_recency_bias.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V4GraphContextRequestRecencyBias = typing.Union[typing.Literal["off", "mild", "strong"], typing.Any] diff --git a/src/zep_cloud/graph/types/v4subgraph_request_direction.py b/src/zep_cloud/graph/types/v4subgraph_request_direction.py new file mode 100644 index 00000000..ac84fb19 --- /dev/null +++ b/src/zep_cloud/graph/types/v4subgraph_request_direction.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V4SubgraphRequestDirection = typing.Union[typing.Literal["in", "out", "both"], typing.Any] diff --git a/src/zep_cloud/lookup/client.py b/src/zep_cloud/lookup/client.py index 03e3fc6f..b9a11ce7 100644 --- a/src/zep_cloud/lookup/client.py +++ b/src/zep_cloud/lookup/client.py @@ -39,10 +39,13 @@ def batch( Parameters ---------- graphs : typing.Optional[typing.Sequence[str]] + Developer-assigned graph IDs to resolve to UUIDs. threads : typing.Optional[typing.Sequence[str]] + Developer-assigned thread IDs to resolve to UUIDs. users : typing.Optional[typing.Sequence[str]] + Developer-assigned user IDs to resolve to UUIDs. idempotency_key : typing.Optional[str] @@ -101,10 +104,13 @@ async def batch( Parameters ---------- graphs : typing.Optional[typing.Sequence[str]] + Developer-assigned graph IDs to resolve to UUIDs. threads : typing.Optional[typing.Sequence[str]] + Developer-assigned thread IDs to resolve to UUIDs. users : typing.Optional[typing.Sequence[str]] + Developer-assigned user IDs to resolve to UUIDs. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/lookup/raw_client.py b/src/zep_cloud/lookup/raw_client.py index 621630a7..05de7f5c 100644 --- a/src/zep_cloud/lookup/raw_client.py +++ b/src/zep_cloud/lookup/raw_client.py @@ -37,10 +37,13 @@ def batch( Parameters ---------- graphs : typing.Optional[typing.Sequence[str]] + Developer-assigned graph IDs to resolve to UUIDs. threads : typing.Optional[typing.Sequence[str]] + Developer-assigned thread IDs to resolve to UUIDs. users : typing.Optional[typing.Sequence[str]] + Developer-assigned user IDs to resolve to UUIDs. idempotency_key : typing.Optional[str] @@ -141,10 +144,13 @@ async def batch( Parameters ---------- graphs : typing.Optional[typing.Sequence[str]] + Developer-assigned graph IDs to resolve to UUIDs. threads : typing.Optional[typing.Sequence[str]] + Developer-assigned thread IDs to resolve to UUIDs. users : typing.Optional[typing.Sequence[str]] + Developer-assigned user IDs to resolve to UUIDs. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/project/client.py b/src/zep_cloud/project/client.py index 10f6ab6c..bb2e0771 100644 --- a/src/zep_cloud/project/client.py +++ b/src/zep_cloud/project/client.py @@ -4,12 +4,15 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.request_options import RequestOptions +from ..types.custom_instruction import CustomInstruction from ..types.edge_type import EdgeType from ..types.entity_type import EntityType from ..types.instructions import Instructions from ..types.observation_steering import ObservationSteering +from ..types.observation_type import ObservationType from ..types.ontology import Ontology from ..types.project import Project +from ..types.user_instruction import UserInstruction from ..types.user_summary_instructions import UserSummaryInstructions from .raw_client import AsyncRawProjectClient, RawProjectClient @@ -67,7 +70,8 @@ def update( Parameters ---------- default_time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The project's IANA fallback time zone. Set to null to clear the existing + value. idempotency_key : typing.Optional[str] @@ -121,7 +125,7 @@ def set_instructions( self, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Instructions: @@ -129,8 +133,12 @@ def set_instructions( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[CustomInstruction]] + The custom extraction instructions in effect at this scope, each with a + name and text. idempotency_key : typing.Optional[str] @@ -190,7 +198,7 @@ def set_observation_steering( *, inherited: typing.Optional[bool] = OMIT, instruction: typing.Optional[str] = OMIT, - types: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ObservationSteering: @@ -198,10 +206,16 @@ def set_observation_steering( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. instruction : typing.Optional[str] + The natural-language instruction steering how observations are generated + at this scope. - types : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + types : typing.Optional[typing.Sequence[ObservationType]] + The named observation types, each with a description, that generation + should steer toward at this scope. idempotency_key : typing.Optional[str] @@ -268,10 +282,14 @@ def set_ontology( Parameters ---------- edge_types : typing.Optional[typing.Sequence[EdgeType]] + The edge types defined in the ontology in effect at this scope. entity_types : typing.Optional[typing.Sequence[EntityType]] + The entity types defined in the ontology in effect at this scope. inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. idempotency_key : typing.Optional[str] @@ -331,7 +349,7 @@ def set_user_summary_instructions( self, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> UserSummaryInstructions: @@ -339,8 +357,12 @@ def set_user_summary_instructions( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[UserInstruction]] + The custom instructions used when generating a user's summary at this + scope, each with a name and text. idempotency_key : typing.Optional[str] @@ -428,7 +450,8 @@ async def update( Parameters ---------- default_time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The project's IANA fallback time zone. Set to null to clear the existing + value. idempotency_key : typing.Optional[str] @@ -498,7 +521,7 @@ async def set_instructions( self, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Instructions: @@ -506,8 +529,12 @@ async def set_instructions( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[CustomInstruction]] + The custom extraction instructions in effect at this scope, each with a + name and text. idempotency_key : typing.Optional[str] @@ -583,7 +610,7 @@ async def set_observation_steering( *, inherited: typing.Optional[bool] = OMIT, instruction: typing.Optional[str] = OMIT, - types: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ObservationSteering: @@ -591,10 +618,16 @@ async def set_observation_steering( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. instruction : typing.Optional[str] + The natural-language instruction steering how observations are generated + at this scope. - types : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + types : typing.Optional[typing.Sequence[ObservationType]] + The named observation types, each with a description, that generation + should steer toward at this scope. idempotency_key : typing.Optional[str] @@ -677,10 +710,14 @@ async def set_ontology( Parameters ---------- edge_types : typing.Optional[typing.Sequence[EdgeType]] + The edge types defined in the ontology in effect at this scope. entity_types : typing.Optional[typing.Sequence[EntityType]] + The entity types defined in the ontology in effect at this scope. inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. idempotency_key : typing.Optional[str] @@ -756,7 +793,7 @@ async def set_user_summary_instructions( self, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> UserSummaryInstructions: @@ -764,8 +801,12 @@ async def set_user_summary_instructions( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[UserInstruction]] + The custom instructions used when generating a user's summary at this + scope, each with a name and text. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/project/raw_client.py b/src/zep_cloud/project/raw_client.py index efd78893..c0eef778 100644 --- a/src/zep_cloud/project/raw_client.py +++ b/src/zep_cloud/project/raw_client.py @@ -11,15 +11,19 @@ from ..core.request_options import RequestOptions from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..types.api_error import ApiError as types_api_error_ApiError +from ..types.custom_instruction import CustomInstruction from ..types.edge_type import EdgeType from ..types.entity_type import EntityType from ..types.instructions import Instructions from ..types.observation_steering import ObservationSteering +from ..types.observation_type import ObservationType from ..types.ontology import Ontology from ..types.project import Project +from ..types.user_instruction import UserInstruction from ..types.user_summary_instructions import UserSummaryInstructions from pydantic import ValidationError @@ -115,7 +119,8 @@ def update( Parameters ---------- default_time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The project's IANA fallback time zone. Set to null to clear the existing + value. idempotency_key : typing.Optional[str] @@ -183,6 +188,17 @@ def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -275,7 +291,7 @@ def set_instructions( self, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Instructions]: @@ -283,8 +299,12 @@ def set_instructions( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[CustomInstruction]] + The custom extraction instructions in effect at this scope, each with a + name and text. idempotency_key : typing.Optional[str] @@ -301,7 +321,9 @@ def set_instructions( method="PUT", json={ "inherited": inherited, - "instructions": instructions, + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[CustomInstruction], direction="write" + ), }, headers={ "content-type": "application/json", @@ -446,7 +468,7 @@ def set_observation_steering( *, inherited: typing.Optional[bool] = OMIT, instruction: typing.Optional[str] = OMIT, - types: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[ObservationSteering]: @@ -454,10 +476,16 @@ def set_observation_steering( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. instruction : typing.Optional[str] + The natural-language instruction steering how observations are generated + at this scope. - types : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + types : typing.Optional[typing.Sequence[ObservationType]] + The named observation types, each with a description, that generation + should steer toward at this scope. idempotency_key : typing.Optional[str] @@ -475,7 +503,9 @@ def set_observation_steering( json={ "inherited": inherited, "instruction": instruction, - "types": types, + "types": convert_and_respect_annotation_metadata( + object_=types, annotation=typing.Sequence[ObservationType], direction="write" + ), }, headers={ "content-type": "application/json", @@ -626,10 +656,14 @@ def set_ontology( Parameters ---------- edge_types : typing.Optional[typing.Sequence[EdgeType]] + The edge types defined in the ontology in effect at this scope. entity_types : typing.Optional[typing.Sequence[EntityType]] + The entity types defined in the ontology in effect at this scope. inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. idempotency_key : typing.Optional[str] @@ -795,7 +829,7 @@ def set_user_summary_instructions( self, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[UserSummaryInstructions]: @@ -803,8 +837,12 @@ def set_user_summary_instructions( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[UserInstruction]] + The custom instructions used when generating a user's summary at this + scope, each with a name and text. idempotency_key : typing.Optional[str] @@ -821,7 +859,9 @@ def set_user_summary_instructions( method="PUT", json={ "inherited": inherited, - "instructions": instructions, + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[UserInstruction], direction="write" + ), }, headers={ "content-type": "application/json", @@ -975,7 +1015,8 @@ async def update( Parameters ---------- default_time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The project's IANA fallback time zone. Set to null to clear the existing + value. idempotency_key : typing.Optional[str] @@ -1043,6 +1084,17 @@ async def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1135,7 +1187,7 @@ async def set_instructions( self, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Instructions]: @@ -1143,8 +1195,12 @@ async def set_instructions( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[CustomInstruction]] + The custom extraction instructions in effect at this scope, each with a + name and text. idempotency_key : typing.Optional[str] @@ -1161,7 +1217,9 @@ async def set_instructions( method="PUT", json={ "inherited": inherited, - "instructions": instructions, + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[CustomInstruction], direction="write" + ), }, headers={ "content-type": "application/json", @@ -1306,7 +1364,7 @@ async def set_observation_steering( *, inherited: typing.Optional[bool] = OMIT, instruction: typing.Optional[str] = OMIT, - types: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[ObservationSteering]: @@ -1314,10 +1372,16 @@ async def set_observation_steering( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. instruction : typing.Optional[str] + The natural-language instruction steering how observations are generated + at this scope. - types : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + types : typing.Optional[typing.Sequence[ObservationType]] + The named observation types, each with a description, that generation + should steer toward at this scope. idempotency_key : typing.Optional[str] @@ -1335,7 +1399,9 @@ async def set_observation_steering( json={ "inherited": inherited, "instruction": instruction, - "types": types, + "types": convert_and_respect_annotation_metadata( + object_=types, annotation=typing.Sequence[ObservationType], direction="write" + ), }, headers={ "content-type": "application/json", @@ -1488,10 +1554,14 @@ async def set_ontology( Parameters ---------- edge_types : typing.Optional[typing.Sequence[EdgeType]] + The edge types defined in the ontology in effect at this scope. entity_types : typing.Optional[typing.Sequence[EntityType]] + The entity types defined in the ontology in effect at this scope. inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. idempotency_key : typing.Optional[str] @@ -1657,7 +1727,7 @@ async def set_user_summary_instructions( self, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[UserSummaryInstructions]: @@ -1665,8 +1735,12 @@ async def set_user_summary_instructions( Parameters ---------- inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[UserInstruction]] + The custom instructions used when generating a user's summary at this + scope, each with a name and text. idempotency_key : typing.Optional[str] @@ -1683,7 +1757,9 @@ async def set_user_summary_instructions( method="PUT", json={ "inherited": inherited, - "instructions": instructions, + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[UserInstruction], direction="write" + ), }, headers={ "content-type": "application/json", diff --git a/src/zep_cloud/thread/client.py b/src/zep_cloud/thread/client.py index 17923130..f3107992 100644 --- a/src/zep_cloud/thread/client.py +++ b/src/zep_cloud/thread/client.py @@ -111,17 +111,19 @@ def list( def create( self, *, + user_uuid: str, thread_id: typing.Optional[str] = OMIT, - user_uuid: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Thread: """ Parameters ---------- - thread_id : typing.Optional[str] + user_uuid : str + The UUID of the user this thread belongs to. - user_uuid : typing.Optional[str] + thread_id : typing.Optional[str] + An optional developer-assigned identifier for the thread. idempotency_key : typing.Optional[str] @@ -140,10 +142,12 @@ def create( client = Zep( api_key="YOUR_API_KEY", ) - client.thread.create() + client.thread.create( + user_uuid="user_uuid", + ) """ _response = self._raw_client.create( - thread_id=thread_id, user_uuid=user_uuid, idempotency_key=idempotency_key, request_options=request_options + user_uuid=user_uuid, thread_id=thread_id, idempotency_key=idempotency_key, request_options=request_options ) return _response.data @@ -160,10 +164,16 @@ def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -402,8 +412,8 @@ def add_messages( self, thread_uuid: str, *, + messages: typing.Sequence[AddMessage], ignore_roles: typing.Optional[typing.Sequence[str]] = OMIT, - messages: typing.Optional[typing.Sequence[AddMessage]] = OMIT, return_context: typing.Optional[bool] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -415,13 +425,20 @@ def add_messages( thread_uuid : str Thread UUID - ignore_roles : typing.Optional[typing.Sequence[str]] + messages : typing.Sequence[AddMessage] + The messages to add to the thread. - messages : typing.Optional[typing.Sequence[AddMessage]] + ignore_roles : typing.Optional[typing.Sequence[str]] + Message roles to skip during graph extraction; the messages are still + stored. return_context : typing.Optional[bool] + When true, returns the context block for the thread's most recent + messages. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology. idempotency_key : typing.Optional[str] @@ -435,19 +452,20 @@ def add_messages( Examples -------- - from zep_cloud import Zep + from zep_cloud import AddMessage, Zep client = Zep( api_key="YOUR_API_KEY", ) client.thread.add_messages( thread_uuid="thread_uuid", + messages=[AddMessage()], ) """ _response = self._raw_client.add_messages( thread_uuid, - ignore_roles=ignore_roles, messages=messages, + ignore_roles=ignore_roles, return_context=return_context, strict_ontology=strict_ontology, idempotency_key=idempotency_key, @@ -589,17 +607,19 @@ async def main() -> None: async def create( self, *, + user_uuid: str, thread_id: typing.Optional[str] = OMIT, - user_uuid: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Thread: """ Parameters ---------- - thread_id : typing.Optional[str] + user_uuid : str + The UUID of the user this thread belongs to. - user_uuid : typing.Optional[str] + thread_id : typing.Optional[str] + An optional developer-assigned identifier for the thread. idempotency_key : typing.Optional[str] @@ -623,13 +643,15 @@ async def create( async def main() -> None: - await client.thread.create() + await client.thread.create( + user_uuid="user_uuid", + ) asyncio.run(main()) """ _response = await self._raw_client.create( - thread_id=thread_id, user_uuid=user_uuid, idempotency_key=idempotency_key, request_options=request_options + user_uuid=user_uuid, thread_id=thread_id, idempotency_key=idempotency_key, request_options=request_options ) return _response.data @@ -646,10 +668,16 @@ async def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -942,8 +970,8 @@ async def add_messages( self, thread_uuid: str, *, + messages: typing.Sequence[AddMessage], ignore_roles: typing.Optional[typing.Sequence[str]] = OMIT, - messages: typing.Optional[typing.Sequence[AddMessage]] = OMIT, return_context: typing.Optional[bool] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -955,13 +983,20 @@ async def add_messages( thread_uuid : str Thread UUID - ignore_roles : typing.Optional[typing.Sequence[str]] + messages : typing.Sequence[AddMessage] + The messages to add to the thread. - messages : typing.Optional[typing.Sequence[AddMessage]] + ignore_roles : typing.Optional[typing.Sequence[str]] + Message roles to skip during graph extraction; the messages are still + stored. return_context : typing.Optional[bool] + When true, returns the context block for the thread's most recent + messages. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology. idempotency_key : typing.Optional[str] @@ -977,7 +1012,7 @@ async def add_messages( -------- import asyncio - from zep_cloud import AsyncZep + from zep_cloud import AddMessage, AsyncZep client = AsyncZep( api_key="YOUR_API_KEY", @@ -987,6 +1022,7 @@ async def add_messages( async def main() -> None: await client.thread.add_messages( thread_uuid="thread_uuid", + messages=[AddMessage()], ) @@ -994,8 +1030,8 @@ async def main() -> None: """ _response = await self._raw_client.add_messages( thread_uuid, - ignore_roles=ignore_roles, messages=messages, + ignore_roles=ignore_roles, return_context=return_context, strict_ontology=strict_ontology, idempotency_key=idempotency_key, diff --git a/src/zep_cloud/thread/message/client.py b/src/zep_cloud/thread/message/client.py index 6006e6c0..bc1b36da 100644 --- a/src/zep_cloud/thread/message/client.py +++ b/src/zep_cloud/thread/message/client.py @@ -80,6 +80,7 @@ def update( Message UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the message; a key set to null is removed. idempotency_key : typing.Optional[str] @@ -190,6 +191,7 @@ async def update( Message UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the message; a key set to null is removed. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/thread/message/raw_client.py b/src/zep_cloud/thread/message/raw_client.py index 97053fb5..516a28b2 100644 --- a/src/zep_cloud/thread/message/raw_client.py +++ b/src/zep_cloud/thread/message/raw_client.py @@ -11,6 +11,7 @@ from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError from ...errors.not_found_error import NotFoundError from ...errors.unauthorized_error import UnauthorizedError from ...types.api_error import ApiError as types_api_error_ApiError @@ -125,6 +126,7 @@ def update( Message UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the message; a key set to null is removed. idempotency_key : typing.Optional[str] @@ -192,6 +194,17 @@ def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -310,6 +323,7 @@ async def update( Message UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the message; a key set to null is removed. idempotency_key : typing.Optional[str] @@ -377,6 +391,17 @@ async def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( diff --git a/src/zep_cloud/thread/raw_client.py b/src/zep_cloud/thread/raw_client.py index d75c377b..0c93ef76 100644 --- a/src/zep_cloud/thread/raw_client.py +++ b/src/zep_cloud/thread/raw_client.py @@ -13,6 +13,8 @@ from ..core.request_options import RequestOptions from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..types.add_message import AddMessage @@ -155,17 +157,19 @@ def list( def create( self, *, + user_uuid: str, thread_id: typing.Optional[str] = OMIT, - user_uuid: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Thread]: """ Parameters ---------- - thread_id : typing.Optional[str] + user_uuid : str + The UUID of the user this thread belongs to. - user_uuid : typing.Optional[str] + thread_id : typing.Optional[str] + An optional developer-assigned identifier for the thread. idempotency_key : typing.Optional[str] @@ -234,6 +238,17 @@ def create( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -260,10 +275,16 @@ def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -496,6 +517,17 @@ def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -584,6 +616,17 @@ def get_context( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -675,6 +718,17 @@ def list_episodes( ), ), ) + 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), @@ -686,6 +740,17 @@ def list_episodes( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -805,8 +870,8 @@ def add_messages( self, thread_uuid: str, *, + messages: typing.Sequence[AddMessage], ignore_roles: typing.Optional[typing.Sequence[str]] = OMIT, - messages: typing.Optional[typing.Sequence[AddMessage]] = OMIT, return_context: typing.Optional[bool] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -818,13 +883,20 @@ def add_messages( thread_uuid : str Thread UUID - ignore_roles : typing.Optional[typing.Sequence[str]] + messages : typing.Sequence[AddMessage] + The messages to add to the thread. - messages : typing.Optional[typing.Sequence[AddMessage]] + ignore_roles : typing.Optional[typing.Sequence[str]] + Message roles to skip during graph extraction; the messages are still + stored. return_context : typing.Optional[bool] + When true, returns the context block for the thread's most recent + messages. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology. idempotency_key : typing.Optional[str] @@ -897,6 +969,17 @@ def add_messages( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -964,6 +1047,17 @@ def get_summary( ), ), ) + 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), @@ -1114,17 +1208,19 @@ async def _get_next(): async def create( self, *, + user_uuid: str, thread_id: typing.Optional[str] = OMIT, - user_uuid: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Thread]: """ Parameters ---------- - thread_id : typing.Optional[str] + user_uuid : str + The UUID of the user this thread belongs to. - user_uuid : typing.Optional[str] + thread_id : typing.Optional[str] + An optional developer-assigned identifier for the thread. idempotency_key : typing.Optional[str] @@ -1193,6 +1289,17 @@ async def create( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1219,10 +1326,16 @@ async def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -1457,6 +1570,17 @@ async def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1545,6 +1669,17 @@ async def get_context( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1639,6 +1774,17 @@ async def _get_next(): ), ), ) + 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), @@ -1650,6 +1796,17 @@ async def _get_next(): ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1772,8 +1929,8 @@ async def add_messages( self, thread_uuid: str, *, + messages: typing.Sequence[AddMessage], ignore_roles: typing.Optional[typing.Sequence[str]] = OMIT, - messages: typing.Optional[typing.Sequence[AddMessage]] = OMIT, return_context: typing.Optional[bool] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -1785,13 +1942,20 @@ async def add_messages( thread_uuid : str Thread UUID - ignore_roles : typing.Optional[typing.Sequence[str]] + messages : typing.Sequence[AddMessage] + The messages to add to the thread. - messages : typing.Optional[typing.Sequence[AddMessage]] + ignore_roles : typing.Optional[typing.Sequence[str]] + Message roles to skip during graph extraction; the messages are still + stored. return_context : typing.Optional[bool] + When true, returns the context block for the thread's most recent + messages. strict_ontology : typing.Optional[bool] + When true, prevents extraction of generic entity nodes that do not match + the configured ontology. idempotency_key : typing.Optional[str] @@ -1864,6 +2028,17 @@ async def add_messages( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1931,6 +2106,17 @@ async def get_summary( ), ), ) + 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), diff --git a/src/zep_cloud/types/__init__.py b/src/zep_cloud/types/__init__.py index be434f6e..690e4c16 100644 --- a/src/zep_cloud/types/__init__.py +++ b/src/zep_cloud/types/__init__.py @@ -18,12 +18,14 @@ from .async_result import AsyncResult from .batch import Batch from .batch_item import BatchItem + from .batch_item_input import BatchItemInput from .batch_item_kind import BatchItemKind from .batch_item_page import BatchItemPage from .batch_item_status import BatchItemStatus from .batch_items_response import BatchItemsResponse from .batch_page import BatchPage from .clone_graph_result import CloneGraphResult + from .comparison_operator import ComparisonOperator from .context_edge import ContextEdge from .context_episode import ContextEpisode from .context_node import ContextNode @@ -33,9 +35,12 @@ from .context_template_page import ContextTemplatePage from .context_thread_summary import ContextThreadSummary from .create_context_template_request import CreateContextTemplateRequest + from .custom_instruction import CustomInstruction + from .date_filter import DateFilter from .document_summary import DocumentSummary from .document_summary_page import DocumentSummaryPage from .edge import Edge + from .edge_node_ref import EdgeNodeRef from .edge_page import EdgePage from .edge_source_target import EdgeSourceTarget from .edge_type import EdgeType @@ -43,6 +48,7 @@ from .entity_property_type import EntityPropertyType from .entity_type import EntityType from .episode import Episode + from .episode_metadata_filter import EpisodeMetadataFilter from .episode_page import EpisodePage from .error_body import ErrorBody from .graph import Graph @@ -50,23 +56,32 @@ from .graph_data_type import GraphDataType from .graph_delete_result import GraphDeleteResult from .graph_page import GraphPage + from .graphiti_metadata_filter_group_type import GraphitiMetadataFilterGroupType from .instructions import Instructions from .lookup_batch_response import LookupBatchResponse from .lookup_item import LookupItem from .lookup_request import LookupRequest + from .membership_mutation_result import MembershipMutationResult from .message import Message from .message_page import MessagePage + from .metadata_filter_group import MetadataFilterGroup + from .mutate_members_request import MutateMembersRequest from .neighbor_entry import NeighborEntry from .neighbor_page import NeighborPage from .node import Node + from .node_input import NodeInput from .node_page import NodePage from .observation import Observation from .observation_page import ObservationPage from .observation_steering import ObservationSteering + from .observation_type import ObservationType from .ontology import Ontology from .process_batch_result import ProcessBatchResult from .project import Project + from .property_filter import PropertyFilter from .role_type import RoleType + from .search_filters import SearchFilters + from .search_list_request import SearchListRequest from .search_request import SearchRequest from .subgraph_response import SubgraphResponse from .task import Task @@ -80,8 +95,15 @@ from .thread_summary_page import ThreadSummaryPage from .user import User from .user_delete_result import UserDeleteResult + from .user_group import UserGroup + from .user_group_page import UserGroupPage + from .user_instruction import UserInstruction from .user_page import UserPage from .user_summary_instructions import UserSummaryInstructions + from .v4batch_item_input_data_type import V4BatchItemInputDataType + from .v4batch_item_input_role import V4BatchItemInputRole + from .v4batch_item_input_type import V4BatchItemInputType + from .v4search_request_reranker import V4SearchRequestReranker _dynamic_imports: typing.Dict[str, str] = { "AddEdgeResult": ".add_edge_result", "AddEpisodeResult": ".add_episode_result", @@ -95,12 +117,14 @@ "AsyncResult": ".async_result", "Batch": ".batch", "BatchItem": ".batch_item", + "BatchItemInput": ".batch_item_input", "BatchItemKind": ".batch_item_kind", "BatchItemPage": ".batch_item_page", "BatchItemStatus": ".batch_item_status", "BatchItemsResponse": ".batch_items_response", "BatchPage": ".batch_page", "CloneGraphResult": ".clone_graph_result", + "ComparisonOperator": ".comparison_operator", "ContextEdge": ".context_edge", "ContextEpisode": ".context_episode", "ContextNode": ".context_node", @@ -110,9 +134,12 @@ "ContextTemplatePage": ".context_template_page", "ContextThreadSummary": ".context_thread_summary", "CreateContextTemplateRequest": ".create_context_template_request", + "CustomInstruction": ".custom_instruction", + "DateFilter": ".date_filter", "DocumentSummary": ".document_summary", "DocumentSummaryPage": ".document_summary_page", "Edge": ".edge", + "EdgeNodeRef": ".edge_node_ref", "EdgePage": ".edge_page", "EdgeSourceTarget": ".edge_source_target", "EdgeType": ".edge_type", @@ -120,6 +147,7 @@ "EntityPropertyType": ".entity_property_type", "EntityType": ".entity_type", "Episode": ".episode", + "EpisodeMetadataFilter": ".episode_metadata_filter", "EpisodePage": ".episode_page", "ErrorBody": ".error_body", "Graph": ".graph", @@ -127,23 +155,32 @@ "GraphDataType": ".graph_data_type", "GraphDeleteResult": ".graph_delete_result", "GraphPage": ".graph_page", + "GraphitiMetadataFilterGroupType": ".graphiti_metadata_filter_group_type", "Instructions": ".instructions", "LookupBatchResponse": ".lookup_batch_response", "LookupItem": ".lookup_item", "LookupRequest": ".lookup_request", + "MembershipMutationResult": ".membership_mutation_result", "Message": ".message", "MessagePage": ".message_page", + "MetadataFilterGroup": ".metadata_filter_group", + "MutateMembersRequest": ".mutate_members_request", "NeighborEntry": ".neighbor_entry", "NeighborPage": ".neighbor_page", "Node": ".node", + "NodeInput": ".node_input", "NodePage": ".node_page", "Observation": ".observation", "ObservationPage": ".observation_page", "ObservationSteering": ".observation_steering", + "ObservationType": ".observation_type", "Ontology": ".ontology", "ProcessBatchResult": ".process_batch_result", "Project": ".project", + "PropertyFilter": ".property_filter", "RoleType": ".role_type", + "SearchFilters": ".search_filters", + "SearchListRequest": ".search_list_request", "SearchRequest": ".search_request", "SubgraphResponse": ".subgraph_response", "Task": ".task", @@ -157,8 +194,15 @@ "ThreadSummaryPage": ".thread_summary_page", "User": ".user", "UserDeleteResult": ".user_delete_result", + "UserGroup": ".user_group", + "UserGroupPage": ".user_group_page", + "UserInstruction": ".user_instruction", "UserPage": ".user_page", "UserSummaryInstructions": ".user_summary_instructions", + "V4BatchItemInputDataType": ".v4batch_item_input_data_type", + "V4BatchItemInputRole": ".v4batch_item_input_role", + "V4BatchItemInputType": ".v4batch_item_input_type", + "V4SearchRequestReranker": ".v4search_request_reranker", } @@ -196,12 +240,14 @@ def __dir__(): "AsyncResult", "Batch", "BatchItem", + "BatchItemInput", "BatchItemKind", "BatchItemPage", "BatchItemStatus", "BatchItemsResponse", "BatchPage", "CloneGraphResult", + "ComparisonOperator", "ContextEdge", "ContextEpisode", "ContextNode", @@ -211,9 +257,12 @@ def __dir__(): "ContextTemplatePage", "ContextThreadSummary", "CreateContextTemplateRequest", + "CustomInstruction", + "DateFilter", "DocumentSummary", "DocumentSummaryPage", "Edge", + "EdgeNodeRef", "EdgePage", "EdgeSourceTarget", "EdgeType", @@ -221,6 +270,7 @@ def __dir__(): "EntityPropertyType", "EntityType", "Episode", + "EpisodeMetadataFilter", "EpisodePage", "ErrorBody", "Graph", @@ -228,23 +278,32 @@ def __dir__(): "GraphDataType", "GraphDeleteResult", "GraphPage", + "GraphitiMetadataFilterGroupType", "Instructions", "LookupBatchResponse", "LookupItem", "LookupRequest", + "MembershipMutationResult", "Message", "MessagePage", + "MetadataFilterGroup", + "MutateMembersRequest", "NeighborEntry", "NeighborPage", "Node", + "NodeInput", "NodePage", "Observation", "ObservationPage", "ObservationSteering", + "ObservationType", "Ontology", "ProcessBatchResult", "Project", + "PropertyFilter", "RoleType", + "SearchFilters", + "SearchListRequest", "SearchRequest", "SubgraphResponse", "Task", @@ -258,6 +317,13 @@ def __dir__(): "ThreadSummaryPage", "User", "UserDeleteResult", + "UserGroup", + "UserGroupPage", + "UserInstruction", "UserPage", "UserSummaryInstructions", + "V4BatchItemInputDataType", + "V4BatchItemInputRole", + "V4BatchItemInputType", + "V4SearchRequestReranker", ] diff --git a/src/zep_cloud/types/add_edge_result.py b/src/zep_cloud/types/add_edge_result.py index 4736e270..eda0788f 100644 --- a/src/zep_cloud/types/add_edge_result.py +++ b/src/zep_cloud/types/add_edge_result.py @@ -11,10 +11,15 @@ class AddEdgeResult(UniversalBaseModel): edge: typing.Optional[AddedEdge] = pydantic.Field(default=None) """ - 8.6: edge is an accept-time acknowledgement, not a full Edge. + An accept-time acknowledgement of the fact you submitted, carrying the + identifier and fields you supplied rather than the full edge resource + returned by later reads. """ - task: typing.Optional[Task] = None + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks the edge's extraction and indexing. + """ 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/add_episode_result.py b/src/zep_cloud/types/add_episode_result.py index aee7dcc1..3f395974 100644 --- a/src/zep_cloud/types/add_episode_result.py +++ b/src/zep_cloud/types/add_episode_result.py @@ -11,11 +11,15 @@ class AddEpisodeResult(UniversalBaseModel): episode: typing.Optional[Episode] = pydantic.Field(default=None) """ - 8.6: only the episode response is a stored resource, so it is a full - Episode readable immediately with processed false. + The newly created episode, a full resource that is readable immediately. + Its processed field is false until graph extraction finishes. """ - task: typing.Optional[Task] = None + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks the episode's graph extraction and + indexing. + """ 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/add_message.py b/src/zep_cloud/types/add_message.py index c44d5029..497b7481 100644 --- a/src/zep_cloud/types/add_message.py +++ b/src/zep_cloud/types/add_message.py @@ -10,12 +10,34 @@ class AddMessage(UniversalBaseModel): - content: typing.Optional[str] = None - metadata: typing.Optional[typing.Dict[str, typing.Any]] = None - name: typing.Optional[str] = None - role: typing.Optional[RoleType] = None + content: typing.Optional[str] = pydantic.Field(default=None) + """ + The content of the message. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Custom metadata to store with the message. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + A customizable name for the sender of the message, for example "john" or + "sales_agent". + """ + + role: typing.Optional[RoleType] = pydantic.Field(default=None) + """ + The role of the message's sender. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field( + alias="uuid", + description="Reserved for future use. Message identifiers are always server-assigned,\nso this field must be left unset.", + ), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/add_messages_result.py b/src/zep_cloud/types/add_messages_result.py index c5a1d8d5..c731e54b 100644 --- a/src/zep_cloud/types/add_messages_result.py +++ b/src/zep_cloud/types/add_messages_result.py @@ -9,9 +9,22 @@ class AddMessagesResult(UniversalBaseModel): - context: typing.Optional[str] = None - messages: typing.Optional[typing.List[Message]] = None - task: typing.Optional[Task] = None + context: typing.Optional[str] = pydantic.Field(default=None) + """ + The context block assembled from the graph after adding the messages, + present only when return_context is true in the request. + """ + + messages: typing.Optional[typing.List[Message]] = pydantic.Field(default=None) + """ + The messages that were added, each including its assigned identifier. + """ + + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks the messages' graph extraction and + indexing. + """ 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/add_nodes_result.py b/src/zep_cloud/types/add_nodes_result.py index 5f59fff3..2bf3c9ef 100644 --- a/src/zep_cloud/types/add_nodes_result.py +++ b/src/zep_cloud/types/add_nodes_result.py @@ -11,11 +11,15 @@ class AddNodesResult(UniversalBaseModel): nodes: typing.Optional[typing.List[AddedNode]] = pydantic.Field(default=None) """ - 8.6: nodes is an accept-time acknowledgement carrying the assigned - identifier plus the fields the caller supplied, not a full Node. + An accept-time acknowledgement of the nodes you submitted, each carrying + its assigned identifier and the fields you supplied, not the full stored + node. """ - task: typing.Optional[Task] = None + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks the nodes' extraction and indexing. + """ 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/added_edge.py b/src/zep_cloud/types/added_edge.py index 40b7f23d..7e06ac37 100644 --- a/src/zep_cloud/types/added_edge.py +++ b/src/zep_cloud/types/added_edge.py @@ -6,21 +6,59 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata +from .edge_node_ref import EdgeNodeRef class AddedEdge(UniversalBaseModel): - attributes: typing.Optional[typing.Dict[str, typing.Any]] = None - expired_at: typing.Optional[str] = None - fact: typing.Optional[str] = None - fact_name: typing.Optional[str] = None - invalid_at: typing.Optional[str] = None - metadata: typing.Optional[typing.Dict[str, typing.Any]] = None - source_node: typing.Optional[typing.Dict[str, typing.Any]] = None - target_node: typing.Optional[typing.Dict[str, typing.Any]] = None + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the edge. + """ + + expired_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the fact was superseded or removed. + """ + + fact: typing.Optional[str] = pydantic.Field(default=None) + """ + The natural-language fact you submitted for this edge. + """ + + fact_name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the edge, in upper snake case, for example RELATES_TO. + """ + + invalid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the fact stopped being true. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Custom metadata associated with the edge. + """ + + source_node: typing.Optional[EdgeNodeRef] = pydantic.Field(default=None) + """ + The source node fields you supplied when creating this edge. + """ + + target_node: typing.Optional[EdgeNodeRef] = pydantic.Field(default=None) + """ + The target node fields you supplied when creating this edge. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier assigned to the edge."), ] = None - valid_at: typing.Optional[str] = None + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time from which the fact is considered true. + """ 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/artifact_list_request.py b/src/zep_cloud/types/artifact_list_request.py index 722ce371..c5fff2e4 100644 --- a/src/zep_cloud/types/artifact_list_request.py +++ b/src/zep_cloud/types/artifact_list_request.py @@ -7,7 +7,10 @@ class ArtifactListRequest(UniversalBaseModel): - filters: typing.Optional[typing.Dict[str, typing.Any]] = None + filters: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Filters constraining which items are returned. + """ 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/async_result.py b/src/zep_cloud/types/async_result.py index eaa8a12c..39f7a89e 100644 --- a/src/zep_cloud/types/async_result.py +++ b/src/zep_cloud/types/async_result.py @@ -8,7 +8,10 @@ class AsyncResult(UniversalBaseModel): - task: typing.Optional[Task] = None + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks this operation's progress. + """ 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/batch.py b/src/zep_cloud/types/batch.py index 7f5429fc..5185d2c6 100644 --- a/src/zep_cloud/types/batch.py +++ b/src/zep_cloud/types/batch.py @@ -9,13 +9,38 @@ class Batch(UniversalBaseModel): - created_at: typing.Optional[str] = None - metadata: typing.Optional[typing.Dict[str, typing.Any]] = None - progress: typing.Optional[typing.Dict[str, typing.Any]] = None - status: typing.Optional[str] = None - strict_ontology: typing.Optional[bool] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the batch was created. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Custom metadata associated with the batch, supplied when it was created. + """ + + progress: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + The batch's processing progress, including its current stage and item + counts. Present only once processing has started. + """ + + status: typing.Optional[str] = pydantic.Field(default=None) + """ + The processing status of the batch: draft, invalid, queued, processing, + succeeded, partial, failed, or canceled. + """ + + strict_ontology: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether ontology enforcement is applied when this batch is processed, + rejecting entities that do not match the configured ontology. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the batch."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/batch_item.py b/src/zep_cloud/types/batch_item.py index f0143600..0673fb5d 100644 --- a/src/zep_cloud/types/batch_item.py +++ b/src/zep_cloud/types/batch_item.py @@ -11,16 +11,52 @@ class BatchItem(UniversalBaseModel): - created_at: typing.Optional[str] = None - episode_uuid: typing.Optional[str] = None - graph_uuid: typing.Optional[str] = None - sequence_index: typing.Optional[int] = None - source_uuid: typing.Optional[str] = None - status: typing.Optional[BatchItemStatus] = None - thread_uuid: typing.Optional[str] = None - type: typing.Optional[BatchItemKind] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the item was appended to the batch. + """ + + episode_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The identifier of the episode created for this item, equal to source_uuid. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The graph the item's episode is or will be ingested into. + """ + + sequence_index: typing.Optional[int] = pydantic.Field(default=None) + """ + The item's position within the batch, in the order it was appended. + """ + + source_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the item's stored source row. + """ + + status: typing.Optional[BatchItemStatus] = pydantic.Field(default=None) + """ + The processing status of the item: pending, queued, processing, succeeded, + failed, skipped, or canceled. + """ + + thread_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The thread the item's message is or will be added to. Present only for + thread_message items. + """ + + type: typing.Optional[BatchItemKind] = pydantic.Field(default=None) + """ + The kind of item: graph_episode or thread_message. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the batch item."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/batch_item_input.py b/src/zep_cloud/types/batch_item_input.py new file mode 100644 index 00000000..e67bea5c --- /dev/null +++ b/src/zep_cloud/types/batch_item_input.py @@ -0,0 +1,80 @@ +# 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 .v4batch_item_input_data_type import V4BatchItemInputDataType +from .v4batch_item_input_role import V4BatchItemInputRole +from .v4batch_item_input_type import V4BatchItemInputType + + +class BatchItemInput(UniversalBaseModel): + content: typing.Optional[str] = pydantic.Field(default=None) + """ + The message content, for a thread_message item. + """ + + data: typing.Optional[str] = pydantic.Field(default=None) + """ + The episode content, for a graph_episode item. + """ + + data_type: typing.Optional[V4BatchItemInputDataType] = pydantic.Field(default=None) + """ + The data format of the episode: text, json, or message. + """ + + document_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Groups this item as a chunk of a document on the graph. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The graph to ingest this item into. Mutually exclusive with user_uuid. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Metadata to store on the item. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + A customizable name for the sender of the message. + """ + + role: typing.Optional[V4BatchItemInputRole] = pydantic.Field(default=None) + """ + The role of the message's sender, for a thread_message item. + """ + + source_description: typing.Optional[str] = pydantic.Field(default=None) + """ + A description of the source of this episode. + """ + + thread_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The thread this message is added to, for a thread_message item. + """ + + type: V4BatchItemInputType = pydantic.Field() + """ + The kind of item: graph_episode or thread_message. + """ + + user_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The user whose graph this item is ingested into. Mutually exclusive with graph_uuid. + """ + + 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/batch_item_page.py b/src/zep_cloud/types/batch_item_page.py index 83419e23..7a7db4a6 100644 --- a/src/zep_cloud/types/batch_item_page.py +++ b/src/zep_cloud/types/batch_item_page.py @@ -8,9 +8,21 @@ class BatchItemPage(UniversalBaseModel): - items: typing.Optional[typing.List[BatchItem]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[BatchItem]] = pydantic.Field(default=None) + """ + The batch items on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + Opaque cursor for retrieving the next page, present only when more results + are available. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of items in the batch that match the request. + """ 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/batch_items_response.py b/src/zep_cloud/types/batch_items_response.py index 50c44d74..4be7199f 100644 --- a/src/zep_cloud/types/batch_items_response.py +++ b/src/zep_cloud/types/batch_items_response.py @@ -8,7 +8,10 @@ class BatchItemsResponse(UniversalBaseModel): - items: typing.Optional[typing.List[BatchItem]] = None + items: typing.Optional[typing.List[BatchItem]] = pydantic.Field(default=None) + """ + The batch items that were added, in the order they were appended. + """ 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/batch_page.py b/src/zep_cloud/types/batch_page.py index b7685aad..02b9a30a 100644 --- a/src/zep_cloud/types/batch_page.py +++ b/src/zep_cloud/types/batch_page.py @@ -8,9 +8,21 @@ class BatchPage(UniversalBaseModel): - items: typing.Optional[typing.List[Batch]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[Batch]] = pydantic.Field(default=None) + """ + The batches on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + Opaque cursor for retrieving the next page, present only when more results + are available. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of batches that match the request. + """ 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/clone_graph_result.py b/src/zep_cloud/types/clone_graph_result.py index 3bda3605..04e9e6ea 100644 --- a/src/zep_cloud/types/clone_graph_result.py +++ b/src/zep_cloud/types/clone_graph_result.py @@ -9,8 +9,15 @@ class CloneGraphResult(UniversalBaseModel): - graph: typing.Optional[Graph] = None - task: typing.Optional[Task] = None + graph: typing.Optional[Graph] = pydantic.Field(default=None) + """ + The newly created graph the source graph is being cloned into. + """ + + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks the clone operation. + """ 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/comparison_operator.py b/src/zep_cloud/types/comparison_operator.py new file mode 100644 index 00000000..8e1df62e --- /dev/null +++ b/src/zep_cloud/types/comparison_operator.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ComparisonOperator = typing.Union[ + typing.Literal["=", "<>", ">", "<", ">=", "<=", "IS NULL", "is_null", "IS NOT NULL", "CONTAINS"], typing.Any +] diff --git a/src/zep_cloud/types/context_edge.py b/src/zep_cloud/types/context_edge.py index dbe1c8d1..b6abe458 100644 --- a/src/zep_cloud/types/context_edge.py +++ b/src/zep_cloud/types/context_edge.py @@ -9,33 +9,117 @@ class ContextEdge(UniversalBaseModel): - attributes: typing.Optional[typing.Dict[str, typing.Any]] = None - created_at: typing.Optional[str] = None - episode_uuids: typing.Optional[typing.List[str]] = None - expired_at: typing.Optional[str] = None - fact: typing.Optional[str] = None - graph_uuid: typing.Optional[str] = None - invalid_at: typing.Optional[str] = None - name: typing.Optional[str] = None - relevance: typing.Optional[float] = None - scope: typing.Optional[str] = None - score: typing.Optional[float] = None - selection_rank: typing.Optional[int] = None - source_node_labels: typing.Optional[typing.List[str]] = None + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the edge. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the edge was created. + """ + + episode_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The episodes this edge was derived from. + """ + + expired_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the fact was superseded or removed. + """ + + fact: typing.Optional[str] = pydantic.Field(default=None) + """ + The natural-language fact this edge represents. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the graph this edge belongs to. + """ + + invalid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the fact stopped being true. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the edge, in upper snake case, for example RELATES_TO. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + + scope: typing.Optional[str] = pydantic.Field(default=None) + """ + The kind of edge this is, for example entity or episodic. + """ + + score: typing.Optional[float] = pydantic.Field(default=None) + """ + The ranking score returned with every search result; omitted when the edge + appears in a plain list rather than a search result. + """ + + selection_rank: typing.Optional[int] = pydantic.Field(default=None) + """ + The 1-based position this edge was selected in across all context-assembly + scopes. + """ + + source_node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The current labels of the source node. This is read at request time rather + than stored on the edge, and is omitted when the source node cannot be + resolved. + """ + source_node_name: typing.Optional[str] = pydantic.Field(default=None) """ - Endpoint-name and label projections are read-time and subject to the - ABAC omission rule of spec-2 section 4, so each is omitted when denied. + The current name of the source node. This is read at request time rather + than stored on the edge, and is omitted when the source node cannot be + resolved. + """ + + source_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the edge's source node. + """ + + target_node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The current labels of the target node. This is read at request time rather + than stored on the edge, and is omitted when the target node cannot be + resolved. + """ + + target_node_name: typing.Optional[str] = pydantic.Field(default=None) + """ + The current name of the target node. This is read at request time rather + than stored on the edge, and is omitted when the target node cannot be + resolved. + """ + + target_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the edge's target node. """ - source_node_uuid: typing.Optional[str] = None - target_node_labels: typing.Optional[typing.List[str]] = None - target_node_name: typing.Optional[str] = None - target_node_uuid: typing.Optional[str] = None uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the edge."), ] = None - valid_at: typing.Optional[str] = None + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time from which the fact is considered true. + """ 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/context_episode.py b/src/zep_cloud/types/context_episode.py index 114779b6..f56676ea 100644 --- a/src/zep_cloud/types/context_episode.py +++ b/src/zep_cloud/types/context_episode.py @@ -11,24 +11,94 @@ class ContextEpisode(UniversalBaseModel): - content: typing.Optional[str] = None - created_at: typing.Optional[str] = None - document_id: typing.Optional[str] = None - graph_uuid: typing.Optional[str] = None - metadata: typing.Optional[typing.Dict[str, typing.Any]] = None - processed: typing.Optional[bool] = None - relevance: typing.Optional[float] = None - role: typing.Optional[RoleType] = None - role_name: typing.Optional[str] = None - score: typing.Optional[float] = None - selection_rank: typing.Optional[int] = None - source: typing.Optional[GraphDataType] = None - source_description: typing.Optional[str] = None - thread_uuid: typing.Optional[str] = None + content: typing.Optional[str] = pydantic.Field(default=None) + """ + The raw content of the episode. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the episode was created. + """ + + document_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned identifier of the document this episode belongs to, + present only for episodes added to a document. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the graph this episode belongs to. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Custom metadata associated with the episode. + """ + + processed: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the episode has finished graph extraction and indexing. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + + role: typing.Optional[RoleType] = pydantic.Field(default=None) + """ + The role of the episode's sender, present only when the episode was added + as a message. + """ + + role_name: typing.Optional[str] = pydantic.Field(default=None) + """ + The free-form display name of the episode's sender, present only when the + episode was added as a message. + """ + + score: typing.Optional[float] = pydantic.Field(default=None) + """ + The ranking score returned with every search result; omitted when the + episode appears in a plain list rather than a search result. + """ + + selection_rank: typing.Optional[int] = pydantic.Field(default=None) + """ + The 1-based position this episode was selected in across all + context-assembly scopes. + """ + + source: typing.Optional[GraphDataType] = pydantic.Field(default=None) + """ + The format of the episode's content: text, json, or message. + """ + + source_description: typing.Optional[str] = pydantic.Field(default=None) + """ + A free-form description of where the episode's content came from. + """ + + thread_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The thread this episode belongs to, present only for episodes added to a + thread. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the episode."), ] = None - valid_at: typing.Optional[str] = None + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the episode's content became true or was observed, used for + temporal reasoning. + """ 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/context_node.py b/src/zep_cloud/types/context_node.py index 20c6f519..5aaced05 100644 --- a/src/zep_cloud/types/context_node.py +++ b/src/zep_cloud/types/context_node.py @@ -9,17 +9,59 @@ class ContextNode(UniversalBaseModel): - attributes: typing.Optional[typing.Dict[str, typing.Any]] = None - created_at: typing.Optional[str] = None - graph_uuid: typing.Optional[str] = None - labels: typing.Optional[typing.List[str]] = None - name: typing.Optional[str] = None - relevance: typing.Optional[float] = None - score: typing.Optional[float] = None - selection_rank: typing.Optional[int] = None - summary: typing.Optional[str] = None + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the node, as defined by its entity type. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the node was created. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the graph this node belongs to. + """ + + labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The entity type labels assigned to the node. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the entity that the node represents. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + + score: typing.Optional[float] = pydantic.Field(default=None) + """ + The ranking score returned with every search result; omitted when the node + appears in a plain list rather than a search result. + """ + + selection_rank: typing.Optional[int] = pydantic.Field(default=None) + """ + The 1-based position this node was selected in across all context-assembly + scopes. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + A generated summary of the entity that the node represents. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The node UUID, assigned by Zep."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/context_observation.py b/src/zep_cloud/types/context_observation.py index 60105d8d..f90c9685 100644 --- a/src/zep_cloud/types/context_observation.py +++ b/src/zep_cloud/types/context_observation.py @@ -9,18 +9,64 @@ class ContextObservation(UniversalBaseModel): - attributes: typing.Optional[typing.Dict[str, typing.Any]] = None - created_at: typing.Optional[str] = None - episode_uuids: typing.Optional[typing.List[str]] = None - graph_uuid: typing.Optional[str] = None - labels: typing.Optional[typing.List[str]] = None - name: typing.Optional[str] = None - relevance: typing.Optional[float] = None - score: typing.Optional[float] = None - selection_rank: typing.Optional[int] = None - summary: typing.Optional[str] = None + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the derived node, as defined by its entity type. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the observation was created. + """ + + episode_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The unique identifiers of the episodes that support this observation. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the graph this observation belongs to. + """ + + labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The labels identifying the type of this observation. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the observation. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + + score: typing.Optional[float] = pydantic.Field(default=None) + """ + The ranking score returned with every search result; omitted when the + observation appears in a plain list rather than a search result. + """ + + selection_rank: typing.Optional[int] = pydantic.Field(default=None) + """ + The 1-based position this observation was selected in across all + context-assembly scopes. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + A generated summary of the observation. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the observation, assigned by Zep."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/context_results.py b/src/zep_cloud/types/context_results.py index d34d9ef8..8119fa96 100644 --- a/src/zep_cloud/types/context_results.py +++ b/src/zep_cloud/types/context_results.py @@ -12,11 +12,30 @@ class ContextResults(UniversalBaseModel): - edges: typing.Optional[typing.List[ContextEdge]] = None - episodes: typing.Optional[typing.List[ContextEpisode]] = None - nodes: typing.Optional[typing.List[ContextNode]] = None - observations: typing.Optional[typing.List[ContextObservation]] = None - thread_summaries: typing.Optional[typing.List[ContextThreadSummary]] = None + edges: typing.Optional[typing.List[ContextEdge]] = pydantic.Field(default=None) + """ + The edges selected for inclusion in the assembled context. + """ + + episodes: typing.Optional[typing.List[ContextEpisode]] = pydantic.Field(default=None) + """ + The episodes selected for inclusion in the assembled context. + """ + + nodes: typing.Optional[typing.List[ContextNode]] = pydantic.Field(default=None) + """ + The nodes selected for inclusion in the assembled context. + """ + + observations: typing.Optional[typing.List[ContextObservation]] = pydantic.Field(default=None) + """ + The observations selected for inclusion in the assembled context. + """ + + thread_summaries: typing.Optional[typing.List[ContextThreadSummary]] = pydantic.Field(default=None) + """ + The thread summaries selected for inclusion in the assembled context. + """ 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/context_template.py b/src/zep_cloud/types/context_template.py index dc877f25..eef45951 100644 --- a/src/zep_cloud/types/context_template.py +++ b/src/zep_cloud/types/context_template.py @@ -9,11 +9,25 @@ class ContextTemplate(UniversalBaseModel): - created_at: typing.Optional[str] = None - name: typing.Optional[str] = None - template: typing.Optional[str] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the template was created. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the context template. + """ + + template: typing.Optional[str] = pydantic.Field(default=None) + """ + The template content. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the context template."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/context_template_page.py b/src/zep_cloud/types/context_template_page.py index 270fac05..6f61acd0 100644 --- a/src/zep_cloud/types/context_template_page.py +++ b/src/zep_cloud/types/context_template_page.py @@ -8,9 +8,21 @@ class ContextTemplatePage(UniversalBaseModel): - items: typing.Optional[typing.List[ContextTemplate]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[ContextTemplate]] = pydantic.Field(default=None) + """ + The context templates on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + Opaque cursor for retrieving the next page, present only when more results + are available. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of context templates that match the request. + """ 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/context_thread_summary.py b/src/zep_cloud/types/context_thread_summary.py index 82ef6720..08c469cd 100644 --- a/src/zep_cloud/types/context_thread_summary.py +++ b/src/zep_cloud/types/context_thread_summary.py @@ -9,21 +9,55 @@ class ContextThreadSummary(UniversalBaseModel): - created_at: typing.Optional[str] = None - last_summarized_at: typing.Optional[str] = None - last_summarized_episode_valid_at: typing.Optional[str] = None - relevance: typing.Optional[float] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the summary was first created. + """ + + last_summarized_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The wall-clock time of the most recent summary update. + """ + + last_summarized_episode_valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The latest episode reference time covered by the most recent summary + update. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + score: typing.Optional[float] = pydantic.Field(default=None) """ - 8.7 puts score on every search result and relevance on the ones the - cross-encoder scored. Pointers keep both off the listing (8.4). + A score accompanies every search result; it is omitted when the summary + appears in a plain list rather than a search result. + """ + + selection_rank: typing.Optional[int] = pydantic.Field(default=None) + """ + The 1-based position this thread summary was selected in across all + context-assembly scopes. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + The generated summary text for the thread. + """ + + thread_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the thread this summary belongs to. """ - selection_rank: typing.Optional[int] = None - summary: typing.Optional[str] = None - thread_uuid: typing.Optional[str] = None uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the thread summary."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/create_context_template_request.py b/src/zep_cloud/types/create_context_template_request.py index 5f81d0af..2cac439d 100644 --- a/src/zep_cloud/types/create_context_template_request.py +++ b/src/zep_cloud/types/create_context_template_request.py @@ -7,8 +7,15 @@ class CreateContextTemplateRequest(UniversalBaseModel): - name: typing.Optional[str] = None - template: typing.Optional[str] = None + name: typing.Optional[str] = pydantic.Field(default=None) + """ + A unique, human-readable name for the template. + """ + + template: typing.Optional[str] = pydantic.Field(default=None) + """ + The template content used to render context blocks. + """ 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/custom_instruction.py b/src/zep_cloud/types/custom_instruction.py new file mode 100644 index 00000000..d3801425 --- /dev/null +++ b/src/zep_cloud/types/custom_instruction.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 CustomInstruction(UniversalBaseModel): + name: str = pydantic.Field() + """ + logical key for identifying the instruction + """ + + text: str = pydantic.Field() + """ + the actual instruction text + """ + + 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/date_filter.py b/src/zep_cloud/types/date_filter.py new file mode 100644 index 00000000..19ab4222 --- /dev/null +++ b/src/zep_cloud/types/date_filter.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 .comparison_operator import ComparisonOperator + + +class DateFilter(UniversalBaseModel): + comparison_operator: ComparisonOperator = pydantic.Field() + """ + Comparison operator for date filter + """ + + date: typing.Optional[str] = pydantic.Field(default=None) + """ + Date to filter on. Required for non-null operators (`=`, `<>`, `>`, `<`, `>=`, `<=`). + Should be omitted for IS NULL (or is_null) and IS NOT NULL operators. + """ + + 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/document_summary.py b/src/zep_cloud/types/document_summary.py index cc77b2ab..715059e4 100644 --- a/src/zep_cloud/types/document_summary.py +++ b/src/zep_cloud/types/document_summary.py @@ -9,13 +9,35 @@ class DocumentSummary(UniversalBaseModel): - created_at: typing.Optional[str] = None - document_id: typing.Optional[str] = None - last_summarized_at: typing.Optional[str] = None - last_summarized_episode_valid_at: typing.Optional[str] = None - summary: typing.Optional[str] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the summary was created. + """ + + document_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned identifier of the document this summary covers. + """ + + last_summarized_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the summary was most recently generated. + """ + + last_summarized_episode_valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The latest episode reference time covered by the summary. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + A generated summary of the document's episodes. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the document summary."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/document_summary_page.py b/src/zep_cloud/types/document_summary_page.py index c5404588..6bbb658b 100644 --- a/src/zep_cloud/types/document_summary_page.py +++ b/src/zep_cloud/types/document_summary_page.py @@ -8,9 +8,22 @@ class DocumentSummaryPage(UniversalBaseModel): - items: typing.Optional[typing.List[DocumentSummary]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[DocumentSummary]] = pydantic.Field(default=None) + """ + The document summaries on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + Opaque cursor for retrieving the next page, present only when more results + are available. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Omitted for this collection; use next_cursor to detect the end of + pagination. + """ 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/edge.py b/src/zep_cloud/types/edge.py index 3f52bc82..a6bc4937 100644 --- a/src/zep_cloud/types/edge.py +++ b/src/zep_cloud/types/edge.py @@ -9,32 +9,111 @@ class Edge(UniversalBaseModel): - attributes: typing.Optional[typing.Dict[str, typing.Any]] = None - created_at: typing.Optional[str] = None - episode_uuids: typing.Optional[typing.List[str]] = None - expired_at: typing.Optional[str] = None - fact: typing.Optional[str] = None - graph_uuid: typing.Optional[str] = None - invalid_at: typing.Optional[str] = None - name: typing.Optional[str] = None - relevance: typing.Optional[float] = None - scope: typing.Optional[str] = None - score: typing.Optional[float] = None - source_node_labels: typing.Optional[typing.List[str]] = None + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the edge. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the edge was created. + """ + + episode_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The episodes this edge was derived from. + """ + + expired_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the fact was superseded or removed. + """ + + fact: typing.Optional[str] = pydantic.Field(default=None) + """ + The natural-language fact this edge represents. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the graph this edge belongs to. + """ + + invalid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the fact stopped being true. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the edge, in upper snake case, for example RELATES_TO. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + + scope: typing.Optional[str] = pydantic.Field(default=None) + """ + The kind of edge this is, for example entity or episodic. + """ + + score: typing.Optional[float] = pydantic.Field(default=None) + """ + The ranking score returned with every search result; omitted when the edge + appears in a plain list rather than a search result. + """ + + source_node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The current labels of the source node. This is read at request time rather + than stored on the edge, and is omitted when the source node cannot be + resolved. + """ + source_node_name: typing.Optional[str] = pydantic.Field(default=None) """ - Endpoint-name and label projections are read-time and subject to the - ABAC omission rule of spec-2 section 4, so each is omitted when denied. + The current name of the source node. This is read at request time rather + than stored on the edge, and is omitted when the source node cannot be + resolved. + """ + + source_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the edge's source node. + """ + + target_node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The current labels of the target node. This is read at request time rather + than stored on the edge, and is omitted when the target node cannot be + resolved. + """ + + target_node_name: typing.Optional[str] = pydantic.Field(default=None) + """ + The current name of the target node. This is read at request time rather + than stored on the edge, and is omitted when the target node cannot be + resolved. + """ + + target_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the edge's target node. """ - source_node_uuid: typing.Optional[str] = None - target_node_labels: typing.Optional[typing.List[str]] = None - target_node_name: typing.Optional[str] = None - target_node_uuid: typing.Optional[str] = None uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the edge."), ] = None - valid_at: typing.Optional[str] = None + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time from which the fact is considered true. + """ 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/edge_node_ref.py b/src/zep_cloud/types/edge_node_ref.py new file mode 100644 index 00000000..e409c420 --- /dev/null +++ b/src/zep_cloud/types/edge_node_ref.py @@ -0,0 +1,45 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class EdgeNodeRef(UniversalBaseModel): + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the node, as defined by its entity type. + """ + + labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The entity type labels to assign to the node. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the node to create or match. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + A summary of the node. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of an existing node to attach the edge to."), + ] = 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/edge_page.py b/src/zep_cloud/types/edge_page.py index 403fa7f6..b39cf71f 100644 --- a/src/zep_cloud/types/edge_page.py +++ b/src/zep_cloud/types/edge_page.py @@ -8,9 +8,22 @@ class EdgePage(UniversalBaseModel): - items: typing.Optional[typing.List[Edge]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[Edge]] = pydantic.Field(default=None) + """ + The edges on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + Opaque cursor for retrieving the next page, present only when more results + are available. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Omitted for this collection; use next_cursor to detect the end of + pagination. + """ 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/edge_source_target.py b/src/zep_cloud/types/edge_source_target.py index c58aa1ff..202c4e8e 100644 --- a/src/zep_cloud/types/edge_source_target.py +++ b/src/zep_cloud/types/edge_source_target.py @@ -7,8 +7,15 @@ class EdgeSourceTarget(UniversalBaseModel): - source_entity_type: typing.Optional[str] = None - target_entity_type: typing.Optional[str] = None + source: typing.Optional[str] = pydantic.Field(default=None) + """ + The entity type an edge of this type originates from. + """ + + target: typing.Optional[str] = pydantic.Field(default=None) + """ + The entity type an edge of this type points to. + """ 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/edge_type.py b/src/zep_cloud/types/edge_type.py index 10092bd8..71878b15 100644 --- a/src/zep_cloud/types/edge_type.py +++ b/src/zep_cloud/types/edge_type.py @@ -9,10 +9,26 @@ class EdgeType(UniversalBaseModel): - description: typing.Optional[str] = None - name: typing.Optional[str] = None - properties: typing.Optional[typing.List[EntityProperty]] = None - source_targets: typing.Optional[typing.List[EdgeSourceTarget]] = None + description: typing.Optional[str] = pydantic.Field(default=None) + """ + A description of the relationship this edge type represents, used to guide + extraction. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the edge type, in upper snake case. + """ + + properties: typing.Optional[typing.List[EntityProperty]] = pydantic.Field(default=None) + """ + The custom properties defined on edges of this type. + """ + + source_targets: typing.Optional[typing.List[EdgeSourceTarget]] = pydantic.Field(default=None) + """ + The allowed source and target entity type pairs for edges of this type. + """ 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/entity_property.py b/src/zep_cloud/types/entity_property.py index 118be6b1..92f4f8d4 100644 --- a/src/zep_cloud/types/entity_property.py +++ b/src/zep_cloud/types/entity_property.py @@ -8,9 +8,20 @@ class EntityProperty(UniversalBaseModel): - description: typing.Optional[str] = None - name: typing.Optional[str] = None - type: typing.Optional[EntityPropertyType] = None + description: typing.Optional[str] = pydantic.Field(default=None) + """ + A description of the property, used to guide extraction. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the property. + """ + + type: typing.Optional[EntityPropertyType] = pydantic.Field(default=None) + """ + The value type of the property: text, int, float, or boolean. + """ 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/entity_type.py b/src/zep_cloud/types/entity_type.py index 313770e8..cf9d3577 100644 --- a/src/zep_cloud/types/entity_type.py +++ b/src/zep_cloud/types/entity_type.py @@ -8,10 +8,26 @@ class EntityType(UniversalBaseModel): - description: typing.Optional[str] = None - identity_properties: typing.Optional[typing.List[str]] = None - name: typing.Optional[str] = None - properties: typing.Optional[typing.List[EntityProperty]] = None + description: typing.Optional[str] = pydantic.Field(default=None) + """ + A description of the entity type, used to guide extraction. + """ + + identity_properties: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The property names that determine whether two nodes of this type are the + same entity. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the entity type. + """ + + properties: typing.Optional[typing.List[EntityProperty]] = pydantic.Field(default=None) + """ + The custom properties defined on nodes of this type. + """ 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/episode.py b/src/zep_cloud/types/episode.py index f3ca89f6..4933eba2 100644 --- a/src/zep_cloud/types/episode.py +++ b/src/zep_cloud/types/episode.py @@ -11,23 +11,88 @@ class Episode(UniversalBaseModel): - content: typing.Optional[str] = None - created_at: typing.Optional[str] = None - document_id: typing.Optional[str] = None - graph_uuid: typing.Optional[str] = None - metadata: typing.Optional[typing.Dict[str, typing.Any]] = None - processed: typing.Optional[bool] = None - relevance: typing.Optional[float] = None - role: typing.Optional[RoleType] = None - role_name: typing.Optional[str] = None - score: typing.Optional[float] = None - source: typing.Optional[GraphDataType] = None - source_description: typing.Optional[str] = None - thread_uuid: typing.Optional[str] = None + content: typing.Optional[str] = pydantic.Field(default=None) + """ + The raw content of the episode. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the episode was created. + """ + + document_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned identifier of the document this episode belongs to, + present only for episodes added to a document. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the graph this episode belongs to. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Custom metadata associated with the episode. + """ + + processed: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the episode has finished graph extraction and indexing. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + + role: typing.Optional[RoleType] = pydantic.Field(default=None) + """ + The role of the episode's sender, present only when the episode was added + as a message. + """ + + role_name: typing.Optional[str] = pydantic.Field(default=None) + """ + The free-form display name of the episode's sender, present only when the + episode was added as a message. + """ + + score: typing.Optional[float] = pydantic.Field(default=None) + """ + The ranking score returned with every search result; omitted when the + episode appears in a plain list rather than a search result. + """ + + source: typing.Optional[GraphDataType] = pydantic.Field(default=None) + """ + The format of the episode's content: text, json, or message. + """ + + source_description: typing.Optional[str] = pydantic.Field(default=None) + """ + A free-form description of where the episode's content came from. + """ + + thread_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The thread this episode belongs to, present only for episodes added to a + thread. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the episode."), ] = None - valid_at: typing.Optional[str] = None + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the episode's content became true or was observed, used for + temporal reasoning. + """ 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/episode_metadata_filter.py b/src/zep_cloud/types/episode_metadata_filter.py new file mode 100644 index 00000000..d3c15798 --- /dev/null +++ b/src/zep_cloud/types/episode_metadata_filter.py @@ -0,0 +1,33 @@ +# 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 .comparison_operator import ComparisonOperator + + +class EpisodeMetadataFilter(UniversalBaseModel): + comparison_operator: ComparisonOperator = pydantic.Field() + """ + Comparison operator: =, <>, >, <, >=, <=, IS NULL, IS NOT NULL, IN, CONTAINS + """ + + property_name: str = pydantic.Field() + """ + Metadata key to filter on + """ + + property_value: typing.Optional[typing.Any] = pydantic.Field(default=None) + """ + Value to compare against. Not required for IS NULL / IS NOT NULL operators. + """ + + 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/episode_page.py b/src/zep_cloud/types/episode_page.py index 24b51d95..bea1a1ea 100644 --- a/src/zep_cloud/types/episode_page.py +++ b/src/zep_cloud/types/episode_page.py @@ -8,9 +8,22 @@ class EpisodePage(UniversalBaseModel): - items: typing.Optional[typing.List[Episode]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[Episode]] = pydantic.Field(default=None) + """ + The episodes on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + Opaque cursor for retrieving the next page, present only when more results + are available. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Omitted for this collection; use next_cursor to detect the end of + pagination. + """ 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/graph.py b/src/zep_cloud/types/graph.py index c321f5bc..78a2321e 100644 --- a/src/zep_cloud/types/graph.py +++ b/src/zep_cloud/types/graph.py @@ -9,16 +9,53 @@ class Graph(UniversalBaseModel): - created_at: typing.Optional[str] = None - description: typing.Optional[str] = None - graph_id: typing.Optional[str] = None - name: typing.Optional[str] = None - time_zone: typing.Optional[str] = None - type: typing.Optional[str] = None - updated_at: typing.Optional[str] = None - user_uuid: typing.Optional[str] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the graph was created. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + A description of the graph. + """ + + graph_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned identifier of the graph, present only for standard + graphs. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The display name of the graph. + """ + + time_zone: typing.Optional[str] = pydantic.Field(default=None) + """ + The graph's IANA time zone. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The kind of graph: user for a user's personal graph, or standard for a + named graph created directly. + """ + + updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the graph was last updated. + """ + + user_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the user this graph belongs to, present only for + a user graph. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the graph."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/graph_context_response.py b/src/zep_cloud/types/graph_context_response.py index a8d0c1ac..1a66ccf0 100644 --- a/src/zep_cloud/types/graph_context_response.py +++ b/src/zep_cloud/types/graph_context_response.py @@ -8,9 +8,22 @@ class GraphContextResponse(UniversalBaseModel): - context: typing.Optional[str] = None - results: typing.Optional[ContextResults] = None - truncated: typing.Optional[bool] = None + context: typing.Optional[str] = pydantic.Field(default=None) + """ + The assembled context block of facts, entities, and episodes, ready to + insert into a system prompt. + """ + + results: typing.Optional[ContextResults] = pydantic.Field(default=None) + """ + The individual edges, nodes, episodes, observations, and thread summaries + selected to build the context. Present only when requested. + """ + + truncated: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the character budget limited the size of the context block. + """ 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/graph_delete_result.py b/src/zep_cloud/types/graph_delete_result.py index 0c10eb61..c572403b 100644 --- a/src/zep_cloud/types/graph_delete_result.py +++ b/src/zep_cloud/types/graph_delete_result.py @@ -8,7 +8,10 @@ class GraphDeleteResult(UniversalBaseModel): - task: typing.Optional[Task] = None + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks the graph's deletion. + """ 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/graph_page.py b/src/zep_cloud/types/graph_page.py index acc12f5b..de984fe9 100644 --- a/src/zep_cloud/types/graph_page.py +++ b/src/zep_cloud/types/graph_page.py @@ -8,9 +8,21 @@ class GraphPage(UniversalBaseModel): - items: typing.Optional[typing.List[Graph]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[Graph]] = pydantic.Field(default=None) + """ + The graphs on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + Opaque cursor for retrieving the next page, present only when more results + are available. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of graphs that match the request. + """ 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/graphiti_metadata_filter_group_type.py b/src/zep_cloud/types/graphiti_metadata_filter_group_type.py new file mode 100644 index 00000000..c788e943 --- /dev/null +++ b/src/zep_cloud/types/graphiti_metadata_filter_group_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +GraphitiMetadataFilterGroupType = typing.Union[typing.Literal["and", "or"], typing.Any] diff --git a/src/zep_cloud/types/instructions.py b/src/zep_cloud/types/instructions.py index a308ddc6..7eb4b1fa 100644 --- a/src/zep_cloud/types/instructions.py +++ b/src/zep_cloud/types/instructions.py @@ -4,11 +4,21 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .custom_instruction import CustomInstruction class Instructions(UniversalBaseModel): - inherited: typing.Optional[bool] = None - instructions: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = None + inherited: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether this is the project's default value rather than an override set on + this graph. + """ + + instructions: typing.Optional[typing.List[CustomInstruction]] = pydantic.Field(default=None) + """ + The custom extraction instructions in effect at this scope, each with a + name and text. + """ 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/lookup_batch_response.py b/src/zep_cloud/types/lookup_batch_response.py index 3aff393d..31f6fb1b 100644 --- a/src/zep_cloud/types/lookup_batch_response.py +++ b/src/zep_cloud/types/lookup_batch_response.py @@ -8,7 +8,11 @@ class LookupBatchResponse(UniversalBaseModel): - items: typing.Optional[typing.List[LookupItem]] = None + items: typing.Optional[typing.List[LookupItem]] = pydantic.Field(default=None) + """ + The lookup result for each identifier submitted, in request order within + each resource type. + """ 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/lookup_item.py b/src/zep_cloud/types/lookup_item.py index 20775236..cb642343 100644 --- a/src/zep_cloud/types/lookup_item.py +++ b/src/zep_cloud/types/lookup_item.py @@ -9,11 +9,25 @@ class LookupItem(UniversalBaseModel): - found: typing.Optional[bool] = None - legacy_id: typing.Optional[str] = None - resource_type: typing.Optional[str] = None + found: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the identifier resolved to a resource visible to the caller. + """ + + legacy_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned identifier that was looked up. + """ + + resource_type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of resource this entry resolves: user, thread, or graph. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The resource's unique identifier; present only when found is true."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/lookup_request.py b/src/zep_cloud/types/lookup_request.py index 6783e396..e16b0686 100644 --- a/src/zep_cloud/types/lookup_request.py +++ b/src/zep_cloud/types/lookup_request.py @@ -7,9 +7,23 @@ class LookupRequest(UniversalBaseModel): - graph_id: typing.Optional[str] = None - thread_id: typing.Optional[str] = None - user_id: typing.Optional[str] = None + graph_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. + """ + + thread_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. + """ + + user_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. + """ 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/membership_mutation_result.py b/src/zep_cloud/types/membership_mutation_result.py new file mode 100644 index 00000000..f74789e9 --- /dev/null +++ b/src/zep_cloud/types/membership_mutation_result.py @@ -0,0 +1,33 @@ +# 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 MembershipMutationResult(UniversalBaseModel): + added_count: typing.Optional[int] = pydantic.Field(default=None) + """ + The number of users added to the group. + """ + + no_op_count: typing.Optional[int] = pydantic.Field(default=None) + """ + The number of requested users that already matched the target membership + state and were left unchanged. + """ + + removed_count: typing.Optional[int] = pydantic.Field(default=None) + """ + The number of users removed from the group. + """ + + 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.py b/src/zep_cloud/types/message.py index 14767c73..92ff273a 100644 --- a/src/zep_cloud/types/message.py +++ b/src/zep_cloud/types/message.py @@ -10,15 +10,47 @@ class Message(UniversalBaseModel): - content: typing.Optional[str] = None - created_at: typing.Optional[str] = None - metadata: typing.Optional[typing.Dict[str, typing.Any]] = None - name: typing.Optional[str] = None - processed: typing.Optional[bool] = None - role: typing.Optional[RoleType] = None - thread_uuid: typing.Optional[str] = None + content: typing.Optional[str] = pydantic.Field(default=None) + """ + The content of the message. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the message was created. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Arbitrary key-value metadata attached to the message. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + A custom name for the message's sender, for example a specific user or + agent name. + """ + + processed: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the message has finished being ingested into the user's graph. + """ + + role: typing.Optional[RoleType] = pydantic.Field(default=None) + """ + The role of the message's sender: system, assistant, user, function, or + tool. + """ + + thread_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the thread this message belongs to. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the message."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/message_page.py b/src/zep_cloud/types/message_page.py index 7da041cb..f008f81d 100644 --- a/src/zep_cloud/types/message_page.py +++ b/src/zep_cloud/types/message_page.py @@ -8,9 +8,22 @@ class MessagePage(UniversalBaseModel): - items: typing.Optional[typing.List[Message]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[Message]] = pydantic.Field(default=None) + """ + The messages on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of matching messages, counted at the time of this + response. It does not indicate whether more pages remain. + """ 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/metadata_filter_group.py b/src/zep_cloud/types/metadata_filter_group.py new file mode 100644 index 00000000..4c662e35 --- /dev/null +++ b/src/zep_cloud/types/metadata_filter_group.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs +from .episode_metadata_filter import EpisodeMetadataFilter +from .graphiti_metadata_filter_group_type import GraphitiMetadataFilterGroupType + + +class MetadataFilterGroup(UniversalBaseModel): + filters: typing.Optional[typing.List[EpisodeMetadataFilter]] = pydantic.Field(default=None) + """ + Leaf filters (predicates on metadata key-value pairs) + """ + + groups: typing.Optional[typing.List["MetadataFilterGroup"]] = pydantic.Field(default=None) + """ + Nested sub-groups for composing complex boolean expressions + """ + + type: GraphitiMetadataFilterGroupType = pydantic.Field() + """ + Logical operator: "and" or "or" + """ + + 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 + + +update_forward_refs(MetadataFilterGroup) diff --git a/src/zep_cloud/types/mutate_members_request.py b/src/zep_cloud/types/mutate_members_request.py new file mode 100644 index 00000000..32029246 --- /dev/null +++ b/src/zep_cloud/types/mutate_members_request.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 MutateMembersRequest(UniversalBaseModel): + user_uuids: typing.List[str] = pydantic.Field() + """ + The UUIDs of the users to add or remove. + """ + + 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/neighbor_entry.py b/src/zep_cloud/types/neighbor_entry.py index 9898fbd7..82eace17 100644 --- a/src/zep_cloud/types/neighbor_entry.py +++ b/src/zep_cloud/types/neighbor_entry.py @@ -9,8 +9,15 @@ class NeighborEntry(UniversalBaseModel): - edges: typing.Optional[typing.List[Edge]] = None - node: typing.Optional[Node] = None + edges: typing.Optional[typing.List[Edge]] = pydantic.Field(default=None) + """ + The edges connecting the neighboring node to the queried node. + """ + + node: typing.Optional[Node] = pydantic.Field(default=None) + """ + The neighboring node reached from the queried node. + """ 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/neighbor_page.py b/src/zep_cloud/types/neighbor_page.py index e353facc..ba9a68e8 100644 --- a/src/zep_cloud/types/neighbor_page.py +++ b/src/zep_cloud/types/neighbor_page.py @@ -8,9 +8,22 @@ class NeighborPage(UniversalBaseModel): - items: typing.Optional[typing.List[NeighborEntry]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[NeighborEntry]] = pydantic.Field(default=None) + """ + The neighboring nodes and their connecting edges on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Omitted for this collection; use next_cursor to detect the end of + pagination. + """ 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/node.py b/src/zep_cloud/types/node.py index 0a8c9dee..ca63fc56 100644 --- a/src/zep_cloud/types/node.py +++ b/src/zep_cloud/types/node.py @@ -9,16 +9,53 @@ class Node(UniversalBaseModel): - attributes: typing.Optional[typing.Dict[str, typing.Any]] = None - created_at: typing.Optional[str] = None - graph_uuid: typing.Optional[str] = None - labels: typing.Optional[typing.List[str]] = None - name: typing.Optional[str] = None - relevance: typing.Optional[float] = None - score: typing.Optional[float] = None - summary: typing.Optional[str] = None + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the node, as defined by its entity type. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the node was created. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the graph this node belongs to. + """ + + labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The entity type labels assigned to the node. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the entity that the node represents. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + + score: typing.Optional[float] = pydantic.Field(default=None) + """ + The ranking score returned with every search result; omitted when the node + appears in a plain list rather than a search result. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + A generated summary of the entity that the node represents. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The node UUID, assigned by Zep."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/node_input.py b/src/zep_cloud/types/node_input.py new file mode 100644 index 00000000..bc615922 --- /dev/null +++ b/src/zep_cloud/types/node_input.py @@ -0,0 +1,42 @@ +# 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 NodeInput(UniversalBaseModel): + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the node, as defined by its entity type. + """ + + label: typing.Optional[str] = pydantic.Field(default=None) + """ + The node's entity type. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Metadata to store on the node. + """ + + name: str = pydantic.Field() + """ + The name of the entity the node represents. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + A summary of the entity the node represents. + """ + + 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/node_page.py b/src/zep_cloud/types/node_page.py index 020bb73f..70835fe9 100644 --- a/src/zep_cloud/types/node_page.py +++ b/src/zep_cloud/types/node_page.py @@ -8,9 +8,22 @@ class NodePage(UniversalBaseModel): - items: typing.Optional[typing.List[Node]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[Node]] = pydantic.Field(default=None) + """ + The nodes on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Omitted for this collection; use next_cursor to detect the end of + pagination. + """ 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/observation.py b/src/zep_cloud/types/observation.py index 3c07f063..052a268b 100644 --- a/src/zep_cloud/types/observation.py +++ b/src/zep_cloud/types/observation.py @@ -9,17 +9,58 @@ class Observation(UniversalBaseModel): - attributes: typing.Optional[typing.Dict[str, typing.Any]] = None - created_at: typing.Optional[str] = None - episode_uuids: typing.Optional[typing.List[str]] = None - graph_uuid: typing.Optional[str] = None - labels: typing.Optional[typing.List[str]] = None - name: typing.Optional[str] = None - relevance: typing.Optional[float] = None - score: typing.Optional[float] = None - summary: typing.Optional[str] = None + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the derived node, as defined by its entity type. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the observation was created. + """ + + episode_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The unique identifiers of the episodes that support this observation. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the graph this observation belongs to. + """ + + labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The labels identifying the type of this observation. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the observation. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + + score: typing.Optional[float] = pydantic.Field(default=None) + """ + The ranking score returned with every search result; omitted when the + observation appears in a plain list rather than a search result. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + A generated summary of the observation. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the observation, assigned by Zep."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/observation_page.py b/src/zep_cloud/types/observation_page.py index 7e618c12..e3ea0dd8 100644 --- a/src/zep_cloud/types/observation_page.py +++ b/src/zep_cloud/types/observation_page.py @@ -8,9 +8,22 @@ class ObservationPage(UniversalBaseModel): - items: typing.Optional[typing.List[Observation]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[Observation]] = pydantic.Field(default=None) + """ + The observations on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Omitted for this collection; use next_cursor to detect the end of + pagination. + """ 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/observation_steering.py b/src/zep_cloud/types/observation_steering.py index f82f1abd..f317c57a 100644 --- a/src/zep_cloud/types/observation_steering.py +++ b/src/zep_cloud/types/observation_steering.py @@ -4,12 +4,27 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .observation_type import ObservationType class ObservationSteering(UniversalBaseModel): - inherited: typing.Optional[bool] = None - instruction: typing.Optional[str] = None - types: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = None + inherited: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether this is the project's default value rather than an override set on + this graph. + """ + + instruction: typing.Optional[str] = pydantic.Field(default=None) + """ + The natural-language instruction steering how observations are generated + at this scope. + """ + + types: typing.Optional[typing.List[ObservationType]] = pydantic.Field(default=None) + """ + The named observation types, each with a description, that generation + should steer toward at this scope. + """ 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/observation_type.py b/src/zep_cloud/types/observation_type.py new file mode 100644 index 00000000..60fbb880 --- /dev/null +++ b/src/zep_cloud/types/observation_type.py @@ -0,0 +1,20 @@ +# 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 ObservationType(UniversalBaseModel): + description: typing.Optional[str] = None + name: typing.Optional[str] = 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/ontology.py b/src/zep_cloud/types/ontology.py index fce76f60..385f5723 100644 --- a/src/zep_cloud/types/ontology.py +++ b/src/zep_cloud/types/ontology.py @@ -9,9 +9,21 @@ class Ontology(UniversalBaseModel): - edge_types: typing.Optional[typing.List[EdgeType]] = None - entity_types: typing.Optional[typing.List[EntityType]] = None - inherited: typing.Optional[bool] = None + edge_types: typing.Optional[typing.List[EdgeType]] = pydantic.Field(default=None) + """ + The edge types defined in the ontology in effect at this scope. + """ + + entity_types: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) + """ + The entity types defined in the ontology in effect at this scope. + """ + + inherited: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether this is the project's default value rather than an override set on + this graph. + """ 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/process_batch_result.py b/src/zep_cloud/types/process_batch_result.py index 3930882b..0e112a49 100644 --- a/src/zep_cloud/types/process_batch_result.py +++ b/src/zep_cloud/types/process_batch_result.py @@ -9,8 +9,15 @@ class ProcessBatchResult(UniversalBaseModel): - batch: typing.Optional[Batch] = None - task: typing.Optional[Task] = None + batch: typing.Optional[Batch] = pydantic.Field(default=None) + """ + The batch that was submitted for processing. + """ + + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The task tracking the batch's asynchronous processing. + """ 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/project.py b/src/zep_cloud/types/project.py index 9b82f0b2..44720fa8 100644 --- a/src/zep_cloud/types/project.py +++ b/src/zep_cloud/types/project.py @@ -9,12 +9,31 @@ class Project(UniversalBaseModel): - created_at: typing.Optional[str] = None - default_time_zone: typing.Optional[str] = None - description: typing.Optional[str] = None - name: typing.Optional[str] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the project was created. + """ + + default_time_zone: typing.Optional[str] = pydantic.Field(default=None) + """ + The project's default IANA time zone, used as the fallback when a resource + does not set its own. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + A human-readable description of the project. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the project. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the project."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/property_filter.py b/src/zep_cloud/types/property_filter.py new file mode 100644 index 00000000..48420e85 --- /dev/null +++ b/src/zep_cloud/types/property_filter.py @@ -0,0 +1,35 @@ +# 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 .comparison_operator import ComparisonOperator + + +class PropertyFilter(UniversalBaseModel): + comparison_operator: ComparisonOperator = pydantic.Field() + """ + Comparison operator for property filter + """ + + property_name: str = pydantic.Field() + """ + Property name to filter on + """ + + property_value: typing.Optional[typing.Any] = pydantic.Field(default=None) + """ + Property value to match on. Accepted types: string, int, float64, bool, or nil. + Invalid types (e.g., arrays, objects) will be rejected by validation. + Must be non-nil for non-null operators (`=`, `<>`, `>`, `<`, `>=`, `<=`). + """ + + 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/search_filters.py b/src/zep_cloud/types/search_filters.py new file mode 100644 index 00000000..38263d69 --- /dev/null +++ b/src/zep_cloud/types/search_filters.py @@ -0,0 +1,127 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs +from .date_filter import DateFilter +from .property_filter import PropertyFilter + + +class SearchFilters(UniversalBaseModel): + connected_node_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of node UUIDs to filter edges on: an edge matches if its source OR + target node UUID is in this list. Applies to edges only; rejected on + requests whose result type contains no edges. Max 256 entries. + """ + + created_at: typing.Optional[typing.List[typing.List[DateFilter]]] = pydantic.Field(default=None) + """ + 2D array of date filters for the created_at field. + The outer array elements are combined with OR logic. + The inner array elements are combined with AND logic. + Example: `[[{">", date1}, {"<", date2}], [{"=", date3}]]` + This translates to: `(created_at > date1 AND created_at < date2) OR (created_at = date3)` + """ + + edge_types: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of edge types to filter on + """ + + edge_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of edge UUIDs to filter on. Max 256 to align with graph-service filter limits. + """ + + episode_metadata_filters: typing.Optional["MetadataFilterGroup"] = pydantic.Field(default=None) + """ + [Experimental] Episode metadata filter. Restricts results to edges/nodes derived from episodes + matching the metadata predicates. Uses explicit AND/OR groups. This feature is experimental and may change in future releases. + """ + + episode_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of episode UUIDs to filter on. An edge matches if it was derived + from any listed episode; a node matches if it is mentioned by any + listed episode. Valid for both edge and node result types. Max 256 + entries. + """ + + exclude_edge_types: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of edge types to exclude from results + """ + + exclude_node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of node labels to exclude from results + """ + + expired_at: typing.Optional[typing.List[typing.List[DateFilter]]] = pydantic.Field(default=None) + """ + 2D array of date filters for the expired_at field. + The outer array elements are combined with OR logic. + The inner array elements are combined with AND logic. + Example: `[[{">", date1}, {"<", date2}], [{"=", date3}]]` + This translates to: `(expired_at > date1 AND expired_at < date2) OR (expired_at = date3)` + """ + + invalid_at: typing.Optional[typing.List[typing.List[DateFilter]]] = pydantic.Field(default=None) + """ + 2D array of date filters for the invalid_at field. + The outer array elements are combined with OR logic. + The inner array elements are combined with AND logic. + Example: `[[{">", date1}, {"<", date2}], [{"=", date3}]]` + This translates to: `(invalid_at > date1 AND invalid_at < date2) OR (invalid_at = date3)` + """ + + node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of node labels to filter on + """ + + property_filters: typing.Optional[typing.List[PropertyFilter]] = pydantic.Field(default=None) + """ + List of property filters to apply to nodes and edges + """ + + source_node_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of node UUIDs to filter edges on: an edge matches if its source + node UUID is in this list. Applies to edges only; rejected on requests + whose result type contains no edges. Max 256 entries. + """ + + target_node_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of node UUIDs to filter edges on: an edge matches if its target + node UUID is in this list. Applies to edges only; rejected on requests + whose result type contains no edges. Max 256 entries. + """ + + valid_at: typing.Optional[typing.List[typing.List[DateFilter]]] = pydantic.Field(default=None) + """ + 2D array of date filters for the valid_at field. + The outer array elements are combined with OR logic. + The inner array elements are combined with AND logic. + Example: `[[{">", date1}, {"<", date2}], [{"=", date3}]]` + This translates to: `(valid_at > date1 AND valid_at < date2) OR (valid_at = date3)` + """ + + 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 + + +from .metadata_filter_group import MetadataFilterGroup # noqa: E402, I001 + +update_forward_refs(SearchFilters, MetadataFilterGroup=MetadataFilterGroup) diff --git a/src/zep_cloud/types/search_list_request.py b/src/zep_cloud/types/search_list_request.py new file mode 100644 index 00000000..7569b14e --- /dev/null +++ b/src/zep_cloud/types/search_list_request.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 SearchListRequest(UniversalBaseModel): + search: typing.Optional[str] = pydantic.Field(default=None) + """ + Filters results to items matching this free-text search term. + """ + + 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/search_request.py b/src/zep_cloud/types/search_request.py index 6faa83d2..5a9a7b31 100644 --- a/src/zep_cloud/types/search_request.py +++ b/src/zep_cloud/types/search_request.py @@ -1,18 +1,47 @@ # This file was auto-generated by Fern from our API Definition. +from __future__ import annotations + import typing import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs +from .search_filters import SearchFilters +from .v4search_request_reranker import V4SearchRequestReranker class SearchRequest(UniversalBaseModel): - bfs_origin_node_uuids: typing.Optional[typing.List[str]] = None - center_node_uuid: typing.Optional[str] = None - filters: typing.Optional[typing.Dict[str, typing.Any]] = None - mmr_lambda: typing.Optional[float] = None - query: typing.Optional[str] = None - reranker: typing.Optional[str] = None + bfs_origin_node_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Nodes used as BFS origins for graph-distance-aware retrieval. + """ + + center_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The node to rank results by distance from. Required when reranker is + node_distance. + """ + + filters: typing.Optional[SearchFilters] = pydantic.Field(default=None) + """ + Filters constraining which items are returned. + """ + + mmr_lambda: typing.Optional[float] = pydantic.Field(default=None) + """ + The diversity weighting used for maximal marginal relevance reranking. + Required when reranker is mmr. + """ + + query: str = pydantic.Field() + """ + The search query. + """ + + reranker: typing.Optional[V4SearchRequestReranker] = pydantic.Field(default=None) + """ + The reranking strategy applied to retrieved results. Defaults to rrf. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -22,3 +51,6 @@ class Config: frozen = True smart_union = True extra = pydantic.Extra.allow + + +update_forward_refs(SearchRequest) diff --git a/src/zep_cloud/types/subgraph_response.py b/src/zep_cloud/types/subgraph_response.py index b04fca04..b2ae6800 100644 --- a/src/zep_cloud/types/subgraph_response.py +++ b/src/zep_cloud/types/subgraph_response.py @@ -9,10 +9,28 @@ class SubgraphResponse(UniversalBaseModel): - edges: typing.Optional[typing.List[Edge]] = None - nodes: typing.Optional[typing.List[Node]] = None - truncated: typing.Optional[bool] = None - truncation_reason: typing.Optional[str] = None + edges: typing.Optional[typing.List[Edge]] = pydantic.Field(default=None) + """ + Every traversed edge that passed the request filters; both endpoints of + every edge are present in nodes. + """ + + nodes: typing.Optional[typing.List[Node]] = pydantic.Field(default=None) + """ + Every admitted seed node and every node reached within the traversal + budget. + """ + + truncated: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether any budget or limit reduced the result. + """ + + truncation_reason: typing.Optional[str] = pydantic.Field(default=None) + """ + The binding limit that caused truncation, such as max_nodes or max_edges; + present only when truncated is true. + """ 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/task.py b/src/zep_cloud/types/task.py index 97f0790a..a2614b13 100644 --- a/src/zep_cloud/types/task.py +++ b/src/zep_cloud/types/task.py @@ -11,17 +11,61 @@ class Task(UniversalBaseModel): - completed_at: typing.Optional[str] = None - created_at: typing.Optional[str] = None - error: typing.Optional[ErrorBody] = None - progress: typing.Optional[TaskProgress] = None - result: typing.Optional[typing.Dict[str, typing.Any]] = None - started_at: typing.Optional[str] = None - status: typing.Optional[str] = None - type: typing.Optional[str] = None - updated_at: typing.Optional[str] = None + completed_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the task reached a terminal status; absent while it is still in + progress. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the task was created. + """ + + error: typing.Optional[ErrorBody] = pydantic.Field(default=None) + """ + The error that caused the task to fail; also present on a partial task + when the worker can name a single cause. + """ + + progress: typing.Optional[TaskProgress] = pydantic.Field(default=None) + """ + The last processing stage a worker reported for this task. It is not + cleared when the task finishes, so a completed task may still show its + final stage. + """ + + result: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Operation-specific output populated once the task reaches succeeded or + partial, such as identifiers the operation could not return synchronously. + """ + + started_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time a worker began processing the task; absent until then. + """ + + status: typing.Optional[str] = pydantic.Field(default=None) + """ + The task's current state: pending, processing, succeeded, partial, or + failed. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The kind of asynchronous operation the task represents. + """ + + updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the task was last updated. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the task, used to poll its status."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/task_page.py b/src/zep_cloud/types/task_page.py index 1cdb4caf..9c119477 100644 --- a/src/zep_cloud/types/task_page.py +++ b/src/zep_cloud/types/task_page.py @@ -8,9 +8,22 @@ class TaskPage(UniversalBaseModel): - items: typing.Optional[typing.List[Task]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[Task]] = pydantic.Field(default=None) + """ + The tasks on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of matching tasks, counted at the time of this response. + It does not indicate whether more pages remain. + """ 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/task_progress.py b/src/zep_cloud/types/task_progress.py index 460a7af3..5aa94854 100644 --- a/src/zep_cloud/types/task_progress.py +++ b/src/zep_cloud/types/task_progress.py @@ -7,7 +7,10 @@ class TaskProgress(UniversalBaseModel): - stage: typing.Optional[str] = None + stage: typing.Optional[str] = pydantic.Field(default=None) + """ + The most recent processing stage reported by the worker handling the task. + """ 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/thread.py b/src/zep_cloud/types/thread.py index d7f0008e..5a4ab0bf 100644 --- a/src/zep_cloud/types/thread.py +++ b/src/zep_cloud/types/thread.py @@ -9,13 +9,35 @@ class Thread(UniversalBaseModel): - created_at: typing.Optional[str] = None - graph_uuid: typing.Optional[str] = None - thread_id: typing.Optional[str] = None - updated_at: typing.Optional[str] = None - user_uuid: typing.Optional[str] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the thread was created. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the owning user's graph. + """ + + thread_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned identifier of the thread. + """ + + updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the thread was last updated. + """ + + user_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the user the thread belongs to. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the thread."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/thread_context_response.py b/src/zep_cloud/types/thread_context_response.py index 48d8132c..b36725f6 100644 --- a/src/zep_cloud/types/thread_context_response.py +++ b/src/zep_cloud/types/thread_context_response.py @@ -7,7 +7,12 @@ class ThreadContextResponse(UniversalBaseModel): - context: typing.Optional[str] = None + context: typing.Optional[str] = pydantic.Field(default=None) + """ + The context block containing relevant facts, entities, and messages or + episodes from the user's graph, meant to be placed in the system prompt on + every turn. + """ 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/thread_delete_result.py b/src/zep_cloud/types/thread_delete_result.py index 28e377ea..549f5403 100644 --- a/src/zep_cloud/types/thread_delete_result.py +++ b/src/zep_cloud/types/thread_delete_result.py @@ -8,7 +8,10 @@ class ThreadDeleteResult(UniversalBaseModel): - task: typing.Optional[Task] = None + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The task tracking the thread's asynchronous deletion. + """ 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/thread_page.py b/src/zep_cloud/types/thread_page.py index 4ca285d2..3c83506b 100644 --- a/src/zep_cloud/types/thread_page.py +++ b/src/zep_cloud/types/thread_page.py @@ -8,9 +8,22 @@ class ThreadPage(UniversalBaseModel): - items: typing.Optional[typing.List[Thread]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[Thread]] = pydantic.Field(default=None) + """ + The threads on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of matching threads, counted at the time of this + response. It does not indicate whether more pages remain. + """ 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/thread_summary.py b/src/zep_cloud/types/thread_summary.py index 92be1c90..e43ac320 100644 --- a/src/zep_cloud/types/thread_summary.py +++ b/src/zep_cloud/types/thread_summary.py @@ -9,20 +9,49 @@ class ThreadSummary(UniversalBaseModel): - created_at: typing.Optional[str] = None - last_summarized_at: typing.Optional[str] = None - last_summarized_episode_valid_at: typing.Optional[str] = None - relevance: typing.Optional[float] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the summary was first created. + """ + + last_summarized_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The wall-clock time of the most recent summary update. + """ + + last_summarized_episode_valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The latest episode reference time covered by the most recent summary + update. + """ + + relevance: typing.Optional[float] = pydantic.Field(default=None) + """ + A cross-encoder-derived relevance score, present only when the + cross-encoder reranker scored this result; like score, it is omitted from + plain list results. + """ + score: typing.Optional[float] = pydantic.Field(default=None) """ - 8.7 puts score on every search result and relevance on the ones the - cross-encoder scored. Pointers keep both off the listing (8.4). + A score accompanies every search result; it is omitted when the summary + appears in a plain list rather than a search result. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + The generated summary text for the thread. + """ + + thread_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the thread this summary belongs to. """ - summary: typing.Optional[str] = None - thread_uuid: typing.Optional[str] = None uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the thread summary."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/thread_summary_page.py b/src/zep_cloud/types/thread_summary_page.py index ccc49990..161421d4 100644 --- a/src/zep_cloud/types/thread_summary_page.py +++ b/src/zep_cloud/types/thread_summary_page.py @@ -8,9 +8,22 @@ class ThreadSummaryPage(UniversalBaseModel): - items: typing.Optional[typing.List[ThreadSummary]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[ThreadSummary]] = pydantic.Field(default=None) + """ + The thread summaries on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Omitted for this collection; use next_cursor to detect the end of + pagination. + """ 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/user.py b/src/zep_cloud/types/user.py index 59fc484e..80af802d 100644 --- a/src/zep_cloud/types/user.py +++ b/src/zep_cloud/types/user.py @@ -9,17 +9,57 @@ class User(UniversalBaseModel): - created_at: typing.Optional[str] = None - disable_default_ontology: typing.Optional[bool] = None - email: typing.Optional[str] = None - first_name: typing.Optional[str] = None - graph_uuid: typing.Optional[str] = None - last_name: typing.Optional[str] = None - metadata: typing.Optional[typing.Dict[str, typing.Any]] = None - time_zone: typing.Optional[str] = None - user_id: typing.Optional[str] = None + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the user was created. + """ + + disable_default_ontology: typing.Optional[bool] = pydantic.Field(default=None) + """ + When true, disables the use of the default fallback ontology for the + user's graph. + """ + + email: typing.Optional[str] = pydantic.Field(default=None) + """ + The email address of the user. + """ + + first_name: typing.Optional[str] = pydantic.Field(default=None) + """ + The first name of the user. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the user's graph, populated when the user is + created. + """ + + last_name: typing.Optional[str] = pydantic.Field(default=None) + """ + The last name of the user. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Arbitrary key-value metadata attached to the user. + """ + + time_zone: typing.Optional[str] = pydantic.Field(default=None) + """ + The user's IANA time zone, used to localize dates in generated context. + """ + + user_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned identifier of the user. + """ + uuid_: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the user."), ] = None if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/user_delete_result.py b/src/zep_cloud/types/user_delete_result.py index 4178a7ab..806b842e 100644 --- a/src/zep_cloud/types/user_delete_result.py +++ b/src/zep_cloud/types/user_delete_result.py @@ -8,7 +8,11 @@ class UserDeleteResult(UniversalBaseModel): - task: typing.Optional[Task] = None + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The task tracking the user's asynchronous deletion. Once it completes, the + user's threads, messages, and graph are removed as well. + """ 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/user_group.py b/src/zep_cloud/types/user_group.py new file mode 100644 index 00000000..4d2665ea --- /dev/null +++ b/src/zep_cloud/types/user_group.py @@ -0,0 +1,49 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class UserGroup(UniversalBaseModel): + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the user group was created. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + A human-readable description of the user group. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the user group. + """ + + updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the user group was last updated. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the user group."), + ] = None + version: typing.Optional[int] = pydantic.Field(default=None) + """ + The user group's version, used for optimistic concurrency on updates. + """ + + 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/user_group_page.py b/src/zep_cloud/types/user_group_page.py new file mode 100644 index 00000000..eb02efb1 --- /dev/null +++ b/src/zep_cloud/types/user_group_page.py @@ -0,0 +1,35 @@ +# 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 .user_group import UserGroup + + +class UserGroupPage(UniversalBaseModel): + items: typing.Optional[typing.List[UserGroup]] = pydantic.Field(default=None) + """ + The user groups on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of matching user groups, counted at the time of this + response. It does not indicate whether more pages remain. + """ + + 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/user_instruction.py b/src/zep_cloud/types/user_instruction.py new file mode 100644 index 00000000..42b087a5 --- /dev/null +++ b/src/zep_cloud/types/user_instruction.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 UserInstruction(UniversalBaseModel): + name: str = pydantic.Field() + """ + logical key for identifying the instruction + """ + + text: str = pydantic.Field() + """ + the actual instruction text + """ + + 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/user_page.py b/src/zep_cloud/types/user_page.py index 4c373c00..146ccaf5 100644 --- a/src/zep_cloud/types/user_page.py +++ b/src/zep_cloud/types/user_page.py @@ -8,9 +8,22 @@ class UserPage(UniversalBaseModel): - items: typing.Optional[typing.List[User]] = None - next_cursor: typing.Optional[str] = None - total_size: typing.Optional[int] = None + items: typing.Optional[typing.List[User]] = pydantic.Field(default=None) + """ + The users on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of matching users, counted at the time of this response. + It does not indicate whether more pages remain. + """ 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/user_summary_instructions.py b/src/zep_cloud/types/user_summary_instructions.py index 7d188ae9..bb02a6e4 100644 --- a/src/zep_cloud/types/user_summary_instructions.py +++ b/src/zep_cloud/types/user_summary_instructions.py @@ -4,11 +4,21 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .user_instruction import UserInstruction class UserSummaryInstructions(UniversalBaseModel): - inherited: typing.Optional[bool] = None - instructions: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = None + inherited: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether this is the project's default value rather than an override set on + this graph. + """ + + instructions: typing.Optional[typing.List[UserInstruction]] = pydantic.Field(default=None) + """ + The custom instructions used when generating a user's summary at this + scope, each with a name and text. + """ 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/v4batch_item_input_data_type.py b/src/zep_cloud/types/v4batch_item_input_data_type.py new file mode 100644 index 00000000..8a38865e --- /dev/null +++ b/src/zep_cloud/types/v4batch_item_input_data_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V4BatchItemInputDataType = typing.Union[typing.Literal["text", "json", "message"], typing.Any] diff --git a/src/zep_cloud/types/v4batch_item_input_role.py b/src/zep_cloud/types/v4batch_item_input_role.py new file mode 100644 index 00000000..938d52b6 --- /dev/null +++ b/src/zep_cloud/types/v4batch_item_input_role.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V4BatchItemInputRole = typing.Union[typing.Literal["system", "assistant", "user", "function", "tool"], typing.Any] diff --git a/src/zep_cloud/types/v4batch_item_input_type.py b/src/zep_cloud/types/v4batch_item_input_type.py new file mode 100644 index 00000000..32203c4c --- /dev/null +++ b/src/zep_cloud/types/v4batch_item_input_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V4BatchItemInputType = typing.Union[typing.Literal["graph_episode", "thread_message"], typing.Any] diff --git a/src/zep_cloud/types/v4search_request_reranker.py b/src/zep_cloud/types/v4search_request_reranker.py new file mode 100644 index 00000000..e4733141 --- /dev/null +++ b/src/zep_cloud/types/v4search_request_reranker.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +V4SearchRequestReranker = typing.Union[ + typing.Literal["rrf", "mmr", "node_distance", "episode_mentions", "cross_encoder"], typing.Any +] diff --git a/src/zep_cloud/user/client.py b/src/zep_cloud/user/client.py index 99b5c97c..1ade51d7 100644 --- a/src/zep_cloud/user/client.py +++ b/src/zep_cloud/user/client.py @@ -8,6 +8,7 @@ from ..types.node import Node from ..types.user import User from ..types.user_delete_result import UserDeleteResult +from ..types.user_instruction import UserInstruction from ..types.user_page import UserPage from ..types.user_summary_instructions import UserSummaryInstructions from .raw_client import AsyncRawUserClient, RawUserClient @@ -48,18 +49,25 @@ def create( Parameters ---------- disable_default_ontology : typing.Optional[bool] + When true, disables the default ontology for the user's graph. email : typing.Optional[str] + The email address of the user. first_name : typing.Optional[str] + The user's first name. last_name : typing.Optional[str] + The user's last name. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the user. time_zone : typing.Optional[str] + The user's IANA time zone. user_id : typing.Optional[str] + An optional developer-assigned identifier for the user. idempotency_key : typing.Optional[str] @@ -120,6 +128,7 @@ def list( asc or desc search : typing.Optional[str] + Filters results to users whose user ID, email, or name contains this text. idempotency_key : typing.Optional[str] @@ -173,10 +182,16 @@ def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -292,21 +307,22 @@ def update( User UUID disable_default_ontology : typing.Optional[bool] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + When true, disables the default ontology for the user's graph. email : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The email address of the user. first_name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's first name. last_name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's last name. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the user; a key set to null is removed. time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's IANA time zone. idempotency_key : typing.Optional[str] @@ -407,7 +423,7 @@ def set_summary_instructions( user_uuid: str, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> UserSummaryInstructions: @@ -418,8 +434,12 @@ def set_summary_instructions( User UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[UserInstruction]] + The custom instructions used when generating a user's summary at this + scope, each with a name and text. idempotency_key : typing.Optional[str] @@ -484,18 +504,25 @@ async def create( Parameters ---------- disable_default_ontology : typing.Optional[bool] + When true, disables the default ontology for the user's graph. email : typing.Optional[str] + The email address of the user. first_name : typing.Optional[str] + The user's first name. last_name : typing.Optional[str] + The user's last name. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the user. time_zone : typing.Optional[str] + The user's IANA time zone. user_id : typing.Optional[str] + An optional developer-assigned identifier for the user. idempotency_key : typing.Optional[str] @@ -564,6 +591,7 @@ async def list( asc or desc search : typing.Optional[str] + Filters results to users whose user ID, email, or name contains this text. idempotency_key : typing.Optional[str] @@ -626,10 +654,16 @@ async def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -771,21 +805,22 @@ async def update( User UUID disable_default_ontology : typing.Optional[bool] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + When true, disables the default ontology for the user's graph. email : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The email address of the user. first_name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's first name. last_name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's last name. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the user; a key set to null is removed. time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's IANA time zone. idempotency_key : typing.Optional[str] @@ -910,7 +945,7 @@ async def set_summary_instructions( user_uuid: str, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> UserSummaryInstructions: @@ -921,8 +956,12 @@ async def set_summary_instructions( User UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[UserInstruction]] + The custom instructions used when generating a user's summary at this + scope, each with a name and text. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/user/raw_client.py b/src/zep_cloud/user/raw_client.py index a6012387..e7c5d1e0 100644 --- a/src/zep_cloud/user/raw_client.py +++ b/src/zep_cloud/user/raw_client.py @@ -11,13 +11,17 @@ from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..types.api_error import ApiError as types_api_error_ApiError from ..types.node import Node from ..types.user import User from ..types.user_delete_result import UserDeleteResult +from ..types.user_instruction import UserInstruction from ..types.user_page import UserPage from ..types.user_summary_instructions import UserSummaryInstructions from pydantic import ValidationError @@ -47,18 +51,25 @@ def create( Parameters ---------- disable_default_ontology : typing.Optional[bool] + When true, disables the default ontology for the user's graph. email : typing.Optional[str] + The email address of the user. first_name : typing.Optional[str] + The user's first name. last_name : typing.Optional[str] + The user's last name. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the user. time_zone : typing.Optional[str] + The user's IANA time zone. user_id : typing.Optional[str] + An optional developer-assigned identifier for the user. idempotency_key : typing.Optional[str] @@ -132,6 +143,17 @@ def create( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -172,6 +194,7 @@ def list( asc or desc search : typing.Optional[str] + Filters results to users whose user ID, email, or name contains this text. idempotency_key : typing.Optional[str] @@ -283,10 +306,16 @@ def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -519,6 +548,17 @@ def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -552,21 +592,22 @@ def update( User UUID disable_default_ontology : typing.Optional[bool] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + When true, disables the default ontology for the user's graph. email : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The email address of the user. first_name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's first name. last_name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's last name. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the user; a key set to null is removed. time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's IANA time zone. idempotency_key : typing.Optional[str] @@ -639,6 +680,17 @@ def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -706,6 +758,17 @@ def get_node( ), ), ) + 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), @@ -717,6 +780,17 @@ def get_node( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -813,7 +887,7 @@ def set_summary_instructions( user_uuid: str, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[UserSummaryInstructions]: @@ -824,8 +898,12 @@ def set_summary_instructions( User UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[UserInstruction]] + The custom instructions used when generating a user's summary at this + scope, each with a name and text. idempotency_key : typing.Optional[str] @@ -842,7 +920,9 @@ def set_summary_instructions( method="PUT", json={ "inherited": inherited, - "instructions": instructions, + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[UserInstruction], direction="write" + ), }, headers={ "content-type": "application/json", @@ -929,18 +1009,25 @@ async def create( Parameters ---------- disable_default_ontology : typing.Optional[bool] + When true, disables the default ontology for the user's graph. email : typing.Optional[str] + The email address of the user. first_name : typing.Optional[str] + The user's first name. last_name : typing.Optional[str] + The user's last name. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to store on the user. time_zone : typing.Optional[str] + The user's IANA time zone. user_id : typing.Optional[str] + An optional developer-assigned identifier for the user. idempotency_key : typing.Optional[str] @@ -1014,6 +1101,17 @@ async def create( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1054,6 +1152,7 @@ async def list( asc or desc search : typing.Optional[str] + Filters results to users whose user ID, email, or name contains this text. idempotency_key : typing.Optional[str] @@ -1168,10 +1267,16 @@ async def lookup( Parameters ---------- graph_id : typing.Optional[str] + The developer-assigned graph ID to resolve to a UUID. Mutually exclusive + with user_id and thread_id. thread_id : typing.Optional[str] + The developer-assigned thread ID to resolve to a UUID. Mutually exclusive + with user_id and graph_id. user_id : typing.Optional[str] + The developer-assigned user ID to resolve to a UUID. Mutually exclusive + with thread_id and graph_id. idempotency_key : typing.Optional[str] @@ -1406,6 +1511,17 @@ async def delete( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1439,21 +1555,22 @@ async def update( User UUID disable_default_ontology : typing.Optional[bool] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + When true, disables the default ontology for the user's graph. email : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The email address of the user. first_name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's first name. last_name : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's last name. metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata to merge onto the user; a key set to null is removed. time_zone : typing.Optional[str] - Omit to leave unchanged, send JSON null to clear, or send a value to set. + The user's IANA time zone. idempotency_key : typing.Optional[str] @@ -1526,6 +1643,17 @@ async def update( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1593,6 +1721,17 @@ async def get_node( ), ), ) + 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), @@ -1604,6 +1743,17 @@ async def get_node( ), ), ) + if _response.status_code == 409: + raise ConflictError( + 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( @@ -1700,7 +1850,7 @@ async def set_summary_instructions( user_uuid: str, *, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT, + instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[UserSummaryInstructions]: @@ -1711,8 +1861,12 @@ async def set_summary_instructions( User UUID inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. - instructions : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] + instructions : typing.Optional[typing.Sequence[UserInstruction]] + The custom instructions used when generating a user's summary at this + scope, each with a name and text. idempotency_key : typing.Optional[str] @@ -1729,7 +1883,9 @@ async def set_summary_instructions( method="PUT", json={ "inherited": inherited, - "instructions": instructions, + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[UserInstruction], direction="write" + ), }, headers={ "content-type": "application/json", diff --git a/src/zep_cloud/user_group/__init__.py b/src/zep_cloud/user_group/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/user_group/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/user_group/client.py b/src/zep_cloud/user_group/client.py new file mode 100644 index 00000000..f9d01e71 --- /dev/null +++ b/src/zep_cloud/user_group/client.py @@ -0,0 +1,1228 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.pagination import AsyncPager, SyncPager +from ..core.request_options import RequestOptions +from ..types.membership_mutation_result import MembershipMutationResult +from ..types.user import User +from ..types.user_group import UserGroup +from ..types.user_group_page import UserGroupPage +from ..types.user_page import UserPage +from .raw_client import AsyncRawUserGroupClient, RawUserGroupClient + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class UserGroupClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawUserGroupClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawUserGroupClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawUserGroupClient + """ + return self._raw_client + + def create( + self, + *, + name: str, + description: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> UserGroup: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + name : str + The name of the user group. + + description : typing.Optional[str] + A description of the user group. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + UserGroup + Created + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.user_group.create( + name="name", + ) + """ + _response = self._raw_client.create( + name=name, description=description, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[UserGroup, UserGroupPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[UserGroup, UserGroupPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.user_group.list( + limit=1, + cursor="cursor", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + limit=limit, cursor=cursor, search=search, idempotency_key=idempotency_key, request_options=request_options + ) + + def get(self, group_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> UserGroup: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + UserGroup + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.user_group.get( + group_uuid="group_uuid", + ) + """ + _response = self._raw_client.get(group_uuid, request_options=request_options) + return _response.data + + def delete( + self, + group_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.user_group.delete( + group_uuid="group_uuid", + ) + """ + _response = self._raw_client.delete( + group_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def update( + self, + group_uuid: str, + *, + description: typing.Optional[str] = OMIT, + expected_version: typing.Optional[int] = OMIT, + name: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> UserGroup: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + description : typing.Optional[str] + A description of the user group. + + expected_version : typing.Optional[int] + The user group's current version, used to detect concurrent updates. + + name : typing.Optional[str] + The name of the user group. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + UserGroup + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.user_group.update( + group_uuid="group_uuid", + ) + """ + _response = self._raw_client.update( + group_uuid, + description=description, + expected_version=expected_version, + name=name, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def list_member_candidates( + self, + group_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[User, UserPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[User, UserPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.user_group.list_member_candidates( + group_uuid="group_uuid", + limit=1, + cursor="cursor", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list_member_candidates( + group_uuid, + limit=limit, + cursor=cursor, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + + def add_members( + self, + group_uuid: str, + *, + user_uuids: typing.Sequence[str], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> MembershipMutationResult: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuids : typing.Sequence[str] + The UUIDs of the users to add or remove. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + MembershipMutationResult + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.user_group.add_members( + group_uuid="group_uuid", + user_uuids=["user_uuids"], + ) + """ + _response = self._raw_client.add_members( + group_uuid, user_uuids=user_uuids, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def list_members( + self, + group_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[User, UserPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[User, UserPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.user_group.list_members( + group_uuid="group_uuid", + limit=1, + cursor="cursor", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list_members( + group_uuid, + limit=limit, + cursor=cursor, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + + def remove_members( + self, + group_uuid: str, + *, + user_uuids: typing.Sequence[str], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> MembershipMutationResult: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuids : typing.Sequence[str] + The UUIDs of the users to add or remove. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + MembershipMutationResult + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.user_group.remove_members( + group_uuid="group_uuid", + user_uuids=["user_uuids"], + ) + """ + _response = self._raw_client.remove_members( + group_uuid, user_uuids=user_uuids, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def remove_member( + self, + group_uuid: str, + user_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuid : str + User UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.user_group.remove_member( + group_uuid="group_uuid", + user_uuid="user_uuid", + ) + """ + _response = self._raw_client.remove_member( + group_uuid, user_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def list_for_user( + self, + user_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[UserGroup, UserGroupPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + user_uuid : str + User UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[UserGroup, UserGroupPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.user_group.list_for_user( + user_uuid="user_uuid", + limit=1, + cursor="cursor", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list_for_user(user_uuid, limit=limit, cursor=cursor, request_options=request_options) + + +class AsyncUserGroupClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawUserGroupClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawUserGroupClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawUserGroupClient + """ + return self._raw_client + + async def create( + self, + *, + name: str, + description: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> UserGroup: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + name : str + The name of the user group. + + description : typing.Optional[str] + A description of the user group. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + UserGroup + Created + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.user_group.create( + name="name", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + name=name, description=description, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[UserGroup, UserGroupPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[UserGroup, UserGroupPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.user_group.list( + limit=1, + cursor="cursor", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + limit=limit, cursor=cursor, search=search, idempotency_key=idempotency_key, request_options=request_options + ) + + async def get(self, group_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> UserGroup: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + UserGroup + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.user_group.get( + group_uuid="group_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(group_uuid, request_options=request_options) + return _response.data + + async def delete( + self, + group_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.user_group.delete( + group_uuid="group_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete( + group_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def update( + self, + group_uuid: str, + *, + description: typing.Optional[str] = OMIT, + expected_version: typing.Optional[int] = OMIT, + name: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> UserGroup: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + description : typing.Optional[str] + A description of the user group. + + expected_version : typing.Optional[int] + The user group's current version, used to detect concurrent updates. + + name : typing.Optional[str] + The name of the user group. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + UserGroup + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.user_group.update( + group_uuid="group_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + group_uuid, + description=description, + expected_version=expected_version, + name=name, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def list_member_candidates( + self, + group_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[User, UserPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[User, UserPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.user_group.list_member_candidates( + group_uuid="group_uuid", + limit=1, + cursor="cursor", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list_member_candidates( + group_uuid, + limit=limit, + cursor=cursor, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + + async def add_members( + self, + group_uuid: str, + *, + user_uuids: typing.Sequence[str], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> MembershipMutationResult: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuids : typing.Sequence[str] + The UUIDs of the users to add or remove. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + MembershipMutationResult + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.user_group.add_members( + group_uuid="group_uuid", + user_uuids=["user_uuids"], + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.add_members( + group_uuid, user_uuids=user_uuids, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def list_members( + self, + group_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[User, UserPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[User, UserPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.user_group.list_members( + group_uuid="group_uuid", + limit=1, + cursor="cursor", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list_members( + group_uuid, + limit=limit, + cursor=cursor, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + + async def remove_members( + self, + group_uuid: str, + *, + user_uuids: typing.Sequence[str], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> MembershipMutationResult: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuids : typing.Sequence[str] + The UUIDs of the users to add or remove. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + MembershipMutationResult + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.user_group.remove_members( + group_uuid="group_uuid", + user_uuids=["user_uuids"], + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.remove_members( + group_uuid, user_uuids=user_uuids, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def remove_member( + self, + group_uuid: str, + user_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuid : str + User UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.user_group.remove_member( + group_uuid="group_uuid", + user_uuid="user_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.remove_member( + group_uuid, user_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def list_for_user( + self, + user_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[UserGroup, UserGroupPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + user_uuid : str + User UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[UserGroup, UserGroupPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.user_group.list_for_user( + user_uuid="user_uuid", + limit=1, + cursor="cursor", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list_for_user( + user_uuid, limit=limit, cursor=cursor, request_options=request_options + ) diff --git a/src/zep_cloud/user_group/raw_client.py b/src/zep_cloud/user_group/raw_client.py new file mode 100644 index 00000000..518b06ca --- /dev/null +++ b/src/zep_cloud/user_group/raw_client.py @@ -0,0 +1,2690 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError as core_api_error_ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import jsonable_encoder +from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.api_error import ApiError as types_api_error_ApiError +from ..types.membership_mutation_result import MembershipMutationResult +from ..types.user import User +from ..types.user_group import UserGroup +from ..types.user_group_page import UserGroupPage +from ..types.user_page import UserPage +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawUserGroupClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def create( + self, + *, + name: str, + description: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[UserGroup]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + name : str + The name of the user group. + + description : typing.Optional[str] + A description of the user group. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[UserGroup] + Created + """ + _response = self._client_wrapper.httpx_client.request( + "user-groups", + method="POST", + json={ + "description": description, + "name": name, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + UserGroup, + parse_obj_as( + type_=UserGroup, # 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[UserGroup, UserGroupPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[UserGroup, UserGroupPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "user-groups/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "search": search, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + UserGroupPage, + parse_obj_as( + type_=UserGroupPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + limit=limit, + cursor=_parsed_next, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + 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 == 401: + raise UnauthorizedError( + 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(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, group_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[UserGroup]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[UserGroup] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + UserGroup, + parse_obj_as( + type_=UserGroup, # 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 == 401: + raise UnauthorizedError( + 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(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def delete( + self, + group_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[None]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + group_uuid: str, + *, + description: typing.Optional[str] = OMIT, + expected_version: typing.Optional[int] = OMIT, + name: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[UserGroup]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + description : typing.Optional[str] + A description of the user group. + + expected_version : typing.Optional[int] + The user group's current version, used to detect concurrent updates. + + name : typing.Optional[str] + The name of the user group. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[UserGroup] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}", + method="PATCH", + json={ + "description": description, + "expected_version": expected_version, + "name": name, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + UserGroup, + parse_obj_as( + type_=UserGroup, # 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list_member_candidates( + self, + group_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[User, UserPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[User, UserPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/member-candidates/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "search": search, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + UserPage, + parse_obj_as( + type_=UserPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list_member_candidates( + group_uuid, + limit=limit, + cursor=_parsed_next, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def add_members( + self, + group_uuid: str, + *, + user_uuids: typing.Sequence[str], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[MembershipMutationResult]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuids : typing.Sequence[str] + The UUIDs of the users to add or remove. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[MembershipMutationResult] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/members", + method="POST", + json={ + "user_uuids": user_uuids, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + MembershipMutationResult, + parse_obj_as( + type_=MembershipMutationResult, # 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list_members( + self, + group_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[User, UserPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[User, UserPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/members/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "search": search, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + UserPage, + parse_obj_as( + type_=UserPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list_members( + group_uuid, + limit=limit, + cursor=_parsed_next, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + 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 == 401: + raise UnauthorizedError( + 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(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def remove_members( + self, + group_uuid: str, + *, + user_uuids: typing.Sequence[str], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[MembershipMutationResult]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuids : typing.Sequence[str] + The UUIDs of the users to add or remove. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[MembershipMutationResult] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/members/remove", + method="POST", + json={ + "user_uuids": user_uuids, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + MembershipMutationResult, + parse_obj_as( + type_=MembershipMutationResult, # 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def remove_member( + self, + group_uuid: str, + user_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[None]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuid : str + User UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/members/{jsonable_encoder(user_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list_for_user( + self, + user_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[UserGroup, UserGroupPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + user_uuid : str + User UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[UserGroup, UserGroupPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"users/{jsonable_encoder(user_uuid)}/user-groups", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + UserGroupPage, + parse_obj_as( + type_=UserGroupPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list_for_user( + user_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawUserGroupClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def create( + self, + *, + name: str, + description: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[UserGroup]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + name : str + The name of the user group. + + description : typing.Optional[str] + A description of the user group. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[UserGroup] + Created + """ + _response = await self._client_wrapper.httpx_client.request( + "user-groups", + method="POST", + json={ + "description": description, + "name": name, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + UserGroup, + parse_obj_as( + type_=UserGroup, # 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[UserGroup, UserGroupPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[UserGroup, UserGroupPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + "user-groups/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "search": search, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + UserGroupPage, + parse_obj_as( + type_=UserGroupPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + limit=limit, + cursor=_parsed_next, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + 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 == 401: + raise UnauthorizedError( + 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(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, group_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[UserGroup]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[UserGroup] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + UserGroup, + parse_obj_as( + type_=UserGroup, # 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 == 401: + raise UnauthorizedError( + 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(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def delete( + self, + group_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[None]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + group_uuid: str, + *, + description: typing.Optional[str] = OMIT, + expected_version: typing.Optional[int] = OMIT, + name: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[UserGroup]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + description : typing.Optional[str] + A description of the user group. + + expected_version : typing.Optional[int] + The user group's current version, used to detect concurrent updates. + + name : typing.Optional[str] + The name of the user group. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[UserGroup] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}", + method="PATCH", + json={ + "description": description, + "expected_version": expected_version, + "name": name, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + UserGroup, + parse_obj_as( + type_=UserGroup, # 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list_member_candidates( + self, + group_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[User, UserPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[User, UserPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/member-candidates/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "search": search, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + UserPage, + parse_obj_as( + type_=UserPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list_member_candidates( + group_uuid, + limit=limit, + cursor=_parsed_next, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def add_members( + self, + group_uuid: str, + *, + user_uuids: typing.Sequence[str], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[MembershipMutationResult]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuids : typing.Sequence[str] + The UUIDs of the users to add or remove. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[MembershipMutationResult] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/members", + method="POST", + json={ + "user_uuids": user_uuids, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + MembershipMutationResult, + parse_obj_as( + type_=MembershipMutationResult, # 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list_members( + self, + group_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + search: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[User, UserPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + search : typing.Optional[str] + Filters results to items matching this free-text search term. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[User, UserPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/members/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "search": search, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + UserPage, + parse_obj_as( + type_=UserPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list_members( + group_uuid, + limit=limit, + cursor=_parsed_next, + search=search, + idempotency_key=idempotency_key, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + 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 == 401: + raise UnauthorizedError( + 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(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def remove_members( + self, + group_uuid: str, + *, + user_uuids: typing.Sequence[str], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[MembershipMutationResult]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuids : typing.Sequence[str] + The UUIDs of the users to add or remove. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[MembershipMutationResult] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/members/remove", + method="POST", + json={ + "user_uuids": user_uuids, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + MembershipMutationResult, + parse_obj_as( + type_=MembershipMutationResult, # 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def remove_member( + self, + group_uuid: str, + user_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[None]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + group_uuid : str + User group UUID + + user_uuid : str + User UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"user-groups/{jsonable_encoder(group_uuid)}/members/{jsonable_encoder(user_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list_for_user( + self, + user_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[UserGroup, UserGroupPage]: + """ + Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. + + Parameters + ---------- + user_uuid : str + User UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[UserGroup, UserGroupPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"users/{jsonable_encoder(user_uuid)}/user-groups", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + UserGroupPage, + parse_obj_as( + type_=UserGroupPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list_for_user( + user_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + 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 == 401: + raise UnauthorizedError( + 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 == 409: + raise ConflictError( + 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 + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + )