@langchain/langgraph-sdk 0.0.69 → 0.0.71

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/client.d.ts CHANGED
@@ -271,7 +271,7 @@ export declare class ThreadsClient<TStateType = DefaultValues, TUpdateType = TSt
271
271
  /**
272
272
  * Sort by.
273
273
  */
274
- sortBy?: "id" | "status" | "created_at" | "updated_at";
274
+ sortBy?: "thread_id" | "status" | "created_at" | "updated_at";
275
275
  /**
276
276
  * Sort order.
277
277
  * Must be one of 'asc' or 'desc'.
@@ -211,12 +211,14 @@ const useControllableThreadId = (options) => {
211
211
  function useStream(options) {
212
212
  let { assistantId, messagesKey, onError, onFinish } = options;
213
213
  messagesKey ??= "messages";
214
- const client = (0, react_1.useMemo)(() => new client_js_1.Client({
215
- apiUrl: options.apiUrl,
216
- apiKey: options.apiKey,
217
- callerOptions: options.callerOptions,
218
- defaultHeaders: options.defaultHeaders,
219
- }), [
214
+ const client = (0, react_1.useMemo)(() => options.client ??
215
+ new client_js_1.Client({
216
+ apiUrl: options.apiUrl,
217
+ apiKey: options.apiKey,
218
+ callerOptions: options.callerOptions,
219
+ defaultHeaders: options.defaultHeaders,
220
+ }), [
221
+ options.client,
220
222
  options.apiKey,
221
223
  options.apiUrl,
222
224
  options.callerOptions,
@@ -240,14 +242,25 @@ function useStream(options) {
240
242
  }, []);
241
243
  const hasUpdateListener = options.onUpdateEvent != null;
242
244
  const hasCustomListener = options.onCustomEvent != null;
245
+ const hasLangChainListener = options.onLangChainEvent != null;
246
+ const hasDebugListener = options.onDebugEvent != null;
243
247
  const callbackStreamMode = (0, react_1.useMemo)(() => {
244
248
  const modes = [];
245
249
  if (hasUpdateListener)
246
250
  modes.push("updates");
247
251
  if (hasCustomListener)
248
252
  modes.push("custom");
253
+ if (hasLangChainListener)
254
+ modes.push("events");
255
+ if (hasDebugListener)
256
+ modes.push("debug");
249
257
  return modes;
250
- }, [hasUpdateListener, hasCustomListener]);
258
+ }, [
259
+ hasUpdateListener,
260
+ hasCustomListener,
261
+ hasLangChainListener,
262
+ hasDebugListener,
263
+ ]);
251
264
  const clearCallbackRef = (0, react_1.useRef)(null);
252
265
  clearCallbackRef.current = () => {
253
266
  setStreamError(undefined);
@@ -391,6 +404,10 @@ function useStream(options) {
391
404
  });
392
405
  if (event === "metadata")
393
406
  options.onMetadataEvent?.(data);
407
+ if (event === "events")
408
+ options.onLangChainEvent?.(data);
409
+ if (event === "debug")
410
+ options.onDebugEvent?.(data);
394
411
  if (event === "values")
395
412
  setStreamValues(data);
396
413
  if (event === "messages") {
@@ -2,7 +2,7 @@ import { Client, type ClientConfig } from "../client.js";
2
2
  import type { Command, DisconnectMode, MultitaskStrategy, OnCompletionBehavior } from "../types.js";
3
3
  import type { Message } from "../types.messages.js";
4
4
  import type { Checkpoint, Config, Interrupt, Metadata, ThreadState } from "../schema.js";
5
- import type { CustomStreamEvent, MetadataStreamEvent, StreamMode, UpdatesStreamEvent } from "../types.stream.js";
5
+ import type { CustomStreamEvent, DebugStreamEvent, EventsStreamEvent, MetadataStreamEvent, StreamMode, UpdatesStreamEvent } from "../types.stream.js";
6
6
  interface Node<StateType = any> {
7
7
  type: "node";
8
8
  value: ThreadState<StateType>;
@@ -58,10 +58,14 @@ export interface UseStreamOptions<StateType extends Record<string, unknown> = Re
58
58
  * The ID of the assistant to use.
59
59
  */
60
60
  assistantId: string;
61
+ /**
62
+ * Client used to send requests.
63
+ */
64
+ client?: Client;
61
65
  /**
62
66
  * The URL of the API to use.
63
67
  */
64
- apiUrl: ClientConfig["apiUrl"];
68
+ apiUrl?: ClientConfig["apiUrl"];
65
69
  /**
66
70
  * The API key to use.
67
71
  */
