@langchain/react 1.0.3 → 1.0.5

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 CHANGED
@@ -7,11 +7,11 @@ import { UseVideoPlayerOptions, VideoPlayerHandle, useVideoPlayer } from "./use-
7
7
  import { UseSuspenseStreamReturn, useSuspenseStream } from "./suspense-stream.cjs";
8
8
  import { StreamProvider, StreamProviderCustomProps, StreamProviderProps, useStreamContext } from "./context.cjs";
9
9
  import { AIMessage, ToolMessage } from "@langchain/core/messages";
10
- import { AnyHeadlessToolImplementation, DefaultToolCall, DefaultToolCall as DefaultToolCall$1, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallFromTool, ToolCallState, ToolCallWithResult as ToolCallWithResult$1, ToolCallsFromTools, ToolEvent, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload } from "@langchain/langgraph-sdk";
11
- import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, MessageMetadata, MessageMetadataMap, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
10
+ import { AnyHeadlessToolImplementation, DefaultToolCall, DefaultToolCall as DefaultToolCall$1, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallState, ToolCallWithResult as ToolCallWithResult$1, ToolCallsFromTools, ToolEvent, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload } from "@langchain/langgraph-sdk";
11
+ import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AssembledToolCallFromTool as ToolCallFromTool, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, InferToolOutput, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, MessageMetadata, MessageMetadataMap, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
12
12
 
13
13
  //#region src/index.d.ts
14
14
  type ToolCallWithResult<ToolCall = DefaultToolCall$1> = ToolCallWithResult$1<ToolCall, ToolMessage, AIMessage>;
15
15
  //#endregion
