@langchain/vue 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
@@ -1,4 +1,4 @@
1
- import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER, StateOf, ThreadStream, UseStreamOptions, UseStreamResult, UseStreamReturn, useStream } from "./use-stream.cjs";
1
+ import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER, ThreadStream, UseStreamOptions, UseStreamResult, UseStreamReturn, useStream } from "./use-stream.cjs";
2
2
  import { useProjection } from "./use-projection.cjs";
3
3
  import { SelectorTarget, SubmissionQueueEntry, SubmissionQueueSnapshot, UseSubmissionQueueReturn, useAudio, useChannel, useExtension, useFiles, useImages, useMessageMetadata, useMessages, useSubmissionQueue, useToolCalls, useValues, useVideo } from "./selectors.cjs";
4
4
  import { useMediaURL } from "./use-media-url.cjs";
@@ -6,6 +6,6 @@ import { AudioPlayerHandle, PlayerStatus, UseAudioPlayerOptions, useAudioPlayer
6
6
  import { UseVideoPlayerOptions, VideoPlayerHandle, useVideoPlayer } from "./use-video-player.cjs";
7
7
  import { LANGCHAIN_OPTIONS, LangChainPlugin, LangChainPluginOptions, provideStream, useStreamContext } from "./context.cjs";
8
8
  import { VueReactiveOptions } from "./types.cjs";
9
- import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallFromTool, ToolCallState, ToolCallWithResult, 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";
11
- 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, LANGCHAIN_OPTIONS, LangChainPlugin, type LangChainPluginOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, type PlayerStatus, STREAM_CONTROLLER, type SelectorTarget, type StateOf, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type UseAudioPlayerOptions, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type UseSubmissionQueueReturn, type UseVideoPlayerOptions, type VideoMedia, type VideoPlayerHandle, type VueReactiveOptions, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, useAudio, useAudioPlayer, useChannel, useExtension, useFiles, useImages, useMediaURL, useMessageMetadata, useMessages, useProjection, useStream, useStreamContext, useSubmissionQueue, useToolCalls, useValues, useVideo, useVideoPlayer };
9
+ import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallState, ToolCallWithResult, 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, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, MessageMetadata, MessageMetadataMap, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
11
+ 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, LANGCHAIN_OPTIONS, LangChainPlugin, type LangChainPluginOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, type PlayerStatus, STREAM_CONTROLLER, type SelectorTarget, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type UseAudioPlayerOptions, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type UseSubmissionQueueReturn, type UseVideoPlayerOptions, type VideoMedia, type VideoPlayerHandle, type VueReactiveOptions, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, useAudio, useAudioPlayer, useChannel, useExtension, useFiles, useImages, useMediaURL, useMessageMetadata, useMessages, useProjection, useStream, useStreamContext, useSubmissionQueue, useToolCalls, useValues, useVideo, useVideoPlayer };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER, StateOf, ThreadStream, UseStreamOptions, UseStreamResult, UseStreamReturn, useStream } from "./use-stream.js";
1
+ import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER, ThreadStream, UseStreamOptions, UseStreamResult, UseStreamReturn, useStream } from "./use-stream.js";
2
2
  import { useProjection } from "./use-projection.js";
3
3
  import { SelectorTarget, SubmissionQueueEntry, SubmissionQueueSnapshot, UseSubmissionQueueReturn, useAudio, useChannel, useExtension, useFiles, useImages, useMessageMetadata, useMessages, useSubmissionQueue, useToolCalls, useValues, useVideo } from "./selectors.js";
4
4
  import { useMediaURL } from "./use-media-url.js";
@@ -6,6 +6,6 @@ import { AudioPlayerHandle, PlayerStatus, UseAudioPlayerOptions, useAudioPlayer
6
6
  import { UseVideoPlayerOptions, VideoPlayerHandle, useVideoPlayer } from "./use-video-player.js";
7
7
  import { LANGCHAIN_OPTIONS, LangChainPlugin, LangChainPluginOptions, provideStream, useStreamContext } from "./context.js";
8
8
  import { VueReactiveOptions } from "./types.js";
9
- import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallFromTool, ToolCallState, ToolCallWithResult, 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";
11
- 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, LANGCHAIN_OPTIONS, LangChainPlugin, type LangChainPluginOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, type PlayerStatus, STREAM_CONTROLLER, type SelectorTarget, type StateOf, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type UseAudioPlayerOptions, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type UseSubmissionQueueReturn, type UseVideoPlayerOptions, type VideoMedia, type VideoPlayerHandle, type VueReactiveOptions, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, useAudio, useAudioPlayer, useChannel, useExtension, useFiles, useImages, useMediaURL, useMessageMetadata, useMessages, useProjection, useStream, useStreamContext, useSubmissionQueue, useToolCalls, useValues, useVideo, useVideoPlayer };
9
+ import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallState, ToolCallWithResult, 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, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, MessageMetadata, MessageMetadataMap, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
11
+ 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, LANGCHAIN_OPTIONS, LangChainPlugin, type LangChainPluginOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, type PlayerStatus, STREAM_CONTROLLER, type SelectorTarget, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type UseAudioPlayerOptions, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type UseSubmissionQueueReturn, type UseVideoPlayerOptions, type VideoMedia, type VideoPlayerHandle, type VueReactiveOptions, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, useAudio, useAudioPlayer, useChannel, useExtension, useFiles, useImages, useMediaURL, useMessageMetadata, useMessages, useProjection, useStream, useStreamContext, useSubmissionQueue, useToolCalls, useValues, useVideo, useVideoPlayer };
@@ -37,11 +37,6 @@ function useMessages(stream, target) {
37
37
  return require_use_projection.useProjection(require_use_stream.getRegistry(stream), () => (0, _langchain_langgraph_sdk_stream.messagesProjection)(namespace.value), key, EMPTY_MESSAGES);
38
38
  }
39
39
  const EMPTY_MESSAGES = [];
