@langchain/react 1.0.17 → 1.0.18

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.
@@ -91,8 +91,13 @@ function useValues(stream, target, options) {
91
91
  return isRoot(namespace) ? stream.values : scoped;
92
92
  }
93
93
  /**
94
- * Subscribe to a `custom:<name>` stream extension — most-recent
94
+ * Subscribe to a `custom:<name>` stream extension — the most-recent
95
95
  * payload emitted by the transformer, scoped to the target namespace.
96
+ *
97
+ * Returns only the latest value and resumes across serial runs, so it is
98
+ * ideal for "current state" panels (progress, score, status). When you
99
+ * need the full history of events rather than just the latest payload,
100
+ * use {@link useChannel} instead.
96
101
  */
97
102
  function useExtension(stream, name, target) {
98
103
  const namespace = resolveNamespace(target);
@@ -100,12 +105,6 @@ function useExtension(stream, name, target) {
100
105
  return require_use_projection.useProjection(require_use_stream.getRegistry(stream), () => (0, _langchain_langgraph_sdk_stream.extensionProjection)(name, namespace), key, void 0);
101
106
  }
102
107
  /**
103
- * Raw-events escape hatch. Subscribes to one or more channels at a
104
- * namespace and returns a bounded buffer of raw protocol events.
105
- * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}
106
- * for the common cases.
107
- */
108
- /**
109
108
  * Subscribe to a scoped audio-media stream. Returns an array of
110
109
  * {@link AudioMedia} handles, one per message containing at least one
111
110
  * `AudioBlock` in the target namespace.
@@ -154,6 +153,17 @@ function useFiles(stream, target) {
154
153
  return require_use_projection.useProjection(require_use_stream.getRegistry(stream), () => (0, _langchain_langgraph_sdk_stream.filesProjection)(namespace), key, EMPTY_FILES);
155
154
  }
156
155
  const EMPTY_FILES = [];
156
+ /**
157
+ * Raw-events escape hatch. Subscribes to one or more channels at a
158
+ * namespace and returns a bounded buffer of raw protocol events.
159
+ *
160
+ * The buffer keeps accumulating across serial runs for the lifetime of
161
+ * the thread, so this is the hook to use for an event log / stream of a
162
+ * custom channel (e.g. `["custom:redaction-stats"]`). When you only need
163
+ * the latest payload of a single `custom:<name>` channel, prefer
164
+ * {@link useExtension}. For the common message/tool/value cases prefer
165
+ * {@link useMessages} / {@link useToolCalls} / {@link useValues}.
166
+ */
157
167
  function useChannel(stream, channels, target, options) {
158
168
  const namespace = resolveNamespace(target);
159
169
  const channelKey = (0, react.useMemo)(() => [...channels].sort().join(","), [channels]);
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.cjs","names":["STREAM_CONTROLLER","NAMESPACE_SEPARATOR","useProjection","getRegistry"],"sources":["../src/selectors.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n MessageMetadata,\n MessageMetadataMap,\n SubmissionQueueEntry,\n SubmissionQueueSnapshot,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector hooks don't need to carry `InterruptType` /\n * `ConfigurableType` — they only ever read state. Accepting a\n * `StateType`-parameterised stream (with the other two generics\n * widened to `any`) lets callers keep their full\n * `useStream<State, Interrupt, Configurable>()` handle\n * without re-declaring the interrupt / configurable shapes at every\n * selector call site.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector hook can be targeted at. Callers can pass any of:\n * - `undefined` — root namespace (cheap: served by the always-on root store)\n * - a {@link SubagentDiscoverySnapshot} — the snapshot returned by `stream.subagents.get(...)`\n * - a {@link SubgraphDiscoverySnapshot} — the snapshot returned by `stream.subgraphs.get(...)`\n * - an explicit `{ namespace: string[] }` — any other namespaced scope\n * - a raw `string[]` — escape hatch identical to the object form\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target;\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\n/**\n * If `target` is a subagent snapshot still on its default\n * `tools:<toolCallId>` namespace, return that tool-call id so the\n * caller can trigger lazy execution-namespace resolution. Returns\n * `null` for root targets, subgraph hosts, explicit namespaces, and\n * already-promoted subagents.\n */\nfunction subagentNeedingNamespace(target: SelectorTarget): string | null {\n if (target == null || Array.isArray(target)) return null;\n const obj = target as { id?: unknown; namespace?: readonly string[] };\n if (typeof obj.id !== \"string\" || !Array.isArray(obj.namespace)) return null;\n if (obj.namespace.length === 1 && obj.namespace[0] === `tools:${obj.id}`) {\n return obj.id;\n }\n return null;\n}\n\n/**\n * Lazily resolve a subagent's execution namespace on the first scoped\n * mount. Deep-agent subagents execute under a `tools:<uuid>` namespace\n * distinct from their `tools:<toolCallId>` discovery key; until that is\n * known a scoped `useMessages`/`useToolCalls` would target the wrong\n * scope. The controller de-dupes and skips already-promoted ids, so\n * this is safe to call from every consumer of the same subagent.\n */\nfunction useResolveSubagentNamespace(\n stream: AnyStream,\n target: SelectorTarget\n): void {\n const controller = stream[STREAM_CONTROLLER];\n const toolCallId = subagentNeedingNamespace(target);\n useEffect(() => {\n if (toolCallId == null) return;\n void controller.resolveSubagentNamespace(toolCallId);\n }, [controller, toolCallId]);\n}\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n// The stream type we accept for selectors — purposely loose so\n// selector hooks remain callable from components that don't carry\n// the exact State/Interrupt/Configurable generics. We use `any` for\n// all three generics because `UseStreamReturn` is\n// invariant in `State` and `Configurable` (they flow through both\n// reader and writer positions), so a concrete\n// `useStream<typeof agent>()` handle wouldn't flow into\n// a `<object, unknown, object>` slot otherwise.\n//\n// Typed selectors (`useValues<S>` etc.) use {@link StreamHandle}\n// above so the concrete `StateType` flows into the return; hooks\n// that don't depend on state (`useMessages`, `useAudio`, …) stay on\n// `AnyStream` for maximum flexibility.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Subscribe to a scoped `messages` stream. Pass `stream` and\n * optionally a subagent/subgraph snapshot (or any namespaced target).\n *\n * Contract:\n * - At the root (no target) this returns `stream.messages` directly\n * — no extra subscription is opened. `stream.messages` is the\n * live merge of `messages`-channel token deltas and\n * `values.messages` snapshots (see\n * {@link UseStreamReturn.messages}), so token-by-token\n * streaming here depends on the backend emitting `messages`\n * channel events. Backends that only emit `values` updates will\n * render full turns at once rather than streaming.\n * - For any other namespace, the mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. Unmounting\n * the last component that watches this namespace closes the\n * subscription automatically.\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: SelectorTarget\n): BaseMessage[] {\n useResolveSubagentNamespace(stream, target);\n const namespace = resolveNamespace(target);\n const key = `messages|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace),\n key,\n EMPTY_MESSAGES\n );\n return isRoot(namespace) ? stream.messages : scoped;\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link useMessages}; at the root this just returns\n * `stream.toolCalls`.\n *\n * The optional generic `T` can be passed to narrow the type of\n * assembled tool calls on the returned array. Accepts either:\n * - an agent brand (`typeof agent`) — union is derived from the\n * agent's declared tools via {@link InferToolCalls};\n * - an array of LangGraph tools (`typeof tools`) — union is derived\n * from {@link InferToolCalls} (parallel to {@link ToolCallsFromTools}).\n *\n * When omitted, returns the plain `AssembledToolCall[]` union used by\n * the controller.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget\n): InferToolCalls<T>[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[] {\n useResolveSubagentNamespace(stream, target);\n const namespace = resolveNamespace(target);\n const key = `toolCalls|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace),\n key,\n EMPTY_TOOLCALLS\n );\n return isRoot(namespace) ? stream.toolCalls : scoped;\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — most-recent state payload\n * for a namespace. Equivalent to reading `stream.values` at the root.\n *\n * When the payload carries a `messages` array, it is coerced to\n * `BaseMessage` instances to keep parity with the root projection.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on the parent `useStream<State>()` — no explicit\n * generic required. Non-nullable because the root snapshot always\n * carries `values` (falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): the scoped payload can\n * have a different shape than the root state (e.g. a subagent\n * returning its own substate). Callers should annotate the\n * expected shape explicitly: `useValues<SubagentState>(stream, sub)`.\n * Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): StateType;\n/**\n * Explicit-generic override. Accepts:\n * - an agent brand or compiled graph (unwrapped via\n * {@link InferStateType});\n * - a plain state shape (returned as-is).\n *\n * The root-call form is non-nullable (the root snapshot is always\n * present); the scoped form returns `T | undefined` because a\n * projection may not have emitted a payload yet.\n */\nexport function useValues<T>(stream: AnyStream): InferStateType<T>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): T | undefined;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): unknown {\n const namespace = resolveNamespace(target);\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\n return isRoot(namespace) ? stream.values : scoped;\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — most-recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function useExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget\n): T | undefined {\n const namespace = resolveNamespace(target);\n const key = `extension|${name}|${namespaceKey(namespace)}`;\n return useProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}\n * for the common cases.\n */\n/**\n * Subscribe to a scoped audio-media stream. Returns an array of\n * {@link AudioMedia} handles, one per message containing at least one\n * `AudioBlock` in the target namespace.\n *\n * Each handle is yielded on its first matching `content-block-start`,\n * exposes `.partialBytes` for live access, settles `.blob` /\n * `.objectURL` / `.transcript` on `message-finish`, and surfaces\n * fail-loud errors via `.error`.\n *\n * Pair with {@link useMediaURL} to turn a handle into an `<audio src>`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): AudioMedia[] {\n const namespace = resolveNamespace(target);\n const key = `audio|${namespaceKey(namespace)}`;\n return useProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): ImageMedia[] {\n const namespace = resolveNamespace(target);\n const key = `images|${namespaceKey(namespace)}`;\n return useProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): VideoMedia[] {\n const namespace = resolveNamespace(target);\n const key = `video|${namespaceKey(namespace)}`;\n return useProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for an\n * `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): FileMedia[] {\n const namespace = resolveNamespace(target);\n const key = `files|${namespaceKey(namespace)}`;\n return useProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Event[] {\n const namespace = resolveNamespace(target);\n const channelKey = useMemo(() => [...channels].sort().join(\",\"), [channels]);\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${channelKey}|${namespaceKey(namespace)}`;\n return useProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace, options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Read metadata recorded for a specific message id — today exposes\n * `parentCheckpointId`, the checkpoint the message was first seen on.\n * Designed for fork / edit flows:\n *\n * ```tsx\n * const { parentCheckpointId } = useMessageMetadata(stream, msg.id) ?? {};\n * if (parentCheckpointId) {\n * await stream.submit(input, { forkFrom: parentCheckpointId });\n * }\n * ```\n *\n * Returns `undefined` when the id isn't known yet (e.g. the server\n * hasn't emitted `parent_checkpoint` for that message, or the message\n * arrived via `messages`-channel deltas only and no `values` snapshot\n * has landed for it yet).\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: string | undefined\n): MessageMetadata | undefined {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const snapshot = useSyncExternalStore<MessageMetadataMap>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return messageId == null ? undefined : snapshot.get(messageId);\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with `multitaskStrategy:\n * \"enqueue\"` while another run is in flight. The returned object is\n * stable per snapshot so consumers can pass `entries` straight into a\n * `<Fragment key={e.id}>` list without extra memoisation.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: SubmissionQueueSnapshot<StateType>;\n readonly size: number;\n cancel(id: string): Promise<boolean>;\n clear(): Promise<void>;\n}\n\nexport function useSubmissionQueue<StateType extends object>(\n stream: StreamHandle<StateType>\n): UseSubmissionQueueReturn<StateType>;\nexport function useSubmissionQueue(stream: AnyStream): UseSubmissionQueueReturn;\nexport function useSubmissionQueue(\n stream: AnyStream\n): UseSubmissionQueueReturn {\n const controller = stream[STREAM_CONTROLLER];\n const store = controller.queueStore;\n const entries = useSyncExternalStore<SubmissionQueueSnapshot>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return useMemo<UseSubmissionQueueReturn>(\n () => ({\n entries,\n size: entries.length,\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\n }),\n [entries, controller]\n );\n}\n\nexport type { SubmissionQueueEntry, SubmissionQueueSnapshot };\n"],"mappings":"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"}
1
+ {"version":3,"file":"selectors.cjs","names":["STREAM_CONTROLLER","NAMESPACE_SEPARATOR","useProjection","getRegistry"],"sources":["../src/selectors.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n MessageMetadata,\n MessageMetadataMap,\n SubmissionQueueEntry,\n SubmissionQueueSnapshot,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector hooks don't need to carry `InterruptType` /\n * `ConfigurableType` — they only ever read state. Accepting a\n * `StateType`-parameterised stream (with the other two generics\n * widened to `any`) lets callers keep their full\n * `useStream<State, Interrupt, Configurable>()` handle\n * without re-declaring the interrupt / configurable shapes at every\n * selector call site.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector hook can be targeted at. Callers can pass any of:\n * - `undefined` — root namespace (cheap: served by the always-on root store)\n * - a {@link SubagentDiscoverySnapshot} — the snapshot returned by `stream.subagents.get(...)`\n * - a {@link SubgraphDiscoverySnapshot} — the snapshot returned by `stream.subgraphs.get(...)`\n * - an explicit `{ namespace: string[] }` — any other namespaced scope\n * - a raw `string[]` — escape hatch identical to the object form\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target;\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\n/**\n * If `target` is a subagent snapshot still on its default\n * `tools:<toolCallId>` namespace, return that tool-call id so the\n * caller can trigger lazy execution-namespace resolution. Returns\n * `null` for root targets, subgraph hosts, explicit namespaces, and\n * already-promoted subagents.\n */\nfunction subagentNeedingNamespace(target: SelectorTarget): string | null {\n if (target == null || Array.isArray(target)) return null;\n const obj = target as { id?: unknown; namespace?: readonly string[] };\n if (typeof obj.id !== \"string\" || !Array.isArray(obj.namespace)) return null;\n if (obj.namespace.length === 1 && obj.namespace[0] === `tools:${obj.id}`) {\n return obj.id;\n }\n return null;\n}\n\n/**\n * Lazily resolve a subagent's execution namespace on the first scoped\n * mount. Deep-agent subagents execute under a `tools:<uuid>` namespace\n * distinct from their `tools:<toolCallId>` discovery key; until that is\n * known a scoped `useMessages`/`useToolCalls` would target the wrong\n * scope. The controller de-dupes and skips already-promoted ids, so\n * this is safe to call from every consumer of the same subagent.\n */\nfunction useResolveSubagentNamespace(\n stream: AnyStream,\n target: SelectorTarget\n): void {\n const controller = stream[STREAM_CONTROLLER];\n const toolCallId = subagentNeedingNamespace(target);\n useEffect(() => {\n if (toolCallId == null) return;\n void controller.resolveSubagentNamespace(toolCallId);\n }, [controller, toolCallId]);\n}\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n// The stream type we accept for selectors — purposely loose so\n// selector hooks remain callable from components that don't carry\n// the exact State/Interrupt/Configurable generics. We use `any` for\n// all three generics because `UseStreamReturn` is\n// invariant in `State` and `Configurable` (they flow through both\n// reader and writer positions), so a concrete\n// `useStream<typeof agent>()` handle wouldn't flow into\n// a `<object, unknown, object>` slot otherwise.\n//\n// Typed selectors (`useValues<S>` etc.) use {@link StreamHandle}\n// above so the concrete `StateType` flows into the return; hooks\n// that don't depend on state (`useMessages`, `useAudio`, …) stay on\n// `AnyStream` for maximum flexibility.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Subscribe to a scoped `messages` stream. Pass `stream` and\n * optionally a subagent/subgraph snapshot (or any namespaced target).\n *\n * Contract:\n * - At the root (no target) this returns `stream.messages` directly\n * — no extra subscription is opened. `stream.messages` is the\n * live merge of `messages`-channel token deltas and\n * `values.messages` snapshots (see\n * {@link UseStreamReturn.messages}), so token-by-token\n * streaming here depends on the backend emitting `messages`\n * channel events. Backends that only emit `values` updates will\n * render full turns at once rather than streaming.\n * - For any other namespace, the mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. Unmounting\n * the last component that watches this namespace closes the\n * subscription automatically.\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: SelectorTarget\n): BaseMessage[] {\n useResolveSubagentNamespace(stream, target);\n const namespace = resolveNamespace(target);\n const key = `messages|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace),\n key,\n EMPTY_MESSAGES\n );\n return isRoot(namespace) ? stream.messages : scoped;\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link useMessages}; at the root this just returns\n * `stream.toolCalls`.\n *\n * The optional generic `T` can be passed to narrow the type of\n * assembled tool calls on the returned array. Accepts either:\n * - an agent brand (`typeof agent`) — union is derived from the\n * agent's declared tools via {@link InferToolCalls};\n * - an array of LangGraph tools (`typeof tools`) — union is derived\n * from {@link InferToolCalls} (parallel to {@link ToolCallsFromTools}).\n *\n * When omitted, returns the plain `AssembledToolCall[]` union used by\n * the controller.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget\n): InferToolCalls<T>[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[] {\n useResolveSubagentNamespace(stream, target);\n const namespace = resolveNamespace(target);\n const key = `toolCalls|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace),\n key,\n EMPTY_TOOLCALLS\n );\n return isRoot(namespace) ? stream.toolCalls : scoped;\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — most-recent state payload\n * for a namespace. Equivalent to reading `stream.values` at the root.\n *\n * When the payload carries a `messages` array, it is coerced to\n * `BaseMessage` instances to keep parity with the root projection.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on the parent `useStream<State>()` — no explicit\n * generic required. Non-nullable because the root snapshot always\n * carries `values` (falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): the scoped payload can\n * have a different shape than the root state (e.g. a subagent\n * returning its own substate). Callers should annotate the\n * expected shape explicitly: `useValues<SubagentState>(stream, sub)`.\n * Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): StateType;\n/**\n * Explicit-generic override. Accepts:\n * - an agent brand or compiled graph (unwrapped via\n * {@link InferStateType});\n * - a plain state shape (returned as-is).\n *\n * The root-call form is non-nullable (the root snapshot is always\n * present); the scoped form returns `T | undefined` because a\n * projection may not have emitted a payload yet.\n */\nexport function useValues<T>(stream: AnyStream): InferStateType<T>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): T | undefined;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): unknown {\n const namespace = resolveNamespace(target);\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\n return isRoot(namespace) ? stream.values : scoped;\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most-recent\n * payload emitted by the transformer, scoped to the target namespace.\n *\n * Returns only the latest value and resumes across serial runs, so it is\n * ideal for \"current state\" panels (progress, score, status). When you\n * need the full history of events rather than just the latest payload,\n * use {@link useChannel} instead.\n */\nexport function useExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget\n): T | undefined {\n const namespace = resolveNamespace(target);\n const key = `extension|${name}|${namespaceKey(namespace)}`;\n return useProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace),\n key,\n undefined\n );\n}\n\n/**\n * Subscribe to a scoped audio-media stream. Returns an array of\n * {@link AudioMedia} handles, one per message containing at least one\n * `AudioBlock` in the target namespace.\n *\n * Each handle is yielded on its first matching `content-block-start`,\n * exposes `.partialBytes` for live access, settles `.blob` /\n * `.objectURL` / `.transcript` on `message-finish`, and surfaces\n * fail-loud errors via `.error`.\n *\n * Pair with {@link useMediaURL} to turn a handle into an `<audio src>`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): AudioMedia[] {\n const namespace = resolveNamespace(target);\n const key = `audio|${namespaceKey(namespace)}`;\n return useProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): ImageMedia[] {\n const namespace = resolveNamespace(target);\n const key = `images|${namespaceKey(namespace)}`;\n return useProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): VideoMedia[] {\n const namespace = resolveNamespace(target);\n const key = `video|${namespaceKey(namespace)}`;\n return useProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for an\n * `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): FileMedia[] {\n const namespace = resolveNamespace(target);\n const key = `files|${namespaceKey(namespace)}`;\n return useProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n\nexport type UseChannelOptions = ChannelProjectionOptions;\n\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 *\n * The buffer keeps accumulating across serial runs for the lifetime of\n * the thread, so this is the hook to use for an event log / stream of a\n * custom channel (e.g. `[\"custom:redaction-stats\"]`). When you only need\n * the latest payload of a single `custom:<name>` channel, prefer\n * {@link useExtension}. For the common message/tool/value cases prefer\n * {@link useMessages} / {@link useToolCalls} / {@link useValues}.\n */\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Event[] {\n const namespace = resolveNamespace(target);\n const channelKey = useMemo(() => [...channels].sort().join(\",\"), [channels]);\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${channelKey}|${namespaceKey(namespace)}`;\n return useProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace, options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Read metadata recorded for a specific message id — today exposes\n * `parentCheckpointId`, the checkpoint the message was first seen on.\n * Designed for fork / edit flows:\n *\n * ```tsx\n * const { parentCheckpointId } = useMessageMetadata(stream, msg.id) ?? {};\n * if (parentCheckpointId) {\n * await stream.submit(input, { forkFrom: parentCheckpointId });\n * }\n * ```\n *\n * Returns `undefined` when the id isn't known yet (e.g. the server\n * hasn't emitted `parent_checkpoint` for that message, or the message\n * arrived via `messages`-channel deltas only and no `values` snapshot\n * has landed for it yet).\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: string | undefined\n): MessageMetadata | undefined {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const snapshot = useSyncExternalStore<MessageMetadataMap>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return messageId == null ? undefined : snapshot.get(messageId);\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with `multitaskStrategy:\n * \"enqueue\"` while another run is in flight. The returned object is\n * stable per snapshot so consumers can pass `entries` straight into a\n * `<Fragment key={e.id}>` list without extra memoisation.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: SubmissionQueueSnapshot<StateType>;\n readonly size: number;\n cancel(id: string): Promise<boolean>;\n clear(): Promise<void>;\n}\n\nexport function useSubmissionQueue<StateType extends object>(\n stream: StreamHandle<StateType>\n): UseSubmissionQueueReturn<StateType>;\nexport function useSubmissionQueue(stream: AnyStream): UseSubmissionQueueReturn;\nexport function useSubmissionQueue(\n stream: AnyStream\n): UseSubmissionQueueReturn {\n const controller = stream[STREAM_CONTROLLER];\n const store = controller.queueStore;\n const entries = useSyncExternalStore<SubmissionQueueSnapshot>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return useMemo<UseSubmissionQueueReturn>(\n () => ({\n entries,\n size: entries.length,\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\n }),\n [entries, controller]\n );\n}\n\nexport type { SubmissionQueueEntry, SubmissionQueueSnapshot };\n"],"mappings":"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"}
@@ -98,16 +98,15 @@ declare function useValues<T = unknown>(stream: AnyStream, target: SelectorTarge
98
98
  messagesKey?: string;
99
99
  }): T | undefined;
100
100
  /**
101
- * Subscribe to a `custom:<name>` stream extension — most-recent
101
+ * Subscribe to a `custom:<name>` stream extension — the most-recent
102
102
  * payload emitted by the transformer, scoped to the target namespace.
103
+ *
104
+ * Returns only the latest value and resumes across serial runs, so it is
105
+ * ideal for "current state" panels (progress, score, status). When you
106
+ * need the full history of events rather than just the latest payload,
107
+ * use {@link useChannel} instead.
103
108
  */
104
109
  declare function useExtension<T = unknown>(stream: AnyStream, name: string, target?: SelectorTarget): T | undefined;
105
- /**
106
- * Raw-events escape hatch. Subscribes to one or more channels at a
107
- * namespace and returns a bounded buffer of raw protocol events.
108
- * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}
109
- * for the common cases.
110
- */
111
110
  /**
112
111
  * Subscribe to a scoped audio-media stream. Returns an array of
113
112
  * {@link AudioMedia} handles, one per message containing at least one
@@ -138,6 +137,17 @@ declare function useVideo(stream: AnyStream, target?: SelectorTarget): VideoMedi
138
137
  */
139
138
  declare function useFiles(stream: AnyStream, target?: SelectorTarget): FileMedia[];
140
139
  type UseChannelOptions = ChannelProjectionOptions;
140
+ /**
141
+ * Raw-events escape hatch. Subscribes to one or more channels at a
142
+ * namespace and returns a bounded buffer of raw protocol events.
143
+ *
144
+ * The buffer keeps accumulating across serial runs for the lifetime of
145
+ * the thread, so this is the hook to use for an event log / stream of a
146
+ * custom channel (e.g. `["custom:redaction-stats"]`). When you only need
147
+ * the latest payload of a single `custom:<name>` channel, prefer
148
+ * {@link useExtension}. For the common message/tool/value cases prefer
149
+ * {@link useMessages} / {@link useToolCalls} / {@link useValues}.
150
+ */
141
151
  declare function useChannel(stream: AnyStream, channels: readonly Channel[], target?: SelectorTarget, options?: UseChannelOptions): Event[];
142
152
  /**
143
153
  * Read metadata recorded for a specific message id — today exposes
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.cts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;AAwCyB;;;;;;;;KAapB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;AAeF;;;;;;;;AAAA,KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;AAAA,KAsEC,SAAA,GAAY,eAAA;;;AAuBjB;;;;;;;;;;;;;;;AAkCA;;;;iBAlCgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,WAAA;;;;;;;;;;;AAmCH;;;;;iBAJgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;AAAA,iBACa,YAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,cAAA,CAAe,CAAA;;;;;;;;;;;;AAsClB;;;;;;;iBAAgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,SAAA;;;;;;;;AAWH;;;iBAAgB,SAAA,GAAA,CAAa,MAAA,EAAQ,SAAA,GAAY,cAAA,CAAe,CAAA;AAAA,iBAChD,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,CAAA;;;;;iBAuBa,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,CAAA;;;;AA/BH;;;;;;;;;;;;;;;iBA4DgB,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;AApCH;;iBAqDgB,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;;iBAkBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,SAAA;AAAA,KAaS,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,KAAA;;AApFH;;;;;;;;;;;;;;;AAoBA;iBA+FgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,uBACC,eAAA;;;;;;;;;UAkBc,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAAA,SACjC,IAAA;EACT,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,KAAA,IAAS,OAAA;AAAA;AAAA,iBAGK,kBAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,wBAAA,CAAyB,SAAA;AAAA,iBACZ,kBAAA,CAAmB,MAAA,EAAQ,SAAA,GAAY,wBAAA"}
1
+ {"version":3,"file":"selectors.d.cts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;AAwCyB;;;;;;;;KAapB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;AAeF;;;;;;;;AAAA,KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;AAAA,KAsEC,SAAA,GAAY,eAAA;;;AAuBjB;;;;;;;;;;;;;;;AAkCA;;;;iBAlCgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,WAAA;;;;;;;;;;;AAmCH;;;;;iBAJgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;AAAA,iBACa,YAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,cAAA,CAAe,CAAA;;;;;;;;;;;;AAsClB;;;;;;;iBAAgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,SAAA;;;;;;;;AAWH;;;iBAAgB,SAAA,GAAA,CAAa,MAAA,EAAQ,SAAA,GAAY,cAAA,CAAe,CAAA;AAAA,iBAChD,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,CAAA;;;;;;;;;AAJH;iBAgCgB,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,CAAA;;;;;;;;;;;;;iBAuBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;AA9BH;iBA+CgB,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;;iBAkBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,SAAA;AAAA,KAaS,iBAAA,GAAoB,wBAAA;;;;AA7EhC;;;;;;;;iBA0FgB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,KAAA;;;;;;;AA3EH;;;;;;;;;;;iBA0GgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,uBACC,eAAA;;;;AAzFH;;;;;UA2GiB,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAAA,SACjC,IAAA;EACT,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,KAAA,IAAS,OAAA;AAAA;AAAA,iBAGK,kBAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,wBAAA,CAAyB,SAAA;AAAA,iBACZ,kBAAA,CAAmB,MAAA,EAAQ,SAAA,GAAY,wBAAA"}
@@ -98,16 +98,15 @@ declare function useValues<T = unknown>(stream: AnyStream, target: SelectorTarge
98
98
  messagesKey?: string;
99
99
  }): T | undefined;
100
100
  /**
101
- * Subscribe to a `custom:<name>` stream extension — most-recent
101
+ * Subscribe to a `custom:<name>` stream extension — the most-recent
102
102
  * payload emitted by the transformer, scoped to the target namespace.
103
+ *
104
+ * Returns only the latest value and resumes across serial runs, so it is
105
+ * ideal for "current state" panels (progress, score, status). When you
106
+ * need the full history of events rather than just the latest payload,
107
+ * use {@link useChannel} instead.
103
108
  */
104
109
  declare function useExtension<T = unknown>(stream: AnyStream, name: string, target?: SelectorTarget): T | undefined;
105
- /**
106
- * Raw-events escape hatch. Subscribes to one or more channels at a
107
- * namespace and returns a bounded buffer of raw protocol events.
108
- * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}
109
- * for the common cases.
110
- */
111
110
  /**
112
111
  * Subscribe to a scoped audio-media stream. Returns an array of
113
112
  * {@link AudioMedia} handles, one per message containing at least one
@@ -138,6 +137,17 @@ declare function useVideo(stream: AnyStream, target?: SelectorTarget): VideoMedi
138
137
  */
139
138
  declare function useFiles(stream: AnyStream, target?: SelectorTarget): FileMedia[];
140
139
  type UseChannelOptions = ChannelProjectionOptions;
140
+ /**
141
+ * Raw-events escape hatch. Subscribes to one or more channels at a
142
+ * namespace and returns a bounded buffer of raw protocol events.
143
+ *
144
+ * The buffer keeps accumulating across serial runs for the lifetime of
145
+ * the thread, so this is the hook to use for an event log / stream of a
146
+ * custom channel (e.g. `["custom:redaction-stats"]`). When you only need
147
+ * the latest payload of a single `custom:<name>` channel, prefer
148
+ * {@link useExtension}. For the common message/tool/value cases prefer
149
+ * {@link useMessages} / {@link useToolCalls} / {@link useValues}.
150
+ */
141
151
  declare function useChannel(stream: AnyStream, channels: readonly Channel[], target?: SelectorTarget, options?: UseChannelOptions): Event[];
142
152
  /**
143
153
  * Read metadata recorded for a specific message id — today exposes
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.ts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;AAwCyB;;;;;;;;KAapB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;AAeF;;;;;;;;AAAA,KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;AAAA,KAsEC,SAAA,GAAY,eAAA;;;AAuBjB;;;;;;;;;;;;;;;AAkCA;;;;iBAlCgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,WAAA;;;;;;;;;;;AAmCH;;;;;iBAJgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;AAAA,iBACa,YAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,cAAA,CAAe,CAAA;;;;;;;;;;;;AAsClB;;;;;;;iBAAgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,SAAA;;;;;;;;AAWH;;;iBAAgB,SAAA,GAAA,CAAa,MAAA,EAAQ,SAAA,GAAY,cAAA,CAAe,CAAA;AAAA,iBAChD,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,CAAA;;;;;iBAuBa,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,CAAA;;;;AA/BH;;;;;;;;;;;;;;;iBA4DgB,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;AApCH;;iBAqDgB,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;;iBAkBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,SAAA;AAAA,KAaS,iBAAA,GAAoB,wBAAA;AAAA,iBAEhB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,KAAA;;AApFH;;;;;;;;;;;;;;;AAoBA;iBA+FgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,uBACC,eAAA;;;;;;;;;UAkBc,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAAA,SACjC,IAAA;EACT,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,KAAA,IAAS,OAAA;AAAA;AAAA,iBAGK,kBAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,wBAAA,CAAyB,SAAA;AAAA,iBACZ,kBAAA,CAAmB,MAAA,EAAQ,SAAA,GAAY,wBAAA"}
1
+ {"version":3,"file":"selectors.d.ts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;AAwCyB;;;;;;;;KAapB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;AAeF;;;;;;;;AAAA,KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;AAAA,KAsEC,SAAA,GAAY,eAAA;;;AAuBjB;;;;;;;;;;;;;;;AAkCA;;;;iBAlCgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,WAAA;;;;;;;;;;;AAmCH;;;;;iBAJgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,iBAAA;AAAA,iBACa,YAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,cAAA,CAAe,CAAA;;;;;;;;;;;;AAsClB;;;;;;;iBAAgB,SAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,SAAA;;;;;;;;AAWH;;;iBAAgB,SAAA,GAAA,CAAa,MAAA,EAAQ,SAAA,GAAY,cAAA,CAAe,CAAA;AAAA,iBAChD,SAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,EACR,OAAA;EAAY,WAAA;AAAA,IACX,CAAA;;;;;;;;;AAJH;iBAgCgB,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GACR,CAAA;;;;;;;;;;;;;iBAuBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;AA9BH;iBA+CgB,SAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;iBAiBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,UAAA;;;;;;iBAkBa,QAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GACR,SAAA;AAAA,KAaS,iBAAA,GAAoB,wBAAA;;;;AA7EhC;;;;;;;;iBA0FgB,UAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,EACT,OAAA,GAAU,iBAAA,GACT,KAAA;;;;;;;AA3EH;;;;;;;;;;;iBA0GgB,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,SAAA,uBACC,eAAA;;;;AAzFH;;;;;UA2GiB,wBAAA,4BACY,MAAA;EAAA,SAElB,OAAA,EAAS,uBAAA,CAAwB,SAAA;EAAA,SACjC,IAAA;EACT,MAAA,CAAO,EAAA,WAAa,OAAA;EACpB,KAAA,IAAS,OAAA;AAAA;AAAA,iBAGK,kBAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,wBAAA,CAAyB,SAAA;AAAA,iBACZ,kBAAA,CAAmB,MAAA,EAAQ,SAAA,GAAY,wBAAA"}
package/dist/selectors.js CHANGED
@@ -91,8 +91,13 @@ function useValues(stream, target, options) {
91
91
  return isRoot(namespace) ? stream.values : scoped;
92
92
  }
93
93
  /**
94
- * Subscribe to a `custom:<name>` stream extension — most-recent
94
+ * Subscribe to a `custom:<name>` stream extension — the most-recent
95
95
  * payload emitted by the transformer, scoped to the target namespace.
96
+ *
97
+ * Returns only the latest value and resumes across serial runs, so it is
98
+ * ideal for "current state" panels (progress, score, status). When you
99
+ * need the full history of events rather than just the latest payload,
100
+ * use {@link useChannel} instead.
96
101
  */
97
102
  function useExtension(stream, name, target) {
98
103
  const namespace = resolveNamespace(target);
@@ -100,12 +105,6 @@ function useExtension(stream, name, target) {
100
105
  return useProjection(getRegistry(stream), () => extensionProjection(name, namespace), key, void 0);
101
106
  }
102
107
  /**
103
- * Raw-events escape hatch. Subscribes to one or more channels at a
104
- * namespace and returns a bounded buffer of raw protocol events.
105
- * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}
106
- * for the common cases.
107
- */
108
- /**
109
108
  * Subscribe to a scoped audio-media stream. Returns an array of
110
109
  * {@link AudioMedia} handles, one per message containing at least one
111
110
  * `AudioBlock` in the target namespace.
@@ -154,6 +153,17 @@ function useFiles(stream, target) {
154
153
  return useProjection(getRegistry(stream), () => filesProjection(namespace), key, EMPTY_FILES);
155
154
  }
156
155
  const EMPTY_FILES = [];
156
+ /**
157
+ * Raw-events escape hatch. Subscribes to one or more channels at a
158
+ * namespace and returns a bounded buffer of raw protocol events.
159
+ *
160
+ * The buffer keeps accumulating across serial runs for the lifetime of
161
+ * the thread, so this is the hook to use for an event log / stream of a
162
+ * custom channel (e.g. `["custom:redaction-stats"]`). When you only need
163
+ * the latest payload of a single `custom:<name>` channel, prefer
164
+ * {@link useExtension}. For the common message/tool/value cases prefer
165
+ * {@link useMessages} / {@link useToolCalls} / {@link useValues}.
166
+ */
157
167
  function useChannel(stream, channels, target, options) {
158
168
  const namespace = resolveNamespace(target);
159
169
  const channelKey = useMemo(() => [...channels].sort().join(","), [channels]);
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.js","names":[],"sources":["../src/selectors.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n MessageMetadata,\n MessageMetadataMap,\n SubmissionQueueEntry,\n SubmissionQueueSnapshot,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector hooks don't need to carry `InterruptType` /\n * `ConfigurableType` — they only ever read state. Accepting a\n * `StateType`-parameterised stream (with the other two generics\n * widened to `any`) lets callers keep their full\n * `useStream<State, Interrupt, Configurable>()` handle\n * without re-declaring the interrupt / configurable shapes at every\n * selector call site.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector hook can be targeted at. Callers can pass any of:\n * - `undefined` — root namespace (cheap: served by the always-on root store)\n * - a {@link SubagentDiscoverySnapshot} — the snapshot returned by `stream.subagents.get(...)`\n * - a {@link SubgraphDiscoverySnapshot} — the snapshot returned by `stream.subgraphs.get(...)`\n * - an explicit `{ namespace: string[] }` — any other namespaced scope\n * - a raw `string[]` — escape hatch identical to the object form\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target;\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\n/**\n * If `target` is a subagent snapshot still on its default\n * `tools:<toolCallId>` namespace, return that tool-call id so the\n * caller can trigger lazy execution-namespace resolution. Returns\n * `null` for root targets, subgraph hosts, explicit namespaces, and\n * already-promoted subagents.\n */\nfunction subagentNeedingNamespace(target: SelectorTarget): string | null {\n if (target == null || Array.isArray(target)) return null;\n const obj = target as { id?: unknown; namespace?: readonly string[] };\n if (typeof obj.id !== \"string\" || !Array.isArray(obj.namespace)) return null;\n if (obj.namespace.length === 1 && obj.namespace[0] === `tools:${obj.id}`) {\n return obj.id;\n }\n return null;\n}\n\n/**\n * Lazily resolve a subagent's execution namespace on the first scoped\n * mount. Deep-agent subagents execute under a `tools:<uuid>` namespace\n * distinct from their `tools:<toolCallId>` discovery key; until that is\n * known a scoped `useMessages`/`useToolCalls` would target the wrong\n * scope. The controller de-dupes and skips already-promoted ids, so\n * this is safe to call from every consumer of the same subagent.\n */\nfunction useResolveSubagentNamespace(\n stream: AnyStream,\n target: SelectorTarget\n): void {\n const controller = stream[STREAM_CONTROLLER];\n const toolCallId = subagentNeedingNamespace(target);\n useEffect(() => {\n if (toolCallId == null) return;\n void controller.resolveSubagentNamespace(toolCallId);\n }, [controller, toolCallId]);\n}\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n// The stream type we accept for selectors — purposely loose so\n// selector hooks remain callable from components that don't carry\n// the exact State/Interrupt/Configurable generics. We use `any` for\n// all three generics because `UseStreamReturn` is\n// invariant in `State` and `Configurable` (they flow through both\n// reader and writer positions), so a concrete\n// `useStream<typeof agent>()` handle wouldn't flow into\n// a `<object, unknown, object>` slot otherwise.\n//\n// Typed selectors (`useValues<S>` etc.) use {@link StreamHandle}\n// above so the concrete `StateType` flows into the return; hooks\n// that don't depend on state (`useMessages`, `useAudio`, …) stay on\n// `AnyStream` for maximum flexibility.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Subscribe to a scoped `messages` stream. Pass `stream` and\n * optionally a subagent/subgraph snapshot (or any namespaced target).\n *\n * Contract:\n * - At the root (no target) this returns `stream.messages` directly\n * — no extra subscription is opened. `stream.messages` is the\n * live merge of `messages`-channel token deltas and\n * `values.messages` snapshots (see\n * {@link UseStreamReturn.messages}), so token-by-token\n * streaming here depends on the backend emitting `messages`\n * channel events. Backends that only emit `values` updates will\n * render full turns at once rather than streaming.\n * - For any other namespace, the mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. Unmounting\n * the last component that watches this namespace closes the\n * subscription automatically.\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: SelectorTarget\n): BaseMessage[] {\n useResolveSubagentNamespace(stream, target);\n const namespace = resolveNamespace(target);\n const key = `messages|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace),\n key,\n EMPTY_MESSAGES\n );\n return isRoot(namespace) ? stream.messages : scoped;\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link useMessages}; at the root this just returns\n * `stream.toolCalls`.\n *\n * The optional generic `T` can be passed to narrow the type of\n * assembled tool calls on the returned array. Accepts either:\n * - an agent brand (`typeof agent`) — union is derived from the\n * agent's declared tools via {@link InferToolCalls};\n * - an array of LangGraph tools (`typeof tools`) — union is derived\n * from {@link InferToolCalls} (parallel to {@link ToolCallsFromTools}).\n *\n * When omitted, returns the plain `AssembledToolCall[]` union used by\n * the controller.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget\n): InferToolCalls<T>[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[] {\n useResolveSubagentNamespace(stream, target);\n const namespace = resolveNamespace(target);\n const key = `toolCalls|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace),\n key,\n EMPTY_TOOLCALLS\n );\n return isRoot(namespace) ? stream.toolCalls : scoped;\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — most-recent state payload\n * for a namespace. Equivalent to reading `stream.values` at the root.\n *\n * When the payload carries a `messages` array, it is coerced to\n * `BaseMessage` instances to keep parity with the root projection.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on the parent `useStream<State>()` — no explicit\n * generic required. Non-nullable because the root snapshot always\n * carries `values` (falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): the scoped payload can\n * have a different shape than the root state (e.g. a subagent\n * returning its own substate). Callers should annotate the\n * expected shape explicitly: `useValues<SubagentState>(stream, sub)`.\n * Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): StateType;\n/**\n * Explicit-generic override. Accepts:\n * - an agent brand or compiled graph (unwrapped via\n * {@link InferStateType});\n * - a plain state shape (returned as-is).\n *\n * The root-call form is non-nullable (the root snapshot is always\n * present); the scoped form returns `T | undefined` because a\n * projection may not have emitted a payload yet.\n */\nexport function useValues<T>(stream: AnyStream): InferStateType<T>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): T | undefined;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): unknown {\n const namespace = resolveNamespace(target);\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\n return isRoot(namespace) ? stream.values : scoped;\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — most-recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function useExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget\n): T | undefined {\n const namespace = resolveNamespace(target);\n const key = `extension|${name}|${namespaceKey(namespace)}`;\n return useProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link useMessages} / {@link useToolCalls} / {@link useValues}\n * for the common cases.\n */\n/**\n * Subscribe to a scoped audio-media stream. Returns an array of\n * {@link AudioMedia} handles, one per message containing at least one\n * `AudioBlock` in the target namespace.\n *\n * Each handle is yielded on its first matching `content-block-start`,\n * exposes `.partialBytes` for live access, settles `.blob` /\n * `.objectURL` / `.transcript` on `message-finish`, and surfaces\n * fail-loud errors via `.error`.\n *\n * Pair with {@link useMediaURL} to turn a handle into an `<audio src>`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): AudioMedia[] {\n const namespace = resolveNamespace(target);\n const key = `audio|${namespaceKey(namespace)}`;\n return useProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): ImageMedia[] {\n const namespace = resolveNamespace(target);\n const key = `images|${namespaceKey(namespace)}`;\n return useProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): VideoMedia[] {\n const namespace = resolveNamespace(target);\n const key = `video|${namespaceKey(namespace)}`;\n return useProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for an\n * `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): FileMedia[] {\n const namespace = resolveNamespace(target);\n const key = `files|${namespaceKey(namespace)}`;\n return useProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n\nexport type UseChannelOptions = ChannelProjectionOptions;\n\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Event[] {\n const namespace = resolveNamespace(target);\n const channelKey = useMemo(() => [...channels].sort().join(\",\"), [channels]);\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${channelKey}|${namespaceKey(namespace)}`;\n return useProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace, options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Read metadata recorded for a specific message id — today exposes\n * `parentCheckpointId`, the checkpoint the message was first seen on.\n * Designed for fork / edit flows:\n *\n * ```tsx\n * const { parentCheckpointId } = useMessageMetadata(stream, msg.id) ?? {};\n * if (parentCheckpointId) {\n * await stream.submit(input, { forkFrom: parentCheckpointId });\n * }\n * ```\n *\n * Returns `undefined` when the id isn't known yet (e.g. the server\n * hasn't emitted `parent_checkpoint` for that message, or the message\n * arrived via `messages`-channel deltas only and no `values` snapshot\n * has landed for it yet).\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: string | undefined\n): MessageMetadata | undefined {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const snapshot = useSyncExternalStore<MessageMetadataMap>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return messageId == null ? undefined : snapshot.get(messageId);\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with `multitaskStrategy:\n * \"enqueue\"` while another run is in flight. The returned object is\n * stable per snapshot so consumers can pass `entries` straight into a\n * `<Fragment key={e.id}>` list without extra memoisation.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: SubmissionQueueSnapshot<StateType>;\n readonly size: number;\n cancel(id: string): Promise<boolean>;\n clear(): Promise<void>;\n}\n\nexport function useSubmissionQueue<StateType extends object>(\n stream: StreamHandle<StateType>\n): UseSubmissionQueueReturn<StateType>;\nexport function useSubmissionQueue(stream: AnyStream): UseSubmissionQueueReturn;\nexport function useSubmissionQueue(\n stream: AnyStream\n): UseSubmissionQueueReturn {\n const controller = stream[STREAM_CONTROLLER];\n const store = controller.queueStore;\n const entries = useSyncExternalStore<SubmissionQueueSnapshot>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return useMemo<UseSubmissionQueueReturn>(\n () => ({\n entries,\n size: entries.length,\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\n }),\n [entries, controller]\n );\n}\n\nexport type { SubmissionQueueEntry, SubmissionQueueSnapshot };\n"],"mappings":"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"}
1
+ {"version":3,"file":"selectors.js","names":[],"sources":["../src/selectors.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n MessageMetadata,\n MessageMetadataMap,\n SubmissionQueueEntry,\n SubmissionQueueSnapshot,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { useProjection } from \"./use-projection.js\";\n\n/**\n * Selector hooks don't need to carry `InterruptType` /\n * `ConfigurableType` — they only ever read state. Accepting a\n * `StateType`-parameterised stream (with the other two generics\n * widened to `any`) lets callers keep their full\n * `useStream<State, Interrupt, Configurable>()` handle\n * without re-declaring the interrupt / configurable shapes at every\n * selector call site.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector hook can be targeted at. Callers can pass any of:\n * - `undefined` — root namespace (cheap: served by the always-on root store)\n * - a {@link SubagentDiscoverySnapshot} — the snapshot returned by `stream.subagents.get(...)`\n * - a {@link SubgraphDiscoverySnapshot} — the snapshot returned by `stream.subgraphs.get(...)`\n * - an explicit `{ namespace: string[] }` — any other namespaced scope\n * - a raw `string[]` — escape hatch identical to the object form\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target;\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\n/**\n * If `target` is a subagent snapshot still on its default\n * `tools:<toolCallId>` namespace, return that tool-call id so the\n * caller can trigger lazy execution-namespace resolution. Returns\n * `null` for root targets, subgraph hosts, explicit namespaces, and\n * already-promoted subagents.\n */\nfunction subagentNeedingNamespace(target: SelectorTarget): string | null {\n if (target == null || Array.isArray(target)) return null;\n const obj = target as { id?: unknown; namespace?: readonly string[] };\n if (typeof obj.id !== \"string\" || !Array.isArray(obj.namespace)) return null;\n if (obj.namespace.length === 1 && obj.namespace[0] === `tools:${obj.id}`) {\n return obj.id;\n }\n return null;\n}\n\n/**\n * Lazily resolve a subagent's execution namespace on the first scoped\n * mount. Deep-agent subagents execute under a `tools:<uuid>` namespace\n * distinct from their `tools:<toolCallId>` discovery key; until that is\n * known a scoped `useMessages`/`useToolCalls` would target the wrong\n * scope. The controller de-dupes and skips already-promoted ids, so\n * this is safe to call from every consumer of the same subagent.\n */\nfunction useResolveSubagentNamespace(\n stream: AnyStream,\n target: SelectorTarget\n): void {\n const controller = stream[STREAM_CONTROLLER];\n const toolCallId = subagentNeedingNamespace(target);\n useEffect(() => {\n if (toolCallId == null) return;\n void controller.resolveSubagentNamespace(toolCallId);\n }, [controller, toolCallId]);\n}\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n// The stream type we accept for selectors — purposely loose so\n// selector hooks remain callable from components that don't carry\n// the exact State/Interrupt/Configurable generics. We use `any` for\n// all three generics because `UseStreamReturn` is\n// invariant in `State` and `Configurable` (they flow through both\n// reader and writer positions), so a concrete\n// `useStream<typeof agent>()` handle wouldn't flow into\n// a `<object, unknown, object>` slot otherwise.\n//\n// Typed selectors (`useValues<S>` etc.) use {@link StreamHandle}\n// above so the concrete `StateType` flows into the return; hooks\n// that don't depend on state (`useMessages`, `useAudio`, …) stay on\n// `AnyStream` for maximum flexibility.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Subscribe to a scoped `messages` stream. Pass `stream` and\n * optionally a subagent/subgraph snapshot (or any namespaced target).\n *\n * Contract:\n * - At the root (no target) this returns `stream.messages` directly\n * — no extra subscription is opened. `stream.messages` is the\n * live merge of `messages`-channel token deltas and\n * `values.messages` snapshots (see\n * {@link UseStreamReturn.messages}), so token-by-token\n * streaming here depends on the backend emitting `messages`\n * channel events. Backends that only emit `values` updates will\n * render full turns at once rather than streaming.\n * - For any other namespace, the mount triggers a ref-counted\n * `messages` subscription scoped to that namespace. Unmounting\n * the last component that watches this namespace closes the\n * subscription automatically.\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function useMessages(\n stream: AnyStream,\n target?: SelectorTarget\n): BaseMessage[] {\n useResolveSubagentNamespace(stream, target);\n const namespace = resolveNamespace(target);\n const key = `messages|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace),\n key,\n EMPTY_MESSAGES\n );\n return isRoot(namespace) ? stream.messages : scoped;\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link useMessages}; at the root this just returns\n * `stream.toolCalls`.\n *\n * The optional generic `T` can be passed to narrow the type of\n * assembled tool calls on the returned array. Accepts either:\n * - an agent brand (`typeof agent`) — union is derived from the\n * agent's declared tools via {@link InferToolCalls};\n * - an array of LangGraph tools (`typeof tools`) — union is derived\n * from {@link InferToolCalls} (parallel to {@link ToolCallsFromTools}).\n *\n * When omitted, returns the plain `AssembledToolCall[]` union used by\n * the controller.\n */\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[];\nexport function useToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget\n): InferToolCalls<T>[];\nexport function useToolCalls(\n stream: AnyStream,\n target?: SelectorTarget\n): AssembledToolCall[] {\n useResolveSubagentNamespace(stream, target);\n const namespace = resolveNamespace(target);\n const key = `toolCalls|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace),\n key,\n EMPTY_TOOLCALLS\n );\n return isRoot(namespace) ? stream.toolCalls : scoped;\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — most-recent state payload\n * for a namespace. Equivalent to reading `stream.values` at the root.\n *\n * When the payload carries a `messages` array, it is coerced to\n * `BaseMessage` instances to keep parity with the root projection.\n *\n * Typing:\n * - **Root** (`useValues(stream)`): returns the `StateType` declared\n * on the parent `useStream<State>()` — no explicit\n * generic required. Non-nullable because the root snapshot always\n * carries `values` (falling back to `initialValues ?? {}`).\n * - **Scoped** (`useValues(stream, target)`): the scoped payload can\n * have a different shape than the root state (e.g. a subagent\n * returning its own substate). Callers should annotate the\n * expected shape explicitly: `useValues<SubagentState>(stream, sub)`.\n * Defaults to `unknown` when not annotated.\n */\nexport function useValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): StateType;\n/**\n * Explicit-generic override. Accepts:\n * - an agent brand or compiled graph (unwrapped via\n * {@link InferStateType});\n * - a plain state shape (returned as-is).\n *\n * The root-call form is non-nullable (the root snapshot is always\n * present); the scoped form returns `T | undefined` because a\n * projection may not have emitted a payload yet.\n */\nexport function useValues<T>(stream: AnyStream): InferStateType<T>;\nexport function useValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget,\n options?: { messagesKey?: string }\n): T | undefined;\nexport function useValues(\n stream: AnyStream,\n target?: SelectorTarget,\n options?: { messagesKey?: string }\n): unknown {\n const namespace = resolveNamespace(target);\n const messagesKey = options?.messagesKey ?? \"messages\";\n const key = `values|${messagesKey}|${namespaceKey(namespace)}`;\n const registry = isRoot(namespace) ? null : getRegistry(stream);\n const scoped = useProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace, messagesKey),\n key,\n undefined\n );\n return isRoot(namespace) ? stream.values : scoped;\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most-recent\n * payload emitted by the transformer, scoped to the target namespace.\n *\n * Returns only the latest value and resumes across serial runs, so it is\n * ideal for \"current state\" panels (progress, score, status). When you\n * need the full history of events rather than just the latest payload,\n * use {@link useChannel} instead.\n */\nexport function useExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget\n): T | undefined {\n const namespace = resolveNamespace(target);\n const key = `extension|${name}|${namespaceKey(namespace)}`;\n return useProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace),\n key,\n undefined\n );\n}\n\n/**\n * Subscribe to a scoped audio-media stream. Returns an array of\n * {@link AudioMedia} handles, one per message containing at least one\n * `AudioBlock` in the target namespace.\n *\n * Each handle is yielded on its first matching `content-block-start`,\n * exposes `.partialBytes` for live access, settles `.blob` /\n * `.objectURL` / `.transcript` on `message-finish`, and surfaces\n * fail-loud errors via `.error`.\n *\n * Pair with {@link useMediaURL} to turn a handle into an `<audio src>`.\n */\nexport function useAudio(\n stream: AnyStream,\n target?: SelectorTarget\n): AudioMedia[] {\n const namespace = resolveNamespace(target);\n const key = `audio|${namespaceKey(namespace)}`;\n return useProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<img src>`.\n */\nexport function useImages(\n stream: AnyStream,\n target?: SelectorTarget\n): ImageMedia[] {\n const namespace = resolveNamespace(target);\n const key = `images|${namespaceKey(namespace)}`;\n return useProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for `<video src>`.\n */\nexport function useVideo(\n stream: AnyStream,\n target?: SelectorTarget\n): VideoMedia[] {\n const namespace = resolveNamespace(target);\n const key = `video|${namespaceKey(namespace)}`;\n return useProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. See {@link useAudio} for\n * shared semantics; pair with {@link useMediaURL} for an\n * `<a download href>` target.\n */\nexport function useFiles(\n stream: AnyStream,\n target?: SelectorTarget\n): FileMedia[] {\n const namespace = resolveNamespace(target);\n const key = `files|${namespaceKey(namespace)}`;\n return useProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n\nexport type UseChannelOptions = ChannelProjectionOptions;\n\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 *\n * The buffer keeps accumulating across serial runs for the lifetime of\n * the thread, so this is the hook to use for an event log / stream of a\n * custom channel (e.g. `[\"custom:redaction-stats\"]`). When you only need\n * the latest payload of a single `custom:<name>` channel, prefer\n * {@link useExtension}. For the common message/tool/value cases prefer\n * {@link useMessages} / {@link useToolCalls} / {@link useValues}.\n */\nexport function useChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget,\n options?: UseChannelOptions\n): Event[] {\n const namespace = resolveNamespace(target);\n const channelKey = useMemo(() => [...channels].sort().join(\",\"), [channels]);\n const key = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${channelKey}|${namespaceKey(namespace)}`;\n return useProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace, options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Read metadata recorded for a specific message id — today exposes\n * `parentCheckpointId`, the checkpoint the message was first seen on.\n * Designed for fork / edit flows:\n *\n * ```tsx\n * const { parentCheckpointId } = useMessageMetadata(stream, msg.id) ?? {};\n * if (parentCheckpointId) {\n * await stream.submit(input, { forkFrom: parentCheckpointId });\n * }\n * ```\n *\n * Returns `undefined` when the id isn't known yet (e.g. the server\n * hasn't emitted `parent_checkpoint` for that message, or the message\n * arrived via `messages`-channel deltas only and no `values` snapshot\n * has landed for it yet).\n */\nexport function useMessageMetadata(\n stream: AnyStream,\n messageId: string | undefined\n): MessageMetadata | undefined {\n const store = stream[STREAM_CONTROLLER].messageMetadataStore;\n const snapshot = useSyncExternalStore<MessageMetadataMap>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return messageId == null ? undefined : snapshot.get(messageId);\n}\n\n/**\n * Reactive handle on the server-side submission queue.\n *\n * Populated when `submit()` is invoked with `multitaskStrategy:\n * \"enqueue\"` while another run is in flight. The returned object is\n * stable per snapshot so consumers can pass `entries` straight into a\n * `<Fragment key={e.id}>` list without extra memoisation.\n */\nexport interface UseSubmissionQueueReturn<\n StateType extends object = Record<string, unknown>,\n> {\n readonly entries: SubmissionQueueSnapshot<StateType>;\n readonly size: number;\n cancel(id: string): Promise<boolean>;\n clear(): Promise<void>;\n}\n\nexport function useSubmissionQueue<StateType extends object>(\n stream: StreamHandle<StateType>\n): UseSubmissionQueueReturn<StateType>;\nexport function useSubmissionQueue(stream: AnyStream): UseSubmissionQueueReturn;\nexport function useSubmissionQueue(\n stream: AnyStream\n): UseSubmissionQueueReturn {\n const controller = stream[STREAM_CONTROLLER];\n const store = controller.queueStore;\n const entries = useSyncExternalStore<SubmissionQueueSnapshot>(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot\n );\n return useMemo<UseSubmissionQueueReturn>(\n () => ({\n entries,\n size: entries.length,\n cancel: (id) => controller.cancelQueued(id),\n clear: () => controller.clearQueue(),\n }),\n [entries, controller]\n );\n}\n\nexport type { SubmissionQueueEntry, SubmissionQueueSnapshot };\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/react",
3
- "version": "1.0.17",
3
+ "version": "1.0.18",
4
4
  "description": "React integration for LangGraph & LangChain",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,7 +10,7 @@
10
10
  "directory": "libs/sdk-react"
11
11
  },
12
12
  "dependencies": {
13
- "@langchain/langgraph-sdk": "1.9.17"
13
+ "@langchain/langgraph-sdk": "1.9.18"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@hono/node-server": "^1.19.13",