@@ -103,6 +107,16 @@ export interface UseStreamOptions<StateType extends Record<string, unknown> = Re
103
107
  * Callback that is called when a metadata event is received.
104
108
  */
105
109
  onMetadataEvent?: (data: MetadataStreamEvent["data"]) => void;
110
+ /**
111
+ * Callback that is called when a LangChain event is received.
112
+ * @see https://langchain-ai.github.io/langgraph/cloud/how-tos/stream_events/#stream-graph-in-events-mode for more details.
113
+ */
114
+ onLangChainEvent?: (data: EventsStreamEvent["data"]) => void;
115
+ /**
116
+ * Callback that is called when a debug event is received.
117
+ * @internal This API is experimental and subject to change.
118
+ */
119
+ onDebugEvent?: (data: DebugStreamEvent["data"]) => void;
106
120
  /**
107
121
  * The ID of the thread to fetch history and current values from.
108
122
  */
@@ -208,12 +208,14 @@ const useControllableThreadId = (options) => {
208
208
  export function useStream(options) {
209
209
  let { assistantId, messagesKey, onError, onFinish } = options;
210
210
  messagesKey ??= "messages";
211
- const client = useMemo(() => new Client({
212
- apiUrl: options.apiUrl,
213
- apiKey: options.apiKey,
214
- callerOptions: options.callerOptions,
215
- defaultHeaders: options.defaultHeaders,
216
- }), [
211
+ const client = useMemo(() => options.client ??
212
+ new Client({
213
+ apiUrl: options.apiUrl,
214
+ apiKey: options.apiKey,
215
+ callerOptions: options.callerOptions,
216
+ defaultHeaders: options.defaultHeaders,
217
+ }), [
218
+ options.client,
217
219
  options.apiKey,
218
220
  options.apiUrl,
219
221
  options.callerOptions,
@@ -237,14 +239,25 @@ export function useStream(options) {
237
239
  }, []);
238
240
  const hasUpdateListener = options.onUpdateEvent != null;
239
241
  const hasCustomListener = options.onCustomEvent != null;
242
+ const hasLangChainListener = options.onLangChainEvent != null;
243
+ const hasDebugListener = options.onDebugEvent != null;
240
244
  const callbackStreamMode = useMemo(() => {
241
245
  const modes = [];
242
246
  if (hasUpdateListener)
243
247
  modes.push("updates");
244
248
  if (hasCustomListener)
245
249
  modes.push("custom");
250
+ if (hasLangChainListener)
251
+ modes.push("events");
252
+ if (hasDebugListener)
253
+ modes.push("debug");
246
254
  return modes;
247
- }, [hasUpdateListener, hasCustomListener]);
255
+ }, [
256
+ hasUpdateListener,
257
+ hasCustomListener,
258
+ hasLangChainListener,
259
+ hasDebugListener,
260
+ ]);
248
261
  const clearCallbackRef = useRef(null);
249
262
  clearCallbackRef.current = () => {
250
263
  setStreamError(undefined);
@@ -388,6 +401,10 @@ export function useStream(options) {
388
401
  });
389
402
  if (event === "metadata")
390
403
  options.onMetadataEvent?.(data);
404
+ if (event === "events")
405
+ options.onLangChainEvent?.(data);
406
+ if (event === "debug")
407
+ options.onDebugEvent?.(data);
391
408
  if (event === "values")
392
409
  setStreamValues(data);
393
410
  if (event === "messages") {
@@ -88,6 +88,28 @@ const COMPONENT_STORE = new ComponentStore();
88
88
  const EXT_STORE_SYMBOL = Symbol.for("LGUI_EXT_STORE");
89
89
  const REQUIRE_SYMBOL = Symbol.for("LGUI_REQUIRE");
90
90
  const REQUIRE_EXTRA_SYMBOL = Symbol.for("LGUI_REQUIRE_EXTRA");
91
+ const isIterable = (value) => value != null && typeof value === "object" && Symbol.iterator in value;
92
+ const isPromise = (value) => value != null &&
93
+ typeof value === "object" &&
94
+ "then" in value &&
95
+ typeof value.then === "function";
96
+ const isReactNode = (value) => {
97
+ if (React.isValidElement(value))
98
+ return true;
99
+ if (value == null)
100
+ return true;
101
+ if (typeof value === "string" ||
102
+ typeof value === "number" ||
103
+ typeof value === "bigint" ||
104
+ typeof value === "boolean") {
105
+ return true;
106
+ }
107
+ if (isIterable(value))
108
+ return true;
109
+ if (isPromise(value))
110
+ return true;
111
+ return false;
112
+ };
91
113
  function LoadExternalComponent({ stream, namespace, message, meta, fallback, components, ...props }) {
92
114
  const ref = React.useRef(null);
93
115
  const id = React.useId();
@@ -96,6 +118,11 @@ function LoadExternalComponent({ stream, namespace, message, meta, fallback, com
96
118
  const state = React.useSyncExternalStore(store.subscribe, store.getSnapshot);
97
119
  const clientComponent = components?.[message.name];
98
120
  const hasClientComponent = clientComponent != null;
121
+ const fallbackComponent = isReactNode(fallback)
122
+ ? fallback
123
+ : typeof fallback === "object" && fallback != null
124
+ ? fallback?.[message.name]
125
+ : null;
99
126
  const uiNamespace = namespace ?? stream.assistantId;
100
127
  const uiClient = stream.client["~ui"];
101
128
  React.useEffect(() => {
@@ -117,7 +144,7 @@ function LoadExternalComponent({ stream, namespace, message, meta, fallback, com
117
144
  }
118
145
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { id: shadowRootId, ref: ref, ...props }), (0, jsx_runtime_1.jsx)(UseStreamContext.Provider, { value: { stream, meta }, children: state?.target != null
119
146
  ? ReactDOM.createPortal(React.createElement(state.comp, message.props), state.target)
120
- : fallback })] }));
147
+ : fallbackComponent })] }));
121
148
  }
