@langchain/langgraph-sdk 1.5.6 → 1.6.1
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/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/react/index.cjs +6 -0
- package/dist/react/index.d.cts +7 -2
- package/dist/react/index.d.ts +7 -2
- package/dist/react/index.js +2 -1
- package/dist/react/stream.cjs.map +1 -1
- package/dist/react/stream.custom.cjs +36 -7
- package/dist/react/stream.custom.cjs.map +1 -1
- package/dist/react/stream.custom.d.cts.map +1 -1
- package/dist/react/stream.custom.d.ts.map +1 -1
- package/dist/react/stream.custom.js +36 -7
- package/dist/react/stream.custom.js.map +1 -1
- package/dist/react/stream.d.cts +51 -31
- package/dist/react/stream.d.cts.map +1 -1
- package/dist/react/stream.d.ts +51 -31
- package/dist/react/stream.d.ts.map +1 -1
- package/dist/react/stream.js.map +1 -1
- package/dist/react/stream.lgp.cjs +45 -13
- package/dist/react/stream.lgp.cjs.map +1 -1
- package/dist/react/stream.lgp.js +45 -13
- package/dist/react/stream.lgp.js.map +1 -1
- package/dist/react/types.d.cts +5 -88
- package/dist/react/types.d.cts.map +1 -1
- package/dist/react/types.d.ts +5 -88
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react-ui/client.cjs.map +1 -1
- package/dist/react-ui/client.d.cts +5 -3
- package/dist/react-ui/client.d.cts.map +1 -1
- package/dist/react-ui/client.d.ts +5 -3
- package/dist/react-ui/client.d.ts.map +1 -1
- package/dist/react-ui/client.js.map +1 -1
- package/dist/schema.d.cts.map +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/types.stream.d.ts.map +1 -1
- package/dist/ui/manager.cjs +140 -14
- package/dist/ui/manager.cjs.map +1 -1
- package/dist/ui/manager.js +140 -14
- package/dist/ui/manager.js.map +1 -1
- package/dist/ui/stream/agent.d.cts +143 -0
- package/dist/ui/stream/agent.d.cts.map +1 -0
- package/dist/ui/stream/agent.d.ts +143 -0
- package/dist/ui/stream/agent.d.ts.map +1 -0
- package/dist/ui/stream/base.d.cts +144 -0
- package/dist/ui/stream/base.d.cts.map +1 -0
- package/dist/ui/stream/base.d.ts +144 -0
- package/dist/ui/stream/base.d.ts.map +1 -0
- package/dist/ui/stream/deep-agent.d.cts +277 -0
- package/dist/ui/stream/deep-agent.d.cts.map +1 -0
- package/dist/ui/stream/deep-agent.d.ts +277 -0
- package/dist/ui/stream/deep-agent.d.ts.map +1 -0
- package/dist/ui/stream/index.d.cts +172 -0
- package/dist/ui/stream/index.d.cts.map +1 -0
- package/dist/ui/stream/index.d.ts +172 -0
- package/dist/ui/stream/index.d.ts.map +1 -0
- package/dist/ui/subagents.cjs +593 -0
- package/dist/ui/subagents.cjs.map +1 -0
- package/dist/ui/subagents.d.cts +291 -0
- package/dist/ui/subagents.d.cts.map +1 -0
- package/dist/ui/subagents.d.ts +291 -0
- package/dist/ui/subagents.d.ts.map +1 -0
- package/dist/ui/subagents.js +589 -0
- package/dist/ui/subagents.js.map +1 -0
- package/dist/ui/types.d.cts +384 -5
- package/dist/ui/types.d.cts.map +1 -1
- package/dist/ui/types.d.ts +384 -5
- package/dist/ui/types.d.ts.map +1 -1
- package/package.json +6 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.cts","names":["
|
|
1
|
+
{"version":3,"file":"stream.d.cts","names":["BagTemplate","UseStreamCustomOptions","ResolveStreamInterface","ResolveStreamOptions","InferBag","InferStateType","useStream","Record","T","Bag"],"sources":["../../src/react/stream.d.ts"],"sourcesContent":["import type { BagTemplate } from \"../types.template.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\nimport type { ResolveStreamInterface, ResolveStreamOptions, InferBag, InferStateType } from \"../ui/stream/index.js\";\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 declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: ResolveStreamOptions<T, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;\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 declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;\n"],"mappings":";;;;;;;;AAuJA;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAjBwBM,cAAcC,qCAAqCP,cAAcA,sBAAsBG,qBAAqBK,GAAGJ,SAASI,GAAGC,QAAQP,uBAAuBM,GAAGJ,SAASI,GAAGC;;;;;;;;;;;;;;;;;iBAiBzKH,cAAcC,qCAAqCP,cAAcA,sBAAsBC,uBAAuBI,eAAeG,IAAIJ,SAASI,GAAGC,QAAQP,uBAAuBM,GAAGJ,SAASI,GAAGC"}
|
package/dist/react/stream.d.ts
CHANGED
|
@@ -1,40 +1,15 @@
|
|
|
1
1
|
import { BagTemplate } from "../types.template.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { UseStreamCustomOptions } from "../ui/types.js";
|
|
3
|
+
import { InferBag, InferStateType, ResolveStreamInterface, ResolveStreamOptions } from "../ui/stream/index.js";
|
|
4
4
|
|
|
5
5
|
//#region src/react/stream.d.ts
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Helper type that infers StateType based on whether T is an agent-like type, a CompiledGraph/Pregel instance, or a state type.
|
|
9
|
-
* - If T has `~agentTypes`, returns the full agent state including:
|
|
10
|
-
* - Base agent state with typed messages based on the agent's tools
|
|
11
|
-
* - The agent's custom state schema
|
|
12
|
-
* - All middleware states
|
|
13
|
-
* - If T has `~RunOutput` (CompiledGraph/CompiledStateGraph), returns the state type
|
|
14
|
-
* - If T has `~OutputType` (Pregel), returns the output type as state
|
|
15
|
-
* - Otherwise, returns T (direct state type)
|
|
16
|
-
*/
|
|
17
|
-
type InferStateType<T> = T extends {
|
|
18
|
-
"~agentTypes": unknown;
|
|
19
|
-
} ? InferAgentState<T> : T extends {
|
|
20
|
-
"~RunOutput": infer S;
|
|
21
|
-
} ? S extends Record<string, unknown> ? S : Record<string, unknown> : T extends {
|
|
22
|
-
"~OutputType": infer O;
|
|
23
|
-
} ? O extends Record<string, unknown> ? O : Record<string, unknown> : T extends Record<string, unknown> ? T : Record<string, unknown>;
|
|
24
|
-
/**
|
|
25
|
-
* Helper type that infers Bag based on whether T is an agent-like type.
|
|
26
|
-
* - If T has `~agentTypes`, extracts bag from the agent's tools
|
|
27
|
-
* - Otherwise, returns the default BagTemplate
|
|
28
|
-
*/
|
|
29
|
-
type InferBag<T, B extends BagTemplate = BagTemplate> = T extends {
|
|
30
|
-
"~agentTypes": unknown;
|
|
31
|
-
} ? BagTemplate : B;
|
|
32
7
|
/**
|
|
33
8
|
* A React hook that provides seamless integration with LangGraph streaming capabilities.
|
|
34
9
|
*
|
|
35
10
|
* The `useStream` hook handles all the complexities of streaming, state management, and branching logic,
|
|
36
11
|
* letting you focus on building great chat experiences. It provides automatic state management for
|
|
37
|
-
* messages, interrupts, loading states, and errors.
|
|
12
|
+
* messages, interrupts, loading states, subagent streams, and errors.
|
|
38
13
|
*
|
|
39
14
|
* ## Usage with ReactAgent (recommended for createAgent users)
|
|
40
15
|
*
|
|
@@ -44,7 +19,7 @@ type InferBag<T, B extends BagTemplate = BagTemplate> = T extends {
|
|
|
44
19
|
* @example
|
|
45
20
|
* ```typescript
|
|
46
21
|
* // In your agent file (e.g., agent.ts)
|
|
47
|
-
* import { createAgent, tool } from "
|
|
22
|
+
* import { createAgent, tool } from "langchain";
|
|
48
23
|
* import { z } from "zod";
|
|
49
24
|
*
|
|
50
25
|
* const getWeather = tool(
|
|
@@ -123,6 +98,51 @@ type InferBag<T, B extends BagTemplate = BagTemplate> = T extends {
|
|
|
123
98
|
* }
|
|
124
99
|
* ```
|
|
125
100
|
*
|
|
101
|
+
* ## Usage with Deep Agents (subagent streaming, experimental)
|
|
102
|
+
*
|
|
103
|
+
* For agents that spawn subagents (nested graphs), use `filterSubagentMessages`
|
|
104
|
+
* to keep the main message stream clean while tracking subagent activity separately:
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* import { useStream, SubagentStream } from "@langchain/langgraph-sdk/react";
|
|
109
|
+
* import type { agent } from "./agent";
|
|
110
|
+
*
|
|
111
|
+
* function DeepAgentChat() {
|
|
112
|
+
* const stream = useStream<typeof agent>({
|
|
113
|
+
* assistantId: "deepagent",
|
|
114
|
+
* apiUrl: "http://localhost:2024",
|
|
115
|
+
* // Filter subagent messages from main stream
|
|
116
|
+
* filterSubagentMessages: true,
|
|
117
|
+
* });
|
|
118
|
+
*
|
|
119
|
+
* const handleSubmit = (content: string) => {
|
|
120
|
+
* stream.submit(
|
|
121
|
+
* { messages: [{ content, type: "human" }] },
|
|
122
|
+
* { streamSubgraphs: true } // Enable subgraph streaming
|
|
123
|
+
* );
|
|
124
|
+
* };
|
|
125
|
+
*
|
|
126
|
+
* // Access subagent streams via stream.subagents (Map<string, SubagentStream>)
|
|
127
|
+
* const subagentList = [...stream.subagents.values()];
|
|
128
|
+
*
|
|
129
|
+
* return (
|
|
130
|
+
* <div>
|
|
131
|
+
* {stream.messages.map((msg) => <Message key={msg.id} message={msg} />)}
|
|
132
|
+
*
|
|
133
|
+
* {subagentList.map((subagent) => (
|
|
134
|
+
* <SubagentCard
|
|
135
|
+
* key={subagent.id}
|
|
136
|
+
* status={subagent.status} // "pending" | "running" | "complete" | "error"
|
|
137
|
+
* messages={subagent.messages}
|
|
138
|
+
* toolCalls={subagent.toolCalls}
|
|
139
|
+
* />
|
|
140
|
+
* ))}
|
|
141
|
+
* </div>
|
|
142
|
+
* );
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
126
146
|
* @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)
|
|
127
147
|
* @template Bag Type configuration bag containing:
|
|
128
148
|
* - `ConfigurableType`: Type for the `config.configurable` property
|
|
@@ -132,7 +152,7 @@ type InferBag<T, B extends BagTemplate = BagTemplate> = T extends {
|
|
|
132
152
|
*
|
|
133
153
|
* @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}
|
|
134
154
|
*/
|
|
135
|
-
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options:
|
|
155
|
+
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: ResolveStreamOptions<T, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;
|
|
136
156
|
/**
|
|
137
157
|
* A React hook that provides seamless integration with LangGraph streaming capabilities.
|
|
138
158
|
*
|
|
@@ -149,7 +169,7 @@ declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate
|
|
|
149
169
|
*
|
|
150
170
|
* @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}
|
|
151
171
|
*/
|
|
152
|
-
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>):
|
|
172
|
+
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;
|
|
153
173
|
//#endregion
|
|
154
174
|
export { useStream };
|
|
155
175
|
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","names":["
|
|
1
|
+
{"version":3,"file":"stream.d.ts","names":["BagTemplate","UseStreamCustomOptions","ResolveStreamInterface","ResolveStreamOptions","InferBag","InferStateType","useStream","Record","T","Bag"],"sources":["../../src/react/stream.d.ts"],"sourcesContent":["import type { BagTemplate } from \"../types.template.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\nimport type { ResolveStreamInterface, ResolveStreamOptions, InferBag, InferStateType } from \"../ui/stream/index.js\";\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 declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: ResolveStreamOptions<T, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;\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 declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>): ResolveStreamInterface<T, InferBag<T, Bag>>;\n"],"mappings":";;;;;;;;AAuJA;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAjBwBM,cAAcC,qCAAqCP,cAAcA,sBAAsBG,qBAAqBK,GAAGJ,SAASI,GAAGC,QAAQP,uBAAuBM,GAAGJ,SAASI,GAAGC;;;;;;;;;;;;;;;;;iBAiBzKH,cAAcC,qCAAqCP,cAAcA,sBAAsBC,uBAAuBI,eAAeG,IAAIJ,SAASI,GAAGC,QAAQP,uBAAuBM,GAAGJ,SAASI,GAAGC"}
|
package/dist/react/stream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","names":[],"sources":["../../src/react/stream.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useStreamLGP } from \"./stream.lgp.js\";\nimport { useStreamCustom } from \"./stream.custom.js\";\nimport type { UseStreamOptions
|
|
1
|
+
{"version":3,"file":"stream.js","names":[],"sources":["../../src/react/stream.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useStreamLGP } from \"./stream.lgp.js\";\nimport { useStreamCustom } from \"./stream.custom.js\";\nimport type { UseStreamOptions } from \"../ui/types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\nimport type {\n ResolveStreamInterface,\n ResolveStreamOptions,\n InferBag,\n InferStateType,\n} from \"../ui/stream/index.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\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): 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): 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":";;;;;AAaA,SAAS,gBAIP,SAGmD;AACnD,QAAO,eAAe;;AAsLxB,SAAgB,UAAU,SAAmB;CAE3C,MAAM,CAAC,YAAY,SAAS,gBAAgB,QAAQ,CAAC;AAErD,KAAI,SAEF,QAAO,gBAAgB,QAAQ;AAIjC,QAAO,aAAa,QAAQ"}
|
|
@@ -6,8 +6,8 @@ const require_utils = require('../ui/utils.cjs');
|
|
|
6
6
|
const require_errors = require('../ui/errors.cjs');
|
|
7
7
|
const require_branching = require('../ui/branching.cjs');
|
|
8
8
|
const require_messages = require('../ui/messages.cjs');
|
|
9
|
-
const require_manager = require('../ui/manager.cjs');
|
|
10
9
|
const require_tools = require('../utils/tools.cjs');
|
|
10
|
+
const require_manager = require('../ui/manager.cjs');
|
|
11
11
|
const require_thread = require('./thread.cjs');
|
|
12
12
|
let react = require("react");
|
|
13
13
|
|
|
@@ -122,7 +122,11 @@ function useStreamLGP(options) {
|
|
|
122
122
|
options.defaultHeaders
|
|
123
123
|
]);
|
|
124
124
|
const [messageManager] = (0, react.useState)(() => new require_messages.MessageTupleManager());
|
|
125
|
-
const [stream] = (0, react.useState)(() => new require_manager.StreamManager(messageManager, {
|
|
125
|
+
const [stream] = (0, react.useState)(() => new require_manager.StreamManager(messageManager, {
|
|
126
|
+
throttle: options.throttle ?? false,
|
|
127
|
+
subagentToolNames: options.subagentToolNames,
|
|
128
|
+
filterSubagentMessages: options.filterSubagentMessages
|
|
129
|
+
}));
|
|
126
130
|
(0, react.useSyncExternalStore)(stream.subscribe, stream.getSnapshot, stream.getSnapshot);
|
|
127
131
|
const [threadId, onThreadId] = require_thread.useControllableThreadId(options);
|
|
128
132
|
const trackStreamModeRef = (0, react.useRef)([]);
|
|
@@ -182,6 +186,11 @@ function useStreamLGP(options) {
|
|
|
182
186
|
const [branch, setBranch] = (0, react.useState)("");
|
|
183
187
|
const branchContext = require_branching.getBranchContext(branch, history.data ?? void 0);
|
|
184
188
|
const historyValues = branchContext.threadHead?.values ?? options.initialValues ?? {};
|
|
189
|
+
const historyMessages = getMessages(historyValues);
|
|
190
|
+
const shouldReconstructSubagents = options.filterSubagentMessages && !stream.isLoading && !history.isLoading && historyMessages.length > 0;
|
|
191
|
+
(0, react.useEffect)(() => {
|
|
192
|
+
if (shouldReconstructSubagents) stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });
|
|
193
|
+
}, [shouldReconstructSubagents, historyMessages.length]);
|
|
185
194
|
const historyError = (() => {
|
|
186
195
|
const error = branchContext.threadHead?.tasks?.at(-1)?.error;
|
|
187
196
|
if (error == null) return void 0;
|
|
@@ -233,7 +242,7 @@ function useStreamLGP(options) {
|
|
|
233
242
|
stream.setStreamValues((values) => {
|
|
234
243
|
const prev = {
|
|
235
244
|
...historyValues,
|
|
236
|
-
...values
|
|
245
|
+
...values
|
|
237
246
|
};
|
|
238
247
|
if (submitOptions?.optimisticValues != null) return {
|
|
239
248
|
...prev,
|
|
@@ -405,20 +414,23 @@ function useStreamLGP(options) {
|
|
|
405
414
|
if (historyLimit === false) throw new Error("`fetchStateHistory` must be set to `true` to use `experimental_branchTree`");
|
|
406
415
|
return branchContext.branchTree;
|
|
407
416
|
},
|
|
408
|
-
get
|
|
417
|
+
get interrupts() {
|
|
409
418
|
if (values != null && "__interrupt__" in values && Array.isArray(values.__interrupt__)) {
|
|
410
419
|
const valueInterrupts = values.__interrupt__;
|
|
411
|
-
if (valueInterrupts.length === 0) return { when: "breakpoint" };
|
|
412
|
-
if (valueInterrupts.length === 1) return valueInterrupts[0];
|
|
420
|
+
if (valueInterrupts.length === 0) return [{ when: "breakpoint" }];
|
|
413
421
|
return valueInterrupts;
|
|
414
422
|
}
|
|
415
|
-
if (stream.isLoading) return
|
|
416
|
-
const
|
|
417
|
-
if (
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
423
|
+
if (stream.isLoading) return [];
|
|
424
|
+
const allInterrupts = (branchContext.threadHead?.tasks ?? []).flatMap((t) => t.interrupts ?? []);
|
|
425
|
+
if (allInterrupts.length > 0) return allInterrupts;
|
|
426
|
+
if (!(branchContext.threadHead?.next ?? []).length || error != null) return [];
|
|
427
|
+
return [{ when: "breakpoint" }];
|
|
428
|
+
},
|
|
429
|
+
get interrupt() {
|
|
430
|
+
const all = this.interrupts;
|
|
431
|
+
if (all.length === 0) return void 0;
|
|
432
|
+
if (all.length === 1) return all[0];
|
|
433
|
+
return all;
|
|
422
434
|
},
|
|
423
435
|
get messages() {
|
|
424
436
|
trackStreamMode("messages-tuple", "values");
|
|
@@ -440,6 +452,26 @@ function useStreamLGP(options) {
|
|
|
440
452
|
...historyMetadata,
|
|
441
453
|
streamMetadata
|
|
442
454
|
};
|
|
455
|
+
},
|
|
456
|
+
get subagents() {
|
|
457
|
+
trackStreamMode("updates", "messages-tuple");
|
|
458
|
+
return stream.getSubagents();
|
|
459
|
+
},
|
|
460
|
+
get activeSubagents() {
|
|
461
|
+
trackStreamMode("updates", "messages-tuple");
|
|
462
|
+
return stream.getActiveSubagents();
|
|
463
|
+
},
|
|
464
|
+
getSubagent(toolCallId) {
|
|
465
|
+
trackStreamMode("updates", "messages-tuple");
|
|
466
|
+
return stream.getSubagent(toolCallId);
|
|
467
|
+
},
|
|
468
|
+
getSubagentsByType(type) {
|
|
469
|
+
trackStreamMode("updates", "messages-tuple");
|
|
470
|
+
return stream.getSubagentsByType(type);
|
|
471
|
+
},
|
|
472
|
+
getSubagentsByMessage(messageId) {
|
|
473
|
+
trackStreamMode("updates", "messages-tuple");
|
|
474
|
+
return stream.getSubagentsByMessage(messageId);
|
|
443
475
|
}
|
|
444
476
|
};
|
|
445
477
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.lgp.cjs","names":["getClientConfigHash","Client","MessageTupleManager","StreamManager","useControllableThreadId","getBranchContext","StreamError","findLast","unique","filterStream","getToolCallsWithResults"],"sources":["../../src/react/stream.lgp.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { filterStream, findLast, unique } from \"../ui/utils.js\";\nimport { StreamError } from \"../ui/errors.js\";\nimport { getBranchContext } from \"../ui/branching.js\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n UseStreamOptions,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n GetToolCallsType,\n RunCallbackMeta,\n MessageMetadata,\n UseStreamThread,\n} from \"../ui/types.js\";\nimport type { UseStream, SubmitOptions } from \"./types.js\";\nimport { Client, getClientConfigHash } from \"../client.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport type { Interrupt, ThreadState } from \"../schema.js\";\nimport type { StreamMode } from \"../types.stream.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { StreamEvent } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\n\nfunction getFetchHistoryKey(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number\n) {\n return [getClientConfigHash(client), threadId, limit].join(\":\");\n}\n\nfunction fetchHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string,\n options?: { limit?: boolean | number }\n) {\n if (options?.limit === false) {\n return client.threads.getState<StateType>(threadId).then((state) => {\n if (state.checkpoint == null) return [];\n return [state];\n });\n }\n\n const limit = typeof options?.limit === \"number\" ? options.limit : 10;\n return client.threads.getHistory<StateType>(threadId, { limit });\n}\n\nfunction useThreadHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number,\n options: {\n passthrough: boolean;\n submittingRef: RefObject<string | null>;\n onError?: (error: unknown, run?: RunCallbackMeta) => void;\n }\n): UseStreamThread<StateType> {\n const key = getFetchHistoryKey(client, threadId, limit);\n const [state, setState] = useState<{\n key: string | undefined;\n data: ThreadState<StateType>[] | undefined;\n error: unknown | undefined;\n isLoading: boolean;\n }>(() => ({\n key: undefined,\n data: undefined,\n error: undefined,\n isLoading: threadId != null,\n }));\n\n const clientRef = useRef(client);\n clientRef.current = client;\n\n const onErrorRef = useRef(options?.onError);\n onErrorRef.current = options?.onError;\n\n const fetcher = useCallback(\n (\n threadId: string | undefined | null,\n limit: boolean | number\n ): Promise<ThreadState<StateType>[]> => {\n // If only passthrough is enabled, don't fetch history\n if (options.passthrough) return Promise.resolve([]);\n\n const client = clientRef.current;\n const key = getFetchHistoryKey(client, threadId, limit);\n\n if (threadId != null) {\n setState((state) => {\n if (state.key === key) return { ...state, isLoading: true };\n return { key, data: undefined, error: undefined, isLoading: true };\n });\n return fetchHistory<StateType>(client, threadId, { limit }).then(\n (data) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data, error: undefined, isLoading: false };\n });\n return data;\n },\n (error) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data: state.data, error, isLoading: false };\n });\n onErrorRef.current?.(error);\n return Promise.reject(error);\n }\n );\n }\n\n setState({ key, data: undefined, error: undefined, isLoading: false });\n return Promise.resolve([]);\n },\n [options.passthrough]\n );\n\n useEffect(() => {\n // Skip if a stream is already in progress, no need to fetch history\n if (\n options.submittingRef.current != null &&\n options.submittingRef.current === threadId\n ) {\n return;\n }\n\n void fetcher(threadId, limit);\n // The `threadId` and `limit` arguments are already present in `key`\n // Thus we don't need to include them in the dependency array\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetcher, key]);\n\n return {\n data: state.data,\n error: state.error,\n isLoading: state.isLoading,\n mutate: (mutateId?: string) => fetcher(mutateId ?? threadId, limit),\n };\n}\n\nexport function useStreamLGP<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(options: UseStreamOptions<StateType, Bag>): UseStream<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 reconnectOnMountRef = useRef(options.reconnectOnMount);\n const runMetadataStorage = useMemo(() => {\n if (typeof window === \"undefined\") return null;\n const storage = reconnectOnMountRef.current;\n if (storage === true) return window.sessionStorage;\n if (typeof storage === \"function\") return storage();\n return null;\n }, []);\n\n const client = useMemo(\n () =>\n options.client ??\n new Client({\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n callerOptions: options.callerOptions,\n defaultHeaders: options.defaultHeaders,\n }),\n [\n options.client,\n options.apiKey,\n options.apiUrl,\n options.callerOptions,\n options.defaultHeaders,\n ]\n );\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const trackStreamModeRef = useRef<Exclude<StreamMode, \"messages\">[]>([]);\n\n const trackStreamMode = useCallback(\n (...mode: Exclude<StreamMode, \"messages\">[]) => {\n const ref = trackStreamModeRef.current;\n for (const m of mode) {\n if (!ref.includes(m)) ref.push(m);\n }\n },\n []\n );\n\n const hasUpdateListener = options.onUpdateEvent != null;\n const hasCustomListener = options.onCustomEvent != null;\n const hasLangChainListener = options.onLangChainEvent != null;\n const hasDebugListener = options.onDebugEvent != null;\n const hasCheckpointListener = options.onCheckpointEvent != null;\n const hasTaskListener = options.onTaskEvent != null;\n\n const callbackStreamMode = useMemo(() => {\n const modes: Exclude<StreamMode, \"messages\">[] = [];\n if (hasUpdateListener) modes.push(\"updates\");\n if (hasCustomListener) modes.push(\"custom\");\n if (hasLangChainListener) modes.push(\"events\");\n if (hasDebugListener) modes.push(\"debug\");\n if (hasCheckpointListener) modes.push(\"checkpoints\");\n if (hasTaskListener) modes.push(\"tasks\");\n return modes;\n }, [\n hasUpdateListener,\n hasCustomListener,\n hasLangChainListener,\n hasDebugListener,\n hasCheckpointListener,\n hasTaskListener,\n ]);\n\n const threadIdRef = useRef<string | null>(threadId);\n const threadIdStreamingRef = useRef<string | null>(null);\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 historyLimit =\n typeof options.fetchStateHistory === \"object\" &&\n options.fetchStateHistory != null\n ? options.fetchStateHistory.limit ?? false\n : options.fetchStateHistory ?? false;\n\n const builtInHistory = useThreadHistory<StateType>(\n client,\n threadId,\n historyLimit,\n {\n passthrough: options.thread != null,\n submittingRef: threadIdStreamingRef,\n onError: options.onError,\n }\n );\n const history = options.thread ?? builtInHistory;\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 [branch, setBranch] = useState<string>(\"\");\n const branchContext = getBranchContext(branch, history.data ?? undefined);\n\n const historyValues =\n branchContext.threadHead?.values ??\n options.initialValues ??\n ({} as StateType);\n\n const historyError = (() => {\n const error = branchContext.threadHead?.tasks?.at(-1)?.error;\n if (error == null) return undefined;\n try {\n const parsed = JSON.parse(error) as unknown;\n if (StreamError.isStructuredError(parsed)) return new StreamError(parsed);\n return parsed;\n } catch {\n // do nothing\n }\n return error;\n })();\n\n const messageMetadata = (() => {\n const alreadyShown = new Set<string>();\n return getMessages(historyValues).map(\n (message, idx): Omit<MessageMetadata<StateType>, \"streamMetadata\"> => {\n const messageId = message.id ?? idx;\n\n // Find the first checkpoint where the message was seen\n const firstSeenState = findLast(history.data ?? [], (state) =>\n getMessages(state.values)\n .map((m, idx) => m.id ?? idx)\n .includes(messageId)\n );\n\n const checkpointId = firstSeenState?.checkpoint?.checkpoint_id;\n let branch =\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]\n : undefined;\n if (!branch?.branch?.length) branch = undefined;\n\n // serialize branches\n const optionsShown = branch?.branchOptions?.flat(2).join(\",\");\n if (optionsShown) {\n if (alreadyShown.has(optionsShown)) branch = undefined;\n alreadyShown.add(optionsShown);\n }\n\n return {\n messageId: messageId.toString(),\n firstSeenState,\n\n branch: branch?.branch,\n branchOptions: branch?.branchOptions,\n };\n }\n );\n })();\n\n const stop = () =>\n stream.stop(historyValues, {\n onStop: (args) => {\n if (runMetadataStorage && threadId) {\n const runId = runMetadataStorage.getItem(`lg:stream:${threadId}`);\n if (runId) void client.runs.cancel(threadId, runId);\n runMetadataStorage.removeItem(`lg:stream:${threadId}`);\n }\n\n options.onStop?.(args);\n },\n });\n\n // --- TRANSPORT ---\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: SubmitOptions<StateType, ConfigurableType>\n ) => {\n // Unbranch things\n const checkpointId = submitOptions?.checkpoint?.checkpoint_id;\n setBranch(\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]?.branch ?? \"\"\n : \"\"\n );\n\n // When `fetchStateHistory` is requested, thus we assume that branching\n // is enabled. We then need to include the implicit branch.\n const includeImplicitBranch =\n historyLimit === true || typeof historyLimit === \"number\";\n\n const shouldRefetch =\n // We're expecting the whole thread state in onFinish\n options.onFinish != null ||\n // We're fetching history, thus we need the latest checkpoint\n // to ensure we're not accidentally submitting to a wrong branch\n includeImplicitBranch;\n\n let callbackMeta: RunCallbackMeta | undefined;\n let rejoinKey: `lg:stream:${string}` | undefined;\n let usableThreadId = threadId;\n\n await stream.start(\n async (signal: AbortSignal) => {\n stream.setStreamValues((values) => {\n const prev = { ...historyValues, ...(values ?? {}) };\n if (submitOptions?.optimisticValues != null) {\n return {\n ...prev,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(prev)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...prev };\n });\n\n if (!usableThreadId) {\n const thread = await client.threads.create({\n threadId: submitOptions?.threadId,\n metadata: submitOptions?.metadata,\n signal,\n });\n\n usableThreadId = thread.thread_id;\n\n // Pre-emptively update the thread ID before\n // stream cancellation is kicked off and thread\n // is being refetched\n threadIdRef.current = usableThreadId;\n threadIdStreamingRef.current = usableThreadId;\n\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n threadIdStreamingRef.current = usableThreadId;\n\n const streamMode = unique([\n ...(submitOptions?.streamMode ?? []),\n ...trackStreamModeRef.current,\n ...callbackStreamMode,\n ]);\n\n let checkpoint =\n submitOptions?.checkpoint ??\n (includeImplicitBranch\n ? branchContext.threadHead?.checkpoint\n : undefined) ??\n undefined;\n\n // Avoid specifying a checkpoint if user explicitly set it to null\n if (submitOptions?.checkpoint === null) checkpoint = undefined;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (checkpoint != null) delete checkpoint.thread_id;\n const streamResumable =\n submitOptions?.streamResumable ?? !!runMetadataStorage;\n\n return client.runs.stream(usableThreadId, options.assistantId, {\n input: values as Record<string, unknown>,\n config: submitOptions?.config,\n context: submitOptions?.context,\n command: submitOptions?.command,\n\n interruptBefore: submitOptions?.interruptBefore,\n interruptAfter: submitOptions?.interruptAfter,\n metadata: submitOptions?.metadata,\n multitaskStrategy: submitOptions?.multitaskStrategy,\n onCompletion: submitOptions?.onCompletion,\n onDisconnect:\n submitOptions?.onDisconnect ??\n (streamResumable ? \"continue\" : \"cancel\"),\n\n signal,\n\n checkpoint,\n streamMode,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n streamResumable,\n durability: submitOptions?.durability,\n onRunCreated(params) {\n callbackMeta = {\n run_id: params.run_id,\n thread_id: params.thread_id ?? usableThreadId!,\n };\n\n if (runMetadataStorage) {\n rejoinKey = `lg:stream:${usableThreadId}`;\n runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);\n }\n\n options.onCreated?.(callbackMeta);\n },\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: options,\n\n async onSuccess() {\n if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);\n\n if (shouldRefetch) {\n const newHistory = await history.mutate(usableThreadId!);\n const lastHead = newHistory?.at(0);\n if (lastHead) {\n // We now have the latest update from /history\n // Thus we can clear the local stream state\n options.onFinish?.(lastHead, callbackMeta);\n return null;\n }\n }\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const joinStream = async (\n runId: string,\n lastEventId?: string,\n joinOptions?: {\n streamMode?: StreamMode | StreamMode[];\n filter?: (event: {\n id?: string;\n event: StreamEvent;\n data: unknown;\n }) => boolean;\n }\n ) => {\n // eslint-disable-next-line no-param-reassign\n lastEventId ??= \"-1\";\n if (!threadId) return;\n\n const callbackMeta: RunCallbackMeta = {\n thread_id: threadId,\n run_id: runId,\n };\n\n await stream.start(\n async (signal: AbortSignal) => {\n threadIdStreamingRef.current = threadId;\n const stream = client.runs.joinStream(threadId, runId, {\n signal,\n lastEventId,\n streamMode: joinOptions?.streamMode,\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n\n return joinOptions?.filter != null\n ? filterStream(stream, joinOptions.filter)\n : stream;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: options,\n async onSuccess() {\n runMetadataStorage?.removeItem(`lg:stream:${threadId}`);\n const newHistory = await history.mutate(threadId);\n const lastHead = newHistory?.at(0);\n if (lastHead) options.onFinish?.(lastHead, callbackMeta);\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const reconnectKey = useMemo(() => {\n if (!runMetadataStorage || stream.isLoading) return undefined;\n if (typeof window === \"undefined\") return undefined;\n const runId = runMetadataStorage?.getItem(`lg:stream:${threadId}`);\n if (!runId) return undefined;\n return { runId, threadId };\n }, [runMetadataStorage, stream.isLoading, threadId]);\n\n const shouldReconnect = !!runMetadataStorage;\n const reconnectRef = useRef({ threadId, shouldReconnect });\n\n const joinStreamRef = useRef<typeof joinStream>(joinStream);\n joinStreamRef.current = joinStream;\n\n useEffect(() => {\n // reset shouldReconnect when switching threads\n if (reconnectRef.current.threadId !== threadId) {\n reconnectRef.current = { threadId, shouldReconnect };\n }\n }, [threadId, shouldReconnect]);\n\n useEffect(() => {\n if (reconnectKey && reconnectRef.current.shouldReconnect) {\n reconnectRef.current.shouldReconnect = false;\n void joinStreamRef.current?.(reconnectKey.runId);\n }\n }, [reconnectKey]);\n\n const error = stream.error ?? historyError ?? history.error;\n const values = stream.values ?? historyValues;\n\n return {\n get values() {\n trackStreamMode(\"values\");\n return values;\n },\n\n client,\n assistantId: options.assistantId,\n\n error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n\n joinStream,\n\n branch,\n setBranch,\n\n get history() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `history`\"\n );\n }\n\n return branchContext.flatHistory;\n },\n\n isThreadLoading: history.isLoading && history.data == null,\n\n get experimental_branchTree() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `experimental_branchTree`\"\n );\n }\n\n return branchContext.branchTree;\n },\n\n get interrupt() {\n if (\n values != null &&\n \"__interrupt__\" in values &&\n Array.isArray(values.__interrupt__)\n ) {\n const valueInterrupts = values.__interrupt__;\n if (valueInterrupts.length === 0) return { when: \"breakpoint\" };\n if (valueInterrupts.length === 1) return valueInterrupts[0];\n\n // TODO: fix the typing of interrupts if multiple interrupts are returned\n return valueInterrupts;\n }\n\n // If we're deferring to old interrupt detection logic, don't show the interrupt if the stream is loading\n if (stream.isLoading) return undefined;\n\n const interrupts = branchContext.threadHead?.tasks?.at(-1)?.interrupts;\n if (interrupts == null || interrupts.length === 0) {\n // check if there's a next task present\n const next = branchContext.threadHead?.next ?? [];\n if (!next.length || error != null) return undefined;\n return { when: \"breakpoint\" };\n }\n\n // Return only the current interrupt\n return interrupts.at(-1) as Interrupt<InterruptType> | undefined;\n },\n\n get messages(): Message<ToolCallType>[] {\n trackStreamMode(\"messages-tuple\", \"values\");\n return getMessages(values);\n },\n\n get toolCalls() {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n getMessagesMetadata(\n message: Message<ToolCallType>,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n trackStreamMode(\"values\");\n\n const streamMetadata = messageManager.get(message.id)?.metadata;\n const historyMetadata = messageMetadata?.find(\n (m) => m.messageId === (message.id ?? index)\n );\n\n if (streamMetadata != null || historyMetadata != null) {\n return {\n ...historyMetadata,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n\n return undefined;\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stream.lgp.cjs","names":["getClientConfigHash","Client","MessageTupleManager","StreamManager","useControllableThreadId","getBranchContext","StreamError","findLast","unique","filterStream","getToolCallsWithResults"],"sources":["../../src/react/stream.lgp.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { filterStream, findLast, unique } from \"../ui/utils.js\";\nimport { StreamError } from \"../ui/errors.js\";\nimport { getBranchContext } from \"../ui/branching.js\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n AnyStreamOptions,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n GetToolCallsType,\n RunCallbackMeta,\n MessageMetadata,\n UseStreamThread,\n} from \"../ui/types.js\";\nimport type { UseStream, SubmitOptions } from \"./types.js\";\n\nimport { Client, getClientConfigHash } from \"../client.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport type { Interrupt, ThreadState } from \"../schema.js\";\nimport type { StreamMode } from \"../types.stream.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { StreamEvent } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\n\nfunction getFetchHistoryKey(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number\n) {\n return [getClientConfigHash(client), threadId, limit].join(\":\");\n}\n\nfunction fetchHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string,\n options?: { limit?: boolean | number }\n) {\n if (options?.limit === false) {\n return client.threads.getState<StateType>(threadId).then((state) => {\n if (state.checkpoint == null) return [];\n return [state];\n });\n }\n\n const limit = typeof options?.limit === \"number\" ? options.limit : 10;\n return client.threads.getHistory<StateType>(threadId, { limit });\n}\n\nfunction useThreadHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number,\n options: {\n passthrough: boolean;\n submittingRef: RefObject<string | null>;\n onError?: (error: unknown, run?: RunCallbackMeta) => void;\n }\n): UseStreamThread<StateType> {\n const key = getFetchHistoryKey(client, threadId, limit);\n const [state, setState] = useState<{\n key: string | undefined;\n data: ThreadState<StateType>[] | undefined;\n error: unknown | undefined;\n isLoading: boolean;\n }>(() => ({\n key: undefined,\n data: undefined,\n error: undefined,\n isLoading: threadId != null,\n }));\n\n const clientRef = useRef(client);\n clientRef.current = client;\n\n const onErrorRef = useRef(options?.onError);\n onErrorRef.current = options?.onError;\n\n const fetcher = useCallback(\n (\n threadId: string | undefined | null,\n limit: boolean | number\n ): Promise<ThreadState<StateType>[]> => {\n // If only passthrough is enabled, don't fetch history\n if (options.passthrough) return Promise.resolve([]);\n\n const client = clientRef.current;\n const key = getFetchHistoryKey(client, threadId, limit);\n\n if (threadId != null) {\n setState((state) => {\n if (state.key === key) return { ...state, isLoading: true };\n return { key, data: undefined, error: undefined, isLoading: true };\n });\n return fetchHistory<StateType>(client, threadId, { limit }).then(\n (data) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data, error: undefined, isLoading: false };\n });\n return data;\n },\n (error) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data: state.data, error, isLoading: false };\n });\n onErrorRef.current?.(error);\n return Promise.reject(error);\n }\n );\n }\n\n setState({ key, data: undefined, error: undefined, isLoading: false });\n return Promise.resolve([]);\n },\n [options.passthrough]\n );\n\n useEffect(() => {\n // Skip if a stream is already in progress, no need to fetch history\n if (\n options.submittingRef.current != null &&\n options.submittingRef.current === threadId\n ) {\n return;\n }\n\n void fetcher(threadId, limit);\n // The `threadId` and `limit` arguments are already present in `key`\n // Thus we don't need to include them in the dependency array\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetcher, key]);\n\n return {\n data: state.data,\n error: state.error,\n isLoading: state.isLoading,\n mutate: (mutateId?: string) => fetcher(mutateId ?? threadId, limit),\n };\n}\n\nexport function useStreamLGP<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(options: AnyStreamOptions<StateType, Bag>): UseStream<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 reconnectOnMountRef = useRef(options.reconnectOnMount);\n const runMetadataStorage = useMemo(() => {\n if (typeof window === \"undefined\") return null;\n const storage = reconnectOnMountRef.current;\n if (storage === true) return window.sessionStorage;\n if (typeof storage === \"function\") return storage();\n return null;\n }, []);\n\n const client = useMemo(\n () =>\n options.client ??\n new Client({\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n callerOptions: options.callerOptions,\n defaultHeaders: options.defaultHeaders,\n }),\n [\n options.client,\n options.apiKey,\n options.apiUrl,\n options.callerOptions,\n options.defaultHeaders,\n ]\n );\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 })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const trackStreamModeRef = useRef<Exclude<StreamMode, \"messages\">[]>([]);\n\n const trackStreamMode = useCallback(\n (...mode: Exclude<StreamMode, \"messages\">[]) => {\n const ref = trackStreamModeRef.current;\n for (const m of mode) {\n if (!ref.includes(m)) ref.push(m);\n }\n },\n []\n );\n\n const hasUpdateListener = options.onUpdateEvent != null;\n const hasCustomListener = options.onCustomEvent != null;\n const hasLangChainListener = options.onLangChainEvent != null;\n const hasDebugListener = options.onDebugEvent != null;\n const hasCheckpointListener = options.onCheckpointEvent != null;\n const hasTaskListener = options.onTaskEvent != null;\n\n const callbackStreamMode = useMemo(() => {\n const modes: Exclude<StreamMode, \"messages\">[] = [];\n if (hasUpdateListener) modes.push(\"updates\");\n if (hasCustomListener) modes.push(\"custom\");\n if (hasLangChainListener) modes.push(\"events\");\n if (hasDebugListener) modes.push(\"debug\");\n if (hasCheckpointListener) modes.push(\"checkpoints\");\n if (hasTaskListener) modes.push(\"tasks\");\n return modes;\n }, [\n hasUpdateListener,\n hasCustomListener,\n hasLangChainListener,\n hasDebugListener,\n hasCheckpointListener,\n hasTaskListener,\n ]);\n\n const threadIdRef = useRef<string | null>(threadId);\n const threadIdStreamingRef = useRef<string | null>(null);\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 historyLimit =\n typeof options.fetchStateHistory === \"object\" &&\n options.fetchStateHistory != null\n ? options.fetchStateHistory.limit ?? false\n : options.fetchStateHistory ?? false;\n\n const builtInHistory = useThreadHistory<StateType>(\n client,\n threadId,\n historyLimit,\n {\n passthrough: options.thread != null,\n submittingRef: threadIdStreamingRef,\n onError: options.onError,\n }\n );\n const history = options.thread ?? builtInHistory;\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 [branch, setBranch] = useState<string>(\"\");\n const branchContext = getBranchContext(branch, history.data ?? undefined);\n\n const historyValues =\n branchContext.threadHead?.values ??\n options.initialValues ??\n ({} as StateType);\n\n // Reconstruct subagents from history when:\n // 1. History is loaded (not loading, has data)\n // 2. No active stream is running\n // 3. Subagent filtering is enabled (otherwise subagents aren't tracked)\n // This ensures subagent visualization persists after page refresh or stream completion\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n !history.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 historyError = (() => {\n const error = branchContext.threadHead?.tasks?.at(-1)?.error;\n if (error == null) return undefined;\n try {\n const parsed = JSON.parse(error) as unknown;\n if (StreamError.isStructuredError(parsed)) return new StreamError(parsed);\n return parsed;\n } catch {\n // do nothing\n }\n return error;\n })();\n\n const messageMetadata = (() => {\n const alreadyShown = new Set<string>();\n return getMessages(historyValues).map(\n (message, idx): Omit<MessageMetadata<StateType>, \"streamMetadata\"> => {\n const messageId = message.id ?? idx;\n\n // Find the first checkpoint where the message was seen\n const firstSeenState = findLast(history.data ?? [], (state) =>\n getMessages(state.values)\n .map((m, idx) => m.id ?? idx)\n .includes(messageId)\n );\n\n const checkpointId = firstSeenState?.checkpoint?.checkpoint_id;\n let branch =\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]\n : undefined;\n if (!branch?.branch?.length) branch = undefined;\n\n // serialize branches\n const optionsShown = branch?.branchOptions?.flat(2).join(\",\");\n if (optionsShown) {\n if (alreadyShown.has(optionsShown)) branch = undefined;\n alreadyShown.add(optionsShown);\n }\n\n return {\n messageId: messageId.toString(),\n firstSeenState,\n\n branch: branch?.branch,\n branchOptions: branch?.branchOptions,\n };\n }\n );\n })();\n\n const stop = () =>\n stream.stop(historyValues, {\n onStop: (args) => {\n if (runMetadataStorage && threadId) {\n const runId = runMetadataStorage.getItem(`lg:stream:${threadId}`);\n if (runId) void client.runs.cancel(threadId, runId);\n runMetadataStorage.removeItem(`lg:stream:${threadId}`);\n }\n\n options.onStop?.(args);\n },\n });\n\n // --- TRANSPORT ---\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: SubmitOptions<StateType, ConfigurableType>\n ) => {\n // Unbranch things\n const checkpointId = submitOptions?.checkpoint?.checkpoint_id;\n setBranch(\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]?.branch ?? \"\"\n : \"\"\n );\n\n // When `fetchStateHistory` is requested, thus we assume that branching\n // is enabled. We then need to include the implicit branch.\n const includeImplicitBranch =\n historyLimit === true || typeof historyLimit === \"number\";\n\n const shouldRefetch =\n // We're expecting the whole thread state in onFinish\n options.onFinish != null ||\n // We're fetching history, thus we need the latest checkpoint\n // to ensure we're not accidentally submitting to a wrong branch\n includeImplicitBranch;\n\n let callbackMeta: RunCallbackMeta | undefined;\n let rejoinKey: `lg:stream:${string}` | undefined;\n let usableThreadId = threadId;\n\n await stream.start(\n async (signal: AbortSignal) => {\n stream.setStreamValues((values) => {\n const prev = { ...historyValues, ...values };\n if (submitOptions?.optimisticValues != null) {\n return {\n ...prev,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(prev)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...prev };\n });\n\n if (!usableThreadId) {\n const thread = await client.threads.create({\n threadId: submitOptions?.threadId,\n metadata: submitOptions?.metadata,\n signal,\n });\n\n usableThreadId = thread.thread_id;\n\n // Pre-emptively update the thread ID before\n // stream cancellation is kicked off and thread\n // is being refetched\n threadIdRef.current = usableThreadId;\n threadIdStreamingRef.current = usableThreadId;\n\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n threadIdStreamingRef.current = usableThreadId;\n\n const streamMode = unique([\n ...(submitOptions?.streamMode ?? []),\n ...trackStreamModeRef.current,\n ...callbackStreamMode,\n ]);\n\n let checkpoint =\n submitOptions?.checkpoint ??\n (includeImplicitBranch\n ? branchContext.threadHead?.checkpoint\n : undefined) ??\n undefined;\n\n // Avoid specifying a checkpoint if user explicitly set it to null\n if (submitOptions?.checkpoint === null) checkpoint = undefined;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (checkpoint != null) delete checkpoint.thread_id;\n const streamResumable =\n submitOptions?.streamResumable ?? !!runMetadataStorage;\n\n return client.runs.stream(usableThreadId, options.assistantId, {\n input: values as Record<string, unknown>,\n config: submitOptions?.config,\n context: submitOptions?.context,\n command: submitOptions?.command,\n\n interruptBefore: submitOptions?.interruptBefore,\n interruptAfter: submitOptions?.interruptAfter,\n metadata: submitOptions?.metadata,\n multitaskStrategy: submitOptions?.multitaskStrategy,\n onCompletion: submitOptions?.onCompletion,\n onDisconnect:\n submitOptions?.onDisconnect ??\n (streamResumable ? \"continue\" : \"cancel\"),\n\n signal,\n\n checkpoint,\n streamMode,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n streamResumable,\n durability: submitOptions?.durability,\n onRunCreated(params) {\n callbackMeta = {\n run_id: params.run_id,\n thread_id: params.thread_id ?? usableThreadId!,\n };\n\n if (runMetadataStorage) {\n rejoinKey = `lg:stream:${usableThreadId}`;\n runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);\n }\n\n options.onCreated?.(callbackMeta);\n },\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: options,\n\n async onSuccess() {\n if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);\n\n if (shouldRefetch) {\n const newHistory = await history.mutate(usableThreadId!);\n const lastHead = newHistory?.at(0);\n if (lastHead) {\n // We now have the latest update from /history\n // Thus we can clear the local stream state\n options.onFinish?.(lastHead, callbackMeta);\n return null;\n }\n }\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const joinStream = async (\n runId: string,\n lastEventId?: string,\n joinOptions?: {\n streamMode?: StreamMode | StreamMode[];\n filter?: (event: {\n id?: string;\n event: StreamEvent;\n data: unknown;\n }) => boolean;\n }\n ) => {\n // eslint-disable-next-line no-param-reassign\n lastEventId ??= \"-1\";\n if (!threadId) return;\n\n const callbackMeta: RunCallbackMeta = {\n thread_id: threadId,\n run_id: runId,\n };\n\n await stream.start(\n async (signal: AbortSignal) => {\n threadIdStreamingRef.current = threadId;\n const stream = client.runs.joinStream(threadId, runId, {\n signal,\n lastEventId,\n streamMode: joinOptions?.streamMode,\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n\n return joinOptions?.filter != null\n ? filterStream(stream, joinOptions.filter)\n : stream;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: options,\n async onSuccess() {\n runMetadataStorage?.removeItem(`lg:stream:${threadId}`);\n const newHistory = await history.mutate(threadId);\n const lastHead = newHistory?.at(0);\n if (lastHead) options.onFinish?.(lastHead, callbackMeta);\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const reconnectKey = useMemo(() => {\n if (!runMetadataStorage || stream.isLoading) return undefined;\n if (typeof window === \"undefined\") return undefined;\n const runId = runMetadataStorage?.getItem(`lg:stream:${threadId}`);\n if (!runId) return undefined;\n return { runId, threadId };\n }, [runMetadataStorage, stream.isLoading, threadId]);\n\n const shouldReconnect = !!runMetadataStorage;\n const reconnectRef = useRef({ threadId, shouldReconnect });\n\n const joinStreamRef = useRef<typeof joinStream>(joinStream);\n joinStreamRef.current = joinStream;\n\n useEffect(() => {\n // reset shouldReconnect when switching threads\n if (reconnectRef.current.threadId !== threadId) {\n reconnectRef.current = { threadId, shouldReconnect };\n }\n }, [threadId, shouldReconnect]);\n\n useEffect(() => {\n if (reconnectKey && reconnectRef.current.shouldReconnect) {\n reconnectRef.current.shouldReconnect = false;\n void joinStreamRef.current?.(reconnectKey.runId);\n }\n }, [reconnectKey]);\n\n const error = stream.error ?? historyError ?? history.error;\n const values = stream.values ?? historyValues;\n\n return {\n get values() {\n trackStreamMode(\"values\");\n return values;\n },\n\n client,\n assistantId: options.assistantId,\n\n error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n\n joinStream,\n\n branch,\n setBranch,\n\n get history() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `history`\"\n );\n }\n\n return branchContext.flatHistory;\n },\n\n isThreadLoading: history.isLoading && history.data == null,\n\n get experimental_branchTree() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `experimental_branchTree`\"\n );\n }\n\n return branchContext.branchTree;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n values != null &&\n \"__interrupt__\" in values &&\n Array.isArray(values.__interrupt__)\n ) {\n const valueInterrupts = values.__interrupt__;\n if (valueInterrupts.length === 0) return [{ when: \"breakpoint\" }];\n return valueInterrupts;\n }\n\n // If we're deferring to old interrupt detection logic, don't show the interrupt if the stream is loading\n if (stream.isLoading) return [];\n\n // Collect interrupts from ALL tasks (not just the last one)\n const allTasks = branchContext.threadHead?.tasks ?? [];\n const allInterrupts = allTasks.flatMap((t) => t.interrupts ?? []);\n\n if (allInterrupts.length > 0) {\n return allInterrupts as Interrupt<InterruptType>[];\n }\n\n // check if there's a next task present (breakpoint-style interrupt)\n const next = branchContext.threadHead?.next ?? [];\n if (!next.length || error != null) return [];\n return [{ when: \"breakpoint\" }];\n },\n\n get interrupt() {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n trackStreamMode(\"messages-tuple\", \"values\");\n return getMessages(values);\n },\n\n get toolCalls() {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n getMessagesMetadata(\n message: Message<ToolCallType>,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n trackStreamMode(\"values\");\n\n const streamMetadata = messageManager.get(message.id)?.metadata;\n const historyMetadata = messageMetadata?.find(\n (m) => m.messageId === (message.id ?? index)\n );\n\n if (streamMetadata != null || historyMetadata != null) {\n return {\n ...historyMetadata,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n\n return undefined;\n },\n\n get subagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByMessage(messageId);\n },\n };\n}\n"],"mappings":"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"}
|
package/dist/react/stream.lgp.js
CHANGED
|
@@ -5,8 +5,8 @@ import { filterStream, findLast, unique } from "../ui/utils.js";
|
|
|
5
5
|
import { StreamError } from "../ui/errors.js";
|
|
6
6
|
import { getBranchContext } from "../ui/branching.js";
|
|
7
7
|
import { MessageTupleManager } from "../ui/messages.js";
|
|
8
|
-
import { StreamManager } from "../ui/manager.js";
|
|
9
8
|
import { getToolCallsWithResults } from "../utils/tools.js";
|
|
9
|
+
import { StreamManager } from "../ui/manager.js";
|
|
10
10
|
import { useControllableThreadId } from "./thread.js";
|
|
11
11
|
import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
12
12
|
|
|
@@ -121,7 +121,11 @@ function useStreamLGP(options) {
|
|
|
121
121
|
options.defaultHeaders
|
|
122
122
|
]);
|
|
123
123
|
const [messageManager] = useState(() => new MessageTupleManager());
|
|
124
|
-
const [stream] = useState(() => new StreamManager(messageManager, {
|
|
124
|
+
const [stream] = useState(() => new StreamManager(messageManager, {
|
|
125
|
+
throttle: options.throttle ?? false,
|
|
126
|
+
subagentToolNames: options.subagentToolNames,
|
|
127
|
+
filterSubagentMessages: options.filterSubagentMessages
|
|
128
|
+
}));
|
|
125
129
|
useSyncExternalStore(stream.subscribe, stream.getSnapshot, stream.getSnapshot);
|
|
126
130
|
const [threadId, onThreadId] = useControllableThreadId(options);
|
|
127
131
|
const trackStreamModeRef = useRef([]);
|
|
@@ -181,6 +185,11 @@ function useStreamLGP(options) {
|
|
|
181
185
|
const [branch, setBranch] = useState("");
|
|
182
186
|
const branchContext = getBranchContext(branch, history.data ?? void 0);
|
|
183
187
|
const historyValues = branchContext.threadHead?.values ?? options.initialValues ?? {};
|
|
188
|
+
const historyMessages = getMessages(historyValues);
|
|
189
|
+
const shouldReconstructSubagents = options.filterSubagentMessages && !stream.isLoading && !history.isLoading && historyMessages.length > 0;
|
|
190
|
+
useEffect(() => {
|
|
191
|
+
if (shouldReconstructSubagents) stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });
|
|
192
|
+
}, [shouldReconstructSubagents, historyMessages.length]);
|
|
184
193
|
const historyError = (() => {
|
|
185
194
|
const error = branchContext.threadHead?.tasks?.at(-1)?.error;
|
|
186
195
|
if (error == null) return void 0;
|
|
@@ -232,7 +241,7 @@ function useStreamLGP(options) {
|
|
|
232
241
|
stream.setStreamValues((values) => {
|
|
233
242
|
const prev = {
|
|
234
243
|
...historyValues,
|
|
235
|
-
...values
|
|
244
|
+
...values
|
|
236
245
|
};
|
|
237
246
|
if (submitOptions?.optimisticValues != null) return {
|
|
238
247
|
...prev,
|
|
@@ -404,20 +413,23 @@ function useStreamLGP(options) {
|
|
|
404
413
|
if (historyLimit === false) throw new Error("`fetchStateHistory` must be set to `true` to use `experimental_branchTree`");
|
|
405
414
|
return branchContext.branchTree;
|
|
406
415
|
},
|
|
407
|
-
get
|
|
416
|
+
get interrupts() {
|
|
408
417
|
if (values != null && "__interrupt__" in values && Array.isArray(values.__interrupt__)) {
|
|
409
418
|
const valueInterrupts = values.__interrupt__;
|
|
410
|
-
if (valueInterrupts.length === 0) return { when: "breakpoint" };
|
|
411
|
-
if (valueInterrupts.length === 1) return valueInterrupts[0];
|
|
419
|
+
if (valueInterrupts.length === 0) return [{ when: "breakpoint" }];
|
|
412
420
|
return valueInterrupts;
|
|
413
421
|
}
|
|
414
|
-
if (stream.isLoading) return
|
|
415
|
-
const
|
|
416
|
-
if (
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
422
|
+
if (stream.isLoading) return [];
|
|
423
|
+
const allInterrupts = (branchContext.threadHead?.tasks ?? []).flatMap((t) => t.interrupts ?? []);
|
|
424
|
+
if (allInterrupts.length > 0) return allInterrupts;
|
|
425
|
+
if (!(branchContext.threadHead?.next ?? []).length || error != null) return [];
|
|
426
|
+
return [{ when: "breakpoint" }];
|
|
427
|
+
},
|
|
428
|
+
get interrupt() {
|
|
429
|
+
const all = this.interrupts;
|
|
430
|
+
if (all.length === 0) return void 0;
|
|
431
|
+
if (all.length === 1) return all[0];
|
|
432
|
+
return all;
|
|
421
433
|
},
|
|
422
434
|
get messages() {
|
|
423
435
|
trackStreamMode("messages-tuple", "values");
|
|
@@ -439,6 +451,26 @@ function useStreamLGP(options) {
|
|
|
439
451
|
...historyMetadata,
|
|
440
452
|
streamMetadata
|
|
441
453
|
};
|
|
454
|
+
},
|
|
455
|
+
get subagents() {
|
|
456
|
+
trackStreamMode("updates", "messages-tuple");
|
|
457
|
+
return stream.getSubagents();
|
|
458
|
+
},
|
|
459
|
+
get activeSubagents() {
|
|
460
|
+
trackStreamMode("updates", "messages-tuple");
|
|
461
|
+
return stream.getActiveSubagents();
|
|
462
|
+
},
|
|
463
|
+
getSubagent(toolCallId) {
|
|
464
|
+
trackStreamMode("updates", "messages-tuple");
|
|
465
|
+
return stream.getSubagent(toolCallId);
|
|
466
|
+
},
|
|
467
|
+
getSubagentsByType(type) {
|
|
468
|
+
trackStreamMode("updates", "messages-tuple");
|
|
469
|
+
return stream.getSubagentsByType(type);
|
|
470
|
+
},
|
|
471
|
+
getSubagentsByMessage(messageId) {
|
|
472
|
+
trackStreamMode("updates", "messages-tuple");
|
|
473
|
+
return stream.getSubagentsByMessage(messageId);
|
|
442
474
|
}
|
|
443
475
|
};
|
|
444
476
|
}
|