diff --git a/libs/sdk-js/package.json b/libs/sdk-js/package.json index 3c49f934f..20c32aeac 100644 --- a/libs/sdk-js/package.json +++ b/libs/sdk-js/package.json @@ -1,6 +1,6 @@ { "name": "@langchain/langgraph-sdk", - "version": "0.0.48", + "version": "0.0.49", "description": "Client library for interacting with the LangGraph API", "type": "module", "packageManager": "yarn@1.22.19", diff --git a/libs/sdk-js/src/client.ts b/libs/sdk-js/src/client.ts index 930c419b5..5fd611c47 100644 --- a/libs/sdk-js/src/client.ts +++ b/libs/sdk-js/src/client.ts @@ -1088,12 +1088,28 @@ export class StoreClient extends BaseClient { * @param namespace A list of strings representing the namespace path. * @param key The unique identifier for the item within the namespace. * @param value A dictionary containing the item's data. + * @param options.index Controls search indexing - null (use defaults), false (disable), or list of field paths to index. + * @param options.ttl Optional time-to-live in minutes for the item, or null for no expiration. * @returns Promise + * + * @example + * ```typescript + * await client.store.putItem( + * ["documents", "user123"], + * "item456", + * { title: "My Document", content: "Hello World" }, + * { ttl: 60 } // expires in 60 minutes + * ); + * ``` */ async putItem( namespace: string[], key: string, value: Record, + options?: { + index?: false | string[] | null; + ttl?: number | null; + }, ): Promise { namespace.forEach((label) => { if (label.includes(".")) { @@ -1107,6 +1123,8 @@ export class StoreClient extends BaseClient { namespace, key, value, + index: options?.index, + ttl: options?.ttl, }; return this.fetch("/store/items", { @@ -1120,9 +1138,33 @@ export class StoreClient extends BaseClient { * * @param namespace A list of strings representing the namespace path. * @param key The unique identifier for the item. + * @param options.refreshTtl Whether to refresh the TTL on this read operation. If null, uses the store's default behavior. * @returns Promise + * + * @example + * ```typescript + * const item = await client.store.getItem( + * ["documents", "user123"], + * "item456", + * { refreshTtl: true } + * ); + * console.log(item); + * // { + * // namespace: ["documents", "user123"], + * // key: "item456", + * // value: { title: "My Document", content: "Hello World" }, + * // createdAt: "2024-07-30T12:00:00Z", + * // updatedAt: "2024-07-30T12:00:00Z" + * // } + * ``` */ - async getItem(namespace: string[], key: string): Promise { + async getItem( + namespace: string[], + key: string, + options?: { + refreshTtl?: boolean | null; + }, + ): Promise { namespace.forEach((label) => { if (label.includes(".")) { throw new Error( @@ -1131,8 +1173,17 @@ export class StoreClient extends BaseClient { } }); + const params: Record = { + namespace: namespace.join("."), + key, + }; + + if (options?.refreshTtl !== undefined) { + params.refresh_ttl = options.refreshTtl; + } + const response = await this.fetch("/store/items", { - params: { namespace: namespace.join("."), key }, + params, }); return response @@ -1174,7 +1225,33 @@ export class StoreClient extends BaseClient { * @param options.limit Maximum number of items to return (default is 10). * @param options.offset Number of items to skip before returning results (default is 0). * @param options.query Optional search query. + * @param options.refreshTtl Whether to refresh the TTL on items returned by this search. If null, uses the store's default behavior. * @returns Promise + * + * @example + * ```typescript + * const results = await client.store.searchItems( + * ["documents"], + * { + * filter: { author: "John Doe" }, + * limit: 5, + * refreshTtl: true + * } + * ); + * console.log(results); + * // { + * // items: [ + * // { + * // namespace: ["documents", "user123"], + * // key: "item789", + * // value: { title: "Another Document", author: "John Doe" }, + * // createdAt: "2024-07-30T12:00:00Z", + * // updatedAt: "2024-07-30T12:00:00Z" + * // }, + * // // ... additional items ... + * // ] + * // } + * ``` */ async searchItems( namespacePrefix: string[], @@ -1183,6 +1260,7 @@ export class StoreClient extends BaseClient { limit?: number; offset?: number; query?: string; + refreshTtl?: boolean | null; }, ): Promise { const payload = { @@ -1191,6 +1269,7 @@ export class StoreClient extends BaseClient { limit: options?.limit ?? 10, offset: options?.offset ?? 0, query: options?.query, + refresh_ttl: options?.refreshTtl, }; const response = await this.fetch( diff --git a/libs/sdk-py/langgraph_sdk/client.py b/libs/sdk-py/langgraph_sdk/client.py index 59d37c23e..16898646b 100644 --- a/libs/sdk-py/langgraph_sdk/client.py +++ b/libs/sdk-py/langgraph_sdk/client.py @@ -2129,6 +2129,7 @@ class StoreClient: key: str, value: dict[str, Any], index: Optional[Union[Literal[False], list[str]]] = None, + ttl: Optional[int] = None, ) -> None: """Store or update an item. @@ -2137,6 +2138,7 @@ class StoreClient: key: The unique identifier for the item within the namespace. value: A dictionary containing the item's data. index: Controls search indexing - None (use defaults), False (disable), or list of field paths to index. + ttl: Optional time-to-live in minutes for the item, or None for no expiration. Returns: None @@ -2154,15 +2156,29 @@ class StoreClient: raise ValueError( f"Invalid namespace label '{label}'. Namespace labels cannot contain periods ('.')." ) - payload = {"namespace": namespace, "key": key, "value": value, "index": index} + payload = { + "namespace": namespace, + "key": key, + "value": value, + "index": index, + "ttl": ttl, + } await self.http.put("/store/items", json=payload) - async def get_item(self, namespace: Sequence[str], /, key: str) -> Item: + async def get_item( + self, + namespace: Sequence[str], + /, + key: str, + *, + refresh_ttl: Optional[bool] = None, + ) -> Item: """Retrieve a single item. Args: key: The unique identifier for the item. namespace: Optional list of strings representing the namespace path. + refresh_ttl: Whether to refresh the TTL on this read operation. If None, uses the store's default behavior. Returns: Item: The retrieved item. @@ -2190,9 +2206,10 @@ class StoreClient: raise ValueError( f"Invalid namespace label '{label}'. Namespace labels cannot contain periods ('.')." ) - return await self.http.get( - "/store/items", params={"namespace": ".".join(namespace), "key": key} - ) + params = {"namespace": ".".join(namespace), "key": key} + if refresh_ttl is not None: + params["refresh_ttl"] = refresh_ttl + return await self.http.get("/store/items", params=params) async def delete_item(self, namespace: Sequence[str], /, key: str) -> None: """Delete an item. @@ -2223,6 +2240,7 @@ class StoreClient: limit: int = 10, offset: int = 0, query: Optional[str] = None, + refresh_ttl: Optional[bool] = None, ) -> SearchItemsResponse: """Search for items within a namespace prefix. @@ -2232,6 +2250,7 @@ class StoreClient: limit: Maximum number of items to return (default is 10). offset: Number of items to skip before returning results (default is 0). query: Optional query for natural language search. + refresh_ttl: Whether to refresh the TTL on items returned by this search. If None, uses the store's default behavior. Returns: List[Item]: A list of items matching the search criteria. @@ -2270,6 +2289,7 @@ class StoreClient: "limit": limit, "offset": offset, "query": query, + "refresh_ttl": refresh_ttl, } return await self.http.post("/store/items/search", json=_provided_vals(payload)) @@ -4254,6 +4274,7 @@ class SyncStoreClient: key: str, value: dict[str, Any], index: Optional[Union[Literal[False], list[str]]] = None, + ttl: Optional[int] = None, ) -> None: """Store or update an item. @@ -4262,7 +4283,7 @@ class SyncStoreClient: key: The unique identifier for the item within the namespace. value: A dictionary containing the item's data. index: Controls search indexing - None (use defaults), False (disable), or list of field paths to index. - + ttl: Optional time-to-live in minutes for the item, or None for no expiration. Returns: None @@ -4284,15 +4305,24 @@ class SyncStoreClient: "key": key, "value": value, "index": index, + "ttl": ttl, } self.http.put("/store/items", json=payload) - def get_item(self, namespace: Sequence[str], /, key: str) -> Item: + def get_item( + self, + namespace: Sequence[str], + /, + key: str, + *, + refresh_ttl: Optional[bool] = None, + ) -> Item: """Retrieve a single item. Args: key: The unique identifier for the item. namespace: Optional list of strings representing the namespace path. + refresh_ttl: Whether to refresh the TTL on this read operation. If None, uses the store's default behavior. Returns: Item: The retrieved item. @@ -4321,9 +4351,10 @@ class SyncStoreClient: f"Invalid namespace label '{label}'. Namespace labels cannot contain periods ('.')." ) - return self.http.get( - "/store/items", params={"key": key, "namespace": ".".join(namespace)} - ) + params = {"key": key, "namespace": ".".join(namespace)} + if refresh_ttl is not None: + params["refresh_ttl"] = refresh_ttl + return self.http.get("/store/items", params=params) def delete_item(self, namespace: Sequence[str], /, key: str) -> None: """Delete an item. @@ -4352,6 +4383,7 @@ class SyncStoreClient: limit: int = 10, offset: int = 0, query: Optional[str] = None, + refresh_ttl: Optional[bool] = None, ) -> SearchItemsResponse: """Search for items within a namespace prefix. @@ -4361,6 +4393,7 @@ class SyncStoreClient: limit: Maximum number of items to return (default is 10). offset: Number of items to skip before returning results (default is 0). query: Optional query for natural language search. + refresh_ttl: Whether to refresh the TTL on items returned by this search. If None, uses the store's default behavior. Returns: List[Item]: A list of items matching the search criteria. @@ -4399,6 +4432,7 @@ class SyncStoreClient: "limit": limit, "offset": offset, "query": query, + "refresh_ttl": refresh_ttl, } return self.http.post("/store/items/search", json=_provided_vals(payload)) diff --git a/libs/sdk-py/pyproject.toml b/libs/sdk-py/pyproject.toml index c28b9a5e8..2cdd946da 100644 --- a/libs/sdk-py/pyproject.toml +++ b/libs/sdk-py/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langgraph-sdk" -version = "0.1.54" +version = "0.1.55" description = "SDK for interacting with LangGraph API" authors = [] license = "MIT"