122
149
  exports.LoadExternalComponent = LoadExternalComponent;
123
150
  function experimental_loadShare(name, module) {
@@ -129,8 +156,6 @@ function experimental_loadShare(name, module) {
129
156
  exports.experimental_loadShare = experimental_loadShare;
130
157
  function bootstrapUiContext() {
131
158
  if (typeof window === "undefined") {
132
- console.warn("Attempting to bootstrap UI context outside of browser environment. " +
133
- "Avoid importing from `@langchain/langgraph-sdk/react-ui` in server context.");
134
159
  return;
135
160
  }
136
161
  window[EXT_STORE_SYMBOL] = COMPONENT_STORE;
@@ -59,7 +59,7 @@ interface LoadExternalComponentProps extends Pick<React.HTMLAttributes<HTMLDivEl
59
59
  /** Additional context to be passed to the child component */
60
60
  meta?: unknown;
61
61
  /** Fallback to be rendered when the component is loading */
62
- fallback?: React.ReactNode;
62
+ fallback?: React.ReactNode | Record<string, React.ReactNode>;
63
63
  /**
64
64
  * Map of components that can be rendered directly without fetching the UI code
65
65
  * from the server.
@@ -61,6 +61,28 @@ const COMPONENT_STORE = new ComponentStore();
61
61
  const EXT_STORE_SYMBOL = Symbol.for("LGUI_EXT_STORE");
62
62
  const REQUIRE_SYMBOL = Symbol.for("LGUI_REQUIRE");
63
63
  const REQUIRE_EXTRA_SYMBOL = Symbol.for("LGUI_REQUIRE_EXTRA");
64
+ const isIterable = (value) => value != null && typeof value === "object" && Symbol.iterator in value;
65
+ const isPromise = (value) => value != null &&
66
+ typeof value === "object" &&
67
+ "then" in value &&
68
+ typeof value.then === "function";
69
+ const isReactNode = (value) => {
70
+ if (React.isValidElement(value))
71
+ return true;
72
+ if (value == null)
73
+ return true;
74
+ if (typeof value === "string" ||
75
+ typeof value === "number" ||
76
+ typeof value === "bigint" ||
77
+ typeof value === "boolean") {
78
+ return true;
79
+ }
80
+ if (isIterable(value))
81
+ return true;
82
+ if (isPromise(value))
83
+ return true;
84
+ return false;
85
+ };
64
86
  export function LoadExternalComponent({ stream, namespace, message, meta, fallback, components, ...props }) {
65
87
  const ref = React.useRef(null);
66
88
  const id = React.useId();
@@ -69,6 +91,11 @@ export function LoadExternalComponent({ stream, namespace, message, meta, fallba
69
91
  const state = React.useSyncExternalStore(store.subscribe, store.getSnapshot);
70
92
  const clientComponent = components?.[message.name];
71
93
  const hasClientComponent = clientComponent != null;
94
+ const fallbackComponent = isReactNode(fallback)
95
+ ? fallback
96
+ : typeof fallback === "object" && fallback != null
97
+ ? fallback?.[message.name]
98
+ : null;
72
99
  const uiNamespace = namespace ?? stream.assistantId;
73
100
  const uiClient = stream.client["~ui"];
74
101
  React.useEffect(() => {
@@ -90,7 +117,7 @@ export function LoadExternalComponent({ stream, namespace, message, meta, fallba
90
117
  }
91
118
  return (_jsxs(_Fragment, { children: [_jsx("div", { id: shadowRootId, ref: ref, ...props }), _jsx(UseStreamContext.Provider, { value: { stream, meta }, children: state?.target != null
92
119
  ? ReactDOM.createPortal(React.createElement(state.comp, message.props), state.target)
93
- : fallback })] }));
120
+ : fallbackComponent })] }));
94
121
  }
95
122
  export function experimental_loadShare(name, module) {
96
123
  if (typeof window === "undefined")
@@ -100,8 +127,6 @@ export function experimental_loadShare(name, module) {
100
127
  }
101
128
  export function bootstrapUiContext() {
102
129
  if (typeof window === "undefined") {
103
- console.warn("Attempting to bootstrap UI context outside of browser environment. " +
104
- "Avoid importing from `@langchain/langgraph-sdk/react-ui` in server context.");
105
130
  return;
106
131
  }
107
132
  window[EXT_STORE_SYMBOL] = COMPONENT_STORE;
@@ -16,12 +16,6 @@ const typedUi = (config, options) => {
16
16
  const runId = config.metadata?.run_id ?? config.runId;
17
17
  if (!runId)
18
18
  throw new Error("run_id is required");
19
- const metadata = {
20
- ...config.metadata,
21
- tags: config.tags,
22
- name: config.runName,
23
- run_id: runId,
24
- };
25
19
  const handlePush = (message, options) => {
26
20
  const evt = {
27
21
  type: "ui",
@@ -29,7 +23,9 @@ const typedUi = (config, options) => {
29
23
  name: message?.name,
30
24
  props: message?.props,
31
25
  metadata: {
32
- ...metadata,
26
+ run_id: runId,
27
+ tags: config.tags,
28
+ name: config.runName,
33
29
  ...message?.metadata,
34
30
  ...(options?.message ? { message_id: options.message.id } : null),
35
31
  },
@@ -13,12 +13,6 @@ export const typedUi = (config, options) => {
13
13
  const runId = config.metadata?.run_id ?? config.runId;
14
14
  if (!runId)
15
15
  throw new Error("run_id is required");
16
- const metadata = {
17
- ...config.metadata,
18
- tags: config.tags,
19
- name: config.runName,
20
- run_id: runId,
21
- };
22
16
  const handlePush = (message, options) => {
23
17
  const evt = {
24
18
  type: "ui",
@@ -26,7 +20,9 @@ export const typedUi = (config, options) => {
26
20
  name: message?.name,
27
21
  props: message?.props,
28
22
  metadata: {
29
- ...metadata,
23
+ run_id: runId,
24
+ tags: config.tags,
25
+ name: config.runName,
30
26
  ...message?.metadata,
31
27
  ...(options?.message ? { message_id: options.message.id } : null),
32
28
  },
@@ -4,7 +4,9 @@ export interface UIMessage {
4
4
  name: string;
5
5
  props: Record<string, unknown>;
6
6
  metadata: {
7
- run_id: string;
7
+ run_id?: string;
8
+ name?: string;
9
+ tags?: string[];
8
10
  message_id?: string;
9
11
  [key: string]: unknown;
10
12
  };
@@ -120,7 +120,15 @@ export type SubgraphDebugStreamEvent = AsSubgraph<DebugStreamEvent>;
120
120
  */
121
121
  export type EventsStreamEvent = {
122
122
  event: "events";
123
- data: unknown;
123
+ data: {
124
+ event: `on_${"chat_model" | "llm" | "chain" | "tool" | "retriever" | "prompt"}_${"start" | "stream" | "end"}` | (string & {});
125
+ name: string;
126
+ tags: string[];
127
+ run_id: string;
128
+ metadata: Record<string, unknown>;
129
+ parent_ids: string[];
130
+ data: unknown;
131
+ };
124
132
  };
125
133
  /** @internal */
126
134
  export type SubgraphEventsStreamEvent = AsSubgraph<EventsStreamEvent>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-sdk",
3
- "version": "0.0.69",
3
+ "version": "0.0.71",
4
4
  "description": "Client library for interacting with the LangGraph API",
5
5
  "type": "module",
6
6
  "packageManager": "yarn@1.22.19",