40
- /**
41
- * Subscribe to a scoped `tools` (tool-call) stream. Same target and
42
- * lifecycle rules as {@link useMessages}; at the root this returns
43
- * `stream.toolCalls` directly.
44
- */
45
40
  function useToolCalls(stream, target) {
46
41
  const namespace = (0, vue.computed)(() => resolveNamespace((0, vue.toValue)(target)));
47
42
  if (isRoot(namespace.value)) return stream.toolCalls;
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.cjs","names":["NAMESPACE_SEPARATOR","useProjection","getRegistry","STREAM_CONTROLLER"],"sources":["../src/selectors.ts"],"sourcesContent":["import {\n computed,\n onScopeDispose,\n readonly,\n shallowRef,\n toValue,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from \"vue\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\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 MessageMetadata,\n type MessageMetadataMap,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type SubmissionQueueEntry,\n type SubmissionQueueSnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector composables don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `useStream<S, I, C>()` handle pass it in without\n * redeclaring those generics at every 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 composable can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents.value.get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs.value.get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\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/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling scope\n * disappears (and the registry closes the underlying server\n * subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<BaseMessage[]>> {\n const namespace = computed(() => resolveNamespace(toValue(target)));\n if (isRoot(namespace.value)) return stream.messages;\n const key = computed(() => `messages|${namespaceKey(namespace.value)}`);\n return useProjection<BaseMessage[]>(\n getRegistry(stream),\n () => messagesProjection(namespace.value),\n key,\n EMPTY_MESSAGES\n );\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 returns\n * `stream.toolCalls` directly.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<AssembledToolCall[]>> {\n const namespace = computed(() => resolveNamespace(toValue(target)));\n if (isRoot(namespace.value)) return stream.toolCalls;\n const key = computed(() => `toolCalls|${namespaceKey(namespace.value)}`);\n return useProjection<AssembledToolCall[]>(\n getRegistry(stream),\n () => toolCallsProjection(namespace.value),\n key,\n EMPTY_TOOLCALLS\n );\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on `useStream<State>()` — non-nullable (the root snapshot always\n * has values, falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the\n * expected shape explicitly (`useValues<SubagentState>(stream,\n * sub)`). Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Readonly<ShallowRef<StateType>>;\nexport function useValues<T>(\n stream: AnyStream\n): Readonly<ShallowRef<InferStateType<T>>>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): Readonly<ShallowRef<T | undefined>>;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): Readonly<ShallowRef<unknown>> {\n const namespace = resolveNamespace(target);\n if (isRoot(namespace)) return stream.values as Readonly<ShallowRef<unknown>>;\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n return useProjection<unknown>(\n getRegistry(stream),\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\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): Readonly<ShallowRef<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 */\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Readonly<ShallowRef<Event[]>> {\n const namespace = resolveNamespace(target);\n const sortedChannels = [...channels].sort().join(\",\");\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}|${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 * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for an `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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\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 * ```ts\n * const meta = useMessageMetadata(stream, () => msg.id);\n * // meta.value?.parentCheckpointId\n * ```\n *\n * `messageId` accepts a raw string, a `Ref<string | undefined>`, or\n * a getter — the binding re-evaluates whenever the id changes.\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: MaybeRefOrGetter<string | undefined>\n): ComputedRef<MessageMetadata | undefined> {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const mapRef = shallowRef<MessageMetadataMap>(store.getSnapshot());\n const unsubscribe = store.subscribe(() => {\n mapRef.value = store.getSnapshot();\n });\n onScopeDispose(unsubscribe);\n\n return computed<MessageMetadata | undefined>(() => {\n const key = toValue(messageId);\n if (key == null) return undefined;\n return mapRef.value.get(key);\n });\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with\n * `multitaskStrategy: \"enqueue\"` while another run is in flight. The\n * returned refs are shared per call — safe to pass into `v-for`.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: Readonly<ShallowRef<SubmissionQueueSnapshot<StateType>>>;\n readonly size: ComputedRef<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 = shallowRef<SubmissionQueueSnapshot>(store.getSnapshot());\n const unsubscribe = store.subscribe(() => {\n entries.value = store.getSnapshot();\n });\n onScopeDispose(unsubscribe);\n\n return {\n entries: readonly(entries) as Readonly<ShallowRef<SubmissionQueueSnapshot>>,\n size: computed(() => entries.value.length),\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\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":["import {\n computed,\n onScopeDispose,\n readonly,\n shallowRef,\n toValue,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from \"vue\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\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 MessageMetadata,\n type MessageMetadataMap,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type SubmissionQueueEntry,\n type SubmissionQueueSnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector composables don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `useStream<S, I, C>()` handle pass it in without\n * redeclaring those generics at every 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 composable can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents.value.get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs.value.get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\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/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling scope\n * disappears (and the registry closes the underlying server\n * subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<BaseMessage[]>> {\n const namespace = computed(() => resolveNamespace(toValue(target)));\n if (isRoot(namespace.value)) return stream.messages;\n const key = computed(() => `messages|${namespaceKey(namespace.value)}`);\n return useProjection<BaseMessage[]>(\n getRegistry(stream),\n () => messagesProjection(namespace.value),\n key,\n EMPTY_MESSAGES\n );\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 returns\n * `stream.toolCalls` directly.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<AssembledToolCall[]>>;\nexport function useToolCalls<T>(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<InferToolCalls<T>[]>>;\nexport function useToolCalls(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<AssembledToolCall[]>> {\n const namespace = computed(() => resolveNamespace(toValue(target)));\n if (isRoot(namespace.value)) return stream.toolCalls;\n const key = computed(() => `toolCalls|${namespaceKey(namespace.value)}`);\n return useProjection<AssembledToolCall[]>(\n getRegistry(stream),\n () => toolCallsProjection(namespace.value),\n key,\n EMPTY_TOOLCALLS\n );\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on `useStream<State>()` — non-nullable (the root snapshot always\n * has values, falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the\n * expected shape explicitly (`useValues<SubagentState>(stream,\n * sub)`). Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Readonly<ShallowRef<StateType>>;\nexport function useValues<T>(\n stream: AnyStream\n): Readonly<ShallowRef<InferStateType<T>>>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): Readonly<ShallowRef<T | undefined>>;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): Readonly<ShallowRef<unknown>> {\n const namespace = resolveNamespace(target);\n if (isRoot(namespace)) return stream.values as Readonly<ShallowRef<unknown>>;\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n return useProjection<unknown>(\n getRegistry(stream),\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\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): Readonly<ShallowRef<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 */\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Readonly<ShallowRef<Event[]>> {\n const namespace = resolveNamespace(target);\n const sortedChannels = [...channels].sort().join(\",\");\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}|${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 * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for an `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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\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 * ```ts\n * const meta = useMessageMetadata(stream, () => msg.id);\n * // meta.value?.parentCheckpointId\n * ```\n *\n * `messageId` accepts a raw string, a `Ref<string | undefined>`, or\n * a getter — the binding re-evaluates whenever the id changes.\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: MaybeRefOrGetter<string | undefined>\n): ComputedRef<MessageMetadata | undefined> {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const mapRef = shallowRef<MessageMetadataMap>(store.getSnapshot());\n const unsubscribe = store.subscribe(() => {\n mapRef.value = store.getSnapshot();\n });\n onScopeDispose(unsubscribe);\n\n return computed<MessageMetadata | undefined>(() => {\n const key = toValue(messageId);\n if (key == null) return undefined;\n return mapRef.value.get(key);\n });\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with\n * `multitaskStrategy: \"enqueue\"` while another run is in flight. The\n * returned refs are shared per call — safe to pass into `v-for`.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: Readonly<ShallowRef<SubmissionQueueSnapshot<StateType>>>;\n readonly size: ComputedRef<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 = shallowRef<SubmissionQueueSnapshot>(store.getSnapshot());\n const unsubscribe = store.subscribe(() => {\n entries.value = store.getSnapshot();\n });\n onScopeDispose(unsubscribe);\n\n return {\n entries: readonly(entries) as Readonly<ShallowRef<SubmissionQueueSnapshot>>,\n size: computed(() => entries.value.length),\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\n };\n}\n\nexport type { SubmissionQueueEntry, SubmissionQueueSnapshot };\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { AnyStream, UseStreamReturn } from "./use-stream.cjs";
2
2
  import { ComputedRef, MaybeRefOrGetter, ShallowRef } from "vue";
3
3
  import { BaseMessage } from "@langchain/core/messages";
4
- import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, MessageMetadata, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, SubmissionQueueEntry, SubmissionQueueSnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
4
+ import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, InferToolCalls, MessageMetadata, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, SubmissionQueueEntry, SubmissionQueueSnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
5
5
 
6
6
  //#region src/selectors.d.ts
7
7
  /**
@@ -45,6 +45,7 @@ declare function useMessages(stream: AnyStream, target?: MaybeRefOrGetter<Select
45
45
  * `stream.toolCalls` directly.
46
46
  */
47
47
  declare function useToolCalls(stream: AnyStream, target?: MaybeRefOrGetter<SelectorTarget>): Readonly<ShallowRef<AssembledToolCall[]>>;
48
+ declare function useToolCalls<T>(stream: AnyStream, target?: MaybeRefOrGetter<SelectorTarget>): Readonly<ShallowRef<InferToolCalls<T>[]>>;
48
49
  /**
49
50
  * Subscribe to a scoped `values` stream — the most recent state
50
51
  * payload for a namespace. At the root returns `stream.values`.
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.cts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;AA2CyB;;;;KAUpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAgBF;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;AAkCJ;;;;;;;;;;;;;;iBAAgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,WAAA;;;;;;iBAmBP,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,iBAAA;AAHvB;;;;;;;;;;;;;AAAA,iBA8BgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,QAAA,CAAS,UAAA,CAAW,SAAA;AAAA,iBACP,SAAA,GAAA,CACd,MAAA,EAAQ,SAAA,GACP,QAAA,CAAS,UAAA,CAAW,cAAA,CAAe,CAAA;AAAA,iBACtB,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,QAAA,CAAS,UAAA,CAAW,CAAA;;;;AAVvB;iBAgCgB,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,CAAA;;;;;;;KAiBX,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,QAAA,CAAS,UAAA,CAAW,KAAA;;;;;;;;iBAqBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;AAjFvB;;;iBAkGgB,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;;;;iBAiBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;;;;iBAiBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,SAAA;;;;;;AA1IvB;;;;;;;;iBAoKgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,EAAW,gBAAA,uBACV,WAAA,CAAY,eAAA;;;;;;;;UAsBE,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,QAAA,CAAS,UAAA,CAAW,uBAAA,CAAwB,SAAA;EAAA,SACrD,IAAA,EAAM,WAAA;EACf,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":";;;;;;;;AA4CyB;;;;KAUpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAgBF;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;AAkCJ;;;;;;;;;;;;;;iBAAgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,WAAA;;;;;;iBAmBP,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,iBAAA;AAAA,iBACP,YAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,cAAA,CAAe,CAAA;;;;;;;;;;;;;;iBA+BtB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,QAAA,CAAS,UAAA,CAAW,SAAA;AAAA,iBACP,SAAA,GAAA,CACd,MAAA,EAAQ,SAAA,GACP,QAAA,CAAS,UAAA,CAAW,cAAA,CAAe,CAAA;AAAA,iBACtB,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,QAAA,CAAS,UAAA,CAAW,CAAA;;;AA5CvB;;iBAkEgB,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,CAAA;;;;;;;KAiBX,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,QAAA,CAAS,UAAA,CAAW,KAAA;;;;;;;;iBAqBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;;;;iBAiBP,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;AAxGvB;;;;AAAA,iBAyHgB,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;;;;iBAiBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,SAAA;;;;;;;;;;AA7IvB;;;;iBAuKgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,EAAW,gBAAA,uBACV,WAAA,CAAY,eAAA;;;;;;;;UAsBE,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,QAAA,CAAS,UAAA,CAAW,uBAAA,CAAwB,SAAA;EAAA,SACrD,IAAA,EAAM,WAAA;EACf,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,6 +1,6 @@
1
1
  import { AnyStream, UseStreamReturn } from "./use-stream.js";
2
2
  import { ComputedRef, MaybeRefOrGetter, ShallowRef } from "vue";
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
  import { BaseMessage } from "@langchain/core/messages";
5
5
 
6
6
  //#region src/selectors.d.ts
@@ -45,6 +45,7 @@ declare function useMessages(stream: AnyStream, target?: MaybeRefOrGetter<Select
45
45
  * `stream.toolCalls` directly.
46
46
  */
47
47
  declare function useToolCalls(stream: AnyStream, target?: MaybeRefOrGetter<SelectorTarget>): Readonly<ShallowRef<AssembledToolCall[]>>;
48
+ declare function useToolCalls<T>(stream: AnyStream, target?: MaybeRefOrGetter<SelectorTarget>): Readonly<ShallowRef<InferToolCalls<T>[]>>;
48
49
  /**
49
50
  * Subscribe to a scoped `values` stream — the most recent state
50
51
  * payload for a namespace. At the root returns `stream.values`.
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.ts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;AA2CyB;;;;KAUpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAgBF;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;AAkCJ;;;;;;;;;;;;;;iBAAgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,WAAA;;;;;;iBAmBP,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,iBAAA;AAHvB;;;;;;;;;;;;;AAAA,iBA8BgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,QAAA,CAAS,UAAA,CAAW,SAAA;AAAA,iBACP,SAAA,GAAA,CACd,MAAA,EAAQ,SAAA,GACP,QAAA,CAAS,UAAA,CAAW,cAAA,CAAe,CAAA;AAAA,iBACtB,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,QAAA,CAAS,UAAA,CAAW,CAAA;;;;AAVvB;iBAgCgB,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,CAAA;;;;;;;KAiBX,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,QAAA,CAAS,UAAA,CAAW,KAAA;;;;;;;;iBAqBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;AAjFvB;;;iBAkGgB,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;;;;iBAiBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;;;;iBAiBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,SAAA;;;;;;AA1IvB;;;;;;;;iBAoKgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,EAAW,gBAAA,uBACV,WAAA,CAAY,eAAA;;;;;;;;UAsBE,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,QAAA,CAAS,UAAA,CAAW,uBAAA,CAAwB,SAAA;EAAA,SACrD,IAAA,EAAM,WAAA;EACf,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":";;;;;;;;AA4CyB;;;;KAUpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAgBF;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;AAkCJ;;;;;;;;;;;;;;iBAAgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,WAAA;;;;;;iBAmBP,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,iBAAA;AAAA,iBACP,YAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,gBAAA,CAAiB,cAAA,IACzB,QAAA,CAAS,UAAA,CAAW,cAAA,CAAe,CAAA;;;;;;;;;;;;;;iBA+BtB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,QAAA,CAAS,UAAA,CAAW,SAAA;AAAA,iBACP,SAAA,GAAA,CACd,MAAA,EAAQ,SAAA,GACP,QAAA,CAAS,UAAA,CAAW,cAAA,CAAe,CAAA;AAAA,iBACtB,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,QAAA,CAAS,UAAA,CAAW,CAAA;;;AA5CvB;;iBAkEgB,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,CAAA;;;;;;;KAiBX,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,QAAA,CAAS,UAAA,CAAW,KAAA;;;;;;;;iBAqBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;;;;iBAiBP,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;AAxGvB;;;;AAAA,iBAyHgB,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,UAAA;;;;;iBAiBP,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,QAAA,CAAS,UAAA,CAAW,SAAA;;;;;;;;;;AA7IvB;;;;iBAuKgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,EAAW,gBAAA,uBACV,WAAA,CAAY,eAAA;;;;;;;;UAsBE,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,QAAA,CAAS,UAAA,CAAW,uBAAA,CAAwB,SAAA;EAAA,SACrD,IAAA,EAAM,WAAA;EACf,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"}
package/dist/selectors.js CHANGED
@@ -37,11 +37,6 @@ function useMessages(stream, target) {
37
37
  return useProjection(getRegistry(stream), () => messagesProjection(namespace.value), key, EMPTY_MESSAGES);
38
38
  }
39
39
  const EMPTY_MESSAGES = [];
40
- /**
41
- * Subscribe to a scoped `tools` (tool-call) stream. Same target and
42
- * lifecycle rules as {@link useMessages}; at the root this returns
43
- * `stream.toolCalls` directly.
44
- */
45
40
  function useToolCalls(stream, target) {
46
41
  const namespace = computed(() => resolveNamespace(toValue(target)));
47
42
  if (isRoot(namespace.value)) return stream.toolCalls;
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.js","names":[],"sources":["../src/selectors.ts"],"sourcesContent":["import {\n computed,\n onScopeDispose,\n readonly,\n shallowRef,\n toValue,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from \"vue\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\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 MessageMetadata,\n type MessageMetadataMap,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type SubmissionQueueEntry,\n type SubmissionQueueSnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector composables don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `useStream<S, I, C>()` handle pass it in without\n * redeclaring those generics at every 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 composable can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents.value.get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs.value.get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\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/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling scope\n * disappears (and the registry closes the underlying server\n * subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<BaseMessage[]>> {\n const namespace = computed(() => resolveNamespace(toValue(target)));\n if (isRoot(namespace.value)) return stream.messages;\n const key = computed(() => `messages|${namespaceKey(namespace.value)}`);\n return useProjection<BaseMessage[]>(\n getRegistry(stream),\n () => messagesProjection(namespace.value),\n key,\n EMPTY_MESSAGES\n );\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 returns\n * `stream.toolCalls` directly.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<AssembledToolCall[]>> {\n const namespace = computed(() => resolveNamespace(toValue(target)));\n if (isRoot(namespace.value)) return stream.toolCalls;\n const key = computed(() => `toolCalls|${namespaceKey(namespace.value)}`);\n return useProjection<AssembledToolCall[]>(\n getRegistry(stream),\n () => toolCallsProjection(namespace.value),\n key,\n EMPTY_TOOLCALLS\n );\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on `useStream<State>()` — non-nullable (the root snapshot always\n * has values, falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the\n * expected shape explicitly (`useValues<SubagentState>(stream,\n * sub)`). Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Readonly<ShallowRef<StateType>>;\nexport function useValues<T>(\n stream: AnyStream\n): Readonly<ShallowRef<InferStateType<T>>>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): Readonly<ShallowRef<T | undefined>>;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): Readonly<ShallowRef<unknown>> {\n const namespace = resolveNamespace(target);\n if (isRoot(namespace)) return stream.values as Readonly<ShallowRef<unknown>>;\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n return useProjection<unknown>(\n getRegistry(stream),\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\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): Readonly<ShallowRef<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 */\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Readonly<ShallowRef<Event[]>> {\n const namespace = resolveNamespace(target);\n const sortedChannels = [...channels].sort().join(\",\");\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}|${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 * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for an `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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\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 * ```ts\n * const meta = useMessageMetadata(stream, () => msg.id);\n * // meta.value?.parentCheckpointId\n * ```\n *\n * `messageId` accepts a raw string, a `Ref<string | undefined>`, or\n * a getter — the binding re-evaluates whenever the id changes.\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: MaybeRefOrGetter<string | undefined>\n): ComputedRef<MessageMetadata | undefined> {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const mapRef = shallowRef<MessageMetadataMap>(store.getSnapshot());\n const unsubscribe = store.subscribe(() => {\n mapRef.value = store.getSnapshot();\n });\n onScopeDispose(unsubscribe);\n\n return computed<MessageMetadata | undefined>(() => {\n const key = toValue(messageId);\n if (key == null) return undefined;\n return mapRef.value.get(key);\n });\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with\n * `multitaskStrategy: \"enqueue\"` while another run is in flight. The\n * returned refs are shared per call — safe to pass into `v-for`.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: Readonly<ShallowRef<SubmissionQueueSnapshot<StateType>>>;\n readonly size: ComputedRef<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 = shallowRef<SubmissionQueueSnapshot>(store.getSnapshot());\n const unsubscribe = store.subscribe(() => {\n entries.value = store.getSnapshot();\n });\n onScopeDispose(unsubscribe);\n\n return {\n entries: readonly(entries) as Readonly<ShallowRef<SubmissionQueueSnapshot>>,\n size: computed(() => entries.value.length),\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\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":["import {\n computed,\n onScopeDispose,\n readonly,\n shallowRef,\n toValue,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from \"vue\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\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 MessageMetadata,\n type MessageMetadataMap,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type SubmissionQueueEntry,\n type SubmissionQueueSnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector composables don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `useStream<S, I, C>()` handle pass it in without\n * redeclaring those generics at every 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 composable can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents.value.get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs.value.get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\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/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling scope\n * disappears (and the registry closes the underlying server\n * subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<BaseMessage[]>> {\n const namespace = computed(() => resolveNamespace(toValue(target)));\n if (isRoot(namespace.value)) return stream.messages;\n const key = computed(() => `messages|${namespaceKey(namespace.value)}`);\n return useProjection<BaseMessage[]>(\n getRegistry(stream),\n () => messagesProjection(namespace.value),\n key,\n EMPTY_MESSAGES\n );\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 returns\n * `stream.toolCalls` directly.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<AssembledToolCall[]>>;\nexport function useToolCalls<T>(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<InferToolCalls<T>[]>>;\nexport function useToolCalls(\n stream: AnyStream,\n target?: MaybeRefOrGetter<SelectorTarget>\n): Readonly<ShallowRef<AssembledToolCall[]>> {\n const namespace = computed(() => resolveNamespace(toValue(target)));\n if (isRoot(namespace.value)) return stream.toolCalls;\n const key = computed(() => `toolCalls|${namespaceKey(namespace.value)}`);\n return useProjection<AssembledToolCall[]>(\n getRegistry(stream),\n () => toolCallsProjection(namespace.value),\n key,\n EMPTY_TOOLCALLS\n );\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on `useStream<State>()` — non-nullable (the root snapshot always\n * has values, falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the\n * expected shape explicitly (`useValues<SubagentState>(stream,\n * sub)`). Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Readonly<ShallowRef<StateType>>;\nexport function useValues<T>(\n stream: AnyStream\n): Readonly<ShallowRef<InferStateType<T>>>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): Readonly<ShallowRef<T | undefined>>;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): Readonly<ShallowRef<unknown>> {\n const namespace = resolveNamespace(target);\n if (isRoot(namespace)) return stream.values as Readonly<ShallowRef<unknown>>;\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n return useProjection<unknown>(\n getRegistry(stream),\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\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): Readonly<ShallowRef<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 */\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Readonly<ShallowRef<Event[]>> {\n const namespace = resolveNamespace(target);\n const sortedChannels = [...channels].sort().join(\",\");\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}|${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 * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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. Pair with\n * {@link useMediaURL} for an `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): Readonly<ShallowRef<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\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 * ```ts\n * const meta = useMessageMetadata(stream, () => msg.id);\n * // meta.value?.parentCheckpointId\n * ```\n *\n * `messageId` accepts a raw string, a `Ref<string | undefined>`, or\n * a getter — the binding re-evaluates whenever the id changes.\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: MaybeRefOrGetter<string | undefined>\n): ComputedRef<MessageMetadata | undefined> {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const mapRef = shallowRef<MessageMetadataMap>(store.getSnapshot());\n const unsubscribe = store.subscribe(() => {\n mapRef.value = store.getSnapshot();\n });\n onScopeDispose(unsubscribe);\n\n return computed<MessageMetadata | undefined>(() => {\n const key = toValue(messageId);\n if (key == null) return undefined;\n return mapRef.value.get(key);\n });\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with\n * `multitaskStrategy: \"enqueue\"` while another run is in flight. The\n * returned refs are shared per call — safe to pass into `v-for`.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: Readonly<ShallowRef<SubmissionQueueSnapshot<StateType>>>;\n readonly size: ComputedRef<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 = shallowRef<SubmissionQueueSnapshot>(store.getSnapshot());\n const unsubscribe = store.subscribe(() => {\n entries.value = store.getSnapshot();\n });\n onScopeDispose(unsubscribe);\n\n return {\n entries: readonly(entries) as Readonly<ShallowRef<SubmissionQueueSnapshot>>,\n size: computed(() => entries.value.length),\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\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":["LANGCHAIN_OPTIONS","ClientCtor","StreamController"],"sources":["../src/use-stream.ts"],"sourcesContent":["import {\n computed,\n onScopeDispose,\n readonly,\n shallowRef,\n toValue,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from \"vue\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n type AnyHeadlessToolImplementation,\n type OnToolCallback,\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 StateOf as StreamStateOf,\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\";\nimport { inject } from \"vue\";\nimport { LANGCHAIN_OPTIONS } from \"./context.js\";\n\n/** @deprecated Prefer {@link InferStateType}. */\nexport type StateOf<T> = StreamStateOf<T>;\n\ntype VueThreadId = MaybeRefOrGetter<string | null | undefined>;\ntype VueApiString = MaybeRefOrGetter<string | undefined>;\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType, VueThreadId, VueApiString, VueApiString>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType, VueThreadId, string>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<\n StateType,\n VueThreadId,\n VueApiString,\n VueApiString,\n string\n>;\n\n/**\n * Private field on the handle that carries the {@link StreamController}\n * reference. Selector composables read this to reach the shared\n * {@link ChannelRegistry}. Use the selector composables (`useMessages`,\n * `useToolCalls`, `useValues`, …) instead of reading this directly.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/vue/controller\"\n);\n\n/**\n * Vue binding return type for {@link useStream}.\n *\n * Reactive primitives follow Vue conventions:\n *\n * - Data projections are `Readonly<ShallowRef<T>>` / `ComputedRef<T>`\n * so templates auto-unwrap via `msg.value` in `<script setup>`\n * and directly in templates. They are snapshots — never mutate.\n * - Imperative methods (`submit` / `stop` / `respond`) are plain\n * functions — no refs involved.\n * - Identity values captured at setup time (`client` / `assistantId`)\n * are exposed as plain values; if you need to swap the bound agent\n * or client, remount the composable.\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 readonly values: Readonly<ShallowRef<StateType>>;\n readonly messages: Readonly<ShallowRef<BaseMessage[]>>;\n readonly toolCalls: Readonly<ShallowRef<AssembledToolCall[]>>;\n readonly interrupts: Readonly<ShallowRef<Interrupt<InterruptType>[]>>;\n readonly interrupt: ComputedRef<Interrupt<InterruptType> | undefined>;\n readonly isLoading: ComputedRef<boolean>;\n readonly isThreadLoading: ComputedRef<boolean>;\n readonly error: ComputedRef<unknown>;\n readonly threadId: ComputedRef<string | null>;\n\n /**\n * Promise that settles when the active thread's initial hydration\n * completes. Exposed so `async setup()` sites can\n * `await stream.hydrationPromise` to implement a Suspense-like\n * boundary.\n */\n readonly hydrationPromise: ComputedRef<Promise<void>>;\n\n readonly subagents: Readonly<\n ShallowRef<\n ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >\n >\n >;\n readonly subgraphs: Readonly<\n ShallowRef<ReadonlyMap<string, SubgraphDiscoverySnapshot>>\n >;\n readonly subgraphsByNode: Readonly<\n ShallowRef<ReadonlyMap<string, readonly SubgraphDiscoverySnapshot[]>>\n >;\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 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 composables. */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased handle useful as a parameter type for helpers and wrapper\n * components that pass a `stream` through to selector composables\n * without reading `values` directly. Mirrors the React\n * `AnyStream` alias.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/** Convenience alias for the fully-resolved stream handle type. */\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 * Vue Composition API binding for the v2-native stream runtime.\n *\n * Returns a handle whose projections are Vue refs so templates\n * auto-unwrap and scripts can feed them into `computed`/`watch`.\n * Scoped views (subagents, subgraphs, any namespaced projection) are\n * surfaced via the companion selector composables (`useMessages`,\n * `useToolCalls`, `useValues`, `useMessageMetadata`,\n * `useSubmissionQueue`, `useExtension`, `useChannel`, plus media\n * composables).\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useStream } from \"@langchain/vue\";\n *\n * const stream = useStream({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n * </script>\n *\n * <template>\n * <div v-for=\"msg in stream.messages.value\" :key=\"msg.id\">\n * {{ msg.content }}\n * </div>\n * <button @click=\"stream.submit({ messages: [{ type: 'human', content: 'Hi' }] })\">\n * Send\n * </button>\n * </template>\n * ```\n *\n * `assistantId`, `client`, and `transport` are captured at setup time.\n * To bind a new assistant/transport, remount the component. Reactive\n * inputs (`threadId`, `apiUrl`, `apiKey`) trigger in-place behaviour\n * changes on the active controller.\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\n interface OptionsBag {\n assistantId?: string;\n threadId?: MaybeRefOrGetter<string | null | undefined>;\n client?: Client;\n apiUrl?: MaybeRefOrGetter<string | undefined>;\n apiKey?: MaybeRefOrGetter<string | undefined>;\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 tools?: AnyHeadlessToolImplementation[];\n onTool?: OnToolCallback;\n }\n const asBag = options as OptionsBag;\n\n // Inherit missing apiUrl / apiKey / client from any LangChainPlugin\n // installed on the app. Vue's `inject` returns `undefined` if the\n // key was never provided; that's fine — we only merge when the\n // caller didn't set a value.\n const pluginOptions =\n inject(LANGCHAIN_OPTIONS, undefined) ?? ({} as Record<string, unknown>);\n\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n // ─── Client construction ────────────────────────────────────────────\n //\n // Identity-stable per setup. Watches apiUrl/apiKey refs so callers\n // that flip a backend at runtime get a fresh client without a full\n // remount — the controller is swapped in lock-step below.\n const resolveApiUrl = () =>\n toValue(asBag.apiUrl) ?? (pluginOptions as { apiUrl?: string }).apiUrl;\n const resolveApiKey = () =>\n toValue(asBag.apiKey) ?? (pluginOptions as { apiKey?: string }).apiKey;\n const explicitClient =\n asBag.client ?? (pluginOptions as { client?: Client }).client;\n\n const clientRef = shallowRef<Client>(\n explicitClient ??\n (new ClientCtor({\n apiUrl: resolveApiUrl(),\n apiKey: resolveApiKey(),\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client)\n );\n\n // Note: we intentionally bind the controller to the *initial* client\n // instance. A dynamic client swap would require tearing the\n // controller down (in-flight subscriptions, queue, hydration), so we\n // keep the rule simple: client is captured at setup. Mirrors React\n // v1 which bakes `useMemo` on `[client, assistantId, transport]`.\n const client = clientRef.value;\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n const initialThreadId = toValue(asBag.threadId) ?? null;\n\n // ─── Controller construction ────────────────────────────────────────\n const controller = new StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >({\n assistantId,\n client: client as unknown as Client<StateType>,\n threadId: initialThreadId,\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\n // Deferred dispose: on the next microtask after the owning scope\n // disappears. Mirrors React's StrictMode-safe activate/deactivate\n // pattern — HMR and other scope-reuse scenarios stay clean because\n // `activate()` cancels the pending dispose if the scope survives.\n const deactivate = controller.activate();\n onScopeDispose(deactivate);\n\n // ─── Reactivity adapters — StreamStore → shallowRef ─────────────────\n function bindStore<S>(\n subscribe: (listener: () => void) => () => void,\n getSnapshot: () => S\n ): Readonly<ShallowRef<S>> {\n const ref = shallowRef<S>(getSnapshot());\n const unsubscribe = subscribe(() => {\n ref.value = getSnapshot();\n });\n onScopeDispose(unsubscribe);\n return readonly(ref) as Readonly<ShallowRef<S>>;\n }\n\n const rootRef = bindStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot\n );\n const subagentRef = bindStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot\n );\n const subgraphRef = bindStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot\n );\n const subgraphByNodeRef = bindStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n // Derived refs for individual root-snapshot fields. Using computed\n // means templates that read `values.value` only retrigger when the\n // root snapshot's identity actually changes — we can't split further\n // because `StreamStore` fans the whole snapshot out on every update.\n const values = computed(() => rootRef.value.values);\n const messages = computed(() => rootRef.value.messages);\n const toolCalls = computed(() => rootRef.value.toolCalls);\n const interrupts = computed(() =>\n filterOutHeadlessToolInterrupts(rootRef.value.interrupts)\n );\n const interrupt = computed(() => interrupts.value[0]);\n const isLoading = computed(() => rootRef.value.isLoading);\n const isThreadLoading = computed(() => rootRef.value.isThreadLoading);\n const error = computed(() => rootRef.value.error);\n const threadId = computed(() => rootRef.value.threadId);\n const hydrationPromise = computed(() => controller.hydrationPromise);\n\n // Expose the derived refs through a `readonly(shallowRef)` shape to\n // match the rest of the public surface. `computed` already gives us\n // read-only semantics but templates type-check more cleanly when the\n // fully-typed return claims `Readonly<ShallowRef<T>>` everywhere.\n // The cast is safe — a ComputedRef<T> is structurally a\n // Readonly<Ref<T>>.\n const asShallow = <V>(c: ComputedRef<V>): Readonly<ShallowRef<V>> =>\n c as unknown as Readonly<ShallowRef<V>>;\n\n // ─── threadId reactivity ────────────────────────────────────────────\n //\n // Re-hydrate whenever the caller's threadId input changes post-setup.\n // The initial hydrate already fired synchronously in the controller\n // constructor, so we skip that first tick; otherwise we'd double-fetch\n // `thread.state.get()`.\n let skipFirstThreadIdWatch = true;\n watch(\n () => toValue(asBag.threadId) ?? null,\n (next) => {\n if (skipFirstThreadIdWatch) {\n skipFirstThreadIdWatch = false;\n return;\n }\n void controller.hydrate(next);\n }\n );\n\n // ─── Headless-tool handling ─────────────────────────────────────────\n //\n // Watch root values + protocol interrupts for items targeting a\n // registered tool, invoke the handler, and resume the run with the\n // handler's return value. Dedup via an id set so StrictMode /\n // rerenders don't replay a tool call twice.\n const handledTools = new Set<string>();\n watch(\n () => toValue(asBag.threadId) ?? null,\n () => handledTools.clear()\n );\n const tools = options.tools;\n const onTool = options.onTool;\n if (tools?.length) {\n watch(\n () => [rootRef.value.values, rootRef.value.interrupts] as const,\n ([rootValues, rootInterrupts]) => {\n const bag = rootValues as unknown as Record<string, unknown>;\n const existing = Array.isArray(bag?.__interrupt__)\n ? (bag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existing,\n ...(rootInterrupts as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n flushPendingHeadlessToolInterrupts(\n { ...bag, __interrupt__: combined },\n tools,\n handledTools,\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 },\n { immediate: true, flush: \"sync\" }\n );\n }\n\n const handle: UseStreamReturn<T, InterruptType, ConfigurableType> = {\n values: asShallow(values) as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"values\"],\n messages: asShallow(messages),\n toolCalls: asShallow(toolCalls),\n interrupts: asShallow(interrupts),\n interrupt,\n isLoading,\n isThreadLoading,\n error,\n threadId,\n hydrationPromise,\n subagents: subagentRef as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs: subgraphRef,\n subgraphsByNode: subgraphByNodeRef,\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 };\n\n return handle;\n}\n\n/**\n * Helper used by the selector composables to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `useMessages`, `useToolCalls`, etc.\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":["LANGCHAIN_OPTIONS","ClientCtor","StreamController"],"sources":["../src/use-stream.ts"],"sourcesContent":["import {\n computed,\n onScopeDispose,\n readonly,\n shallowRef,\n toValue,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from \"vue\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n type AnyHeadlessToolImplementation,\n type OnToolCallback,\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\";\nimport { inject } from \"vue\";\nimport { LANGCHAIN_OPTIONS } from \"./context.js\";\n\ntype VueThreadId = MaybeRefOrGetter<string | null | undefined>;\ntype VueApiString = MaybeRefOrGetter<string | undefined>;\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType, VueThreadId, VueApiString, VueApiString>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType, VueThreadId, string>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<\n StateType,\n VueThreadId,\n VueApiString,\n VueApiString,\n string\n>;\n\n/**\n * Private field on the handle that carries the {@link StreamController}\n * reference. Selector composables read this to reach the shared\n * {@link ChannelRegistry}. Use the selector composables (`useMessages`,\n * `useToolCalls`, `useValues`, …) instead of reading this directly.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/vue/controller\"\n);\n\n/**\n * Vue binding return type for {@link useStream}.\n *\n * Reactive primitives follow Vue conventions:\n *\n * - Data projections are `Readonly<ShallowRef<T>>` / `ComputedRef<T>`\n * so templates auto-unwrap via `msg.value` in `<script setup>`\n * and directly in templates. They are snapshots — never mutate.\n * - Imperative methods (`submit` / `stop` / `respond`) are plain\n * functions — no refs involved.\n * - Identity values captured at setup time (`client` / `assistantId`)\n * are exposed as plain values; if you need to swap the bound agent\n * or client, remount the composable.\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 readonly values: Readonly<ShallowRef<StateType>>;\n readonly messages: Readonly<ShallowRef<BaseMessage[]>>;\n readonly toolCalls: Readonly<ShallowRef<InferToolCalls<T>[]>>;\n readonly interrupts: Readonly<ShallowRef<Interrupt<InterruptType>[]>>;\n readonly interrupt: ComputedRef<Interrupt<InterruptType> | undefined>;\n readonly isLoading: ComputedRef<boolean>;\n readonly isThreadLoading: ComputedRef<boolean>;\n readonly error: ComputedRef<unknown>;\n readonly threadId: ComputedRef<string | null>;\n\n /**\n * Promise that settles when the active thread's initial hydration\n * completes. Exposed so `async setup()` sites can\n * `await stream.hydrationPromise` to implement a Suspense-like\n * boundary.\n */\n readonly hydrationPromise: ComputedRef<Promise<void>>;\n\n readonly subagents: Readonly<\n ShallowRef<\n ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >\n >\n >;\n readonly subgraphs: Readonly<\n ShallowRef<ReadonlyMap<string, SubgraphDiscoverySnapshot>>\n >;\n readonly subgraphsByNode: Readonly<\n ShallowRef<ReadonlyMap<string, readonly SubgraphDiscoverySnapshot[]>>\n >;\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 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 composables. */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased handle useful as a parameter type for helpers and wrapper\n * components that pass a `stream` through to selector composables\n * without reading `values` directly. Mirrors the React\n * `AnyStream` alias.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/** Convenience alias for the fully-resolved stream handle type. */\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 * Vue Composition API binding for the v2-native stream runtime.\n *\n * Returns a handle whose projections are Vue refs so templates\n * auto-unwrap and scripts can feed them into `computed`/`watch`.\n * Scoped views (subagents, subgraphs, any namespaced projection) are\n * surfaced via the companion selector composables (`useMessages`,\n * `useToolCalls`, `useValues`, `useMessageMetadata`,\n * `useSubmissionQueue`, `useExtension`, `useChannel`, plus media\n * composables).\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useStream } from \"@langchain/vue\";\n *\n * const stream = useStream({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n * </script>\n *\n * <template>\n * <div v-for=\"msg in stream.messages.value\" :key=\"msg.id\">\n * {{ msg.content }}\n * </div>\n * <button @click=\"stream.submit({ messages: [{ type: 'human', content: 'Hi' }] })\">\n * Send\n * </button>\n * </template>\n * ```\n *\n * `assistantId`, `client`, and `transport` are captured at setup time.\n * To bind a new assistant/transport, remount the component. Reactive\n * inputs (`threadId`, `apiUrl`, `apiKey`) trigger in-place behaviour\n * changes on the active controller.\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\n interface OptionsBag {\n assistantId?: string;\n threadId?: MaybeRefOrGetter<string | null | undefined>;\n client?: Client;\n apiUrl?: MaybeRefOrGetter<string | undefined>;\n apiKey?: MaybeRefOrGetter<string | undefined>;\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 tools?: AnyHeadlessToolImplementation[];\n onTool?: OnToolCallback;\n }\n const asBag = options as OptionsBag;\n\n // Inherit missing apiUrl / apiKey / client from any LangChainPlugin\n // installed on the app. Vue's `inject` returns `undefined` if the\n // key was never provided; that's fine — we only merge when the\n // caller didn't set a value.\n const pluginOptions =\n inject(LANGCHAIN_OPTIONS, undefined) ?? ({} as Record<string, unknown>);\n\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n // ─── Client construction ────────────────────────────────────────────\n //\n // Identity-stable per setup. Watches apiUrl/apiKey refs so callers\n // that flip a backend at runtime get a fresh client without a full\n // remount — the controller is swapped in lock-step below.\n const resolveApiUrl = () =>\n toValue(asBag.apiUrl) ?? (pluginOptions as { apiUrl?: string }).apiUrl;\n const resolveApiKey = () =>\n toValue(asBag.apiKey) ?? (pluginOptions as { apiKey?: string }).apiKey;\n const explicitClient =\n asBag.client ?? (pluginOptions as { client?: Client }).client;\n\n const clientRef = shallowRef<Client>(\n explicitClient ??\n (new ClientCtor({\n apiUrl: resolveApiUrl(),\n apiKey: resolveApiKey(),\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client)\n );\n\n // Note: we intentionally bind the controller to the *initial* client\n // instance. A dynamic client swap would require tearing the\n // controller down (in-flight subscriptions, queue, hydration), so we\n // keep the rule simple: client is captured at setup. Mirrors React\n // v1 which bakes `useMemo` on `[client, assistantId, transport]`.\n const client = clientRef.value;\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n const initialThreadId = toValue(asBag.threadId) ?? null;\n\n // ─── Controller construction ────────────────────────────────────────\n const controller = new StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >({\n assistantId,\n client: client as unknown as Client<StateType>,\n threadId: initialThreadId,\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\n // Deferred dispose: on the next microtask after the owning scope\n // disappears. Mirrors React's StrictMode-safe activate/deactivate\n // pattern — HMR and other scope-reuse scenarios stay clean because\n // `activate()` cancels the pending dispose if the scope survives.\n const deactivate = controller.activate();\n onScopeDispose(deactivate);\n\n // ─── Reactivity adapters — StreamStore → shallowRef ─────────────────\n function bindStore<S>(\n subscribe: (listener: () => void) => () => void,\n getSnapshot: () => S\n ): Readonly<ShallowRef<S>> {\n const ref = shallowRef<S>(getSnapshot());\n const unsubscribe = subscribe(() => {\n ref.value = getSnapshot();\n });\n onScopeDispose(unsubscribe);\n return readonly(ref) as Readonly<ShallowRef<S>>;\n }\n\n const rootRef = bindStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot\n );\n const subagentRef = bindStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot\n );\n const subgraphRef = bindStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot\n );\n const subgraphByNodeRef = bindStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n // Derived refs for individual root-snapshot fields. Using computed\n // means templates that read `values.value` only retrigger when the\n // root snapshot's identity actually changes — we can't split further\n // because `StreamStore` fans the whole snapshot out on every update.\n const values = computed(() => rootRef.value.values);\n const messages = computed(() => rootRef.value.messages);\n const toolCalls = computed(\n () => rootRef.value.toolCalls as InferToolCalls<T>[]\n );\n const interrupts = computed(() =>\n filterOutHeadlessToolInterrupts(rootRef.value.interrupts)\n );\n const interrupt = computed(() => interrupts.value[0]);\n const isLoading = computed(() => rootRef.value.isLoading);\n const isThreadLoading = computed(() => rootRef.value.isThreadLoading);\n const error = computed(() => rootRef.value.error);\n const threadId = computed(() => rootRef.value.threadId);\n const hydrationPromise = computed(() => controller.hydrationPromise);\n\n // Expose the derived refs through a `readonly(shallowRef)` shape to\n // match the rest of the public surface. `computed` already gives us\n // read-only semantics but templates type-check more cleanly when the\n // fully-typed return claims `Readonly<ShallowRef<T>>` everywhere.\n // The cast is safe — a ComputedRef<T> is structurally a\n // Readonly<Ref<T>>.\n const asShallow = <V>(c: ComputedRef<V>): Readonly<ShallowRef<V>> =>\n c as unknown as Readonly<ShallowRef<V>>;\n\n // ─── threadId reactivity ────────────────────────────────────────────\n //\n // Re-hydrate whenever the caller's threadId input changes post-setup.\n // The initial hydrate already fired synchronously in the controller\n // constructor, so we skip that first tick; otherwise we'd double-fetch\n // `thread.state.get()`.\n let skipFirstThreadIdWatch = true;\n watch(\n () => toValue(asBag.threadId) ?? null,\n (next) => {\n if (skipFirstThreadIdWatch) {\n skipFirstThreadIdWatch = false;\n return;\n }\n void controller.hydrate(next);\n }\n );\n\n // ─── Headless-tool handling ─────────────────────────────────────────\n //\n // Watch root values + protocol interrupts for items targeting a\n // registered tool, invoke the handler, and resume the run with the\n // handler's return value. Dedup via an id set so StrictMode /\n // rerenders don't replay a tool call twice.\n const handledTools = new Set<string>();\n watch(\n () => toValue(asBag.threadId) ?? null,\n () => handledTools.clear()\n );\n const tools = options.tools;\n const onTool = options.onTool;\n if (tools?.length) {\n watch(\n () => [rootRef.value.values, rootRef.value.interrupts] as const,\n ([rootValues, rootInterrupts]) => {\n const bag = rootValues as unknown as Record<string, unknown>;\n const existing = Array.isArray(bag?.__interrupt__)\n ? (bag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existing,\n ...(rootInterrupts as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n flushPendingHeadlessToolInterrupts(\n { ...bag, __interrupt__: combined },\n tools,\n handledTools,\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 },\n { immediate: true, flush: \"sync\" }\n );\n }\n\n const handle: UseStreamReturn<T, InterruptType, ConfigurableType> = {\n values: asShallow(values) as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"values\"],\n messages: asShallow(messages),\n toolCalls: asShallow(toolCalls),\n interrupts: asShallow(interrupts),\n interrupt,\n isLoading,\n isThreadLoading,\n error,\n threadId,\n hydrationPromise,\n subagents: subagentRef as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs: subgraphRef,\n subgraphsByNode: subgraphByNodeRef,\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 };\n\n return handle;\n}\n\n/**\n * Helper used by the selector composables to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `useMessages`, `useToolCalls`, etc.\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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"}
@@ -2,11 +2,9 @@ import { ComputedRef, MaybeRefOrGetter, ShallowRef } from "vue";
2
2
  import { BaseMessage } from "@langchain/core/messages";
3
3
  import { Client, Interrupt } from "@langchain/langgraph-sdk";
4
4
  import { ThreadStream } from "@langchain/langgraph-sdk/client";
5
- import { AgentServerOptions, AssembledToolCall, ChannelRegistry, CustomAdapterOptions, InferStateType, InferSubagentStates, StateOf, StreamController, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, UseStreamOptions, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
5
+ import { AgentServerOptions, ChannelRegistry, CustomAdapterOptions, InferStateType, InferSubagentStates, InferToolCalls, StreamController, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, UseStreamOptions, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
6
6
 
7
7
  //#region src/use-stream.d.ts
8
- /** @deprecated Prefer {@link InferStateType}. */
9
- type StateOf$1<T> = StateOf<T>;
10
8
  type VueThreadId = MaybeRefOrGetter<string | null | undefined>;
11
9
  type VueApiString = MaybeRefOrGetter<string | undefined>;
12
10
  type AgentServerOptions$1<StateType extends object> = AgentServerOptions<StateType, VueThreadId, VueApiString, VueApiString>;
@@ -36,7 +34,7 @@ declare const STREAM_CONTROLLER: unique symbol;
36
34
  interface UseStreamReturn<T = Record<string, unknown>, InterruptType = unknown, ConfigurableType extends object = Record<string, unknown>, StateType extends object = InferStateType<T>, SubagentStates = InferSubagentStates<T>> {
37
35
  readonly values: Readonly<ShallowRef<StateType>>;
38
36
  readonly messages: Readonly<ShallowRef<BaseMessage[]>>;
39
- readonly toolCalls: Readonly<ShallowRef<AssembledToolCall[]>>;
37
+ readonly toolCalls: Readonly<ShallowRef<InferToolCalls<T>[]>>;
40
38
  readonly interrupts: Readonly<ShallowRef<Interrupt<InterruptType>[]>>;
41
39
  readonly interrupt: ComputedRef<Interrupt<InterruptType> | undefined>;
42
40
  readonly isLoading: ComputedRef<boolean>;
@@ -114,5 +112,5 @@ type UseStreamResult<T = Record<string, unknown>, InterruptType = unknown, Confi
114
112
  */
115
113
  declare function useStream<T = Record<string, unknown>, InterruptType = unknown, ConfigurableType extends object = Record<string, unknown>>(options: UseStreamOptions$1<InferStateType<T>>): UseStreamReturn<T, InterruptType, ConfigurableType>;
116
114
  //#endregion
117
- export { AgentServerOptions$1 as AgentServerOptions, AnyStream, CustomAdapterOptions$1 as CustomAdapterOptions, STREAM_CONTROLLER, StateOf$1 as StateOf, type ThreadStream, UseStreamOptions$1 as UseStreamOptions, UseStreamResult, UseStreamReturn, useStream };
115
+ export { AgentServerOptions$1 as AgentServerOptions, AnyStream, CustomAdapterOptions$1 as CustomAdapterOptions, STREAM_CONTROLLER, type ThreadStream, UseStreamOptions$1 as UseStreamOptions, UseStreamResult, UseStreamReturn, useStream };
118
116
  //# sourceMappingURL=use-stream.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-stream.d.cts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;;;KAgDY,SAAA,MAAa,OAAA,CAAc,CAAA;AAAA,KAElC,WAAA,GAAc,gBAAA;AAAA,KACd,YAAA,GAAe,gBAAA;AAAA,KAER,oBAAA,6BACV,kBAAA,CAAyB,SAAA,EAAW,WAAA,EAAa,YAAA,EAAc,YAAA;AAAA,KAErD,sBAAA,6BACV,oBAAA,CAA2B,SAAA,EAAW,WAAA;AAAA,KAE5B,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CACF,SAAA,EACA,WAAA,EACA,YAAA,EACA,YAAA;;;;;AAjBwC;;cA2B7B,iBAAA;;;AAzBsB;;;;;AAGnC;;;;;;;UAwCiB,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EAAA,SAE5B,MAAA,EAAQ,QAAA,CAAS,UAAA,CAAW,SAAA;EAAA,SAC5B,QAAA,EAAU,QAAA,CAAS,UAAA,CAAW,WAAA;EAAA,SAC9B,SAAA,EAAW,QAAA,CAAS,UAAA,CAAW,iBAAA;EAAA,SAC/B,UAAA,EAAY,QAAA,CAAS,UAAA,CAAW,SAAA,CAAU,aAAA;EAAA,SAC1C,SAAA,EAAW,WAAA,CAAY,SAAA,CAAU,aAAA;EAAA,SACjC,SAAA,EAAW,WAAA;EAAA,SACX,eAAA,EAAiB,WAAA;EAAA,SACjB,KAAA,EAAO,WAAA;EAAA,SACP,QAAA,EAAU,WAAA;EAtDwD;AAE7E;;;;;EAF6E,SA8DlE,gBAAA,EAAkB,WAAA,CAAY,OAAA;EAAA,SAE9B,SAAA,EAAW,QAAA,CAClB,UAAA,CACE,WAAA,OACQ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAAA,SAIG,SAAA,EAAW,QAAA,CAClB,UAAA,CAAW,WAAA,SAAoB,yBAAA;EAAA,SAExB,eAAA,EAAiB,QAAA,CACxB,UAAA,CAAW,WAAA,kBAA6B,yBAAA;EAG1C,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,SAEM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;EAtFkB;EAyF3B,SAAA,IAAa,YAAA;EAtFb;EAAA,UAyFU,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;;KAWQ,SAAA,GAAY,eAAA;;KAGZ,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;AAlGtC;;;;;AAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuHgB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,KACxC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA"}
1
+ {"version":3,"file":"use-stream.d.cts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;;KAgDK,WAAA,GAAc,gBAAA;AAAA,KACd,YAAA,GAAe,gBAAA;AAAA,KAER,oBAAA,6BACV,kBAAA,CAAyB,SAAA,EAAW,WAAA,EAAa,YAAA,EAAc,YAAA;AAAA,KAErD,sBAAA,6BACV,oBAAA,CAA2B,SAAA,EAAW,WAAA;AAAA,KAE5B,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CACF,SAAA,EACA,WAAA,EACA,YAAA,EACA,YAAA;;;AAfiC;;;;cAyBtB,iBAAA;AAtBb;;;;;;;;;;;;;;AAAA,UAwCiB,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EAAA,SAE5B,MAAA,EAAQ,QAAA,CAAS,UAAA,CAAW,SAAA;EAAA,SAC5B,QAAA,EAAU,QAAA,CAAS,UAAA,CAAW,WAAA;EAAA,SAC9B,SAAA,EAAW,QAAA,CAAS,UAAA,CAAW,cAAA,CAAe,CAAA;EAAA,SAC9C,UAAA,EAAY,QAAA,CAAS,UAAA,CAAW,SAAA,CAAU,aAAA;EAAA,SAC1C,SAAA,EAAW,WAAA,CAAY,SAAA,CAAU,aAAA;EAAA,SACjC,SAAA,EAAW,WAAA;EAAA,SACX,eAAA,EAAiB,WAAA;EAAA,SACjB,KAAA,EAAO,WAAA;EAAA,SACP,QAAA,EAAU,WAAA;EAnDO;;;;;;EAAA,SA2DjB,gBAAA,EAAkB,WAAA,CAAY,OAAA;EAAA,SAE9B,SAAA,EAAW,QAAA,CAClB,UAAA,CACE,WAAA,OACQ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAAA,SAIG,SAAA,EAAW,QAAA,CAClB,UAAA,CAAW,WAAA,SAAoB,yBAAA;EAAA,SAExB,eAAA,EAAiB,QAAA,CACxB,UAAA,CAAW,WAAA,kBAA6B,yBAAA;EAG1C,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,SAEM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;EArFe;EAwFxB,SAAA,IAAa,YAAA;EAzFc;EAAA,UA4FjB,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;AAhFJ;KA2FY,SAAA,GAAY,eAAA;;KAGZ,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;AAhFtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuHgB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,KACxC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA"}
@@ -1,12 +1,10 @@
1
1
  import { ComputedRef, MaybeRefOrGetter, ShallowRef } from "vue";
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, StateOf, 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
  import { BaseMessage } from "@langchain/core/messages";
6
6
 
7
7
  //#region src/use-stream.d.ts
8
- /** @deprecated Prefer {@link InferStateType}. */
9
- type StateOf$1<T> = StateOf<T>;
10
8
  type VueThreadId = MaybeRefOrGetter<string | null | undefined>;
11
9
  type VueApiString = MaybeRefOrGetter<string | undefined>;
12
10
  type AgentServerOptions$1<StateType extends object> = AgentServerOptions<StateType, VueThreadId, VueApiString, VueApiString>;
@@ -36,7 +34,7 @@ declare const STREAM_CONTROLLER: unique symbol;
36
34
  interface UseStreamReturn<T = Record<string, unknown>, InterruptType = unknown, ConfigurableType extends object = Record<string, unknown>, StateType extends object = InferStateType<T>, SubagentStates = InferSubagentStates<T>> {
37
35
  readonly values: Readonly<ShallowRef<StateType>>;
38
36
  readonly messages: Readonly<ShallowRef<BaseMessage[]>>;
39
- readonly toolCalls: Readonly<ShallowRef<AssembledToolCall[]>>;
37
+ readonly toolCalls: Readonly<ShallowRef<InferToolCalls<T>[]>>;
40
38
  readonly interrupts: Readonly<ShallowRef<Interrupt<InterruptType>[]>>;
41
39
  readonly interrupt: ComputedRef<Interrupt<InterruptType> | undefined>;
42
40
  readonly isLoading: ComputedRef<boolean>;
@@ -114,5 +112,5 @@ type UseStreamResult<T = Record<string, unknown>, InterruptType = unknown, Confi
114
112
  */
115
113
  declare function useStream<T = Record<string, unknown>, InterruptType = unknown, ConfigurableType extends object = Record<string, unknown>>(options: UseStreamOptions$1<InferStateType<T>>): UseStreamReturn<T, InterruptType, ConfigurableType>;
116
114
  //#endregion
117
- export { AgentServerOptions$1 as AgentServerOptions, AnyStream, CustomAdapterOptions$1 as CustomAdapterOptions, STREAM_CONTROLLER, StateOf$1 as StateOf, type ThreadStream, UseStreamOptions$1 as UseStreamOptions, UseStreamResult, UseStreamReturn, useStream };
115
+ export { AgentServerOptions$1 as AgentServerOptions, AnyStream, CustomAdapterOptions$1 as CustomAdapterOptions, STREAM_CONTROLLER, type ThreadStream, UseStreamOptions$1 as UseStreamOptions, UseStreamResult, UseStreamReturn, useStream };
118
116
  //# sourceMappingURL=use-stream.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-stream.d.ts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;;;KAgDY,SAAA,MAAa,OAAA,CAAc,CAAA;AAAA,KAElC,WAAA,GAAc,gBAAA;AAAA,KACd,YAAA,GAAe,gBAAA;AAAA,KAER,oBAAA,6BACV,kBAAA,CAAyB,SAAA,EAAW,WAAA,EAAa,YAAA,EAAc,YAAA;AAAA,KAErD,sBAAA,6BACV,oBAAA,CAA2B,SAAA,EAAW,WAAA;AAAA,KAE5B,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CACF,SAAA,EACA,WAAA,EACA,YAAA,EACA,YAAA;;;;;AAjBwC;;cA2B7B,iBAAA;;;AAzBsB;;;;;AAGnC;;;;;;;UAwCiB,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EAAA,SAE5B,MAAA,EAAQ,QAAA,CAAS,UAAA,CAAW,SAAA;EAAA,SAC5B,QAAA,EAAU,QAAA,CAAS,UAAA,CAAW,WAAA;EAAA,SAC9B,SAAA,EAAW,QAAA,CAAS,UAAA,CAAW,iBAAA;EAAA,SAC/B,UAAA,EAAY,QAAA,CAAS,UAAA,CAAW,SAAA,CAAU,aAAA;EAAA,SAC1C,SAAA,EAAW,WAAA,CAAY,SAAA,CAAU,aAAA;EAAA,SACjC,SAAA,EAAW,WAAA;EAAA,SACX,eAAA,EAAiB,WAAA;EAAA,SACjB,KAAA,EAAO,WAAA;EAAA,SACP,QAAA,EAAU,WAAA;EAtDwD;AAE7E;;;;;EAF6E,SA8DlE,gBAAA,EAAkB,WAAA,CAAY,OAAA;EAAA,SAE9B,SAAA,EAAW,QAAA,CAClB,UAAA,CACE,WAAA,OACQ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAAA,SAIG,SAAA,EAAW,QAAA,CAClB,UAAA,CAAW,WAAA,SAAoB,yBAAA;EAAA,SAExB,eAAA,EAAiB,QAAA,CACxB,UAAA,CAAW,WAAA,kBAA6B,yBAAA;EAG1C,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,SAEM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;EAtFkB;EAyF3B,SAAA,IAAa,YAAA;EAtFb;EAAA,UAyFU,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;;KAWQ,SAAA,GAAY,eAAA;;KAGZ,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;AAlGtC;;;;;AAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuHgB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,KACxC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA"}
1
+ {"version":3,"file":"use-stream.d.ts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;;KAgDK,WAAA,GAAc,gBAAA;AAAA,KACd,YAAA,GAAe,gBAAA;AAAA,KAER,oBAAA,6BACV,kBAAA,CAAyB,SAAA,EAAW,WAAA,EAAa,YAAA,EAAc,YAAA;AAAA,KAErD,sBAAA,6BACV,oBAAA,CAA2B,SAAA,EAAW,WAAA;AAAA,KAE5B,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CACF,SAAA,EACA,WAAA,EACA,YAAA,EACA,YAAA;;;AAfiC;;;;cAyBtB,iBAAA;AAtBb;;;;;;;;;;;;;;AAAA,UAwCiB,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EAAA,SAE5B,MAAA,EAAQ,QAAA,CAAS,UAAA,CAAW,SAAA;EAAA,SAC5B,QAAA,EAAU,QAAA,CAAS,UAAA,CAAW,WAAA;EAAA,SAC9B,SAAA,EAAW,QAAA,CAAS,UAAA,CAAW,cAAA,CAAe,CAAA;EAAA,SAC9C,UAAA,EAAY,QAAA,CAAS,UAAA,CAAW,SAAA,CAAU,aAAA;EAAA,SAC1C,SAAA,EAAW,WAAA,CAAY,SAAA,CAAU,aAAA;EAAA,SACjC,SAAA,EAAW,WAAA;EAAA,SACX,eAAA,EAAiB,WAAA;EAAA,SACjB,KAAA,EAAO,WAAA;EAAA,SACP,QAAA,EAAU,WAAA;EAnDO;;;;;;EAAA,SA2DjB,gBAAA,EAAkB,WAAA,CAAY,OAAA;EAAA,SAE9B,SAAA,EAAW,QAAA,CAClB,UAAA,CACE,WAAA,OACQ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAAA,SAIG,SAAA,EAAW,QAAA,CAClB,UAAA,CAAW,WAAA,SAAoB,yBAAA;EAAA,SAExB,eAAA,EAAiB,QAAA,CACxB,UAAA,CAAW,WAAA,kBAA6B,yBAAA;EAG1C,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,SAEM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;EArFe;EAwFxB,SAAA,IAAa,YAAA;EAzFc;EAAA,UA4FjB,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;AAhFJ;KA2FY,SAAA,GAAY,eAAA;;KAGZ,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;AAhFtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuHgB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,KACxC,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":["import {\n computed,\n onScopeDispose,\n readonly,\n shallowRef,\n toValue,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from \"vue\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n type AnyHeadlessToolImplementation,\n type OnToolCallback,\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 StateOf as StreamStateOf,\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\";\nimport { inject } from \"vue\";\nimport { LANGCHAIN_OPTIONS } from \"./context.js\";\n\n/** @deprecated Prefer {@link InferStateType}. */\nexport type StateOf<T> = StreamStateOf<T>;\n\ntype VueThreadId = MaybeRefOrGetter<string | null | undefined>;\ntype VueApiString = MaybeRefOrGetter<string | undefined>;\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType, VueThreadId, VueApiString, VueApiString>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType, VueThreadId, string>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<\n StateType,\n VueThreadId,\n VueApiString,\n VueApiString,\n string\n>;\n\n/**\n * Private field on the handle that carries the {@link StreamController}\n * reference. Selector composables read this to reach the shared\n * {@link ChannelRegistry}. Use the selector composables (`useMessages`,\n * `useToolCalls`, `useValues`, …) instead of reading this directly.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/vue/controller\"\n);\n\n/**\n * Vue binding return type for {@link useStream}.\n *\n * Reactive primitives follow Vue conventions:\n *\n * - Data projections are `Readonly<ShallowRef<T>>` / `ComputedRef<T>`\n * so templates auto-unwrap via `msg.value` in `<script setup>`\n * and directly in templates. They are snapshots — never mutate.\n * - Imperative methods (`submit` / `stop` / `respond`) are plain\n * functions — no refs involved.\n * - Identity values captured at setup time (`client` / `assistantId`)\n * are exposed as plain values; if you need to swap the bound agent\n * or client, remount the composable.\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 readonly values: Readonly<ShallowRef<StateType>>;\n readonly messages: Readonly<ShallowRef<BaseMessage[]>>;\n readonly toolCalls: Readonly<ShallowRef<AssembledToolCall[]>>;\n readonly interrupts: Readonly<ShallowRef<Interrupt<InterruptType>[]>>;\n readonly interrupt: ComputedRef<Interrupt<InterruptType> | undefined>;\n readonly isLoading: ComputedRef<boolean>;\n readonly isThreadLoading: ComputedRef<boolean>;\n readonly error: ComputedRef<unknown>;\n readonly threadId: ComputedRef<string | null>;\n\n /**\n * Promise that settles when the active thread's initial hydration\n * completes. Exposed so `async setup()` sites can\n * `await stream.hydrationPromise` to implement a Suspense-like\n * boundary.\n */\n readonly hydrationPromise: ComputedRef<Promise<void>>;\n\n readonly subagents: Readonly<\n ShallowRef<\n ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >\n >\n >;\n readonly subgraphs: Readonly<\n ShallowRef<ReadonlyMap<string, SubgraphDiscoverySnapshot>>\n >;\n readonly subgraphsByNode: Readonly<\n ShallowRef<ReadonlyMap<string, readonly SubgraphDiscoverySnapshot[]>>\n >;\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 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 composables. */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased handle useful as a parameter type for helpers and wrapper\n * components that pass a `stream` through to selector composables\n * without reading `values` directly. Mirrors the React\n * `AnyStream` alias.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/** Convenience alias for the fully-resolved stream handle type. */\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 * Vue Composition API binding for the v2-native stream runtime.\n *\n * Returns a handle whose projections are Vue refs so templates\n * auto-unwrap and scripts can feed them into `computed`/`watch`.\n * Scoped views (subagents, subgraphs, any namespaced projection) are\n * surfaced via the companion selector composables (`useMessages`,\n * `useToolCalls`, `useValues`, `useMessageMetadata`,\n * `useSubmissionQueue`, `useExtension`, `useChannel`, plus media\n * composables).\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useStream } from \"@langchain/vue\";\n *\n * const stream = useStream({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n * </script>\n *\n * <template>\n * <div v-for=\"msg in stream.messages.value\" :key=\"msg.id\">\n * {{ msg.content }}\n * </div>\n * <button @click=\"stream.submit({ messages: [{ type: 'human', content: 'Hi' }] })\">\n * Send\n * </button>\n * </template>\n * ```\n *\n * `assistantId`, `client`, and `transport` are captured at setup time.\n * To bind a new assistant/transport, remount the component. Reactive\n * inputs (`threadId`, `apiUrl`, `apiKey`) trigger in-place behaviour\n * changes on the active controller.\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\n interface OptionsBag {\n assistantId?: string;\n threadId?: MaybeRefOrGetter<string | null | undefined>;\n client?: Client;\n apiUrl?: MaybeRefOrGetter<string | undefined>;\n apiKey?: MaybeRefOrGetter<string | undefined>;\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 tools?: AnyHeadlessToolImplementation[];\n onTool?: OnToolCallback;\n }\n const asBag = options as OptionsBag;\n\n // Inherit missing apiUrl / apiKey / client from any LangChainPlugin\n // installed on the app. Vue's `inject` returns `undefined` if the\n // key was never provided; that's fine — we only merge when the\n // caller didn't set a value.\n const pluginOptions =\n inject(LANGCHAIN_OPTIONS, undefined) ?? ({} as Record<string, unknown>);\n\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n // ─── Client construction ────────────────────────────────────────────\n //\n // Identity-stable per setup. Watches apiUrl/apiKey refs so callers\n // that flip a backend at runtime get a fresh client without a full\n // remount — the controller is swapped in lock-step below.\n const resolveApiUrl = () =>\n toValue(asBag.apiUrl) ?? (pluginOptions as { apiUrl?: string }).apiUrl;\n const resolveApiKey = () =>\n toValue(asBag.apiKey) ?? (pluginOptions as { apiKey?: string }).apiKey;\n const explicitClient =\n asBag.client ?? (pluginOptions as { client?: Client }).client;\n\n const clientRef = shallowRef<Client>(\n explicitClient ??\n (new ClientCtor({\n apiUrl: resolveApiUrl(),\n apiKey: resolveApiKey(),\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client)\n );\n\n // Note: we intentionally bind the controller to the *initial* client\n // instance. A dynamic client swap would require tearing the\n // controller down (in-flight subscriptions, queue, hydration), so we\n // keep the rule simple: client is captured at setup. Mirrors React\n // v1 which bakes `useMemo` on `[client, assistantId, transport]`.\n const client = clientRef.value;\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n const initialThreadId = toValue(asBag.threadId) ?? null;\n\n // ─── Controller construction ────────────────────────────────────────\n const controller = new StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >({\n assistantId,\n client: client as unknown as Client<StateType>,\n threadId: initialThreadId,\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\n // Deferred dispose: on the next microtask after the owning scope\n // disappears. Mirrors React's StrictMode-safe activate/deactivate\n // pattern — HMR and other scope-reuse scenarios stay clean because\n // `activate()` cancels the pending dispose if the scope survives.\n const deactivate = controller.activate();\n onScopeDispose(deactivate);\n\n // ─── Reactivity adapters — StreamStore → shallowRef ─────────────────\n function bindStore<S>(\n subscribe: (listener: () => void) => () => void,\n getSnapshot: () => S\n ): Readonly<ShallowRef<S>> {\n const ref = shallowRef<S>(getSnapshot());\n const unsubscribe = subscribe(() => {\n ref.value = getSnapshot();\n });\n onScopeDispose(unsubscribe);\n return readonly(ref) as Readonly<ShallowRef<S>>;\n }\n\n const rootRef = bindStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot\n );\n const subagentRef = bindStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot\n );\n const subgraphRef = bindStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot\n );\n const subgraphByNodeRef = bindStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n // Derived refs for individual root-snapshot fields. Using computed\n // means templates that read `values.value` only retrigger when the\n // root snapshot's identity actually changes — we can't split further\n // because `StreamStore` fans the whole snapshot out on every update.\n const values = computed(() => rootRef.value.values);\n const messages = computed(() => rootRef.value.messages);\n const toolCalls = computed(() => rootRef.value.toolCalls);\n const interrupts = computed(() =>\n filterOutHeadlessToolInterrupts(rootRef.value.interrupts)\n );\n const interrupt = computed(() => interrupts.value[0]);\n const isLoading = computed(() => rootRef.value.isLoading);\n const isThreadLoading = computed(() => rootRef.value.isThreadLoading);\n const error = computed(() => rootRef.value.error);\n const threadId = computed(() => rootRef.value.threadId);\n const hydrationPromise = computed(() => controller.hydrationPromise);\n\n // Expose the derived refs through a `readonly(shallowRef)` shape to\n // match the rest of the public surface. `computed` already gives us\n // read-only semantics but templates type-check more cleanly when the\n // fully-typed return claims `Readonly<ShallowRef<T>>` everywhere.\n // The cast is safe — a ComputedRef<T> is structurally a\n // Readonly<Ref<T>>.\n const asShallow = <V>(c: ComputedRef<V>): Readonly<ShallowRef<V>> =>\n c as unknown as Readonly<ShallowRef<V>>;\n\n // ─── threadId reactivity ────────────────────────────────────────────\n //\n // Re-hydrate whenever the caller's threadId input changes post-setup.\n // The initial hydrate already fired synchronously in the controller\n // constructor, so we skip that first tick; otherwise we'd double-fetch\n // `thread.state.get()`.\n let skipFirstThreadIdWatch = true;\n watch(\n () => toValue(asBag.threadId) ?? null,\n (next) => {\n if (skipFirstThreadIdWatch) {\n skipFirstThreadIdWatch = false;\n return;\n }\n void controller.hydrate(next);\n }\n );\n\n // ─── Headless-tool handling ─────────────────────────────────────────\n //\n // Watch root values + protocol interrupts for items targeting a\n // registered tool, invoke the handler, and resume the run with the\n // handler's return value. Dedup via an id set so StrictMode /\n // rerenders don't replay a tool call twice.\n const handledTools = new Set<string>();\n watch(\n () => toValue(asBag.threadId) ?? null,\n () => handledTools.clear()\n );\n const tools = options.tools;\n const onTool = options.onTool;\n if (tools?.length) {\n watch(\n () => [rootRef.value.values, rootRef.value.interrupts] as const,\n ([rootValues, rootInterrupts]) => {\n const bag = rootValues as unknown as Record<string, unknown>;\n const existing = Array.isArray(bag?.__interrupt__)\n ? (bag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existing,\n ...(rootInterrupts as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n flushPendingHeadlessToolInterrupts(\n { ...bag, __interrupt__: combined },\n tools,\n handledTools,\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 },\n { immediate: true, flush: \"sync\" }\n );\n }\n\n const handle: UseStreamReturn<T, InterruptType, ConfigurableType> = {\n values: asShallow(values) as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"values\"],\n messages: asShallow(messages),\n toolCalls: asShallow(toolCalls),\n interrupts: asShallow(interrupts),\n interrupt,\n isLoading,\n isThreadLoading,\n error,\n threadId,\n hydrationPromise,\n subagents: subagentRef as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs: subgraphRef,\n subgraphsByNode: subgraphByNodeRef,\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 };\n\n return handle;\n}\n\n/**\n * Helper used by the selector composables to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `useMessages`, `useToolCalls`, etc.\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":["import {\n computed,\n onScopeDispose,\n readonly,\n shallowRef,\n toValue,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from \"vue\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n type AnyHeadlessToolImplementation,\n type OnToolCallback,\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\";\nimport { inject } from \"vue\";\nimport { LANGCHAIN_OPTIONS } from \"./context.js\";\n\ntype VueThreadId = MaybeRefOrGetter<string | null | undefined>;\ntype VueApiString = MaybeRefOrGetter<string | undefined>;\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType, VueThreadId, VueApiString, VueApiString>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType, VueThreadId, string>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<\n StateType,\n VueThreadId,\n VueApiString,\n VueApiString,\n string\n>;\n\n/**\n * Private field on the handle that carries the {@link StreamController}\n * reference. Selector composables read this to reach the shared\n * {@link ChannelRegistry}. Use the selector composables (`useMessages`,\n * `useToolCalls`, `useValues`, …) instead of reading this directly.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/vue/controller\"\n);\n\n/**\n * Vue binding return type for {@link useStream}.\n *\n * Reactive primitives follow Vue conventions:\n *\n * - Data projections are `Readonly<ShallowRef<T>>` / `ComputedRef<T>`\n * so templates auto-unwrap via `msg.value` in `<script setup>`\n * and directly in templates. They are snapshots — never mutate.\n * - Imperative methods (`submit` / `stop` / `respond`) are plain\n * functions — no refs involved.\n * - Identity values captured at setup time (`client` / `assistantId`)\n * are exposed as plain values; if you need to swap the bound agent\n * or client, remount the composable.\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 readonly values: Readonly<ShallowRef<StateType>>;\n readonly messages: Readonly<ShallowRef<BaseMessage[]>>;\n readonly toolCalls: Readonly<ShallowRef<InferToolCalls<T>[]>>;\n readonly interrupts: Readonly<ShallowRef<Interrupt<InterruptType>[]>>;\n readonly interrupt: ComputedRef<Interrupt<InterruptType> | undefined>;\n readonly isLoading: ComputedRef<boolean>;\n readonly isThreadLoading: ComputedRef<boolean>;\n readonly error: ComputedRef<unknown>;\n readonly threadId: ComputedRef<string | null>;\n\n /**\n * Promise that settles when the active thread's initial hydration\n * completes. Exposed so `async setup()` sites can\n * `await stream.hydrationPromise` to implement a Suspense-like\n * boundary.\n */\n readonly hydrationPromise: ComputedRef<Promise<void>>;\n\n readonly subagents: Readonly<\n ShallowRef<\n ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >\n >\n >;\n readonly subgraphs: Readonly<\n ShallowRef<ReadonlyMap<string, SubgraphDiscoverySnapshot>>\n >;\n readonly subgraphsByNode: Readonly<\n ShallowRef<ReadonlyMap<string, readonly SubgraphDiscoverySnapshot[]>>\n >;\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 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 composables. */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased handle useful as a parameter type for helpers and wrapper\n * components that pass a `stream` through to selector composables\n * without reading `values` directly. Mirrors the React\n * `AnyStream` alias.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/** Convenience alias for the fully-resolved stream handle type. */\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 * Vue Composition API binding for the v2-native stream runtime.\n *\n * Returns a handle whose projections are Vue refs so templates\n * auto-unwrap and scripts can feed them into `computed`/`watch`.\n * Scoped views (subagents, subgraphs, any namespaced projection) are\n * surfaced via the companion selector composables (`useMessages`,\n * `useToolCalls`, `useValues`, `useMessageMetadata`,\n * `useSubmissionQueue`, `useExtension`, `useChannel`, plus media\n * composables).\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useStream } from \"@langchain/vue\";\n *\n * const stream = useStream({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n * </script>\n *\n * <template>\n * <div v-for=\"msg in stream.messages.value\" :key=\"msg.id\">\n * {{ msg.content }}\n * </div>\n * <button @click=\"stream.submit({ messages: [{ type: 'human', content: 'Hi' }] })\">\n * Send\n * </button>\n * </template>\n * ```\n *\n * `assistantId`, `client`, and `transport` are captured at setup time.\n * To bind a new assistant/transport, remount the component. Reactive\n * inputs (`threadId`, `apiUrl`, `apiKey`) trigger in-place behaviour\n * changes on the active controller.\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\n interface OptionsBag {\n assistantId?: string;\n threadId?: MaybeRefOrGetter<string | null | undefined>;\n client?: Client;\n apiUrl?: MaybeRefOrGetter<string | undefined>;\n apiKey?: MaybeRefOrGetter<string | undefined>;\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 tools?: AnyHeadlessToolImplementation[];\n onTool?: OnToolCallback;\n }\n const asBag = options as OptionsBag;\n\n // Inherit missing apiUrl / apiKey / client from any LangChainPlugin\n // installed on the app. Vue's `inject` returns `undefined` if the\n // key was never provided; that's fine — we only merge when the\n // caller didn't set a value.\n const pluginOptions =\n inject(LANGCHAIN_OPTIONS, undefined) ?? ({} as Record<string, unknown>);\n\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n // ─── Client construction ────────────────────────────────────────────\n //\n // Identity-stable per setup. Watches apiUrl/apiKey refs so callers\n // that flip a backend at runtime get a fresh client without a full\n // remount — the controller is swapped in lock-step below.\n const resolveApiUrl = () =>\n toValue(asBag.apiUrl) ?? (pluginOptions as { apiUrl?: string }).apiUrl;\n const resolveApiKey = () =>\n toValue(asBag.apiKey) ?? (pluginOptions as { apiKey?: string }).apiKey;\n const explicitClient =\n asBag.client ?? (pluginOptions as { client?: Client }).client;\n\n const clientRef = shallowRef<Client>(\n explicitClient ??\n (new ClientCtor({\n apiUrl: resolveApiUrl(),\n apiKey: resolveApiKey(),\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client)\n );\n\n // Note: we intentionally bind the controller to the *initial* client\n // instance. A dynamic client swap would require tearing the\n // controller down (in-flight subscriptions, queue, hydration), so we\n // keep the rule simple: client is captured at setup. Mirrors React\n // v1 which bakes `useMemo` on `[client, assistantId, transport]`.\n const client = clientRef.value;\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n const initialThreadId = toValue(asBag.threadId) ?? null;\n\n // ─── Controller construction ────────────────────────────────────────\n const controller = new StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >({\n assistantId,\n client: client as unknown as Client<StateType>,\n threadId: initialThreadId,\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\n // Deferred dispose: on the next microtask after the owning scope\n // disappears. Mirrors React's StrictMode-safe activate/deactivate\n // pattern — HMR and other scope-reuse scenarios stay clean because\n // `activate()` cancels the pending dispose if the scope survives.\n const deactivate = controller.activate();\n onScopeDispose(deactivate);\n\n // ─── Reactivity adapters — StreamStore → shallowRef ─────────────────\n function bindStore<S>(\n subscribe: (listener: () => void) => () => void,\n getSnapshot: () => S\n ): Readonly<ShallowRef<S>> {\n const ref = shallowRef<S>(getSnapshot());\n const unsubscribe = subscribe(() => {\n ref.value = getSnapshot();\n });\n onScopeDispose(unsubscribe);\n return readonly(ref) as Readonly<ShallowRef<S>>;\n }\n\n const rootRef = bindStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot\n );\n const subagentRef = bindStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot\n );\n const subgraphRef = bindStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot\n );\n const subgraphByNodeRef = bindStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n // Derived refs for individual root-snapshot fields. Using computed\n // means templates that read `values.value` only retrigger when the\n // root snapshot's identity actually changes — we can't split further\n // because `StreamStore` fans the whole snapshot out on every update.\n const values = computed(() => rootRef.value.values);\n const messages = computed(() => rootRef.value.messages);\n const toolCalls = computed(\n () => rootRef.value.toolCalls as InferToolCalls<T>[]\n );\n const interrupts = computed(() =>\n filterOutHeadlessToolInterrupts(rootRef.value.interrupts)\n );\n const interrupt = computed(() => interrupts.value[0]);\n const isLoading = computed(() => rootRef.value.isLoading);\n const isThreadLoading = computed(() => rootRef.value.isThreadLoading);\n const error = computed(() => rootRef.value.error);\n const threadId = computed(() => rootRef.value.threadId);\n const hydrationPromise = computed(() => controller.hydrationPromise);\n\n // Expose the derived refs through a `readonly(shallowRef)` shape to\n // match the rest of the public surface. `computed` already gives us\n // read-only semantics but templates type-check more cleanly when the\n // fully-typed return claims `Readonly<ShallowRef<T>>` everywhere.\n // The cast is safe — a ComputedRef<T> is structurally a\n // Readonly<Ref<T>>.\n const asShallow = <V>(c: ComputedRef<V>): Readonly<ShallowRef<V>> =>\n c as unknown as Readonly<ShallowRef<V>>;\n\n // ─── threadId reactivity ────────────────────────────────────────────\n //\n // Re-hydrate whenever the caller's threadId input changes post-setup.\n // The initial hydrate already fired synchronously in the controller\n // constructor, so we skip that first tick; otherwise we'd double-fetch\n // `thread.state.get()`.\n let skipFirstThreadIdWatch = true;\n watch(\n () => toValue(asBag.threadId) ?? null,\n (next) => {\n if (skipFirstThreadIdWatch) {\n skipFirstThreadIdWatch = false;\n return;\n }\n void controller.hydrate(next);\n }\n );\n\n // ─── Headless-tool handling ─────────────────────────────────────────\n //\n // Watch root values + protocol interrupts for items targeting a\n // registered tool, invoke the handler, and resume the run with the\n // handler's return value. Dedup via an id set so StrictMode /\n // rerenders don't replay a tool call twice.\n const handledTools = new Set<string>();\n watch(\n () => toValue(asBag.threadId) ?? null,\n () => handledTools.clear()\n );\n const tools = options.tools;\n const onTool = options.onTool;\n if (tools?.length) {\n watch(\n () => [rootRef.value.values, rootRef.value.interrupts] as const,\n ([rootValues, rootInterrupts]) => {\n const bag = rootValues as unknown as Record<string, unknown>;\n const existing = Array.isArray(bag?.__interrupt__)\n ? (bag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existing,\n ...(rootInterrupts as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n flushPendingHeadlessToolInterrupts(\n { ...bag, __interrupt__: combined },\n tools,\n handledTools,\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 },\n { immediate: true, flush: \"sync\" }\n );\n }\n\n const handle: UseStreamReturn<T, InterruptType, ConfigurableType> = {\n values: asShallow(values) as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"values\"],\n messages: asShallow(messages),\n toolCalls: asShallow(toolCalls),\n interrupts: asShallow(interrupts),\n interrupt,\n isLoading,\n isThreadLoading,\n error,\n threadId,\n hydrationPromise,\n subagents: subagentRef as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs: subgraphRef,\n subgraphsByNode: subgraphByNodeRef,\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 };\n\n return handle;\n}\n\n/**\n * Helper used by the selector composables to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `useMessages`, `useToolCalls`, etc.\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/vue",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Vue integration for LangGraph & LangChain",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,7 +10,7 @@
10
10
  "directory": "libs/sdk-vue"
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",
@@ -31,7 +31,7 @@
31
31
  "vue": "^3.5.33",
32
32
  "webdriverio": "^9.25.0",
33
33
  "zod": "^4.3.6",
34
- "@langchain/langgraph": "1.3.1",
34
+ "@langchain/langgraph": "1.3.2",
35
35
  "@langchain/langgraph-api": "1.2.2",
36
36
  "@langchain/langgraph-checkpoint": "1.0.2"
37
37
  },