From b89ef60b91e019c3cb4422af1e3cc216804ccb20 Mon Sep 17 00:00:00 2001 From: William FH <13333726+hinthornw@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:29:59 -0800 Subject: [PATCH] feat(sdk-py): add extract parameter to threads.search() (#6880) ## Summary - Adds `extract` parameter to `threads.search()` in both async and sync clients - Adds `extracted` field to the `Thread` TypedDict response type - The `extract` parameter accepts a `dict[str, str]` mapping aliases to JSONB paths (e.g., `{"last_msg": "values.messages[-1]"}`) - Depends on server-side support in https://github.com/langchain-ai/langgraph-api/pull/2609 ## Test plan - [ ] Verify types are correct via lint/format (already passing) - [ ] Integration test against server with extract feature enabled Release Notes: Add `extract` parameter to `threads.search()` for extracting nested values from thread data during search. Co-authored-by: Claude Opus 4.6 --- libs/sdk-py/langgraph_sdk/_async/threads.py | 10 ++++++++++ libs/sdk-py/langgraph_sdk/_sync/threads.py | 13 +++++++++++++ libs/sdk-py/langgraph_sdk/schema.py | 4 +++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/libs/sdk-py/langgraph_sdk/_async/threads.py b/libs/sdk-py/langgraph_sdk/_async/threads.py index a25c21ba5..a4439c22d 100644 --- a/libs/sdk-py/langgraph_sdk/_async/threads.py +++ b/libs/sdk-py/langgraph_sdk/_async/threads.py @@ -260,6 +260,7 @@ class ThreadsClient: sort_by: ThreadSortBy | None = None, sort_order: SortOrder | None = None, select: list[ThreadSelectField] | None = None, + extract: dict[str, str] | None = None, headers: Mapping[str, str] | None = None, params: QueryParamTypes | None = None, ) -> list[Thread]: @@ -275,6 +276,13 @@ class ThreadsClient: offset: Offset in threads table to start search from. sort_by: Sort by field. sort_order: Sort order. + select: List of fields to include in the response. + extract: Dictionary mapping aliases to JSONB paths to extract + from thread data. Paths use dot notation for nested keys and + bracket notation for array indices (e.g., + `{"last_msg": "values.messages[-1]"}`). Extracted values are + returned in an `extracted` field on each thread. Maximum 10 + paths per request. headers: Optional custom headers to include with the request. params: Optional query parameters to include with the request. @@ -312,6 +320,8 @@ class ThreadsClient: payload["sort_order"] = sort_order if select: payload["select"] = select + if extract: + payload["extract"] = extract return await self.http.post( "/threads/search", json=payload, diff --git a/libs/sdk-py/langgraph_sdk/_sync/threads.py b/libs/sdk-py/langgraph_sdk/_sync/threads.py index 172faf43b..b1ebf6b59 100644 --- a/libs/sdk-py/langgraph_sdk/_sync/threads.py +++ b/libs/sdk-py/langgraph_sdk/_sync/threads.py @@ -255,6 +255,7 @@ class SyncThreadsClient: sort_by: ThreadSortBy | None = None, sort_order: SortOrder | None = None, select: list[ThreadSelectField] | None = None, + extract: dict[str, str] | None = None, headers: Mapping[str, str] | None = None, params: QueryParamTypes | None = None, ) -> list[Thread]: @@ -268,7 +269,17 @@ class SyncThreadsClient: Must be one of 'idle', 'busy', 'interrupted' or 'error'. limit: Limit on number of threads to return. offset: Offset in threads table to start search from. + sort_by: Sort by field. + sort_order: Sort order. + select: List of fields to include in the response. + extract: Dictionary mapping aliases to JSONB paths to extract + from thread data. Paths use dot notation for nested keys and + bracket notation for array indices (e.g., + `{"last_msg": "values.messages[-1]"}`). Extracted values are + returned in an `extracted` field on each thread. Maximum 10 + paths per request. headers: Optional custom headers to include with the request. + params: Optional query parameters to include with the request. Returns: List of the threads matching the search parameters. @@ -303,6 +314,8 @@ class SyncThreadsClient: payload["sort_order"] = sort_order if select: payload["select"] = select + if extract: + payload["extract"] = extract return self.http.post( "/threads/search", json=payload, headers=headers, params=params ) diff --git a/libs/sdk-py/langgraph_sdk/schema.py b/libs/sdk-py/langgraph_sdk/schema.py index 7567f4077..163f13bb7 100644 --- a/libs/sdk-py/langgraph_sdk/schema.py +++ b/libs/sdk-py/langgraph_sdk/schema.py @@ -15,7 +15,7 @@ from typing import ( Union, ) -from typing_extensions import TypedDict +from typing_extensions import NotRequired, TypedDict Json = dict[str, Any] | None """Represents a JSON-like structure, which can be None or a dictionary with string keys and any values.""" @@ -304,6 +304,8 @@ class Thread(TypedDict): """The current state of the thread.""" interrupts: dict[str, list[Interrupt]] """Mapping of task ids to interrupts that were raised in that task.""" + extracted: NotRequired[dict[str, Any]] + """Extracted values from thread data. Only present when `extract` is used in search.""" class ThreadTask(TypedDict):