@langchain/react 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -142,7 +142,11 @@ function Chat() {
142
142
 
143
143
  ### Options
144
144
 
145
- `useSuspenseStream` accepts the same options as `useStream` (LangGraph Platform mode). See [`useStream` Options](#usestream-options) above.
145
+ `useSuspenseStream` accepts the same options as `useStream` (LangGraph Platform mode), plus:
146
+
147
+ | Option | Type | Description |
148
+ |---|---|---|
149
+ | `suspenseCache` | `SuspenseCache` | Optional cache instance for Suspense history prefetching. Useful in tests to avoid cross-test cache sharing. |
146
150
 
147
151
  ### Return Values
148
152
 
@@ -212,6 +216,23 @@ import { invalidateSuspenseCache } from "@langchain/react";
212
216
  </ErrorBoundary>
213
217
  ```
214
218
 
219
+ For test isolation, you can create and pass a dedicated cache instance:
220
+
221
+ ```tsx
222
+ import { createSuspenseCache, useSuspenseStream } from "@langchain/react";
223
+
224
+ const suspenseCache = createSuspenseCache();
225
+
226
+ function Chat() {
227
+ const stream = useSuspenseStream({
228
+ assistantId: "agent",
229
+ apiUrl: "http://localhost:2024",
230
+ suspenseCache,
231
+ });
232
+ // ...
233
+ }
234
+ ```
235
+
215
236
  ## Type Safety
216
237
 
217
238
  ### With `createAgent`
package/dist/index.cjs CHANGED
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "calculateDepthFromNamespace", {
18
18
  return _langchain_langgraph_sdk_ui.calculateDepthFromNamespace;
19
19
  }
20
20
  });
21
+ exports.createSuspenseCache = require_suspense_stream.createSuspenseCache;
21
22
  Object.defineProperty(exports, "extractParentIdFromNamespace", {
22
23
  enumerable: true,
23
24
  get: function() {
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { SubagentStream, SubagentStreamInterface, UseStream, UseStreamCustom, UseSuspenseStream } from "./types.cjs";
2
2
  import { ClassSubagentStreamInterface, useStream } from "./stream.cjs";
3
- import { invalidateSuspenseCache, useSuspenseStream } from "./suspense-stream.cjs";
3
+ import { SuspenseCache, createSuspenseCache, invalidateSuspenseCache, useSuspenseStream } from "./suspense-stream.cjs";
4
4
  import { FetchStreamTransport } from "./stream.custom.cjs";
5
5
  import { StreamProvider, StreamProviderCustomProps, StreamProviderProps, useStreamContext } from "./context.cjs";
6
6
  import { AIMessage, ToolMessage } from "@langchain/core/messages";
@@ -10,5 +10,5 @@ import { AgentTypeConfigLike, BaseStream, BaseSubagentState, CompiledSubAgentLik
10
10
  //#region src/index.d.ts
11
11
  type ToolCallWithResult<ToolCall = DefaultToolCall$1> = ToolCallWithResult$1<ToolCall, ToolMessage, AIMessage>;
12
12
  //#endregion
13
- export { type AgentTypeConfigLike, type BaseStream, type BaseSubagentState, type ClassSubagentStreamInterface, type CompiledSubAgentLike, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, FetchStreamTransport, type GetToolCallsType, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type IsAgentLike, type IsDeepAgentLike, type MessageMetadata, type QueueEntry, type QueueInterface, type ResolveStreamInterface, type ResolveStreamOptions, StreamProvider, type StreamProviderCustomProps, type StreamProviderProps, type SubAgentLike, SubagentManager, type SubagentStateMap, type SubagentStatus, type SubagentStream, type SubagentStreamInterface, type SubagentToolCall, type ToolCallFromTool, type ToolCallState, ToolCallWithResult, type ToolCallsFromTools, type UseAgentStream, type UseAgentStreamOptions, type UseDeepAgentStream, type UseDeepAgentStreamOptions, type UseStream, type UseStreamCustom, type UseStreamCustomOptions, type UseStreamOptions, type UseStreamThread, type UseStreamTransport, type UseSuspenseStream, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, invalidateSuspenseCache, isSubagentNamespace, useStream, useStreamContext, useSuspenseStream };
13
+ export { type AgentTypeConfigLike, type BaseStream, type BaseSubagentState, type ClassSubagentStreamInterface, type CompiledSubAgentLike, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, FetchStreamTransport, type GetToolCallsType, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type IsAgentLike, type IsDeepAgentLike, type MessageMetadata, type QueueEntry, type QueueInterface, type ResolveStreamInterface, type ResolveStreamOptions, StreamProvider, type StreamProviderCustomProps, type StreamProviderProps, type SubAgentLike, SubagentManager, type SubagentStateMap, type SubagentStatus, type SubagentStream, type SubagentStreamInterface, type SubagentToolCall, type SuspenseCache, type ToolCallFromTool, type ToolCallState, ToolCallWithResult, type ToolCallsFromTools, type UseAgentStream, type UseAgentStreamOptions, type UseDeepAgentStream, type UseDeepAgentStreamOptions, type UseStream, type UseStreamCustom, type UseStreamCustomOptions, type UseStreamOptions, type UseStreamThread, type UseStreamTransport, type UseSuspenseStream, calculateDepthFromNamespace, createSuspenseCache, extractParentIdFromNamespace, extractToolCallIdFromNamespace, invalidateSuspenseCache, isSubagentNamespace, useStream, useStreamContext, useSuspenseStream };
14
14
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;KAgFY,kBAAA,YAA8B,iBAAA,IACxC,oBAAA,CAAoB,QAAA,EAAU,WAAA,EAAiB,SAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;KAkFY,kBAAA,YAA8B,iBAAA,IACxC,oBAAA,CAAoB,QAAA,EAAU,WAAA,EAAiB,SAAA"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { SubagentStream, SubagentStreamInterface, UseStream, UseStreamCustom, UseSuspenseStream } from "./types.js";
2
2
  import { ClassSubagentStreamInterface, useStream } from "./stream.js";
3
- import { invalidateSuspenseCache, useSuspenseStream } from "./suspense-stream.js";
3
+ import { SuspenseCache, createSuspenseCache, invalidateSuspenseCache, useSuspenseStream } from "./suspense-stream.js";
4
4
  import { FetchStreamTransport } from "./stream.custom.js";
5
5
  import { StreamProvider, StreamProviderCustomProps, StreamProviderProps, useStreamContext } from "./context.js";
6
6
  import { AgentTypeConfigLike, BaseStream, BaseSubagentState, CompiledSubAgentLike, DeepAgentTypeConfigLike, DefaultSubagentStates, ExtractAgentConfig, ExtractDeepAgentConfig, ExtractSubAgentMiddleware, GetToolCallsType, InferAgentToolCalls, InferBag, InferDeepAgentSubagents, InferNodeNames, InferStateType, InferSubagentByName, InferSubagentNames, InferSubagentState, InferSubagentStates, InferToolCalls, IsAgentLike, IsDeepAgentLike, MessageMetadata, QueueEntry, QueueInterface, ResolveStreamInterface, ResolveStreamOptions, SubAgentLike, SubagentManager, SubagentStateMap, SubagentStatus, SubagentToolCall, UseAgentStream, UseAgentStreamOptions, UseDeepAgentStream, UseDeepAgentStreamOptions, UseStreamCustomOptions, UseStreamOptions, UseStreamThread, UseStreamTransport, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace } from "@langchain/langgraph-sdk/ui";
@@ -10,5 +10,5 @@ import { DefaultToolCall, DefaultToolCall as DefaultToolCall$1, ToolCallFromTool
10
10
  //#region src/index.d.ts
11
11
  type ToolCallWithResult<ToolCall = DefaultToolCall$1> = ToolCallWithResult$1<ToolCall, ToolMessage, AIMessage>;
12
12
  //#endregion
13
- export { type AgentTypeConfigLike, type BaseStream, type BaseSubagentState, type ClassSubagentStreamInterface, type CompiledSubAgentLike, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, FetchStreamTransport, type GetToolCallsType, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type IsAgentLike, type IsDeepAgentLike, type MessageMetadata, type QueueEntry, type QueueInterface, type ResolveStreamInterface, type ResolveStreamOptions, StreamProvider, type StreamProviderCustomProps, type StreamProviderProps, type SubAgentLike, SubagentManager, type SubagentStateMap, type SubagentStatus, type SubagentStream, type SubagentStreamInterface, type SubagentToolCall, type ToolCallFromTool, type ToolCallState, ToolCallWithResult, type ToolCallsFromTools, type UseAgentStream, type UseAgentStreamOptions, type UseDeepAgentStream, type UseDeepAgentStreamOptions, type UseStream, type UseStreamCustom, type UseStreamCustomOptions, type UseStreamOptions, type UseStreamThread, type UseStreamTransport, type UseSuspenseStream, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, invalidateSuspenseCache, isSubagentNamespace, useStream, useStreamContext, useSuspenseStream };
13
+ export { type AgentTypeConfigLike, type BaseStream, type BaseSubagentState, type ClassSubagentStreamInterface, type CompiledSubAgentLike, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, FetchStreamTransport, type GetToolCallsType, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type IsAgentLike, type IsDeepAgentLike, type MessageMetadata, type QueueEntry, type QueueInterface, type ResolveStreamInterface, type ResolveStreamOptions, StreamProvider, type StreamProviderCustomProps, type StreamProviderProps, type SubAgentLike, SubagentManager, type SubagentStateMap, type SubagentStatus, type SubagentStream, type SubagentStreamInterface, type SubagentToolCall, type SuspenseCache, type ToolCallFromTool, type ToolCallState, ToolCallWithResult, type ToolCallsFromTools, type UseAgentStream, type UseAgentStreamOptions, type UseDeepAgentStream, type UseDeepAgentStreamOptions, type UseStream, type UseStreamCustom, type UseStreamCustomOptions, type UseStreamOptions, type UseStreamThread, type UseStreamTransport, type UseSuspenseStream, calculateDepthFromNamespace, createSuspenseCache, extractParentIdFromNamespace, extractToolCallIdFromNamespace, invalidateSuspenseCache, isSubagentNamespace, useStream, useStreamContext, useSuspenseStream };
14
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;KAgFY,kBAAA,YAA8B,iBAAA,IACxC,oBAAA,CAAoB,QAAA,EAAU,WAAA,EAAiB,SAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;KAkFY,kBAAA,YAA8B,iBAAA,IACxC,oBAAA,CAAoB,QAAA,EAAU,WAAA,EAAiB,SAAA"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { FetchStreamTransport } from "./stream.custom.js";
2
2
  import { useStream } from "./stream.js";
3
- import { invalidateSuspenseCache, useSuspenseStream } from "./suspense-stream.js";
3
+ import { createSuspenseCache, invalidateSuspenseCache, useSuspenseStream } from "./suspense-stream.js";
4
4
  import { StreamProvider, useStreamContext } from "./context.js";
5
5
  import { SubagentManager, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace } from "@langchain/langgraph-sdk/ui";
6
- export { FetchStreamTransport, StreamProvider, SubagentManager, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, invalidateSuspenseCache, isSubagentNamespace, useStream, useStreamContext, useSuspenseStream };
6
+ export { FetchStreamTransport, StreamProvider, SubagentManager, calculateDepthFromNamespace, createSuspenseCache, extractParentIdFromNamespace, extractToolCallIdFromNamespace, invalidateSuspenseCache, isSubagentNamespace, useStream, useStreamContext, useSuspenseStream };
package/dist/stream.cjs CHANGED
@@ -5,10 +5,12 @@ let react = require("react");
5
5
  function isCustomOptions(options) {
6
6
  return "transport" in options;
7
7
  }
8
+ function selectStreamImplementation(options) {
9
+ return isCustomOptions(options) ? require_stream_custom.useStreamCustom : require_stream_lgp.useStreamLGP;
10
+ }
8
11
  function useStream(options) {
9
- const [isCustom] = (0, react.useState)(isCustomOptions(options));
10
- if (isCustom) return require_stream_custom.useStreamCustom(options);
11
- return require_stream_lgp.useStreamLGP(options);
12
+ const [useSelectedStream] = (0, react.useState)(() => selectStreamImplementation(options));
13
+ return useSelectedStream(options);
12
14
  }
13
15
  //#endregion
14
16
  exports.useStream = useStream;
@@ -1 +1 @@
1
- {"version":3,"file":"stream.cjs","names":["useStreamCustom","useStreamLGP"],"sources":["../src/stream.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport type {\n BaseMessage,\n ToolMessage as CoreToolMessage,\n AIMessage as CoreAIMessage,\n} from \"@langchain/core/messages\";\nimport type {\n BagTemplate,\n ToolCallWithResult,\n DefaultToolCall,\n} from \"@langchain/langgraph-sdk\";\nimport type {\n UseStreamOptions,\n AcceptBaseMessages,\n ResolveStreamInterface,\n ResolveStreamOptions,\n InferBag,\n InferStateType,\n MessageMetadata,\n SubagentStreamInterface,\n HistoryWithBaseMessages,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { useStreamLGP } from \"./stream.lgp.js\";\nimport { useStreamCustom } from \"./stream.custom.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\n\nfunction isCustomOptions<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options:\n | UseStreamOptions<StateType, Bag>\n | UseStreamCustomOptions<StateType, Bag>,\n): options is UseStreamCustomOptions<StateType, Bag> {\n return \"transport\" in options;\n}\n\ntype ClassToolCallWithResult<T> =\n T extends ToolCallWithResult<infer TC, unknown, unknown>\n ? ToolCallWithResult<TC, CoreToolMessage, CoreAIMessage>\n : T;\n\nexport type ClassSubagentStreamInterface<\n StateType = Record<string, unknown>,\n ToolCall = DefaultToolCall,\n SubagentName extends string = string,\n> = Omit<\n SubagentStreamInterface<StateType, ToolCall, SubagentName>,\n \"messages\"\n> & {\n messages: BaseMessage[];\n};\n\n/**\n * Maps a stream interface to use @langchain/core BaseMessage class instances\n * instead of plain Message objects for the `messages` property, and remaps\n * tool call types to use @langchain/core message classes.\n */\nexport type WithClassMessages<T> = Omit<\n T,\n | \"messages\"\n | \"history\"\n | \"getMessagesMetadata\"\n | \"toolCalls\"\n | \"getToolCalls\"\n | \"submit\"\n | \"subagents\"\n | \"activeSubagents\"\n | \"getSubagent\"\n | \"getSubagentsByType\"\n | \"getSubagentsByMessage\"\n> & {\n messages: BaseMessage[];\n getMessagesMetadata: (\n message: BaseMessage,\n index?: number,\n ) => MessageMetadata<Record<string, unknown>> | undefined;\n} & (\"history\" extends keyof T\n ? { history: HistoryWithBaseMessages<T[\"history\"]> }\n : unknown) &\n (\"submit\" extends keyof T\n ? {\n submit: T extends {\n submit: (values: infer V, options?: infer O) => infer Ret;\n }\n ? (\n values:\n | AcceptBaseMessages<Exclude<V, null | undefined>>\n | null\n | undefined,\n options?: O,\n ) => Ret\n : never;\n }\n : unknown) &\n (\"toolCalls\" extends keyof T\n ? {\n toolCalls: T extends { toolCalls: (infer TC)[] }\n ? ClassToolCallWithResult<TC>[]\n : never;\n }\n : unknown) &\n (\"getToolCalls\" extends keyof T\n ? {\n getToolCalls: T extends {\n getToolCalls: (message: infer _M) => (infer TC)[];\n }\n ? (message: CoreAIMessage) => ClassToolCallWithResult<TC>[]\n : never;\n }\n : unknown) &\n (\"subagents\" extends keyof T\n ? {\n subagents: T extends {\n subagents: Map<\n string,\n SubagentStreamInterface<infer S, infer TC, infer N>\n >;\n }\n ? Map<string, ClassSubagentStreamInterface<S, TC, N>>\n : never;\n activeSubagents: T extends {\n activeSubagents: SubagentStreamInterface<\n infer S,\n infer TC,\n infer N\n >[];\n }\n ? ClassSubagentStreamInterface<S, TC, N>[]\n : never;\n getSubagent: T extends {\n getSubagent: (\n id: string,\n ) => SubagentStreamInterface<infer S, infer TC, infer N> | undefined;\n }\n ? (\n toolCallId: string,\n ) => ClassSubagentStreamInterface<S, TC, N> | undefined\n : never;\n getSubagentsByType: T extends {\n getSubagentsByType: (\n type: string,\n ) => SubagentStreamInterface<infer S, infer TC, infer N>[];\n }\n ? (type: string) => ClassSubagentStreamInterface<S, TC, N>[]\n : never;\n getSubagentsByMessage: T extends {\n getSubagentsByMessage: (\n id: string,\n ) => SubagentStreamInterface<infer S, infer TC, infer N>[];\n }\n ? (messageId: string) => ClassSubagentStreamInterface<S, TC, N>[]\n : never;\n }\n : unknown);\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, subagent streams, and errors.\n *\n * ## Usage with ReactAgent (recommended for createAgent users)\n *\n * When using `createAgent` from `@langchain/langgraph`, you can pass `typeof agent` as the\n * type parameter to automatically infer tool call types:\n *\n * @example\n * ```typescript\n * // In your agent file (e.g., agent.ts)\n * import { createAgent, tool } from \"langchain\";\n * import { z } from \"zod\";\n *\n * const getWeather = tool(\n * async ({ location }) => `Weather in ${location}`,\n * { name: \"get_weather\", schema: z.object({ location: z.string() }) }\n * );\n *\n * export const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather],\n * });\n *\n * // In your React component\n * import { agent } from \"./agent\";\n *\n * function Chat() {\n * // Tool calls are automatically typed from the agent's tools!\n * const stream = useStream<typeof agent>({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.toolCalls[0].call.name is typed as \"get_weather\"\n * // stream.toolCalls[0].call.args is typed as { location: string }\n * }\n * ```\n *\n * ## Usage with StateGraph (for custom LangGraph applications)\n *\n * When building custom graphs with `StateGraph`, embed your tool call types directly\n * in your state's messages property using `Message<MyToolCalls>`:\n *\n * @example\n * ```typescript\n * import { Message } from \"@langchain/langgraph-sdk\";\n *\n * // Define your tool call types as a discriminated union\n * type MyToolCalls =\n * | { name: \"search\"; args: { query: string }; id?: string }\n * | { name: \"calculate\"; args: { expression: string }; id?: string };\n *\n * // Embed tool call types in your state's messages\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * context?: string;\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.values is typed as MyGraphState\n * // stream.toolCalls[0].call.name is typed as \"search\" | \"calculate\"\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With additional type configuration (interrupts, configurable)\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState, {\n * InterruptType: { question: string };\n * ConfigurableType: { userId: string };\n * }>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.interrupt is typed as { question: string } | undefined\n * }\n * ```\n *\n * ## Usage with Deep Agents (subagent streaming, experimental)\n *\n * For agents that spawn subagents (nested graphs), use `filterSubagentMessages`\n * to keep the main message stream clean while tracking subagent activity separately:\n *\n * @example\n * ```typescript\n * import { useStream, SubagentStream } from \"@langchain/langgraph-sdk/react\";\n * import type { agent } from \"./agent\";\n *\n * function DeepAgentChat() {\n * const stream = useStream<typeof agent>({\n * assistantId: \"deepagent\",\n * apiUrl: \"http://localhost:2024\",\n * // Filter subagent messages from main stream\n * filterSubagentMessages: true,\n * });\n *\n * const handleSubmit = (content: string) => {\n * stream.submit(\n * { messages: [{ content, type: \"human\" }] },\n * { streamSubgraphs: true } // Enable subgraph streaming\n * );\n * };\n *\n * // Access subagent streams via stream.subagents (Map<string, SubagentStream>)\n * const subagentList = [...stream.subagents.values()];\n *\n * return (\n * <div>\n * {stream.messages.map((msg) => <Message key={msg.id} message={msg} />)}\n *\n * {subagentList.map((subagent) => (\n * <SubagentCard\n * key={subagent.id}\n * status={subagent.status} // \"pending\" | \"running\" | \"complete\" | \"error\"\n * messages={subagent.messages}\n * toolCalls={subagent.toolCalls}\n * />\n * ))}\n * </div>\n * );\n * }\n * ```\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: ResolveStreamOptions<T, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useStream(options: any): any {\n // Store this in useState to make sure we're not changing the implementation in re-renders\n const [isCustom] = useState(isCustomOptions(options));\n\n if (isCustom) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStreamCustom(options);\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStreamLGP(options);\n}\n"],"mappings":";;;;AA0BA,SAAS,gBAIP,SAGmD;AACnD,QAAO,eAAe;;AA6SxB,SAAgB,UAAU,SAAmB;CAE3C,MAAM,CAAC,aAAA,GAAA,MAAA,UAAqB,gBAAgB,QAAQ,CAAC;AAErD,KAAI,SAEF,QAAOA,sBAAAA,gBAAgB,QAAQ;AAIjC,QAAOC,mBAAAA,aAAa,QAAQ"}
1
+ {"version":3,"file":"stream.cjs","names":["useStreamCustom","useStreamLGP"],"sources":["../src/stream.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport type { BagTemplate } from \"@langchain/langgraph-sdk\";\nimport type {\n UseStreamOptions,\n ResolveStreamInterface,\n ResolveStreamOptions,\n InferBag,\n InferStateType,\n WithClassMessages,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { useStreamLGP } from \"./stream.lgp.js\";\nimport { useStreamCustom } from \"./stream.custom.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\n\nfunction isCustomOptions<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options:\n | UseStreamOptions<StateType, Bag>\n | UseStreamCustomOptions<StateType, Bag>,\n): options is UseStreamCustomOptions<StateType, Bag> {\n return \"transport\" in options;\n}\n\ntype UseStreamImplementation = typeof useStreamLGP | typeof useStreamCustom;\n\ntype AnyUseStreamOptions =\n | UseStreamOptions<Record<string, unknown>, BagTemplate>\n | UseStreamCustomOptions<Record<string, unknown>, BagTemplate>;\n\nfunction selectStreamImplementation(\n options: AnyUseStreamOptions,\n): UseStreamImplementation {\n return isCustomOptions(options) ? useStreamCustom : useStreamLGP;\n}\n\nexport type {\n WithClassMessages,\n ClassSubagentStreamInterface,\n} from \"@langchain/langgraph-sdk/ui\";\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, subagent streams, and errors.\n *\n * ## Usage with ReactAgent (recommended for createAgent users)\n *\n * When using `createAgent` from `@langchain/langgraph`, you can pass `typeof agent` as the\n * type parameter to automatically infer tool call types:\n *\n * @example\n * ```typescript\n * // In your agent file (e.g., agent.ts)\n * import { createAgent, tool } from \"langchain\";\n * import { z } from \"zod\";\n *\n * const getWeather = tool(\n * async ({ location }) => `Weather in ${location}`,\n * { name: \"get_weather\", schema: z.object({ location: z.string() }) }\n * );\n *\n * export const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather],\n * });\n *\n * // In your React component\n * import { agent } from \"./agent\";\n *\n * function Chat() {\n * // Tool calls are automatically typed from the agent's tools!\n * const stream = useStream<typeof agent>({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.toolCalls[0].call.name is typed as \"get_weather\"\n * // stream.toolCalls[0].call.args is typed as { location: string }\n * }\n * ```\n *\n * ## Usage with StateGraph (for custom LangGraph applications)\n *\n * When building custom graphs with `StateGraph`, embed your tool call types directly\n * in your state's messages property using `Message<MyToolCalls>`:\n *\n * @example\n * ```typescript\n * import { Message } from \"@langchain/langgraph-sdk\";\n *\n * // Define your tool call types as a discriminated union\n * type MyToolCalls =\n * | { name: \"search\"; args: { query: string }; id?: string }\n * | { name: \"calculate\"; args: { expression: string }; id?: string };\n *\n * // Embed tool call types in your state's messages\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * context?: string;\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.values is typed as MyGraphState\n * // stream.toolCalls[0].call.name is typed as \"search\" | \"calculate\"\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With additional type configuration (interrupts, configurable)\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState, {\n * InterruptType: { question: string };\n * ConfigurableType: { userId: string };\n * }>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.interrupt is typed as { question: string } | undefined\n * }\n * ```\n *\n * ## Usage with Deep Agents (subagent streaming, experimental)\n *\n * For agents that spawn subagents (nested graphs), use `filterSubagentMessages`\n * to keep the main message stream clean while tracking subagent activity separately:\n *\n * @example\n * ```typescript\n * import { useStream, SubagentStream } from \"@langchain/langgraph-sdk/react\";\n * import type { agent } from \"./agent\";\n *\n * function DeepAgentChat() {\n * const stream = useStream<typeof agent>({\n * assistantId: \"deepagent\",\n * apiUrl: \"http://localhost:2024\",\n * // Filter subagent messages from main stream\n * filterSubagentMessages: true,\n * });\n *\n * const handleSubmit = (content: string) => {\n * stream.submit(\n * { messages: [{ content, type: \"human\" }] },\n * { streamSubgraphs: true } // Enable subgraph streaming\n * );\n * };\n *\n * // Access subagent streams via stream.subagents (Map<string, SubagentStream>)\n * const subagentList = [...stream.subagents.values()];\n *\n * return (\n * <div>\n * {stream.messages.map((msg) => <Message key={msg.id} message={msg} />)}\n *\n * {subagentList.map((subagent) => (\n * <SubagentCard\n * key={subagent.id}\n * status={subagent.status} // \"pending\" | \"running\" | \"complete\" | \"error\"\n * messages={subagent.messages}\n * toolCalls={subagent.toolCalls}\n * />\n * ))}\n * </div>\n * );\n * }\n * ```\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: ResolveStreamOptions<T, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useStream(options: any): any {\n // Keep implementation stable for the lifetime of this hook instance.\n const [useSelectedStream] = useState(() =>\n selectStreamImplementation(options),\n );\n return useSelectedStream(options);\n}\n"],"mappings":";;;;AAcA,SAAS,gBAIP,SAGmD;AACnD,QAAO,eAAe;;AASxB,SAAS,2BACP,SACyB;AACzB,QAAO,gBAAgB,QAAQ,GAAGA,sBAAAA,kBAAkBC,mBAAAA;;AA2LtD,SAAgB,UAAU,SAAmB;CAE3C,MAAM,CAAC,sBAAA,GAAA,MAAA,gBACL,2BAA2B,QAAQ,CACpC;AACD,QAAO,kBAAkB,QAAQ"}
@@ -140,7 +140,7 @@ function useStreamCustom(options) {
140
140
  if (stream.values != null && "__interrupt__" in stream.values && Array.isArray(stream.values.__interrupt__)) {
141
141
  const valueInterrupts = stream.values.__interrupt__;
142
142
  if (valueInterrupts.length === 0) return [{ when: "breakpoint" }];
143
- return valueInterrupts;
143
+ return (0, _langchain_langgraph_sdk_ui.normalizeInterruptsList)(valueInterrupts);
144
144
  }
145
145
  return [];
146
146
  },
@@ -1 +1 @@
1
- {"version":3,"file":"stream.custom.cjs","names":["MessageTupleManager","StreamManager","toMessageClass","useControllableThreadId"],"sources":["../src/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n StreamManager,\n MessageTupleManager,\n extractInterrupts,\n FetchStreamTransport,\n toMessageClass,\n ensureMessageInstances,\n type EventStreamEvent,\n type GetUpdateType,\n type GetCustomEventType,\n type GetInterruptType,\n type GetToolCallsType,\n type GetConfigurableType,\n type AnyStreamCustomOptions,\n type CustomSubmitOptions,\n type MessageMetadata,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { getToolCallsWithResults } from \"@langchain/langgraph-sdk/utils\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n BagTemplate,\n Message,\n Interrupt,\n ThreadState,\n} from \"@langchain/langgraph-sdk\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { UseStreamCustom } from \"./types.js\";\n\nexport { FetchStreamTransport };\n\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>,\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n }),\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot,\n );\n\n const [branch, _setBranch] = useState(\"\");\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n }\n },\n [stream],\n );\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submitDirect = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n if (threadId !== threadIdRef.current) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n\n let usableThreadId = threadIdRef.current ?? submitOptions?.threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = stream.values ?? historyValues;\n options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined,\n );\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n },\n );\n };\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n await submitDirect(values, submitOptions);\n };\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n branch,\n setBranch: _setBranch,\n\n getMessagesMetadata(\n message: BaseMessage,\n index?: number,\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n const valueInterrupts = stream.values.__interrupt__;\n if (valueInterrupts.length === 0) return [{ when: \"breakpoint\" }];\n return valueInterrupts;\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n return extractInterrupts<InterruptType>(stream.values);\n },\n\n get messages(): BaseMessage[] {\n if (!stream.values) return [];\n return ensureMessageInstances(\n getMessages(stream.values),\n ) as BaseMessage[];\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n\n queue: {\n get entries() {\n return [];\n },\n get size() {\n return 0;\n },\n async cancel() {\n return false;\n },\n async clear() {},\n },\n };\n}\n"],"mappings":";;;;;;AAyCA,SAAS,iCAEP,QAAmB,UAA0C;AAC7D,QAAO;EACL;EACA,MAAM,EAAE;EACR,OAAO,EAAE;EACT,UAAU,KAAA;EACV,YAAY;EACZ,YAAY;GACV,WAAW;GACX,eAAe;GACf,eAAe;GACf,gBAAgB;GACjB;EACD,mBAAmB;EACpB;;AAGH,SAAgB,gBAId,SACiC;CAOjC,MAAM,CAAC,mBAAA,GAAA,MAAA,gBAAiC,IAAIA,4BAAAA,qBAAqB,CAAC;CAClE,MAAM,CAAC,WAAA,GAAA,MAAA,gBAEH,IAAIC,4BAAAA,cAA8B,gBAAgB;EAChD,UAAU,QAAQ,YAAY;EAC9B,mBAAmB,QAAQ;EAC3B,wBAAwB,QAAQ;EAChC,WAAW,QAAQ,aAAaC,4BAAAA;EACjC,CAAC,CACL;AAED,EAAA,GAAA,MAAA,sBACE,OAAO,WACP,OAAO,aACP,OAAO,YACR;CAED,MAAM,CAAC,QAAQ,eAAA,GAAA,MAAA,UAAuB,GAAG;CAEzC,MAAM,CAAC,UAAU,cAAcC,eAAAA,wBAAwB,QAAQ;CAC/D,MAAM,eAAA,GAAA,MAAA,QAAoC,SAAS;AAGnD,EAAA,GAAA,MAAA,iBAAgB;AACd,MAAI,YAAY,YAAY,UAAU;AACpC,eAAY,UAAU;AACtB,UAAO,OAAO;;IAEf,CAAC,UAAU,OAAO,CAAC;CAEtB,MAAM,gBAAA,GAAA,MAAA,cACH,gBAA+B;AAC9B,MAAI,gBAAgB,YAAY,SAAS;AACvC,eAAY,UAAU;AACtB,UAAO,OAAO;;IAGlB,CAAC,OAAO,CACT;CAED,MAAM,eAAe,UAAgC;EACnD,MAAM,cAAc,QAAQ,eAAe;AAC3C,SAAO,MAAM,QAAQ,MAAM,aAAa,GACnC,MAAM,eACP,EAAE;;CAGR,MAAM,eAAe,SAAoB,aAAmC;EAC1E,MAAM,cAAc,QAAQ,eAAe;AAC3C,SAAO;GAAE,GAAG;IAAU,cAAc;GAAU;;CAGhD,MAAM,gBAAgB,QAAQ,iBAAkB,EAAE;CAOlD,MAAM,kBAAkB,YAAY,cAAc;CAClD,MAAM,6BACJ,QAAQ,0BACR,CAAC,OAAO,aACR,gBAAgB,SAAS;AAE3B,EAAA,GAAA,MAAA,iBAAgB;AACd,MAAI,2BAEF,QAAO,qBAAqB,iBAAiB,EAAE,iBAAiB,MAAM,CAAC;IAKxE,CAAC,4BAA4B,gBAAgB,OAAO,CAAC;CAExD,MAAM,aAAa,OAAO,KAAK,eAAe,EAAE,QAAQ,QAAQ,QAAQ,CAAC;CAEzE,MAAM,eAAe,OACnB,QACA,kBACG;AACH,MAAI,aAAa,YAAY,SAAS;AACpC,eAAY,UAAU;AACtB,UAAO,OAAO;;EAGhB,IAAI,iBAAiB,YAAY,WAAW,eAAe;AAE3D,SAAO,sBAAsB;AAC3B,OAAI,eAAe,oBAAoB,KACrC,QAAO;IACL,GAAG;IACH,GAAI,OAAO,cAAc,qBAAqB,aAC1C,cAAc,iBAAiB,cAAc,GAC7C,cAAc;IACnB;AAGH,UAAO,EAAE,GAAG,eAAe;IAC3B;AAEF,QAAM,OAAO,MACX,OAAO,WAAwB;AAC7B,OAAI,CAAC,gBAAgB;AACnB,qBAAiB,OAAO,YAAY;AACpC,gBAAY,UAAU;AACtB,eAAW,eAAe;;AAG5B,OAAI,CAAC,eACH,OAAM,IAAI,MAAM,oCAAoC;AAGtD,UAAO,QAAQ,UAAU,OAAO;IAC9B,OAAO;IACP,SAAS,eAAe;IACxB,SAAS,eAAe;IACxB,iBAAiB,eAAe;IAChC;IACA,QAAQ;KACN,GAAG,eAAe;KAClB,cAAc;MACZ,WAAW;MACX,GAAG,eAAe,QAAQ;MAC3B;KACF;IACF,CAAC;KAIJ;GACE;GACA;GAEA,eAAe,EAAE;GACjB,WAAW;GAEX,iBAAiB;AACf,QAAI,CAAC,eAAgB,QAAO,KAAA;IAE5B,MAAM,cAAc,OAAO,UAAU;AACrC,YAAQ,WACN,iCAAiC,aAAa,eAAe,EAC7D,KAAA,EACD;;GAIH,QAAQ,OAAO;AACb,YAAQ,UAAU,OAAO,KAAA,EAAU;AACnC,mBAAe,UAAU,OAAO,KAAA,EAAU;;GAE7C,CACF;;CAGH,MAAM,SAAS,OACb,QACA,kBACG;AACH,QAAM,aAAa,QAAQ,cAAc;;AAG3C,QAAO;EACL,IAAI,SAAS;AACX,UAAO,OAAO,UAAW,EAAE;;EAG7B,OAAO,OAAO;EACd,WAAW,OAAO;EAElB;EACA;EACA;EAEA;EACA,WAAW;EAEX,oBACE,SACA,OACwC;GACxC,MAAM,iBAAiB,eAAe,IAAI,QAAQ,GAAG,EAAE;AACvD,OAAI,kBAAkB,KACpB,QAAO;IACL,WAAW,QAAQ,MAAM,OAAO,MAAM;IACtC,gBAAgB,KAAA;IAChB,QAAQ,KAAA;IACR,eAAe,KAAA;IACf;IACD;;EAKL,IAAI,aAAyC;AAC3C,OACE,OAAO,UAAU,QACjB,mBAAmB,OAAO,UAC1B,MAAM,QAAQ,OAAO,OAAO,cAAc,EAC1C;IACA,MAAM,kBAAkB,OAAO,OAAO;AACtC,QAAI,gBAAgB,WAAW,EAAG,QAAO,CAAC,EAAE,MAAM,cAAc,CAAC;AACjE,WAAO;;AAGT,UAAO,EAAE;;EAGX,IAAI,YAAkD;AACpD,WAAA,GAAA,4BAAA,mBAAwC,OAAO,OAAO;;EAGxD,IAAI,WAA0B;AAC5B,OAAI,CAAC,OAAO,OAAQ,QAAO,EAAE;AAC7B,WAAA,GAAA,4BAAA,wBACE,YAAY,OAAO,OAAO,CAC3B;;EAGH,IAAI,YAAY;AACd,OAAI,CAAC,OAAO,OAAQ,QAAO,EAAE;AAE7B,WAAA,GAAA,+BAAA,yBADa,YAAY,OAAO,OAAO,CACW;;EAGpD,aAAa,SAAS;AACpB,OAAI,CAAC,OAAO,OAAQ,QAAO,EAAE;AAG7B,WAAA,GAAA,+BAAA,yBAFa,YAAY,OAAO,OAAO,CACyB,CAC5C,QAAQ,OAAO,GAAG,UAAU,OAAO,QAAQ,GAAG;;EAGpE,IAAI,YAAY;AACd,UAAO,OAAO,cAAc;;EAG9B,IAAI,kBAAkB;AACpB,UAAO,OAAO,oBAAoB;;EAGpC,YAAY,YAAoB;AAC9B,UAAO,OAAO,YAAY,WAAW;;EAGvC,mBAAmB,MAAc;AAC/B,UAAO,OAAO,mBAAmB,KAAK;;EAGxC,sBAAsB,WAAmB;AACvC,UAAO,OAAO,sBAAsB,UAAU;;EAGhD,OAAO;GACL,IAAI,UAAU;AACZ,WAAO,EAAE;;GAEX,IAAI,OAAO;AACT,WAAO;;GAET,MAAM,SAAS;AACb,WAAO;;GAET,MAAM,QAAQ;GACf;EACF"}
1
+ {"version":3,"file":"stream.custom.cjs","names":["MessageTupleManager","StreamManager","toMessageClass","useControllableThreadId"],"sources":["../src/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n StreamManager,\n MessageTupleManager,\n extractInterrupts,\n normalizeInterruptsList,\n FetchStreamTransport,\n toMessageClass,\n ensureMessageInstances,\n type EventStreamEvent,\n type GetUpdateType,\n type GetCustomEventType,\n type GetInterruptType,\n type GetToolCallsType,\n type GetConfigurableType,\n type AnyStreamCustomOptions,\n type CustomSubmitOptions,\n type MessageMetadata,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { getToolCallsWithResults } from \"@langchain/langgraph-sdk/utils\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n BagTemplate,\n Message,\n Interrupt,\n ThreadState,\n} from \"@langchain/langgraph-sdk\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { UseStreamCustom } from \"./types.js\";\n\nexport { FetchStreamTransport };\n\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>,\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n }),\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot,\n );\n\n const [branch, _setBranch] = useState(\"\");\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n }\n },\n [stream],\n );\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submitDirect = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n if (threadId !== threadIdRef.current) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n\n let usableThreadId = threadIdRef.current ?? submitOptions?.threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = stream.values ?? historyValues;\n options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined,\n );\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n },\n );\n };\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n await submitDirect(values, submitOptions);\n };\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n branch,\n setBranch: _setBranch,\n\n getMessagesMetadata(\n message: BaseMessage,\n index?: number,\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n const valueInterrupts = stream.values.__interrupt__;\n if (valueInterrupts.length === 0) return [{ when: \"breakpoint\" }];\n return normalizeInterruptsList(\n valueInterrupts as Interrupt<InterruptType>[],\n );\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n return extractInterrupts<InterruptType>(stream.values);\n },\n\n get messages(): BaseMessage[] {\n if (!stream.values) return [];\n return ensureMessageInstances(\n getMessages(stream.values),\n ) as BaseMessage[];\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n\n queue: {\n get entries() {\n return [];\n },\n get size() {\n return 0;\n },\n async cancel() {\n return false;\n },\n async clear() {},\n },\n };\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useControllableThreadId } from "./thread.js";
3
3
  import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
4
- import { FetchStreamTransport, MessageTupleManager, StreamManager, ensureMessageInstances, extractInterrupts, toMessageClass } from "@langchain/langgraph-sdk/ui";
4
+ import { FetchStreamTransport, MessageTupleManager, StreamManager, ensureMessageInstances, extractInterrupts, normalizeInterruptsList, toMessageClass } from "@langchain/langgraph-sdk/ui";
5
5
  import { getToolCallsWithResults } from "@langchain/langgraph-sdk/utils";
6
6
  //#region src/stream.custom.tsx
7
7
  function createCustomTransportThreadState(values, threadId) {
@@ -140,7 +140,7 @@ function useStreamCustom(options) {
140
140
  if (stream.values != null && "__interrupt__" in stream.values && Array.isArray(stream.values.__interrupt__)) {
141
141
  const valueInterrupts = stream.values.__interrupt__;
142
142
  if (valueInterrupts.length === 0) return [{ when: "breakpoint" }];
143
- return valueInterrupts;
143
+ return normalizeInterruptsList(valueInterrupts);
144
144
  }
145
145
  return [];
146
146
  },
@@ -1 +1 @@
1
- {"version":3,"file":"stream.custom.js","names":[],"sources":["../src/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n StreamManager,\n MessageTupleManager,\n extractInterrupts,\n FetchStreamTransport,\n toMessageClass,\n ensureMessageInstances,\n type EventStreamEvent,\n type GetUpdateType,\n type GetCustomEventType,\n type GetInterruptType,\n type GetToolCallsType,\n type GetConfigurableType,\n type AnyStreamCustomOptions,\n type CustomSubmitOptions,\n type MessageMetadata,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { getToolCallsWithResults } from \"@langchain/langgraph-sdk/utils\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n BagTemplate,\n Message,\n Interrupt,\n ThreadState,\n} from \"@langchain/langgraph-sdk\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { UseStreamCustom } from \"./types.js\";\n\nexport { FetchStreamTransport };\n\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>,\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n }),\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot,\n );\n\n const [branch, _setBranch] = useState(\"\");\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n }\n },\n [stream],\n );\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submitDirect = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n if (threadId !== threadIdRef.current) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n\n let usableThreadId = threadIdRef.current ?? submitOptions?.threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = stream.values ?? historyValues;\n options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined,\n );\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n },\n );\n };\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n await submitDirect(values, submitOptions);\n };\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n branch,\n setBranch: _setBranch,\n\n getMessagesMetadata(\n message: BaseMessage,\n index?: number,\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n const valueInterrupts = stream.values.__interrupt__;\n if (valueInterrupts.length === 0) return [{ when: \"breakpoint\" }];\n return valueInterrupts;\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n return extractInterrupts<InterruptType>(stream.values);\n },\n\n get messages(): BaseMessage[] {\n if (!stream.values) return [];\n return ensureMessageInstances(\n getMessages(stream.values),\n ) as BaseMessage[];\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n\n queue: {\n get entries() {\n return [];\n },\n get size() {\n return 0;\n },\n async cancel() {\n return false;\n },\n async clear() {},\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"stream.custom.js","names":[],"sources":["../src/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n StreamManager,\n MessageTupleManager,\n extractInterrupts,\n normalizeInterruptsList,\n FetchStreamTransport,\n toMessageClass,\n ensureMessageInstances,\n type EventStreamEvent,\n type GetUpdateType,\n type GetCustomEventType,\n type GetInterruptType,\n type GetToolCallsType,\n type GetConfigurableType,\n type AnyStreamCustomOptions,\n type CustomSubmitOptions,\n type MessageMetadata,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { getToolCallsWithResults } from \"@langchain/langgraph-sdk/utils\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n BagTemplate,\n Message,\n Interrupt,\n ThreadState,\n} from \"@langchain/langgraph-sdk\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { UseStreamCustom } from \"./types.js\";\n\nexport { FetchStreamTransport };\n\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>,\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n }),\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot,\n );\n\n const [branch, _setBranch] = useState(\"\");\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n }\n },\n [stream],\n );\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submitDirect = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n if (threadId !== threadIdRef.current) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n\n let usableThreadId = threadIdRef.current ?? submitOptions?.threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = stream.values ?? historyValues;\n options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined,\n );\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n },\n );\n };\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n await submitDirect(values, submitOptions);\n };\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n branch,\n setBranch: _setBranch,\n\n getMessagesMetadata(\n message: BaseMessage,\n index?: number,\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n const valueInterrupts = stream.values.__interrupt__;\n if (valueInterrupts.length === 0) return [{ when: \"breakpoint\" }];\n return normalizeInterruptsList(\n valueInterrupts as Interrupt<InterruptType>[],\n );\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n return extractInterrupts<InterruptType>(stream.values);\n },\n\n get messages(): BaseMessage[] {\n if (!stream.values) return [];\n return ensureMessageInstances(\n getMessages(stream.values),\n ) as BaseMessage[];\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n\n queue: {\n get entries() {\n return [];\n },\n get size() {\n return 0;\n },\n async cancel() {\n return false;\n },\n async clear() {},\n },\n };\n}\n"],"mappings":"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"}
package/dist/stream.d.cts CHANGED
@@ -1,52 +1,8 @@
1
1
  import { UseStreamCustomOptions as UseStreamCustomOptions$1 } from "./types.cjs";
2
- import { AIMessage, BaseMessage, ToolMessage } from "@langchain/core/messages";
3
- import { BagTemplate, DefaultToolCall, ToolCallWithResult } from "@langchain/langgraph-sdk";
4
- import { AcceptBaseMessages, HistoryWithBaseMessages, InferBag, InferStateType, MessageMetadata, ResolveStreamInterface, ResolveStreamOptions, SubagentStreamInterface } from "@langchain/langgraph-sdk/ui";
2
+ import { BagTemplate } from "@langchain/langgraph-sdk";
3
+ import { ClassSubagentStreamInterface, InferBag, InferStateType, ResolveStreamInterface, ResolveStreamOptions, WithClassMessages, WithClassMessages as WithClassMessages$1 } from "@langchain/langgraph-sdk/ui";
5
4
 
6
5
  //#region src/stream.d.ts
7
- type ClassToolCallWithResult<T> = T extends ToolCallWithResult<infer TC, unknown, unknown> ? ToolCallWithResult<TC, ToolMessage, AIMessage> : T;
8
- type ClassSubagentStreamInterface<StateType = Record<string, unknown>, ToolCall = DefaultToolCall, SubagentName extends string = string> = Omit<SubagentStreamInterface<StateType, ToolCall, SubagentName>, "messages"> & {
9
- messages: BaseMessage[];
10
- };
11
- /**
12
- * Maps a stream interface to use @langchain/core BaseMessage class instances
13
- * instead of plain Message objects for the `messages` property, and remaps
14
- * tool call types to use @langchain/core message classes.
15
- */
16
- type WithClassMessages<T> = Omit<T, "messages" | "history" | "getMessagesMetadata" | "toolCalls" | "getToolCalls" | "submit" | "subagents" | "activeSubagents" | "getSubagent" | "getSubagentsByType" | "getSubagentsByMessage"> & {
17
- messages: BaseMessage[];
18
- getMessagesMetadata: (message: BaseMessage, index?: number) => MessageMetadata<Record<string, unknown>> | undefined;
19
- } & ("history" extends keyof T ? {
20
- history: HistoryWithBaseMessages<T["history"]>;
21
- } : unknown) & ("submit" extends keyof T ? {
22
- submit: T extends {
23
- submit: (values: infer V, options?: infer O) => infer Ret;
24
- } ? (values: AcceptBaseMessages<Exclude<V, null | undefined>> | null | undefined, options?: O) => Ret : never;
25
- } : unknown) & ("toolCalls" extends keyof T ? {
26
- toolCalls: T extends {
27
- toolCalls: (infer TC)[];
28
- } ? ClassToolCallWithResult<TC>[] : never;
29
- } : unknown) & ("getToolCalls" extends keyof T ? {
30
- getToolCalls: T extends {
31
- getToolCalls: (message: infer _M) => (infer TC)[];
32
- } ? (message: AIMessage) => ClassToolCallWithResult<TC>[] : never;
33
- } : unknown) & ("subagents" extends keyof T ? {
34
- subagents: T extends {
35
- subagents: Map<string, SubagentStreamInterface<infer S, infer TC, infer N>>;
36
- } ? Map<string, ClassSubagentStreamInterface<S, TC, N>> : never;
37
- activeSubagents: T extends {
38
- activeSubagents: SubagentStreamInterface<infer S, infer TC, infer N>[];
39
- } ? ClassSubagentStreamInterface<S, TC, N>[] : never;
40
- getSubagent: T extends {
41
- getSubagent: (id: string) => SubagentStreamInterface<infer S, infer TC, infer N> | undefined;
42
- } ? (toolCallId: string) => ClassSubagentStreamInterface<S, TC, N> | undefined : never;
43
- getSubagentsByType: T extends {
44
- getSubagentsByType: (type: string) => SubagentStreamInterface<infer S, infer TC, infer N>[];
45
- } ? (type: string) => ClassSubagentStreamInterface<S, TC, N>[] : never;
46
- getSubagentsByMessage: T extends {
47
- getSubagentsByMessage: (id: string) => SubagentStreamInterface<infer S, infer TC, infer N>[];
48
- } ? (messageId: string) => ClassSubagentStreamInterface<S, TC, N>[] : never;
49
- } : unknown);
50
6
  /**
51
7
  * A React hook that provides seamless integration with LangGraph streaming capabilities.
52
8
  *
@@ -214,5 +170,5 @@ declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate
214
170
  */
215
171
  declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions$1<InferStateType<T>, InferBag<T, Bag>>): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;
216
172
  //#endregion
217
- export { ClassSubagentStreamInterface, WithClassMessages, useStream };
173
+ export { type ClassSubagentStreamInterface, type WithClassMessages$1 as WithClassMessages, useStream };
218
174
  //# sourceMappingURL=stream.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.cts","names":[],"sources":["../src/stream.tsx"],"mappings":";;;;;;KAqCK,uBAAA,MACH,CAAA,SAAU,kBAAA,+BACN,kBAAA,CAAmB,EAAA,EAAI,WAAA,EAAiB,SAAA,IACxC,CAAA;AAAA,KAEM,4BAAA,aACE,MAAA,8BACD,eAAA,0CAET,IAAA,CACF,uBAAA,CAAwB,SAAA,EAAW,QAAA,EAAU,YAAA;EAG7C,QAAA,EAAU,WAAA;AAAA;;;;;;KAQA,iBAAA,MAAuB,IAAA,CACjC,CAAA;EAaA,QAAA,EAAU,WAAA;EACV,mBAAA,GACE,OAAA,EAAS,WAAA,EACT,KAAA,cACG,eAAA,CAAgB,MAAA;AAAA,6BACM,CAAA;EACrB,OAAA,EAAS,uBAAA,CAAwB,CAAA;AAAA,uCAEf,CAAA;EAElB,MAAA,EAAQ,CAAA;IACN,MAAA,GAAS,MAAA,WAAiB,OAAA;EAAA,KAGtB,MAAA,EACI,kBAAA,CAAmB,OAAA,CAAQ,CAAA,yCAG/B,OAAA,GAAU,CAAA,KACP,GAAA;AAAA,0CAIY,CAAA;EAErB,SAAA,EAAW,CAAA;IAAY,SAAA;EAAA,IACnB,uBAAA,CAAwB,EAAA;AAAA,6CAIJ,CAAA;EAExB,YAAA,EAAc,CAAA;IACZ,YAAA,GAAe,OAAA;EAAA,KAEZ,OAAA,EAAS,SAAA,KAAkB,uBAAA,CAAwB,EAAA;AAAA,0CAInC,CAAA;EAErB,SAAA,EAAW,CAAA;IACT,SAAA,EAAW,GAAA,SAET,uBAAA;EAAA,IAGA,GAAA,SAAY,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAEpD,eAAA,EAAiB,CAAA;IACf,eAAA,EAAiB,uBAAA;EAAA,IAMf,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAExC,WAAA,EAAa,CAAA;IACX,WAAA,GACE,EAAA,aACG,uBAAA;EAAA,KAGD,UAAA,aACG,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAE7C,kBAAA,EAAoB,CAAA;IAClB,kBAAA,GACE,IAAA,aACG,uBAAA;EAAA,KAEF,IAAA,aAAiB,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAE1D,qBAAA,EAAuB,CAAA;IACrB,qBAAA,GACE,EAAA,aACG,uBAAA;EAAA,KAEF,SAAA,aAAsB,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;AAAA;;;;;;;;;;AA7FvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsPgB,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,oBAAA,CAAqB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA,KAC5C,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA;;;;;;;;;;;;;;;;;iBAkB3C,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,wBAAA,CAAuB,cAAA,CAAe,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,GAAA,KAC9D,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA"}
1
+ {"version":3,"file":"stream.d.cts","names":[],"sources":["../src/stream.tsx"],"mappings":";;;;;;AA8LA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAvBgB,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,oBAAA,CAAqB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA,KAC5C,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA;;;;;;;;;;;;;;;;;iBAkB3C,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,wBAAA,CAAuB,cAAA,CAAe,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,GAAA,KAC9D,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA"}
package/dist/stream.d.ts CHANGED
@@ -1,52 +1,8 @@
1
1
  import { UseStreamCustomOptions as UseStreamCustomOptions$1 } from "./types.js";
2
- import { AcceptBaseMessages, HistoryWithBaseMessages, InferBag, InferStateType, MessageMetadata, ResolveStreamInterface, ResolveStreamOptions, SubagentStreamInterface } from "@langchain/langgraph-sdk/ui";
3
- import { AIMessage, BaseMessage, ToolMessage } from "@langchain/core/messages";
4
- import { BagTemplate, DefaultToolCall, ToolCallWithResult } from "@langchain/langgraph-sdk";
2
+ import { ClassSubagentStreamInterface, InferBag, InferStateType, ResolveStreamInterface, ResolveStreamOptions, WithClassMessages, WithClassMessages as WithClassMessages$1 } from "@langchain/langgraph-sdk/ui";
3
+ import { BagTemplate } from "@langchain/langgraph-sdk";
5
4
 
6
5
  //#region src/stream.d.ts
7
- type ClassToolCallWithResult<T> = T extends ToolCallWithResult<infer TC, unknown, unknown> ? ToolCallWithResult<TC, ToolMessage, AIMessage> : T;
8
- type ClassSubagentStreamInterface<StateType = Record<string, unknown>, ToolCall = DefaultToolCall, SubagentName extends string = string> = Omit<SubagentStreamInterface<StateType, ToolCall, SubagentName>, "messages"> & {
9
- messages: BaseMessage[];
10
- };
11
- /**
12
- * Maps a stream interface to use @langchain/core BaseMessage class instances
13
- * instead of plain Message objects for the `messages` property, and remaps
14
- * tool call types to use @langchain/core message classes.
15
- */
16
- type WithClassMessages<T> = Omit<T, "messages" | "history" | "getMessagesMetadata" | "toolCalls" | "getToolCalls" | "submit" | "subagents" | "activeSubagents" | "getSubagent" | "getSubagentsByType" | "getSubagentsByMessage"> & {
17
- messages: BaseMessage[];
18
- getMessagesMetadata: (message: BaseMessage, index?: number) => MessageMetadata<Record<string, unknown>> | undefined;
19
- } & ("history" extends keyof T ? {
20
- history: HistoryWithBaseMessages<T["history"]>;
21
- } : unknown) & ("submit" extends keyof T ? {
22
- submit: T extends {
23
- submit: (values: infer V, options?: infer O) => infer Ret;
24
- } ? (values: AcceptBaseMessages<Exclude<V, null | undefined>> | null | undefined, options?: O) => Ret : never;
25
- } : unknown) & ("toolCalls" extends keyof T ? {
26
- toolCalls: T extends {
27
- toolCalls: (infer TC)[];
28
- } ? ClassToolCallWithResult<TC>[] : never;
29
- } : unknown) & ("getToolCalls" extends keyof T ? {
30
- getToolCalls: T extends {
31
- getToolCalls: (message: infer _M) => (infer TC)[];
32
- } ? (message: AIMessage) => ClassToolCallWithResult<TC>[] : never;
33
- } : unknown) & ("subagents" extends keyof T ? {
34
- subagents: T extends {
35
- subagents: Map<string, SubagentStreamInterface<infer S, infer TC, infer N>>;
36
- } ? Map<string, ClassSubagentStreamInterface<S, TC, N>> : never;
37
- activeSubagents: T extends {
38
- activeSubagents: SubagentStreamInterface<infer S, infer TC, infer N>[];
39
- } ? ClassSubagentStreamInterface<S, TC, N>[] : never;
40
- getSubagent: T extends {
41
- getSubagent: (id: string) => SubagentStreamInterface<infer S, infer TC, infer N> | undefined;
42
- } ? (toolCallId: string) => ClassSubagentStreamInterface<S, TC, N> | undefined : never;
43
- getSubagentsByType: T extends {
44
- getSubagentsByType: (type: string) => SubagentStreamInterface<infer S, infer TC, infer N>[];
45
- } ? (type: string) => ClassSubagentStreamInterface<S, TC, N>[] : never;
46
- getSubagentsByMessage: T extends {
47
- getSubagentsByMessage: (id: string) => SubagentStreamInterface<infer S, infer TC, infer N>[];
48
- } ? (messageId: string) => ClassSubagentStreamInterface<S, TC, N>[] : never;
49
- } : unknown);
50
6
  /**
51
7
  * A React hook that provides seamless integration with LangGraph streaming capabilities.
52
8
  *
@@ -214,5 +170,5 @@ declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate
214
170
  */
215
171
  declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions$1<InferStateType<T>, InferBag<T, Bag>>): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;
216
172
  //#endregion
217
- export { ClassSubagentStreamInterface, WithClassMessages, useStream };
173
+ export { type ClassSubagentStreamInterface, type WithClassMessages$1 as WithClassMessages, useStream };
218
174
  //# sourceMappingURL=stream.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","names":[],"sources":["../src/stream.tsx"],"mappings":";;;;;;KAqCK,uBAAA,MACH,CAAA,SAAU,kBAAA,+BACN,kBAAA,CAAmB,EAAA,EAAI,WAAA,EAAiB,SAAA,IACxC,CAAA;AAAA,KAEM,4BAAA,aACE,MAAA,8BACD,eAAA,0CAET,IAAA,CACF,uBAAA,CAAwB,SAAA,EAAW,QAAA,EAAU,YAAA;EAG7C,QAAA,EAAU,WAAA;AAAA;;;;;;KAQA,iBAAA,MAAuB,IAAA,CACjC,CAAA;EAaA,QAAA,EAAU,WAAA;EACV,mBAAA,GACE,OAAA,EAAS,WAAA,EACT,KAAA,cACG,eAAA,CAAgB,MAAA;AAAA,6BACM,CAAA;EACrB,OAAA,EAAS,uBAAA,CAAwB,CAAA;AAAA,uCAEf,CAAA;EAElB,MAAA,EAAQ,CAAA;IACN,MAAA,GAAS,MAAA,WAAiB,OAAA;EAAA,KAGtB,MAAA,EACI,kBAAA,CAAmB,OAAA,CAAQ,CAAA,yCAG/B,OAAA,GAAU,CAAA,KACP,GAAA;AAAA,0CAIY,CAAA;EAErB,SAAA,EAAW,CAAA;IAAY,SAAA;EAAA,IACnB,uBAAA,CAAwB,EAAA;AAAA,6CAIJ,CAAA;EAExB,YAAA,EAAc,CAAA;IACZ,YAAA,GAAe,OAAA;EAAA,KAEZ,OAAA,EAAS,SAAA,KAAkB,uBAAA,CAAwB,EAAA;AAAA,0CAInC,CAAA;EAErB,SAAA,EAAW,CAAA;IACT,SAAA,EAAW,GAAA,SAET,uBAAA;EAAA,IAGA,GAAA,SAAY,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAEpD,eAAA,EAAiB,CAAA;IACf,eAAA,EAAiB,uBAAA;EAAA,IAMf,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAExC,WAAA,EAAa,CAAA;IACX,WAAA,GACE,EAAA,aACG,uBAAA;EAAA,KAGD,UAAA,aACG,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAE7C,kBAAA,EAAoB,CAAA;IAClB,kBAAA,GACE,IAAA,aACG,uBAAA;EAAA,KAEF,IAAA,aAAiB,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAE1D,qBAAA,EAAuB,CAAA;IACrB,qBAAA,GACE,EAAA,aACG,uBAAA;EAAA,KAEF,SAAA,aAAsB,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;AAAA;;;;;;;;;;AA7FvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsPgB,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,oBAAA,CAAqB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA,KAC5C,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA;;;;;;;;;;;;;;;;;iBAkB3C,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,wBAAA,CAAuB,cAAA,CAAe,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,GAAA,KAC9D,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA"}
1
+ {"version":3,"file":"stream.d.ts","names":[],"sources":["../src/stream.tsx"],"mappings":";;;;;;AA8LA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAvBgB,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,oBAAA,CAAqB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA,KAC5C,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA;;;;;;;;;;;;;;;;;iBAkB3C,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,wBAAA,CAAuB,cAAA,CAAe,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,GAAA,KAC9D,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA"}
package/dist/stream.js CHANGED
@@ -5,10 +5,12 @@ import { useState } from "react";
5
5
  function isCustomOptions(options) {
6
6
  return "transport" in options;
7
7
  }
8
+ function selectStreamImplementation(options) {
9
+ return isCustomOptions(options) ? useStreamCustom : useStreamLGP;
10
+ }
8
11
  function useStream(options) {
9
- const [isCustom] = useState(isCustomOptions(options));
10
- if (isCustom) return useStreamCustom(options);
11
- return useStreamLGP(options);
12
+ const [useSelectedStream] = useState(() => selectStreamImplementation(options));
13
+ return useSelectedStream(options);
12
14
  }
13
15
  //#endregion
14
16
  export { useStream };
@@ -1 +1 @@
1
- {"version":3,"file":"stream.js","names":[],"sources":["../src/stream.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport type {\n BaseMessage,\n ToolMessage as CoreToolMessage,\n AIMessage as CoreAIMessage,\n} from \"@langchain/core/messages\";\nimport type {\n BagTemplate,\n ToolCallWithResult,\n DefaultToolCall,\n} from \"@langchain/langgraph-sdk\";\nimport type {\n UseStreamOptions,\n AcceptBaseMessages,\n ResolveStreamInterface,\n ResolveStreamOptions,\n InferBag,\n InferStateType,\n MessageMetadata,\n SubagentStreamInterface,\n HistoryWithBaseMessages,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { useStreamLGP } from \"./stream.lgp.js\";\nimport { useStreamCustom } from \"./stream.custom.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\n\nfunction isCustomOptions<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options:\n | UseStreamOptions<StateType, Bag>\n | UseStreamCustomOptions<StateType, Bag>,\n): options is UseStreamCustomOptions<StateType, Bag> {\n return \"transport\" in options;\n}\n\ntype ClassToolCallWithResult<T> =\n T extends ToolCallWithResult<infer TC, unknown, unknown>\n ? ToolCallWithResult<TC, CoreToolMessage, CoreAIMessage>\n : T;\n\nexport type ClassSubagentStreamInterface<\n StateType = Record<string, unknown>,\n ToolCall = DefaultToolCall,\n SubagentName extends string = string,\n> = Omit<\n SubagentStreamInterface<StateType, ToolCall, SubagentName>,\n \"messages\"\n> & {\n messages: BaseMessage[];\n};\n\n/**\n * Maps a stream interface to use @langchain/core BaseMessage class instances\n * instead of plain Message objects for the `messages` property, and remaps\n * tool call types to use @langchain/core message classes.\n */\nexport type WithClassMessages<T> = Omit<\n T,\n | \"messages\"\n | \"history\"\n | \"getMessagesMetadata\"\n | \"toolCalls\"\n | \"getToolCalls\"\n | \"submit\"\n | \"subagents\"\n | \"activeSubagents\"\n | \"getSubagent\"\n | \"getSubagentsByType\"\n | \"getSubagentsByMessage\"\n> & {\n messages: BaseMessage[];\n getMessagesMetadata: (\n message: BaseMessage,\n index?: number,\n ) => MessageMetadata<Record<string, unknown>> | undefined;\n} & (\"history\" extends keyof T\n ? { history: HistoryWithBaseMessages<T[\"history\"]> }\n : unknown) &\n (\"submit\" extends keyof T\n ? {\n submit: T extends {\n submit: (values: infer V, options?: infer O) => infer Ret;\n }\n ? (\n values:\n | AcceptBaseMessages<Exclude<V, null | undefined>>\n | null\n | undefined,\n options?: O,\n ) => Ret\n : never;\n }\n : unknown) &\n (\"toolCalls\" extends keyof T\n ? {\n toolCalls: T extends { toolCalls: (infer TC)[] }\n ? ClassToolCallWithResult<TC>[]\n : never;\n }\n : unknown) &\n (\"getToolCalls\" extends keyof T\n ? {\n getToolCalls: T extends {\n getToolCalls: (message: infer _M) => (infer TC)[];\n }\n ? (message: CoreAIMessage) => ClassToolCallWithResult<TC>[]\n : never;\n }\n : unknown) &\n (\"subagents\" extends keyof T\n ? {\n subagents: T extends {\n subagents: Map<\n string,\n SubagentStreamInterface<infer S, infer TC, infer N>\n >;\n }\n ? Map<string, ClassSubagentStreamInterface<S, TC, N>>\n : never;\n activeSubagents: T extends {\n activeSubagents: SubagentStreamInterface<\n infer S,\n infer TC,\n infer N\n >[];\n }\n ? ClassSubagentStreamInterface<S, TC, N>[]\n : never;\n getSubagent: T extends {\n getSubagent: (\n id: string,\n ) => SubagentStreamInterface<infer S, infer TC, infer N> | undefined;\n }\n ? (\n toolCallId: string,\n ) => ClassSubagentStreamInterface<S, TC, N> | undefined\n : never;\n getSubagentsByType: T extends {\n getSubagentsByType: (\n type: string,\n ) => SubagentStreamInterface<infer S, infer TC, infer N>[];\n }\n ? (type: string) => ClassSubagentStreamInterface<S, TC, N>[]\n : never;\n getSubagentsByMessage: T extends {\n getSubagentsByMessage: (\n id: string,\n ) => SubagentStreamInterface<infer S, infer TC, infer N>[];\n }\n ? (messageId: string) => ClassSubagentStreamInterface<S, TC, N>[]\n : never;\n }\n : unknown);\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, subagent streams, and errors.\n *\n * ## Usage with ReactAgent (recommended for createAgent users)\n *\n * When using `createAgent` from `@langchain/langgraph`, you can pass `typeof agent` as the\n * type parameter to automatically infer tool call types:\n *\n * @example\n * ```typescript\n * // In your agent file (e.g., agent.ts)\n * import { createAgent, tool } from \"langchain\";\n * import { z } from \"zod\";\n *\n * const getWeather = tool(\n * async ({ location }) => `Weather in ${location}`,\n * { name: \"get_weather\", schema: z.object({ location: z.string() }) }\n * );\n *\n * export const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather],\n * });\n *\n * // In your React component\n * import { agent } from \"./agent\";\n *\n * function Chat() {\n * // Tool calls are automatically typed from the agent's tools!\n * const stream = useStream<typeof agent>({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.toolCalls[0].call.name is typed as \"get_weather\"\n * // stream.toolCalls[0].call.args is typed as { location: string }\n * }\n * ```\n *\n * ## Usage with StateGraph (for custom LangGraph applications)\n *\n * When building custom graphs with `StateGraph`, embed your tool call types directly\n * in your state's messages property using `Message<MyToolCalls>`:\n *\n * @example\n * ```typescript\n * import { Message } from \"@langchain/langgraph-sdk\";\n *\n * // Define your tool call types as a discriminated union\n * type MyToolCalls =\n * | { name: \"search\"; args: { query: string }; id?: string }\n * | { name: \"calculate\"; args: { expression: string }; id?: string };\n *\n * // Embed tool call types in your state's messages\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * context?: string;\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.values is typed as MyGraphState\n * // stream.toolCalls[0].call.name is typed as \"search\" | \"calculate\"\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With additional type configuration (interrupts, configurable)\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState, {\n * InterruptType: { question: string };\n * ConfigurableType: { userId: string };\n * }>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.interrupt is typed as { question: string } | undefined\n * }\n * ```\n *\n * ## Usage with Deep Agents (subagent streaming, experimental)\n *\n * For agents that spawn subagents (nested graphs), use `filterSubagentMessages`\n * to keep the main message stream clean while tracking subagent activity separately:\n *\n * @example\n * ```typescript\n * import { useStream, SubagentStream } from \"@langchain/langgraph-sdk/react\";\n * import type { agent } from \"./agent\";\n *\n * function DeepAgentChat() {\n * const stream = useStream<typeof agent>({\n * assistantId: \"deepagent\",\n * apiUrl: \"http://localhost:2024\",\n * // Filter subagent messages from main stream\n * filterSubagentMessages: true,\n * });\n *\n * const handleSubmit = (content: string) => {\n * stream.submit(\n * { messages: [{ content, type: \"human\" }] },\n * { streamSubgraphs: true } // Enable subgraph streaming\n * );\n * };\n *\n * // Access subagent streams via stream.subagents (Map<string, SubagentStream>)\n * const subagentList = [...stream.subagents.values()];\n *\n * return (\n * <div>\n * {stream.messages.map((msg) => <Message key={msg.id} message={msg} />)}\n *\n * {subagentList.map((subagent) => (\n * <SubagentCard\n * key={subagent.id}\n * status={subagent.status} // \"pending\" | \"running\" | \"complete\" | \"error\"\n * messages={subagent.messages}\n * toolCalls={subagent.toolCalls}\n * />\n * ))}\n * </div>\n * );\n * }\n * ```\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: ResolveStreamOptions<T, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useStream(options: any): any {\n // Store this in useState to make sure we're not changing the implementation in re-renders\n const [isCustom] = useState(isCustomOptions(options));\n\n if (isCustom) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStreamCustom(options);\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStreamLGP(options);\n}\n"],"mappings":";;;;AA0BA,SAAS,gBAIP,SAGmD;AACnD,QAAO,eAAe;;AA6SxB,SAAgB,UAAU,SAAmB;CAE3C,MAAM,CAAC,YAAY,SAAS,gBAAgB,QAAQ,CAAC;AAErD,KAAI,SAEF,QAAO,gBAAgB,QAAQ;AAIjC,QAAO,aAAa,QAAQ"}
1
+ {"version":3,"file":"stream.js","names":[],"sources":["../src/stream.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport type { BagTemplate } from \"@langchain/langgraph-sdk\";\nimport type {\n UseStreamOptions,\n ResolveStreamInterface,\n ResolveStreamOptions,\n InferBag,\n InferStateType,\n WithClassMessages,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { useStreamLGP } from \"./stream.lgp.js\";\nimport { useStreamCustom } from \"./stream.custom.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\n\nfunction isCustomOptions<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options:\n | UseStreamOptions<StateType, Bag>\n | UseStreamCustomOptions<StateType, Bag>,\n): options is UseStreamCustomOptions<StateType, Bag> {\n return \"transport\" in options;\n}\n\ntype UseStreamImplementation = typeof useStreamLGP | typeof useStreamCustom;\n\ntype AnyUseStreamOptions =\n | UseStreamOptions<Record<string, unknown>, BagTemplate>\n | UseStreamCustomOptions<Record<string, unknown>, BagTemplate>;\n\nfunction selectStreamImplementation(\n options: AnyUseStreamOptions,\n): UseStreamImplementation {\n return isCustomOptions(options) ? useStreamCustom : useStreamLGP;\n}\n\nexport type {\n WithClassMessages,\n ClassSubagentStreamInterface,\n} from \"@langchain/langgraph-sdk/ui\";\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, subagent streams, and errors.\n *\n * ## Usage with ReactAgent (recommended for createAgent users)\n *\n * When using `createAgent` from `@langchain/langgraph`, you can pass `typeof agent` as the\n * type parameter to automatically infer tool call types:\n *\n * @example\n * ```typescript\n * // In your agent file (e.g., agent.ts)\n * import { createAgent, tool } from \"langchain\";\n * import { z } from \"zod\";\n *\n * const getWeather = tool(\n * async ({ location }) => `Weather in ${location}`,\n * { name: \"get_weather\", schema: z.object({ location: z.string() }) }\n * );\n *\n * export const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather],\n * });\n *\n * // In your React component\n * import { agent } from \"./agent\";\n *\n * function Chat() {\n * // Tool calls are automatically typed from the agent's tools!\n * const stream = useStream<typeof agent>({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.toolCalls[0].call.name is typed as \"get_weather\"\n * // stream.toolCalls[0].call.args is typed as { location: string }\n * }\n * ```\n *\n * ## Usage with StateGraph (for custom LangGraph applications)\n *\n * When building custom graphs with `StateGraph`, embed your tool call types directly\n * in your state's messages property using `Message<MyToolCalls>`:\n *\n * @example\n * ```typescript\n * import { Message } from \"@langchain/langgraph-sdk\";\n *\n * // Define your tool call types as a discriminated union\n * type MyToolCalls =\n * | { name: \"search\"; args: { query: string }; id?: string }\n * | { name: \"calculate\"; args: { expression: string }; id?: string };\n *\n * // Embed tool call types in your state's messages\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * context?: string;\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.values is typed as MyGraphState\n * // stream.toolCalls[0].call.name is typed as \"search\" | \"calculate\"\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With additional type configuration (interrupts, configurable)\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState, {\n * InterruptType: { question: string };\n * ConfigurableType: { userId: string };\n * }>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.interrupt is typed as { question: string } | undefined\n * }\n * ```\n *\n * ## Usage with Deep Agents (subagent streaming, experimental)\n *\n * For agents that spawn subagents (nested graphs), use `filterSubagentMessages`\n * to keep the main message stream clean while tracking subagent activity separately:\n *\n * @example\n * ```typescript\n * import { useStream, SubagentStream } from \"@langchain/langgraph-sdk/react\";\n * import type { agent } from \"./agent\";\n *\n * function DeepAgentChat() {\n * const stream = useStream<typeof agent>({\n * assistantId: \"deepagent\",\n * apiUrl: \"http://localhost:2024\",\n * // Filter subagent messages from main stream\n * filterSubagentMessages: true,\n * });\n *\n * const handleSubmit = (content: string) => {\n * stream.submit(\n * { messages: [{ content, type: \"human\" }] },\n * { streamSubgraphs: true } // Enable subgraph streaming\n * );\n * };\n *\n * // Access subagent streams via stream.subagents (Map<string, SubagentStream>)\n * const subagentList = [...stream.subagents.values()];\n *\n * return (\n * <div>\n * {stream.messages.map((msg) => <Message key={msg.id} message={msg} />)}\n *\n * {subagentList.map((subagent) => (\n * <SubagentCard\n * key={subagent.id}\n * status={subagent.status} // \"pending\" | \"running\" | \"complete\" | \"error\"\n * messages={subagent.messages}\n * toolCalls={subagent.toolCalls}\n * />\n * ))}\n * </div>\n * );\n * }\n * ```\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: ResolveStreamOptions<T, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useStream(options: any): any {\n // Keep implementation stable for the lifetime of this hook instance.\n const [useSelectedStream] = useState(() =>\n selectStreamImplementation(options),\n );\n return useSelectedStream(options);\n}\n"],"mappings":";;;;AAcA,SAAS,gBAIP,SAGmD;AACnD,QAAO,eAAe;;AASxB,SAAS,2BACP,SACyB;AACzB,QAAO,gBAAgB,QAAQ,GAAG,kBAAkB;;AA2LtD,SAAgB,UAAU,SAAmB;CAE3C,MAAM,CAAC,qBAAqB,eAC1B,2BAA2B,QAAQ,CACpC;AACD,QAAO,kBAAkB,QAAQ"}
@@ -560,11 +560,11 @@ function useStreamLGP(options) {
560
560
  if (values != null && "__interrupt__" in values && Array.isArray(values.__interrupt__)) {
561
561
  const valueInterrupts = values.__interrupt__;
562
562
  if (valueInterrupts.length === 0) return [{ when: "breakpoint" }];
563
- return valueInterrupts;
563
+ return (0, _langchain_langgraph_sdk_ui.normalizeInterruptsList)(valueInterrupts);
564
564
  }
565
565
  if (stream.isLoading) return [];
566
566
  const allInterrupts = (branchContext.threadHead?.tasks ?? []).flatMap((t) => t.interrupts ?? []);
567
- if (allInterrupts.length > 0) return allInterrupts;
567
+ if (allInterrupts.length > 0) return (0, _langchain_langgraph_sdk_ui.normalizeInterruptsList)(allInterrupts);
568
568
  if (!(branchContext.threadHead?.next ?? []).length || error != null) return [];
569
569
  return [{ when: "breakpoint" }];
570
570
  },