16
- export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type AudioPlayerHandle, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, type PlayerStatus, STREAM_CONTROLLER, type SelectorTarget, StreamProvider, type StreamProviderCustomProps, type StreamProviderProps, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type UseAudioPlayerOptions, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type UseSubmissionQueueReturn, type UseSuspenseStreamReturn, type UseVideoPlayerOptions, type VideoMedia, type VideoPlayerHandle, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, useAudio, useAudioPlayer, useChannel, useExtension, useFiles, useImages, useMediaURL, useMessageMetadata, useMessages, useProjection, useStream, useStreamContext, useSubmissionQueue, useSuspenseStream, useToolCalls, useValues, useVideo, useVideoPlayer };
16
+ export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type AudioPlayerHandle, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InferToolOutput, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, type PlayerStatus, STREAM_CONTROLLER, type SelectorTarget, StreamProvider, type StreamProviderCustomProps, type StreamProviderProps, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type UseAudioPlayerOptions, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type UseSubmissionQueueReturn, type UseSuspenseStreamReturn, type UseVideoPlayerOptions, type VideoMedia, type VideoPlayerHandle, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, useAudio, useAudioPlayer, useChannel, useExtension, useFiles, useImages, useMediaURL, useMessageMetadata, useMessages, useProjection, useStream, useStreamContext, useSubmissionQueue, useSuspenseStream, useToolCalls, useValues, useVideo, useVideoPlayer };
17
17
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;KAkGY,kBAAA,YAA8B,iBAAA,IACxC,oBAAA,CAAoB,QAAA,EAAU,WAAA,EAAiB,SAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;KAoGY,kBAAA,YAA8B,iBAAA,IACxC,oBAAA,CAAoB,QAAA,EAAU,WAAA,EAAiB,SAAA"}
package/dist/index.d.ts CHANGED
@@ -6,12 +6,12 @@ import { AudioPlayerHandle, PlayerStatus, UseAudioPlayerOptions, useAudioPlayer
6
6
  import { UseVideoPlayerOptions, VideoPlayerHandle, useVideoPlayer } from "./use-video-player.js";
7
7
  import { UseSuspenseStreamReturn, useSuspenseStream } from "./suspense-stream.js";
8
8
  import { StreamProvider, StreamProviderCustomProps, StreamProviderProps, useStreamContext } from "./context.js";
9
- import { AnyHeadlessToolImplementation, DefaultToolCall, DefaultToolCall as DefaultToolCall$1, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallFromTool, ToolCallState, ToolCallWithResult as ToolCallWithResult$1, ToolCallsFromTools, ToolEvent, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload } from "@langchain/langgraph-sdk";
10
- import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, MessageMetadata, MessageMetadataMap, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
9
+ import { AnyHeadlessToolImplementation, DefaultToolCall, DefaultToolCall as DefaultToolCall$1, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallState, ToolCallWithResult as ToolCallWithResult$1, ToolCallsFromTools, ToolEvent, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload } from "@langchain/langgraph-sdk";
10
+ import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AssembledToolCallFromTool as ToolCallFromTool, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, InferToolOutput, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, MessageMetadata, MessageMetadataMap, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
11
11
  import { AIMessage, ToolMessage } from "@langchain/core/messages";
12
12
 
13
13
  //#region src/index.d.ts
14
14
  type ToolCallWithResult<ToolCall = DefaultToolCall$1> = ToolCallWithResult$1<ToolCall, ToolMessage, AIMessage>;
15
15
  //#endregion
16
- export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type AudioPlayerHandle, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, type PlayerStatus, STREAM_CONTROLLER, type SelectorTarget, StreamProvider, type StreamProviderCustomProps, type StreamProviderProps, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type UseAudioPlayerOptions, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type UseSubmissionQueueReturn, type UseSuspenseStreamReturn, type UseVideoPlayerOptions, type VideoMedia, type VideoPlayerHandle, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, useAudio, useAudioPlayer, useChannel, useExtension, useFiles, useImages, useMediaURL, useMessageMetadata, useMessages, useProjection, useStream, useStreamContext, useSubmissionQueue, useSuspenseStream, useToolCalls, useValues, useVideo, useVideoPlayer };
16
+ export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type AudioPlayerHandle, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InferToolOutput, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, type PlayerStatus, STREAM_CONTROLLER, type SelectorTarget, StreamProvider, type StreamProviderCustomProps, type StreamProviderProps, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type UseAudioPlayerOptions, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type UseSubmissionQueueReturn, type UseSuspenseStreamReturn, type UseVideoPlayerOptions, type VideoMedia, type VideoPlayerHandle, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, useAudio, useAudioPlayer, useChannel, useExtension, useFiles, useImages, useMediaURL, useMessageMetadata, useMessages, useProjection, useStream, useStreamContext, useSubmissionQueue, useSuspenseStream, useToolCalls, useValues, useVideo, useVideoPlayer };
17
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;KAkGY,kBAAA,YAA8B,iBAAA,IACxC,oBAAA,CAAoB,QAAA,EAAU,WAAA,EAAiB,SAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;KAoGY,kBAAA,YAA8B,iBAAA,IACxC,oBAAA,CAAoB,QAAA,EAAU,WAAA,EAAiB,SAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.cjs","names":["NAMESPACE_SEPARATOR","useProjection","getRegistry","STREAM_CONTROLLER"],"sources":["../src/selectors.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useMemo, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n MessageMetadata,\n MessageMetadataMap,\n SubmissionQueueEntry,\n SubmissionQueueSnapshot,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector hooks don't need to carry `InterruptType` /\n * `ConfigurableType` — they only ever read state. Accepting a\n * `StateType`-parameterised stream (with the other two generics\n * widened to `any`) lets callers keep their full\n * `useStream<State, Interrupt, Configurable>()` handle\n * without re-declaring the interrupt / configurable shapes at every\n * selector call site.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector hook can be targeted at. Callers can pass any of:\n * - `undefined` — root namespace (cheap: served by the always-on root store)\n * - a {@link SubagentDiscoverySnapshot} — the snapshot returned by `stream.subagents.get(...)`\n * - a {@link SubgraphDiscoverySnapshot} — the snapshot returned by `stream.subgraphs.get(...)`\n * - an explicit `{ namespace: string[] }` — any other namespaced scope\n * - a raw `string[]` — escape hatch identical to the object form\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target;\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n// The stream type we accept for selectors — purposely loose so\n// selector hooks remain callable from components that don't carry\n// the exact State/Interrupt/Configurable generics. We use `any` for\n// all three generics because `UseStreamReturn` is\n// invariant in `State` and `Configurable` (they flow through both\n// reader and writer positions), so a concrete\n// `useStream<typeof agent>()` handle wouldn't flow into\n// a `<object, unknown, object>` slot otherwise.\n//\n// Typed selectors (`useValues<S>` etc.) use {@link StreamHandle}\n// above so the concrete `StateType` flows into the return; hooks\n// that don't depend on state (`useMessages`, `useAudio`, …) stay on\n// `AnyStream` for maximum flexibility.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Subscribe to a scoped `messages` stream. Pass `stream` and\n * optionally a subagent/subgraph snapshot (or any namespaced target).\n *\n * Contract:\n * - At the root (no target) this returns `stream.messages` directly\n * — no extra subscription is opened. `stream.messages` is the\n * live merge of `messages`-channel token deltas and\n * `values.messages` snapshots (see\n * {@link UseStreamReturn.messages}), so token-by-token\n * streaming here depends on the backend emitting `messages`\n * channel events. Backends that only emit `values` updates will\n * render full turns at once rather than streaming.\n * - For any other namespace, the mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. Unmounting\n * the last component that watches this namespace closes the\n * subscription automatically.\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: SelectorTarget\n): BaseMessage[] {\n const namespace = resolveNamespace(target);\n const key = `messages|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace),\n key,\n EMPTY_MESSAGES\n );\n return isRoot(namespace) ? stream.messages : scoped;\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link useMessages}; at the root this just returns\n * `stream.toolCalls`.\n *\n * The optional generic `T` can be passed to narrow the type of\n * `toolCall.args` on the returned array. Accepts either:\n * - an agent brand (`typeof agent`) — union is derived from the\n * agent's declared tools;\n * - an array of LangGraph tools (`typeof tools`) — union is derived\n * from `ToolCallFromTool<T[number]>`;\n * - any direct `DefaultToolCall` shape.\n *\n * When omitted, returns the plain `AssembledToolCall[]` union used by\n * the controller.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[] {\n const namespace = resolveNamespace(target);\n const key = `toolCalls|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace),\n key,\n EMPTY_TOOLCALLS\n );\n return isRoot(namespace) ? stream.toolCalls : scoped;\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — most-recent state payload\n * for a namespace. Equivalent to reading `stream.values` at the root.\n *\n * When the payload carries a `messages` array, it is coerced to\n * `BaseMessage` instances to keep parity with the root projection.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on the parent `useStream<State>()` — no explicit\n * generic required. Non-nullable because the root snapshot always\n * carries `values` (falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): the scoped payload can\n * have a different shape than the root state (e.g. a subagent\n * returning its own substate). Callers should annotate the\n * expected shape explicitly: `useValues<SubagentState>(stream, sub)`.\n * Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): StateType;\n/**\n * Explicit-generic override. Accepts:\n * - an agent brand or compiled graph (unwrapped via\n * {@link InferStateType});\n * - a plain state shape (returned as-is).\n *\n * The root-call form is non-nullable (the root snapshot is always\n * present); the scoped form returns `T | undefined` because a\n * projection may not have emitted a payload yet.\n */\nexport function useValues<T>(stream: AnyStream): InferStateType<T>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): T | undefined;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): unknown {\n const namespace = resolveNamespace(target);\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\n return isRoot(namespace) ? stream.values : scoped;\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — most-recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function useExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget\n): T | undefined {\n const namespace = resolveNamespace(target);\n const key = `extension|${name}|${namespaceKey(namespace)}`;\n return useProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}\n * for the common cases.\n */\n/**\n * Subscribe to a scoped audio-media stream. Returns an array of\n * {@link AudioMedia} handles, one per message containing at least one\n * `AudioBlock` in the target namespace.\n *\n * Each handle is yielded on its first matching `content-block-start`,\n * exposes `.partialBytes` for live access, settles `.blob` /\n * `.objectURL` / `.transcript` on `message-finish`, and surfaces\n * fail-loud errors via `.error`.\n *\n * Pair with {@link useMediaURL} to turn a handle into an `<audio src>`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): AudioMedia[] {\n const namespace = resolveNamespace(target);\n const key = `audio|${namespaceKey(namespace)}`;\n return useProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): ImageMedia[] {\n const namespace = resolveNamespace(target);\n const key = `images|${namespaceKey(namespace)}`;\n return useProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): VideoMedia[] {\n const namespace = resolveNamespace(target);\n const key = `video|${namespaceKey(namespace)}`;\n return useProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for an\n * `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): FileMedia[] {\n const namespace = resolveNamespace(target);\n const key = `files|${namespaceKey(namespace)}`;\n return useProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Event[] {\n const namespace = resolveNamespace(target);\n const channelKey = useMemo(() => [...channels].sort().join(\",\"), [channels]);\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${channelKey}|${namespaceKey(namespace)}`;\n return useProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace, options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Read metadata recorded for a specific message id — today exposes\n * `parentCheckpointId`, the checkpoint the message was first seen on.\n * Designed for fork / edit flows:\n *\n * ```tsx\n * const { parentCheckpointId } = useMessageMetadata(stream, msg.id) ?? {};\n * if (parentCheckpointId) {\n * await stream.submit(input, { forkFrom: { checkpointId: parentCheckpointId } });\n * }\n * ```\n *\n * Returns `undefined` when the id isn't known yet (e.g. the server\n * hasn't emitted `parent_checkpoint` for that message, or the message\n * arrived via `messages`-channel deltas only and no `values` snapshot\n * has landed for it yet).\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: string | undefined\n): MessageMetadata | undefined {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const snapshot = useSyncExternalStore<MessageMetadataMap>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return messageId == null ? undefined : snapshot.get(messageId);\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with `multitaskStrategy:\n * \"enqueue\"` while another run is in flight. The returned object is\n * stable per snapshot so consumers can pass `entries` straight into a\n * `<Fragment key={e.id}>` list without extra memoisation.\n *\n * Today the queue is maintained client-side; once the server starts\n * emitting a dedicated queue channel (roadmap A0.3) the controller\n * will mirror that state directly — the hook surface will not change.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: SubmissionQueueSnapshot<StateType>;\n readonly size: number;\n cancel(id: string): Promise<boolean>;\n clear(): Promise<void>;\n}\n\nexport function useSubmissionQueue<StateType extends object>(\n stream: StreamHandle<StateType>\n): UseSubmissionQueueReturn<StateType>;\nexport function useSubmissionQueue(stream: AnyStream): UseSubmissionQueueReturn;\nexport function useSubmissionQueue(\n stream: AnyStream\n): UseSubmissionQueueReturn {\n const controller = stream[STREAM_CONTROLLER];\n const store = controller.queueStore;\n const entries = useSyncExternalStore<SubmissionQueueSnapshot>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return useMemo<UseSubmissionQueueReturn>(\n () => ({\n entries,\n size: entries.length,\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\n }),\n [entries, controller]\n );\n}\n\nexport type { SubmissionQueueEntry, SubmissionQueueSnapshot };\n"],"mappings":"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"}
1
+ {"version":3,"file":"selectors.cjs","names":["NAMESPACE_SEPARATOR","useProjection","getRegistry","STREAM_CONTROLLER"],"sources":["../src/selectors.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useMemo, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n MessageMetadata,\n MessageMetadataMap,\n SubmissionQueueEntry,\n SubmissionQueueSnapshot,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector hooks don't need to carry `InterruptType` /\n * `ConfigurableType` — they only ever read state. Accepting a\n * `StateType`-parameterised stream (with the other two generics\n * widened to `any`) lets callers keep their full\n * `useStream<State, Interrupt, Configurable>()` handle\n * without re-declaring the interrupt / configurable shapes at every\n * selector call site.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector hook can be targeted at. Callers can pass any of:\n * - `undefined` — root namespace (cheap: served by the always-on root store)\n * - a {@link SubagentDiscoverySnapshot} — the snapshot returned by `stream.subagents.get(...)`\n * - a {@link SubgraphDiscoverySnapshot} — the snapshot returned by `stream.subgraphs.get(...)`\n * - an explicit `{ namespace: string[] }` — any other namespaced scope\n * - a raw `string[]` — escape hatch identical to the object form\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target;\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n// The stream type we accept for selectors — purposely loose so\n// selector hooks remain callable from components that don't carry\n// the exact State/Interrupt/Configurable generics. We use `any` for\n// all three generics because `UseStreamReturn` is\n// invariant in `State` and `Configurable` (they flow through both\n// reader and writer positions), so a concrete\n// `useStream<typeof agent>()` handle wouldn't flow into\n// a `<object, unknown, object>` slot otherwise.\n//\n// Typed selectors (`useValues<S>` etc.) use {@link StreamHandle}\n// above so the concrete `StateType` flows into the return; hooks\n// that don't depend on state (`useMessages`, `useAudio`, …) stay on\n// `AnyStream` for maximum flexibility.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Subscribe to a scoped `messages` stream. Pass `stream` and\n * optionally a subagent/subgraph snapshot (or any namespaced target).\n *\n * Contract:\n * - At the root (no target) this returns `stream.messages` directly\n * — no extra subscription is opened. `stream.messages` is the\n * live merge of `messages`-channel token deltas and\n * `values.messages` snapshots (see\n * {@link UseStreamReturn.messages}), so token-by-token\n * streaming here depends on the backend emitting `messages`\n * channel events. Backends that only emit `values` updates will\n * render full turns at once rather than streaming.\n * - For any other namespace, the mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. Unmounting\n * the last component that watches this namespace closes the\n * subscription automatically.\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: SelectorTarget\n): BaseMessage[] {\n const namespace = resolveNamespace(target);\n const key = `messages|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace),\n key,\n EMPTY_MESSAGES\n );\n return isRoot(namespace) ? stream.messages : scoped;\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link useMessages}; at the root this just returns\n * `stream.toolCalls`.\n *\n * The optional generic `T` can be passed to narrow the type of\n * assembled tool calls on the returned array. Accepts either:\n * - an agent brand (`typeof agent`) — union is derived from the\n * agent's declared tools via {@link InferToolCalls};\n * - an array of LangGraph tools (`typeof tools`) — union is derived\n * from {@link InferToolCalls} (parallel to {@link ToolCallsFromTools}).\n *\n * When omitted, returns the plain `AssembledToolCall[]` union used by\n * the controller.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget\n): InferToolCalls<T>[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[] {\n const namespace = resolveNamespace(target);\n const key = `toolCalls|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace),\n key,\n EMPTY_TOOLCALLS\n );\n return isRoot(namespace) ? stream.toolCalls : scoped;\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — most-recent state payload\n * for a namespace. Equivalent to reading `stream.values` at the root.\n *\n * When the payload carries a `messages` array, it is coerced to\n * `BaseMessage` instances to keep parity with the root projection.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on the parent `useStream<State>()` — no explicit\n * generic required. Non-nullable because the root snapshot always\n * carries `values` (falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): the scoped payload can\n * have a different shape than the root state (e.g. a subagent\n * returning its own substate). Callers should annotate the\n * expected shape explicitly: `useValues<SubagentState>(stream, sub)`.\n * Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): StateType;\n/**\n * Explicit-generic override. Accepts:\n * - an agent brand or compiled graph (unwrapped via\n * {@link InferStateType});\n * - a plain state shape (returned as-is).\n *\n * The root-call form is non-nullable (the root snapshot is always\n * present); the scoped form returns `T | undefined` because a\n * projection may not have emitted a payload yet.\n */\nexport function useValues<T>(stream: AnyStream): InferStateType<T>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): T | undefined;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): unknown {\n const namespace = resolveNamespace(target);\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\n return isRoot(namespace) ? stream.values : scoped;\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — most-recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function useExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget\n): T | undefined {\n const namespace = resolveNamespace(target);\n const key = `extension|${name}|${namespaceKey(namespace)}`;\n return useProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}\n * for the common cases.\n */\n/**\n * Subscribe to a scoped audio-media stream. Returns an array of\n * {@link AudioMedia} handles, one per message containing at least one\n * `AudioBlock` in the target namespace.\n *\n * Each handle is yielded on its first matching `content-block-start`,\n * exposes `.partialBytes` for live access, settles `.blob` /\n * `.objectURL` / `.transcript` on `message-finish`, and surfaces\n * fail-loud errors via `.error`.\n *\n * Pair with {@link useMediaURL} to turn a handle into an `<audio src>`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): AudioMedia[] {\n const namespace = resolveNamespace(target);\n const key = `audio|${namespaceKey(namespace)}`;\n return useProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): ImageMedia[] {\n const namespace = resolveNamespace(target);\n const key = `images|${namespaceKey(namespace)}`;\n return useProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): VideoMedia[] {\n const namespace = resolveNamespace(target);\n const key = `video|${namespaceKey(namespace)}`;\n return useProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for an\n * `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): FileMedia[] {\n const namespace = resolveNamespace(target);\n const key = `files|${namespaceKey(namespace)}`;\n return useProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Event[] {\n const namespace = resolveNamespace(target);\n const channelKey = useMemo(() => [...channels].sort().join(\",\"), [channels]);\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${channelKey}|${namespaceKey(namespace)}`;\n return useProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace, options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Read metadata recorded for a specific message id — today exposes\n * `parentCheckpointId`, the checkpoint the message was first seen on.\n * Designed for fork / edit flows:\n *\n * ```tsx\n * const { parentCheckpointId } = useMessageMetadata(stream, msg.id) ?? {};\n * if (parentCheckpointId) {\n * await stream.submit(input, { forkFrom: { checkpointId: parentCheckpointId } });\n * }\n * ```\n *\n * Returns `undefined` when the id isn't known yet (e.g. the server\n * hasn't emitted `parent_checkpoint` for that message, or the message\n * arrived via `messages`-channel deltas only and no `values` snapshot\n * has landed for it yet).\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: string | undefined\n): MessageMetadata | undefined {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const snapshot = useSyncExternalStore<MessageMetadataMap>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return messageId == null ? undefined : snapshot.get(messageId);\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with `multitaskStrategy:\n * \"enqueue\"` while another run is in flight. The returned object is\n * stable per snapshot so consumers can pass `entries` straight into a\n * `<Fragment key={e.id}>` list without extra memoisation.\n *\n * Today the queue is maintained client-side; once the server starts\n * emitting a dedicated queue channel (roadmap A0.3) the controller\n * will mirror that state directly — the hook surface will not change.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: SubmissionQueueSnapshot<StateType>;\n readonly size: number;\n cancel(id: string): Promise<boolean>;\n clear(): Promise<void>;\n}\n\nexport function useSubmissionQueue<StateType extends object>(\n stream: StreamHandle<StateType>\n): UseSubmissionQueueReturn<StateType>;\nexport function useSubmissionQueue(stream: AnyStream): UseSubmissionQueueReturn;\nexport function useSubmissionQueue(\n stream: AnyStream\n): UseSubmissionQueueReturn {\n const controller = stream[STREAM_CONTROLLER];\n const store = controller.queueStore;\n const entries = useSyncExternalStore<SubmissionQueueSnapshot>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return useMemo<UseSubmissionQueueReturn>(\n () => ({\n entries,\n size: entries.length,\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\n }),\n [entries, controller]\n );\n}\n\nexport type { SubmissionQueueEntry, SubmissionQueueSnapshot };\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { UseStreamReturn } from "./use-stream.cjs";
2
2
  import { BaseMessage } from "@langchain/core/messages";
3
- import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, MessageMetadata, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, SubmissionQueueEntry, SubmissionQueueSnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
3
+ import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, InferToolCalls, MessageMetadata, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, SubmissionQueueEntry, SubmissionQueueSnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
4
4
 
5
5
  //#region src/selectors.d.ts
6
6
  /**
@@ -53,18 +53,17 @@ declare function useMessages(stream: AnyStream, target?: SelectorTarget): BaseMe
53
53
  * `stream.toolCalls`.
54
54
  *
55
55
  * The optional generic `T` can be passed to narrow the type of
56
- * `toolCall.args` on the returned array. Accepts either:
56
+ * assembled tool calls on the returned array. Accepts either:
57
57
  * - an agent brand (`typeof agent`) — union is derived from the
58
- * agent's declared tools;
58
+ * agent's declared tools via {@link InferToolCalls};
59
59
  * - an array of LangGraph tools (`typeof tools`) — union is derived
60
- * from `ToolCallFromTool<T[number]>`;
61
- * - any direct `DefaultToolCall` shape.
60
+ * from {@link InferToolCalls} (parallel to {@link ToolCallsFromTools}).
62
61
  *
63
62
  * When omitted, returns the plain `AssembledToolCall[]` union used by
64
63
  * the controller.
65
64
  */
66
65
  declare function useToolCalls(stream: AnyStream, target?: SelectorTarget): AssembledToolCall[];
67
- declare function useToolCalls(stream: AnyStream, target?: SelectorTarget): AssembledToolCall[];
66
+ declare function useToolCalls<T>(stream: AnyStream, target?: SelectorTarget): InferToolCalls<T>[];
68
67
  /**
69
68
  * Subscribe to a scoped `values` stream — most-recent state payload
70
69
  * for a namespace. Equivalent to reading `stream.values` at the root.
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.cts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;AAuCyB;;;;;;;;KAapB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;AAeF;;;;;;;;AAAA,KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;AAAA,KAiCC,SAAA,GAAY,eAAA;;;AAuBjB;;;;;;;;;;;;;;;AAmCA;;;;iBAnCgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,WAAA;;;;;;;;;;;AAoCH;;;;;;iBAJgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;AAAA,iBACa,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;;;;;;;;AAqCH;;;;;;;;;;;iBAAgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,SAAA;;;;AAWH;;;;;;;iBAAgB,SAAA,GAAA,CAAa,MAAA,EAAQ,SAAA,GAAY,cAAA,CAAe,CAAA;AAAA,iBAChD,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,CAAA;;;;;iBAuBa,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,CAAA;;;;;;;;;;;;;;;;;;AAJH;iBAiCgB,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;;iBAkBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,SAAA;AAAA,KAaS,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,KAAA;;;;;;;;;;;;;AAhEH;;;;;iBA+FgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,uBACC,eAAA;;;;;;;;;;AA9EH;;;UAoGiB,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAAA,SACjC,IAAA;EACT,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,KAAA,IAAS,OAAA;AAAA;AAAA,iBAGK,kBAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,wBAAA,CAAyB,SAAA;AAAA,iBACZ,kBAAA,CAAmB,MAAA,EAAQ,SAAA,GAAY,wBAAA"}
1
+ {"version":3,"file":"selectors.d.cts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;AAwCyB;;;;;;;;KAapB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;AAeF;;;;;;;;AAAA,KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;AAAA,KAiCC,SAAA,GAAY,eAAA;;;AAuBjB;;;;;;;;;;;;;;;AAiCA;;;;iBAjCgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,WAAA;;;;;;;;;;;AAkCH;;;;;iBAJgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;AAAA,iBACa,YAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,cAAA,CAAe,CAAA;;;;;;;;;;;;AAqClB;;;;;;;iBAAgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,SAAA;;;;;;;;AAWH;;;iBAAgB,SAAA,GAAA,CAAa,MAAA,EAAQ,SAAA,GAAY,cAAA,CAAe,CAAA;AAAA,iBAChD,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,CAAA;;;;;iBAuBa,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,CAAA;;;;AA/BH;;;;;;;;;;;;;;;iBA4DgB,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;AApCH;;iBAqDgB,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;;iBAkBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,SAAA;AAAA,KAaS,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,KAAA;;AApFH;;;;;;;;;;;;;;;AAoBA;iBA+FgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,uBACC,eAAA;;;;;;;;;;;;;UAsBc,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAAA,SACjC,IAAA;EACT,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,KAAA,IAAS,OAAA;AAAA;AAAA,iBAGK,kBAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,wBAAA,CAAyB,SAAA;AAAA,iBACZ,kBAAA,CAAmB,MAAA,EAAQ,SAAA,GAAY,wBAAA"}
@@ -1,5 +1,5 @@
1
1
  import { UseStreamReturn } from "./use-stream.js";
2
- import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, MessageMetadata, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, SubmissionQueueEntry, SubmissionQueueSnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
2
+ import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, InferToolCalls, MessageMetadata, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, SubmissionQueueEntry, SubmissionQueueSnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
3
3
  import { BaseMessage } from "@langchain/core/messages";
4
4
 
5
5
  //#region src/selectors.d.ts
@@ -53,18 +53,17 @@ declare function useMessages(stream: AnyStream, target?: SelectorTarget): BaseMe
53
53
  * `stream.toolCalls`.
54
54
  *
55
55
  * The optional generic `T` can be passed to narrow the type of
56
- * `toolCall.args` on the returned array. Accepts either:
56
+ * assembled tool calls on the returned array. Accepts either:
57
57
  * - an agent brand (`typeof agent`) — union is derived from the
58
- * agent's declared tools;
58
+ * agent's declared tools via {@link InferToolCalls};
59
59
  * - an array of LangGraph tools (`typeof tools`) — union is derived
60
- * from `ToolCallFromTool<T[number]>`;
61
- * - any direct `DefaultToolCall` shape.
60
+ * from {@link InferToolCalls} (parallel to {@link ToolCallsFromTools}).
62
61
  *
63
62
  * When omitted, returns the plain `AssembledToolCall[]` union used by
64
63
  * the controller.
65
64
  */
66
65
  declare function useToolCalls(stream: AnyStream, target?: SelectorTarget): AssembledToolCall[];
67
- declare function useToolCalls(stream: AnyStream, target?: SelectorTarget): AssembledToolCall[];
66
+ declare function useToolCalls<T>(stream: AnyStream, target?: SelectorTarget): InferToolCalls<T>[];
68
67
  /**
69
68
  * Subscribe to a scoped `values` stream — most-recent state payload
70
69
  * for a namespace. Equivalent to reading `stream.values` at the root.
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.ts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;AAuCyB;;;;;;;;KAapB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;AAeF;;;;;;;;AAAA,KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;AAAA,KAiCC,SAAA,GAAY,eAAA;;;AAuBjB;;;;;;;;;;;;;;;AAmCA;;;;iBAnCgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,WAAA;;;;;;;;;;;AAoCH;;;;;;iBAJgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;AAAA,iBACa,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;;;;;;;;AAqCH;;;;;;;;;;;iBAAgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,SAAA;;;;AAWH;;;;;;;iBAAgB,SAAA,GAAA,CAAa,MAAA,EAAQ,SAAA,GAAY,cAAA,CAAe,CAAA;AAAA,iBAChD,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,CAAA;;;;;iBAuBa,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,CAAA;;;;;;;;;;;;;;;;;;AAJH;iBAiCgB,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;;iBAkBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,SAAA;AAAA,KAaS,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,KAAA;;;;;;;;;;;;;AAhEH;;;;;iBA+FgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,uBACC,eAAA;;;;;;;;;;AA9EH;;;UAoGiB,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAAA,SACjC,IAAA;EACT,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,KAAA,IAAS,OAAA;AAAA;AAAA,iBAGK,kBAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,wBAAA,CAAyB,SAAA;AAAA,iBACZ,kBAAA,CAAmB,MAAA,EAAQ,SAAA,GAAY,wBAAA"}
1
+ {"version":3,"file":"selectors.d.ts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;AAwCyB;;;;;;;;KAapB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;AAeF;;;;;;;;AAAA,KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;AAAA,KAiCC,SAAA,GAAY,eAAA;;;AAuBjB;;;;;;;;;;;;;;;AAiCA;;;;iBAjCgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,WAAA;;;;;;;;;;;AAkCH;;;;;iBAJgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;AAAA,iBACa,YAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,cAAA,CAAe,CAAA;;;;;;;;;;;;AAqClB;;;;;;;iBAAgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,SAAA;;;;;;;;AAWH;;;iBAAgB,SAAA,GAAA,CAAa,MAAA,EAAQ,SAAA,GAAY,cAAA,CAAe,CAAA;AAAA,iBAChD,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,CAAA;;;;;iBAuBa,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,CAAA;;;;AA/BH;;;;;;;;;;;;;;;iBA4DgB,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;AApCH;;iBAqDgB,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;;iBAkBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,SAAA;AAAA,KAaS,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,KAAA;;AApFH;;;;;;;;;;;;;;;AAoBA;iBA+FgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,uBACC,eAAA;;;;;;;;;;;;;UAsBc,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAAA,SACjC,IAAA;EACT,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,KAAA,IAAS,OAAA;AAAA;AAAA,iBAGK,kBAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,wBAAA,CAAyB,SAAA;AAAA,iBACZ,kBAAA,CAAmB,MAAA,EAAQ,SAAA,GAAY,wBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.js","names":[],"sources":["../src/selectors.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useMemo, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n MessageMetadata,\n MessageMetadataMap,\n SubmissionQueueEntry,\n SubmissionQueueSnapshot,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector hooks don't need to carry `InterruptType` /\n * `ConfigurableType` — they only ever read state. Accepting a\n * `StateType`-parameterised stream (with the other two generics\n * widened to `any`) lets callers keep their full\n * `useStream<State, Interrupt, Configurable>()` handle\n * without re-declaring the interrupt / configurable shapes at every\n * selector call site.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector hook can be targeted at. Callers can pass any of:\n * - `undefined` — root namespace (cheap: served by the always-on root store)\n * - a {@link SubagentDiscoverySnapshot} — the snapshot returned by `stream.subagents.get(...)`\n * - a {@link SubgraphDiscoverySnapshot} — the snapshot returned by `stream.subgraphs.get(...)`\n * - an explicit `{ namespace: string[] }` — any other namespaced scope\n * - a raw `string[]` — escape hatch identical to the object form\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target;\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n// The stream type we accept for selectors — purposely loose so\n// selector hooks remain callable from components that don't carry\n// the exact State/Interrupt/Configurable generics. We use `any` for\n// all three generics because `UseStreamReturn` is\n// invariant in `State` and `Configurable` (they flow through both\n// reader and writer positions), so a concrete\n// `useStream<typeof agent>()` handle wouldn't flow into\n// a `<object, unknown, object>` slot otherwise.\n//\n// Typed selectors (`useValues<S>` etc.) use {@link StreamHandle}\n// above so the concrete `StateType` flows into the return; hooks\n// that don't depend on state (`useMessages`, `useAudio`, …) stay on\n// `AnyStream` for maximum flexibility.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Subscribe to a scoped `messages` stream. Pass `stream` and\n * optionally a subagent/subgraph snapshot (or any namespaced target).\n *\n * Contract:\n * - At the root (no target) this returns `stream.messages` directly\n * — no extra subscription is opened. `stream.messages` is the\n * live merge of `messages`-channel token deltas and\n * `values.messages` snapshots (see\n * {@link UseStreamReturn.messages}), so token-by-token\n * streaming here depends on the backend emitting `messages`\n * channel events. Backends that only emit `values` updates will\n * render full turns at once rather than streaming.\n * - For any other namespace, the mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. Unmounting\n * the last component that watches this namespace closes the\n * subscription automatically.\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: SelectorTarget\n): BaseMessage[] {\n const namespace = resolveNamespace(target);\n const key = `messages|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace),\n key,\n EMPTY_MESSAGES\n );\n return isRoot(namespace) ? stream.messages : scoped;\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link useMessages}; at the root this just returns\n * `stream.toolCalls`.\n *\n * The optional generic `T` can be passed to narrow the type of\n * `toolCall.args` on the returned array. Accepts either:\n * - an agent brand (`typeof agent`) — union is derived from the\n * agent's declared tools;\n * - an array of LangGraph tools (`typeof tools`) — union is derived\n * from `ToolCallFromTool<T[number]>`;\n * - any direct `DefaultToolCall` shape.\n *\n * When omitted, returns the plain `AssembledToolCall[]` union used by\n * the controller.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[] {\n const namespace = resolveNamespace(target);\n const key = `toolCalls|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace),\n key,\n EMPTY_TOOLCALLS\n );\n return isRoot(namespace) ? stream.toolCalls : scoped;\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — most-recent state payload\n * for a namespace. Equivalent to reading `stream.values` at the root.\n *\n * When the payload carries a `messages` array, it is coerced to\n * `BaseMessage` instances to keep parity with the root projection.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on the parent `useStream<State>()` — no explicit\n * generic required. Non-nullable because the root snapshot always\n * carries `values` (falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): the scoped payload can\n * have a different shape than the root state (e.g. a subagent\n * returning its own substate). Callers should annotate the\n * expected shape explicitly: `useValues<SubagentState>(stream, sub)`.\n * Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): StateType;\n/**\n * Explicit-generic override. Accepts:\n * - an agent brand or compiled graph (unwrapped via\n * {@link InferStateType});\n * - a plain state shape (returned as-is).\n *\n * The root-call form is non-nullable (the root snapshot is always\n * present); the scoped form returns `T | undefined` because a\n * projection may not have emitted a payload yet.\n */\nexport function useValues<T>(stream: AnyStream): InferStateType<T>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): T | undefined;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): unknown {\n const namespace = resolveNamespace(target);\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\n return isRoot(namespace) ? stream.values : scoped;\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — most-recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function useExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget\n): T | undefined {\n const namespace = resolveNamespace(target);\n const key = `extension|${name}|${namespaceKey(namespace)}`;\n return useProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}\n * for the common cases.\n */\n/**\n * Subscribe to a scoped audio-media stream. Returns an array of\n * {@link AudioMedia} handles, one per message containing at least one\n * `AudioBlock` in the target namespace.\n *\n * Each handle is yielded on its first matching `content-block-start`,\n * exposes `.partialBytes` for live access, settles `.blob` /\n * `.objectURL` / `.transcript` on `message-finish`, and surfaces\n * fail-loud errors via `.error`.\n *\n * Pair with {@link useMediaURL} to turn a handle into an `<audio src>`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): AudioMedia[] {\n const namespace = resolveNamespace(target);\n const key = `audio|${namespaceKey(namespace)}`;\n return useProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): ImageMedia[] {\n const namespace = resolveNamespace(target);\n const key = `images|${namespaceKey(namespace)}`;\n return useProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): VideoMedia[] {\n const namespace = resolveNamespace(target);\n const key = `video|${namespaceKey(namespace)}`;\n return useProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for an\n * `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): FileMedia[] {\n const namespace = resolveNamespace(target);\n const key = `files|${namespaceKey(namespace)}`;\n return useProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Event[] {\n const namespace = resolveNamespace(target);\n const channelKey = useMemo(() => [...channels].sort().join(\",\"), [channels]);\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${channelKey}|${namespaceKey(namespace)}`;\n return useProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace, options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Read metadata recorded for a specific message id — today exposes\n * `parentCheckpointId`, the checkpoint the message was first seen on.\n * Designed for fork / edit flows:\n *\n * ```tsx\n * const { parentCheckpointId } = useMessageMetadata(stream, msg.id) ?? {};\n * if (parentCheckpointId) {\n * await stream.submit(input, { forkFrom: { checkpointId: parentCheckpointId } });\n * }\n * ```\n *\n * Returns `undefined` when the id isn't known yet (e.g. the server\n * hasn't emitted `parent_checkpoint` for that message, or the message\n * arrived via `messages`-channel deltas only and no `values` snapshot\n * has landed for it yet).\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: string | undefined\n): MessageMetadata | undefined {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const snapshot = useSyncExternalStore<MessageMetadataMap>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return messageId == null ? undefined : snapshot.get(messageId);\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with `multitaskStrategy:\n * \"enqueue\"` while another run is in flight. The returned object is\n * stable per snapshot so consumers can pass `entries` straight into a\n * `<Fragment key={e.id}>` list without extra memoisation.\n *\n * Today the queue is maintained client-side; once the server starts\n * emitting a dedicated queue channel (roadmap A0.3) the controller\n * will mirror that state directly — the hook surface will not change.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: SubmissionQueueSnapshot<StateType>;\n readonly size: number;\n cancel(id: string): Promise<boolean>;\n clear(): Promise<void>;\n}\n\nexport function useSubmissionQueue<StateType extends object>(\n stream: StreamHandle<StateType>\n): UseSubmissionQueueReturn<StateType>;\nexport function useSubmissionQueue(stream: AnyStream): UseSubmissionQueueReturn;\nexport function useSubmissionQueue(\n stream: AnyStream\n): UseSubmissionQueueReturn {\n const controller = stream[STREAM_CONTROLLER];\n const store = controller.queueStore;\n const entries = useSyncExternalStore<SubmissionQueueSnapshot>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return useMemo<UseSubmissionQueueReturn>(\n () => ({\n entries,\n size: entries.length,\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\n }),\n [entries, controller]\n );\n}\n\nexport type { SubmissionQueueEntry, SubmissionQueueSnapshot };\n"],"mappings":"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"}
1
+ {"version":3,"file":"selectors.js","names":[],"sources":["../src/selectors.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useMemo, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n MessageMetadata,\n MessageMetadataMap,\n SubmissionQueueEntry,\n SubmissionQueueSnapshot,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector hooks don't need to carry `InterruptType` /\n * `ConfigurableType` — they only ever read state. Accepting a\n * `StateType`-parameterised stream (with the other two generics\n * widened to `any`) lets callers keep their full\n * `useStream<State, Interrupt, Configurable>()` handle\n * without re-declaring the interrupt / configurable shapes at every\n * selector call site.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector hook can be targeted at. Callers can pass any of:\n * - `undefined` — root namespace (cheap: served by the always-on root store)\n * - a {@link SubagentDiscoverySnapshot} — the snapshot returned by `stream.subagents.get(...)`\n * - a {@link SubgraphDiscoverySnapshot} — the snapshot returned by `stream.subgraphs.get(...)`\n * - an explicit `{ namespace: string[] }` — any other namespaced scope\n * - a raw `string[]` — escape hatch identical to the object form\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target;\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n// The stream type we accept for selectors — purposely loose so\n// selector hooks remain callable from components that don't carry\n// the exact State/Interrupt/Configurable generics. We use `any` for\n// all three generics because `UseStreamReturn` is\n// invariant in `State` and `Configurable` (they flow through both\n// reader and writer positions), so a concrete\n// `useStream<typeof agent>()` handle wouldn't flow into\n// a `<object, unknown, object>` slot otherwise.\n//\n// Typed selectors (`useValues<S>` etc.) use {@link StreamHandle}\n// above so the concrete `StateType` flows into the return; hooks\n// that don't depend on state (`useMessages`, `useAudio`, …) stay on\n// `AnyStream` for maximum flexibility.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Subscribe to a scoped `messages` stream. Pass `stream` and\n * optionally a subagent/subgraph snapshot (or any namespaced target).\n *\n * Contract:\n * - At the root (no target) this returns `stream.messages` directly\n * — no extra subscription is opened. `stream.messages` is the\n * live merge of `messages`-channel token deltas and\n * `values.messages` snapshots (see\n * {@link UseStreamReturn.messages}), so token-by-token\n * streaming here depends on the backend emitting `messages`\n * channel events. Backends that only emit `values` updates will\n * render full turns at once rather than streaming.\n * - For any other namespace, the mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. Unmounting\n * the last component that watches this namespace closes the\n * subscription automatically.\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: SelectorTarget\n): BaseMessage[] {\n const namespace = resolveNamespace(target);\n const key = `messages|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace),\n key,\n EMPTY_MESSAGES\n );\n return isRoot(namespace) ? stream.messages : scoped;\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link useMessages}; at the root this just returns\n * `stream.toolCalls`.\n *\n * The optional generic `T` can be passed to narrow the type of\n * assembled tool calls on the returned array. Accepts either:\n * - an agent brand (`typeof agent`) — union is derived from the\n * agent's declared tools via {@link InferToolCalls};\n * - an array of LangGraph tools (`typeof tools`) — union is derived\n * from {@link InferToolCalls} (parallel to {@link ToolCallsFromTools}).\n *\n * When omitted, returns the plain `AssembledToolCall[]` union used by\n * the controller.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget\n): InferToolCalls<T>[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[] {\n const namespace = resolveNamespace(target);\n const key = `toolCalls|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace),\n key,\n EMPTY_TOOLCALLS\n );\n return isRoot(namespace) ? stream.toolCalls : scoped;\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — most-recent state payload\n * for a namespace. Equivalent to reading `stream.values` at the root.\n *\n * When the payload carries a `messages` array, it is coerced to\n * `BaseMessage` instances to keep parity with the root projection.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on the parent `useStream<State>()` — no explicit\n * generic required. Non-nullable because the root snapshot always\n * carries `values` (falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): the scoped payload can\n * have a different shape than the root state (e.g. a subagent\n * returning its own substate). Callers should annotate the\n * expected shape explicitly: `useValues<SubagentState>(stream, sub)`.\n * Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): StateType;\n/**\n * Explicit-generic override. Accepts:\n * - an agent brand or compiled graph (unwrapped via\n * {@link InferStateType});\n * - a plain state shape (returned as-is).\n *\n * The root-call form is non-nullable (the root snapshot is always\n * present); the scoped form returns `T | undefined` because a\n * projection may not have emitted a payload yet.\n */\nexport function useValues<T>(stream: AnyStream): InferStateType<T>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): T | undefined;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): unknown {\n const namespace = resolveNamespace(target);\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\n return isRoot(namespace) ? stream.values : scoped;\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — most-recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function useExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget\n): T | undefined {\n const namespace = resolveNamespace(target);\n const key = `extension|${name}|${namespaceKey(namespace)}`;\n return useProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}\n * for the common cases.\n */\n/**\n * Subscribe to a scoped audio-media stream. Returns an array of\n * {@link AudioMedia} handles, one per message containing at least one\n * `AudioBlock` in the target namespace.\n *\n * Each handle is yielded on its first matching `content-block-start`,\n * exposes `.partialBytes` for live access, settles `.blob` /\n * `.objectURL` / `.transcript` on `message-finish`, and surfaces\n * fail-loud errors via `.error`.\n *\n * Pair with {@link useMediaURL} to turn a handle into an `<audio src>`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): AudioMedia[] {\n const namespace = resolveNamespace(target);\n const key = `audio|${namespaceKey(namespace)}`;\n return useProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): ImageMedia[] {\n const namespace = resolveNamespace(target);\n const key = `images|${namespaceKey(namespace)}`;\n return useProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): VideoMedia[] {\n const namespace = resolveNamespace(target);\n const key = `video|${namespaceKey(namespace)}`;\n return useProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for an\n * `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): FileMedia[] {\n const namespace = resolveNamespace(target);\n const key = `files|${namespaceKey(namespace)}`;\n return useProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Event[] {\n const namespace = resolveNamespace(target);\n const channelKey = useMemo(() => [...channels].sort().join(\",\"), [channels]);\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${channelKey}|${namespaceKey(namespace)}`;\n return useProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace, options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Read metadata recorded for a specific message id — today exposes\n * `parentCheckpointId`, the checkpoint the message was first seen on.\n * Designed for fork / edit flows:\n *\n * ```tsx\n * const { parentCheckpointId } = useMessageMetadata(stream, msg.id) ?? {};\n * if (parentCheckpointId) {\n * await stream.submit(input, { forkFrom: { checkpointId: parentCheckpointId } });\n * }\n * ```\n *\n * Returns `undefined` when the id isn't known yet (e.g. the server\n * hasn't emitted `parent_checkpoint` for that message, or the message\n * arrived via `messages`-channel deltas only and no `values` snapshot\n * has landed for it yet).\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: string | undefined\n): MessageMetadata | undefined {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const snapshot = useSyncExternalStore<MessageMetadataMap>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return messageId == null ? undefined : snapshot.get(messageId);\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with `multitaskStrategy:\n * \"enqueue\"` while another run is in flight. The returned object is\n * stable per snapshot so consumers can pass `entries` straight into a\n * `<Fragment key={e.id}>` list without extra memoisation.\n *\n * Today the queue is maintained client-side; once the server starts\n * emitting a dedicated queue channel (roadmap A0.3) the controller\n * will mirror that state directly — the hook surface will not change.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: SubmissionQueueSnapshot<StateType>;\n readonly size: number;\n cancel(id: string): Promise<boolean>;\n clear(): Promise<void>;\n}\n\nexport function useSubmissionQueue<StateType extends object>(\n stream: StreamHandle<StateType>\n): UseSubmissionQueueReturn<StateType>;\nexport function useSubmissionQueue(stream: AnyStream): UseSubmissionQueueReturn;\nexport function useSubmissionQueue(\n stream: AnyStream\n): UseSubmissionQueueReturn {\n const controller = stream[STREAM_CONTROLLER];\n const store = controller.queueStore;\n const entries = useSyncExternalStore<SubmissionQueueSnapshot>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return useMemo<UseSubmissionQueueReturn>(\n () => ({\n entries,\n size: entries.length,\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\n }),\n [entries, controller]\n );\n}\n\nexport type { SubmissionQueueEntry, SubmissionQueueSnapshot };\n"],"mappings":"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"}
@@ -72,6 +72,7 @@ function useStream(options) {
72
72
  webSocketFactory: hasCustomAdapter ? void 0 : asBag.webSocketFactory,
73
73
  onThreadId: options.onThreadId,
74
74
  onCreated: options.onCreated,
75
+ onCompleted: options.onCompleted,
75
76
  initialValues: options.initialValues,
76
77
  messagesKey: options.messagesKey
77
78
  }), [
@@ -1 +1 @@
1
- {"version":3,"file":"use-stream.cjs","names":["ClientCtor","StreamController"],"sources":["../src/use-stream.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n} from \"@langchain/langgraph-sdk\";\nimport {\n Client as ClientCtor,\n type ClientConfig,\n type ThreadStream,\n} from \"@langchain/langgraph-sdk/client\";\nimport {\n StreamController,\n type AgentServerAdapter,\n type AgentServerOptions as StreamAgentServerOptions,\n type AssembledToolCall,\n type ChannelRegistry,\n type CustomAdapterOptions as StreamCustomAdapterOptions,\n type InferStateType,\n type InferSubagentStates,\n type RootSnapshot,\n type StreamSubmitOptions,\n type SubagentDiscoverySnapshot,\n type SubagentMap,\n type SubgraphByNodeMap,\n type SubgraphDiscoverySnapshot,\n type SubgraphMap,\n type UseStreamOptions as StreamUseStreamOptions,\n type WidenUpdateMessages,\n} from \"@langchain/langgraph-sdk/stream\";\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<StateType>;\n\n/**\n * Private field on the hook return that carries the\n * {@link StreamController} reference. Selector hooks (`useMessages`,\n * `useToolCalls`, …) read this to reach the shared\n * {@link ChannelRegistry}. Typed as a symbol-keyed field to discourage\n * end-user access — use the selector hooks instead.\n *\n * Exported as a unique symbol so type narrowing works across\n * `useMessages(stream, target)` call sites.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/react/controller\"\n);\n\nexport interface UseStreamReturn<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n StateType extends object = InferStateType<T>,\n SubagentStates = InferSubagentStates<T>,\n> {\n // ----- always-on root projections -----\n /**\n * The most recent `values`-channel snapshot emitted at the root\n * namespace — i.e. the thread-level state as the server sees it\n * after each superstep. Updated on every root `values` event, not\n * on token-level deltas: if you render `values.messages` directly\n * you'll see full turns appear at once instead of streaming\n * token-by-token. Use {@link messages} (or `useMessages`) for the\n * token-streamed view.\n *\n * Equivalent to calling `useValues(stream)`.\n */\n readonly values: StateType;\n /**\n * Type-only: the resolved state shape. Exposed so consumers can\n * derive companion hook argument types (`useValues<typeof stream>`)\n * without plumbing `T` through their component hierarchy.\n *\n * @internal\n */\n readonly \"~stateType\"?: StateType;\n /**\n * The root message projection. Assembled from two sources and\n * merged in real time:\n *\n * 1. `messages`-channel deltas — token-level streaming events\n * (`message-start`, `content-block-delta`, `message-finish`)\n * emitted by the runtime. These drive live, token-by-token\n * updates.\n * 2. `values.messages` snapshots — the authoritative ordering\n * and any messages the agent produces without token streaming\n * (human turns, tool results, echoes from subagents).\n *\n * If the backend only emits `values` events (no `messages`\n * channel), every message will appear fully-formed on each\n * values update rather than streaming. This is a backend/runtime\n * concern — the React layer faithfully renders whatever the\n * server sends.\n *\n * Equivalent to calling `useMessages(stream)` with no target.\n */\n readonly messages: BaseMessage[];\n readonly toolCalls: AssembledToolCall[];\n readonly interrupts: Interrupt<InterruptType>[];\n readonly interrupt: Interrupt<InterruptType> | undefined;\n readonly isLoading: boolean;\n readonly isThreadLoading: boolean;\n /**\n * Promise that settles when the current thread's initial hydration\n * completes. Exposed so Suspense wrappers can `throw` it until the\n * first {@link StreamController.hydrate} call resolves (or rejects)\n * for the active thread. A fresh promise is installed on every\n * `switchThread`/`threadId` change.\n */\n readonly hydrationPromise: Promise<void>;\n readonly error: unknown;\n readonly threadId: string | null;\n\n // ----- always-on discovery -----\n /**\n * Subagents discovered on the root run. For DeepAgent-typed\n * streams the key set is narrowed to the subagent names declared\n * on the agent brand (`keyof InferSubagentStates<T>`).\n */\n readonly subagents: ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >;\n /**\n * Subgraphs discovered on the root run.\n *\n * A namespace is classified as a subgraph iff at least one\n * strictly-deeper namespace has been observed with it as a prefix.\n * This is inferred from the lifecycle event stream — plain function\n * nodes (`orchestrator`, `writer` in the nested-stategraph example)\n * never appear here even though the server emits namespaced\n * lifecycle events for them. Promotion is monotonic and retroactive;\n * an entry appears as soon as the first descendant event lands.\n */\n readonly subgraphs: ReadonlyMap<string, SubgraphDiscoverySnapshot>;\n /**\n * Subgraphs indexed by the graph node that produced them\n * (`addNode(\"visualizer_0\", …)`). Each value is an array because\n * parallel fan-outs and loops can spawn multiple invocations of\n * the same node; arrays preserve insertion order. Updates in\n * lock-step with {@link subgraphs}.\n */\n readonly subgraphsByNode: ReadonlyMap<\n string,\n readonly SubgraphDiscoverySnapshot[]\n >;\n\n // ----- imperatives -----\n /**\n * Dispatch a new run on the bound thread.\n *\n * `input` is typed as `Partial<StateType>` so IDE autocompletion\n * surfaces the state keys declared on the root hook. Pass `null`\n * (or omit fields) when resuming an interrupt via `options.command.resume`\n * — the server accepts a null payload in that case.\n */\n submit(\n input: WidenUpdateMessages<Partial<StateType>> | null | undefined,\n options?: StreamSubmitOptions<StateType, ConfigurableType>\n ): Promise<void>;\n stop(): Promise<void>;\n respond(\n response: unknown,\n target?: { interruptId: string; namespace?: string[] }\n ): Promise<void>;\n\n // ----- identity -----\n readonly client: Client;\n readonly assistantId: string;\n\n /** v2 escape hatch — returns the bound {@link ThreadStream}. */\n getThread(): ThreadStream | undefined;\n\n /** @internal Used by selector hooks (`useMessages`, `useToolCalls`, …). */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased stream handle useful as a parameter type for helpers and\n * wrapper components that pass a `stream` through to selector hooks\n * (`useMessages`, `useChannel`, …) without reading `values` directly.\n * Any fully-typed `UseStreamReturn<S, I, C>` is\n * assignable to `AnyStream` because the generic slots are `any`\n * (bivariant), which avoids the `CompiledStateGraph` → `Record<string,\n * unknown>` assignment friction you hit when using the bare\n * `UseStreamReturn` default.\n *\n * @example\n * ```tsx\n * function SubgraphCard({ stream, subgraph }: {\n * stream: AnyStream;\n * subgraph: SubgraphDiscoverySnapshot;\n * }) {\n * const messages = useMessages(stream, subgraph);\n * return <Feed messages={messages} />;\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * React binding for the v2-native stream runtime.\n *\n * `useStream` exposes three always-on projections\n * (`values` / `messages` / `toolCalls`) at the thread root plus\n * cheap discovery maps for subagents / subgraphs. Scoped views of\n * subagents, subgraphs, or any namespaced projection are surfaced via\n * the companion selector hooks:\n *\n * ```tsx\n * const stream = useStream({ assistantId: \"deep-agent\" });\n *\n * // Root messages — always on, already class instances.\n * stream.messages.map((m) => <Bubble key={m.id} msg={m} />);\n *\n * // Subagent view — mount = subscribe, unmount = unsubscribe.\n * function SubagentCard({ subagent }) {\n * const messages = useMessages(stream, subagent);\n * const toolCalls = useToolCalls(stream, subagent);\n * return <>{messages.map(...)}</>;\n * }\n * ```\n *\n * The first generic accepts either a plain state type\n * (`useStream<MyState>()`) *or* a compiled graph type\n * (`useStream<typeof agent>()`); in the latter case the\n * state shape is unwrapped from the graph via {@link InferStateType}, so\n * `stream.values` is always typed as the state, never as the graph\n * class itself.\n */\nexport function useStream<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n>(\n options: UseStreamOptions<InferStateType<T>>\n): UseStreamReturn<T, InterruptType, ConfigurableType> {\n type StateType = InferStateType<T>;\n // Branch-stable narrowings for each code path. The custom-adapter\n // branch can skip LGP client construction entirely, which keeps\n // bundles that *only* use a custom adapter free of the default\n // `sse`/`websocket` transport factories (tree-shaken).\n // Treat the options as a flat bag here — the discriminated union\n // exists to give call sites a nice error message, but at runtime\n // both branches are reachable through the same set of fields.\n interface OptionsBag {\n assistantId?: string;\n threadId?: string | null;\n client?: Client;\n apiUrl?: string;\n apiKey?: string;\n callerOptions?: ClientConfig[\"callerOptions\"];\n defaultHeaders?: ClientConfig[\"defaultHeaders\"];\n transport?: \"sse\" | \"websocket\" | AgentServerAdapter;\n fetch?: typeof fetch;\n webSocketFactory?: (url: string) => WebSocket;\n onThreadId?: (threadId: string) => void;\n onCreated?: (meta: { run_id: string; thread_id: string }) => void;\n initialValues?: StateType;\n messagesKey?: string;\n }\n const asBag = options as OptionsBag;\n // Narrow once: a non-string `transport` is a custom adapter; anything\n // else (`\"sse\"` / `\"websocket\"` / `undefined`) is a built-in.\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n const client = useMemo<Client>(\n () =>\n asBag.client ??\n (new ClientCtor({\n apiUrl: asBag.apiUrl,\n apiKey: asBag.apiKey,\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client),\n [\n asBag.client,\n asBag.apiUrl,\n asBag.apiKey,\n asBag.callerOptions,\n asBag.defaultHeaders,\n ]\n );\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n // `\"_\"` is the well-known sentinel for \"adapter doesn't care\".\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n // Recreate the controller only on assistantId / client / transport\n // change; the ThreadStream is bound to one assistant for its\n // lifetime and we want selector-hook subscriptions to stay stable\n // across renders.\n const controller = useMemo(\n () =>\n new StreamController<StateType, InterruptType, ConfigurableType>({\n assistantId,\n // Cast: the runtime `Client` is state-shape agnostic, but the\n // controller declares `client: Client<StateType>` so its own\n // typings line up. Tightening `submit`'s `input` parameter to\n // `Partial<StateType>` surfaced this variance mismatch that\n // was previously masked — the cast is equivalent to the\n // ClientCtor cast above.\n client: client as unknown as Client<StateType>,\n threadId: options.threadId ?? null,\n transport,\n fetch: hasCustomAdapter ? undefined : asBag.fetch,\n webSocketFactory: hasCustomAdapter ? undefined : asBag.webSocketFactory,\n onThreadId: options.onThreadId,\n onCreated: options.onCreated,\n initialValues: options.initialValues,\n messagesKey: options.messagesKey,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, assistantId, transport]\n );\n\n // Rehydrate on threadId change. The initial hydrate is fired\n // synchronously inside the controller constructor so Suspense\n // callers don't deadlock waiting for an effect that never runs\n // (throwing `hydrationPromise` during render unmounts the subtree\n // before effects fire). We only re-hydrate here when the threadId\n // prop changes after the controller was already constructed with a\n // matching id.\n const lastHydratedRef = useRef<{\n controller: StreamController<StateType, InterruptType, ConfigurableType>;\n threadId: string | null;\n } | null>(null);\n useEffect(() => {\n const target = options.threadId ?? null;\n const last = lastHydratedRef.current;\n if (last?.controller !== controller) {\n // Freshly constructed controller already seeded the hydrate in\n // its constructor — record the id and skip the redundant call.\n lastHydratedRef.current = { controller, threadId: target };\n return;\n }\n if (last.threadId === target) return;\n lastHydratedRef.current = { controller, threadId: target };\n void controller.hydrate(target);\n }, [controller, options.threadId]);\n\n // Dispose on unmount / controller swap.\n //\n // We use `controller.activate()` instead of a naive\n // `() => controller.dispose()` cleanup because React 18+\n // `<StrictMode>` in dev mounts → unmounts → remounts components\n // synchronously to surface cleanup bugs. A naive cleanup would\n // permanently tear the controller down on that first synthetic\n // unmount and turn every subsequent `submit()` into a silent\n // no-op. `activate()` defers disposal to the next microtask and\n // cancels it if the effect re-runs — which is exactly the\n // StrictMode remount pattern.\n useEffect(() => controller.activate(), [controller]);\n\n // Headless-tool handling: if the caller supplied `tools`, watch the\n // root `values.__interrupt__` channel for protocol interrupts that\n // target a registered tool, invoke the handler, and auto-resume the\n // run. Ref-tracks the ids we've already handled so the same\n // interrupt on a subsequent render is never executed twice\n // (StrictMode safe).\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [options.threadId]);\n const tools = options.tools;\n const onTool = options.onTool;\n // Subscribe to values + interrupt updates via the root store so the\n // effect re-runs whenever a protocol interrupt lands or the\n // `__interrupt__` key is projected into values, not only on hook\n // re-render. We feed both sources to the flush helper because\n // v2-native runs surface protocol interrupts via\n // `rootStore.interrupts` (`input.requested` events), while legacy\n // graphs may still emit `values.__interrupt__`.\n const rootValuesForTools = useSyncExternalStore<StateType>(\n controller.rootStore.subscribe,\n () => controller.rootStore.getSnapshot().values,\n () => controller.rootStore.getSnapshot().values\n );\n const rootInterruptsForTools = useSyncExternalStore<\n readonly Interrupt<InterruptType>[]\n >(\n controller.rootStore.subscribe,\n () => controller.rootStore.getSnapshot().interrupts,\n () => controller.rootStore.getSnapshot().interrupts\n );\n useEffect(() => {\n if (!tools?.length) return;\n const valuesBag = rootValuesForTools as unknown as Record<string, unknown>;\n const existingInterrupts = Array.isArray(valuesBag?.__interrupt__)\n ? (valuesBag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existingInterrupts,\n ...(rootInterruptsForTools as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n flushPendingHeadlessToolInterrupts(\n { ...valuesBag, __interrupt__: combined },\n tools,\n handledToolsRef.current,\n {\n onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n controller.submit(null, {\n command,\n } as StreamSubmitOptions<StateType, ConfigurableType>),\n }\n );\n }, [controller, tools, onTool, rootValuesForTools, rootInterruptsForTools]);\n\n const root = useSyncExternalStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot,\n controller.rootStore.getSnapshot\n );\n const subagents = useSyncExternalStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot,\n controller.subagentStore.getSnapshot\n );\n const subgraphs = useSyncExternalStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot,\n controller.subgraphStore.getSnapshot\n );\n const subgraphsByNode = useSyncExternalStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n return useMemo<UseStreamReturn<T, InterruptType, ConfigurableType>>(() => {\n const userFacingInterrupts = filterOutHeadlessToolInterrupts(\n root.interrupts\n );\n return {\n values: root.values,\n messages: root.messages,\n toolCalls: root.toolCalls,\n interrupts: userFacingInterrupts,\n interrupt: userFacingInterrupts[0],\n isLoading: root.isLoading,\n isThreadLoading: root.isThreadLoading,\n hydrationPromise: controller.hydrationPromise,\n error: root.error,\n threadId: root.threadId,\n subagents: subagents as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs,\n subgraphsByNode,\n submit: (input, submitOptions) => controller.submit(input, submitOptions),\n stop: () => controller.stop(),\n respond: (response, target) => controller.respond(response, target),\n getThread: () => controller.getThread(),\n client,\n assistantId,\n [STREAM_CONTROLLER]: controller,\n } as UseStreamReturn<T, InterruptType, ConfigurableType>;\n }, [\n root,\n subagents,\n subgraphs,\n subgraphsByNode,\n controller,\n client,\n assistantId,\n ]);\n}\n\n/**\n * Convenience alias for the fully-resolved stream handle type.\n */\nexport type UseStreamResult<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * Helper used by the selector hooks to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `useMessages`, `useToolCalls`, etc.\n * instead of reading this directly.\n *\n * @internal\n */\nexport function getRegistry(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: UseStreamReturn<any, any, any>\n): ChannelRegistry {\n return stream[STREAM_CONTROLLER].registry;\n}\n\nexport type { ThreadStream };\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-stream.cjs","names":["ClientCtor","StreamController"],"sources":["../src/use-stream.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n} from \"@langchain/langgraph-sdk\";\nimport {\n Client as ClientCtor,\n type ClientConfig,\n type ThreadStream,\n} from \"@langchain/langgraph-sdk/client\";\nimport {\n StreamController,\n type AgentServerAdapter,\n type AgentServerOptions as StreamAgentServerOptions,\n type ChannelRegistry,\n type CustomAdapterOptions as StreamCustomAdapterOptions,\n type InferStateType,\n type InferSubagentStates,\n type InferToolCalls,\n type RootSnapshot,\n type RunCompletedInfo,\n type RunExecutionInfo,\n type StreamSubmitOptions,\n type SubagentDiscoverySnapshot,\n type SubagentMap,\n type SubgraphByNodeMap,\n type SubgraphDiscoverySnapshot,\n type SubgraphMap,\n type UseStreamOptions as StreamUseStreamOptions,\n type WidenUpdateMessages,\n} from \"@langchain/langgraph-sdk/stream\";\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<StateType>;\n\n/**\n * Private field on the hook return that carries the\n * {@link StreamController} reference. Selector hooks (`useMessages`,\n * `useToolCalls`, …) read this to reach the shared\n * {@link ChannelRegistry}. Typed as a symbol-keyed field to discourage\n * end-user access — use the selector hooks instead.\n *\n * Exported as a unique symbol so type narrowing works across\n * `useMessages(stream, target)` call sites.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/react/controller\"\n);\n\nexport interface UseStreamReturn<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n StateType extends object = InferStateType<T>,\n SubagentStates = InferSubagentStates<T>,\n> {\n // ----- always-on root projections -----\n /**\n * The most recent `values`-channel snapshot emitted at the root\n * namespace — i.e. the thread-level state as the server sees it\n * after each superstep. Updated on every root `values` event, not\n * on token-level deltas: if you render `values.messages` directly\n * you'll see full turns appear at once instead of streaming\n * token-by-token. Use {@link messages} (or `useMessages`) for the\n * token-streamed view.\n *\n * Equivalent to calling `useValues(stream)`.\n */\n readonly values: StateType;\n /**\n * Type-only: the resolved state shape. Exposed so consumers can\n * derive companion hook argument types (`useValues<typeof stream>`)\n * without plumbing `T` through their component hierarchy.\n *\n * @internal\n */\n readonly \"~stateType\"?: StateType;\n /**\n * The root message projection. Assembled from two sources and\n * merged in real time:\n *\n * 1. `messages`-channel deltas — token-level streaming events\n * (`message-start`, `content-block-delta`, `message-finish`)\n * emitted by the runtime. These drive live, token-by-token\n * updates.\n * 2. `values.messages` snapshots — the authoritative ordering\n * and any messages the agent produces without token streaming\n * (human turns, tool results, echoes from subagents).\n *\n * If the backend only emits `values` events (no `messages`\n * channel), every message will appear fully-formed on each\n * values update rather than streaming. This is a backend/runtime\n * concern — the React layer faithfully renders whatever the\n * server sends.\n *\n * Equivalent to calling `useMessages(stream)` with no target.\n */\n readonly messages: BaseMessage[];\n readonly toolCalls: InferToolCalls<T>[];\n readonly interrupts: Interrupt<InterruptType>[];\n readonly interrupt: Interrupt<InterruptType> | undefined;\n readonly isLoading: boolean;\n readonly isThreadLoading: boolean;\n /**\n * Promise that settles when the current thread's initial hydration\n * completes. Exposed so Suspense wrappers can `throw` it until the\n * first {@link StreamController.hydrate} call resolves (or rejects)\n * for the active thread. A fresh promise is installed on every\n * `switchThread`/`threadId` change.\n */\n readonly hydrationPromise: Promise<void>;\n readonly error: unknown;\n readonly threadId: string | null;\n\n // ----- always-on discovery -----\n /**\n * Subagents discovered on the root run. For DeepAgent-typed\n * streams the key set is narrowed to the subagent names declared\n * on the agent brand (`keyof InferSubagentStates<T>`).\n */\n readonly subagents: ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >;\n /**\n * Subgraphs discovered on the root run.\n *\n * A namespace is classified as a subgraph iff at least one\n * strictly-deeper namespace has been observed with it as a prefix.\n * This is inferred from the lifecycle event stream — plain function\n * nodes (`orchestrator`, `writer` in the nested-stategraph example)\n * never appear here even though the server emits namespaced\n * lifecycle events for them. Promotion is monotonic and retroactive;\n * an entry appears as soon as the first descendant event lands.\n */\n readonly subgraphs: ReadonlyMap<string, SubgraphDiscoverySnapshot>;\n /**\n * Subgraphs indexed by the graph node that produced them\n * (`addNode(\"visualizer_0\", …)`). Each value is an array because\n * parallel fan-outs and loops can spawn multiple invocations of\n * the same node; arrays preserve insertion order. Updates in\n * lock-step with {@link subgraphs}.\n */\n readonly subgraphsByNode: ReadonlyMap<\n string,\n readonly SubgraphDiscoverySnapshot[]\n >;\n\n // ----- imperatives -----\n /**\n * Dispatch a new run on the bound thread.\n *\n * `input` is typed as `Partial<StateType>` so IDE autocompletion\n * surfaces the state keys declared on the root hook. Pass `null`\n * (or omit fields) when resuming an interrupt via `options.command.resume`\n * — the server accepts a null payload in that case.\n */\n submit(\n input: WidenUpdateMessages<Partial<StateType>> | null | undefined,\n options?: StreamSubmitOptions<StateType, ConfigurableType>\n ): Promise<void>;\n stop(): Promise<void>;\n respond(\n response: unknown,\n target?: { interruptId: string; namespace?: string[] }\n ): Promise<void>;\n\n // ----- identity -----\n readonly client: Client;\n readonly assistantId: string;\n\n /** v2 escape hatch — returns the bound {@link ThreadStream}. */\n getThread(): ThreadStream | undefined;\n\n /** @internal Used by selector hooks (`useMessages`, `useToolCalls`, …). */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased stream handle useful as a parameter type for helpers and\n * wrapper components that pass a `stream` through to selector hooks\n * (`useMessages`, `useChannel`, …) without reading `values` directly.\n * Any fully-typed `UseStreamReturn<S, I, C>` is\n * assignable to `AnyStream` because the generic slots are `any`\n * (bivariant), which avoids the `CompiledStateGraph` → `Record<string,\n * unknown>` assignment friction you hit when using the bare\n * `UseStreamReturn` default.\n *\n * @example\n * ```tsx\n * function SubgraphCard({ stream, subgraph }: {\n * stream: AnyStream;\n * subgraph: SubgraphDiscoverySnapshot;\n * }) {\n * const messages = useMessages(stream, subgraph);\n * return <Feed messages={messages} />;\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * React binding for the v2-native stream runtime.\n *\n * `useStream` exposes three always-on projections\n * (`values` / `messages` / `toolCalls`) at the thread root plus\n * cheap discovery maps for subagents / subgraphs. Scoped views of\n * subagents, subgraphs, or any namespaced projection are surfaced via\n * the companion selector hooks:\n *\n * ```tsx\n * const stream = useStream({ assistantId: \"deep-agent\" });\n *\n * // Root messages — always on, already class instances.\n * stream.messages.map((m) => <Bubble key={m.id} msg={m} />);\n *\n * // Subagent view — mount = subscribe, unmount = unsubscribe.\n * function SubagentCard({ subagent }) {\n * const messages = useMessages(stream, subagent);\n * const toolCalls = useToolCalls(stream, subagent);\n * return <>{messages.map(...)}</>;\n * }\n * ```\n *\n * The first generic accepts either a plain state type\n * (`useStream<MyState>()`) *or* a compiled graph type\n * (`useStream<typeof agent>()`); in the latter case the\n * state shape is unwrapped from the graph via {@link InferStateType}, so\n * `stream.values` is always typed as the state, never as the graph\n * class itself.\n */\nexport function useStream<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n>(\n options: UseStreamOptions<InferStateType<T>>\n): UseStreamReturn<T, InterruptType, ConfigurableType> {\n type StateType = InferStateType<T>;\n // Branch-stable narrowings for each code path. The custom-adapter\n // branch can skip LGP client construction entirely, which keeps\n // bundles that *only* use a custom adapter free of the default\n // `sse`/`websocket` transport factories (tree-shaken).\n // Treat the options as a flat bag here — the discriminated union\n // exists to give call sites a nice error message, but at runtime\n // both branches are reachable through the same set of fields.\n interface OptionsBag {\n assistantId?: string;\n threadId?: string | null;\n client?: Client;\n apiUrl?: string;\n apiKey?: string;\n callerOptions?: ClientConfig[\"callerOptions\"];\n defaultHeaders?: ClientConfig[\"defaultHeaders\"];\n transport?: \"sse\" | \"websocket\" | AgentServerAdapter;\n fetch?: typeof fetch;\n webSocketFactory?: (url: string) => WebSocket;\n onThreadId?: (threadId: string) => void;\n onCreated?: (info: RunExecutionInfo) => void;\n onCompleted?: (info: RunCompletedInfo) => void;\n initialValues?: StateType;\n messagesKey?: string;\n }\n const asBag = options as OptionsBag;\n // Narrow once: a non-string `transport` is a custom adapter; anything\n // else (`\"sse\"` / `\"websocket\"` / `undefined`) is a built-in.\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n const client = useMemo<Client>(\n () =>\n asBag.client ??\n (new ClientCtor({\n apiUrl: asBag.apiUrl,\n apiKey: asBag.apiKey,\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client),\n [\n asBag.client,\n asBag.apiUrl,\n asBag.apiKey,\n asBag.callerOptions,\n asBag.defaultHeaders,\n ]\n );\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n // `\"_\"` is the well-known sentinel for \"adapter doesn't care\".\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n // Recreate the controller only on assistantId / client / transport\n // change; the ThreadStream is bound to one assistant for its\n // lifetime and we want selector-hook subscriptions to stay stable\n // across renders.\n const controller = useMemo(\n () =>\n new StreamController<StateType, InterruptType, ConfigurableType>({\n assistantId,\n // Cast: the runtime `Client` is state-shape agnostic, but the\n // controller declares `client: Client<StateType>` so its own\n // typings line up. Tightening `submit`'s `input` parameter to\n // `Partial<StateType>` surfaced this variance mismatch that\n // was previously masked — the cast is equivalent to the\n // ClientCtor cast above.\n client: client as unknown as Client<StateType>,\n threadId: options.threadId ?? null,\n transport,\n fetch: hasCustomAdapter ? undefined : asBag.fetch,\n webSocketFactory: hasCustomAdapter ? undefined : asBag.webSocketFactory,\n onThreadId: options.onThreadId,\n onCreated: options.onCreated,\n onCompleted: options.onCompleted,\n initialValues: options.initialValues,\n messagesKey: options.messagesKey,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, assistantId, transport]\n );\n\n // Rehydrate on threadId change. The initial hydrate is fired\n // synchronously inside the controller constructor so Suspense\n // callers don't deadlock waiting for an effect that never runs\n // (throwing `hydrationPromise` during render unmounts the subtree\n // before effects fire). We only re-hydrate here when the threadId\n // prop changes after the controller was already constructed with a\n // matching id.\n const lastHydratedRef = useRef<{\n controller: StreamController<StateType, InterruptType, ConfigurableType>;\n threadId: string | null;\n } | null>(null);\n useEffect(() => {\n const target = options.threadId ?? null;\n const last = lastHydratedRef.current;\n if (last?.controller !== controller) {\n // Freshly constructed controller already seeded the hydrate in\n // its constructor — record the id and skip the redundant call.\n lastHydratedRef.current = { controller, threadId: target };\n return;\n }\n if (last.threadId === target) return;\n lastHydratedRef.current = { controller, threadId: target };\n void controller.hydrate(target);\n }, [controller, options.threadId]);\n\n // Dispose on unmount / controller swap.\n //\n // We use `controller.activate()` instead of a naive\n // `() => controller.dispose()` cleanup because React 18+\n // `<StrictMode>` in dev mounts → unmounts → remounts components\n // synchronously to surface cleanup bugs. A naive cleanup would\n // permanently tear the controller down on that first synthetic\n // unmount and turn every subsequent `submit()` into a silent\n // no-op. `activate()` defers disposal to the next microtask and\n // cancels it if the effect re-runs — which is exactly the\n // StrictMode remount pattern.\n useEffect(() => controller.activate(), [controller]);\n\n // Headless-tool handling: if the caller supplied `tools`, watch the\n // root `values.__interrupt__` channel for protocol interrupts that\n // target a registered tool, invoke the handler, and auto-resume the\n // run. Ref-tracks the ids we've already handled so the same\n // interrupt on a subsequent render is never executed twice\n // (StrictMode safe).\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [options.threadId]);\n const tools = options.tools;\n const onTool = options.onTool;\n // Subscribe to values + interrupt updates via the root store so the\n // effect re-runs whenever a protocol interrupt lands or the\n // `__interrupt__` key is projected into values, not only on hook\n // re-render. We feed both sources to the flush helper because\n // v2-native runs surface protocol interrupts via\n // `rootStore.interrupts` (`input.requested` events), while legacy\n // graphs may still emit `values.__interrupt__`.\n const rootValuesForTools = useSyncExternalStore<StateType>(\n controller.rootStore.subscribe,\n () => controller.rootStore.getSnapshot().values,\n () => controller.rootStore.getSnapshot().values\n );\n const rootInterruptsForTools = useSyncExternalStore<\n readonly Interrupt<InterruptType>[]\n >(\n controller.rootStore.subscribe,\n () => controller.rootStore.getSnapshot().interrupts,\n () => controller.rootStore.getSnapshot().interrupts\n );\n useEffect(() => {\n if (!tools?.length) return;\n const valuesBag = rootValuesForTools as unknown as Record<string, unknown>;\n const existingInterrupts = Array.isArray(valuesBag?.__interrupt__)\n ? (valuesBag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existingInterrupts,\n ...(rootInterruptsForTools as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n flushPendingHeadlessToolInterrupts(\n { ...valuesBag, __interrupt__: combined },\n tools,\n handledToolsRef.current,\n {\n onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n controller.submit(null, {\n command,\n } as StreamSubmitOptions<StateType, ConfigurableType>),\n }\n );\n }, [controller, tools, onTool, rootValuesForTools, rootInterruptsForTools]);\n\n const root = useSyncExternalStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot,\n controller.rootStore.getSnapshot\n );\n const subagents = useSyncExternalStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot,\n controller.subagentStore.getSnapshot\n );\n const subgraphs = useSyncExternalStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot,\n controller.subgraphStore.getSnapshot\n );\n const subgraphsByNode = useSyncExternalStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n return useMemo<UseStreamReturn<T, InterruptType, ConfigurableType>>(() => {\n const userFacingInterrupts = filterOutHeadlessToolInterrupts(\n root.interrupts\n );\n return {\n values: root.values,\n messages: root.messages,\n toolCalls: root.toolCalls as InferToolCalls<T>[],\n interrupts: userFacingInterrupts,\n interrupt: userFacingInterrupts[0],\n isLoading: root.isLoading,\n isThreadLoading: root.isThreadLoading,\n hydrationPromise: controller.hydrationPromise,\n error: root.error,\n threadId: root.threadId,\n subagents: subagents as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs,\n subgraphsByNode,\n submit: (input, submitOptions) => controller.submit(input, submitOptions),\n stop: () => controller.stop(),\n respond: (response, target) => controller.respond(response, target),\n getThread: () => controller.getThread(),\n client,\n assistantId,\n [STREAM_CONTROLLER]: controller,\n } as UseStreamReturn<T, InterruptType, ConfigurableType>;\n }, [\n root,\n subagents,\n subgraphs,\n subgraphsByNode,\n controller,\n client,\n assistantId,\n ]);\n}\n\n/**\n * Convenience alias for the fully-resolved stream handle type.\n */\nexport type UseStreamResult<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * Helper used by the selector hooks to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `useMessages`, `useToolCalls`, etc.\n * instead of reading this directly.\n *\n * @internal\n */\nexport function getRegistry(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: UseStreamReturn<any, any, any>\n): ChannelRegistry {\n return stream[STREAM_CONTROLLER].registry;\n}\n\nexport type { ThreadStream };\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { BaseMessage } from "@langchain/core/messages";
2
2
  import { Client, Interrupt } from "@langchain/langgraph-sdk";
3
3
  import { ThreadStream } from "@langchain/langgraph-sdk/client";
4
- import { AgentServerOptions, AssembledToolCall, ChannelRegistry, CustomAdapterOptions, InferStateType, InferSubagentStates, StreamController, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, UseStreamOptions, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
4
+ import { AgentServerOptions, ChannelRegistry, CustomAdapterOptions, InferStateType, InferSubagentStates, InferToolCalls, StreamController, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, UseStreamOptions, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
5
5
 
6
6
  //#region src/use-stream.d.ts
7
7
  type AgentServerOptions$1<StateType extends object> = AgentServerOptions<StateType>;
@@ -60,7 +60,7 @@ interface UseStreamReturn<T = Record<string, unknown>, InterruptType = unknown,
60
60
  * Equivalent to calling `useMessages(stream)` with no target.
61
61
  */
62
62
  readonly messages: BaseMessage[];
63
- readonly toolCalls: AssembledToolCall[];
63
+ readonly toolCalls: InferToolCalls<T>[];
64
64
  readonly interrupts: Interrupt<InterruptType>[];
65
65
  readonly interrupt: Interrupt<InterruptType> | undefined;
66
66
  readonly isLoading: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"use-stream.d.cts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;KAoCY,oBAAA,6BACV,kBAAA,CAAyB,SAAA;AAAA,KAEf,sBAAA,6BACV,oBAAA,CAA2B,SAAA;AAAA,KAEjB,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CAAuB,SAAA;;;;;;;;;AAL3B;;cAiBa,iBAAA;AAAA,UAII,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EA1BN;;;;;AAGjC;;;;;;EAHiC,SAwCtB,MAAA,EAAQ,SAAA;EAnCO;;;;;;;EAAA,SA2Cf,YAAA,GAAe,SAAA;EA7BzB;;;;AAED;;;;;;;;;;;;;;;;EAFC,SAkDU,QAAA,EAAU,WAAA;EAAA,SACV,SAAA,EAAW,iBAAA;EAAA,SACX,UAAA,EAAY,SAAA,CAAU,aAAA;EAAA,SACtB,SAAA,EAAW,SAAA,CAAU,aAAA;EAAA,SACrB,SAAA;EAAA,SACA,eAAA;EAmC+B;;;;;;;EAAA,SA3B/B,gBAAA,EAAkB,OAAA;EAAA,SAClB,KAAA;EAAA,SACA,QAAA;EAkDN;;;;;EAAA,SA1CM,SAAA,EAAW,WAAA,OACZ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAuDA;;;;;;;;;;;EAAA,SA1CO,SAAA,EAAW,WAAA,SAAoB,yBAAA;EApFb;;;;;;;EAAA,SA4FlB,eAAA,EAAiB,WAAA,kBAEf,yBAAA;EAvEa;;;;;;;;EAmFxB,MAAA,CACE,KAAA,EAAO,mBAAA,CAAoB,OAAA,CAAQ,SAAA,uBACnC,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EACH,IAAA,IAAQ,OAAA;EACR,OAAA,CACE,QAAA,WACA,MAAA;IAAW,WAAA;IAAqB,SAAA;EAAA,IAC/B,OAAA;EAAA,SAGM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;EA3DA;EA8DT,SAAA,IAAa,YAAA;EAtDO;EAAA,UAyDV,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;KA0BQ,SAAA,GAAY,eAAA;;;;;;;;;;;;;;;;AAAxB;;;;;AAgCA;;;;;;;;;;iBAAgB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,KACxC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;KAuPzB,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA"}
1
+ {"version":3,"file":"use-stream.d.cts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;KAsCY,oBAAA,6BACV,kBAAA,CAAyB,SAAA;AAAA,KAEf,sBAAA,6BACV,oBAAA,CAA2B,SAAA;AAAA,KAEjB,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CAAuB,SAAA;;;;;;;;;AAL3B;;cAiBa,iBAAA;AAAA,UAII,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EA1BN;;;;;AAGjC;;;;;;EAHiC,SAwCtB,MAAA,EAAQ,SAAA;EAnCO;;;;;;;EAAA,SA2Cf,YAAA,GAAe,SAAA;EA7BzB;;;;AAED;;;;;;;;;;;;;;;;EAFC,SAkDU,QAAA,EAAU,WAAA;EAAA,SACV,SAAA,EAAW,cAAA,CAAe,CAAA;EAAA,SAC1B,UAAA,EAAY,SAAA,CAAU,aAAA;EAAA,SACtB,SAAA,EAAW,SAAA,CAAU,aAAA;EAAA,SACrB,SAAA;EAAA,SACA,eAAA;EAkBW;;;;;;;EAAA,SAVX,gBAAA,EAAkB,OAAA;EAAA,SAClB,KAAA;EAAA,SACA,QAAA;EAiDG;;;;;EAAA,SAzCH,SAAA,EAAW,WAAA,OACZ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAsDA;;;;;;;;;;;EAAA,SAzCO,SAAA,EAAW,WAAA,SAAoB,yBAAA;EApFxC;;;;;;;EAAA,SA4FS,eAAA,EAAiB,WAAA,kBAEf,yBAAA;EAvEF;;;;;;;;EAmFT,MAAA,CACE,KAAA,EAAO,mBAAA,CAAoB,OAAA,CAAQ,SAAA,uBACnC,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EACH,IAAA,IAAQ,OAAA;EACR,OAAA,CACE,QAAA,WACA,MAAA;IAAW,WAAA;IAAqB,SAAA;EAAA,IAC/B,OAAA;EAAA,SAGM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;EA7DkB;EAgE3B,SAAA,IAAa,YAAA;EA9DJ;EAAA,UAiEC,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;KA0BQ,SAAA,GAAY,eAAA;;;;;;;;;;;;;;;;;;AAAxB;;;;;AAgCA;;;;;;;;iBAAgB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,KACxC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;KAyPzB,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA"}
@@ -1,6 +1,6 @@
1
1
  import { Client, Interrupt } from "@langchain/langgraph-sdk";
2
2
  import { ThreadStream } from "@langchain/langgraph-sdk/client";
3
- import { AgentServerOptions, AssembledToolCall, ChannelRegistry, CustomAdapterOptions, InferStateType, InferSubagentStates, StreamController, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, UseStreamOptions, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
3
+ import { AgentServerOptions, ChannelRegistry, CustomAdapterOptions, InferStateType, InferSubagentStates, InferToolCalls, StreamController, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, UseStreamOptions, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
4
4
  import { BaseMessage } from "@langchain/core/messages";
5
5
 
6
6
  //#region src/use-stream.d.ts
@@ -60,7 +60,7 @@ interface UseStreamReturn<T = Record<string, unknown>, InterruptType = unknown,
60
60
  * Equivalent to calling `useMessages(stream)` with no target.
61
61
  */
62
62
  readonly messages: BaseMessage[];
63
- readonly toolCalls: AssembledToolCall[];
63
+ readonly toolCalls: InferToolCalls<T>[];
64
64
  readonly interrupts: Interrupt<InterruptType>[];
65
65
  readonly interrupt: Interrupt<InterruptType> | undefined;
66
66
  readonly isLoading: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"use-stream.d.ts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;KAoCY,oBAAA,6BACV,kBAAA,CAAyB,SAAA;AAAA,KAEf,sBAAA,6BACV,oBAAA,CAA2B,SAAA;AAAA,KAEjB,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CAAuB,SAAA;;;;;;;;;AAL3B;;cAiBa,iBAAA;AAAA,UAII,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EA1BN;;;;;AAGjC;;;;;;EAHiC,SAwCtB,MAAA,EAAQ,SAAA;EAnCO;;;;;;;EAAA,SA2Cf,YAAA,GAAe,SAAA;EA7BzB;;;;AAED;;;;;;;;;;;;;;;;EAFC,SAkDU,QAAA,EAAU,WAAA;EAAA,SACV,SAAA,EAAW,iBAAA;EAAA,SACX,UAAA,EAAY,SAAA,CAAU,aAAA;EAAA,SACtB,SAAA,EAAW,SAAA,CAAU,aAAA;EAAA,SACrB,SAAA;EAAA,SACA,eAAA;EAmC+B;;;;;;;EAAA,SA3B/B,gBAAA,EAAkB,OAAA;EAAA,SAClB,KAAA;EAAA,SACA,QAAA;EAkDN;;;;;EAAA,SA1CM,SAAA,EAAW,WAAA,OACZ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAuDA;;;;;;;;;;;EAAA,SA1CO,SAAA,EAAW,WAAA,SAAoB,yBAAA;EApFb;;;;;;;EAAA,SA4FlB,eAAA,EAAiB,WAAA,kBAEf,yBAAA;EAvEa;;;;;;;;EAmFxB,MAAA,CACE,KAAA,EAAO,mBAAA,CAAoB,OAAA,CAAQ,SAAA,uBACnC,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EACH,IAAA,IAAQ,OAAA;EACR,OAAA,CACE,QAAA,WACA,MAAA;IAAW,WAAA;IAAqB,SAAA;EAAA,IAC/B,OAAA;EAAA,SAGM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;EA3DA;EA8DT,SAAA,IAAa,YAAA;EAtDO;EAAA,UAyDV,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;KA0BQ,SAAA,GAAY,eAAA;;;;;;;;;;;;;;;;AAAxB;;;;;AAgCA;;;;;;;;;;iBAAgB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,KACxC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;KAuPzB,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA"}
1
+ {"version":3,"file":"use-stream.d.ts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;KAsCY,oBAAA,6BACV,kBAAA,CAAyB,SAAA;AAAA,KAEf,sBAAA,6BACV,oBAAA,CAA2B,SAAA;AAAA,KAEjB,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CAAuB,SAAA;;;;;;;;;AAL3B;;cAiBa,iBAAA;AAAA,UAII,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EA1BN;;;;;AAGjC;;;;;;EAHiC,SAwCtB,MAAA,EAAQ,SAAA;EAnCO;;;;;;;EAAA,SA2Cf,YAAA,GAAe,SAAA;EA7BzB;;;;AAED;;;;;;;;;;;;;;;;EAFC,SAkDU,QAAA,EAAU,WAAA;EAAA,SACV,SAAA,EAAW,cAAA,CAAe,CAAA;EAAA,SAC1B,UAAA,EAAY,SAAA,CAAU,aAAA;EAAA,SACtB,SAAA,EAAW,SAAA,CAAU,aAAA;EAAA,SACrB,SAAA;EAAA,SACA,eAAA;EAkBW;;;;;;;EAAA,SAVX,gBAAA,EAAkB,OAAA;EAAA,SAClB,KAAA;EAAA,SACA,QAAA;EAiDG;;;;;EAAA,SAzCH,SAAA,EAAW,WAAA,OACZ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAsDA;;;;;;;;;;;EAAA,SAzCO,SAAA,EAAW,WAAA,SAAoB,yBAAA;EApFxC;;;;;;;EAAA,SA4FS,eAAA,EAAiB,WAAA,kBAEf,yBAAA;EAvEF;;;;;;;;EAmFT,MAAA,CACE,KAAA,EAAO,mBAAA,CAAoB,OAAA,CAAQ,SAAA,uBACnC,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EACH,IAAA,IAAQ,OAAA;EACR,OAAA,CACE,QAAA,WACA,MAAA;IAAW,WAAA;IAAqB,SAAA;EAAA,IAC/B,OAAA;EAAA,SAGM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;EA7DkB;EAgE3B,SAAA,IAAa,YAAA;EA9DJ;EAAA,UAiEC,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;KA0BQ,SAAA,GAAY,eAAA;;;;;;;;;;;;;;;;;;AAAxB;;;;;AAgCA;;;;;;;;iBAAgB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,KACxC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;KAyPzB,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA"}
@@ -72,6 +72,7 @@ function useStream(options) {
72
72
  webSocketFactory: hasCustomAdapter ? void 0 : asBag.webSocketFactory,
73
73
  onThreadId: options.onThreadId,
74
74
  onCreated: options.onCreated,
75
+ onCompleted: options.onCompleted,
75
76
  initialValues: options.initialValues,
76
77
  messagesKey: options.messagesKey
77
78
  }), [
@@ -1 +1 @@
1
- {"version":3,"file":"use-stream.js","names":["ClientCtor"],"sources":["../src/use-stream.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n} from \"@langchain/langgraph-sdk\";\nimport {\n Client as ClientCtor,\n type ClientConfig,\n type ThreadStream,\n} from \"@langchain/langgraph-sdk/client\";\nimport {\n StreamController,\n type AgentServerAdapter,\n type AgentServerOptions as StreamAgentServerOptions,\n type AssembledToolCall,\n type ChannelRegistry,\n type CustomAdapterOptions as StreamCustomAdapterOptions,\n type InferStateType,\n type InferSubagentStates,\n type RootSnapshot,\n type StreamSubmitOptions,\n type SubagentDiscoverySnapshot,\n type SubagentMap,\n type SubgraphByNodeMap,\n type SubgraphDiscoverySnapshot,\n type SubgraphMap,\n type UseStreamOptions as StreamUseStreamOptions,\n type WidenUpdateMessages,\n} from \"@langchain/langgraph-sdk/stream\";\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<StateType>;\n\n/**\n * Private field on the hook return that carries the\n * {@link StreamController} reference. Selector hooks (`useMessages`,\n * `useToolCalls`, …) read this to reach the shared\n * {@link ChannelRegistry}. Typed as a symbol-keyed field to discourage\n * end-user access — use the selector hooks instead.\n *\n * Exported as a unique symbol so type narrowing works across\n * `useMessages(stream, target)` call sites.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/react/controller\"\n);\n\nexport interface UseStreamReturn<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n StateType extends object = InferStateType<T>,\n SubagentStates = InferSubagentStates<T>,\n> {\n // ----- always-on root projections -----\n /**\n * The most recent `values`-channel snapshot emitted at the root\n * namespace — i.e. the thread-level state as the server sees it\n * after each superstep. Updated on every root `values` event, not\n * on token-level deltas: if you render `values.messages` directly\n * you'll see full turns appear at once instead of streaming\n * token-by-token. Use {@link messages} (or `useMessages`) for the\n * token-streamed view.\n *\n * Equivalent to calling `useValues(stream)`.\n */\n readonly values: StateType;\n /**\n * Type-only: the resolved state shape. Exposed so consumers can\n * derive companion hook argument types (`useValues<typeof stream>`)\n * without plumbing `T` through their component hierarchy.\n *\n * @internal\n */\n readonly \"~stateType\"?: StateType;\n /**\n * The root message projection. Assembled from two sources and\n * merged in real time:\n *\n * 1. `messages`-channel deltas — token-level streaming events\n * (`message-start`, `content-block-delta`, `message-finish`)\n * emitted by the runtime. These drive live, token-by-token\n * updates.\n * 2. `values.messages` snapshots — the authoritative ordering\n * and any messages the agent produces without token streaming\n * (human turns, tool results, echoes from subagents).\n *\n * If the backend only emits `values` events (no `messages`\n * channel), every message will appear fully-formed on each\n * values update rather than streaming. This is a backend/runtime\n * concern — the React layer faithfully renders whatever the\n * server sends.\n *\n * Equivalent to calling `useMessages(stream)` with no target.\n */\n readonly messages: BaseMessage[];\n readonly toolCalls: AssembledToolCall[];\n readonly interrupts: Interrupt<InterruptType>[];\n readonly interrupt: Interrupt<InterruptType> | undefined;\n readonly isLoading: boolean;\n readonly isThreadLoading: boolean;\n /**\n * Promise that settles when the current thread's initial hydration\n * completes. Exposed so Suspense wrappers can `throw` it until the\n * first {@link StreamController.hydrate} call resolves (or rejects)\n * for the active thread. A fresh promise is installed on every\n * `switchThread`/`threadId` change.\n */\n readonly hydrationPromise: Promise<void>;\n readonly error: unknown;\n readonly threadId: string | null;\n\n // ----- always-on discovery -----\n /**\n * Subagents discovered on the root run. For DeepAgent-typed\n * streams the key set is narrowed to the subagent names declared\n * on the agent brand (`keyof InferSubagentStates<T>`).\n */\n readonly subagents: ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >;\n /**\n * Subgraphs discovered on the root run.\n *\n * A namespace is classified as a subgraph iff at least one\n * strictly-deeper namespace has been observed with it as a prefix.\n * This is inferred from the lifecycle event stream — plain function\n * nodes (`orchestrator`, `writer` in the nested-stategraph example)\n * never appear here even though the server emits namespaced\n * lifecycle events for them. Promotion is monotonic and retroactive;\n * an entry appears as soon as the first descendant event lands.\n */\n readonly subgraphs: ReadonlyMap<string, SubgraphDiscoverySnapshot>;\n /**\n * Subgraphs indexed by the graph node that produced them\n * (`addNode(\"visualizer_0\", …)`). Each value is an array because\n * parallel fan-outs and loops can spawn multiple invocations of\n * the same node; arrays preserve insertion order. Updates in\n * lock-step with {@link subgraphs}.\n */\n readonly subgraphsByNode: ReadonlyMap<\n string,\n readonly SubgraphDiscoverySnapshot[]\n >;\n\n // ----- imperatives -----\n /**\n * Dispatch a new run on the bound thread.\n *\n * `input` is typed as `Partial<StateType>` so IDE autocompletion\n * surfaces the state keys declared on the root hook. Pass `null`\n * (or omit fields) when resuming an interrupt via `options.command.resume`\n * — the server accepts a null payload in that case.\n */\n submit(\n input: WidenUpdateMessages<Partial<StateType>> | null | undefined,\n options?: StreamSubmitOptions<StateType, ConfigurableType>\n ): Promise<void>;\n stop(): Promise<void>;\n respond(\n response: unknown,\n target?: { interruptId: string; namespace?: string[] }\n ): Promise<void>;\n\n // ----- identity -----\n readonly client: Client;\n readonly assistantId: string;\n\n /** v2 escape hatch — returns the bound {@link ThreadStream}. */\n getThread(): ThreadStream | undefined;\n\n /** @internal Used by selector hooks (`useMessages`, `useToolCalls`, …). */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased stream handle useful as a parameter type for helpers and\n * wrapper components that pass a `stream` through to selector hooks\n * (`useMessages`, `useChannel`, …) without reading `values` directly.\n * Any fully-typed `UseStreamReturn<S, I, C>` is\n * assignable to `AnyStream` because the generic slots are `any`\n * (bivariant), which avoids the `CompiledStateGraph` → `Record<string,\n * unknown>` assignment friction you hit when using the bare\n * `UseStreamReturn` default.\n *\n * @example\n * ```tsx\n * function SubgraphCard({ stream, subgraph }: {\n * stream: AnyStream;\n * subgraph: SubgraphDiscoverySnapshot;\n * }) {\n * const messages = useMessages(stream, subgraph);\n * return <Feed messages={messages} />;\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * React binding for the v2-native stream runtime.\n *\n * `useStream` exposes three always-on projections\n * (`values` / `messages` / `toolCalls`) at the thread root plus\n * cheap discovery maps for subagents / subgraphs. Scoped views of\n * subagents, subgraphs, or any namespaced projection are surfaced via\n * the companion selector hooks:\n *\n * ```tsx\n * const stream = useStream({ assistantId: \"deep-agent\" });\n *\n * // Root messages — always on, already class instances.\n * stream.messages.map((m) => <Bubble key={m.id} msg={m} />);\n *\n * // Subagent view — mount = subscribe, unmount = unsubscribe.\n * function SubagentCard({ subagent }) {\n * const messages = useMessages(stream, subagent);\n * const toolCalls = useToolCalls(stream, subagent);\n * return <>{messages.map(...)}</>;\n * }\n * ```\n *\n * The first generic accepts either a plain state type\n * (`useStream<MyState>()`) *or* a compiled graph type\n * (`useStream<typeof agent>()`); in the latter case the\n * state shape is unwrapped from the graph via {@link InferStateType}, so\n * `stream.values` is always typed as the state, never as the graph\n * class itself.\n */\nexport function useStream<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n>(\n options: UseStreamOptions<InferStateType<T>>\n): UseStreamReturn<T, InterruptType, ConfigurableType> {\n type StateType = InferStateType<T>;\n // Branch-stable narrowings for each code path. The custom-adapter\n // branch can skip LGP client construction entirely, which keeps\n // bundles that *only* use a custom adapter free of the default\n // `sse`/`websocket` transport factories (tree-shaken).\n // Treat the options as a flat bag here — the discriminated union\n // exists to give call sites a nice error message, but at runtime\n // both branches are reachable through the same set of fields.\n interface OptionsBag {\n assistantId?: string;\n threadId?: string | null;\n client?: Client;\n apiUrl?: string;\n apiKey?: string;\n callerOptions?: ClientConfig[\"callerOptions\"];\n defaultHeaders?: ClientConfig[\"defaultHeaders\"];\n transport?: \"sse\" | \"websocket\" | AgentServerAdapter;\n fetch?: typeof fetch;\n webSocketFactory?: (url: string) => WebSocket;\n onThreadId?: (threadId: string) => void;\n onCreated?: (meta: { run_id: string; thread_id: string }) => void;\n initialValues?: StateType;\n messagesKey?: string;\n }\n const asBag = options as OptionsBag;\n // Narrow once: a non-string `transport` is a custom adapter; anything\n // else (`\"sse\"` / `\"websocket\"` / `undefined`) is a built-in.\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n const client = useMemo<Client>(\n () =>\n asBag.client ??\n (new ClientCtor({\n apiUrl: asBag.apiUrl,\n apiKey: asBag.apiKey,\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client),\n [\n asBag.client,\n asBag.apiUrl,\n asBag.apiKey,\n asBag.callerOptions,\n asBag.defaultHeaders,\n ]\n );\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n // `\"_\"` is the well-known sentinel for \"adapter doesn't care\".\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n // Recreate the controller only on assistantId / client / transport\n // change; the ThreadStream is bound to one assistant for its\n // lifetime and we want selector-hook subscriptions to stay stable\n // across renders.\n const controller = useMemo(\n () =>\n new StreamController<StateType, InterruptType, ConfigurableType>({\n assistantId,\n // Cast: the runtime `Client` is state-shape agnostic, but the\n // controller declares `client: Client<StateType>` so its own\n // typings line up. Tightening `submit`'s `input` parameter to\n // `Partial<StateType>` surfaced this variance mismatch that\n // was previously masked — the cast is equivalent to the\n // ClientCtor cast above.\n client: client as unknown as Client<StateType>,\n threadId: options.threadId ?? null,\n transport,\n fetch: hasCustomAdapter ? undefined : asBag.fetch,\n webSocketFactory: hasCustomAdapter ? undefined : asBag.webSocketFactory,\n onThreadId: options.onThreadId,\n onCreated: options.onCreated,\n initialValues: options.initialValues,\n messagesKey: options.messagesKey,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, assistantId, transport]\n );\n\n // Rehydrate on threadId change. The initial hydrate is fired\n // synchronously inside the controller constructor so Suspense\n // callers don't deadlock waiting for an effect that never runs\n // (throwing `hydrationPromise` during render unmounts the subtree\n // before effects fire). We only re-hydrate here when the threadId\n // prop changes after the controller was already constructed with a\n // matching id.\n const lastHydratedRef = useRef<{\n controller: StreamController<StateType, InterruptType, ConfigurableType>;\n threadId: string | null;\n } | null>(null);\n useEffect(() => {\n const target = options.threadId ?? null;\n const last = lastHydratedRef.current;\n if (last?.controller !== controller) {\n // Freshly constructed controller already seeded the hydrate in\n // its constructor — record the id and skip the redundant call.\n lastHydratedRef.current = { controller, threadId: target };\n return;\n }\n if (last.threadId === target) return;\n lastHydratedRef.current = { controller, threadId: target };\n void controller.hydrate(target);\n }, [controller, options.threadId]);\n\n // Dispose on unmount / controller swap.\n //\n // We use `controller.activate()` instead of a naive\n // `() => controller.dispose()` cleanup because React 18+\n // `<StrictMode>` in dev mounts → unmounts → remounts components\n // synchronously to surface cleanup bugs. A naive cleanup would\n // permanently tear the controller down on that first synthetic\n // unmount and turn every subsequent `submit()` into a silent\n // no-op. `activate()` defers disposal to the next microtask and\n // cancels it if the effect re-runs — which is exactly the\n // StrictMode remount pattern.\n useEffect(() => controller.activate(), [controller]);\n\n // Headless-tool handling: if the caller supplied `tools`, watch the\n // root `values.__interrupt__` channel for protocol interrupts that\n // target a registered tool, invoke the handler, and auto-resume the\n // run. Ref-tracks the ids we've already handled so the same\n // interrupt on a subsequent render is never executed twice\n // (StrictMode safe).\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [options.threadId]);\n const tools = options.tools;\n const onTool = options.onTool;\n // Subscribe to values + interrupt updates via the root store so the\n // effect re-runs whenever a protocol interrupt lands or the\n // `__interrupt__` key is projected into values, not only on hook\n // re-render. We feed both sources to the flush helper because\n // v2-native runs surface protocol interrupts via\n // `rootStore.interrupts` (`input.requested` events), while legacy\n // graphs may still emit `values.__interrupt__`.\n const rootValuesForTools = useSyncExternalStore<StateType>(\n controller.rootStore.subscribe,\n () => controller.rootStore.getSnapshot().values,\n () => controller.rootStore.getSnapshot().values\n );\n const rootInterruptsForTools = useSyncExternalStore<\n readonly Interrupt<InterruptType>[]\n >(\n controller.rootStore.subscribe,\n () => controller.rootStore.getSnapshot().interrupts,\n () => controller.rootStore.getSnapshot().interrupts\n );\n useEffect(() => {\n if (!tools?.length) return;\n const valuesBag = rootValuesForTools as unknown as Record<string, unknown>;\n const existingInterrupts = Array.isArray(valuesBag?.__interrupt__)\n ? (valuesBag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existingInterrupts,\n ...(rootInterruptsForTools as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n flushPendingHeadlessToolInterrupts(\n { ...valuesBag, __interrupt__: combined },\n tools,\n handledToolsRef.current,\n {\n onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n controller.submit(null, {\n command,\n } as StreamSubmitOptions<StateType, ConfigurableType>),\n }\n );\n }, [controller, tools, onTool, rootValuesForTools, rootInterruptsForTools]);\n\n const root = useSyncExternalStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot,\n controller.rootStore.getSnapshot\n );\n const subagents = useSyncExternalStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot,\n controller.subagentStore.getSnapshot\n );\n const subgraphs = useSyncExternalStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot,\n controller.subgraphStore.getSnapshot\n );\n const subgraphsByNode = useSyncExternalStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n return useMemo<UseStreamReturn<T, InterruptType, ConfigurableType>>(() => {\n const userFacingInterrupts = filterOutHeadlessToolInterrupts(\n root.interrupts\n );\n return {\n values: root.values,\n messages: root.messages,\n toolCalls: root.toolCalls,\n interrupts: userFacingInterrupts,\n interrupt: userFacingInterrupts[0],\n isLoading: root.isLoading,\n isThreadLoading: root.isThreadLoading,\n hydrationPromise: controller.hydrationPromise,\n error: root.error,\n threadId: root.threadId,\n subagents: subagents as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs,\n subgraphsByNode,\n submit: (input, submitOptions) => controller.submit(input, submitOptions),\n stop: () => controller.stop(),\n respond: (response, target) => controller.respond(response, target),\n getThread: () => controller.getThread(),\n client,\n assistantId,\n [STREAM_CONTROLLER]: controller,\n } as UseStreamReturn<T, InterruptType, ConfigurableType>;\n }, [\n root,\n subagents,\n subgraphs,\n subgraphsByNode,\n controller,\n client,\n assistantId,\n ]);\n}\n\n/**\n * Convenience alias for the fully-resolved stream handle type.\n */\nexport type UseStreamResult<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * Helper used by the selector hooks to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `useMessages`, `useToolCalls`, etc.\n * instead of reading this directly.\n *\n * @internal\n */\nexport function getRegistry(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: UseStreamReturn<any, any, any>\n): ChannelRegistry {\n return stream[STREAM_CONTROLLER].registry;\n}\n\nexport type { ThreadStream };\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-stream.js","names":["ClientCtor"],"sources":["../src/use-stream.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n} from \"@langchain/langgraph-sdk\";\nimport {\n Client as ClientCtor,\n type ClientConfig,\n type ThreadStream,\n} from \"@langchain/langgraph-sdk/client\";\nimport {\n StreamController,\n type AgentServerAdapter,\n type AgentServerOptions as StreamAgentServerOptions,\n type ChannelRegistry,\n type CustomAdapterOptions as StreamCustomAdapterOptions,\n type InferStateType,\n type InferSubagentStates,\n type InferToolCalls,\n type RootSnapshot,\n type RunCompletedInfo,\n type RunExecutionInfo,\n type StreamSubmitOptions,\n type SubagentDiscoverySnapshot,\n type SubagentMap,\n type SubgraphByNodeMap,\n type SubgraphDiscoverySnapshot,\n type SubgraphMap,\n type UseStreamOptions as StreamUseStreamOptions,\n type WidenUpdateMessages,\n} from \"@langchain/langgraph-sdk/stream\";\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<StateType>;\n\n/**\n * Private field on the hook return that carries the\n * {@link StreamController} reference. Selector hooks (`useMessages`,\n * `useToolCalls`, …) read this to reach the shared\n * {@link ChannelRegistry}. Typed as a symbol-keyed field to discourage\n * end-user access — use the selector hooks instead.\n *\n * Exported as a unique symbol so type narrowing works across\n * `useMessages(stream, target)` call sites.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/react/controller\"\n);\n\nexport interface UseStreamReturn<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n StateType extends object = InferStateType<T>,\n SubagentStates = InferSubagentStates<T>,\n> {\n // ----- always-on root projections -----\n /**\n * The most recent `values`-channel snapshot emitted at the root\n * namespace — i.e. the thread-level state as the server sees it\n * after each superstep. Updated on every root `values` event, not\n * on token-level deltas: if you render `values.messages` directly\n * you'll see full turns appear at once instead of streaming\n * token-by-token. Use {@link messages} (or `useMessages`) for the\n * token-streamed view.\n *\n * Equivalent to calling `useValues(stream)`.\n */\n readonly values: StateType;\n /**\n * Type-only: the resolved state shape. Exposed so consumers can\n * derive companion hook argument types (`useValues<typeof stream>`)\n * without plumbing `T` through their component hierarchy.\n *\n * @internal\n */\n readonly \"~stateType\"?: StateType;\n /**\n * The root message projection. Assembled from two sources and\n * merged in real time:\n *\n * 1. `messages`-channel deltas — token-level streaming events\n * (`message-start`, `content-block-delta`, `message-finish`)\n * emitted by the runtime. These drive live, token-by-token\n * updates.\n * 2. `values.messages` snapshots — the authoritative ordering\n * and any messages the agent produces without token streaming\n * (human turns, tool results, echoes from subagents).\n *\n * If the backend only emits `values` events (no `messages`\n * channel), every message will appear fully-formed on each\n * values update rather than streaming. This is a backend/runtime\n * concern — the React layer faithfully renders whatever the\n * server sends.\n *\n * Equivalent to calling `useMessages(stream)` with no target.\n */\n readonly messages: BaseMessage[];\n readonly toolCalls: InferToolCalls<T>[];\n readonly interrupts: Interrupt<InterruptType>[];\n readonly interrupt: Interrupt<InterruptType> | undefined;\n readonly isLoading: boolean;\n readonly isThreadLoading: boolean;\n /**\n * Promise that settles when the current thread's initial hydration\n * completes. Exposed so Suspense wrappers can `throw` it until the\n * first {@link StreamController.hydrate} call resolves (or rejects)\n * for the active thread. A fresh promise is installed on every\n * `switchThread`/`threadId` change.\n */\n readonly hydrationPromise: Promise<void>;\n readonly error: unknown;\n readonly threadId: string | null;\n\n // ----- always-on discovery -----\n /**\n * Subagents discovered on the root run. For DeepAgent-typed\n * streams the key set is narrowed to the subagent names declared\n * on the agent brand (`keyof InferSubagentStates<T>`).\n */\n readonly subagents: ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >;\n /**\n * Subgraphs discovered on the root run.\n *\n * A namespace is classified as a subgraph iff at least one\n * strictly-deeper namespace has been observed with it as a prefix.\n * This is inferred from the lifecycle event stream — plain function\n * nodes (`orchestrator`, `writer` in the nested-stategraph example)\n * never appear here even though the server emits namespaced\n * lifecycle events for them. Promotion is monotonic and retroactive;\n * an entry appears as soon as the first descendant event lands.\n */\n readonly subgraphs: ReadonlyMap<string, SubgraphDiscoverySnapshot>;\n /**\n * Subgraphs indexed by the graph node that produced them\n * (`addNode(\"visualizer_0\", …)`). Each value is an array because\n * parallel fan-outs and loops can spawn multiple invocations of\n * the same node; arrays preserve insertion order. Updates in\n * lock-step with {@link subgraphs}.\n */\n readonly subgraphsByNode: ReadonlyMap<\n string,\n readonly SubgraphDiscoverySnapshot[]\n >;\n\n // ----- imperatives -----\n /**\n * Dispatch a new run on the bound thread.\n *\n * `input` is typed as `Partial<StateType>` so IDE autocompletion\n * surfaces the state keys declared on the root hook. Pass `null`\n * (or omit fields) when resuming an interrupt via `options.command.resume`\n * — the server accepts a null payload in that case.\n */\n submit(\n input: WidenUpdateMessages<Partial<StateType>> | null | undefined,\n options?: StreamSubmitOptions<StateType, ConfigurableType>\n ): Promise<void>;\n stop(): Promise<void>;\n respond(\n response: unknown,\n target?: { interruptId: string; namespace?: string[] }\n ): Promise<void>;\n\n // ----- identity -----\n readonly client: Client;\n readonly assistantId: string;\n\n /** v2 escape hatch — returns the bound {@link ThreadStream}. */\n getThread(): ThreadStream | undefined;\n\n /** @internal Used by selector hooks (`useMessages`, `useToolCalls`, …). */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased stream handle useful as a parameter type for helpers and\n * wrapper components that pass a `stream` through to selector hooks\n * (`useMessages`, `useChannel`, …) without reading `values` directly.\n * Any fully-typed `UseStreamReturn<S, I, C>` is\n * assignable to `AnyStream` because the generic slots are `any`\n * (bivariant), which avoids the `CompiledStateGraph` → `Record<string,\n * unknown>` assignment friction you hit when using the bare\n * `UseStreamReturn` default.\n *\n * @example\n * ```tsx\n * function SubgraphCard({ stream, subgraph }: {\n * stream: AnyStream;\n * subgraph: SubgraphDiscoverySnapshot;\n * }) {\n * const messages = useMessages(stream, subgraph);\n * return <Feed messages={messages} />;\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * React binding for the v2-native stream runtime.\n *\n * `useStream` exposes three always-on projections\n * (`values` / `messages` / `toolCalls`) at the thread root plus\n * cheap discovery maps for subagents / subgraphs. Scoped views of\n * subagents, subgraphs, or any namespaced projection are surfaced via\n * the companion selector hooks:\n *\n * ```tsx\n * const stream = useStream({ assistantId: \"deep-agent\" });\n *\n * // Root messages — always on, already class instances.\n * stream.messages.map((m) => <Bubble key={m.id} msg={m} />);\n *\n * // Subagent view — mount = subscribe, unmount = unsubscribe.\n * function SubagentCard({ subagent }) {\n * const messages = useMessages(stream, subagent);\n * const toolCalls = useToolCalls(stream, subagent);\n * return <>{messages.map(...)}</>;\n * }\n * ```\n *\n * The first generic accepts either a plain state type\n * (`useStream<MyState>()`) *or* a compiled graph type\n * (`useStream<typeof agent>()`); in the latter case the\n * state shape is unwrapped from the graph via {@link InferStateType}, so\n * `stream.values` is always typed as the state, never as the graph\n * class itself.\n */\nexport function useStream<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n>(\n options: UseStreamOptions<InferStateType<T>>\n): UseStreamReturn<T, InterruptType, ConfigurableType> {\n type StateType = InferStateType<T>;\n // Branch-stable narrowings for each code path. The custom-adapter\n // branch can skip LGP client construction entirely, which keeps\n // bundles that *only* use a custom adapter free of the default\n // `sse`/`websocket` transport factories (tree-shaken).\n // Treat the options as a flat bag here — the discriminated union\n // exists to give call sites a nice error message, but at runtime\n // both branches are reachable through the same set of fields.\n interface OptionsBag {\n assistantId?: string;\n threadId?: string | null;\n client?: Client;\n apiUrl?: string;\n apiKey?: string;\n callerOptions?: ClientConfig[\"callerOptions\"];\n defaultHeaders?: ClientConfig[\"defaultHeaders\"];\n transport?: \"sse\" | \"websocket\" | AgentServerAdapter;\n fetch?: typeof fetch;\n webSocketFactory?: (url: string) => WebSocket;\n onThreadId?: (threadId: string) => void;\n onCreated?: (info: RunExecutionInfo) => void;\n onCompleted?: (info: RunCompletedInfo) => void;\n initialValues?: StateType;\n messagesKey?: string;\n }\n const asBag = options as OptionsBag;\n // Narrow once: a non-string `transport` is a custom adapter; anything\n // else (`\"sse\"` / `\"websocket\"` / `undefined`) is a built-in.\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n const client = useMemo<Client>(\n () =>\n asBag.client ??\n (new ClientCtor({\n apiUrl: asBag.apiUrl,\n apiKey: asBag.apiKey,\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client),\n [\n asBag.client,\n asBag.apiUrl,\n asBag.apiKey,\n asBag.callerOptions,\n asBag.defaultHeaders,\n ]\n );\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n // `\"_\"` is the well-known sentinel for \"adapter doesn't care\".\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n // Recreate the controller only on assistantId / client / transport\n // change; the ThreadStream is bound to one assistant for its\n // lifetime and we want selector-hook subscriptions to stay stable\n // across renders.\n const controller = useMemo(\n () =>\n new StreamController<StateType, InterruptType, ConfigurableType>({\n assistantId,\n // Cast: the runtime `Client` is state-shape agnostic, but the\n // controller declares `client: Client<StateType>` so its own\n // typings line up. Tightening `submit`'s `input` parameter to\n // `Partial<StateType>` surfaced this variance mismatch that\n // was previously masked — the cast is equivalent to the\n // ClientCtor cast above.\n client: client as unknown as Client<StateType>,\n threadId: options.threadId ?? null,\n transport,\n fetch: hasCustomAdapter ? undefined : asBag.fetch,\n webSocketFactory: hasCustomAdapter ? undefined : asBag.webSocketFactory,\n onThreadId: options.onThreadId,\n onCreated: options.onCreated,\n onCompleted: options.onCompleted,\n initialValues: options.initialValues,\n messagesKey: options.messagesKey,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, assistantId, transport]\n );\n\n // Rehydrate on threadId change. The initial hydrate is fired\n // synchronously inside the controller constructor so Suspense\n // callers don't deadlock waiting for an effect that never runs\n // (throwing `hydrationPromise` during render unmounts the subtree\n // before effects fire). We only re-hydrate here when the threadId\n // prop changes after the controller was already constructed with a\n // matching id.\n const lastHydratedRef = useRef<{\n controller: StreamController<StateType, InterruptType, ConfigurableType>;\n threadId: string | null;\n } | null>(null);\n useEffect(() => {\n const target = options.threadId ?? null;\n const last = lastHydratedRef.current;\n if (last?.controller !== controller) {\n // Freshly constructed controller already seeded the hydrate in\n // its constructor — record the id and skip the redundant call.\n lastHydratedRef.current = { controller, threadId: target };\n return;\n }\n if (last.threadId === target) return;\n lastHydratedRef.current = { controller, threadId: target };\n void controller.hydrate(target);\n }, [controller, options.threadId]);\n\n // Dispose on unmount / controller swap.\n //\n // We use `controller.activate()` instead of a naive\n // `() => controller.dispose()` cleanup because React 18+\n // `<StrictMode>` in dev mounts → unmounts → remounts components\n // synchronously to surface cleanup bugs. A naive cleanup would\n // permanently tear the controller down on that first synthetic\n // unmount and turn every subsequent `submit()` into a silent\n // no-op. `activate()` defers disposal to the next microtask and\n // cancels it if the effect re-runs — which is exactly the\n // StrictMode remount pattern.\n useEffect(() => controller.activate(), [controller]);\n\n // Headless-tool handling: if the caller supplied `tools`, watch the\n // root `values.__interrupt__` channel for protocol interrupts that\n // target a registered tool, invoke the handler, and auto-resume the\n // run. Ref-tracks the ids we've already handled so the same\n // interrupt on a subsequent render is never executed twice\n // (StrictMode safe).\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [options.threadId]);\n const tools = options.tools;\n const onTool = options.onTool;\n // Subscribe to values + interrupt updates via the root store so the\n // effect re-runs whenever a protocol interrupt lands or the\n // `__interrupt__` key is projected into values, not only on hook\n // re-render. We feed both sources to the flush helper because\n // v2-native runs surface protocol interrupts via\n // `rootStore.interrupts` (`input.requested` events), while legacy\n // graphs may still emit `values.__interrupt__`.\n const rootValuesForTools = useSyncExternalStore<StateType>(\n controller.rootStore.subscribe,\n () => controller.rootStore.getSnapshot().values,\n () => controller.rootStore.getSnapshot().values\n );\n const rootInterruptsForTools = useSyncExternalStore<\n readonly Interrupt<InterruptType>[]\n >(\n controller.rootStore.subscribe,\n () => controller.rootStore.getSnapshot().interrupts,\n () => controller.rootStore.getSnapshot().interrupts\n );\n useEffect(() => {\n if (!tools?.length) return;\n const valuesBag = rootValuesForTools as unknown as Record<string, unknown>;\n const existingInterrupts = Array.isArray(valuesBag?.__interrupt__)\n ? (valuesBag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existingInterrupts,\n ...(rootInterruptsForTools as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n flushPendingHeadlessToolInterrupts(\n { ...valuesBag, __interrupt__: combined },\n tools,\n handledToolsRef.current,\n {\n onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n controller.submit(null, {\n command,\n } as StreamSubmitOptions<StateType, ConfigurableType>),\n }\n );\n }, [controller, tools, onTool, rootValuesForTools, rootInterruptsForTools]);\n\n const root = useSyncExternalStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot,\n controller.rootStore.getSnapshot\n );\n const subagents = useSyncExternalStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot,\n controller.subagentStore.getSnapshot\n );\n const subgraphs = useSyncExternalStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot,\n controller.subgraphStore.getSnapshot\n );\n const subgraphsByNode = useSyncExternalStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n return useMemo<UseStreamReturn<T, InterruptType, ConfigurableType>>(() => {\n const userFacingInterrupts = filterOutHeadlessToolInterrupts(\n root.interrupts\n );\n return {\n values: root.values,\n messages: root.messages,\n toolCalls: root.toolCalls as InferToolCalls<T>[],\n interrupts: userFacingInterrupts,\n interrupt: userFacingInterrupts[0],\n isLoading: root.isLoading,\n isThreadLoading: root.isThreadLoading,\n hydrationPromise: controller.hydrationPromise,\n error: root.error,\n threadId: root.threadId,\n subagents: subagents as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs,\n subgraphsByNode,\n submit: (input, submitOptions) => controller.submit(input, submitOptions),\n stop: () => controller.stop(),\n respond: (response, target) => controller.respond(response, target),\n getThread: () => controller.getThread(),\n client,\n assistantId,\n [STREAM_CONTROLLER]: controller,\n } as UseStreamReturn<T, InterruptType, ConfigurableType>;\n }, [\n root,\n subagents,\n subgraphs,\n subgraphsByNode,\n controller,\n client,\n assistantId,\n ]);\n}\n\n/**\n * Convenience alias for the fully-resolved stream handle type.\n */\nexport type UseStreamResult<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * Helper used by the selector hooks to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `useMessages`, `useToolCalls`, etc.\n * instead of reading this directly.\n *\n * @internal\n */\nexport function getRegistry(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: UseStreamReturn<any, any, any>\n): ChannelRegistry {\n return stream[STREAM_CONTROLLER].registry;\n}\n\nexport type { ThreadStream };\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/react",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "React integration for LangGraph & LangChain",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,7 +10,7 @@
10
10
  "directory": "libs/sdk-react"
11
11
  },
12
12
  "dependencies": {
13
- "@langchain/langgraph-sdk": "1.9.3"
13
+ "@langchain/langgraph-sdk": "1.9.5"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@hono/node-server": "^1.19.13",
@@ -30,7 +30,7 @@
30
30
  "vitest-browser-react": "^2.0.5",
31
31
  "webdriverio": "^9.25.0",
32
32
  "zod": "^4.3.6",
33
- "@langchain/langgraph": "^1.3.1",
33
+ "@langchain/langgraph": "^1.3.2",
34
34
  "@langchain/langgraph-api": "^1.2.2",
35
35
  "@langchain/langgraph-checkpoint": "^1.0.2"
36
36
  },