From fb3c61ea4f9f572fe0c0194a76356a36c1030ccf Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Fri, 28 Mar 2025 15:33:16 +0100 Subject: [PATCH 1/3] feat(sdk-js): run optimistic values mutator before any network request --- libs/sdk-js/src/react/stream.tsx | 48 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/libs/sdk-js/src/react/stream.tsx b/libs/sdk-js/src/react/stream.tsx index 4586aa3c4..b7e574cff 100644 --- a/libs/sdk-js/src/react/stream.tsx +++ b/libs/sdk-js/src/react/stream.tsx @@ -782,6 +782,30 @@ export function useStream< submittingRef.current = true; abortRef.current = new AbortController(); + // Unbranch things + const newPath = submitOptions?.checkpoint?.checkpoint_id + ? branchByCheckpoint[submitOptions?.checkpoint?.checkpoint_id]?.branch + : undefined; + + if (newPath != null) setBranch(newPath ?? ""); + + // Assumption: we're setting the initial value + // Used for instant feedback + setStreamValues(() => { + const values = { ...historyValues }; + + if (submitOptions?.optimisticValues != null) { + return { + ...values, + ...(typeof submitOptions.optimisticValues === "function" + ? submitOptions.optimisticValues(values) + : submitOptions.optimisticValues), + }; + } + + return values; + }); + let usableThreadId = threadId; if (!usableThreadId) { const thread = await client.threads.create(); @@ -818,30 +842,6 @@ export function useStream< streamMode, }) as AsyncGenerator; - // Unbranch things - const newPath = submitOptions?.checkpoint?.checkpoint_id - ? branchByCheckpoint[submitOptions?.checkpoint?.checkpoint_id]?.branch - : undefined; - - if (newPath != null) setBranch(newPath ?? ""); - - // Assumption: we're setting the initial value - // Used for instant feedback - setStreamValues(() => { - const values = { ...historyValues }; - - if (submitOptions?.optimisticValues != null) { - return { - ...values, - ...(typeof submitOptions.optimisticValues === "function" - ? submitOptions.optimisticValues(values) - : submitOptions.optimisticValues), - }; - } - - return values; - }); - let streamError: StreamError | undefined; for await (const { event, data } of run) { if (event === "error") { From 2808a7859ac30ffe6d0c8101969d519fc20d6e1a Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Fri, 28 Mar 2025 21:39:09 +0100 Subject: [PATCH 2/3] Bump to 0.0.62 --- libs/sdk-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/sdk-js/package.json b/libs/sdk-js/package.json index f06349dba..3be321092 100644 --- a/libs/sdk-js/package.json +++ b/libs/sdk-js/package.json @@ -1,6 +1,6 @@ { "name": "@langchain/langgraph-sdk", - "version": "0.0.61", + "version": "0.0.62", "description": "Client library for interacting with the LangGraph API", "type": "module", "packageManager": "yarn@1.22.19", From 8e4b8b11ff0cca74ad7d2aeea149b7b736c0193a Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Fri, 28 Mar 2025 21:52:37 +0100 Subject: [PATCH 3/3] Add docs about optimistic updates --- docs/docs/cloud/how-tos/use_stream_react.md | 71 ++++++++++++++------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/docs/docs/cloud/how-tos/use_stream_react.md b/docs/docs/cloud/how-tos/use_stream_react.md index 0468b9bb9..ee62fcaff 100644 --- a/docs/docs/cloud/how-tos/use_stream_react.md +++ b/docs/docs/cloud/how-tos/use_stream_react.md @@ -1,8 +1,6 @@ # How to integrate LangGraph into your React application -!!! info "Prerequisites" - - [LangGraph Platform](../../concepts/langgraph_platform.md) - - [LangGraph Server](../../concepts/langgraph_server.md) +!!! info "Prerequisites" - [LangGraph Platform](../../concepts/langgraph_platform.md) - [LangGraph Server](../../concepts/langgraph_server.md) The `useStream()` React hook provides a seamless way to integrate LangGraph into your React applications. It handles all the complexities of streaming, state management, and branching logic, letting you focus on building great chat experiences. @@ -169,10 +167,7 @@ The `useStream()` hook exposes the `interrupt` property, which will be filled wi Learn more about interrupts in the [How to handle interrupts](../../how-tos/human_in_the_loop/wait-user-input.ipynb) guide. ```tsx -const thread = useStream< - { messages: Message[] }, - { InterruptType: string } ->({ +const thread = useStream<{ messages: Message[] }, { InterruptType: string }>({ apiUrl: "http://localhost:2024", assistantId: "agent", messagesKey: "messages", @@ -182,7 +177,6 @@ if (thread.interrupt) { return (
Interrupted! {thread.interrupt.value} -