@langchain/langgraph-sdk 1.5.6 → 1.6.0
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 +27 -4
- 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 +27 -4
- 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 +32 -3
- package/dist/react/stream.lgp.cjs.map +1 -1
- package/dist/react/stream.lgp.js +32 -3
- 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/types.stream.d.cts.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 +137 -0
- package/dist/ui/stream/base.d.cts.map +1 -0
- package/dist/ui/stream/base.d.ts +137 -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 +592 -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 +588 -0
- package/dist/ui/subagents.js.map +1 -0
- package/dist/ui/types.d.cts +377 -5
- package/dist/ui/types.d.cts.map +1 -1
- package/dist/ui/types.d.ts +377 -5
- package/dist/ui/types.d.ts.map +1 -1
- package/package.json +6 -3
package/dist/index.d.cts
CHANGED
|
@@ -5,4 +5,8 @@ import { Command, OnConflictBehavior, RunsInvokePayload } from "./types.cjs";
|
|
|
5
5
|
import { Client, ClientConfig, RequestHook, getApiKey } from "./client.cjs";
|
|
6
6
|
import { overrideFetchImplementation } from "./singletons/fetch.cjs";
|
|
7
7
|
import { BagTemplate } from "./types.template.cjs";
|
|
8
|
-
|
|
8
|
+
import { BaseStream } from "./ui/stream/base.cjs";
|
|
9
|
+
import { UseAgentStream, UseAgentStreamOptions } from "./ui/stream/agent.cjs";
|
|
10
|
+
import { UseDeepAgentStream, UseDeepAgentStreamOptions } from "./ui/stream/deep-agent.cjs";
|
|
11
|
+
import { InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, ResolveStreamInterface, ResolveStreamOptions } from "./ui/stream/index.cjs";
|
|
12
|
+
export { type AIMessage, type Assistant, type AssistantBase, type AssistantGraph, type AssistantVersion, type AssistantsSearchResponse, type BagTemplate, BaseStream, type Checkpoint, Client, type ClientConfig, type Command, type Config, type Cron, type CronCreateForThreadResponse, type CronCreateResponse, type CustomStreamEvent, type DebugStreamEvent, type DefaultValues, type ErrorStreamEvent, type EventsStreamEvent, type FeedbackStreamEvent, type FunctionMessage, type GraphSchema, type HumanMessage, InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, type Interrupt, type Item, type ListNamespaceResponse, type Message, type MessagesStreamEvent, type MessagesTupleStreamEvent, type Metadata, type MetadataStreamEvent, type OnConflictBehavior, type RemoveMessage, type RequestHook, ResolveStreamInterface, ResolveStreamOptions, type Run, type RunsInvokePayload, type SearchItem, type SearchItemsResponse, type StreamMode, type SystemMessage, type Thread, type ThreadState, type ThreadStatus, type ThreadTask, type ToolMessage, type UpdatesStreamEvent, UseAgentStream, UseAgentStreamOptions, UseDeepAgentStream, UseDeepAgentStreamOptions, type ValuesStreamEvent, getApiKey, overrideFetchImplementation };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,4 +5,8 @@ import { Command, OnConflictBehavior, RunsInvokePayload } from "./types.js";
|
|
|
5
5
|
import { Client, ClientConfig, RequestHook, getApiKey } from "./client.js";
|
|
6
6
|
import { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
7
7
|
import { BagTemplate } from "./types.template.js";
|
|
8
|
-
|
|
8
|
+
import { BaseStream } from "./ui/stream/base.js";
|
|
9
|
+
import { UseAgentStream, UseAgentStreamOptions } from "./ui/stream/agent.js";
|
|
10
|
+
import { UseDeepAgentStream, UseDeepAgentStreamOptions } from "./ui/stream/deep-agent.js";
|
|
11
|
+
import { InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, ResolveStreamInterface, ResolveStreamOptions } from "./ui/stream/index.js";
|
|
12
|
+
export { type AIMessage, type Assistant, type AssistantBase, type AssistantGraph, type AssistantVersion, type AssistantsSearchResponse, type BagTemplate, BaseStream, type Checkpoint, Client, type ClientConfig, type Command, type Config, type Cron, type CronCreateForThreadResponse, type CronCreateResponse, type CustomStreamEvent, type DebugStreamEvent, type DefaultValues, type ErrorStreamEvent, type EventsStreamEvent, type FeedbackStreamEvent, type FunctionMessage, type GraphSchema, type HumanMessage, InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, type Interrupt, type Item, type ListNamespaceResponse, type Message, type MessagesStreamEvent, type MessagesTupleStreamEvent, type Metadata, type MetadataStreamEvent, type OnConflictBehavior, type RemoveMessage, type RequestHook, ResolveStreamInterface, ResolveStreamOptions, type Run, type RunsInvokePayload, type SearchItem, type SearchItemsResponse, type StreamMode, type SystemMessage, type Thread, type ThreadState, type ThreadStatus, type ThreadTask, type ToolMessage, type UpdatesStreamEvent, UseAgentStream, UseAgentStreamOptions, UseDeepAgentStream, UseDeepAgentStreamOptions, type ValuesStreamEvent, getApiKey, overrideFetchImplementation };
|
package/dist/react/index.cjs
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_subagents = require('../ui/subagents.cjs');
|
|
2
3
|
const require_stream_custom = require('./stream.custom.cjs');
|
|
3
4
|
const require_stream = require('./stream.cjs');
|
|
4
5
|
|
|
5
6
|
exports.FetchStreamTransport = require_stream_custom.FetchStreamTransport;
|
|
7
|
+
exports.SubagentManager = require_subagents.SubagentManager;
|
|
8
|
+
exports.calculateDepthFromNamespace = require_subagents.calculateDepthFromNamespace;
|
|
9
|
+
exports.extractParentIdFromNamespace = require_subagents.extractParentIdFromNamespace;
|
|
10
|
+
exports.extractToolCallIdFromNamespace = require_subagents.extractToolCallIdFromNamespace;
|
|
11
|
+
exports.isSubagentNamespace = require_subagents.isSubagentNamespace;
|
|
6
12
|
exports.useStream = require_stream.useStream;
|
package/dist/react/index.d.cts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { DefaultToolCall, ToolCallFromTool, ToolCallState, ToolCallWithResult, ToolCallsFromTools } from "../types.messages.cjs";
|
|
2
|
-
import { AgentTypeConfigLike, ExtractAgentConfig, GetToolCallsType, InferAgentToolCalls, IsAgentLike, MessageMetadata, UseStreamCustomOptions, UseStreamOptions, UseStreamThread, UseStreamTransport } from "../ui/types.cjs";
|
|
2
|
+
import { AgentTypeConfigLike, BaseSubagentState, CompiledSubAgentLike, DeepAgentTypeConfigLike, DefaultSubagentStates, ExtractAgentConfig, ExtractDeepAgentConfig, ExtractSubAgentMiddleware, GetToolCallsType, InferAgentToolCalls, InferDeepAgentSubagents, InferSubagentByName, InferSubagentNames, InferSubagentState, IsAgentLike, IsDeepAgentLike, MessageMetadata, SubAgentLike, SubagentStateMap, SubagentStatus, SubagentStream, SubagentToolCall, UseStreamCustomOptions, UseStreamOptions, UseStreamThread, UseStreamTransport } from "../ui/types.cjs";
|
|
3
|
+
import { BaseStream } from "../ui/stream/base.cjs";
|
|
4
|
+
import { UseAgentStream, UseAgentStreamOptions } from "../ui/stream/agent.cjs";
|
|
5
|
+
import { UseDeepAgentStream, UseDeepAgentStreamOptions } from "../ui/stream/deep-agent.cjs";
|
|
6
|
+
import { InferBag, InferNodeNames, InferStateType, InferSubagentStates, InferToolCalls, ResolveStreamInterface, ResolveStreamOptions } from "../ui/stream/index.cjs";
|
|
3
7
|
import { UseStream, UseStreamCustom } from "./types.cjs";
|
|
4
8
|
import { useStream } from "./stream.cjs";
|
|
5
9
|
import { FetchStreamTransport } from "./stream.custom.cjs";
|
|
6
|
-
|
|
10
|
+
import { SubagentManager, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace } from "../ui/subagents.cjs";
|
|
11
|
+
export { type AgentTypeConfigLike, type BaseStream, type BaseSubagentState, 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 ResolveStreamInterface, type ResolveStreamOptions, type SubAgentLike, SubagentManager, type SubagentStateMap, type SubagentStatus, type SubagentStream, type SubagentToolCall, type ToolCallFromTool, type ToolCallState, type ToolCallWithResult, type ToolCallsFromTools, type UseAgentStream, type UseAgentStreamOptions, type UseDeepAgentStream, type UseDeepAgentStreamOptions, type UseStream, type UseStreamCustom, type UseStreamCustomOptions, type UseStreamOptions, type UseStreamThread, type UseStreamTransport, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace, useStream };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { DefaultToolCall, ToolCallFromTool, ToolCallState, ToolCallWithResult, ToolCallsFromTools } from "../types.messages.js";
|
|
2
|
-
import { AgentTypeConfigLike, ExtractAgentConfig, GetToolCallsType, InferAgentToolCalls, IsAgentLike, MessageMetadata, UseStreamCustomOptions, UseStreamOptions, UseStreamThread, UseStreamTransport } from "../ui/types.js";
|
|
2
|
+
import { AgentTypeConfigLike, BaseSubagentState, CompiledSubAgentLike, DeepAgentTypeConfigLike, DefaultSubagentStates, ExtractAgentConfig, ExtractDeepAgentConfig, ExtractSubAgentMiddleware, GetToolCallsType, InferAgentToolCalls, InferDeepAgentSubagents, InferSubagentByName, InferSubagentNames, InferSubagentState, IsAgentLike, IsDeepAgentLike, MessageMetadata, SubAgentLike, SubagentStateMap, SubagentStatus, SubagentStream, SubagentToolCall, UseStreamCustomOptions, UseStreamOptions, UseStreamThread, UseStreamTransport } from "../ui/types.js";
|
|
3
|
+
import { BaseStream } from "../ui/stream/base.js";
|
|
4
|
+
import { UseAgentStream, UseAgentStreamOptions } from "../ui/stream/agent.js";
|
|
5
|
+
import { UseDeepAgentStream, UseDeepAgentStreamOptions } from "../ui/stream/deep-agent.js";
|
|
6
|
+
import { InferBag, InferNodeNames, InferStateType, InferSubagentStates, InferToolCalls, ResolveStreamInterface, ResolveStreamOptions } from "../ui/stream/index.js";
|
|
3
7
|
import { UseStream, UseStreamCustom } from "./types.js";
|
|
4
8
|
import { useStream } from "./stream.js";
|
|
5
9
|
import { FetchStreamTransport } from "./stream.custom.js";
|
|
6
|
-
|
|
10
|
+
import { SubagentManager, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace } from "../ui/subagents.js";
|
|
11
|
+
export { type AgentTypeConfigLike, type BaseStream, type BaseSubagentState, 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 ResolveStreamInterface, type ResolveStreamOptions, type SubAgentLike, SubagentManager, type SubagentStateMap, type SubagentStatus, type SubagentStream, type SubagentToolCall, type ToolCallFromTool, type ToolCallState, type ToolCallWithResult, type ToolCallsFromTools, type UseAgentStream, type UseAgentStreamOptions, type UseDeepAgentStream, type UseDeepAgentStreamOptions, type UseStream, type UseStreamCustom, type UseStreamCustomOptions, type UseStreamOptions, type UseStreamThread, type UseStreamTransport, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace, useStream };
|
package/dist/react/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import { SubagentManager, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace } from "../ui/subagents.js";
|
|
1
2
|
import { FetchStreamTransport } from "./stream.custom.js";
|
|
2
3
|
import { useStream } from "./stream.js";
|
|
3
4
|
|
|
4
|
-
export { FetchStreamTransport, useStream };
|
|
5
|
+
export { FetchStreamTransport, SubagentManager, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace, useStream };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.cjs","names":["useStreamCustom","useStreamLGP"],"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.cjs","names":["useStreamCustom","useStreamLGP"],"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,gCAAqB,gBAAgB,QAAQ,CAAC;AAErD,KAAI,SAEF,QAAOA,sCAAgB,QAAQ;AAIjC,QAAOC,gCAAa,QAAQ"}
|
|
@@ -4,8 +4,8 @@ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
|
4
4
|
const require_sse = require('../utils/sse.cjs');
|
|
5
5
|
const require_stream = require('../utils/stream.cjs');
|
|
6
6
|
const require_messages = require('../ui/messages.cjs');
|
|
7
|
-
const require_manager = require('../ui/manager.cjs');
|
|
8
7
|
const require_tools = require('../utils/tools.cjs');
|
|
8
|
+
const require_manager = require('../ui/manager.cjs');
|
|
9
9
|
const require_thread = require('./thread.cjs');
|
|
10
10
|
let react = require("react");
|
|
11
11
|
|
|
@@ -34,7 +34,11 @@ var FetchStreamTransport = class {
|
|
|
34
34
|
};
|
|
35
35
|
function useStreamCustom(options) {
|
|
36
36
|
const [messageManager] = (0, react.useState)(() => new require_messages.MessageTupleManager());
|
|
37
|
-
const [stream] = (0, react.useState)(() => new require_manager.StreamManager(messageManager, {
|
|
37
|
+
const [stream] = (0, react.useState)(() => new require_manager.StreamManager(messageManager, {
|
|
38
|
+
throttle: options.throttle ?? false,
|
|
39
|
+
subagentToolNames: options.subagentToolNames,
|
|
40
|
+
filterSubagentMessages: options.filterSubagentMessages
|
|
41
|
+
}));
|
|
38
42
|
(0, react.useSyncExternalStore)(stream.subscribe, stream.getSnapshot, stream.getSnapshot);
|
|
39
43
|
const [threadId, onThreadId] = require_thread.useControllableThreadId(options);
|
|
40
44
|
const threadIdRef = (0, react.useRef)(threadId);
|
|
@@ -56,9 +60,13 @@ function useStreamCustom(options) {
|
|
|
56
60
|
};
|
|
57
61
|
};
|
|
58
62
|
const historyValues = options.initialValues ?? {};
|
|
63
|
+
const historyMessages = getMessages(historyValues);
|
|
64
|
+
const shouldReconstructSubagents = options.filterSubagentMessages && !stream.isLoading && historyMessages.length > 0;
|
|
65
|
+
(0, react.useEffect)(() => {
|
|
66
|
+
if (shouldReconstructSubagents) stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });
|
|
67
|
+
}, [shouldReconstructSubagents, historyMessages.length]);
|
|
59
68
|
const stop = () => stream.stop(historyValues, { onStop: options.onStop });
|
|
60
69
|
const submit = async (values, submitOptions) => {
|
|
61
|
-
let callbackMeta;
|
|
62
70
|
let usableThreadId = threadId;
|
|
63
71
|
stream.setStreamValues(() => {
|
|
64
72
|
if (submitOptions?.optimisticValues != null) return {
|
|
@@ -94,7 +102,7 @@ function useStreamCustom(options) {
|
|
|
94
102
|
callbacks: options,
|
|
95
103
|
onSuccess: () => void 0,
|
|
96
104
|
onError(error) {
|
|
97
|
-
options.onError?.(error,
|
|
105
|
+
options.onError?.(error, void 0);
|
|
98
106
|
}
|
|
99
107
|
});
|
|
100
108
|
};
|
|
@@ -125,6 +133,21 @@ function useStreamCustom(options) {
|
|
|
125
133
|
getToolCalls(message) {
|
|
126
134
|
if (!stream.values) return [];
|
|
127
135
|
return require_tools.getToolCallsWithResults(getMessages(stream.values)).filter((tc) => tc.aiMessage.id === message.id);
|
|
136
|
+
},
|
|
137
|
+
get subagents() {
|
|
138
|
+
return stream.getSubagents();
|
|
139
|
+
},
|
|
140
|
+
get activeSubagents() {
|
|
141
|
+
return stream.getActiveSubagents();
|
|
142
|
+
},
|
|
143
|
+
getSubagent(toolCallId) {
|
|
144
|
+
return stream.getSubagent(toolCallId);
|
|
145
|
+
},
|
|
146
|
+
getSubagentsByType(type) {
|
|
147
|
+
return stream.getSubagentsByType(type);
|
|
148
|
+
},
|
|
149
|
+
getSubagentsByMessage(messageId) {
|
|
150
|
+
return stream.getSubagentsByMessage(messageId);
|
|
128
151
|
}
|
|
129
152
|
};
|
|
130
153
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.custom.cjs","names":["BytesLineDecoder","SSEDecoder","IterableReadableStream","MessageTupleManager","StreamManager","useControllableThreadId","getToolCallsWithResults"],"sources":["../../src/react/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetToolCallsType,\n RunCallbackMeta,\n GetConfigurableType,\n UseStreamTransport,\n UseStreamCustomOptions,\n CustomSubmitOptions,\n} from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { Interrupt } from \"../schema.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\n\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (\n url: string,\n init: RequestInit\n ) => Promise<RequestInit> | RequestInit;\n}\n\nexport class FetchStreamTransport<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n> implements UseStreamTransport<StateType, Bag>\n{\n constructor(private readonly options: FetchStreamTransportOptions) {}\n\n async stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{ id?: string; event: string; data: unknown }>> {\n const { signal, ...body } = payload;\n\n let requestInit: RequestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.options.defaultHeaders,\n },\n body: JSON.stringify(body),\n signal,\n };\n\n if (this.options.onRequest) {\n requestInit = await this.options.onRequest(\n this.options.apiUrl,\n requestInit\n );\n }\n const fetchFn = this.options.fetch ?? fetch;\n\n const response = await fetchFn(this.options.apiUrl, requestInit);\n if (!response.ok) {\n throw new Error(`Failed to stream: ${response.statusText}`);\n }\n\n const stream = (\n response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })\n )\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder());\n\n return IterableReadableStream.fromReadableStream(stream);\n }\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(\n options: UseStreamCustomOptions<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 })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\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 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 const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n let callbackMeta: RunCallbackMeta | undefined;\n let usableThreadId = 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 // generate random thread id\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 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: () => undefined,\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n }\n );\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\n get interrupt(): Interrupt<InterruptType> | undefined {\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 if (valueInterrupts.length === 1) return valueInterrupts[0];\n\n // TODO: fix the typing of interrupts if multiple interrupts are returned\n return valueInterrupts as Interrupt<InterruptType>;\n }\n\n return undefined;\n },\n\n get messages(): Message<ToolCallType>[] {\n if (!stream.values) return [];\n return getMessages(stream.values);\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}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stream.custom.cjs","names":["BytesLineDecoder","SSEDecoder","IterableReadableStream","MessageTupleManager","StreamManager","useControllableThreadId","getToolCallsWithResults"],"sources":["../../src/react/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetToolCallsType,\n GetConfigurableType,\n UseStreamTransport,\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n} from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { Interrupt } from \"../schema.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\n\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (\n url: string,\n init: RequestInit\n ) => Promise<RequestInit> | RequestInit;\n}\n\nexport class FetchStreamTransport<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n> implements UseStreamTransport<StateType, Bag>\n{\n constructor(private readonly options: FetchStreamTransportOptions) {}\n\n async stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{ id?: string; event: string; data: unknown }>> {\n const { signal, ...body } = payload;\n\n let requestInit: RequestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.options.defaultHeaders,\n },\n body: JSON.stringify(body),\n signal,\n };\n\n if (this.options.onRequest) {\n requestInit = await this.options.onRequest(\n this.options.apiUrl,\n requestInit\n );\n }\n const fetchFn = this.options.fetch ?? fetch;\n\n const response = await fetchFn(this.options.apiUrl, requestInit);\n if (!response.ok) {\n throw new Error(`Failed to stream: ${response.statusText}`);\n }\n\n const stream = (\n response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })\n )\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder());\n\n return IterableReadableStream.fromReadableStream(stream);\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 })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\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 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 submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n let usableThreadId = 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 // generate random thread id\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 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: () => undefined,\n onError(error) {\n options.onError?.(error, undefined);\n },\n }\n );\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\n get interrupt(): Interrupt<InterruptType> | undefined {\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 if (valueInterrupts.length === 1) return valueInterrupts[0];\n\n // TODO: fix the typing of interrupts if multiple interrupts are returned\n return valueInterrupts as Interrupt<InterruptType>;\n }\n\n return undefined;\n },\n\n get messages(): Message<ToolCallType>[] {\n if (!stream.values) return [];\n return getMessages(stream.values);\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}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.custom.d.cts","names":["GetUpdateType","GetConfigurableType","UseStreamTransport","
|
|
1
|
+
{"version":3,"file":"stream.custom.d.cts","names":["GetUpdateType","GetConfigurableType","UseStreamTransport","AnyStreamCustomOptions","UseStreamCustom","Command","BagTemplate","FetchStreamTransportOptions","HeadersInit","fetch","RequestInit","Promise","FetchStreamTransport","Record","StateType","Bag","AbortSignal","AsyncGenerator","useStreamCustom"],"sources":["../../src/react/stream.custom.d.ts"],"sourcesContent":["import type { GetUpdateType, GetConfigurableType, UseStreamTransport, AnyStreamCustomOptions } from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any);\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (url: string, init: RequestInit) => Promise<RequestInit> | RequestInit;\n}\nexport declare class FetchStreamTransport<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends BagTemplate = BagTemplate> implements UseStreamTransport<StateType, Bag> {\n private readonly options;\n constructor(options: FetchStreamTransportOptions);\n stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{\n id?: string;\n event: string;\n data: unknown;\n }>>;\n}\nexport declare function useStreamCustom<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: AnyStreamCustomOptions<StateType, Bag>): UseStreamCustom<StateType, Bag>;\nexport {};\n"],"mappings":";;;;;UAIUO,2BAAAA;EAAAA;;;QAYSE,EAAAA,MAAAA;;;;gBAIwDC,CAAAA,EARtDF,WAQsDE;EAAW;AAEtF;;OAA4DG,CAAAA,EAAAA,OANzCJ,KAMyCI,GAAAA,CAAAA,CAAAA,GAAAA,IAAAA,EAAAA,GAAAA,EAAAA,EAAAA,GAAAA,GAAAA,CAAAA;;;;WAAwHC,CAAAA,EAAAA,CAAAA,GAAAA,EAAAA,MAAAA,EAAAA,IAAAA,EAFhJJ,WAEgJI,EAAAA,GAFhIH,OAEgIG,CAFxHJ,WAEwHI,CAAAA,GAFzGJ,WAEyGI;;AAE3JP,cAFJK,oBAEIL,CAAAA,kBAFmCM,MAEnCN,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,GAF6DM,MAE7DN,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,EAAAA,YAFkGD,WAElGC,GAFgHD,WAEhHC,CAAAA,YAFwIL,kBAExIK,CAF2JO,SAE3JP,EAFsKQ,GAEtKR,CAAAA,CAAAA;mBAEIQ,OAAAA;aAAKD,CAAAA,OAAAA,EAFTP,2BAESO;QAAnBd,CAAAA,OAAAA,EAAAA;IACsBe,KAAAA,EADtBf,aACsBe,CADRA,GACQA,EADHD,SACGC,CAAAA,GAAAA,IAAAA,GAAAA,SAAAA;IAApBd,OAAAA,EAAAA,mBAAAA,CAAoBc,GAApBd,CAAAA,GAAAA,SAAAA;IACAI,OAAAA,EAAAA,OAAAA,GAAAA,SAAAA;IACDW,MAAAA,EAAAA,WAAAA;MACRL,OAAQM,CAAAA,cAAAA,CAAAA;IAARN,EAAAA,CAAAA,EAAAA,MAAAA;IARyJT,KAAAA,EAAAA,MAAAA;IAAkB,IAAA,EAAA,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.custom.d.ts","names":["GetUpdateType","GetConfigurableType","UseStreamTransport","
|
|
1
|
+
{"version":3,"file":"stream.custom.d.ts","names":["GetUpdateType","GetConfigurableType","UseStreamTransport","AnyStreamCustomOptions","UseStreamCustom","Command","BagTemplate","FetchStreamTransportOptions","HeadersInit","fetch","RequestInit","Promise","FetchStreamTransport","Record","StateType","Bag","AbortSignal","AsyncGenerator","useStreamCustom"],"sources":["../../src/react/stream.custom.d.ts"],"sourcesContent":["import type { GetUpdateType, GetConfigurableType, UseStreamTransport, AnyStreamCustomOptions } from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any);\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (url: string, init: RequestInit) => Promise<RequestInit> | RequestInit;\n}\nexport declare class FetchStreamTransport<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends BagTemplate = BagTemplate> implements UseStreamTransport<StateType, Bag> {\n private readonly options;\n constructor(options: FetchStreamTransportOptions);\n stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{\n id?: string;\n event: string;\n data: unknown;\n }>>;\n}\nexport declare function useStreamCustom<StateType extends Record<string, unknown> = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: AnyStreamCustomOptions<StateType, Bag>): UseStreamCustom<StateType, Bag>;\nexport {};\n"],"mappings":";;;;;UAIUO,2BAAAA;EAAAA;;;QAYSE,EAAAA,MAAAA;;;;gBAIwDC,CAAAA,EARtDF,WAQsDE;EAAW;AAEtF;;OAA4DG,CAAAA,EAAAA,OANzCJ,KAMyCI,GAAAA,CAAAA,CAAAA,GAAAA,IAAAA,EAAAA,GAAAA,EAAAA,EAAAA,GAAAA,GAAAA,CAAAA;;;;WAAwHC,CAAAA,EAAAA,CAAAA,GAAAA,EAAAA,MAAAA,EAAAA,IAAAA,EAFhJJ,WAEgJI,EAAAA,GAFhIH,OAEgIG,CAFxHJ,WAEwHI,CAAAA,GAFzGJ,WAEyGI;;AAE3JP,cAFJK,oBAEIL,CAAAA,kBAFmCM,MAEnCN,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,GAF6DM,MAE7DN,CAAAA,MAAAA,EAAAA,OAAAA,CAAAA,EAAAA,YAFkGD,WAElGC,GAFgHD,WAEhHC,CAAAA,YAFwIL,kBAExIK,CAF2JO,SAE3JP,EAFsKQ,GAEtKR,CAAAA,CAAAA;mBAEIQ,OAAAA;aAAKD,CAAAA,OAAAA,EAFTP,2BAESO;QAAnBd,CAAAA,OAAAA,EAAAA;IACsBe,KAAAA,EADtBf,aACsBe,CADRA,GACQA,EADHD,SACGC,CAAAA,GAAAA,IAAAA,GAAAA,SAAAA;IAApBd,OAAAA,EAAAA,mBAAAA,CAAoBc,GAApBd,CAAAA,GAAAA,SAAAA;IACAI,OAAAA,EAAAA,OAAAA,GAAAA,SAAAA;IACDW,MAAAA,EAAAA,WAAAA;MACRL,OAAQM,CAAAA,cAAAA,CAAAA;IAARN,EAAAA,CAAAA,EAAAA,MAAAA;IARyJT,KAAAA,EAAAA,MAAAA;IAAkB,IAAA,EAAA,OAAA"}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { BytesLineDecoder, SSEDecoder } from "../utils/sse.js";
|
|
4
4
|
import { IterableReadableStream } from "../utils/stream.js";
|
|
5
5
|
import { MessageTupleManager } from "../ui/messages.js";
|
|
6
|
-
import { StreamManager } from "../ui/manager.js";
|
|
7
6
|
import { getToolCallsWithResults } from "../utils/tools.js";
|
|
7
|
+
import { StreamManager } from "../ui/manager.js";
|
|
8
8
|
import { useControllableThreadId } from "./thread.js";
|
|
9
9
|
import { useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
10
10
|
|
|
@@ -33,7 +33,11 @@ var FetchStreamTransport = class {
|
|
|
33
33
|
};
|
|
34
34
|
function useStreamCustom(options) {
|
|
35
35
|
const [messageManager] = useState(() => new MessageTupleManager());
|
|
36
|
-
const [stream] = useState(() => new StreamManager(messageManager, {
|
|
36
|
+
const [stream] = useState(() => new StreamManager(messageManager, {
|
|
37
|
+
throttle: options.throttle ?? false,
|
|
38
|
+
subagentToolNames: options.subagentToolNames,
|
|
39
|
+
filterSubagentMessages: options.filterSubagentMessages
|
|
40
|
+
}));
|
|
37
41
|
useSyncExternalStore(stream.subscribe, stream.getSnapshot, stream.getSnapshot);
|
|
38
42
|
const [threadId, onThreadId] = useControllableThreadId(options);
|
|
39
43
|
const threadIdRef = useRef(threadId);
|
|
@@ -55,9 +59,13 @@ function useStreamCustom(options) {
|
|
|
55
59
|
};
|
|
56
60
|
};
|
|
57
61
|
const historyValues = options.initialValues ?? {};
|
|
62
|
+
const historyMessages = getMessages(historyValues);
|
|
63
|
+
const shouldReconstructSubagents = options.filterSubagentMessages && !stream.isLoading && historyMessages.length > 0;
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (shouldReconstructSubagents) stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });
|
|
66
|
+
}, [shouldReconstructSubagents, historyMessages.length]);
|
|
58
67
|
const stop = () => stream.stop(historyValues, { onStop: options.onStop });
|
|
59
68
|
const submit = async (values, submitOptions) => {
|
|
60
|
-
let callbackMeta;
|
|
61
69
|
let usableThreadId = threadId;
|
|
62
70
|
stream.setStreamValues(() => {
|
|
63
71
|
if (submitOptions?.optimisticValues != null) return {
|
|
@@ -93,7 +101,7 @@ function useStreamCustom(options) {
|
|
|
93
101
|
callbacks: options,
|
|
94
102
|
onSuccess: () => void 0,
|
|
95
103
|
onError(error) {
|
|
96
|
-
options.onError?.(error,
|
|
104
|
+
options.onError?.(error, void 0);
|
|
97
105
|
}
|
|
98
106
|
});
|
|
99
107
|
};
|
|
@@ -124,6 +132,21 @@ function useStreamCustom(options) {
|
|
|
124
132
|
getToolCalls(message) {
|
|
125
133
|
if (!stream.values) return [];
|
|
126
134
|
return getToolCallsWithResults(getMessages(stream.values)).filter((tc) => tc.aiMessage.id === message.id);
|
|
135
|
+
},
|
|
136
|
+
get subagents() {
|
|
137
|
+
return stream.getSubagents();
|
|
138
|
+
},
|
|
139
|
+
get activeSubagents() {
|
|
140
|
+
return stream.getActiveSubagents();
|
|
141
|
+
},
|
|
142
|
+
getSubagent(toolCallId) {
|
|
143
|
+
return stream.getSubagent(toolCallId);
|
|
144
|
+
},
|
|
145
|
+
getSubagentsByType(type) {
|
|
146
|
+
return stream.getSubagentsByType(type);
|
|
147
|
+
},
|
|
148
|
+
getSubagentsByMessage(messageId) {
|
|
149
|
+
return stream.getSubagentsByMessage(messageId);
|
|
127
150
|
}
|
|
128
151
|
};
|
|
129
152
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.custom.js","names":[],"sources":["../../src/react/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetToolCallsType,\n RunCallbackMeta,\n GetConfigurableType,\n UseStreamTransport,\n UseStreamCustomOptions,\n CustomSubmitOptions,\n} from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { Interrupt } from \"../schema.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\n\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (\n url: string,\n init: RequestInit\n ) => Promise<RequestInit> | RequestInit;\n}\n\nexport class FetchStreamTransport<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n> implements UseStreamTransport<StateType, Bag>\n{\n constructor(private readonly options: FetchStreamTransportOptions) {}\n\n async stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{ id?: string; event: string; data: unknown }>> {\n const { signal, ...body } = payload;\n\n let requestInit: RequestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.options.defaultHeaders,\n },\n body: JSON.stringify(body),\n signal,\n };\n\n if (this.options.onRequest) {\n requestInit = await this.options.onRequest(\n this.options.apiUrl,\n requestInit\n );\n }\n const fetchFn = this.options.fetch ?? fetch;\n\n const response = await fetchFn(this.options.apiUrl, requestInit);\n if (!response.ok) {\n throw new Error(`Failed to stream: ${response.statusText}`);\n }\n\n const stream = (\n response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })\n )\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder());\n\n return IterableReadableStream.fromReadableStream(stream);\n }\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n>(\n options: UseStreamCustomOptions<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 })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\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 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 const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n let callbackMeta: RunCallbackMeta | undefined;\n let usableThreadId = 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 // generate random thread id\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 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: () => undefined,\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n }\n );\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\n get interrupt(): Interrupt<InterruptType> | undefined {\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 if (valueInterrupts.length === 1) return valueInterrupts[0];\n\n // TODO: fix the typing of interrupts if multiple interrupts are returned\n return valueInterrupts as Interrupt<InterruptType>;\n }\n\n return undefined;\n },\n\n get messages(): Message<ToolCallType>[] {\n if (!stream.values) return [];\n return getMessages(stream.values);\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}\n"],"mappings":";;;;;;;;;;;AAqDA,IAAa,uBAAb,MAIA;CACE,YAAY,AAAiB,SAAsC;EAAtC;;CAE7B,MAAM,OAAO,SAK8D;EACzE,MAAM,EAAE,QAAQ,GAAG,SAAS;EAE5B,IAAI,cAA2B;GAC7B,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,GAAG,KAAK,QAAQ;IACjB;GACD,MAAM,KAAK,UAAU,KAAK;GAC1B;GACD;AAED,MAAI,KAAK,QAAQ,UACf,eAAc,MAAM,KAAK,QAAQ,UAC/B,KAAK,QAAQ,QACb,YACD;EAIH,MAAM,WAAW,OAFD,KAAK,QAAQ,SAAS,OAEP,KAAK,QAAQ,QAAQ,YAAY;AAChE,MAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,qBAAqB,SAAS,aAAa;EAG7D,MAAM,UACJ,SAAS,QAAQ,IAAI,eAAe,EAAE,QAAQ,SAAS,KAAK,OAAO,EAAE,CAAC,EAErE,YAAY,kBAAkB,CAAC,CAC/B,YAAY,YAAY,CAAC;AAE5B,SAAO,uBAAuB,mBAAmB,OAAO;;;AAI5D,SAAgB,gBAId,SACiC;CAOjC,MAAM,CAAC,kBAAkB,eAAe,IAAI,qBAAqB,CAAC;CAClE,MAAM,CAAC,UAAU,eAEb,IAAI,cAA8B,gBAAgB,EAChD,UAAU,QAAQ,YAAY,OAC/B,CAAC,CACL;AAED,sBACE,OAAO,WACP,OAAO,aACP,OAAO,YACR;CAED,MAAM,CAAC,UAAU,cAAc,wBAAwB,QAAQ;CAC/D,MAAM,cAAc,OAAsB,SAAS;AAGnD,iBAAgB;AACd,MAAI,YAAY,YAAY,UAAU;AACpC,eAAY,UAAU;AACtB,UAAO,OAAO;;IAEf,CAAC,UAAU,OAAO,CAAC;CAEtB,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;CAElD,MAAM,aAAa,OAAO,KAAK,eAAe,EAAE,QAAQ,QAAQ,QAAQ,CAAC;CAEzE,MAAM,SAAS,OACb,QACA,kBACG;EACH,IAAI;EACJ,IAAI,iBAAiB;AAErB,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;AAEnB,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;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;GACjB,QAAQ,OAAO;AACb,YAAQ,UAAU,OAAO,aAAa;;GAEzC,CACF;;AAGH,QAAO;EACL,IAAI,SAAS;AACX,UAAO,OAAO,UAAW,EAAE;;EAG7B,OAAO,OAAO;EACd,WAAW,OAAO;EAElB;EACA;EAEA,IAAI,YAAkD;AACpD,OACE,OAAO,UAAU,QACjB,mBAAmB,OAAO,UAC1B,MAAM,QAAQ,OAAO,OAAO,cAAc,EAC1C;IACA,MAAM,kBAAkB,OAAO,OAAO;AACtC,QAAI,gBAAgB,WAAW,EAAG,QAAO,EAAE,MAAM,cAAc;AAC/D,QAAI,gBAAgB,WAAW,EAAG,QAAO,gBAAgB;AAGzD,WAAO;;;EAMX,IAAI,WAAoC;AACtC,OAAI,CAAC,OAAO,OAAQ,QAAO,EAAE;AAC7B,UAAO,YAAY,OAAO,OAAO;;EAGnC,IAAI,YAAY;AACd,OAAI,CAAC,OAAO,OAAQ,QAAO,EAAE;AAE7B,UAAO,wBADM,YAAY,OAAO,OAAO,CACW;;EAGpD,aAAa,SAAS;AACpB,OAAI,CAAC,OAAO,OAAQ,QAAO,EAAE;AAG7B,UADqB,wBADR,YAAY,OAAO,OAAO,CACyB,CAC5C,QAAQ,OAAO,GAAG,UAAU,OAAO,QAAQ,GAAG;;EAErE"}
|
|
1
|
+
{"version":3,"file":"stream.custom.js","names":[],"sources":["../../src/react/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetToolCallsType,\n GetConfigurableType,\n UseStreamTransport,\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n} from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { Interrupt } from \"../schema.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\n\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (\n url: string,\n init: RequestInit\n ) => Promise<RequestInit> | RequestInit;\n}\n\nexport class FetchStreamTransport<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate\n> implements UseStreamTransport<StateType, Bag>\n{\n constructor(private readonly options: FetchStreamTransportOptions) {}\n\n async stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{ id?: string; event: string; data: unknown }>> {\n const { signal, ...body } = payload;\n\n let requestInit: RequestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.options.defaultHeaders,\n },\n body: JSON.stringify(body),\n signal,\n };\n\n if (this.options.onRequest) {\n requestInit = await this.options.onRequest(\n this.options.apiUrl,\n requestInit\n );\n }\n const fetchFn = this.options.fetch ?? fetch;\n\n const response = await fetchFn(this.options.apiUrl, requestInit);\n if (!response.ok) {\n throw new Error(`Failed to stream: ${response.statusText}`);\n }\n\n const stream = (\n response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })\n )\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder());\n\n return IterableReadableStream.fromReadableStream(stream);\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 })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\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 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 submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n let usableThreadId = 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 // generate random thread id\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 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: () => undefined,\n onError(error) {\n options.onError?.(error, undefined);\n },\n }\n );\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\n get interrupt(): Interrupt<InterruptType> | undefined {\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 if (valueInterrupts.length === 1) return valueInterrupts[0];\n\n // TODO: fix the typing of interrupts if multiple interrupts are returned\n return valueInterrupts as Interrupt<InterruptType>;\n }\n\n return undefined;\n },\n\n get messages(): Message<ToolCallType>[] {\n if (!stream.values) return [];\n return getMessages(stream.values);\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}\n"],"mappings":"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"}
|
package/dist/react/stream.d.cts
CHANGED
|
@@ -1,40 +1,15 @@
|
|
|
1
1
|
import { BagTemplate } from "../types.template.cjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { UseStreamCustomOptions } from "../ui/types.cjs";
|
|
3
|
+
import { InferBag, InferStateType, ResolveStreamInterface, ResolveStreamOptions } from "../ui/stream/index.cjs";
|
|
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.cts.map
|
|
@@ -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"}
|