diff --git a/docs/docs/cloud/how-tos/use_stream_react.md b/docs/docs/cloud/how-tos/use_stream_react.md index e67fc2fc2..30d9a0751 100644 --- a/docs/docs/cloud/how-tos/use_stream_react.md +++ b/docs/docs/cloud/how-tos/use_stream_react.md @@ -9,14 +9,13 @@ The `useStream()` React hook provides a seamless way to integrate LangGraph into Key features: - Messages streaming: Handle a stream of message chunks to form a complete message -- Automatic state management for messages, loading states, and errors +- Automatic state management for messages, interrupts, loading states, and errors - Conversation branching: Create alternate conversation paths from any point in the chat history -- UI-agnostic design - bring your own components and styling +- UI-agnostic design: bring your own components and styling Let's explore how to use `useStream()` in your React application. -The `useStream()` provides a solid foundation for creating bespoke chat experiences. For pre-built chat components and interfaces, we recommend checking out [CopilotKit](https://docs.copilotkit.ai/coagents/quickstart/langgraph) and [assistant-ui](https://www.assistant-ui.com/docs/runtimes/langgraph). - +The `useStream()` provides a solid foundation for creating bespoke chat experiences. For pre-built chat components and interfaces, we also recommend checking out [CopilotKit](https://docs.copilotkit.ai/coagents/quickstart/langgraph) and [assistant-ui](https://www.assistant-ui.com/docs/runtimes/langgraph). ## Installation @@ -65,9 +64,7 @@ export default function App() { Stop ) : ( - + )} @@ -81,6 +78,7 @@ The `useStream()` hook takes care of all the complex state management behind the - Thread state management - Loading and error states +- Interrupts - Message handling and updates - Branching support @@ -134,9 +132,9 @@ We recommend storing the `threadId` in your URL's query parameters to let users ### Messages Handling -To enable messages handling, you need to pass the `messagesKey` option to the `useStream()` hook. +The `useStream()` hook will keep track of the message chunks received from the server and concatenate them together to form a complete message. The completed message chunks can be retrieved via the `messages` property. -When enabled, the `useStream()` hook will keep track of the message chunks received from the server and concatenate them together to form a complete message. The completed message chunks can be retrieved via the `messages` property. +By default, the `messagesKey` is set to `messages`, where it will append the new messages chunks to `values["messages"]`. If you store messages in a different key, you can change the value of `messagesKey`. ```tsx import type { Message } from "@langchain/langgraph-sdk"; @@ -159,9 +157,49 @@ export default function HomePage() { } ``` -### Branching Support +Under the hood, the `useStream()` hook will use the `streamMode: "messages-key"` to receive a stream of messages (i.e. individual LLM tokens) from any LangChain chat model invocations inside your graph nodes. Learn more about messages streaming in the [How to stream messages from your graph](./stream_messages.md) guide. -To enable branching, you need to enable messages handling. Pass the `messagesKey` option to the `useStream()` hook. For each message, you can use `getMessagesMetadata()` to get the first checkpoint from which the message has been first seen. You can then create a new run from the checkpoint preceding the first seen checkpoint to create a new branch in a thread. +### Interrupts + +The `useStream()` hook exposes the `interrupt` property, which will be filled with the last interrupt from the thread. You can use interrupts to: + +- Render a confirmation UI before executing a node +- Wait for human input, allowing agent to ask the user with clarifying questions + +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 } +>({ + apiUrl: "http://localhost:2024", + assistantId: "agent", + messagesKey: "messages", +}); + +if (thread.interrupt) { + return ( +