feat(sdk): add bulk_update_state in SDK (#3923)

This commit is contained in:
David Duong
2025-03-19 22:09:53 +01:00
committed by GitHub
4 changed files with 86 additions and 42 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@langchain/langgraph-sdk",
"version": "0.0.59",
"version": "0.0.60",
"description": "Client library for interacting with the LangGraph API",
"type": "module",
"packageManager": "yarn@1.22.19",
+33 -35
View File
@@ -482,15 +482,47 @@ export class ThreadsClient<
* Metadata for the thread.
*/
metadata?: Metadata;
/**
* ID of the thread to create.
*
* If not provided, a random UUID will be generated.
*/
threadId?: string;
/**
* How to handle duplicate creation.
*
* @default "raise"
*/
ifExists?: OnConflictBehavior;
/**
* Graph ID to associate with the thread.
*/
graphId?: string;
/**
* Apply a list of supersteps when creating a thread, each containing a sequence of updates.
*
* Used for copying a thread between deployments.
*/
supersteps?: Array<{
updates: Array<{ values: unknown; command?: Command; asNode: string }>;
}>;
}): Promise<Thread<TStateType>> {
return this.fetch<Thread<TStateType>>(`/threads`, {
method: "POST",
json: {
metadata: payload?.metadata,
metadata: {
...payload?.metadata,
graph_id: payload?.graphId,
},
thread_id: payload?.threadId,
if_exists: payload?.ifExists,
supersteps: payload?.supersteps?.map((s) => ({
updates: s.updates.map((u) => ({
values: u.values,
command: u.command,
as_node: u.asNode,
})),
})),
},
});
}
@@ -639,40 +671,6 @@ export class ThreadsClient<
);
}
/**
* Create a new thread from a batch states.
*/
async bulkUpdateState(
supersteps: Array<{
updates: Array<{ values: unknown; command?: Command; asNode: string }>;
}>,
options?: {
graphId?: string;
threadId?: string;
metadata?: Metadata;
ifExists?: OnConflictBehavior;
},
): Promise<Thread<TStateType>> {
return this.fetch<Thread<TStateType>>("/threads/state/batch", {
method: "POST",
json: {
supersteps: supersteps.map((s) => ({
updates: s.updates.map((u) => ({
values: u.values,
command: u.command,
as_node: u.asNode,
})),
})),
thread_id: options?.threadId,
metadata: {
...options?.metadata,
graph_id: options?.graphId,
},
if_exists: options?.ifExists,
},
});
}
/**
* Patch the metadata of a thread.
*
+51 -5
View File
@@ -839,6 +839,8 @@ class ThreadsClient:
metadata: Json = None,
thread_id: Optional[str] = None,
if_exists: Optional[OnConflictBehavior] = None,
supersteps: Optional[Sequence[dict[str, Sequence[dict[str, Any]]]]] = None,
graph_id: Optional[str] = None,
) -> Thread:
"""Create a new thread.
@@ -848,6 +850,9 @@ class ThreadsClient:
If None, ID will be a randomly generated UUID.
if_exists: How to handle duplicate creation. Defaults to 'raise' under the hood.
Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing thread).
supersteps: Apply a list of supersteps when creating a thread, each containing a sequence of updates.
Each update has `values` or `command` and `as_node`. Used for copying a thread between deployments.
graph_id: Optional graph ID to associate with the thread.
Returns:
Thread: The created thread.
@@ -863,10 +868,28 @@ class ThreadsClient:
payload: Dict[str, Any] = {}
if thread_id:
payload["thread_id"] = thread_id
if metadata:
payload["metadata"] = metadata
if metadata or graph_id:
payload["metadata"] = {
**(metadata or {}),
**({"graph_id": graph_id} if graph_id else {}),
}
if if_exists:
payload["if_exists"] = if_exists
if supersteps:
payload["supersteps"] = [
{
"updates": [
{
"values": u["values"],
"command": u.get("command"),
"as_node": u["as_node"],
}
for u in s["updates"]
]
}
for s in supersteps
]
return await self.http.post("/threads", json=payload)
async def update(self, thread_id: str, *, metadata: dict[str, Any]) -> Thread:
@@ -3036,6 +3059,8 @@ class SyncThreadsClient:
metadata: Json = None,
thread_id: Optional[str] = None,
if_exists: Optional[OnConflictBehavior] = None,
supersteps: Optional[Sequence[dict[str, Sequence[dict[str, Any]]]]] = None,
graph_id: Optional[str] = None,
) -> Thread:
"""Create a new thread.
@@ -3045,6 +3070,9 @@ class SyncThreadsClient:
If None, ID will be a randomly generated UUID.
if_exists: How to handle duplicate creation. Defaults to 'raise' under the hood.
Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing thread).
supersteps: Apply a list of supersteps when creating a thread, each containing a sequence of updates.
Each update has `values` or `command` and `as_node`. Used for copying a thread between deployments.
graph_id: Optional graph ID to associate with the thread.
Returns:
Thread: The created thread.
@@ -3060,10 +3088,28 @@ class SyncThreadsClient:
payload: Dict[str, Any] = {}
if thread_id:
payload["thread_id"] = thread_id
if metadata:
payload["metadata"] = metadata
if metadata or graph_id:
payload["metadata"] = {
**(metadata or {}),
**({"graph_id": graph_id} if graph_id else {}),
}
if if_exists:
payload["if_exists"] = if_exists
if supersteps:
payload["supersteps"] = [
{
"updates": [
{
"values": u["values"],
"command": u.get("command"),
"as_node": u["as_node"],
}
for u in s["updates"]
]
}
for s in supersteps
]
return self.http.post("/threads", json=payload)
def update(self, thread_id: str, *, metadata: dict[str, Any]) -> Thread:
@@ -3307,7 +3353,7 @@ class SyncThreadsClient:
Example Usage:
response = client.threads.update_state(
response = await client.threads.update_state(
thread_id="my_thread_id",
values={"messages":[{"role": "user", "content": "hello!"}]},
as_node="my_node",
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "langgraph-sdk"
version = "0.1.57"
version = "0.1.58"
description = "SDK for interacting with LangGraph API"
authors = []
license = "MIT"