From 8ad5331c89d18252f48ac6770f778729ce9a2494 Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Tue, 29 Apr 2025 15:34:03 +0200 Subject: [PATCH] feat(sdk-js): add onLangChainEvent and onDebugEvent to useStream --- libs/sdk-js/src/react/stream.tsx | 27 +++++++++++++++++++++++++-- libs/sdk-js/src/types.stream.ts | 15 ++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/libs/sdk-js/src/react/stream.tsx b/libs/sdk-js/src/react/stream.tsx index 081300d94..2e16f76ee 100644 --- a/libs/sdk-js/src/react/stream.tsx +++ b/libs/sdk-js/src/react/stream.tsx @@ -481,6 +481,18 @@ export interface UseStreamOptions< */ onMetadataEvent?: (data: MetadataStreamEvent["data"]) => void; + /** + * Callback that is called when a LangChain event is received. + * @see https://langchain-ai.github.io/langgraph/cloud/how-tos/stream_events/#stream-graph-in-events-mode for more details. + */ + onLangChainEvent?: (data: EventsStreamEvent["data"]) => void; + + /** + * Callback that is called when a debug event is received. + * @internal This API is experimental and subject to change. + */ + onDebugEvent?: (data: DebugStreamEvent["data"]) => void; + /** * The ID of the thread to fetch history and current values from. */ @@ -679,13 +691,22 @@ export function useStream< const hasUpdateListener = options.onUpdateEvent != null; const hasCustomListener = options.onCustomEvent != null; + const hasLangChainListener = options.onLangChainEvent != null; + const hasDebugListener = options.onDebugEvent != null; const callbackStreamMode = useMemo(() => { - const modes: Exclude[] = []; + const modes: Exclude[] = []; if (hasUpdateListener) modes.push("updates"); if (hasCustomListener) modes.push("custom"); + if (hasLangChainListener) modes.push("events"); + if (hasDebugListener) modes.push("debug"); return modes; - }, [hasUpdateListener, hasCustomListener]); + }, [ + hasUpdateListener, + hasCustomListener, + hasLangChainListener, + hasDebugListener, + ]); const clearCallbackRef = useRef<() => void>(null!); clearCallbackRef.current = () => { @@ -870,6 +891,8 @@ export function useStream< }), }); if (event === "metadata") options.onMetadataEvent?.(data); + if (event === "events") options.onLangChainEvent?.(data); + if (event === "debug") options.onDebugEvent?.(data); if (event === "values") setStreamValues(data); if (event === "messages") { diff --git a/libs/sdk-js/src/types.stream.ts b/libs/sdk-js/src/types.stream.ts index 441745aec..2234cf43a 100644 --- a/libs/sdk-js/src/types.stream.ts +++ b/libs/sdk-js/src/types.stream.ts @@ -134,7 +134,20 @@ export type SubgraphDebugStreamEvent = AsSubgraph; /** * Stream event with events occurring during execution. */ -export type EventsStreamEvent = { event: "events"; data: unknown }; +export type EventsStreamEvent = { + event: "events"; + data: { + event: + | `on_${"chat_model" | "llm" | "chain" | "tool" | "retriever" | "prompt"}_${"start" | "stream" | "end"}` + | (string & {}); + name: string; + tags: string[]; + run_id: string; + metadata: Record; + parent_ids: string[]; + data: unknown; + }; +}; /** @internal */ export type SubgraphEventsStreamEvent = AsSubgraph;